Skip to content

Module Programming Guide

Byungjoon Lee edited this page Aug 7, 2013 · 16 revisions

This document explains how to program a user-defined module.

MacLearning Module

Maybe the easiest way to learn about to module programming is to see the implementation of MacLearning module, which is the most simple IRIS module. As the code of this module has come from the Floodlight, many of its detail is the same. But you should remember following:

  1. IRIS module should be defined as a subclass of OFModule
  2. you should override following methods:
    1. initialize
    2. handleMEssage
    3. handleHandshakedEvent
    4. handleDisconnect
    5. getModels
  3. Module name starts with OFM

initialize method

In initialize method, you normally does following things:

  1. call registerFilter method that makes your module to receive a specific types of messages.
  2. call registerModule method that let other module to know that your module is implementing a specific service.
  3. do other module-specific initialization

Following is a code from OFMLearningMac.initialize().

@Override
protected void initialize() {
	registerFilter(
		OFType.PACKET_IN,
		new OFMFilter() {
			@Override
			public boolean filter(OFMessage m) {
				return true;
			}
		}
	);
}

Above call to registerFilter makes OFMLearningMac module to receive all PACKET_IN messages. The OFMFilter.filter() determines whether m is a message that this module should receive (true or false). In the above, OFMFilter.filter() always returns true. That means this module receives all the PACKET_IN messages.

Following code is from OFMLinkDiscovery.initialize().

...
registerModule(ILinkDiscoveryService.class, this);

// I will receive PACKET_IN messages selectively.
registerFilter(
	OFType.PACKET_IN, 
	new OFMFilter() {
		@Override
		public boolean filter(OFMessage m) {
			OFPacketIn pi = (OFPacketIn) m;
			
			// this checks if the Packet-In is for LLDP!
			// This is very important to guarantee maximum performance. (-_-;)
			if ( pi.getPacketData()[12] != (byte)0x88 || 
                             pi.getPacketData()[13] != (byte)0xcc ){
				// this packet is not mine!
				return false;
			}
			return true;
		}
	}
);
	
// I will receive all PORT_STATUS messages.
registerFilter(
	OFType.PORT_STATUS,
	new OFMFilter() {
		@Override
		public boolean filter(OFMessage m) {
			return true;
		}
	}
);
...

In the OFMLinkDiscovery module, you can see an example usage of registerModule method. As OFMLinkDiscovery module implements ILinkDiscoveryService interface, it register itself as an implementer module of the interface. Because of this, other modules can find and use a module that implements the ILinkdiscoveryService interface.

handleMessage method

@Override
public boolean handleMessage(Connection conn, MessageContext context, OFMessage msg, List<OFMessage> outgoing) {
	return processPacketInMessage(conn, context, msg, outgoing);
}

As you can see, handleMessage gets 4 arguments: connection with switch, message-handling context, Openflow message to process, and a list of outgoing messages to return to switches (which is initially empty).

  • MessageContext object context is created per-message basis. That is, each Openflow message passed to a controller has a designated message context.
  • OFMessage is a superclass of all Openflow messages.
  • If you have messages to return to switches, just put it into the outgoing list. Then all the messages are sent to switches before the msg is passed to other modules. (But if you need the messages to be sent immediately, you should use conn object directly.

Clone this wiki locally