예제 #1
0
  /**
   * Pushes a packet-out to a switch. The assumption here is that the packet-in was also generated
   * from the same switch. Thus, if the input port of the packet-in and the outport are the same,
   * the function will not push the packet-out.
   *
   * @param sw switch that generated the packet-in, and from which packet-out is sent
   * @param pi packet-in
   * @param useBufferId if true, use the bufferId from the packet in and do not add the packetIn's
   *     payload. If false set bufferId to BUFFER_ID_NONE and use the packetIn's payload
   * @param outport output port
   * @param cntx context of the packet
   */
  protected void pushPacket(
      IOFSwitch sw, OFPacketIn pi, boolean useBufferId, short outport, FloodlightContext cntx) {

    if (pi == null) {
      return;
    }

    // The assumption here is (sw) is the switch that generated the
    // packet-in. If the input port is the same as output port, then
    // the packet-out should be ignored.
    if (pi.getInPort() == outport) {
      if (log.isDebugEnabled()) {
        log.debug(
            "Attempting to do packet-out to the same "
                + "interface as packet-in. Dropping packet. "
                + " SrcSwitch={}, pi={}",
            new Object[] {sw, pi});
        return;
      }
    }

    if (log.isTraceEnabled()) {
      log.trace("PacketOut srcSwitch={} pi={}", new Object[] {sw, pi});
    }

    OFPacketOut po =
        (OFPacketOut) floodlightProvider.getOFMessageFactory().getMessage(OFType.PACKET_OUT);

    // set actions
    List<OFAction> actions = new ArrayList<OFAction>();
    actions.add(new OFActionOutput(outport, (short) 0xffff));

    po.setActions(actions).setActionsLength((short) OFActionOutput.MINIMUM_LENGTH);
    short poLength = (short) (po.getActionsLength() + OFPacketOut.MINIMUM_LENGTH);

    if (useBufferId) {
      po.setBufferId(pi.getBufferId());
    } else {
      po.setBufferId(OFPacketOut.BUFFER_ID_NONE);
    }

    if (po.getBufferId() == OFPacketOut.BUFFER_ID_NONE) {
      byte[] packetData = pi.getPacketData();
      poLength += packetData.length;
      po.setPacketData(packetData);
    }

    po.setInPort(pi.getInPort());
    po.setLength(poLength);

    try {
      counterStore.updatePktOutFMCounterStoreLocal(sw, po);
      messageDamper.write(sw, po, cntx);
    } catch (IOException e) {
      log.error("Failure writing packet out", e);
    }
  }
예제 #2
0
  protected void doFlood(IOFSwitch sw, OFPacketIn pi, FloodlightContext cntx) {
    if (topology.isIncomingBroadcastAllowed(sw.getId(), pi.getInPort()) == false) {
      if (log.isTraceEnabled()) {
        log.trace(
            "doFlood, drop broadcast packet, pi={}, "
                + "from a blocked port, srcSwitch=[{},{}], linkInfo={}",
            new Object[] {pi, sw.getId(), pi.getInPort()});
      }
      return;
    }

    // Set Action to flood
    OFPacketOut po =
        (OFPacketOut) floodlightProvider.getOFMessageFactory().getMessage(OFType.PACKET_OUT);
    List<OFAction> actions = new ArrayList<OFAction>();
    if (sw.hasAttribute(IOFSwitch.PROP_SUPPORTS_OFPP_FLOOD)) {
      actions.add(new OFActionOutput(OFPort.OFPP_FLOOD.getValue(), (short) 0xFFFF));
    } else {
      actions.add(new OFActionOutput(OFPort.OFPP_ALL.getValue(), (short) 0xFFFF));
    }
    po.setActions(actions);
    po.setActionsLength((short) OFActionOutput.MINIMUM_LENGTH);

    // set buffer-id, in-port and packet-data based on packet-in
    short poLength = (short) (po.getActionsLength() + OFPacketOut.MINIMUM_LENGTH);
    po.setBufferId(pi.getBufferId());
    po.setInPort(pi.getInPort());
    if (pi.getBufferId() == OFPacketOut.BUFFER_ID_NONE) {
      byte[] packetData = pi.getPacketData();
      poLength += packetData.length;
      po.setPacketData(packetData);
    }
    po.setLength(poLength);

    try {
      if (log.isTraceEnabled()) {
        log.trace(
            "Writing flood PacketOut switch={} packet-in={} packet-out={}",
            new Object[] {sw, pi, po});
      }
      messageDamper.write(sw, po, cntx);
    } catch (IOException e) {
      log.error(
          "Failure writing PacketOut switch={} packet-in={} packet-out={}",
          new Object[] {sw, pi, po},
          e);
    }

    return;
  }
예제 #3
0
  /**
   * Write packetout message to sw with output actions to one or more output ports with
   * inPort/outPorts passed in.
   *
   * @param packetData
   * @param sw
   * @param inPort
   * @param ports
   * @param cntx
   */
  public void packetOutMultiPort(
      byte[] packetData,
      IOFSwitch sw,
      short inPort,
      Set<Integer> outPorts,
      FloodlightContext cntx) {
    // setting actions
    List<OFAction> actions = new ArrayList<OFAction>();

    Iterator<Integer> j = outPorts.iterator();

    while (j.hasNext()) {
      actions.add(new OFActionOutput(j.next().shortValue(), (short) 0));
    }

    OFPacketOut po =
        (OFPacketOut) floodlightProvider.getOFMessageFactory().getMessage(OFType.PACKET_OUT);
    po.setActions(actions);
    po.setActionsLength((short) (OFActionOutput.MINIMUM_LENGTH * outPorts.size()));

    // set buffer-id to BUFFER_ID_NONE, and set in-port to OFPP_NONE
    po.setBufferId(OFPacketOut.BUFFER_ID_NONE);
    po.setInPort(inPort);

    // data (note buffer_id is always BUFFER_ID_NONE) and length
    short poLength = (short) (po.getActionsLength() + OFPacketOut.MINIMUM_LENGTH);
    poLength += packetData.length;
    po.setPacketData(packetData);
    po.setLength(poLength);

    try {
      counterStore.updatePktOutFMCounterStoreLocal(sw, po);
      if (log.isTraceEnabled()) {
        log.trace(
            "write broadcast packet on switch-id={} " + "interfaces={} packet-out={}",
            new Object[] {sw.getId(), outPorts, po});
      }
      messageDamper.write(sw, po, cntx);

    } catch (IOException e) {
      log.error("Failure writing packet out", e);
    }
  }
예제 #4
0
  protected void pushPacket(
      IOFSwitch sw, OFMatch match, OFPacketIn pi, short outport, FloodlightContext cntx) {

    if (pi == null) {
      return;
    } else if (pi.getInPort() == outport) {
      log.warn("Packet out not sent as the outport matches inport. {}", pi);
      return;
    }

    // The assumption here is (sw) is the switch that generated the
    // packet-in. If the input port is the same as output port, then
    // the packet-out should be ignored.
    if (pi.getInPort() == outport) {
      if (log.isDebugEnabled()) {
        log.debug(
            "Attempting to do packet-out to the same "
                + "interface as packet-in. Dropping packet. "
                + " SrcSwitch={}, match = {}, pi={}",
            new Object[] {sw, match, pi});
        return;
      }
    }

    if (log.isTraceEnabled()) {
      log.trace("PacketOut srcSwitch={} match={} pi={}", new Object[] {sw, match, pi});
    }

    OFPacketOut po =
        (OFPacketOut) floodlightProvider.getOFMessageFactory().getMessage(OFType.PACKET_OUT);

    // set actions
    List<OFAction> actions = new ArrayList<OFAction>();
    actions.add(new OFActionOutput(outport, (short) 0xffff));

    po.setActions(actions).setActionsLength((short) OFActionOutput.MINIMUM_LENGTH);
    short poLength = (short) (po.getActionsLength() + OFPacketOut.MINIMUM_LENGTH);

    // If the switch doens't support buffering set the buffer id to be none
    // otherwise it'll be the the buffer id of the PacketIn
    if (sw.getBuffers() == 0) {
      // We set the PI buffer id here so we don't have to check again
      // below
      pi.setBufferId(OFPacketOut.BUFFER_ID_NONE);
      po.setBufferId(OFPacketOut.BUFFER_ID_NONE);
    } else {
      po.setBufferId(pi.getBufferId());
    }

    po.setInPort(pi.getInPort());

    // If the buffer id is none or the switch doesn's support buffering
    // we send the data with the packet out
    if (pi.getBufferId() == OFPacketOut.BUFFER_ID_NONE) {
      byte[] packetData = pi.getPacketData();
      poLength += packetData.length;
      po.setPacketData(packetData);
    }

    po.setLength(poLength);

    try {
      counterStore.updatePktOutFMCounterStoreLocal(sw, po);
      messageDamper.write(sw, po, cntx);
    } catch (IOException e) {
      log.error("Failure writing packet out", e);
    }
  }
예제 #5
0
  public boolean pushRoute(
      Route route,
      OFMatch match,
      Integer wildcard_hints,
      OFPacketIn pi,
      long pinSwitch,
      long cookie,
      FloodlightContext cntx,
      boolean requestFlowRemovedNotifn,
      boolean doFlush,
      short flowModCommand) {

    boolean srcSwitchIncluded = false;
    OFFlowMod fm = (OFFlowMod) floodlightProvider.getOFMessageFactory().getMessage(OFType.FLOW_MOD);
    OFActionOutput action = new OFActionOutput();
    action.setMaxLength((short) 0xffff);
    List<OFAction> actions = new ArrayList<OFAction>();
    actions.add(action);

    fm.setIdleTimeout(FLOWMOD_DEFAULT_IDLE_TIMEOUT)
        .setHardTimeout(FLOWMOD_DEFAULT_HARD_TIMEOUT)
        .setBufferId(OFPacketOut.BUFFER_ID_NONE)
        .setCookie(cookie)
        .setCommand(flowModCommand)
        .setMatch(match)
        .setActions(actions)
        .setLengthU(OFFlowMod.MINIMUM_LENGTH + OFActionOutput.MINIMUM_LENGTH);

    List<NodePortTuple> switchPortList = route.getPath();

    for (int indx = switchPortList.size() - 1; indx > 0; indx -= 2) {
      // indx and indx-1 will always have the same switch DPID.
      long switchDPID = switchPortList.get(indx).getNodeId();
      IOFSwitch sw = floodlightProvider.getSwitches().get(switchDPID);
      if (sw == null) {
        if (log.isWarnEnabled()) {
          log.warn("Unable to push route, switch at DPID {} " + "not available", switchDPID);
        }
        return srcSwitchIncluded;
      }

      // set the match.
      fm.setMatch(wildcard(match, sw, wildcard_hints));

      // set buffer id if it is the source switch
      if (1 == indx) {
        // Set the flag to request flow-mod removal notifications only
        // for the
        // source switch. The removal message is used to maintain the
        // flow
        // cache. Don't set the flag for ARP messages
        if ((requestFlowRemovedNotifn) && (match.getDataLayerType() != Ethernet.TYPE_ARP)) {
          fm.setFlags(OFFlowMod.OFPFF_SEND_FLOW_REM);
          match.setWildcards(fm.getMatch().getWildcards());
        }
      }

      short outPort = switchPortList.get(indx).getPortId();
      short inPort = switchPortList.get(indx - 1).getPortId();
      // set input and output ports on the switch
      fm.getMatch().setInputPort(inPort);
      ((OFActionOutput) fm.getActions().get(0)).setPort(outPort);

      try {
        counterStore.updatePktOutFMCounterStoreLocal(sw, fm);
        if (log.isTraceEnabled()) {
          log.trace(
              "Pushing Route flowmod routeIndx={} " + "sw={} inPort={} outPort={}",
              new Object[] {indx, sw, fm.getMatch().getInputPort(), outPort});
        }
        messageDamper.write(sw, fm, cntx);
        if (doFlush) {
          sw.flush();
          counterStore.updateFlush();
        }

        // Push the packet out the source switch
        if (sw.getId() == pinSwitch) {
          pushPacket(sw, match, pi, outPort, cntx);
          srcSwitchIncluded = true;
        }
      } catch (IOException e) {
        log.error("Failure writing flow mod", e);
      }

      try {
        fm = fm.clone();
      } catch (CloneNotSupportedException e) {
        log.error("Failure cloning flow mod", e);
      }
    }

    return srcSwitchIncluded;
  }
예제 #6
0
  /**
   * Pushes a packet-out to a switch. If bufferId != BUFFER_ID_NONE we assume that the packetOut
   * switch is the same as the packetIn switch and we will use the bufferId. In this case the packet
   * can be null Caller needs to make sure that inPort and outPort differs
   *
   * @param packet packet data to send.
   * @param sw switch from which packet-out is sent
   * @param bufferId bufferId
   * @param inPort input port
   * @param outPort output port
   * @param cntx context of the packet
   * @param flush force to flush the packet.
   */
  @LogMessageDocs({
    @LogMessageDoc(
        level = "ERROR",
        message =
            "BufferId is not and packet data is null. "
                + "Cannot send packetOut. "
                + "srcSwitch={dpid} inPort={port} outPort={port}",
        explanation = "The switch send a malformed packet-in." + "The packet will be dropped",
        recommendation = LogMessageDoc.REPORT_SWITCH_BUG),
    @LogMessageDoc(
        level = "ERROR",
        message = "Failure writing packet out",
        explanation = "An I/O error occurred while writing a " + "packet out to a switch",
        recommendation = LogMessageDoc.CHECK_SWITCH)
  })
  public void pushPacket(
      IPacket packet,
      IOFSwitch sw,
      int bufferId,
      short inPort,
      short outPort,
      FloodlightContext cntx,
      boolean flush) {

    if (log.isTraceEnabled()) {
      log.trace("PacketOut srcSwitch={} inPort={} outPort={}", new Object[] {sw, inPort, outPort});
    }

    OFPacketOut po =
        (OFPacketOut) floodlightProvider.getOFMessageFactory().getMessage(OFType.PACKET_OUT);

    // set actions
    List<OFAction> actions = new ArrayList<OFAction>();
    actions.add(new OFActionOutput(outPort, (short) 0xffff));

    po.setActions(actions).setActionsLength((short) OFActionOutput.MINIMUM_LENGTH);
    short poLength = (short) (po.getActionsLength() + OFPacketOut.MINIMUM_LENGTH);

    // set buffer_id, in_port
    po.setBufferId(bufferId);
    po.setInPort(inPort);

    // set data - only if buffer_id == -1
    if (po.getBufferId() == OFPacketOut.BUFFER_ID_NONE) {
      if (packet == null) {
        log.error(
            "BufferId is not set and packet data is null. "
                + "Cannot send packetOut. "
                + "srcSwitch={} inPort={} outPort={}",
            new Object[] {sw, inPort, outPort});
        return;
      }
      byte[] packetData = packet.serialize();
      poLength += packetData.length;
      po.setPacketData(packetData);
    }

    po.setLength(poLength);

    try {
      counterStore.updatePktOutFMCounterStoreLocal(sw, po);
      messageDamper.write(sw, po, cntx, flush);
    } catch (IOException e) {
      log.error("Failure writing packet out", e);
    }
  }