wiki:Internal/OpenFlow/VendorTutorial

Version 4 (modified by akoshibe, 12 years ago) ( diff )

How-To: Extending OpenFlow with Vendor messages

OpenFlow provides a vendor message type as a way to offer third parties a way to customize the protocol without going out of spec. This tutorial attempts to describe the openflowj implementations of the vendor type message and how to use them in Floodlight.

Overview

The vendor type message has its own message header and a fully customizable payload.

A vendor message header contains a vendor ID and a data type. The vendor ID identifies the vendor implementing the custom message, and is typically the OUI of the vendor. The data type is used to indicate any subtypes that this message may have. For example, Nicira's vendor messages use Nicira's OUI (002320) as the vendor ID and come in two types, a Request and Reply, indicated by the data types of "10" and "11".

The rest of the message is the vendor message payload, and can be freely defined. To sum it up, the full OpenFlow vendor message takes on the following format:

<-------OpenFlow header-------><---Vendor message header--><----vendor message payload----->
[OF ver(1)|OFType(1)|length(2)][Vendor ID(2-8)|dataType(4)][user-defined structures(varied)]

Where the numbers in the parenthesis denote the field size in Bytes. Vendor messages are identified by OpenFlow message type (OFType) value of 4.

In openflowj

The base interface and framework needed for defining vendor messages are found in the package org.openflow.protocol.vendor.

OFVendorData, is the Java interface for the generic vendor message payload. All vendor type message payloads must implement OFVendorData. The vendor ID is also typically defined in the implementing class, as we see here in OFNiciraVendorData, the base class for all Nicira vendor messages:

public class OFNiciraVendorData implements OFVendorData {

    public static final int NX_VENDOR_ID = 0x00002320;
...

This base class is then typically subclassed to implement the various types of this message.

The Vendor ID and message classes must be registered before it can properly be parsed. This is a two step process. If we take a look at the method initVendorMessages() from Floodlight's core controller class Controller, we see that the vendor ID is registered first:

    // Configure openflowj to be able to parse the role request/reply vendor messages.
    // first register the vendor ID
        OFBasicVendorId niciraVendorId = new OFBasicVendorId(             
                OFNiciraVendorData.NX_VENDOR_ID, 4);               (1)
        OFVendorId.registerVendorId(niciraVendorId);

Since vendor IDs may vary in length, we indicate the length in bytes that the vendor ID is when we instantiate the OFBasicVendorId. In (1) we can see that the Nicira vendor ID is 4B long (an Integer).

Next is the registration of each subclass representing a message type:

    // then each data type, starting with reqest 
        OFBasicVendorDataType roleRequestVendorData =                     
                new OFBasicVendorDataType(
                        OFRoleRequestVendorData.NXT_ROLE_REQUEST,
                        OFRoleRequestVendorData.getInstantiable());
        niciraVendorId.registerVendorDataType(roleRequestVendorData);
    
   //then the repy
        OFBasicVendorDataType roleReplyVendorData =
                new OFBasicVendorDataType(
                        OFRoleReplyVendorData.NXT_ROLE_REPLY,
                        OFRoleReplyVendorData.getInstantiable());
         niciraVendorId.registerVendorDataType(roleReplyVendorData);

Where NXT_ROLE_REQUEST and NXT_ROLE_REPLY are the request and reply data type values for the two Nicira vendor message types.

As seen above in the instantiation of the OFBasicVendorDataType, the class implementing the vendor data should be instantiable, so that it can be registered properly. The method getInstantiable() should be available in your message classes for this purpose:

    protected static Instantiable<OFVendorData> instantiable =
            new Instantiable<OFVendorData>() {
                public OFVendorData instantiate() {
                    return new OFRoleRequestVendorData();
                }
            };

    /**
     * @return a subclass of Instantiable<OFVendorData> that instantiates
     *         an instance of OFRoleRequestVendorData.
     */
    public static Instantiable<OFVendorData> getInstantiable() {
        return instantiable;
    }

A non-registered Vendor message data payload is interpreted simply as a byte array (OFByteArrayVendorData to be precise), and cannot be cast to your message (sub)class(es) for further handling.

Each class implementing OFVendorData has a readFrom(ChannelBuffer data, int length) and writeTo(ChannelBuffer data) method for reading and writing the data from/to a ChannelBuffer. A getLength() method that returns the size of the messages is also required for reading. This value does not count the OpenFlow header, which is added in by helper methods to produce the full message length. The message length must be correct in order for it to be processed by the OpenFlow channel pipeline.

In Floodlight

Floodlight uses openflowj as its OpenFlow implementation. Custom vendor messages are usually placed in their own packages, such as org.openflow.vendor.nicira for Nicira messages. Message registration occurs, as mentioned before, in method initVendorMessages() in Controller.java, found in net.floodlightcontroller.core.internal.

Note: See TracWiki for help on using the wiki.