/** * 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); } }
/** * 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); } }