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 Quick Start for Eclipse
- Mininet installed and running, or a physical OpenFlow switch
Creating the project in Eclipse
- Within Eclipse click File ? New ? Other, select Plug-in Development ? Plug-in Project and click Next
- Set the Project Name to net.beaconcontroller.mactracker, uncheck default location and set the absolute path to ~/git/beacon/net.beaconcontroller.mactracker, change the Source folder to src/main/java, change the Target Platform to an OSGi Framework: Equinox, and click Next
- Under Properties change Name to net.beaconcontroller.mactracker, uncheck Generate an activator and click Next
- Uncheck Create a plug-in using one of the templates and click Finish
- Eclipse may prompt you about switching to the PDE perspective, you can select yes or no, but the author generally works in the Java perspective
- You should now see a project named net.beaconcontroller.mactracker on the left, and its MANIFEST.MF should be open in Eclipse's Manifest editor.
Creating the listener
- Eclipse's PDE tooling needs to know that we are going to use classes from the core bundle. Click the dependencies tab of the open Manifest editor, then click the Automated Management of Dependencies header in the bottom left to expand it, click the Add button, start typing net.beacon then select net.beaconcontroller.core, and click OK.
- You should now see net.beaconcontroller.core listed under the list of dependencies. Repeat the process for org.openflow, then save the file, ctl-s. Note this has not yet added these bundles as runtime requirements (todo later), but allows us to reference classes from these bundles during development.
- Right click on the src/main/java source folder inside the mactracker project and click New ? Package. Enter net.beaconcontroller.mactracker for the Name and click Finish
- Right click on the newly created package and click New ? Class. Enter MACTracker for the Name, and click the Add button next to Interfaces. Start typing IOFMessageListener, select it when it is listed under Matching items and click OK. Click Finish to create the class.
Registering the listener
Now that we have a listener class we need to register it with Beacon's core. To do this we must get an IBeaconProvider object. The IBeaconProvider service object is exported to OSGi's Declarative Services using Spring. We will create a Spring application context for our bundle, tell it about our MACTracker class, and state that it depends on the IBeaconProvider service object.
- Add an IBeaconProvider member variable to MACTracker, and associated getter and setter methods.
- Also add public void startUp and shutDown methods that take no arguments, their use will be explained later.
Next create two Spring files, one that declares our MACTracker class instance and its dependency on IBeaconProvider, and one that will tell Spring how to get the IBeaconProvider from OSGi
- Right click the META-INF folder in the mactracker project, click New ? Folder, name it spring and click Finish.
- Right click the new spring folder, and click New ? File, name it context.xml and click Finish.
- Repeat the previous step but name the new file osgi.xml.
- Put the following contents into context.xml
Spring reads all xml files inside the META-INF/spring folder at startup. The context file above states that one bean will be created named mactracker, the class used to create it, and init and destroy methods to call. Inside the bean reference there is also a property element, telling Spring that the mactracker bean requires a bean named beaconProvider, and the property name that will be used to set it is "beaconProvider". In the next osgi.xml file we will see how Spring retrieves the beaconProvider bean.
This file requires the osgi xml namespace. It declares one referenced bean named beaconProvider, retrieving a bean from OSGi's declarative services that matches an exported interface of net.beaconcontroller.core.IBeaconProvider. The cardinality is 1..1 indicating Spring must resolve this bean before starting the application context. Once Spring has resolved beaconProvider it will create an instance of MACTracker, call its specified init-method, and finish loading the application context.
Because bundles can start and stop inside an OSGi container, including Beacon's core, it is important that we correctly start and shutdown MACTracker.
- Add the following code to register this listener with the core for OFPacketIn messages during startup
- Add the following code to deregister this listener with the core for OFPacketIn messages during shutdown
Now we will add the code to track MAC addresses, and log new ones. First we add the logging dependency to our bundle.
- Open the Manifest editor and add slf4j.api to the list of Automated Management of Dependencies
- Add the static logger, set to hold MAC addresses, and fill in the receive method:
The receive method will receive the OFPacketIn. For convenience use the OFMatch class to parse the packet and extract the source MAC address, hash it, and check if we have seen it before. If not, it gets added to our list of seen addresses, and logged.
Before running this bundle we must edit the manifest and properly set our runtime package import requirements.
- Load the manifest in the manifest editor
- On the Dependencies tab under Automatied Management of Dependencies, ensure Import-Package is clicked, then click the add dependencies link. You should now see 4 packages listed under the Imported Packages list.
You will note that org.slf4j has a version number next to it, this is because the bundle we use exported an explicit version for that package. The logging package's API rarely changes so we don't care about a specific version, lets remove the
- Click the org.slf4j (1.5.11) imported package, click the Properties button, erase the Minimum Version, and click OK.
We must also tell Beacon's core bundle that mactracker should receive PacketIn messages before the routing and switch modules, otherwise it will be registered last by default and may not receive all PacketIns.
We need to also ensure our log messages won't be hidden, by default Beacon only logs messages of error or above so lets add a specific logger for our bundle and instruct it to show debug messages.
Launching with the mactracker bundle in Eclipse
We'll start with the base Beacon run configuration, add the mactracker bundle to it, then store it as a file in the project.
- Open the list of debug configurations by clicking the down arrow next to the bug icon, then Debug Configurations or Run ? Debug Configurations
- Select the Beacon run configuration under the OSGi Framework category in the left pane, right click it, and select Duplicate
- Change the name of the new configuration to mactracker, and in the bundles tab select the net.beaconcontroller.mactracker bundle (if you don't see it in the list, ensure Only show selected bundles is not checked)
- Click Apply, then click Debug to launch
Once its running and you have connected a physical or software switch to it (see next section about Mininet software switches), you should see output similar to below:
How to connect Mininet software OpenFlow switches to Beacon
This assumes you are running Mininet inside a VM on your host, and you are running Beacon 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)
- Launch Mininet pointing it at the remote controller
Download this example