예제 #1
0
 @Override
 public FlowEntry matches(long dpid, short inputPort, byte[] packetData) {
   OFMatch m = new OFMatch();
   m.loadFromPacket(packetData, inputPort);
   List<FlowEntry> list = matches(dpid, m);
   // if we match more than one thing, return the highest priority
   if (list.size() > 0) return list.get(0);
   return null;
 }
예제 #2
0
  /**
   * Tell the classifier to drop packets that look like this
   *
   * @param fvClassifier
   * @param flowEntry
   * @param hardTimeout
   * @param idleTimeout
   */
  private void sendDropRule(
      FVClassifier fvClassifier,
      FlowEntry flowEntry,
      String sliceName,
      short hardTimeout,
      short idleTimeout) {
    FVFlowMod flowMod =
        (FVFlowMod) FlowVisor.getInstance().getFactory().getMessage(OFType.FLOW_MOD);
    // block this exact flow
    OFMatch match = new OFMatch();
    match.loadFromPacket(this.packetData, this.inPort);
    // different from previous policty of block by rule
    // flowMod.setMatch(flowEntry.getRuleMatch());

    String drop_policy = null;
    try {
      drop_policy = FVConfig.getDropPolicy(sliceName);
    } catch (ConfigError e) {
      FVLog.log(
          LogLevel.ALERT,
          fvClassifier,
          "Failed to retrieve drop policy from config." + "\nDefauting to exact drop_policy");
      drop_policy = "exact";
    }
    if (drop_policy.equals("exact")) flowMod.setMatch(match);
    else if (drop_policy.equals("rule")) flowMod.setMatch(flowEntry.getRuleMatch());
    else
      // Should never happen
      FVLog.log(LogLevel.CRIT, fvClassifier, "Error in configuration!");
    flowMod.setCommand(FVFlowMod.OFPFC_ADD);
    flowMod.setActions(new LinkedList<OFAction>()); // send to zero-length
    // list, i.e., DROP
    flowMod.setLengthU(OFFlowMod.MINIMUM_LENGTH);
    flowMod.setHardTimeout(hardTimeout);
    flowMod.setIdleTimeout(idleTimeout);
    flowMod.setPriority((short) 0); // set to lowest priority
    flowMod.setFlags((short) 1);
    // send removed msg (1), not the check overlap (2), or
    // emergency flow cache (4)

    FVLog.log(
        LogLevel.WARN,
        fvClassifier,
        "inserting drop (hard=" + hardTimeout + ",idle=" + idleTimeout + ") rule for " + flowEntry);
    fvClassifier.sendMsg(flowMod, fvClassifier);
  }
예제 #3
0
  @LogMessageDoc(
      level = "ERROR",
      message = "Failure writing drop flow mod",
      explanation = "An I/O error occured while trying to write a " + "drop flow mod to a switch",
      recommendation = LogMessageDoc.CHECK_SWITCH)
  protected void doDropFlow(
      IOFSwitch sw, OFPacketIn pi, IRoutingDecision decision, FloodlightContext cntx) {
    // initialize match structure and populate it using the packet
    OFMatch match = new OFMatch();
    match.loadFromPacket(pi.getPacketData(), pi.getInPort());
    if (decision.getWildcards() != null) {
      match.setWildcards(decision.getWildcards());
    }

    // Create flow-mod based on packet-in and src-switch
    OFFlowMod fm = (OFFlowMod) floodlightProvider.getOFMessageFactory().getMessage(OFType.FLOW_MOD);
    List<OFAction> actions = new ArrayList<OFAction>(); // Set no action to
    // drop
    long cookie = AppCookie.makeCookie(FORWARDING_APP_ID, 0);

    fm.setCookie(cookie)
        .setHardTimeout((short) 0)
        .setIdleTimeout((short) 5)
        .setBufferId(OFPacketOut.BUFFER_ID_NONE)
        .setMatch(match)
        .setActions(actions)
        .setLengthU(OFFlowMod.MINIMUM_LENGTH); // +OFActionOutput.MINIMUM_LENGTH);

    try {
      if (log.isDebugEnabled()) {
        log.debug("write drop flow-mod sw={} match={} flow-mod={}", new Object[] {sw, match, fm});
      }
      messageDamper.write(sw, fm, cntx);
    } catch (IOException e) {
      log.error("Failure writing drop flow mod", e);
    }
  }
예제 #4
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);
    }
  }
예제 #5
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);
    }
  }