wiki:Internal/OpenFlow/Controllers/FloodLight

The FloodLight Controller.

FloodLight is an open-source, Java-based controller maintained by OpenFlowHub.

This page is comprised of many notes that may be transient. Anything referencing links will be repeated for completeness.

Installation
Features
Adding functionality
Floodlight/Mininet VM
Architecture - the section is heavily under construction.

Installation.

The following describes the installation of FloodLight on an Ubuntu 11.04 (natty) system. Installation is described on their website, but will be repeated here. If you are using SSH, You may want X11 forwarding to be able to launch Eclipse later on.

  1. install the dependencies:
    apt-get install build-essential default-jdk ant python-dev git-core
    
  1. pull sources from github, and build:
    git clone git://github.com/floodlight/floodlight.git
    cd floodlight/
    ant;
    

Once any completes you should see a build sucess message similar to:

root@node1-2:~/floodlight# ant
Buildfile: /root/floodlight/build.xml

init:
    [mkdir] Created dir: /root/floodlight/target/bin
    [mkdir] Created dir: /root/floodlight/target/bin-test
    [mkdir] Created dir: /root/floodlight/target/lib
    [mkdir] Created dir: /root/floodlight/target/test

compile:
    [javac] Compiling 579 source files to /root/floodlight/target/bin
    [javac] Note: Some input files use unchecked or unsafe operations.
    [javac] Note: Recompile with -Xlint:unchecked for details.
     [copy] Copying 54 files to /root/floodlight/target/bin

compile-test:
    [javac] Compiling 113 source files to /root/floodlight/target/bin-test

dist:
      [jar] Building jar: /root/floodlight/target/floodlight.jar
      [jar] Building jar: /root/floodlight/target/floodlight-test.jar

BUILD SUCCESSFUL
Total time: 7 seconds

Running Floodlight

There are two ways to do this, both from the floodlight/ directory.

  1. directly through java:
    java -jar target/floodlight.jar
    

If parameters e.g. OpenFlow port need to be modified, create a config file and point floodlight to it with the -cf flag:

cp src/main/resources/floodlightdefault.properties path_to_conffile/config.properties
<edit config.properties>
java -jar target/floodlight.jar -cf path_to_conffile/config.properties

For example, if you want floodlight to listen on port 6636 instead of 6633, modify '6633' to '6636' in the following line of your properties file:

net.floodlightcontroller.core.FloodlightProvider.openflowport = 6633
  1. as an Eclipse project - first set up Eclipse:
    ant eclipse;
    

then import Floodlight as a project (verbatim from the website):

  • Open eclipse and create a new workspace
  • File → Import → General → Existing Projects into Workspace. Then click “Next”.
  • From “Select root directory” click “Browse”. Select the parent directory where you placed floodlight earlier.
  • Check the box for “Floodlight”. No other Projects should be present and none should be selected.
  • Click Finish.

Once imported, the controller may be run by right-clicking on Controller.java (net.floodlightcontroller.core.internal.Controller.java, found under src/main/java) and doing the following:

  • Click Run→Run Configurations
  • Right Click Java Application→New
  • For Name use 'FloodlightLaunch'
  • For Project use Floodlight
  • For Main use net.floodlightcontroller.core.Main
  • Click Apply

This creates a handle for launching Controller.java as an application.

The learning switch is loaded by default. The controller listens on 0.0.0.0:6633 (host, all interfaces with an IP address).

Features

Floodlight comes with several tools/features:

The REST API takes the same syntax as the BSN controller. The web UI is already incorporated into the latest version so there is no downloading/git checkout required.

Adding functionality.

A base tutorial can be found here. The steps assume that you are using Eclipse. The rough steps are the following:

  1. Create a new class under src/main/java, with the proper interfaces.
  2. Export services if it interacts with other services e.g. the REST API.
  3. Register the module so that it is loaded at startup. This involves adding the fully qualified module name to two files:
    • net.floodlight.core.module.IFloodlightModule - list of modules recognized by the loader
    • floodlightdefault.properties - list of modules to be loaded at startup.

Some module components

  • IFloodlightProviderService : Needed for listening to OpenFlow messages by registering with the FloodlightProvider.
  • getModuleDependencies() : in a module, the function to indicate dependencies to the module loader e.g the IFloodlightProviderService above. This is probably the function that is called by the loader when it searches for loadable modules and tries to discern its dependencies.
  • getModuleServices() : in a module, the function to indicate services exported by the module.
  • getServiceImpls() :
  • init() : in a module, the function where contexts are defined for services that the module is dependent on. It seems to be similar to a constructor.
  • isCallbackOrderingPrereq(), isCallbackOrderingPostreq() : where the module should be in the message processing chain.
  • startUp() : in a module, defines external initializations associated with other modules to which it is dependent on.
  • receive() : defines what a module does when it receives an event e.g. the one specified in startUp().

Exporting services

  1. create a interface for the service
  2. Add interface to the module
  3. add classes used by the service e.g. the REST API

The Floodlight VM

This is a VM image geared towards VirtualBox containing a running floodlight instance, mininet, and wireshark.
It can easily be run on qemu/kvm after conversion to qcow2 with qemu-img convert -O and with the parameters used to run mininet:

kvm-img convert -O qcow2 Mininet-VM.vmdk mininet.qcow2

Architecture and Implementation

This section describes the architecture and some of the implementations of the various parts of the controller, with focus on the controller core functions (net.floodlightcontroller.core* area of source code). This section is fairly dense, and is best referenced alongside the source code.

To start, here are some references:

You can also generate the docs yourself with ant javadoc in your working directory. You may also want to join the floodlight-dev mailing list.

Overview

The controller has two main components:

  1. the core, which listens to OpenFlow messages and dispatches events, and
  2. various modules which handle the events

In general, events encompass a range of things, including switches joining/leaving the network, reception of OpenFlow messages e.g. PACKET_INs, and the controller's role changing.

Listeners, Modules, and registration

In general, modules are implementations of several interfaces, including, but not limited to:

  • IFloodlightModule - defines interfaces uniform across modules
  • IOFSwitchListener - lets a module be notified of switches joining and leaving
  • IOFMessageListener - lets a module be notified of various types of OpenFlow messages

A module always implements the first interface, but may implement one or both of the latter two as listeners. For example, The REST API module (interested in everything under the sun) implements both, while the Hub module (interested in just PACKET_INs) only implements IOFMessageListener.

Class Controller, Floodlight's core controller implementation, dispatches events to the modules by calling the modules' event handling functions, namely receive(). The controller keeps mappings of which modules implement which listener in two map structures, switchListeners and messageListeners. These maps are used by the controller to dispatch the events to the proper listeners. IFloodLightProviderService, the interface that Controller implements, in turn provides two functions, addOFSwitchListener() and addOFMessageListener(), which the modules can call in their initialization functions to add themselves to the appropriate map.

Startup

The following steps describe the startup process of the Floodlight controller. The reference is the source code in Main.java.

  1. The FloodlightModuleLoader reads in the list of modules, and loads them, returning an IFloodlightModuleContext instance.

The FloodlightModuleLoader basically coordinates calls to the functions provided by the IFloodlightModule interface for each module in the config file (floodlightdefault.properties) and the modules that they depend on. Some key points are:

  • The function loadModulesFromList() finds all of the modules that it needs to load via a DFS beginning with the modules listed in the config file. The search is facilitated by IFloodlightModule functions such as getModuleDependencies() (e.g. the modules themselves specify their dependencies).
  • likewise, this function calls each module's initialization function, populating switchListeners and messageListeners in the controller.
  • The structure moduleSet will ultimately contain the minimum number of modules that need to be loaded at startup.

  1. The IFloodlightModuleContext instance fetches copies of the IRestApiService and IFloodlightProviderService modules.

IFloodlightModuleContext provides a clean mechanism for retrieving references to the loaded modules/services, and their configuration parameters. FloodlightModuleContext implements this interface.

  • IRestApiService provides REST API functions.
  • IFloodlightProviderService as mentioned prior, provides the core controller functions and then some.
  1. Run the REST API and core controller.

At this point, Floodlight is up and running. The TCP server functions are implemented with Netty. The controller's run() routine does two things:

  1. create a server-side channel on port 6633
  2. handle updates.

Updates include switches joining and departing, controller role change, and controller IP change. The definitions are found as inner classes implementing IUpdate, within class Controller.

OpenFlow message processing chain

The specifics of how a control message is processed is defined in the various modules themselves in the IOFMessageListener interface's receive function.

In Controller:

  1. injectOfMessage(sw, msg) calls overloaded injectOfMessage with null context
  2. injectOfMessage (sw, msg, context) calls handleMessage(sw, msg, context)
  3. handleMessage(…) calls receive for each listener subscribed to the particular type of message received from a switch (types are defined in OFType)
    • messageListener maintains mappings between control message type and listeners.
    • This is also where IListener's Command enumeration (return value for IOFMessageListener::receive) is used to decide if a message continues down the processing chain.
  4. OFSwitchImpl's write() function calls Controller's handleOutgoingMessage() to process controller-to-switch side of channel

Alternatively, messageReceived() may call processOFMessage() to invoke handleMessage().

Last modified 9 years ago Last modified on Dec 7, 2014, 9:50:17 PM
Note: See TracWiki for help on using the wiki.