/** * {@inheritDoc} */ @Override public ImmutablePair<Long, Boolean> installTransitFlow(final DatapathId dpid, final String flowId, final Long cookie, final int inputPort, final int outputPort, final int transitVlanId) { List<OFAction> actionList = new ArrayList<>(); IOFSwitch sw = ofSwitchService.getSwitch(dpid); // build match by input port and transit vlan id Match match = matchFlow(sw, inputPort, transitVlanId); // transmit packet from outgoing port actionList.add(actionSetOutputPort(sw, outputPort)); // build instruction with action list OFInstructionApplyActions actions = buildInstructionApplyActions(sw, actionList); // build FLOW_MOD command, no meter OFFlowMod flowMod = buildFlowMod(sw, match, null, actions, cookie & FLOW_COOKIE_MASK, FlowModUtils.PRIORITY_VERY_HIGH); // send FLOW_MOD to the switch boolean response = pushFlow(flowId, dpid, flowMod); return new ImmutablePair<>(flowMod.getXid(), response); }
/** * Builds OFAction list based on flow parameters for replace scheme. * * @param sw IOFSwitch instance * @param outputVlanId set vlan on packet before forwarding via outputPort; 0 means not to set * @param outputVlanType type of action to apply to the outputVlanId if greater than 0 * @return list of {@link OFAction} */ private List<OFAction> replaceSchemeOutputVlanTypeToOFActionList(IOFSwitch sw, int outputVlanId, OutputVlanType outputVlanType) { List<OFAction> actionList; switch (outputVlanType) { case PUSH: case REPLACE: actionList = singletonList(actionReplaceVlan(sw, outputVlanId)); break; case POP: case NONE: actionList = singletonList(actionPopVlan(sw)); break; default: actionList = emptyList(); logger.error("Unknown OutputVlanType: " + outputVlanType); } return actionList; }
/** * Builds OFAction list based on flow parameters for push scheme. * * @param sw IOFSwitch instance * @param outputVlanId set vlan on packet before forwarding via outputPort; 0 means not to set * @param outputVlanType type of action to apply to the outputVlanId if greater than 0 * @return list of {@link OFAction} */ private List<OFAction> pushSchemeOutputVlanTypeToOFActionList(IOFSwitch sw, int outputVlanId, OutputVlanType outputVlanType) { List<OFAction> actionList = new ArrayList<>(2); switch (outputVlanType) { case PUSH: // No VLAN on packet so push a new one actionList.add(actionPushVlan(sw, ETH_TYPE)); actionList.add(actionReplaceVlan(sw, outputVlanId)); break; case REPLACE: // VLAN on packet but needs to be replaced actionList.add(actionReplaceVlan(sw, outputVlanId)); break; case POP: // VLAN on packet, so remove it // TODO: can i do this? pop two vlan's back to back... actionList.add(actionPopVlan(sw)); break; case NONE: break; default: logger.error("Unknown OutputVlanType: " + outputVlanType); } return actionList; }
/** * Create an OFAction to change the outer most vlan. * * @param sw switch object * @param newVlan final VLAN to be set on the packet * @return {@link OFAction} */ private OFAction actionReplaceVlan(final IOFSwitch sw, final int newVlan) { OFFactory factory = sw.getOFFactory(); OFOxms oxms = factory.oxms(); OFActions actions = factory.actions(); if (OF_12.compareTo(factory.getVersion()) == 0) { return actions.buildSetField().setField(oxms.buildVlanVid() .setValue(OFVlanVidMatch.ofRawVid((short) newVlan)) .build()).build(); } else { return actions.buildSetField().setField(oxms.buildVlanVid() .setValue(OFVlanVidMatch.ofVlan(newVlan)) .build()).build(); } }
/** * Installs the verification rule * * @param dpid datapathId of switch * @param isBroadcast if broadcast then set a generic match; else specific to switch Id * @return true if the command is accepted to be sent to switch, false otherwise - switch is disconnected or in * SLAVE mode */ private boolean installVerificationRule(final DatapathId dpid, final boolean isBroadcast) { IOFSwitch sw = ofSwitchService.getSwitch(dpid); Match match = matchVerification(sw, isBroadcast); ArrayList<OFAction> actionList = new ArrayList<>(2); actionList.add(actionSendToController(sw)); actionList.add(actionSetDstMac(sw, dpidToMac(sw))); OFInstructionApplyActions instructionApplyActions = sw.getOFFactory().instructions() .applyActions(actionList).createBuilder().build(); final long cookie = isBroadcast ? 0x8000000000000002L : 0x8000000000000003L; OFFlowMod flowMod = buildFlowMod(sw, match, null, instructionApplyActions, cookie, FlowModUtils.PRIORITY_VERY_HIGH); String flowname = (isBroadcast) ? "Broadcast" : "Unicast"; flowname += "--VerificationFlow--" + dpid.toString(); return pushFlow(flowname, dpid, flowMod); }
/** write a packetOut, which is buffered */ @Test(timeout = 5000) public void testSingleMessageWrite() throws InterruptedException, ExecutionException { Capture<List<OFMessage>> cMsgList = prepareChannelForWriteList(); OFPacketOut packetOut = factory.buildPacketOut() .setData(new byte[] { 0x01, 0x02, 0x03, 0x04 }) .setActions(ImmutableList.<OFAction>of( factory.actions().output(OFPort.of(1), 0))) .build(); conn.write(packetOut); assertThat("Write should have been flushed", cMsgList.hasCaptured(), equalTo(true)); List<OFMessage> value = cMsgList.getValue(); logger.info("Captured channel write: "+value); assertThat("Should have captured MsgList", cMsgList.getValue(), Matchers.<OFMessage> contains(packetOut)); }
@Override public ExtensionTreatment mapAction(OFAction action) throws UnsupportedOperationException { if (action.getType().equals(OFActionType.SET_FIELD)) { OFActionSetField setFieldAction = (OFActionSetField) action; OFOxm<?> oxm = setFieldAction.getField(); switch (oxm.getMatchField().id) { case VLAN_VID: OFOxmVlanVid vlanVid = (OFOxmVlanVid) oxm; return new OfdpaSetVlanVid(VlanId.vlanId(vlanVid.getValue().getRawVid())); default: throw new UnsupportedOperationException( "Driver does not support extension type " + oxm.getMatchField().id); } } throw new UnsupportedOperationException( "Unexpected OFAction: " + action.toString()); }
/** * Rewrite actions to use LINC OF optical extensions. * * @param actions original actions * @return rewritten actions */ private List<OFAction> rewriteActions(List<OFAction> actions) { List<OFAction> newActions = new LinkedList<>(); for (OFAction action : actions) { if (!(action instanceof OFActionSetField)) { newActions.add(action); continue; } OFActionSetField sf = (OFActionSetField) action; if (!(sf.getField() instanceof OFOxmExpOchSigId)) { newActions.add(action); continue; } OFOxmExpOchSigId oxm = (OFOxmExpOchSigId) sf.getField(); CircuitSignalID signalId = oxm.getValue(); newActions.add( factory().actions().circuit(factory().oxms().ochSigid(signalId))); } return newActions; }
@Override public void sendMsg(OFMessage msg) { // Ignore everything but flow mods and stat requests if (!(msg instanceof OFFlowMod || msg instanceof OFFlowStatsRequest)) { super.sendMsg(msg); return; } Match newMatch; OFMessage newMsg = null; if (msg instanceof OFFlowStatsRequest) { // Rewrite match only OFFlowStatsRequest fsr = (OFFlowStatsRequest) msg; newMatch = rewriteMatch(fsr.getMatch()); newMsg = fsr.createBuilder().setMatch(newMatch).build(); } else if (msg instanceof OFFlowMod) { // Rewrite match and actions OFFlowMod fm = (OFFlowMod) msg; newMatch = rewriteMatch(fm.getMatch()); List<OFAction> actions = rewriteActions(fm.getActions()); newMsg = fm.createBuilder().setMatch(newMatch).setActions(actions).build(); } super.sendMsg(newMsg); }
private OFAction buildL1Modification(Instruction i) { L1ModificationInstruction l1m = (L1ModificationInstruction) i; OFOxm<?> oxm = null; switch (l1m.subtype()) { case ODU_SIGID: ModOduSignalIdInstruction modOduSignalIdInstruction = (ModOduSignalIdInstruction) l1m; OduSignalId oduSignalId = modOduSignalIdInstruction.oduSignalId(); OduSignalID oduSignalID = new OduSignalID((short) oduSignalId.tributaryPortNumber(), (short) oduSignalId.tributarySlotLength(), oduSignalId.tributarySlotBitmap()); oxm = factory().oxms().expOduSigId(oduSignalID); break; default: log.warn("Unimplemented action type {}.", l1m.subtype()); break; } if (oxm != null) { return factory().actions().buildSetField().setField(oxm).build(); } return null; }
@Override public OFFlowAdd buildFlowAdd() { Match match = buildMatch(); List<OFAction> actions = buildActions(); long cookie = flowRule().id().value(); OFFlowAdd fm = factory().buildFlowAdd() .setXid(xid) .setCookie(U64.of(cookie)) .setBufferId(OFBufferId.NO_BUFFER) .setActions(actions) .setMatch(match) .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM)) .setPriority(flowRule().priority()) .build(); return fm; }
@Override public OFFlowMod buildFlowMod() { Match match = buildMatch(); List<OFAction> actions = buildActions(); long cookie = flowRule().id().value(); OFFlowMod fm = factory().buildFlowModify() .setXid(xid) .setCookie(U64.of(cookie)) .setBufferId(OFBufferId.NO_BUFFER) .setActions(actions) .setMatch(match) .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM)) .setPriority(flowRule().priority()) .build(); return fm; }
private OFFlowMod createFRESCOFlowMod(IOFSwitch sw, Match match, List<OFAction> actions, int priority){ OFFlowMod.Builder fmb = sw.getOFFactory().buildFlowAdd();; fmb.setIdleTimeout(FlowModUtils.INFINITE_TIMEOUT); fmb.setHardTimeout(FlowModUtils.INFINITE_TIMEOUT); fmb.setBufferId(OFBufferId.NO_BUFFER); fmb.setOutPort(OFPort.ANY); fmb.setCookie(U64.of(0)); fmb.setPriority(U16.t(priority)); fmb.setMatch(match); fmb.setActions(actions); return fmb.build(); }
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(); }
/** * Send link discovery message out of a given switch port. The discovery * message may be a standard LLDP or a modified LLDP, where the dst mac * address is set to :ff. TODO: The modified LLDP will updated in the future * and may use a different eth-type. * * @param sw * @param port * @param isStandard * indicates standard or modified LLDP * @param isReverse * indicates whether the LLDP was sent as a response */ protected void sendDiscoveryMessage(DatapathId sw, OFPort port, boolean isStandard, boolean isReverse) { // Takes care of all checks including null pointer checks. if (!isOutgoingDiscoveryAllowed(sw, port, isStandard, isReverse)) return; IOFSwitch iofSwitch = switchService.getSwitch(sw); if (iofSwitch == null) //fix dereference violations in case race conditions return; OFPortDesc ofpPort = iofSwitch.getPort(port); OFPacketOut po = generateLLDPMessage(iofSwitch, port, isStandard, isReverse); OFPacketOut.Builder pob = po.createBuilder(); // Add actions List<OFAction> actions = getDiscoveryActions(iofSwitch, ofpPort.getPortNo()); pob.setActions(actions); // no need to set length anymore // send // no more try-catch. switch will silently fail iofSwitch.write(pob.build()); }
/** * Parse set_tp_dst actions. * The key and delimiter for the action should be omitted, and only the * data should be presented to this decoder. A leading 0x is permitted. * * @param actionToDecode; The action as a string to decode * @param version; The OF version to create the action for * @param log * @return */ private static OFAction decode_set_dst_port(String actionToDecode, OFVersion version, Logger log) { Matcher n = Pattern.compile("((?:0x)?\\d+)").matcher(actionToDecode); if (n.matches()) { if (n.group(1) != null) { try { TransportPort portnum = TransportPort.of(get_int(n.group(1))); OFActionSetTpDst.Builder ab = OFFactories.getFactory(version).actions().buildSetTpDst(); ab.setTpPort(portnum); log.debug("action {}", ab.build()); return ab.build(); } catch (NumberFormatException e) { log.debug("Invalid dst-port in: {} (error ignored)", actionToDecode); return null; } } } else { log.debug("Invalid action: '{}'", actionToDecode); return null; } return null; }
/** write a packetOut, which is not buffered */ @Test(timeout = 5000) public void testSingleMessageWrite() throws InterruptedException, ExecutionException { Capture<List<OFMessage>> cMsgList = prepareChannelForWriteList(); OFPacketOut packetOut = factory.buildPacketOut() .setData(new byte[] { 0x01, 0x02, 0x03, 0x04 }) .setActions(ImmutableList.<OFAction>of( factory.actions().output(OFPort.of(1), 0))) .build(); conn.write(packetOut); eventLoop.runTasks(); assertThat("Write should have been flushed", cMsgList.hasCaptured(), equalTo(true)); List<OFMessage> value = cMsgList.getValue(); logger.info("Captured channel write: "+value); assertThat("Should have captured MsgList", cMsgList.getValue(), Matchers.<OFMessage> contains(packetOut)); }
/** write a list of messages */ @Test(timeout = 5000) public void testMessageWriteList() throws InterruptedException, ExecutionException { Capture<List<OFMessage>> cMsgList = prepareChannelForWriteList(); OFHello hello = factory.hello(ImmutableList.<OFHelloElem>of()); OFPacketOut packetOut = factory.buildPacketOut() .setData(new byte[] { 0x01, 0x02, 0x03, 0x04 }) .setActions(ImmutableList.<OFAction>of( factory.actions().output(OFPort.of(1), 0))) .build(); conn.write(ImmutableList.of(hello, packetOut)); eventLoop.runTasks(); assertThat("Write should have been written", cMsgList.hasCaptured(), equalTo(true)); List<OFMessage> value = cMsgList.getValue(); logger.info("Captured channel write: "+value); assertThat("Should have captured MsgList", cMsgList.getValue(), Matchers.<OFMessage> contains(hello, packetOut)); }
/** * Writes an OFPacketOut message to a switch. * @param sw The switch to write the PacketOut to. * @param packetInMessage The corresponding PacketIn. * @param egressPort The switchport to output the PacketOut. */ private void writePacketOutForPacketIn(IOFSwitch sw, OFPacketIn packetInMessage, OFPort egressPort) { OFPacketOut.Builder pob = sw.getOFFactory().buildPacketOut(); // Set buffer_id, in_port, actions_len pob.setBufferId(packetInMessage.getBufferId()); pob.setInPort(packetInMessage.getVersion().compareTo(OFVersion.OF_12) < 0 ? packetInMessage.getInPort() : packetInMessage.getMatch().get(MatchField.IN_PORT)); // set actions List<OFAction> actions = new ArrayList<OFAction>(1); actions.add(sw.getOFFactory().actions().buildOutput().setPort(egressPort).setMaxLen(0xffFFffFF).build()); pob.setActions(actions); // set data - only if buffer_id == -1 if (packetInMessage.getBufferId() == OFBufferId.NO_BUFFER) { byte[] packetData = packetInMessage.getData(); pob.setData(packetData); } // and write it out counterPacketOut.increment(); sw.write(pob.build()); }
/** * Parse set_tp_dst actions. * The key and delimiter for the action should be omitted, and only the * data should be presented to this decoder. A leading 0x is permitted. * * @param actionToDecode; The action as a string to decode * @param version; The OF version to create the action for * @param log * @return */ private static OFAction decode_set_dst_port(String actionToDecode, OFVersion version, Logger log) { Matcher n = Pattern.compile("((?:0x)?\\d+)").matcher(actionToDecode); if (n.matches()) { if (n.group(1) != null) { try { TransportPort portnum = TransportPort.of(get_short(n.group(1))); OFActionSetTpDst.Builder ab = OFFactories.getFactory(version).actions().buildSetTpDst(); ab.setTpPort(portnum); log.debug("action {}", ab.build()); return ab.build(); } catch (NumberFormatException e) { log.debug("Invalid dst-port in: {} (error ignored)", actionToDecode); return null; } } } else { log.debug("Invalid action: '{}'", actionToDecode); return null; } return null; }
public void returnPacketToSwitch(IOFSwitch sw, OFPacketIn pi, ArrayList<OFAction> actionList) { OFPacketOut.Builder po = sw.getOFFactory().buildPacketOut(); po.setBufferId(pi.getBufferId()).setInPort(OFPort.ANY).setActions(actionList); // Packet might be buffered in the switch or encapsulated in Packet-In if (pi.getBufferId() == OFBufferId.NO_BUFFER) { //Packet is encapsulated -> send it back byte[] packetData = pi.getData(); po.setData(packetData); } log.info("PACKETOUT : returning packet back to the switch"); sw.write(po.build()); }
/** * {@inheritDoc} */ @Override public ImmutablePair<Long, Boolean> installEgressFlow(final DatapathId dpid, String flowId, final Long cookie, final int inputPort, final int outputPort, final int transitVlanId, final int outputVlanId, final OutputVlanType outputVlanType) { List<OFAction> actionList = new ArrayList<>(); IOFSwitch sw = ofSwitchService.getSwitch(dpid); // build match by input port and transit vlan id Match match = matchFlow(sw, inputPort, transitVlanId); // output action based on encap scheme actionList.addAll(outputVlanTypeToOFActionList(sw, outputVlanId, outputVlanType)); // transmit packet from outgoing port actionList.add(actionSetOutputPort(sw, outputPort)); // build instruction with action list OFInstructionApplyActions actions = buildInstructionApplyActions(sw, actionList); // build FLOW_MOD command, no meter OFFlowMod flowMod = buildFlowMod(sw, match, null, actions, cookie & FLOW_COOKIE_MASK, FlowModUtils.PRIORITY_VERY_HIGH); // send FLOW_MOD to the switch boolean response = pushFlow(flowId, dpid, flowMod); return new ImmutablePair<>(flowMod.getXid(), response); }
/** * Chooses encapsulation scheme for building OFAction list. * * @param sw {@link IOFSwitch} instance * @param transitVlanId set vlan on packet or replace it before forwarding via outputPort; 0 means not to set * @return list of {@link OFAction} */ private List<OFAction> inputVlanTypeToOFActionList(IOFSwitch sw, int transitVlanId, OutputVlanType outputVlanType) { List<OFAction> actionList = new ArrayList<>(3); if (OutputVlanType.PUSH.equals(outputVlanType) || OutputVlanType.NONE.equals(outputVlanType)) { actionList.add(actionPushVlan(sw, ETH_TYPE)); } actionList.add(actionReplaceVlan(sw, transitVlanId)); return actionList; }
@Override public void build(OFPort outPort) { if (isBuilt.getAndSet(true)) { return; } OFPacketOut.Builder builder = sw.factory().buildPacketOut(); OFAction act = buildOutput(outPort.getPortNumber()); pktout = builder.setXid(pktin.getXid()) .setInPort(pktinInPort()) .setBufferId(OFBufferId.NO_BUFFER) .setData(pktin.getData()) // .setBufferId(pktin.getBufferId()) .setActions(Collections.singletonList(act)) .build(); }
private void verifyActions(OFFlowMod testFlowMod, OFFlowMod goodFlowMod) { List<OFAction> goodActions = goodFlowMod.getActions(); List<OFAction> testActions = testFlowMod.getActions(); assertNotNull(goodActions); assertNotNull(testActions); assertEquals(goodActions.size(), testActions.size()); // assumes actions are marshalled in same order; should be safe for(int i = 0; i < goodActions.size(); i++) { assertEquals(goodActions.get(i), testActions.get(i)); } }
@Test public void testFlood() throws Exception { // build our expected flooded packetOut OFPacketOut po = factory.buildPacketOut() .setInPort(OFPort.of(1)) .setActions(Arrays.asList((OFAction)factory.actions().output(OFPort.FLOOD, 0xffFFffFF))) .setBufferId(OFBufferId.NO_BUFFER) .setData(this.testPacketSerialized) .build(); Capture<OFMessage> wc1 = new Capture<OFMessage>(CaptureType.ALL); // Mock up our expected behavior IOFSwitch mockSwitch = createMock(IOFSwitch.class); expect(mockSwitch.getId()).andReturn(DatapathId.of("00:11:22:33:44:55:66:77")).anyTimes(); expect(mockSwitch.getOFFactory()).andReturn(factory).anyTimes(); mockSwitch.write(EasyMock.capture(wc1)); // expect po EasyMock.expectLastCall().once(); // 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); // Make sure it's the right listener listener.receive(mockSwitch, this.packetIn, parseAndAnnotate(this.packetIn)); // Verify the replay matched our expectations OFPort result = learningSwitch.getFromPortMap(mockSwitch, MacAddress.of("00:44:33:22:11:00"), VlanVid.ofVlan(42)); verify(mockSwitch); assertTrue(wc1.hasCaptured()); assertTrue(OFMessageUtils.equalsIgnoreXid(wc1.getValue(), po)); // Verify the MAC table inside the switch assertEquals(OFPort.of(1), result); }
private OFAction buildL0Modification(Instruction i) { L0ModificationInstruction l0m = (L0ModificationInstruction) i; OFOxm<?> oxm = null; switch (l0m.subtype()) { case OCH: try { ModOchSignalInstruction modOchSignalInstruction = (ModOchSignalInstruction) l0m; OchSignal signal = modOchSignalInstruction.lambda(); byte gridType = OpenFlowValueMapper.lookupGridType(signal.gridType()); byte channelSpacing = OpenFlowValueMapper.lookupChannelSpacing(signal.channelSpacing()); oxm = factory().oxms().expOchSigId( new CircuitSignalID(gridType, channelSpacing, (short) signal.spacingMultiplier(), (short) signal.slotGranularity())); } catch (NoMappingFoundException e) { log.warn(e.getMessage()); break; } break; default: log.warn("Unimplemented action type {}.", l0m.subtype()); break; } if (oxm != null) { return factory().actions().buildSetField().setField(oxm).build(); } return null; }
private OFAction buildModOchSignalInstruction(ModOchSignalInstruction instruction) { OchSignal signal = instruction.lambda(); byte gridType = OpenFlowValueMapper.lookupGridType(signal.gridType()); byte channelSpacing = OpenFlowValueMapper.lookupChannelSpacing(signal.channelSpacing()); return factory().actions().circuit(factory().oxms().expOchSigId( new CircuitSignalID(gridType, channelSpacing, (short) signal.spacingMultiplier(), (short) signal.slotGranularity()) )); }
private OFAction buildExtensionAction(ExtensionTreatment i) { if (!driverService.isPresent()) { log.error("No driver service present"); return null; } Driver driver = driverService.get().getDriver(deviceId); if (driver.hasBehaviour(ExtensionTreatmentInterpreter.class)) { DefaultDriverHandler handler = new DefaultDriverHandler(new DefaultDriverData(driver, deviceId)); ExtensionTreatmentInterpreter interpreter = handler.behaviour(ExtensionTreatmentInterpreter.class); return interpreter.mapInstruction(factory(), i); } return null; }
private TrafficTreatment buildTreatment(List<OFAction> actions) { DriverHandler driverHandler = getDriver(dpid); TrafficTreatment.Builder builder = DefaultTrafficTreatment.builder(); // If this is a drop rule if (actions.size() == 0) { builder.drop(); return builder.build(); } return FlowEntryBuilder.configureTreatmentBuilder(actions, builder, driverHandler, DeviceId.deviceId(Dpid.uri(dpid))).build(); }
/** * Builds the GroupAdd OF message. * * @return GroupAdd OF message */ public OFGroupAdd buildGroupAdd() { List<OFBucket> ofBuckets = new ArrayList<OFBucket>(); for (GroupBucket bucket: buckets.buckets()) { List<OFAction> actions = buildActions(bucket.treatment()); OFBucket.Builder bucketBuilder = factory.buildBucket(); bucketBuilder.setActions(actions); if (type == GroupDescription.Type.SELECT) { bucketBuilder.setWeight(1); } if (type == GroupDescription.Type.FAILOVER && bucket.watchPort() != null) { bucketBuilder.setWatchPort(OFPort.of((int) bucket.watchPort().toLong())); } else { bucketBuilder.setWatchPort(OFPort.ANY); } if (type == GroupDescription.Type.FAILOVER && bucket.watchGroup() != null) { bucketBuilder.setWatchGroup(OFGroup.of(bucket.watchGroup().id())); } else { bucketBuilder.setWatchGroup(OFGroup.ANY); } OFBucket ofBucket = bucketBuilder.build(); ofBuckets.add(ofBucket); } OFGroupAdd groupMsg = factory.buildGroupAdd() .setGroup(OFGroup.of(groupId.id())) .setBuckets(ofBuckets) .setGroupType(getOFGroupType(type)) .setXid(xid) .build(); return groupMsg; }
/** * Builds the GroupMod OF message. * * @return GroupMod OF message */ public OFGroupMod buildGroupMod() { List<OFBucket> ofBuckets = new ArrayList<OFBucket>(); for (GroupBucket bucket: buckets.buckets()) { List<OFAction> actions = buildActions(bucket.treatment()); OFBucket.Builder bucketBuilder = factory.buildBucket(); bucketBuilder.setActions(actions); if (type == GroupDescription.Type.SELECT) { bucketBuilder.setWeight(1); } if (type == GroupDescription.Type.FAILOVER && bucket.watchPort() != null) { bucketBuilder.setWatchPort(OFPort.of((int) bucket.watchPort().toLong())); } else { bucketBuilder.setWatchPort(OFPort.ANY); } if (type == GroupDescription.Type.FAILOVER && bucket.watchGroup() != null) { bucketBuilder.setWatchGroup(OFGroup.of(bucket.watchGroup().id())); } else { bucketBuilder.setWatchGroup(OFGroup.ANY); } OFBucket ofBucket = bucketBuilder.build(); ofBuckets.add(ofBucket); } OFGroupMod groupMsg = factory.buildGroupModify() .setGroup(OFGroup.of(groupId.id())) .setBuckets(ofBuckets) .setGroupType(getOFGroupType(type)) .setXid(xid) .build(); return groupMsg; }
private OFAction buildL0Modification(Instruction i) { L0ModificationInstruction l0m = (L0ModificationInstruction) i; switch (l0m.subtype()) { default: log.warn("Unimplemented action type {}.", l0m.subtype()); break; } return null; }
private OFAction buildExtensionAction(ExtensionTreatment i, DeviceId deviceId) { if (!driverService.isPresent()) { log.error("No driver service present"); return null; } Driver driver = driverService.get().getDriver(deviceId); if (driver.hasBehaviour(ExtensionTreatmentInterpreter.class)) { DefaultDriverHandler handler = new DefaultDriverHandler(new DefaultDriverData(driver, deviceId)); ExtensionTreatmentInterpreter interpreter = handler.behaviour(ExtensionTreatmentInterpreter.class); return interpreter.mapInstruction(factory, i); } return null; }
private OFPacketOut packetOut(OpenFlowSwitch sw, byte[] eth, OFPort out) { OFPacketOut.Builder builder = sw.factory().buildPacketOut(); OFAction act = sw.factory().actions() .buildOutput() .setPort(out) .build(); return builder .setBufferId(OFBufferId.NO_BUFFER) .setInPort(OFPort.CONTROLLER) .setActions(Collections.singletonList(act)) .setData(eth) .build(); }
private void enforceBlockAction(BlockAction ba){ //block flow rule lists to instaled in data plane ArrayList<OFFlowMod> blockFMs = new ArrayList<>(); OFFlowMod blockFM; IDevice blockedDevice = getDeviceFromIP(ba.getBlockedIP()); if (blockedDevice == null){ log.error("[FRESCO] Block host " + IPv4Address.of(ba.getBlockedIP()) + " fail because cannot locate the host location"); return; } SwitchPort blockedLocation = getLocationFromDevice(blockedDevice); IOFSwitch inSW = switchService.getSwitch(blockedLocation.getSwitchDPID()); Match.Builder mb = inSW.getOFFactory().buildMatch(); mb.setExact(MatchField.IPV4_SRC, IPv4Address.of(ba.getBlockedIP())); List<OFAction> blockActions = new ArrayList<OFAction>(); blockFM = createFRESCOFlowMod(inSW, mb.build(), blockActions, SEC_PRIORITY_0); blockFMs.add(blockFM); //enforce block flow rules for (OFFlowMod fm : blockFMs){ try { messageDamper.write(inSW, fm); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
private void enforceMirrorAction(FPContext cntx, MirrorAction ma){ //check if the mirrored switch and port are still active IOFSwitch sw = switchService.getSwitch(DatapathId.of(ma.getDPID())); Ethernet eth = IFloodlightProviderService.bcStore.get(cntx.getFlowContext(), IFloodlightProviderService.CONTEXT_PI_PAYLOAD); if (sw == null){ log.error("[FRESCO] Cannot mirrow packet since the destination switch is offline"); return; } if (sw.getPort(OFPort.of(ma.getPortID())) == null){ log.error("[FRESCO] Cannot mirrow packet since the destination port is closed"); return; } //use packet-out to send out packet to a specific switch port OFPacketOut.Builder pob = sw.getOFFactory().buildPacketOut(); ArrayList<OFAction> actions = new ArrayList<OFAction>(); actions.add(sw.getOFFactory().actions().output(OFPort.of(ma.getPortID()),Integer.MAX_VALUE)); byte[] packetData = eth.serialize(); pob.setData(packetData); sw.write(pob.build()); }
protected void doDropFlow(IOFSwitch sw, OFPacketIn pi, IRoutingDecision decision, FloodlightContext cntx) { OFPort inPort = (pi.getVersion().compareTo(OFVersion.OF_12) < 0 ? pi.getInPort() : pi.getMatch().get(MatchField.IN_PORT)); Match m = createMatchFromPacket(sw, inPort, cntx); OFFlowMod.Builder fmb = sw.getOFFactory().buildFlowAdd(); // this will be a drop-flow; a flow that will not output to any ports List<OFAction> actions = new ArrayList<OFAction>(); // set no action to drop U64 cookie = AppCookie.makeCookie(FORWARDING_APP_ID, 0); log.info("Droppingggg"); fmb.setCookie(cookie) .setHardTimeout(FLOWMOD_DEFAULT_HARD_TIMEOUT) .setIdleTimeout(FLOWMOD_DEFAULT_IDLE_TIMEOUT) .setBufferId(OFBufferId.NO_BUFFER) .setMatch(m) .setPriority(FLOWMOD_DEFAULT_PRIORITY); FlowModUtils.setActions(fmb, actions, sw); try { if (log.isDebugEnabled()) { log.debug("write drop flow-mod sw={} match={} flow-mod={}", new Object[] { sw, m, fmb.build() }); } boolean dampened = messageDamper.write(sw, fmb.build()); log.debug("OFMessage dampened: {}", dampened); } catch (IOException e) { log.error("Failure writing drop flow mod", e); } }
/** * Creates a OFPacketOut with the OFPacketIn data that is flooded on all ports unless * the port is blocked, in which case the packet will be dropped. * @param sw The switch that receives the OFPacketIn * @param pi The OFPacketIn that came to the switch * @param cntx The FloodlightContext associated with this OFPacketIn */ protected void doFlood(IOFSwitch sw, OFPacketIn pi, FloodlightContext cntx) { OFPort inPort = (pi.getVersion().compareTo(OFVersion.OF_12) < 0 ? pi.getInPort() : pi.getMatch().get(MatchField.IN_PORT)); // Set Action to flood OFPacketOut.Builder pob = sw.getOFFactory().buildPacketOut(); List<OFAction> actions = new ArrayList<OFAction>(); Set<OFPort> broadcastPorts = this.topologyService.getSwitchBroadcastPorts(sw.getId()); if (broadcastPorts == null) { log.debug("BroadcastPorts returned null. Assuming single switch w/no links."); /* Must be a single-switch w/no links */ broadcastPorts = Collections.singleton(OFPort.FLOOD); } for (OFPort p : broadcastPorts) { if (p.equals(inPort)) continue; actions.add(sw.getOFFactory().actions().output(p, Integer.MAX_VALUE)); } pob.setActions(actions); // log.info("actions {}",actions); // set buffer-id, in-port and packet-data based on packet-in pob.setBufferId(OFBufferId.NO_BUFFER); pob.setInPort(inPort); pob.setData(pi.getData()); try { if (log.isTraceEnabled()) { log.trace("Writing flood PacketOut switch={} packet-in={} packet-out={}", new Object[] {sw, pi, pob.build()}); } messageDamper.write(sw, pob.build()); } catch (IOException e) { log.error("Failure writing PacketOut switch={} packet-in={} packet-out={}", new Object[] {sw, pi, pob.build()}, e); } return; }