| This tutorial is for Floodlight v0.90 and v0.91 (old master). We recommend you upgrade to Floodlight v1.0 for a better API and to use OpenFlow 1.3+ features. You can find the v1.0 documentation here. |
Prerequisites
We are going to create a bundle that will watch for new MAC addresses that have not been seen before, and log the MAC and switch they were seen on.
- Successfully completed the Getting Started tutorial, including setting up Eclipse
- Mininet installed and running, or a physical OpenFlow switch
Creating The Listener
Add Class In Eclipse
- Expand the "floodlight" item in the Package Explorer and find the "src/main/java" folder.
- Right-click on the "src/main/java" folder and choose "New/Class".
- Enter "net.floodlightcontroller.mactracker" in the "Package" box.
- Enter "MACTracker" in the "Name" box.
- Next to the "Interfaces" box, choose "Add...".
- Add the "IOFMessageListener" and the "IFloodlightModule", click "OK".
- Click "Finish" in the dialog.
You should end up with something like this:
Code Block | ||||
---|---|---|---|---|
| ||||
package net.floodlightcontroller.mactracker; import java.util.Collection; import java.util.Map; import org.openflow.protocol.OFMessage; import org.openflow.protocol.OFType; import net.floodlightcontroller.core.FloodlightContext; import net.floodlightcontroller.core.IOFMessageListener; import net.floodlightcontroller.core.IOFSwitch; import net.floodlightcontroller.core.module.FloodlightModuleContext; import net.floodlightcontroller.core.module.FloodlightModuleException; import net.floodlightcontroller.core.module.IFloodlightModule; import net.floodlightcontroller.core.module.IFloodlightService; public class MACTracker implements IOFMessageListener, IFloodlightModule { @Override public String getName() { // TODO Auto-generated method stub return null; } @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 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() { // TODO Auto-generated method stub return null; } @Override public void init(FloodlightModuleContext context) throws FloodlightModuleException { // TODO Auto-generated method stub } @Override public void startUp(FloodlightModuleContext context) { // TODO Auto-generated method stub } @Override public Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) { // TODO Auto-generated method stub return null; } } |
Setting Up Module Dependencies And Initialization
Before we get started, we are going to need a number of dependencies for the code to work. A tool like Eclipse should make it easy to add them. However, if you aren't using eclipse, you may just want to add them up front:
...
Code Block | ||||
---|---|---|---|---|
| ||||
@Override public void init(FloodlightModuleContext context) throws FloodlightModuleException { floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class); macAddresses = new ConcurrentSkipListSet<Long>(); logger = LoggerFactory.getLogger(MACTracker.class); } |
Handling The Packet-In Message
Now it's time to implement the basic listener. We'll register for PACKET_IN messages in our startUp method. Here we are assured other modules we depend on are already initialized.
...
Code Block | ||||
---|---|---|---|---|
| ||||
@Override public net.floodlightcontroller.core.IListener.Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) { Ethernet eth = IFloodlightProviderService.bcStore.get(cntx, IFloodlightProviderService.CONTEXT_PI_PAYLOAD); Long sourceMACHash = Ethernet.toLong(eth.getSourceMACAddress()); if (!macAddresses.contains(sourceMACHash)) { macAddresses.add(sourceMACHash); logger.info("MAC Address: {} seen on switch: {}", HexString.toHexString(sourceMACHash), sw.getId()); } return Command.CONTINUE; } |
Register The Module
{We're almost done, now we just need to tell Floodlight to load the module on startup. First we have to tell the loader that the module exists. This is done by adding the fully qualified module name on it's own line in src/main/resources/META-INF/services/net.floodlight.core.module.IFloodlightModule. We open that file and append this line.
...
Finally, let's run the controller by right clicking on Main.java
and choose "Run As.../Java Application".
How To Connect Mininet Software OpenFlow Switches To Floodlight
This assumes you are running Mininet inside a VM on your host, and you are running Floodlight from Eclipse on the host.
- Determine your host's IP address relative to Mininet, in the below example it is set as the Gateway (192.168.110.2)
Code Block | ||||
---|---|---|---|---|
| ||||
mininet@mininet:~$ sudo route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 192.168.110.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 0.0.0.0 192.168.110.2 0.0.0.0 UG 0 0 0 eth0 |
...
The Pingall command should generate debug output from your MACTracker on the console.
Have You Gotten This Far?
If you have gotten this far, its time to move over to the Floodlight wiki to learn more. We also have a more advanced tutorial available there as well.