Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

(info)

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

  1. Expand the "floodlight" item in the Package Explorer and find the "src/main/java" folder.
  2. Right-click on the "src/main/java" folder and choose "New/Class".
  3. Enter "net.floodlightcontroller.mactracker" in the "Package" box.
  4. Enter "MACTracker" in the "Name" box.
  5. Next to the "Interfaces" box, choose "Add...".
  6. Add the "IOFMessageListener" and the "IFloodlightModule", click "OK".
  7. Click "Finish" in the dialog.

You should end up with something like this:

Code Block
xml
xml
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
xml
xml
@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
xml
xml
@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
xml
xml
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.