Hello, I am a student and I need help. I am working on creating an SDN application with a Floodlight controller. The problem in creating tables for switches. Namely, how to determine which paths in the network are for the given 2x hosts, get the numbers of switches and ports from these paths and transfer it to the flowcreator functions.
package net.floodlightcontroller.HA_app; import java.util.Collection; import java.util.Map; import java.util.HashMap; import org.projectfloodlight.openflow.protocol.OFFactories; import org.projectfloodlight.openflow.protocol.OFFactory; import org.projectfloodlight.openflow.protocol.OFFlowAdd; import org.projectfloodlight.openflow.protocol.OFMessage; import org.projectfloodlight.openflow.protocol.OFPortDesc; import org.projectfloodlight.openflow.protocol.OFType; import org.projectfloodlight.openflow.protocol.OFVersion; import org.projectfloodlight.openflow.protocol.action.OFAction; import org.projectfloodlight.openflow.protocol.action.OFActionOutput; import org.projectfloodlight.openflow.protocol.instruction.OFInstruction; import org.projectfloodlight.openflow.protocol.instruction.OFInstructionApplyActions; import org.projectfloodlight.openflow.protocol.match.Match; import org.projectfloodlight.openflow.protocol.match.MatchField; import org.projectfloodlight.openflow.types.DatapathId; import org.projectfloodlight.openflow.types.EthType; import org.projectfloodlight.openflow.types.IPv4Address; import org.projectfloodlight.openflow.types.IPv6Address; import org.projectfloodlight.openflow.types.IpProtocol; import org.projectfloodlight.openflow.types.MacAddress; import org.projectfloodlight.openflow.types.OFBufferId; import org.projectfloodlight.openflow.types.OFPort; import org.projectfloodlight.openflow.types.TransportPort; import org.projectfloodlight.openflow.types.U64; import org.projectfloodlight.openflow.types.VlanVid; import net.floodlightcontroller.routing.Path; import net.floodlightcontroller.routing.PathId; import net.floodlightcontroller.routing.IRoutingService; import net.floodlightcontroller.core.IFloodlightProviderService; import java.util.ArrayList; import java.util.Set; import java.util.concurrent.ConcurrentSkipListSet; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import net.floodlightcontroller.core.FloodlightContext; import net.floodlightcontroller.core.IOFMessageListener; import net.floodlightcontroller.core.IOFSwitch; import net.floodlightcontroller.core.IOFSwitchListener; import net.floodlightcontroller.core.PortChangeType; import net.floodlightcontroller.core.internal.IOFSwitchService; 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.devicemanager.IDevice; import net.floodlightcontroller.devicemanager.IDeviceService; import net.floodlightcontroller.devicemanager.SwitchPort; import net.floodlightcontroller.packet.Ethernet; import net.floodlightcontroller.packet.IPv4; import net.floodlightcontroller.packet.TCP; import net.floodlightcontroller.packet.UDP; public class HA_App implements IFloodlightModule, IOFMessageListener, IOFSwitchListener { protected IFloodlightProviderService floodlightProvider; protected Set < Long > macAddresses; protected static Logger logger; protected IOFSwitchService switchService; protected IRoutingService routingService; protected IDeviceService deviceService; // more flow-mod defaults public static final long FLOW_COOKIE = 0x5555; protected static short FLOWMOD_DEFAULT_IDLE_TIMEOUT = 0; // in seconds protected static short FLOWMOD_DEFAULT_HARD_TIMEOUT = 0; // infinite protected static short FLOWMOD_PRIORITY = 101; public HashMap < String, ArrayList < String >> extractedData; public HashMap < String, ArrayList < String >> pathID; @Override public String getName() { // TODO Auto-generated method stub return HA_App.class.getSimpleName(); } @Override public boolean isCallbackOrderingPrereq(OFType type, String name) { // TODO Auto-generated method stub return false; } @Override public boolean isCallbackOrderingPostreq(OFType type, String name) { // TODO Auto-generated method stub return false; } @Override public void switchAdded(DatapathId switchId) { if (switchId.toString() == "4a:fc:f9:9c:f0:47") { flowCreator(OFPort.of(3), OFPort.of(1), switchId); flowCreator(OFPort.of(2), OFPort.of(1), switchId); } else if (switchId.toString() == "8a:f1:36:48:fb:44") { flowCreator(OFPort.of(2), OFPort.of(1), switchId); } else if (switchId.toString() == "d2:f4:54:8a:9f:40") { flowCreator(OFPort.of(2), OFPort.of(1), switchId); } else if (switchId.toString() == "1a:15:fa:f5:c5:40") { flowCreator(OFPort.of(2), OFPort.of(2), switchId); } else if (switchId.toString() == " a2:51:46:de:1b:4c") { flowCreator(OFPort.of(2), OFPort.of(1), switchId); } else if (switchId.toString() == "ae:e7:b4:3f:40:4a") { flowCreator(OFPort.of(3), OFPort.of(0), switchId); } } @Override public void switchRemoved(DatapathId switchId) { // TODO Auto-generated method stub } @Override public void switchActivated(DatapathId switchId) { // TODO Auto-generated method stub } @Override public void switchPortChanged(DatapathId switchId, OFPortDesc port, PortChangeType type) { // TODO Auto-generated method stub } @Override public void switchChanged(DatapathId switchId) { // TODO Auto-generated method stub } @Override public void switchDeactivated(DatapathId switchId) { // TODO Auto-generated method stub } @Override public net.floodlightcontroller.core.IListener.Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) { switch (msg.getType()) { case PACKET_IN: /* Retrieve the deserialized packet in message */ Ethernet eth = IFloodlightProviderService.bcStore.get(cntx, IFloodlightProviderService.CONTEXT_PI_PAYLOAD); /* Various getters and setters are exposed in Ethernet */ MacAddress srcMac = eth.getSourceMACAddress(); MacAddress dstMac = eth.getDestinationMACAddress(); System.out.println(dstMac.toString()); System.out.println(srcMac.toString()); VlanVid vlanId = VlanVid.ofVlan(eth.getVlanID()); // Get attachment points ArrayList < String > apSrc = getAttachmentPoints(srcMac); ArrayList < String > apDst = getAttachmentPoints(dstMac); // Get attachment points /* Check the ethertype of the Ethernet frame and retrieve the appropriate payload. * Note the shallow equality check. EthType caches and reuses instances for valid types. */ if (eth.getEtherType() == EthType.IPv4) { /* We got an IPv4 packet; get the payload from Ethernet */ IPv4 ipv4 = (IPv4) eth.getPayload(); /* * Check the IP protocol version of the IPv4 packet's payload. */ if (ipv4.getProtocol() == IpProtocol.TCP) { /* We got a TCP packet; get the payload from IPv4 */ TCP tcp = (TCP) ipv4.getPayload(); /* Various getters and setters are exposed in TCP */ TransportPort srcPort = tcp.getSourcePort(); TransportPort dstPort = tcp.getDestinationPort(); short flags = tcp.getFlags(); /* Your logic here! */ } else if (ipv4.getProtocol() == IpProtocol.UDP) { /* We got a UDP packet; get the payload from IPv4 */ UDP udp = (UDP) ipv4.getPayload(); /* Various getters and setters are exposed in UDP */ TransportPort srcPort = udp.getSourcePort(); TransportPort dstPort = udp.getDestinationPort(); /* Your logic here! */ } } else { /* Unhandled ethertype */ } break; default: break; } return Command.CONTINUE; } public ArrayList < String > getAttachmentPoints(MacAddress mac) { ArrayList < String > list = new ArrayList < > (); IDevice device = deviceService.findDevice( MacAddress.of(mac.getBytes()), VlanVid.ZERO, IPv4Address.NONE, IPv6Address.NONE, DatapathId.NONE, OFPort.ZERO); if (device != null) { SwitchPort[] attachmentPoints = device.getAttachmentPoints(); for (SwitchPort sp: attachmentPoints) { OFPort devPort = sp.getPortId(); DatapathId devNode = sp.getNodeId(); list.add(0, devNode.toString()); list.add(1, devPort.toString()); //System.out.println(" Switch ID: "+ sp.getPortId()); System.out.println(mac.toString() + " hello " + sp.toString()); break; } } return list; } public Path getPath(ArrayList < String > listEndNodes) { Path shortestPath = routingService.getPath( DatapathId.of(listEndNodes.get(0)), OFPort.of(Integer.parseInt(listEndNodes.get(1))), DatapathId.of(listEndNodes.get(0)), OFPort.of(Integer.parseInt(listEndNodes.get(1)))); return shortestPath; } public synchronized HashMap < String, ArrayList < String >> getExtractedDataTable() { return extractedData; } public synchronized HashMap < String, ArrayList < String >> getPathIDTable() { return pathID; } public void flowCreator(OFPort port, OFPort port2, DatapathId switchId) { /* Creating a Flow for specific OFPort * Returns Flow */ IOFSwitch sw = switchService.getSwitch(switchId); ArrayList < OFAction > actionsList = new ArrayList < OFAction > (); ArrayList < OFInstruction > instructionsList = new ArrayList < OFInstruction > (); OFFactory factory = OFFactories.getFactory(OFVersion.OF_13); //OFFactory myFactory = OFFactories.getFactory(OFVersion.OF_13); Match forward = factory.buildMatch() .setExact(MatchField.ETH_TYPE, EthType.IPv4) .setExact(MatchField.IP_PROTO, IpProtocol.TCP) //TCP Protocol .setExact(MatchField.IPV4_SRC, IPv4Address.of("192.168.1.11")) .setExact(MatchField.IPV4_DST, IPv4Address.of("192.168.1.12")) .build(); Match backward = factory.buildMatch() .setExact(MatchField.ETH_TYPE, EthType.IPv4) .setExact(MatchField.IP_PROTO, IpProtocol.TCP) .setExact(MatchField.IPV4_SRC, IPv4Address.of("192.168.1.11")) .setExact(MatchField.IPV4_DST, IPv4Address.of("192.168.1.12")) .build(); OFActionOutput output = factory.actions().buildOutput() .setPort(port) .setMaxLen(0xffFFffFF) .build(); actionsList.add(output); OFActionOutput output2 = factory.actions().buildOutput() .setPort(port2) .setMaxLen(0xffFFffFF) .build(); actionsList.add(output2); OFInstructionApplyActions applyActions = factory.instructions().buildApplyActions() .setActions(actionsList) .build(); instructionsList.add(applyActions); OFFlowAdd flow = factory.buildFlowAdd() .setMatch(forward) .setCookie((U64.of(HA_App.FLOW_COOKIE))) .setIdleTimeout(HA_App.FLOWMOD_DEFAULT_IDLE_TIMEOUT) .setHardTimeout(HA_App.FLOWMOD_DEFAULT_HARD_TIMEOUT) .setPriority(HA_App.FLOWMOD_PRIORITY) .setBufferId(OFBufferId.NO_BUFFER) .setInstructions(instructionsList) .build(); OFFlowAdd flow2 = factory.buildFlowAdd() .setMatch(backward) .setCookie((U64.of(HA_App.FLOW_COOKIE))) .setIdleTimeout(HA_App.FLOWMOD_DEFAULT_IDLE_TIMEOUT) .setHardTimeout(HA_App.FLOWMOD_DEFAULT_HARD_TIMEOUT) .setPriority(HA_App.FLOWMOD_PRIORITY) .setBufferId(OFBufferId.NO_BUFFER) .setInstructions(instructionsList) .build(); sw.write(flow); sw.write(flow2); } @Override public Collection < Class << ? extends IFloodlightService >> getModuleServices() { // TODO Auto-generated method stub return null; } @Override public Map < Class << ? extends IFloodlightService > , IFloodlightService > getServiceImpls() { // TODO Auto-generated method stub 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(IOFSwitchService.class); l.add(IDeviceService.class); l.add(IRoutingService.class); return l; } @Override public void init(FloodlightModuleContext context) throws FloodlightModuleException { floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class); macAddresses = new ConcurrentSkipListSet < Long > (); logger = LoggerFactory.getLogger(HA_App.class); deviceService = context.getServiceImpl(IDeviceService.class); routingService = context.getServiceImpl(IRoutingService.class); switchService = context.getServiceImpl(IOFSwitchService.class); extractedData = new HashMap < String, ArrayList < String >> (); pathID = new HashMap < String, ArrayList < String >> (); } @Override public void startUp(FloodlightModuleContext context) throws FloodlightModuleException { // TODO Auto-generated method stub floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this); switchService.addOFSwitchListener(this); } }