@Override public FlowEntry matches(long dpid, short inputPort, byte[] packetData) { OFMatch m = new OFMatch(); m.loadFromPacket(packetData, inputPort); List<FlowEntry> list = matches(dpid, m); // if we match more than one thing, return the highest priority if (list.size() > 0) return list.get(0); return null; }
@LogMessageDocs({ @LogMessageDoc( level = "ERROR", message = "Failure writing deny flow mod", explanation = "An I/O error occurred while writing a " + "deny flow mod to a switch", recommendation = LogMessageDoc.CHECK_SWITCH) }) public static boolean blockHost( IFloodlightProviderService floodlightProvider, SwitchPort sw_tup, long host_mac, short hardTimeout, long cookie) { if (sw_tup == null) { return false; } IOFSwitch sw = floodlightProvider.getSwitches().get(sw_tup.getSwitchDPID()); if (sw == null) return false; int inputPort = sw_tup.getPort(); log.debug( "blockHost sw={} port={} mac={}", new Object[] {sw, sw_tup.getPort(), new Long(host_mac)}); // Create flow-mod based on packet-in and src-switch OFFlowMod fm = (OFFlowMod) floodlightProvider.getOFMessageFactory().getMessage(OFType.FLOW_MOD); OFMatch match = new OFMatch(); List<OFAction> actions = new ArrayList<OFAction>(); // Set no action to // drop match .setDataLayerSource(Ethernet.toByteArray(host_mac)) .setInputPort((short) inputPort) .setWildcards(OFMatch.OFPFW_ALL & ~OFMatch.OFPFW_DL_SRC & ~OFMatch.OFPFW_IN_PORT); fm.setCookie(cookie) .setHardTimeout(hardTimeout) .setIdleTimeout(FLOWMOD_DEFAULT_IDLE_TIMEOUT) .setHardTimeout(FLOWMOD_DEFAULT_HARD_TIMEOUT) .setBufferId(OFPacketOut.BUFFER_ID_NONE) .setMatch(match) .setActions(actions) .setLengthU(OFFlowMod.MINIMUM_LENGTH); // +OFActionOutput.MINIMUM_LENGTH); try { log.debug("write drop flow-mod sw={} match={} flow-mod={}", new Object[] {sw, match, fm}); // TODO: can't use the message damper sine this method is static sw.write(fm, null); } catch (IOException e) { log.error("Failure writing deny flow mod", e); return false; } return true; }
/** * Tell the classifier to drop packets that look like this * * @param fvClassifier * @param flowEntry * @param hardTimeout * @param idleTimeout */ private void sendDropRule( FVClassifier fvClassifier, FlowEntry flowEntry, String sliceName, short hardTimeout, short idleTimeout) { FVFlowMod flowMod = (FVFlowMod) FlowVisor.getInstance().getFactory().getMessage(OFType.FLOW_MOD); // block this exact flow OFMatch match = new OFMatch(); match.loadFromPacket(this.packetData, this.inPort); // different from previous policty of block by rule // flowMod.setMatch(flowEntry.getRuleMatch()); String drop_policy = null; try { drop_policy = FVConfig.getDropPolicy(sliceName); } catch (ConfigError e) { FVLog.log( LogLevel.ALERT, fvClassifier, "Failed to retrieve drop policy from config." + "\nDefauting to exact drop_policy"); drop_policy = "exact"; } if (drop_policy.equals("exact")) flowMod.setMatch(match); else if (drop_policy.equals("rule")) flowMod.setMatch(flowEntry.getRuleMatch()); else // Should never happen FVLog.log(LogLevel.CRIT, fvClassifier, "Error in configuration!"); flowMod.setCommand(FVFlowMod.OFPFC_ADD); flowMod.setActions(new LinkedList<OFAction>()); // send to zero-length // list, i.e., DROP flowMod.setLengthU(OFFlowMod.MINIMUM_LENGTH); flowMod.setHardTimeout(hardTimeout); flowMod.setIdleTimeout(idleTimeout); flowMod.setPriority((short) 0); // set to lowest priority flowMod.setFlags((short) 1); // send removed msg (1), not the check overlap (2), or // emergency flow cache (4) FVLog.log( LogLevel.WARN, fvClassifier, "inserting drop (hard=" + hardTimeout + ",idle=" + idleTimeout + ") rule for " + flowEntry); fvClassifier.sendMsg(flowMod, fvClassifier); }
/** * Event handler called when a switch leaves the network. * * @param DPID for the switch */ @Override public void switchRemoved(long switchId) { IOFSwitch sw = this.floodlightProv.getSwitch(switchId); log.info(String.format("Switch s%d removed", switchId)); /** ****************************************************************** */ /* TODO: Update routing: change routing rules for all hosts */ // check for (Host host : this.getHosts()) { OFMatch matchCriteria = new OFMatch(); matchCriteria.setDataLayerType(OFMatch.ETH_TYPE_IPV4); matchCriteria.setNetworkDestination(host.getIPv4Address()); for (IOFSwitch currSw : this.getSwitches().values()) { SwitchCommands.removeRules(currSw, this.table, matchCriteria); } updateAllRouting(); } /** ****************************************************************** */ }
static { FlowMod2 = new OFFlowMod(); TestRule2 = new HashMap<String, Object>(); TestRule2.put(COLUMN_NAME, "TestRule2"); TestRule2.put(COLUMN_SWITCH, TestSwitch1DPID); // setup match OFMatch match = new OFMatch(); TestRule2.put(COLUMN_NW_DST, "192.168.1.0/24"); match.fromString("nw_dst=192.168.1.0/24"); // setup actions List<OFAction> actions = new LinkedList<OFAction>(); TestRule2.put(COLUMN_ACTIONS, "output=1"); actions.add(new OFActionOutput((short) 1, (short) Short.MAX_VALUE)); // done FlowMod2.setMatch(match); FlowMod2.setActions(actions); FlowMod2.setBufferId(-1); FlowMod2.setOutPort(OFPort.OFPP_NONE.getValue()); FlowMod2.setPriority(Short.MAX_VALUE); FlowMod2.setLengthU(OFFlowMod.MINIMUM_LENGTH + 8); // 8 bytes of actions }
/** * Test to check whether the IPs given overlap or not at all * * @param flowIntersect - the current potential intersection * @param maskShift - the shift value (ie. either for a src_ip or a dst_ip). * @param masklenX - the netmask for the first ip. * @param masklenY - the netmask for the second ip. * @param x - the first ip * @param y - the second ip. * @return the smallest intersection of this ip space. */ private int testIP( FlowIntersect flowIntersect, int maskShift, int masklenX, int masklenY, int x, int y) { int min = Math.min(masklenX, masklenY); // get the less specific address int max = Math.max(masklenX, masklenY); // get the more specific address int min_encoded = 32 - min; // because OpenFlow does it backwards... grr int max_encoded = 32 - max; // because OpenFlow does it backwards... grr if (max_encoded >= 32) // set all the bits if this is in fact fully max_encoded = 63; // wildcarded; if only for wireshark's sake int mask; if (min == 0) mask = 0; // nasty work around for stupid signed ints else mask = ~((1 << min_encoded) - 1); // min < 32, so no signed issues // int mask = (1 << min) - 1; if ((x & mask) != (y & mask)) // if these are not in the same CIDR block flowIntersect.setMatchType(MatchType.NONE); // else there is some overlap OFMatch interMatch = flowIntersect.getMatch(); int wildCards = interMatch.getWildcards(); // turn off all bits for this match and then turn on the used ones // use MAX not MIN, because we want the most specific intersection // split into two ops, so we can see intermediate step in debugger // assumes SRC mask == DST mask // turn off all bits for this match (making it an exact match) wildCards = wildCards & ~(((1 << OFMatch.OFPFW_NW_SRC_BITS) - 1) << maskShift); // turn on the bits for the intersection wildCards = wildCards | max_encoded << maskShift; interMatch.setWildcards(wildCards); if (masklenX < masklenY) { flowIntersect.maybeSubset = false; return y; } else if (masklenX > masklenY) { flowIntersect.maybeSuperset = false; return x; } // note that b/c of how CIDR addressing works, there is no overlap that // is not a SUB or SUPERSET return x; // x == y; doesn't matter }
private void installL3FwdRule(IOFSwitch currSw, Host host, int opPortTowardsSrc) { if (debug_level < 2) System.out.println( "L3 Install Rule : sw - " + String.valueOf(currSw.getId()) + " port " + opPortTowardsSrc); OFMatch matchCriteria = new OFMatch(); matchCriteria.setDataLayerType(OFMatch.ETH_TYPE_IPV4); matchCriteria.setNetworkDestination(host.getIPv4Address()); List<OFAction> actionOps = new LinkedList<OFAction>(); OFActionOutput actOp = new OFActionOutput(opPortTowardsSrc); actionOps.add(0, actOp); OFInstructionApplyActions applyActions = new OFInstructionApplyActions(actionOps); List<OFInstruction> instructionList = new ArrayList<OFInstruction>(); instructionList.add(applyActions); SwitchCommands.removeRules(currSw, this.table, matchCriteria); if (SwitchCommands.installRule( currSw, this.table, SwitchCommands.DEFAULT_PRIORITY, matchCriteria, instructionList) == false) { System.out.println( "L3 Rule not installed: sw " + String.valueOf(currSw.getId()) + " port: " + opPortTowardsSrc + " table: " + this.table); } else { if (debug_level < 2) System.out.println( "L3 Rule installed : sw " + String.valueOf(currSw.getId()) + " port: " + opPortTowardsSrc + " table: " + this.table); } }
/** * Event handler called when a host is no longer attached to a switch. * * @param device information about the host */ @Override public void deviceRemoved(IDevice device) { Host host = this.knownHosts.get(device); if (null == host) { return; } this.knownHosts.remove(host); log.info(String.format("Host %s is no longer attached to a switch", host.getName())); /** ****************************************************************** */ /* TODO: Update routing: remove rules to route to host */ OFMatch matchCriteria = new OFMatch(); matchCriteria.setDataLayerType(OFMatch.ETH_TYPE_IPV4); matchCriteria.setNetworkDestination(host.getIPv4Address()); for (IOFSwitch currSw : this.getSwitches().values()) { SwitchCommands.removeRules(currSw, this.table, matchCriteria); } /** ****************************************************************** */ }
@Override protected OFMatch wildcard(OFMatch match, IOFSwitch sw, Integer hints) { // use same wilcarding as the learning switch int wildcards = ((Integer) sw.getAttribute(IOFSwitch.PROP_FASTWILDCARDS)).intValue() & ~OFMatch.OFPFW_IN_PORT & ~OFMatch.OFPFW_DL_VLAN & ~OFMatch.OFPFW_DL_SRC & ~OFMatch.OFPFW_DL_DST & ~OFMatch.OFPFW_NW_SRC_MASK & ~OFMatch.OFPFW_NW_DST_MASK; return match.clone().setWildcards(wildcards); }
static { FlowMod3 = new OFFlowMod(); TestRule3 = new HashMap<String, Object>(); TestRule3.put(COLUMN_NAME, "TestRule3"); TestRule3.put(COLUMN_SWITCH, TestSwitch1DPID); // setup match OFMatch match = new OFMatch(); TestRule3.put(COLUMN_DL_DST, "00:20:30:40:50:60"); TestRule3.put(COLUMN_DL_VLAN, 4096); match.fromString("dl_dst=00:20:30:40:50:60,dl_vlan=4096"); // setup actions TestRule3.put(COLUMN_ACTIONS, "output=controller"); List<OFAction> actions = new LinkedList<OFAction>(); actions.add(new OFActionOutput(OFPort.OFPP_CONTROLLER.getValue(), (short) Short.MAX_VALUE)); // done FlowMod3.setMatch(match); FlowMod3.setActions(actions); FlowMod3.setBufferId(-1); FlowMod3.setOutPort(OFPort.OFPP_NONE.getValue()); FlowMod3.setPriority(Short.MAX_VALUE); FlowMod3.setLengthU(OFFlowMod.MINIMUM_LENGTH + 8); // 8 bytes of actions }
@LogMessageDoc( level = "ERROR", message = "Failure writing drop flow mod", explanation = "An I/O error occured while trying to write a " + "drop flow mod to a switch", recommendation = LogMessageDoc.CHECK_SWITCH) protected void doDropFlow( IOFSwitch sw, OFPacketIn pi, IRoutingDecision decision, FloodlightContext cntx) { // initialize match structure and populate it using the packet OFMatch match = new OFMatch(); match.loadFromPacket(pi.getPacketData(), pi.getInPort()); if (decision.getWildcards() != null) { match.setWildcards(decision.getWildcards()); } // Create flow-mod based on packet-in and src-switch OFFlowMod fm = (OFFlowMod) floodlightProvider.getOFMessageFactory().getMessage(OFType.FLOW_MOD); List<OFAction> actions = new ArrayList<OFAction>(); // Set no action to // drop long cookie = AppCookie.makeCookie(FORWARDING_APP_ID, 0); fm.setCookie(cookie) .setHardTimeout((short) 0) .setIdleTimeout((short) 5) .setBufferId(OFPacketOut.BUFFER_ID_NONE) .setMatch(match) .setActions(actions) .setLengthU(OFFlowMod.MINIMUM_LENGTH); // +OFActionOutput.MINIMUM_LENGTH); try { if (log.isDebugEnabled()) { log.debug("write drop flow-mod sw={} match={} flow-mod={}", new Object[] {sw, match, fm}); } messageDamper.write(sw, fm, cntx); } catch (IOException e) { log.error("Failure writing drop flow mod", e); } }
public FVMatch(OFMatch match) { super(); this.wildcards = match.getWildcards(); inputPort = match.getInputPort(); dataLayerSource = match.getDataLayerSource(); dataLayerDestination = match.getDataLayerDestination(); ; dataLayerVirtualLan = match.getDataLayerVirtualLan(); dataLayerVirtualLanPriorityCodePoint = match.getDataLayerVirtualLanPriorityCodePoint(); dataLayerType = match.getDataLayerType(); networkTypeOfService = match.getNetworkTypeOfService(); networkProtocol = match.getNetworkProtocol(); networkSource = match.getNetworkSource(); networkDestination = match.getNetworkDestination(); transportSource = match.getTransportSource(); transportDestination = match.getTransportDestination(); }
protected void doForwardFlow( IOFSwitch sw, OFPacketIn pi, FloodlightContext cntx, boolean requestFlowRemovedNotifn) { OFMatch match = new OFMatch(); match.loadFromPacket(pi.getPacketData(), pi.getInPort()); // Check if we have the location of the destination IDevice dstDevice = IDeviceService.fcStore.get(cntx, IDeviceService.CONTEXT_DST_DEVICE); if (dstDevice != null) { IDevice srcDevice = IDeviceService.fcStore.get(cntx, IDeviceService.CONTEXT_SRC_DEVICE); Long srcIsland = topology.getL2DomainId(sw.getId()); if (srcDevice == null) { log.debug("No device entry found for source device"); return; } if (srcIsland == null) { log.debug("No openflow island found for source {}/{}", sw.getStringId(), pi.getInPort()); return; } // Validate that we have a destination known on the same island // Validate that the source and destination are not on the same switchport boolean on_same_island = false; boolean on_same_if = false; for (SwitchPort dstDap : dstDevice.getAttachmentPoints()) { long dstSwDpid = dstDap.getSwitchDPID(); Long dstIsland = topology.getL2DomainId(dstSwDpid); if ((dstIsland != null) && dstIsland.equals(srcIsland)) { on_same_island = true; if ((sw.getId() == dstSwDpid) && (pi.getInPort() == dstDap.getPort())) { on_same_if = true; } break; } } if (!on_same_island) { // Flood since we don't know the dst device if (log.isTraceEnabled()) { log.trace( "No first hop island found for destination " + "device {}, Action = flooding", dstDevice); } doFlood(sw, pi, cntx); return; } if (on_same_if) { if (log.isTraceEnabled()) { log.trace( "Both source and destination are on the same " + "switch/port {}/{}, Action = NOP", sw.toString(), pi.getInPort()); } return; } // Install all the routes where both src and dst have attachment // points. Since the lists are stored in sorted order we can // traverse the attachment points in O(m+n) time SwitchPort[] srcDaps = srcDevice.getAttachmentPoints(); Arrays.sort(srcDaps, clusterIdComparator); SwitchPort[] dstDaps = dstDevice.getAttachmentPoints(); Arrays.sort(dstDaps, clusterIdComparator); int iSrcDaps = 0, iDstDaps = 0; while ((iSrcDaps < srcDaps.length) && (iDstDaps < dstDaps.length)) { SwitchPort srcDap = srcDaps[iSrcDaps]; SwitchPort dstDap = dstDaps[iDstDaps]; Long srcCluster = topology.getL2DomainId(srcDap.getSwitchDPID()); Long dstCluster = topology.getL2DomainId(dstDap.getSwitchDPID()); int srcVsDest = srcCluster.compareTo(dstCluster); if (srcVsDest == 0) { if (!srcDap.equals(dstDap) && (srcCluster != null) && (dstCluster != null)) { Route route = routingEngine.getRoute( srcDap.getSwitchDPID(), (short) srcDap.getPort(), dstDap.getSwitchDPID(), (short) dstDap.getPort()); if (route != null) { if (log.isTraceEnabled()) { log.trace( "pushRoute match={} route={} " + "destination={}:{}", new Object[] {match, route, dstDap.getSwitchDPID(), dstDap.getPort()}); } long cookie = AppCookie.makeCookie(FORWARDING_APP_ID, 0); pushRoute( route, match, 0, pi, sw.getId(), cookie, cntx, requestFlowRemovedNotifn, false, OFFlowMod.OFPFC_ADD); } } iSrcDaps++; iDstDaps++; } else if (srcVsDest < 0) { iSrcDaps++; } else { iDstDaps++; } } } else { // Flood since we don't know the dst device doFlood(sw, pi, cntx); } }
protected OFMatch wildcard(OFMatch match, IOFSwitch sw, Integer wildcard_hints) { if (wildcard_hints != null) { return match.clone().setWildcards(wildcard_hints.intValue()); } return match.clone(); }
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; }
protected void doForwardFlow(IOFSwitch sw, OFPacketIn pi, FloodlightContext cntx) { // Setup fields for our packets OFMatch match = new OFMatch(); match.loadFromPacket(pi.getPacketData(), pi.getInPort()); // Check if we have the location of the destination IDevice dstDevice = IDeviceService.fcStore.get(cntx, IDeviceService.CONTEXT_DST_DEVICE); if (dstDevice != null) { IDevice srcDevice = IDeviceService.fcStore.get(cntx, IDeviceService.CONTEXT_SRC_DEVICE); Long srcIsland = topology.getL2DomainId(sw.getId()); if (srcDevice == null) { log.debug("No device entry found for source device"); return; } if (srcIsland == null) { log.debug("No openflow island found for source {}/{}", sw.getStringId(), pi.getInPort()); return; } // Validate that we have a destination known on the same // island // Validate that the source and destination are not on // the same switchport boolean on_same_island = false; boolean on_same_if = false; for (SwitchPort dstDap : dstDevice.getAttachmentPoints()) { long dstSwDpid = dstDap.getSwitchDPID(); Long dstIsland = topology.getL2DomainId(dstSwDpid); if ((dstIsland != null) && dstIsland.equals(srcIsland)) { on_same_island = true; if ((sw.getId() == dstSwDpid) && (pi.getInPort() == dstDap.getPort())) { on_same_if = true; } break; } } if (!on_same_island) { // Flood since we don't know the dst device if (log.isTraceEnabled()) { log.trace( "No first hop island found for destination " + "device {}, Action = flooding", dstDevice); } doFlood(sw, pi, cntx); return; } if (on_same_if) { if (log.isTraceEnabled()) { log.trace( "Both source and destination are on the same " + "switch/port {}/{}, Action = NOP", sw.toString(), pi.getInPort()); } return; } // Install all the routes where both src and dst have // attachment // points. Since the lists are stored in sorted order we // can // traverse the attachment points in O(m+n) time SwitchPort[] srcDaps = srcDevice.getAttachmentPoints(); Arrays.sort(srcDaps, clusterIdComparator); SwitchPort[] dstDaps = dstDevice.getAttachmentPoints(); Arrays.sort(dstDaps, clusterIdComparator); int iSrcDaps = 0, iDstDaps = 0; while ((iSrcDaps < srcDaps.length) && (iDstDaps < dstDaps.length)) { SwitchPort srcDap = srcDaps[iSrcDaps]; SwitchPort dstDap = dstDaps[iDstDaps]; Long srcCluster = topology.getL2DomainId(srcDap.getSwitchDPID()); Long dstCluster = topology.getL2DomainId(dstDap.getSwitchDPID()); int srcVsDest = srcCluster.compareTo(dstCluster); if (srcVsDest == 0) { if (!srcDap.equals(dstDap) && (srcCluster != null) && (dstCluster != null)) { // TODO: INSERT DIJKSTRA HERE FOR OUR VIDEO FLOWS // AND CALCULATE FLOWS // Call getroute also with weights!! Route route = getRoute( srcDap.getSwitchDPID(), (short) srcDap.getPort(), dstDap.getSwitchDPID(), (short) dstDap.getPort()); if (route != null) { if (log.isTraceEnabled()) { log.trace( "pushRoute match={} route={} " + "destination={}:{}", new Object[] {match, route, dstDap.getSwitchDPID(), dstDap.getPort()}); } long cookie = AppCookie.makeCookie(FORWARDING_APP_ID, 0); // if there is prior routing decision // use wildcard Integer wildcard_hints = null; IRoutingDecision decision = null; if (cntx != null) { decision = IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION); } if (decision != null) { wildcard_hints = decision.getWildcards(); } else { // L2 only wildcard if there is no // prior route decision wildcard_hints = ((Integer) sw.getAttribute(IOFSwitch.PROP_FASTWILDCARDS)).intValue() & ~OFMatch.OFPFW_IN_PORT & ~OFMatch.OFPFW_DL_VLAN & ~OFMatch.OFPFW_DL_SRC & ~OFMatch.OFPFW_DL_DST & ~OFMatch.OFPFW_NW_SRC_MASK & ~OFMatch.OFPFW_NW_DST_MASK; } pushRoute( route, match, wildcard_hints, pi, sw.getId(), cookie, cntx, false, false, OFFlowMod.OFPFC_ADD); } } iSrcDaps++; iDstDaps++; } else if (srcVsDest < 0) { iSrcDaps++; } else { iDstDaps++; } } } else { // Flood since we don't know the dst device doFlood(sw, pi, cntx); } }
@Override public void addedSwitch(IOFSwitch sw) { /** * 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 */ OFFlowMod flow = new OFFlowMod(); OFMatch match = new OFMatch(); ArrayList<OFAction> actionList = new ArrayList<OFAction>(); OFActionOutput action = new OFActionOutput(); String flowName; if (sw.getStringId().equals(ROOT_NODE_WIFI_OVS_DPID)) { // root node, WiFi bridge, patch to tunnel port flow = new OFFlowMod(); match = new OFMatch(); match.setInputPort(ROOT_NODE_WIFI_OVS_PATCH); action.setType(OFActionType.OUTPUT); action.setPort(ROOT_NODE_WIFI_OVS_TUNNEL); action.setLength((short) OFActionOutput.MINIMUM_LENGTH); actionList.add(action); flow.setCookie(0); flow.setBufferId(-1); flow.setOutPort(ROOT_NODE_WIFI_OVS_TUNNEL); flow.setActions(actionList); flow.setMatch(match); flow.setPriority(PRIORITY_HIGH); flow.setLengthU(OFFlowMod.MINIMUM_LENGTH + action.getLengthU()); flowName = "root-node-wifi-br-patch-tun"; sfp.addFlow(flowName, flow, sw.getStringId()); log.info("added flow on SW " + sw.getStringId() + flowName); actionList.clear(); // root node, WiFi bridge, physical to patch flow = new OFFlowMod(); match = new OFMatch(); match.setInputPort(ROOT_NODE_WIFI_OVS_TUNNEL); action.setType(OFActionType.OUTPUT); action.setPort(ROOT_NODE_WIFI_OVS_PATCH); action.setLength((short) OFActionOutput.MINIMUM_LENGTH); actionList.add(action); flow.setCookie(0); flow.setBufferId(-1); flow.setOutPort(ROOT_NODE_WIFI_OVS_PATCH); flow.setActions(actionList); flow.setMatch(match); flow.setPriority(PRIORITY_HIGH); flow.setLengthU(OFFlowMod.MINIMUM_LENGTH + action.getLengthU()); flowName = "root-node-wifi-br-tun-patch"; sfp.addFlow(flowName, flow, sw.getStringId()); log.info("added flow on SW " + sw.getStringId() + flowName); actionList.clear(); } else if (sw.getStringId().equals(ROOT_NODE_WIMAX_OVS_DPID)) { // root node, WiMAX bridge, patch to physical flow = new OFFlowMod(); match = new OFMatch(); match.setInputPort(ROOT_NODE_WIMAX_OVS_PATCH); action.setType(OFActionType.OUTPUT); action.setPort(ROOT_NODE_WIMAX_OVS_VLAN); action.setLength((short) OFActionOutput.MINIMUM_LENGTH); actionList.add(action); flow.setCookie(0); flow.setBufferId(-1); flow.setOutPort(ROOT_NODE_WIMAX_OVS_VLAN); flow.setActions(actionList); flow.setMatch(match); flow.setPriority(PRIORITY_HIGH); flow.setLengthU(OFFlowMod.MINIMUM_LENGTH + action.getLengthU()); flowName = "root-node-wimax-br-patch-phys"; sfp.addFlow(flowName, flow, sw.getStringId()); log.info("added flow on SW " + sw.getStringId() + flowName); actionList.clear(); // root node, WiMAX bridge, interface to patch flow = new OFFlowMod(); match = new OFMatch(); match.setInputPort(ROOT_NODE_WIMAX_OVS_VLAN); action.setType(OFActionType.OUTPUT); action.setPort(ROOT_NODE_WIMAX_OVS_PATCH); action.setLength((short) OFActionOutput.MINIMUM_LENGTH); actionList.add(action); flow.setCookie(0); flow.setBufferId(-1); flow.setOutPort(ROOT_NODE_WIMAX_OVS_PATCH); flow.setActions(actionList); flow.setMatch(match); flow.setPriority(PRIORITY_HIGH); flow.setLengthU(OFFlowMod.MINIMUM_LENGTH + action.getLengthU()); flowName = "root-node-wimax-br-phys-patch"; sfp.addFlow(flowName, flow, sw.getStringId()); log.info("added flow on SW " + sw.getStringId() + flowName); actionList.clear(); // root node, WiMAX bridge, DHCP on physical match.setInputPort(ROOT_NODE_WIMAX_OVS_VLAN); match.setDataLayerType(Ethernet.TYPE_IPv4); match.setNetworkProtocol(IPv4.PROTOCOL_UDP); match.setTransportSource(UDP.DHCP_CLIENT_PORT); action.setType(OFActionType.OUTPUT); action.setLength((short) OFActionOutput.MINIMUM_LENGTH); action.setPort(OFPort.OFPP_CONTROLLER.getValue()); actionList.add(action); flow.setCookie(0); flow.setBufferId(-1); flow.setOutPort(OFPort.OFPP_CONTROLLER.getValue()); flow.setActions(actionList); flow.setMatch(match); flow.setPriority(PRIORITY_MAX); flow.setLengthU(OFFlowMod.MINIMUM_LENGTH + action.getLengthU()); flowName = "root-node-wimax-br-DHCP-phys"; sfp.addFlow(flowName, flow, sw.getStringId()); log.info("added flow on SW " + sw.getStringId() + flowName); actionList.clear(); } else if (sw.getStringId().equals(ROOT_NODE_ROOT_OVS_DPID)) { // root node, root bridge, patch AP3 (WiFi) to Linux flow = new OFFlowMod(); match = new OFMatch(); match.setInputPort(ROOT_NODE_ROOT_OVS_WIFI_PATCH); action.setType(OFActionType.OUTPUT); action.setPort(OFPort.OFPP_LOCAL.getValue()); action.setLength((short) OFActionOutput.MINIMUM_LENGTH); actionList.add(action); flow.setCookie(0); flow.setBufferId(-1); flow.setOutPort(OFPort.OFPP_LOCAL.getValue()); flow.setActions(actionList); flow.setMatch(match); flow.setPriority(PRIORITY_HIGH); flow.setLengthU(OFFlowMod.MINIMUM_LENGTH + action.getLengthU()); flowName = "root-node-root-br-patchWiFi-linux"; sfp.addFlow(flowName, flow, sw.getStringId()); log.info("added flow on SW " + sw.getStringId() + flowName); actionList.clear(); // root node, root bridge, patch WiMAX to Linux flow = new OFFlowMod(); match = new OFMatch(); match.setInputPort(ROOT_NODE_ROOT_OVS_WIMAX_PATCH); action.setType(OFActionType.OUTPUT); action.setPort(OFPort.OFPP_LOCAL.getValue()); action.setLength((short) OFActionOutput.MINIMUM_LENGTH); actionList.add(action); flow.setCookie(0); flow.setBufferId(-1); flow.setOutPort(OFPort.OFPP_LOCAL.getValue()); flow.setActions(actionList); flow.setMatch(match); flow.setPriority(PRIORITY_HIGH); flow.setLengthU(OFFlowMod.MINIMUM_LENGTH + action.getLengthU()); flowName = "root-node-root-br-patchWiMAX-linux"; sfp.addFlow(flowName, flow, sw.getStringId()); log.info("added flow on SW " + sw.getStringId() + flowName); actionList.clear(); // root node, root bridge, physical to Linux // flow = new OFFlowMod(); // match = new OFMatch(); // match.setInputPort((short) 1); // action.setType(OFActionType.OUTPUT); // action.setPort(OFPort.OFPP_LOCAL.getValue()); // action.setLength((short) OFActionOutput.MINIMUM_LENGTH); // actionList.add(action); // flow.setCookie(0); // flow.setBufferId(-1); // flow.setOutPort(OFPort.OFPP_LOCAL.getValue()); // flow.setActions(actionList); // flow.setMatch(match); // flow.setPriority(PRIORITY_HIGH); // flow.setLengthU(OFFlowMod.MINIMUM_LENGTH + action.getLengthU()); // flowName = "root-ovs-root-br-phys-linux"; // sfp.addFlow(flowName, flow, sw.getStringId()); // log.info("added flow on SW " + sw.getStringId() + flowName); // actionList.clear(); // root node, root bridge, Linux to physical (match extra: src-ip of root node...i.e. it's // outbound) // flow = new OFFlowMod(); // match = new OFMatch(); // match.setInputPort(OFPort.OFPP_LOCAL.getValue()); // match.setDataLayerType(Ethernet.TYPE_IPv4); // ... IP packets ... required for a match on // an IP address // match.setNetworkSource(ROOT_NODE_ROOT_OVS_IP); // action.setType(OFActionType.OUTPUT); // action.setPort((short) 1); // action.setLength((short) OFActionOutput.MINIMUM_LENGTH); // actionList.add(action); // flow.setCookie(0); // flow.setBufferId(-1); // flow.setOutPort((short) 1); // flow.setActions(actionList); // flow.setMatch(match); // flow.setPriority(PRIORITY_HIGH); // flow.setLengthU(OFFlowMod.MINIMUM_LENGTH + action.getLengthU()); // flowName = "root-ovs-root-br-linux-phys-egress"; // sfp.addFlow(flowName, flow, sw.getStringId()); // log.info("added flow on SW " + sw.getStringId() + flowName); // actionList.clear(); } else if (sw.getStringId().equals(WIFI_NODE_WIFI_OVS_DPID)) { // WiFi node, WiFi bridge, physical to patch flow = new OFFlowMod(); match = new OFMatch(); match.setInputPort((short) 1); action.setType(OFActionType.OUTPUT); action.setPort(WIFI_NODE_WIFI_OVS_PATCH); action.setLength((short) OFActionOutput.MINIMUM_LENGTH); actionList.add(action); flow.setCookie(0); flow.setBufferId(-1); flow.setOutPort(WIFI_NODE_WIFI_OVS_PATCH); flow.setActions(actionList); flow.setMatch(match); flow.setPriority(PRIORITY_HIGH); flow.setLengthU(OFFlowMod.MINIMUM_LENGTH + action.getLengthU()); flowName = "wifi-node-wifi-br-phys-patch"; sfp.addFlow(flowName, flow, sw.getStringId()); log.info("added flow on SW " + sw.getStringId() + flowName); actionList.clear(); // WiFi node, WiFi bridge, patch to physical flow = new OFFlowMod(); match = new OFMatch(); match.setInputPort(WIFI_NODE_WIFI_OVS_PATCH); action.setType(OFActionType.OUTPUT); action.setPort((short) 1); action.setLength((short) OFActionOutput.MINIMUM_LENGTH); actionList.add(action); flow.setCookie(0); flow.setBufferId(-1); flow.setOutPort((short) 1); flow.setActions(actionList); flow.setMatch(match); flow.setPriority(PRIORITY_HIGH); flow.setLengthU(OFFlowMod.MINIMUM_LENGTH + action.getLengthU()); flowName = "wifi-node-wifi-br-patch-phys"; sfp.addFlow(flowName, flow, sw.getStringId()); log.info("added flow on SW " + sw.getStringId() + flowName); actionList.clear(); // root node, WiMAX bridge, DHCP on physical match.setInputPort((short) 1); match.setDataLayerType(Ethernet.TYPE_IPv4); match.setNetworkProtocol(IPv4.PROTOCOL_UDP); match.setTransportSource(UDP.DHCP_CLIENT_PORT); action.setType(OFActionType.OUTPUT); action.setLength((short) OFActionOutput.MINIMUM_LENGTH); action.setPort(OFPort.OFPP_CONTROLLER.getValue()); actionList.add(action); flow.setCookie(0); flow.setBufferId(-1); flow.setOutPort(OFPort.OFPP_CONTROLLER.getValue()); flow.setActions(actionList); flow.setMatch(match); flow.setPriority(PRIORITY_MAX); flow.setLengthU(OFFlowMod.MINIMUM_LENGTH + action.getLengthU()); flowName = "wifi-node-wifi-br-DHCP-phys"; sfp.addFlow(flowName, flow, sw.getStringId()); log.info("added flow on SW " + sw.getStringId() + flowName); actionList.clear(); } else if (sw.getStringId().equals(WIFI_NODE_TUNNEL_OVS_DPID)) { // WiFi node, tunnel bridge, tunnel to patch flow = new OFFlowMod(); match = new OFMatch(); match.setInputPort(WIFI_NODE_TUNNEL_OVS_TUNNEL); action.setType(OFActionType.OUTPUT); action.setPort(WIFI_NODE_TUNNEL_OVS_PATCH); action.setLength((short) OFActionOutput.MINIMUM_LENGTH); actionList.add(action); flow.setCookie(0); flow.setBufferId(-1); flow.setOutPort(WIFI_NODE_TUNNEL_OVS_PATCH); flow.setActions(actionList); flow.setMatch(match); flow.setPriority(PRIORITY_HIGH); flow.setLengthU(OFFlowMod.MINIMUM_LENGTH + action.getLengthU()); flowName = "wifi-node-tunnel-br-tun-patch"; sfp.addFlow(flowName, flow, sw.getStringId()); log.info("added flow on SW " + sw.getStringId() + flowName); actionList.clear(); // WiFi node, tunnel bridge, patch to tunnel flow = new OFFlowMod(); match = new OFMatch(); match.setInputPort(WIFI_NODE_TUNNEL_OVS_PATCH); action.setType(OFActionType.OUTPUT); action.setPort(WIFI_NODE_TUNNEL_OVS_TUNNEL); action.setLength((short) OFActionOutput.MINIMUM_LENGTH); actionList.add(action); flow.setCookie(0); flow.setBufferId(-1); flow.setOutPort(WIFI_NODE_TUNNEL_OVS_TUNNEL); flow.setActions(actionList); flow.setMatch(match); flow.setPriority(PRIORITY_HIGH); flow.setLengthU(OFFlowMod.MINIMUM_LENGTH + action.getLengthU()); flowName = "wifi-node-tunnel-br-patch-tun"; sfp.addFlow(flowName, flow, sw.getStringId()); log.info("added flow on SW " + sw.getStringId() + flowName); actionList.clear(); } }