private OFMessage createHubPacketOut(IOFSwitch sw, OFMessage msg) { OFPacketIn pi = (OFPacketIn) msg; OFPacketOut.Builder pob = sw.getOFFactory().buildPacketOut(); pob.setBufferId(pi.getBufferId()).setXid(pi.getXid()).setInPort((pi.getVersion().compareTo(OFVersion.OF_12) < 0 ? pi.getInPort() : pi.getMatch().get(MatchField.IN_PORT))); // set actions OFActionOutput.Builder actionBuilder = sw.getOFFactory().actions().buildOutput(); actionBuilder.setPort(OFPort.FLOOD); pob.setActions(Collections.singletonList((OFAction) actionBuilder.build())); // set data if it is included in the packetin if (pi.getBufferId() == OFBufferId.NO_BUFFER) { byte[] packetData = pi.getData(); pob.setData(packetData); } return pob.build(); }
/** * Creates packet_out BDDP for specified output port. * * @param port the port * @return Packet_out message with LLDP data */ private OFPacketOut createBDDPPacketOut(final OFPortDesc port) { if (port == null) { return null; } OFPacketOut.Builder packetOut = sw.factory().buildPacketOut(); packetOut.setBufferId(OFBufferId.NO_BUFFER); OFActionOutput.Builder act = sw.factory().actions().buildOutput() .setPort(port.getPortNo()); OFAction out = act.build(); packetOut.setActions(Collections.singletonList(out)); this.lldpPacket.setPort(port.getPortNo().getPortNumber()); this.bddpEth.setSourceMACAddress(port.getHwAddr().getBytes()); final byte[] bddp = this.bddpEth.serialize(); packetOut.setData(bddp); return packetOut.build(); }
@Override public boolean matches(Object object) { if (!(object instanceof OFPacketOut)) { return false; } OFPacketOut po = (OFPacketOut) object; if (po.getActions().size() != 1 || !(po.getActions().get(0) instanceof OFActionOutput)) { return false; } OFActionOutput action = (OFActionOutput) po.getActions().get(0); return action.getPort().getPortNumber() == portNumber; }
private OFActionOutput buildOutput(Integer port) { OFActionOutput act = sw.factory().actions() .buildOutput() .setPort(OFPort.of(port)) .build(); return act; }
private OFMessage createHubFlowMod(IOFSwitch sw, OFMessage msg) { OFPacketIn pi = (OFPacketIn) msg; OFFlowAdd.Builder fmb = sw.getOFFactory().buildFlowAdd(); fmb.setBufferId(pi.getBufferId()) .setXid(pi.getXid()); // set actions OFActionOutput.Builder actionBuilder = sw.getOFFactory().actions().buildOutput(); actionBuilder.setPort(OFPort.FLOOD); fmb.setActions(Collections.singletonList((OFAction) actionBuilder.build())); return fmb.build(); }
/** * Parse string and numerical port representations. * The key and delimiter for the action should be omitted, and only the * data should be presented to this decoder. Data can be any signed integer * as a string or the strings 'controller', 'local', 'ingress-port', 'normal', * or 'flood'. * @param actionToDecode; The action as a string to decode * @param version; The OF version to create the action for * @param log * @return */ private static OFActionOutput decode_output(String actionToDecode, OFVersion version, Logger log) { Matcher n = Pattern.compile("((all)|(controller)|(local)|(ingress-port)|(normal)|(flood))").matcher(actionToDecode); OFActionOutput.Builder ab = OFFactories.getFactory(version).actions().buildOutput(); OFPort port = OFPort.ANY; if (n.matches()) { if (n.group(1) != null && n.group(1).equals("all")) port = OFPort.ALL; else if (n.group(1) != null && n.group(1).equals("controller")) port = OFPort.CONTROLLER; else if (n.group(1) != null && n.group(1).equals("local")) port = OFPort.LOCAL; else if (n.group(1) != null && n.group(1).equals("ingress-port")) port = OFPort.IN_PORT; else if (n.group(1) != null && n.group(1).equals("normal")) port = OFPort.NORMAL; else if (n.group(1) != null && n.group(1).equals("flood")) port = OFPort.FLOOD; ab.setPort(port); ab.setMaxLen(Integer.MAX_VALUE); log.debug("action {}", ab.build()); return ab.build(); } else { try { port = OFPort.of(Integer.parseInt(actionToDecode)); ab.setPort(port); ab.setMaxLen(Integer.MAX_VALUE); return ab.build(); } catch (NumberFormatException e) { log.error("Could not parse Integer port: '{}'", actionToDecode); return null; } } }
@Override public void switchAdded(DatapathId dpid) { /* Insert static flows on all ports of the switch to redirect * DHCP client --> DHCP DHCPServer traffic to the controller. * DHCP client's operate on UDP port 67 */ IOFSwitch sw = switchService.getSwitch(dpid); //fix concurrency flaw if (sw == null){ return; } OFFlowAdd.Builder flow = sw.getOFFactory().buildFlowAdd(); Match.Builder match = sw.getOFFactory().buildMatch(); ArrayList<OFAction> actionList = new ArrayList<OFAction>(); OFActionOutput.Builder action = sw.getOFFactory().actions().buildOutput(); for (OFPortDesc port : sw.getPorts()) { match.setExact(MatchField.IN_PORT, port.getPortNo()); match.setExact(MatchField.ETH_TYPE, EthType.IPv4); match.setExact(MatchField.IP_PROTO, IpProtocol.UDP); match.setExact(MatchField.UDP_SRC, UDP.DHCP_CLIENT_PORT); action.setMaxLen(0xffFFffFF); action.setPort(OFPort.CONTROLLER); actionList.add(action.build()); flow.setBufferId(OFBufferId.NO_BUFFER); flow.setHardTimeout(0); flow.setIdleTimeout(0); flow.setOutPort(OFPort.CONTROLLER); flow.setActions(actionList); flow.setMatch(match.build()); flow.setPriority(32767); sfp.addFlow("dhcp-port---" + port.getPortNo().getPortNumber() + "---(" + port.getName() + ")", flow.build(), sw.getId()); } }
@Test public void testFloodNoBufferId() throws Exception { // Mock up our expected behavior IOFSwitch mockSwitch = createMock(IOFSwitch.class); EasyMock.expect(mockSwitch.getOFFactory()).andReturn(OFFactories.getFactory(OFVersion.OF_13)).anyTimes(); // build our expected flooded packetOut OFActionOutput ao = OFFactories.getFactory(OFVersion.OF_13).actions().buildOutput().setPort(OFPort.FLOOD).build(); List<OFAction> al = new ArrayList<OFAction>(); al.add(ao); OFPacketOut po = OFFactories.getFactory(OFVersion.OF_13).buildPacketOut() .setActions(al) .setBufferId(OFBufferId.NO_BUFFER) .setXid(1) .setInPort(OFPort.of(1)) .setData(this.testPacketSerialized).build(); Capture<OFMessage> wc1 = new Capture<OFMessage>(CaptureType.ALL); expect(mockSwitch.write(capture(wc1))).andReturn(true).anyTimes(); // Start recording the replay on the mocks replay(mockSwitch); // Get the listener and trigger the packet in IOFMessageListener listener = mockFloodlightProvider.getListeners().get( OFType.PACKET_IN).get(0); listener.receive(mockSwitch, this.packetIn, parseAndAnnotate(this.packetIn)); // Verify the replay matched our expectations verify(mockSwitch); assertTrue(wc1.hasCaptured()); OFMessage m = wc1.getValue(); assertTrue(OFMessageUtils.equalsIgnoreXid(m, po)); }
@Test public void testFloodBufferId() throws Exception { MockFloodlightProvider mockFloodlightProvider = getMockFloodlightProvider(); this.packetIn = this.packetIn.createBuilder() .setBufferId(OFBufferId.of(10)) .setXid(1) .build(); OFActionOutput ao = OFFactories.getFactory(OFVersion.OF_13).actions().buildOutput().setPort(OFPort.FLOOD).build(); List<OFAction> al = new ArrayList<OFAction>(); al.add(ao); // build our expected flooded packetOut OFPacketOut po = OFFactories.getFactory(OFVersion.OF_13).buildPacketOut() .setActions(al) .setXid(1) .setBufferId(OFBufferId.of(10)) .setInPort(OFPort.of(1)) .build(); // Mock up our expected behavior IOFSwitch mockSwitch = createMock(IOFSwitch.class); EasyMock.expect(mockSwitch.getOFFactory()).andReturn(OFFactories.getFactory(OFVersion.OF_13)).anyTimes(); Capture<OFPacketOut> wc1 = new Capture<OFPacketOut>(CaptureType.ALL); expect(mockSwitch.write(capture(wc1))).andReturn(true).anyTimes(); // Start recording the replay on the mocks replay(mockSwitch); // Get the listener and trigger the packet in IOFMessageListener listener = mockFloodlightProvider.getListeners().get( OFType.PACKET_IN).get(0); listener.receive(mockSwitch, this.packetIn, parseAndAnnotate(this.packetIn)); // Verify the replay matched our expectations verify(mockSwitch); assertTrue(wc1.hasCaptured()); OFMessage m = wc1.getValue(); assertEquals(po, m); }
/** * Parse string and numerical port representations. * The key and delimiter for the action should be omitted, and only the * data should be presented to this decoder. Data can be any signed integer * as a string or the strings 'controller', 'local', 'ingress-port', 'normal', * or 'flood'. * @param actionToDecode; The action as a string to decode * @param version; The OF version to create the action for * @param log * @return */ @LogMessageDoc(level="ERROR", message="Invalid subaction: '{subaction}'", explanation="A static flow entry contained an invalid subaction", recommendation=LogMessageDoc.REPORT_CONTROLLER_BUG) private static OFActionOutput decode_output(String actionToDecode, OFVersion version, Logger log) { Matcher n = Pattern.compile("((all)|(controller)|(local)|(ingress-port)|(normal)|(flood))").matcher(actionToDecode); OFActionOutput.Builder ab = OFFactories.getFactory(version).actions().buildOutput(); OFPort port = OFPort.ANY; if (n.matches()) { if (n.group(1) != null && n.group(1).equals("all")) port = OFPort.ALL; else if (n.group(1) != null && n.group(1).equals("controller")) port = OFPort.CONTROLLER; else if (n.group(1) != null && n.group(1).equals("local")) port = OFPort.LOCAL; else if (n.group(1) != null && n.group(1).equals("ingress-port")) port = OFPort.IN_PORT; else if (n.group(1) != null && n.group(1).equals("normal")) port = OFPort.NORMAL; else if (n.group(1) != null && n.group(1).equals("flood")) port = OFPort.FLOOD; ab.setPort(port); ab.setMaxLen(Integer.MAX_VALUE); log.debug("action {}", ab.build()); return ab.build(); } else { try { port = OFPort.of(Integer.parseInt(actionToDecode)); ab.setPort(port); ab.setMaxLen(Integer.MAX_VALUE); return ab.build(); } catch (NumberFormatException e) { log.error("Could not parse Integer port: '{}'", actionToDecode); return null; } } }
@Override public void switchAdded(DatapathId dpid) { /* Insert static flows on all ports of the switch to redirect * DHCP client --> DHCP DHCPServer traffic to the controller. * DHCP client's operate on UDP port 67 */ IOFSwitch sw = switchService.getSwitch(dpid); OFFlowAdd.Builder flow = sw.getOFFactory().buildFlowAdd(); Match.Builder match = sw.getOFFactory().buildMatch(); ArrayList<OFAction> actionList = new ArrayList<OFAction>(); OFActionOutput.Builder action = sw.getOFFactory().actions().buildOutput(); for (OFPortDesc port : sw.getPorts()) { match.setExact(MatchField.IN_PORT, port.getPortNo()); match.setExact(MatchField.ETH_TYPE, EthType.IPv4); match.setExact(MatchField.IP_PROTO, IpProtocol.UDP); match.setExact(MatchField.UDP_SRC, UDP.DHCP_CLIENT_PORT); action.setMaxLen(0xffFFffFF); action.setPort(OFPort.CONTROLLER); actionList.add(action.build()); flow.setBufferId(OFBufferId.NO_BUFFER); flow.setHardTimeout(0); flow.setIdleTimeout(0); flow.setOutPort(OFPort.CONTROLLER); flow.setActions(actionList); flow.setMatch(match.build()); flow.setPriority(32767); sfp.addFlow("dhcp-port---" + port.getPortNo().getPortNumber() + "---(" + port.getName() + ")", flow.build(), sw.getId()); } }
@Test public void testFloodNoBufferId() throws Exception { // Mock up our expected behavior IOFSwitch mockSwitch = createMock(IOFSwitch.class); EasyMock.expect(mockSwitch.getOFFactory()).andReturn(OFFactories.getFactory(OFVersion.OF_13)).anyTimes(); // build our expected flooded packetOut OFActionOutput ao = OFFactories.getFactory(OFVersion.OF_13).actions().buildOutput().setPort(OFPort.FLOOD).build(); List<OFAction> al = new ArrayList<OFAction>(); al.add(ao); OFPacketOut po = OFFactories.getFactory(OFVersion.OF_13).buildPacketOut() .setActions(al) .setBufferId(OFBufferId.NO_BUFFER) .setXid(1) .setInPort(OFPort.of(1)) .setData(this.testPacketSerialized).build(); Capture<OFMessage> wc1 = new Capture<OFMessage>(CaptureType.ALL); mockSwitch.write(capture(wc1)); // Start recording the replay on the mocks replay(mockSwitch); // Get the listener and trigger the packet in IOFMessageListener listener = mockFloodlightProvider.getListeners().get( OFType.PACKET_IN).get(0); listener.receive(mockSwitch, this.packetIn, parseAndAnnotate(this.packetIn)); // Verify the replay matched our expectations verify(mockSwitch); assertTrue(wc1.hasCaptured()); OFMessage m = wc1.getValue(); assertTrue(OFMessageUtils.equalsIgnoreXid(m, po)); }
@Test public void testFloodBufferId() throws Exception { MockFloodlightProvider mockFloodlightProvider = getMockFloodlightProvider(); this.packetIn = this.packetIn.createBuilder() .setBufferId(OFBufferId.of(10)) .setXid(1) .build(); OFActionOutput ao = OFFactories.getFactory(OFVersion.OF_13).actions().buildOutput().setPort(OFPort.FLOOD).build(); List<OFAction> al = new ArrayList<OFAction>(); al.add(ao); // build our expected flooded packetOut OFPacketOut po = OFFactories.getFactory(OFVersion.OF_13).buildPacketOut() .setActions(al) .setXid(1) .setBufferId(OFBufferId.of(10)) .setInPort(OFPort.of(1)) .build(); // Mock up our expected behavior IOFSwitch mockSwitch = createMock(IOFSwitch.class); EasyMock.expect(mockSwitch.getOFFactory()).andReturn(OFFactories.getFactory(OFVersion.OF_13)).anyTimes(); Capture<OFPacketOut> wc1 = new Capture<OFPacketOut>(CaptureType.ALL); mockSwitch.write(capture(wc1)); // Start recording the replay on the mocks replay(mockSwitch); // Get the listener and trigger the packet in IOFMessageListener listener = mockFloodlightProvider.getListeners().get( OFType.PACKET_IN).get(0); listener.receive(mockSwitch, this.packetIn, parseAndAnnotate(this.packetIn)); // Verify the replay matched our expectations verify(mockSwitch); assertTrue(wc1.hasCaptured()); OFMessage m = wc1.getValue(); assertEquals(po, m); }
protected void pushOFDeleteGroup(IOFSwitch sw) { /* Delete the queues attached to all the member ports*/ long queueId = -1; OFPort ofp = null; ArrayList<OFBucket> ofBuckets = multicastGroup.getMemberOFBucketList(sw.getId()); OVSDBContext ovsdbContext = mcObject.ovsdbChannelMap.get(sw.getId()); for (OFBucket ofb : ofBuckets) { queueId = -1; ofp = null; for (OFAction ofa: ofb.getActions()){ if (ofa.getType() == OFActionType.SET_QUEUE){ OFActionSetQueue ofas = (OFActionSetQueue) ofa; queueId = ofas.getQueueId(); /* removes queue using OVSDBContext on the switch */ } if (ofa.getType() == OFActionType.OUTPUT){ OFActionOutput ofo = (OFActionOutput) ofa; ofp = ofo.getPort(); /* removes queue using OVSDBContext on the switch */ } } if (ofp != null && queueId != -1) ovsdbContext.deleteQueueOnPort(ofp, (int)queueId); else logger.error("pushOFDeleteGroup: unexpected actionset in group bucket"); } /* Creates group flow with set queue option */ OFFactory of13Factory = sw.getOFFactory(); OFGroupDelete delGroup = of13Factory.buildGroupDelete() .setGroup(OFGroup.of(multicastGroup.ofGroupId)) .setGroupType(OFGroupType.ALL) .build(); sw.write(delGroup); }
private void addQoSOFBucketToGroup(IOFSwitch sw, OFPort destPort, long bandwidth) { /* creates queue using OVSDBContext on the switch */ OVSDBContext ovsdbContext = mcObject.ovsdbChannelMap.get(sw.getId()); /* FIXME: hardcoded priority '1' for all flows */ int queueId = ovsdbContext.createQueueOnPort(destPort, Long.toString(bandwidth), "1"); OFFactory of13Factory = sw.getOFFactory(); /* creates actions for the bucket */ ArrayList<OFAction> actionList = new ArrayList<OFAction>(); OFActions actions = of13Factory.actions(); OFActionSetQueue setQueue = actions.buildSetQueue().setQueueId(queueId).build(); actionList.add(setQueue); OFActionOutput output = actions.buildOutput() .setMaxLen(0xFFffFFff) .setPort(destPort).build(); actionList.add(output); /* creates a bucket */ OFBucket bucket = of13Factory.buildBucket() .setActions(actionList) .setWatchGroup(OFGroup.ANY) .setWatchPort(OFPort.ANY) .build(); /* store the bucket in multicastGroup object */ multicastGroup.addMemberOFBucket(sw.getId(), destPort.getShortPortNumber(), bucket); }