/** * {@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); }
/** * Create an OFFlowMod that can be passed to StaticEntryPusher. * * @param sw switch object * @param match match for the flow * @param meter meter for the flow * @param actions actions for the flow * @param cookie cookie for the flow * @param priority priority to set on the flow * @return {@link OFFlowMod} */ private OFFlowMod buildFlowMod(final IOFSwitch sw, final Match match, final OFInstructionMeter meter, final OFInstructionApplyActions actions, final long cookie, final int priority) { OFFlowMod.Builder fmb = sw.getOFFactory().buildFlowAdd(); fmb.setIdleTimeout(FlowModUtils.INFINITE_TIMEOUT); fmb.setHardTimeout(FlowModUtils.INFINITE_TIMEOUT); fmb.setBufferId(OFBufferId.NO_BUFFER); fmb.setCookie(U64.of(cookie)); fmb.setPriority(priority); List<OFInstruction> instructions = new ArrayList<>(2); if (meter != null) { // If no meter then no bandwidth limit instructions.add(meter); } if (actions != null) { // If no instruction then Drops packet instructions.add(actions); } if (match != null) { // If no then match everything fmb.setMatch(match); } return fmb.setInstructions(instructions).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); }
/** * Rewrite match object to use LINC OF optical extensions. * * @param match original match * @return rewritten match */ private Match rewriteMatch(Match match) { Match.Builder mBuilder = factory().buildMatch(); for (MatchField mf : match.getMatchFields()) { if (mf == MatchField.EXP_OCH_SIG_ID) { mBuilder.setExact(MatchField.OCH_SIGID, (CircuitSignalID) match.get(mf)); continue; } if (mf == MatchField.EXP_OCH_SIGTYPE) { mBuilder.setExact(MatchField.OCH_SIGTYPE, (U8) match.get(mf)); continue; } mBuilder.setExact(mf, match.get(mf)); } return mBuilder.build(); }
@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 void sendFlowStatistic() { if (sw.getRole() != RoleState.MASTER) { return; } Match match = sw.factory().buildMatch().build(); //Long statsXid = xidAtomic.getAndIncrement(); OFFlowStatsRequest statsRequest = sw.factory() .buildFlowStatsRequest() .setXid(1127) .setMatch(match) .setOutPort(OFPort.ANY) .setTableId(TableId.ALL) .build(); sw.sendMsg(statsRequest); }
@Override public OFFlowMod buildFlowDel() { Match match = buildMatch(); long cookie = flowRule().id().value(); OFFlowDeleteStrict fm = factory().buildFlowDeleteStrict() .setXid(xid) .setCookie(U64.of(cookie)) .setBufferId(OFBufferId.NO_BUFFER) .setMatch(match) .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM)) .setPriority(flowRule().priority()) .setTableId(TableId.of(flowRule().tableId())) .build(); return fm; }
@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; }
@Override public OFFlowDelete buildFlowDel() { Match match = buildMatch(); long cookie = flowRule().id().value(); OFFlowDelete fm = factory().buildFlowDelete() .setXid(xid) .setCookie(U64.of(cookie)) .setBufferId(OFBufferId.NO_BUFFER) .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(); }
protected Match createMatchFromPacket(IOFSwitch sw, OFPort inPort, FloodlightContext cntx) { // The packet in match will only contain the port number. // We need to add in specifics for the hosts we're routing between. Ethernet eth = IFloodlightProviderService.bcStore.get(cntx, IFloodlightProviderService.CONTEXT_PI_PAYLOAD); VlanVid vlan = VlanVid.ofVlan(eth.getVlanID()); MacAddress srcMac = eth.getSourceMACAddress(); MacAddress dstMac = eth.getDestinationMACAddress(); Match.Builder mb = sw.getOFFactory().buildMatch(); mb.setExact(MatchField.IN_PORT, inPort) .setExact(MatchField.ETH_SRC, srcMac) .setExact(MatchField.ETH_DST, dstMac); if (!vlan.equals(VlanVid.ZERO)) { mb.setExact(MatchField.VLAN_VID, OFVlanVidMatch.ofVlanVid(vlan)); } return mb.build(); }
/** * Create a point-to-point match for two devices at the IP layer. * Takes an existing match (e.g. from a PACKET_IN), and masks all * MatchFields leaving behind: * IN_PORT * VLAN_VID * ETH_TYPE * ETH_SRC * ETH_DST * IPV4_SRC * IPV4_DST * IP_PROTO (might remove this) * * If one of the above MatchFields is wildcarded in Match m, * that MatchField will be wildcarded in the returned Match. * * @param m The match to remove all L4+ MatchFields from * @return A new Match object with all MatchFields masked/wildcared * except for those listed above. */ @SuppressWarnings({ "rawtypes", "unchecked" }) public static Match maskL4AndUp(Match m) { Match.Builder mb = m.createBuilder(); Iterator<MatchField<?>> itr = m.getMatchFields().iterator(); // only get exact or masked fields (not fully wildcarded) while(itr.hasNext()) { MatchField mf = itr.next(); // restrict MatchFields only to L3 and below: IN_PORT, ETH_TYPE, ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_PROTO (this one debatable...) // if a MatchField is not in the access list below, it will not be set --> it will be left wildcarded (default) if (mf.equals(MatchField.IN_PORT) || mf.equals(MatchField.ETH_TYPE) || mf.equals(MatchField.ETH_SRC) || mf.equals(MatchField.ETH_DST) || mf.equals(MatchField.IPV4_SRC) || mf.equals(MatchField.IPV4_DST) || mf.equals(MatchField.IP_PROTO)) { if (m.isExact(mf)) { mb.setExact(mf, m.get(mf)); } else if (m.isPartiallyMasked(mf)) { mb.setMasked(mf, m.getMasked(mf)); } else { // it's either exact, masked, or wildcarded // itr only contains exact and masked MatchFields // we should never get here } } } return mb.build(); }
/** * Examine all the MatchFields in a Match object and pick out * the MatchFields that are not supported by OF-DPA. * * @param m * @return */ public static List<MatchFields> checkMatchFields(Match m) { List<MatchFields> unsupported = null; Iterator<MatchField<?>> mfi = m.getMatchFields().iterator(); while (mfi.hasNext()) { MatchField<?> mf = mfi.next(); if (!getSupportedMatchFields().contains(mf.id)) { if (unsupported == null) { unsupported = new ArrayList<MatchFields>(); } unsupported.add(mf.id); } } return unsupported; }
@Override public net.floodlightcontroller.core.IListener.Command receive( IOFSwitch sw, OFMessage msg, FloodlightContext cntx) { System.out.println("flow expired: "+sw.toString() + msg.toString()); //OFFlowRemoved flowRemoved = (OFFlowRemoved) msg; if (!switchStates.containsKey(sw)) switchStates.put(sw, new ObfuscationSwitchState(sw)); if (msg.getType() == OFType.FLOW_REMOVED) { OFFlowRemoved flowRemoved = (OFFlowRemoved) msg; System.out.println("flow expired: "+sw.toString() + "dst: " + flowRemoved.getCookie()); long dst = flowRemoved.getCookie().getValue(); ObfuscationHeader oHeader = new ObfuscationHeader(); Match match = flowRemoved.getMatch(); switchStates.get(sw).removeDestinationID(dst); } return Command.CONTINUE; }
/** * Create a point-to-point match for two devices at the IP layer. * Takes an existing match (e.g. from a PACKET_IN), and masks all * MatchFields leaving behind: * IN_PORT * VLAN_VID * ETH_TYPE * ETH_SRC * ETH_DST * IPV4_SRC * IPV4_DST * IP_PROTO (might remove this) * * If one of the above MatchFields is wildcarded in Match m, * that MatchField will be wildcarded in the returned Match. * * @param m The match to remove all L4+ MatchFields from * @return A new Match object with all MatchFields masked/wildcared * except for those listed above. */ @SuppressWarnings({ "rawtypes", "unchecked" }) public static Match maskL4AndUp(Match m) { Match.Builder mb = m.createBuilder(); Iterator<MatchField<?>> itr = m.getMatchFields().iterator(); // only get exact or masked fields (not fully wildcarded) while(itr.hasNext()) { MatchField mf = itr.next(); // restrict MatchFields only to L3 and below: IN_PORT, ETH_TYPE, ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_PROTO (this one debatable...) // if a MatchField is not in the access list below, it will not be set --> it will be left wildcarded (default) if (mf.equals(MatchField.IN_PORT) || mf.equals(MatchField.ETH_TYPE) || mf.equals(MatchField.ETH_SRC) || mf.equals(MatchField.ETH_DST) || mf.equals(MatchField.IPV4_SRC) || mf.equals(MatchField.IPV4_DST) || mf.equals(MatchField.IP_PROTO)) { if (m.isExact(mf)) { mb.setExact(mf, m.get(mf)); } else if (m.isPartiallyMasked(mf)) { //mb.setMasked(mf, m.getMasked(mf)); ;//SXT------ } else { // it's either exact, masked, or wildcarded // itr only contains exact and masked MatchFields // we should never get here } } } return mb.build(); }
private Map<String, Object> buildFlowMatch(final Match match) { Map<String, Object> data = new HashMap<>(); for (MatchField field : match.getMatchFields()) { data.put(field.getName(), field.getPrerequisites()); } return data; }
/** * {@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); }
/** * Creates a Match based on an inputPort and VlanID. * NB1: that this match only matches on the outer most tag which must be of ether-type 0x8100. * NB2: vlanId of 0 means match on port, not vlan * * @param sw switch object * @param inputPort input port for the match * @param vlanId vlanID to match on; 0 means match on port * @return {@link Match} */ private Match matchFlow(final IOFSwitch sw, final int inputPort, final int vlanId) { Match.Builder mb = sw.getOFFactory().buildMatch(); // // Extra emphasis: vlan of 0 means match on port on not VLAN. // if (vlanId > 0) { mb.setExact(MatchField.IN_PORT, OFPort.of(inputPort)) .setExact(MatchField.VLAN_VID, OFVlanVidMatch.ofVlan(vlanId)); } else { mb.setExact(MatchField.IN_PORT, OFPort.of(inputPort)); } return mb.build(); }
/** * Create a match object for the verification packets * * @param sw siwtch object * @param isBroadcast if broadcast then set a generic match; else specific to switch Id * @return {@link Match} */ private Match matchVerification(final IOFSwitch sw, final boolean isBroadcast) { MacAddress dstMac = MacAddress.of(VERIFICATION_BCAST_PACKET_DST); if (!isBroadcast) { dstMac = dpidToMac(sw); } Match.Builder mb = sw.getOFFactory().buildMatch(); mb.setExact(MatchField.ETH_DST, dstMac); return mb.build(); }
@Before public void setUp() throws Exception { super.setUp(); OFPacketOut packetOut = pvs.generateVerificationPacket(sw1, OFPort.of(1)); ofPacketIn = EasyMock.createMock(OFPacketIn.class); context = new FloodlightContext(); expect(ofPacketIn.getType()).andReturn(OFType.PACKET_IN).anyTimes(); expect(ofPacketIn.getXid()).andReturn(0L).anyTimes(); expect(ofPacketIn.getVersion()).andReturn(packetOut.getVersion()).anyTimes(); Match match = EasyMock.createMock(Match.class); expect(match.get(MatchField.IN_PORT)).andReturn(OFPort.of(1)).anyTimes(); replay(match); expect(ofPacketIn.getMatch()).andReturn(match).anyTimes(); replay(ofPacketIn); IPacket expected = new Ethernet().deserialize(packetOut.getData(), 0, packetOut.getData().length); context.getStorage().put(IFloodlightProviderService.CONTEXT_PI_PAYLOAD, expected); HashMap<DatapathId, IOFSwitch> switches = new HashMap<>(); switches.put(sw1.getId(), sw1); switches.put(sw2.getId(), sw2); mockSwitchManager.setSwitches(switches); reset(producer); pvs.setKafkaProducer(producer); }
private void sendAggregateStatistic() { if (sw.getRole() != RoleState.MASTER) { return; } Match match = sw.factory().buildMatch().build(); //Long statsXid = xidAtomic.getAndIncrement(); OFAggregateStatsRequest statsRequest = sw.factory().buildAggregateStatsRequest() .setMatch(match) .setOutPort(OFPort.ANY) .setTableId(TableId.ALL) .setXid(1126) .build(); sw.sendMsg(statsRequest); }
private void ofFlowStatsRequestFlowSend(FlowEntry fe) { // set find match Match match = FlowModBuilder.builder(fe, sw.factory(), Optional.empty(), Optional.of(driverService)).buildMatch(); // set find tableId TableId tableId = TableId.of(fe.tableId()); // set output port Instruction ins = fe.treatment().allInstructions().stream() .filter(i -> (i.type() == Instruction.Type.OUTPUT)) .findFirst() .orElse(null); OFPort ofPort = OFPort.NO_MASK; if (ins != null) { Instructions.OutputInstruction out = (Instructions.OutputInstruction) ins; ofPort = OFPort.of((int) ((out.port().toLong()))); } OFFlowStatsRequest request = sw.factory().buildFlowStatsRequest() .setMatch(match) .setTableId(tableId) .setOutPort(ofPort) .build(); synchronized (this) { if (getFlowMissingXid() != NO_FLOW_MISSING_XID) { log.debug("ofFlowStatsRequestFlowSend: previous FlowStatsRequestAll does not be processed yet," + " set no flow missing xid anyway, for {}", sw.getStringId()); setFlowMissingXid(NO_FLOW_MISSING_XID); } sw.sendMsg(request); } }
private MATCH_COMPARE_RESULT matchCommonComparators(Alias a, Alias b){ Match matchA = a.getMatch(); Match matchB = b.getMatch(); MATCH_COMPARE_RESULT result = MATCH_COMPARE_RESULT.EQUAL; //match IP Protocol result = matchExact(matchA.get(MatchField.IP_PROTO), matchB.get(MatchField.IP_PROTO)); if (result == MATCH_COMPARE_RESULT.NONEQUAL){ return result; } //match Ethernet type result = matchExact(matchA.get(MatchField.ETH_TYPE), matchB.get(MatchField.ETH_TYPE)); if (result == MATCH_COMPARE_RESULT.NONEQUAL){ return result; } //match VLAN ID result = matchExact(matchA.get(MatchField.VLAN_VID), matchB.get(MatchField.VLAN_VID)); if (result == MATCH_COMPARE_RESULT.NONEQUAL){ return result; } //match Incoming Port result = matchExact(matchA.get(MatchField.IN_PORT), matchB.get(MatchField.IN_PORT)); if (result == MATCH_COMPARE_RESULT.NONEQUAL){ return result; } return result; }
private MATCH_COMPARE_RESULT matchSrcComparators(Alias a, Alias b){ Match matchA = a.getMatch(); Match matchB = b.getMatch(); MATCH_COMPARE_RESULT result = MATCH_COMPARE_RESULT.EQUAL; //match source MAC result = matchExact(matchA.get(MatchField.ETH_SRC), matchB.get(MatchField.ETH_SRC)); if (result == MATCH_COMPARE_RESULT.NONEQUAL){ return result; } //match source IP result = matchExact(matchA.get(MatchField.IPV4_SRC), matchB.get(MatchField.IPV4_SRC)); if (result == MATCH_COMPARE_RESULT.NONEQUAL){ return result; } //match source Port Number result = matchExact(matchA.get(MatchField.TCP_SRC), matchB.get(MatchField.TCP_SRC)); if (result == MATCH_COMPARE_RESULT.SKIP){ result = matchExact(matchA.get(MatchField.UDP_SRC), matchB.get(MatchField.UDP_SRC)); } if (result == MATCH_COMPARE_RESULT.NONEQUAL){ return result; } return result; }
private MATCH_COMPARE_RESULT matchDstComparators(Alias a, Alias b){ Match matchA = a.getMatch(); Match matchB = b.getMatch(); MATCH_COMPARE_RESULT result = MATCH_COMPARE_RESULT.EQUAL; //match destination MAC result = matchExact(matchA.get(MatchField.ETH_DST), matchB.get(MatchField.ETH_DST)); if (result == MATCH_COMPARE_RESULT.NONEQUAL){ return result; } //match destination IP result = matchExact(matchA.get(MatchField.IPV4_DST), matchB.get(MatchField.IPV4_DST)); if (result == MATCH_COMPARE_RESULT.NONEQUAL){ return result; } //match destination Port Number result = matchExact(matchA.get(MatchField.TCP_DST), matchB.get(MatchField.TCP_DST)); if (result == MATCH_COMPARE_RESULT.SKIP){ result = matchExact(matchA.get(MatchField.UDP_DST), matchB.get(MatchField.UDP_DST)); } if (result == MATCH_COMPARE_RESULT.NONEQUAL){ return result; } return result; }
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(); } } }
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); } }
/** * Processes a flow removed message. We will delete the learned MAC/VLAN mapping from * the switch's table. * @param sw The switch that sent the flow removed message. * @param flowRemovedMessage The flow removed message. * @return Whether to continue processing this message or stop. */ private Command processFlowRemovedMessage(IOFSwitch sw, OFFlowRemoved flowRemovedMessage) { if (!flowRemovedMessage.getCookie().equals(U64.of(LearningSwitch.LEARNING_SWITCH_COOKIE))) { return Command.CONTINUE; } if (log.isTraceEnabled()) { log.trace("{} flow entry removed {}", sw, flowRemovedMessage); } Match match = flowRemovedMessage.getMatch(); // When a flow entry expires, it means the device with the matching source // MAC address and VLAN either stopped sending packets or moved to a different // port. If the device moved, we can't know where it went until it sends // another packet, allowing us to re-learn its port. Meanwhile we remove // it from the macVlanToPortMap to revert to flooding packets to this device. this.removeFromPortMap(sw, match.get(MatchField.ETH_SRC), match.get(MatchField.VLAN_VID) == null ? VlanVid.ZERO : match.get(MatchField.VLAN_VID).getVlanVid()); // Also, if packets keep coming from another device (e.g. from ping), the // corresponding reverse flow entry will never expire on its own and will // send the packets to the wrong port (the matching input port of the // expired flow entry), so we must delete the reverse entry explicitly. Match.Builder mb = sw.getOFFactory().buildMatch(); mb.setExact(MatchField.ETH_SRC, match.get(MatchField.ETH_DST)) .setExact(MatchField.ETH_DST, match.get(MatchField.ETH_SRC)); if (match.get(MatchField.VLAN_VID) != null) { mb.setExact(MatchField.VLAN_VID, match.get(MatchField.VLAN_VID)); } this.writeFlowMod(sw, OFFlowModCommand.DELETE, OFBufferId.NO_BUFFER, mb.build(), match.get(MatchField.IN_PORT)); return Command.CONTINUE; }
@Override public void topologyChanged(List<LDUpdate> appliedUpdates) { for (LDUpdate ldu : appliedUpdates) { if (ldu.getOperation() .equals(ILinkDiscovery.UpdateOperation.PORT_DOWN)) { // Get the switch ID for the OFMatchWithSwDpid object IOFSwitch affectedSwitch = switchService.getSwitch(ldu.getSrc()); // Create an OFMatchReconcile object OFMatchReconcile ofmr = new OFMatchReconcile(); // Generate an OFMatch objects for the OFMatchWithSwDpid object Match match = affectedSwitch.getOFFactory().buildMatch().build(); // nothing specific set, so all wildcarded // Generate the OFMatchWithSwDpid OFMatchWithSwDpid ofmatchsw = new OFMatchWithSwDpid(match, affectedSwitch.getId()); // Set the action to update the path to remove flows routing // towards the downed port ofmr.rcAction = OFMatchReconcile.ReconcileAction.UPDATE_PATH; // Set the match, with the switch dpid ofmr.ofmWithSwDpid = ofmatchsw; // Assign the downed port to the OFMatchReconcile's outPort data // member (I added this to // the OFMatchReconcile class) ofmr.outPort = ldu.getSrcPort(); // Tell the reconcile manager to reconcile matching flows frm.reconcileFlow(ofmr, EventPriority.HIGH); } } }
/** * @param sw * The switch we wish to remove flows from * @param outPort * The specific Output Action OutPort of specific flows we wish * to delete */ public void clearFlowMods(IOFSwitch sw, OFPort outPort) { // Delete all pre-existing flows with the same output action port or // outPort Match match = sw.getOFFactory().buildMatch().build(); OFFlowDelete fm = sw.getOFFactory().buildFlowDelete() .setMatch(match) .setOutPort(outPort) .build(); try { sw.write(fm); } catch (Exception e) { log.error("Failed to clear flows on switch {} - {}", this, e); } }
/** * @param sw * The switch we wish to remove flows from * @param match * The specific OFMatch object of specific flows we wish to * delete * @param outPort * The specific Output Action OutPort of specific flows we wish * to delete */ public void clearFlowMods(IOFSwitch sw, Match match, OFPort outPort) { // Delete pre-existing flows with the same match, and output action port // or outPort OFFlowDelete fm = sw.getOFFactory().buildFlowDelete() .setMatch(match) .setOutPort(outPort) .build(); try { sw.write(fm); } catch (Exception e) { log.error("Failed to clear flows on switch {} - {}", this, e); } }