-
Notifications
You must be signed in to change notification settings - Fork 77
OpenFlow Java library API Cookbook
(work in progress)
The main idea is to create an event-driven application. What develeloper does have to do is to implement his own event handler and launch the Controller listening a tcp port. When Controller connects with a Switch and gets a version information from the Hello message, it starts an appropriate OpenFlow events handler, supporting a given OpenFlow vesrion which deals with OpenFlow messages and generates events against developer-defined event handler.
Use Message and Structure handlers to comm
You may operate with OpenFlow protocol messages and structures via MessageProvider class.
import org.flowforwarding.of.protocol.ofmessages.IOFMessageProvider;
import org.flowforwarding.of.protocol.ofmessages.IOFMessageProviderFactory;
import org.flowforwarding.of.protocol.ofmessages.OFMessageProviderFactoryAvroProtocol;
IOFMessageProviderFactory factory = new OFMessageProviderFactoryAvroProtocol();
IOFMessageProvider provider = factory.getMessageProvider("1.3");Now you can use the Provider to operate OpenFlow messages. Get messages in binary format ready to put into a channel:
byte [] helloMessage = provider.encodeHelloMessage();
/*...*/
byte [] configRequestMessage = provider.encodeSwitchConfigRequest();
/*...*/
byte[] switchFeatureRequestMessage = encodeSwitchFeaturesRequest();To get more complicated messages first you need to build it, and then add fields via Ref classes. Let's consider Flow Modification message:
import org.flowforwarding.of.protocol.ofmessages.OFMessageFlowMod.OFMessageFlowModeRef;
OFMessageFlowModRef fmRef = provider.buildFlowMod();
fmRef.addTableId("1");
fmRef.addPriority("256");
/*...*/
fmRef.addMatchInPort("128");
/*...*/
OFStructureInstructionRef instrRef = provider.buildInstructionApplyActions();
instrRef.addActionOutput("12");
/*...*/
fmRef.addInstuction(instrRef);
byte [] fmBuffer = provider.encodeFlowMod(fmRef);The controller infrastructure is started the next way:
import org.flowforwarding.of.controller.Controller;
/*................*/
Controller.launch (SessionHandler.class); // This launches a controller listening tcp port 6633
Controller.launch (SessionHandler.class, configuration); // This launches a controller listening given tcp port It's a POJO containing some configuration information as tcp port number etc.
import org.flowforwarding.of.controller.Configuration
/*................*/
Configuration config1 = new Configuration(); // tcp port 6633 by default
Configuration config2 = new Configuration(6633);During the Controller-Sessions some events are generated. An application handles it via OF Events handler.
The SwitchHandler class refers to a Switch connected to the Controller. It's unique, you have to use it to communicate with a Switch, send commands or get a Switch state:
SwitchRef swHandler = SwitchHandler.create();
Long SwitchHandler.getDpid();
void SwitchHandler.setDpid(Long dpid);Some code examples:
import org.flowforwarding.of.ofswitch.SwitchState.SwitchHandler;
/*.................................................*/
public class SimpleHandler extends OFSessionHandler {
@Override
protected void handshaked(SwitchHandler swHandler) {
super.handshaked(swHandler);
Long dpid = swHandler.getDpid();
/*.........................................*/
}
/*.........................................*/
}You have to implement your session handler to interact with Controller. You may manage of incoming messages handling or send messages you want. Session handlers extend the class OFSessionHandler:
import org.flowforwarding.of.controller.SwitchState.SwitchHandler;
import org.flowforwarding.of.controller.session.OFSessionHandler;
import org.flowforwarding.of.controller.protocol.ofmessages.OFMessagePacketIn.OFMessagePacketInHandler;
public class SimpleHandler extends OFSessionHandler {
/*
* User-defined Switch event handlers
*/
@Override
protected void handshaked(SwitchHandler swRef) {
super.handshaked(swRef);
/*You have to implement your own logic here*/
}
/*.................................................*/
@Override
protected void connected(SwitchHandler swRef) {
super.connected(swRef);
/*You have to implement your own logic here*/
}
/*.................................................*/
@Override
protected void packetIn(Switch swRef, OFMessagePacketInHandler packetIn) {
super.packetIn(swRef);
/*You have to implement your own logic here*/
}
}You can find a source code in the package org.flowforwarding.of.demo
####org.flowforwarding.of.demo.Launcher.java
package org.flowforwarding.of.demo;
import org.flowforwarding.of.controller.Controller;
import org.flowforwarding.of.controller.Controller.ControllerRef;
public class Launcher {
public static void main(String[] args) {
ControllerRef cRef = Controller.launch(SimpleHandler.class);
}
}####org.flowforwarding.of.demo
package org.flowforwarding.of.demo;
import org.flowforwarding.of.controller.session.OFSessionHandler;
import org.flowforwarding.of.ofswitch.SwitchState.SwitchHandler;
import org.flowforwarding.of.protocol.ofmessages.IOFMessageProvider;
import org.flowforwarding.of.protocol.ofmessages.OFMessageFlowMod.OFMessageFlowModHandler;
import org.flowforwarding.of.protocol.ofmessages.OFMessagePacketIn.OFMessagePacketInHandler;
import org.flowforwarding.of.protocol.ofmessages.OFMessageSwitchConfig.OFMessageSwitchConfigHandler;
import org.flowforwarding.of.protocol.ofstructures.OFStructureInstruction.OFStructureInstructionHandler;
public class SimpleHandler extends OFSessionHandler {
@Override
protected void switchConfig(SwitchHandler swH, OFMessageSwitchConfigHandler configH) {
super.switchConfig(swH, configH);
System.out.print("[OF-INFO] DPID: " + Long.toHexString(swH.getDpid()) + " Configuration: ");
if (configH.isFragDrop()) {
System.out.println("Drop fragments");
}
if (configH.isFragMask()) {
System.out.println("Mask");
}
if (configH.isFragNormal()) {
System.out.println("Normal");
}
if (configH.isFragReasm()) {
System.out.println("Reassemble");
}
}
@Override
protected void handshaked(SwitchHandler swH) {
super.handshaked(swH);
System.out.println("[OF-INFO] HANDSHAKED " + Long.toHexString(swH.getDpid()));
sendSwitchConfigRequest(swH);
}
@Override
protected void packetIn(SwitchHandler swH, OFMessagePacketInHandler packetIn) {
super.packetIn(swH, packetIn);
IOFMessageProvider provider = swH.getProvider();
OFMessageFlowModHandler flowMod = provider.buildFlowModMsg();
if (packetIn.existMatchInPort()) {
flowMod.addMatchInPort(packetIn.getMatchInPort().getMatch());
} else if (packetIn.existMatchEthDst()) {
flowMod.addMatchEthDst(packetIn.getMatchEthDst().getMatch());
} else if (packetIn.existMatchEthSrc()) {
flowMod.addMatchEthSrc(packetIn.getMatchEthSrc().getMatch());
}
OFStructureInstructionHandler instruction = provider.buildInstructionApplyActions();
instruction.addActionOutput("2");
flowMod.addInstruction("apply_actions", instruction);
sendFlowModMessage(swH, flowMod);
}
}