package edu.wisc.cs.sdn.apps.l3routing;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import edu.wisc.cs.sdn.apps.util.Host;
import net.floodlightcontroller.core.IFloodlightProviderService;
import net.floodlightcontroller.core.IOFSwitch;
import net.floodlightcontroller.core.IOFSwitch.PortChangeType;
import net.floodlightcontroller.core.IOFSwitchListener;
import net.floodlightcontroller.core.ImmutablePort;
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.IDeviceListener;
import net.floodlightcontroller.devicemanager.IDeviceService;
import net.floodlightcontroller.linkdiscovery.ILinkDiscoveryListener;
import net.floodlightcontroller.linkdiscovery.ILinkDiscoveryService;
import net.floodlightcontroller.routing.Link;
public class L3Routing implements IFloodlightModule, IOFSwitchListener,
ILinkDiscoveryListener, IDeviceListener, IL3Routing
public static final String MODULE_NAME = L3Routing.class.getSimpleName();
// Interface to the logging system
private static Logger log = LoggerFactory.getLogger(MODULE_NAME);
// Interface to Floodlight core for interacting with connected switches
private IFloodlightProviderService floodlightProv;
// Interface to link discovery service
private ILinkDiscoveryService linkDiscProv;
// Interface to device manager service
private IDeviceService deviceProv;
// Switch table in which rules should be installed
private byte table;
// Map of hosts to devices
private Map
* Loads dependencies and initializes data structures.
public void init(FloodlightModuleContext context)
throws FloodlightModuleException
log.info(String.format(“Initializing %s…”, MODULE_NAME));
Map
this.table = Byte.parseByte(config.get(“table”));
this.floodlightProv = context.getServiceImpl(
IFloodlightProviderService.class);
this.linkDiscProv = context.getServiceImpl(ILinkDiscoveryService.class);
this.deviceProv = context.getServiceImpl(IDeviceService.class);
this.knownHosts = new ConcurrentHashMap
/*********************************************************************/
/* TODO: Initialize other class variables, if necessary */
/*********************************************************************/
* Subscribes to events and performs other startup tasks.
public void startUp(FloodlightModuleContext context)
throws FloodlightModuleException
log.info(String.format(“Starting %s…”, MODULE_NAME));
this.floodlightProv.addOFSwitchListener(this);
this.linkDiscProv.addListener(this);
this.deviceProv.addListener(this);
/*********************************************************************/
/* TODO: Perform other tasks, if necessary */
/*********************************************************************/
* Get the table in which this application installs rules.
public byte getTable()
{ return this.table; }
* Get a list of all known hosts in the network.
private Collection
{ return this.knownHosts.values(); }
* Get a map of all active switches in the network. Switch DPID is used as
* the key.
private Map
{ return floodlightProv.getAllSwitchMap(); }
* Get a list of all active links in the network.
private Collection getLinks()
{ return linkDiscProv.getLinks().keySet(); }
* Event handler called when a host joins the network.
* @param device information about the host
public void deviceAdded(IDevice device)
Host host = new Host(device, this.floodlightProv);
// We only care about a new host if we know its IP
if (host.getIPv4Address() != null)
log.info(String.format(“Host %s added”, host.getName()));
this.knownHosts.put(device, host);
/*****************************************************************/
/* TODO: Update routing: add rules to route to new host */
/*****************************************************************/
* Event handler called when a host is no longer attached to a switch.
* @param device information about the host
public void deviceRemoved(IDevice device)
Host host = this.knownHosts.get(device);
if (null == host)
host = new Host(device, this.floodlightProv);
this.knownHosts.put(device, host);
log.info(String.format(“Host %s is no longer attached to a switch”,
host.getName()));
/*********************************************************************/
/* TODO: Update routing: remove rules to route to host */
/*********************************************************************/
* Event handler called when a host moves within the network.
* @param device information about the host
public void deviceMoved(IDevice device)
Host host = this.knownHosts.get(device);
if (null == host)
host = new Host(device, this.floodlightProv);
this.knownHosts.put(device, host);
if (!host.isAttachedToSwitch())
this.deviceRemoved(device);
log.info(String.format(“Host %s moved to s%d:%d”, host.getName(),
host.getSwitch().getId(), host.getPort()));
/*********************************************************************/
/* TODO: Update routing: change rules to route to host */
/*********************************************************************/
* Event handler called when a switch joins the network.
* @param DPID for the switch
public void switchAdded(long switchId)
IOFSwitch sw = this.floodlightProv.getSwitch(switchId);
log.info(String.format(“Switch s%d added”, switchId));
/*********************************************************************/
/* TODO: Update routing: change routing rules for all hosts */
/*********************************************************************/
* Event handler called when a switch leaves the network.
* @param DPID for the switch
public void switchRemoved(long switchId)
IOFSwitch sw = this.floodlightProv.getSwitch(switchId);
log.info(String.format(“Switch s%d removed”, switchId));
/*********************************************************************/
/* TODO: Update routing: change routing rules for all hosts */
/*********************************************************************/
* Event handler called when multiple links go up or down.
* @param updateList information about the change in each link’s state
public void linkDiscoveryUpdate(List
for (LDUpdate update : updateList)
// If we only know the switch & port for one end of the link, then
// the link must be from a switch to a host
if (0 == update.getDst())
log.info(String.format(“Link s%s:%d -> host updated”,
update.getSrc(), update.getSrcPort()));
// Otherwise, the link is between two switches
log.info(String.format(“Link s%s:%d -> %s:%d updated”,
update.getSrc(), update.getSrcPort(),
update.getDst(), update.getDstPort()));
/*********************************************************************/
/* TODO: Update routing: change routing rules for all hosts */
/*********************************************************************/
* Event handler called when link goes up or down.
* @param update information about the change in link state
public void linkDiscoveryUpdate(LDUpdate update)
{ this.linkDiscoveryUpdate(Arrays.asList(update)); }
* Event handler called when the IP address of a host changes.
* @param device information about the host
public void deviceIPV4AddrChanged(IDevice device)
{ this.deviceAdded(device); }
* Event handler called when the VLAN of a host changes.
* @param device information about the host
public void deviceVlanChanged(IDevice device)
{ /* Nothing we need to do, since we’re not using VLANs */ }
* Event handler called when the controller becomes the master for a switch.
* @param DPID for the switch
public void switchActivated(long switchId)
{ /* Nothing we need to do, since we’re not switching controller roles */ }
* Event handler called when some attribute of a switch changes.
* @param DPID for the switch
public void switchChanged(long switchId)
{ /* Nothing we need to do */ }
* Event handler called when a port on a switch goes up or down, or is
* added or removed.
* @param DPID for the switch
* @param port the port on the switch whose status changed
* @param type the type of status change (up, down, add, remove)
public void switchPortChanged(long switchId, ImmutablePort port,
PortChangeType type)
{ /* Nothing we need to do, since we’ll get a linkDiscoveryUpdate event */ }
* Gets a name for this module.
* @return name for this module
public String getName()
{ return this.MODULE_NAME; }
* Check if events must be passed to another module before this module is
* notified of the event.
public boolean isCallbackOrderingPrereq(String type, String name)
{ return false; }
* Check if events must be passed to another module after this module has
* been notified of the event.
public boolean isCallbackOrderingPostreq(String type, String name)
{ return false; }
* Tell the module system which services we provide.
public Collection
Collection
new ArrayList
services.add(IL3Routing.class);
return services;
* Tell the module system which services we implement.
public Map
getServiceImpls()
Map
new HashMap
IFloodlightService>();
// We are the class that implements the service
services.put(IL3Routing.class, this);
return services;
* Tell the module system which modules we depend on.
public Collection
getModuleDependencies()
Collection
new ArrayList
modules.add(IFloodlightProviderService.class);
modules.add(ILinkDiscoveryService.class);
modules.add(IDeviceService.class);
return modules;