package net.floodlightcontroller.dhcpserver; import java.util.ArrayList; import java.util.Collection; import java.util.Map; import org.openflow.protocol.OFFlowMod; import org.openflow.protocol.OFMatch; import org.openflow.protocol.OFPort; import org.openflow.protocol.action.OFAction; import org.openflow.protocol.action.OFActionOutput; import org.openflow.protocol.action.OFActionType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import net.floodlightcontroller.core.IFloodlightProviderService; import net.floodlightcontroller.core.IOFSwitch; import net.floodlightcontroller.core.IOFSwitchListener; import net.floodlightcontroller.core.module.FloodlightModuleContext; import net.floodlightcontroller.core.module.FloodlightModuleException; import net.floodlightcontroller.core.module.IFloodlightModule; import net.floodlightcontroller.core.module.IFloodlightService; import net.floodlightcontroller.packet.Ethernet; import net.floodlightcontroller.packet.IPv4; import net.floodlightcontroller.packet.UDP; import net.floodlightcontroller.staticflowentry.IStaticFlowEntryPusherService; // Adding a comment to test a new commit public class DHCPSwitchFlowSetter implements IFloodlightModule, IOFSwitchListener { protected static Logger log; protected IFloodlightProviderService floodlightProvider; protected IStaticFlowEntryPusherService sfp; private static String ROOT_NODE_ROOT_OVS_DPID; private static String ROOT_NODE_WIFI_OVS_DPID; private static String ROOT_NODE_WIMAX_OVS_DPID; private static String WIFI_NODE_WIFI_OVS_DPID; private static String WIFI_NODE_TUNNEL_OVS_DPID; private static short ROOT_NODE_WIFI_OVS_PATCH; private static short ROOT_NODE_WIFI_OVS_TUNNEL; private static short ROOT_NODE_WIMAX_OVS_PATCH; private static short ROOT_NODE_WIMAX_OVS_VLAN; private static short ROOT_NODE_ROOT_OVS_WIFI_PATCH; private static short ROOT_NODE_ROOT_OVS_WIMAX_PATCH; private static short WIFI_NODE_WIFI_OVS_PATCH; private static short WIFI_NODE_TUNNEL_OVS_PATCH; private static short WIFI_NODE_TUNNEL_OVS_TUNNEL; private static int ROOT_NODE_ROOT_OVS_IP; private static final short PRIORITY_MAX = (short) 32768; private static final short PRIORITY_HIGH = (short) 32000; private static final short PRIORITY_MEDIUM = (short) 16384; private static final short PRIORITY_LOW = (short) 1000; private static final short PRIORITY_MIN = (short) 0; @Override public Collection<Class<? extends IFloodlightService>> getModuleServices() { return null; } @Override public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() { return null; } @Override public Collection<Class<? extends IFloodlightService>> getModuleDependencies() { Collection<Class<? extends IFloodlightService>> l = new ArrayList<Class<? extends IFloodlightService>>(); l.add(IFloodlightProviderService.class); l.add(IStaticFlowEntryPusherService.class); return l; } @Override public void init(FloodlightModuleContext context) throws FloodlightModuleException { floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class); log = LoggerFactory.getLogger(DHCPServer.class); sfp = context.getServiceImpl(IStaticFlowEntryPusherService.class); } @Override public void startUp(FloodlightModuleContext context) { floodlightProvider.addOFSwitchListener(this); Map<String, String> configOptions = context.getConfigParams(this); try { ROOT_NODE_ROOT_OVS_DPID = configOptions.get("root-node-root-ovs-dpid"); ROOT_NODE_WIFI_OVS_DPID = configOptions.get("root-node-wifi-ovs-dpid"); ROOT_NODE_WIMAX_OVS_DPID = configOptions.get("root-node-wimax-ovs-dpid"); WIFI_NODE_WIFI_OVS_DPID = configOptions.get("wifi-node-wifi-ovs-dpid"); WIFI_NODE_TUNNEL_OVS_DPID = configOptions.get("wifi-node-tunnel-ovs-dpid"); ROOT_NODE_ROOT_OVS_IP = IPv4.toIPv4Address(configOptions.get("root-node-root-ovs-ip")); ROOT_NODE_WIFI_OVS_PATCH = Short.parseShort(configOptions.get("root-node-wifi-ovs-patch-port")); ROOT_NODE_WIFI_OVS_TUNNEL = Short.parseShort(configOptions.get("root-node-wifi-ovs-tunnel-port")); ROOT_NODE_WIMAX_OVS_PATCH = Short.parseShort(configOptions.get("root-node-wimax-ovs-patch-port")); ROOT_NODE_WIMAX_OVS_VLAN = Short.parseShort(configOptions.get("root-node-wimax-ovs-vlan-port")); ROOT_NODE_ROOT_OVS_WIFI_PATCH = Short.parseShort(configOptions.get("root-node-root-ovs-wifi-patch-port")); ROOT_NODE_ROOT_OVS_WIMAX_PATCH = Short.parseShort(configOptions.get("root-node-root-ovs-wimax-patch-port")); WIFI_NODE_WIFI_OVS_PATCH = Short.parseShort(configOptions.get("wifi-node-wifi-ovs-patch-port")); WIFI_NODE_TUNNEL_OVS_TUNNEL = Short.parseShort(configOptions.get("wifi-node-tunnel-ovs-tunnel-port")); WIFI_NODE_TUNNEL_OVS_PATCH = Short.parseShort(configOptions.get("wifi-node-tunnel-ovs-patch-port")); } catch(IllegalArgumentException ex) { log.error("Incorrect DHCP Switch Flow Setter configuration options (illegal arg)", ex); throw ex; } catch(NullPointerException ex) { log.error("Incorrect DHCP Switch Flow Setter configuration options (null ptr)", ex); throw ex; } } @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(); } } @Override public void removedSwitch(IOFSwitch sw) { // We can't exactly remove flows from a switch if/when it disconnects, so do nothing? } @Override public void switchPortChanged(Long switchId) { } @Override public String getName() { return DHCPSwitchFlowSetter.class.getSimpleName(); } }