예제 #1
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;
  }
예제 #2
0
  protected void doForwardFlow(
      IOFSwitch sw, OFPacketIn pi, FloodlightContext cntx, boolean requestFlowRemovedNotifn) {
    OFMatch match = new OFMatch();
    match.loadFromPacket(pi.getPacketData(), pi.getInPort());

    // Check if we have the location of the destination
    IDevice dstDevice = IDeviceService.fcStore.get(cntx, IDeviceService.CONTEXT_DST_DEVICE);

    if (dstDevice != null) {
      IDevice srcDevice = IDeviceService.fcStore.get(cntx, IDeviceService.CONTEXT_SRC_DEVICE);
      Long srcIsland = topology.getL2DomainId(sw.getId());

      if (srcDevice == null) {
        log.debug("No device entry found for source device");
        return;
      }
      if (srcIsland == null) {
        log.debug("No openflow island found for source {}/{}", sw.getStringId(), pi.getInPort());
        return;
      }

      // Validate that we have a destination known on the same island
      // Validate that the source and destination are not on the same switchport
      boolean on_same_island = false;
      boolean on_same_if = false;
      for (SwitchPort dstDap : dstDevice.getAttachmentPoints()) {
        long dstSwDpid = dstDap.getSwitchDPID();
        Long dstIsland = topology.getL2DomainId(dstSwDpid);
        if ((dstIsland != null) && dstIsland.equals(srcIsland)) {
          on_same_island = true;
          if ((sw.getId() == dstSwDpid) && (pi.getInPort() == dstDap.getPort())) {
            on_same_if = true;
          }
          break;
        }
      }

      if (!on_same_island) {
        // Flood since we don't know the dst device
        if (log.isTraceEnabled()) {
          log.trace(
              "No first hop island found for destination " + "device {}, Action = flooding",
              dstDevice);
        }
        doFlood(sw, pi, cntx);
        return;
      }

      if (on_same_if) {
        if (log.isTraceEnabled()) {
          log.trace(
              "Both source and destination are on the same " + "switch/port {}/{}, Action = NOP",
              sw.toString(),
              pi.getInPort());
        }
        return;
      }

      // Install all the routes where both src and dst have attachment
      // points.  Since the lists are stored in sorted order we can
      // traverse the attachment points in O(m+n) time
      SwitchPort[] srcDaps = srcDevice.getAttachmentPoints();
      Arrays.sort(srcDaps, clusterIdComparator);
      SwitchPort[] dstDaps = dstDevice.getAttachmentPoints();
      Arrays.sort(dstDaps, clusterIdComparator);

      int iSrcDaps = 0, iDstDaps = 0;

      while ((iSrcDaps < srcDaps.length) && (iDstDaps < dstDaps.length)) {
        SwitchPort srcDap = srcDaps[iSrcDaps];
        SwitchPort dstDap = dstDaps[iDstDaps];
        Long srcCluster = topology.getL2DomainId(srcDap.getSwitchDPID());
        Long dstCluster = topology.getL2DomainId(dstDap.getSwitchDPID());

        int srcVsDest = srcCluster.compareTo(dstCluster);
        if (srcVsDest == 0) {
          if (!srcDap.equals(dstDap) && (srcCluster != null) && (dstCluster != null)) {
            Route route =
                routingEngine.getRoute(
                    srcDap.getSwitchDPID(),
                    (short) srcDap.getPort(),
                    dstDap.getSwitchDPID(),
                    (short) dstDap.getPort());
            if (route != null) {
              if (log.isTraceEnabled()) {
                log.trace(
                    "pushRoute match={} route={} " + "destination={}:{}",
                    new Object[] {match, route, dstDap.getSwitchDPID(), dstDap.getPort()});
              }
              long cookie = AppCookie.makeCookie(FORWARDING_APP_ID, 0);

              pushRoute(
                  route,
                  match,
                  0,
                  pi,
                  sw.getId(),
                  cookie,
                  cntx,
                  requestFlowRemovedNotifn,
                  false,
                  OFFlowMod.OFPFC_ADD);
            }
          }
          iSrcDaps++;
          iDstDaps++;
        } else if (srcVsDest < 0) {
          iSrcDaps++;
        } else {
          iDstDaps++;
        }
      }
    } else {
      // Flood since we don't know the dst device
      doFlood(sw, pi, cntx);
    }
  }
예제 #3
0
  protected void doForwardFlow(IOFSwitch sw, OFPacketIn pi, FloodlightContext cntx) {

    // Setup fields for our packets
    OFMatch match = new OFMatch();
    match.loadFromPacket(pi.getPacketData(), pi.getInPort());

    // Check if we have the location of the destination
    IDevice dstDevice = IDeviceService.fcStore.get(cntx, IDeviceService.CONTEXT_DST_DEVICE);

    if (dstDevice != null) {
      IDevice srcDevice = IDeviceService.fcStore.get(cntx, IDeviceService.CONTEXT_SRC_DEVICE);
      Long srcIsland = topology.getL2DomainId(sw.getId());

      if (srcDevice == null) {
        log.debug("No device entry found for source device");
        return;
      }
      if (srcIsland == null) {
        log.debug("No openflow island found for source {}/{}", sw.getStringId(), pi.getInPort());
        return;
      }

      // Validate that we have a destination known on the same
      // island
      // Validate that the source and destination are not on
      // the same switchport
      boolean on_same_island = false;
      boolean on_same_if = false;
      for (SwitchPort dstDap : dstDevice.getAttachmentPoints()) {
        long dstSwDpid = dstDap.getSwitchDPID();
        Long dstIsland = topology.getL2DomainId(dstSwDpid);
        if ((dstIsland != null) && dstIsland.equals(srcIsland)) {
          on_same_island = true;
          if ((sw.getId() == dstSwDpid) && (pi.getInPort() == dstDap.getPort())) {
            on_same_if = true;
          }
          break;
        }
      }

      if (!on_same_island) {
        // Flood since we don't know the dst device
        if (log.isTraceEnabled()) {
          log.trace(
              "No first hop island found for destination " + "device {}, Action = flooding",
              dstDevice);
        }
        doFlood(sw, pi, cntx);
        return;
      }

      if (on_same_if) {
        if (log.isTraceEnabled()) {
          log.trace(
              "Both source and destination are on the same " + "switch/port {}/{}, Action = NOP",
              sw.toString(),
              pi.getInPort());
        }
        return;
      }

      // Install all the routes where both src and dst have
      // attachment
      // points. Since the lists are stored in sorted order we
      // can
      // traverse the attachment points in O(m+n) time
      SwitchPort[] srcDaps = srcDevice.getAttachmentPoints();
      Arrays.sort(srcDaps, clusterIdComparator);
      SwitchPort[] dstDaps = dstDevice.getAttachmentPoints();
      Arrays.sort(dstDaps, clusterIdComparator);

      int iSrcDaps = 0, iDstDaps = 0;

      while ((iSrcDaps < srcDaps.length) && (iDstDaps < dstDaps.length)) {
        SwitchPort srcDap = srcDaps[iSrcDaps];
        SwitchPort dstDap = dstDaps[iDstDaps];
        Long srcCluster = topology.getL2DomainId(srcDap.getSwitchDPID());
        Long dstCluster = topology.getL2DomainId(dstDap.getSwitchDPID());

        int srcVsDest = srcCluster.compareTo(dstCluster);
        if (srcVsDest == 0) {
          if (!srcDap.equals(dstDap) && (srcCluster != null) && (dstCluster != null)) {

            // TODO: INSERT DIJKSTRA HERE FOR OUR VIDEO FLOWS
            // AND CALCULATE FLOWS
            // Call getroute also with weights!!

            Route route =
                getRoute(
                    srcDap.getSwitchDPID(),
                    (short) srcDap.getPort(),
                    dstDap.getSwitchDPID(),
                    (short) dstDap.getPort());

            if (route != null) {
              if (log.isTraceEnabled()) {
                log.trace(
                    "pushRoute match={} route={} " + "destination={}:{}",
                    new Object[] {match, route, dstDap.getSwitchDPID(), dstDap.getPort()});
              }
              long cookie = AppCookie.makeCookie(FORWARDING_APP_ID, 0);

              // if there is prior routing decision
              // use wildcard
              Integer wildcard_hints = null;
              IRoutingDecision decision = null;
              if (cntx != null) {
                decision = IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION);
              }
              if (decision != null) {
                wildcard_hints = decision.getWildcards();
              } else {
                // L2 only wildcard if there is no
                // prior route decision
                wildcard_hints =
                    ((Integer) sw.getAttribute(IOFSwitch.PROP_FASTWILDCARDS)).intValue()
                        & ~OFMatch.OFPFW_IN_PORT
                        & ~OFMatch.OFPFW_DL_VLAN
                        & ~OFMatch.OFPFW_DL_SRC
                        & ~OFMatch.OFPFW_DL_DST
                        & ~OFMatch.OFPFW_NW_SRC_MASK
                        & ~OFMatch.OFPFW_NW_DST_MASK;
              }

              pushRoute(
                  route,
                  match,
                  wildcard_hints,
                  pi,
                  sw.getId(),
                  cookie,
                  cntx,
                  false,
                  false,
                  OFFlowMod.OFPFC_ADD);
            }
          }
          iSrcDaps++;
          iDstDaps++;
        } else if (srcVsDest < 0) {
          iSrcDaps++;
        } else {
          iDstDaps++;
        }
      }
    } else {
      // Flood since we don't know the dst device
      doFlood(sw, pi, cntx);
    }
  }