Esempio n. 1
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;
  }
Esempio n. 2
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);
    }
  }
Esempio n. 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);
    }
  }