Beispiel #1
0
  @Override
  public net.floodlightcontroller.core.IListener.Command receive(
      IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {

    if (msg.getType() == OFType.PACKET_IN) {
      OFPacketIn pi = (OFPacketIn) msg;
      Ethernet eth =
          IFloodlightProviderService.bcStore.get(
              cntx, IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
      Short type = eth.getEtherType();

      if (type == Ethernet.TYPE_IPv4) {
        IPv4 ippacket = (IPv4) eth.getPayload();
        log.info("New IPv4 message found. \n  {} \n", eth.toString());

        // For debugging purposes in mininet only
        if (ippacket.getProtocol() == IPv4.PROTOCOL_ICMP) {

          // ICMP icmp = (ICMP)ippacket.getPayload();
          log.info("New ICMP message found. \n  {} \n", ippacket.toString());

          // TODO: Call doForwardFlow with the calculated weights
          // change doForwardFlow args...
          // doForwardFlow(sw, pi, cntx);
        }
      }
    }
    return Command.CONTINUE;
  }
Beispiel #2
0
  @Override
  @LogMessageDoc(
      level = "ERROR",
      message = "Unexpected decision made for this packet-in={}",
      explanation =
          "An unsupported PacketIn decision has been " + "passed to the flow programming component",
      recommendation = LogMessageDoc.REPORT_CONTROLLER_BUG)
  public Command processPacketInMessage(
      IOFSwitch sw, OFPacketIn pi, IRoutingDecision decision, FloodlightContext cntx) {
    Ethernet eth =
        IFloodlightProviderService.bcStore.get(cntx, IFloodlightProviderService.CONTEXT_PI_PAYLOAD);

    // If a decision has been made we obey it
    // otherwise we just forward
    if (decision != null) {
      if (log.isTraceEnabled()) {
        log.trace(
            "Forwaring decision={} was made for PacketIn={}",
            decision.getRoutingAction().toString(),
            pi);
      }

      switch (decision.getRoutingAction()) {
        case NONE:
          // don't do anything
          return Command.CONTINUE;
        case FORWARD_OR_FLOOD:
        case FORWARD:
          doForwardFlow(sw, pi, cntx, false);
          return Command.CONTINUE;
        case MULTICAST:
          // treat as broadcast
          doFlood(sw, pi, cntx);
          return Command.CONTINUE;
        case DROP:
          doDropFlow(sw, pi, decision, cntx);
          return Command.CONTINUE;
        default:
          log.error(
              "Unexpected decision made for this packet-in={}", pi, decision.getRoutingAction());
          return Command.CONTINUE;
      }
    } else {
      if (log.isTraceEnabled()) {
        log.trace("No decision was made for PacketIn={}, forwarding", pi);
      }

      if (eth.isBroadcast() || eth.isMulticast()) {
        // For now we treat multicast as broadcast
        doFlood(sw, pi, cntx);
      } else {
        doForwardFlow(sw, pi, cntx, false);
      }
    }

    return Command.CONTINUE;
  }
Beispiel #3
0
  protected boolean isInSwitchBroadcastCache(IOFSwitch sw, OFPacketIn pi, FloodlightContext cntx) {
    if (sw == null) return true;

    // If the feature is disabled, always return false;
    if (!broadcastCacheFeature) return false;

    // Get the hash of the Ethernet packet.
    Ethernet eth =
        IFloodlightProviderService.bcStore.get(cntx, IFloodlightProviderService.CONTEXT_PI_PAYLOAD);

    long hash = pi.getInPort() * prime2 + eth.hashCode();

    // some FORWARD_OR_FLOOD packets are unicast with unknown destination mac
    return sw.updateBroadcastCache(hash, pi.getInPort());
  }
  protected Command processPacketInMessage(IOFSwitch sw, OFPacketIn pi, FloodlightContext cntx) {

    // get the packet-in switch.
    Ethernet eth =
        IFloodlightProviderService.bcStore.get(cntx, IFloodlightProviderService.CONTEXT_PI_PAYLOAD);

    if (eth.getEtherType() == Ethernet.TYPE_BSN) {
      BSN bsn = (BSN) eth.getPayload();
      if (bsn == null) return Command.STOP;
      if (bsn.getPayload() == null) return Command.STOP;

      // It could be a packet other than BSN LLDP, therefore
      // continue with the regular processing.
      if (bsn.getPayload() instanceof LLDP == false) return Command.CONTINUE;

      doFloodBDDP(sw.getId(), pi, cntx);
    } else {
      return dropFilter(sw.getId(), pi, cntx);
    }
    return Command.STOP;
  }
Beispiel #5
0
  protected boolean isInBroadcastCache(IOFSwitch sw, OFPacketIn pi, FloodlightContext cntx) {
    // Get the cluster id of the switch.
    // Get the hash of the Ethernet packet.
    if (sw == null) return true;

    // If the feature is disabled, always return false;
    if (!broadcastCacheFeature) return false;

    Ethernet eth =
        IFloodlightProviderService.bcStore.get(cntx, IFloodlightProviderService.CONTEXT_PI_PAYLOAD);

    Long broadcastHash;
    broadcastHash =
        topology.getL2DomainId(sw.getId()) * prime1 + pi.getInPort() * prime2 + eth.hashCode();
    if (broadcastCache.update(broadcastHash)) {
      sw.updateBroadcastCache(broadcastHash, pi.getInPort());
      return true;
    } else {
      return false;
    }
  }
Beispiel #6
0
  @LogMessageDocs({
    @LogMessageDoc(
        level = "ERROR",
        message = "Failure writing deny flow mod",
        explanation = "An I/O error occurred while writing a " + "deny flow mod to a switch",
        recommendation = LogMessageDoc.CHECK_SWITCH)
  })
  public static boolean blockHost(
      IFloodlightProviderService floodlightProvider,
      SwitchPort sw_tup,
      long host_mac,
      short hardTimeout,
      long cookie) {

    if (sw_tup == null) {
      return false;
    }

    IOFSwitch sw = floodlightProvider.getSwitches().get(sw_tup.getSwitchDPID());
    if (sw == null) return false;
    int inputPort = sw_tup.getPort();
    log.debug(
        "blockHost sw={} port={} mac={}", new Object[] {sw, sw_tup.getPort(), new Long(host_mac)});

    // Create flow-mod based on packet-in and src-switch
    OFFlowMod fm = (OFFlowMod) floodlightProvider.getOFMessageFactory().getMessage(OFType.FLOW_MOD);
    OFMatch match = new OFMatch();
    List<OFAction> actions = new ArrayList<OFAction>(); // Set no action to
    // drop
    match
        .setDataLayerSource(Ethernet.toByteArray(host_mac))
        .setInputPort((short) inputPort)
        .setWildcards(OFMatch.OFPFW_ALL & ~OFMatch.OFPFW_DL_SRC & ~OFMatch.OFPFW_IN_PORT);
    fm.setCookie(cookie)
        .setHardTimeout(hardTimeout)
        .setIdleTimeout(FLOWMOD_DEFAULT_IDLE_TIMEOUT)
        .setHardTimeout(FLOWMOD_DEFAULT_HARD_TIMEOUT)
        .setBufferId(OFPacketOut.BUFFER_ID_NONE)
        .setMatch(match)
        .setActions(actions)
        .setLengthU(OFFlowMod.MINIMUM_LENGTH); // +OFActionOutput.MINIMUM_LENGTH);

    try {
      log.debug("write drop flow-mod sw={} match={} flow-mod={}", new Object[] {sw, match, fm});
      // TODO: can't use the message damper sine this method is static
      sw.write(fm, null);
    } catch (IOException e) {
      log.error("Failure writing deny flow mod", e);
      return false;
    }
    return true;
  }
Beispiel #7
0
  protected String getCountersKey(IOFSwitch sw, OFMessage m, Ethernet eth) {
    byte mtype = m.getType().getTypeValue();
    // long swid = sw.getId();
    String swsid = sw.getStringId();
    short port = 0;
    short l3type = 0;
    byte l4type = 0;

    if (eth != null) {
      // Packet in counters
      // Need port and protocol level differentiation
      OFPacketIn packet = (OFPacketIn) m;
      port = packet.getInPort();
      l3type = eth.getEtherType();
      if (l3type == (short) 0x0800) {
        IPv4 ipV4 = (IPv4) eth.getPayload();
        l4type = ipV4.getProtocol();
      }
    }

    /* If possible, find and return counters for this tuple
     *
     * NOTE: this can be converted to a tuple for better performance,
     * for now we are using a string representation as a the key
     */
    String countersKey =
        Byte.toString(mtype)
            + "-"
            + swsid
            + "-"
            + Short.toString(port)
            + "-"
            + Short.toString(l3type)
            + "-"
            + Byte.toString(l4type);
    return countersKey;
  }
  @Test
  public void testHandleMessageWithContext() throws Exception {
    IOFSwitch sw = createMock(IOFSwitch.class);
    expect(sw.getId()).andReturn(DatapathId.NONE).anyTimes();

    IOFMessageListener test1 = createMock(IOFMessageListener.class);
    expect(test1.getName()).andReturn("test1").anyTimes();
    expect(test1.isCallbackOrderingPrereq((OFType) anyObject(), (String) anyObject()))
        .andReturn(false)
        .anyTimes();
    expect(test1.isCallbackOrderingPostreq((OFType) anyObject(), (String) anyObject()))
        .andReturn(false)
        .anyTimes();
    FloodlightContext cntx = new FloodlightContext();
    expect(test1.receive(same(sw), same(pi), same(cntx))).andReturn(Command.CONTINUE);

    IOFMessageListener test2 = createMock(IOFMessageListener.class);
    expect(test2.getName()).andReturn("test2").anyTimes();
    expect(test2.isCallbackOrderingPrereq((OFType) anyObject(), (String) anyObject()))
        .andReturn(false)
        .anyTimes();
    expect(test2.isCallbackOrderingPostreq((OFType) anyObject(), (String) anyObject()))
        .andReturn(false)
        .anyTimes();
    // test2 will not receive any message!

    replay(test1, test2, sw);
    controller.addOFMessageListener(OFType.PACKET_IN, test1);
    controller.addOFMessageListener(OFType.ERROR, test2);
    controller.handleMessage(sw, pi, cntx);
    verify(test1, test2, sw);

    Ethernet eth =
        IFloodlightProviderService.bcStore.get(cntx, IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
    assertArrayEquals(testPacket.serialize(), eth.serialize());
  }
  public void doSetUp(HARole role) throws Exception {
    super.setUp();
    FloodlightModuleContext fmc = new FloodlightModuleContext();
    FloodlightProvider cm = new FloodlightProvider();

    fmc.addConfigParam(cm, "role", role.toString());
    controller = (Controller) cm.getServiceImpls().get(IFloodlightProviderService.class);
    fmc.addService(IFloodlightProviderService.class, controller);

    MemoryStorageSource memstorage = new MemoryStorageSource();
    fmc.addService(IStorageSourceService.class, memstorage);

    RestApiServer restApi = new RestApiServer();
    fmc.addService(IRestApiService.class, restApi);

    ThreadPool threadPool = new ThreadPool();
    fmc.addService(IThreadPoolService.class, threadPool);

    MockSwitchManager switchService = new MockSwitchManager();
    fmc.addService(IOFSwitchService.class, switchService);

    PktInProcessingTime ppt = new PktInProcessingTime();
    fmc.addService(IPktInProcessingTimeService.class, ppt);

    // TODO: should mock IDebugCounterService and make sure
    // the expected counters are updated.
    DebugCounterServiceImpl debugCounterService = new DebugCounterServiceImpl();
    fmc.addService(IDebugCounterService.class, debugCounterService);

    DebugEventService debugEventService = new DebugEventService();
    fmc.addService(IDebugEventService.class, debugEventService);

    IShutdownService shutdownService = createMock(IShutdownService.class);
    shutdownService.registerShutdownListener(anyObject(IShutdownListener.class));
    expectLastCall().anyTimes();
    replay(shutdownService);
    fmc.addService(IShutdownService.class, shutdownService);
    verify(shutdownService);

    tp = new MockThreadPoolService();
    fmc.addService(IThreadPoolService.class, tp);

    syncService = new MockSyncService();
    fmc.addService(ISyncService.class, syncService);

    ppt.init(fmc);
    restApi.init(fmc);
    threadPool.init(fmc);
    memstorage.init(fmc);
    tp.init(fmc);
    debugCounterService.init(fmc);
    debugEventService.init(fmc);
    syncService.init(fmc);
    cm.init(fmc);

    ppt.startUp(fmc);
    restApi.startUp(fmc);
    threadPool.startUp(fmc);
    memstorage.startUp(fmc);
    tp.startUp(fmc);
    debugCounterService.startUp(fmc);
    debugEventService.startUp(fmc);
    syncService.startUp(fmc);
    cm.startUp(fmc);

    testPacket =
        new Ethernet()
            .setSourceMACAddress("00:44:33:22:11:00")
            .setDestinationMACAddress("00:11:22:33:44:55")
            .setEtherType(EthType.ARP)
            .setPayload(
                new ARP()
                    .setHardwareType(ARP.HW_TYPE_ETHERNET)
                    .setProtocolType(ARP.PROTO_TYPE_IP)
                    .setHardwareAddressLength((byte) 6)
                    .setProtocolAddressLength((byte) 4)
                    .setOpCode(ARP.OP_REPLY)
                    .setSenderHardwareAddress(Ethernet.toMACAddress("00:44:33:22:11:00"))
                    .setSenderProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.1"))
                    .setTargetHardwareAddress(Ethernet.toMACAddress("00:11:22:33:44:55"))
                    .setTargetProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.2")));
    byte[] testPacketSerialized = testPacket.serialize();

    // The specific factory can be obtained from the switch, but we don't have one
    pi =
        (OFPacketIn)
            factory
                .buildPacketIn()
                .setBufferId(OFBufferId.NO_BUFFER)
                .setInPort(OFPort.of(1))
                .setData(testPacketSerialized)
                .setReason(OFPacketInReason.NO_MATCH)
                .setTotalLen(testPacketSerialized.length)
                .build();
  }
Beispiel #10
0
  protected List<ICounter> getPacketInCounters(IOFSwitch sw, OFMessage m, Ethernet eth) {
    /* If possible, find and return counters for this tuple */
    String countersKey = this.getCountersKey(sw, m, eth);
    List<ICounter> counters = this.pktinCounters.get(countersKey);
    if (counters != null) {
      return counters;
    }

    /*
     *  Create the required counters
     */
    counters = new ArrayList<ICounter>();

    /* values for names */
    short port = ((OFPacketIn) m).getInPort();
    short l3type = eth.getEtherType();
    String switchIdHex = sw.getStringId();
    String etherType = String.format("%04x", eth.getEtherType());
    String packetName = m.getType().toClass().getName();
    packetName = packetName.substring(packetName.lastIndexOf('.') + 1);

    // L2 Type
    String l2Type = null;
    if (eth.isBroadcast()) {
      l2Type = BROADCAST;
    } else if (eth.isMulticast()) {
      l2Type = MULTICAST;
    } else {
      l2Type = UNICAST;
    }

    /*
     * Use alias for L3 type
     * Valid EtherType must be greater than or equal to 0x0600
     * It is V1 Ethernet Frame if EtherType < 0x0600
     */
    if (l3type < 0x0600) {
      etherType = "0599";
    }
    if (TypeAliases.l3TypeAliasMap != null && TypeAliases.l3TypeAliasMap.containsKey(etherType)) {
      etherType = TypeAliases.l3TypeAliasMap.get(etherType);
    } else {
      etherType = "L3_" + etherType;
    }

    // overall controller packet counter names
    String controllerCounterName = CounterStore.createCounterName(CONTROLLER_NAME, -1, packetName);
    counters.add(createCounter(controllerCounterName, CounterType.LONG));

    String switchCounterName = CounterStore.createCounterName(switchIdHex, -1, packetName);
    counters.add(createCounter(switchCounterName, CounterType.LONG));

    String portCounterName = CounterStore.createCounterName(switchIdHex, port, packetName);
    counters.add(createCounter(portCounterName, CounterType.LONG));

    // L2 counter names
    String controllerL2CategoryCounterName =
        CounterStore.createCounterName(CONTROLLER_NAME, -1, packetName, l2Type, NetworkLayer.L2);
    counters.add(createCounter(controllerL2CategoryCounterName, CounterType.LONG));

    String switchL2CategoryCounterName =
        CounterStore.createCounterName(switchIdHex, -1, packetName, l2Type, NetworkLayer.L2);
    counters.add(createCounter(switchL2CategoryCounterName, CounterType.LONG));

    String portL2CategoryCounterName =
        CounterStore.createCounterName(switchIdHex, port, packetName, l2Type, NetworkLayer.L2);
    counters.add(createCounter(portL2CategoryCounterName, CounterType.LONG));

    // L3 counter names
    String controllerL3CategoryCounterName =
        CounterStore.createCounterName(CONTROLLER_NAME, -1, packetName, etherType, NetworkLayer.L3);
    counters.add(createCounter(controllerL3CategoryCounterName, CounterType.LONG));

    String switchL3CategoryCounterName =
        CounterStore.createCounterName(switchIdHex, -1, packetName, etherType, NetworkLayer.L3);
    counters.add(createCounter(switchL3CategoryCounterName, CounterType.LONG));

    String portL3CategoryCounterName =
        CounterStore.createCounterName(switchIdHex, port, packetName, etherType, NetworkLayer.L3);
    counters.add(createCounter(portL3CategoryCounterName, CounterType.LONG));

    // L4 counters
    if (l3type == (short) 0x0800) {

      // resolve protocol alias
      IPv4 ipV4 = (IPv4) eth.getPayload();
      String l4name = String.format("%02x", ipV4.getProtocol());
      if (TypeAliases.l4TypeAliasMap != null && TypeAliases.l4TypeAliasMap.containsKey(l4name)) {
        l4name = TypeAliases.l4TypeAliasMap.get(l4name);
      } else {
        l4name = "L4_" + l4name;
      }

      // create counters
      String controllerL4CategoryCounterName =
          CounterStore.createCounterName(CONTROLLER_NAME, -1, packetName, l4name, NetworkLayer.L4);
      counters.add(createCounter(controllerL4CategoryCounterName, CounterType.LONG));

      String switchL4CategoryCounterName =
          CounterStore.createCounterName(switchIdHex, -1, packetName, l4name, NetworkLayer.L4);
      counters.add(createCounter(switchL4CategoryCounterName, CounterType.LONG));

      String portL4CategoryCounterName =
          CounterStore.createCounterName(switchIdHex, port, packetName, l4name, NetworkLayer.L4);
      counters.add(createCounter(portL4CategoryCounterName, CounterType.LONG));
    }

    /* Add to map and return */
    this.pktinCounters.putIfAbsent(countersKey, counters);
    return this.pktinCounters.get(countersKey);
  }