Openflow 1.3 extension: Bundles

ONF specification

A bundle is a sequence of OpenFlow requests from the controller that is applied as a single OpenFlow operation.

The first goal of bundles is to group related state changes on a switch so that all changes are applied together or that none of them is applied. The second goal is to better synchronize changes across a set of OpenFlow switches, bundles can be prepared and pre-validated on each switch and applied at the same time.

A bundle is specified as all controllers messages encoded with the same bundle_id on a specific controller connection. Messages part of the bundle are encapsulated in a Bundle Add message, the payload of the Bundle Add message is formatted like a regular OpenFlow messages and has the same semantic. The messages part of a bundle are pre-validated as they are stored in the bundle, minimising the risk of errors when the bundle is applied. The applications of the message included in the Bundle Add message is postponed to when the bundle is committed.

A switch is not required to accept arbitrary messages in a bundle, a switch may not accept some message types in bundles, and a switch may not allow all combinations of message types to be bundled together. For example, a switch should not allow to embed a bundle message within a Bundle Add message. At a minimum, a switch must be able to support a bundle of multiple flow-mods and port-mods in any order.

Model definition as extension 230 describes

First you need define bundle id and bundle property type.

    typedef bundle-id {
       description "Identify the bundle.";
       type uint32;
   }
   
typedef bundle-property-type { description "Bundle property types."; type enumeration { enum ONF_ET_BPT_EXPERIMENTER { description "Experimenter property."; value 65535; //0xFFFF } } }

Definition of flags

    typedef bundle-flags {
       description "Bundle configuration flags.";
       type bits {
           bit atomic {
               description "Execute atomically.";
               position 0;
           }
           bit ordered {
               description "Execute in specified order.";
               position 1;
           }
       }
   }

Control message types

    typedef bundle-control-type {
       description "Bundle control message type.";
       type enumeration {
           enum ONF_BCT_OPEN_REQUEST {
               value 0;
           }
           enum ONF_BCT_OPEN_REPLY {
               value 1;
           }
           enum ONF_BCT_CLOSE_REQUEST {
               value 2;
           }
           enum ONF_BCT_CLOSE_REPLY {
               value 3;
           }
           enum ONF_BCT_COMMIT_REQUEST {
               value 4;
           }
           enum ONF_BCT_COMMIT_REPLY {
               value 5;
           }
           enum ONF_BCT_DISCARD_REQUEST {
               value 6;
           }
           enum ONF_BCT_DISCARD_REPLY {
               value 7;
           }
       }
   }

ONF experimenter error codes

    typedef onf-experimenter-error-code {
       description "Error codes for experimenter error type.";
       type enumeration {
           enum ONFERR_ET_UNKNOWN {
               description "Unspecified error.";
               value 2300;
           }
           enum ONFERR_ET_EPERM {
               description "Permissions error.";
               value 2301;
           }
           enum ONFERR_ET_BAD_ID {
               description "Bundle ID doesn’t exist.";
               value 2302;
           }
           enum ONFERR_ET_BUNDLE_EXIST {
               description "Bundle ID already exist.";
               value 2303;
           }
           enum ONFERR_ET_BUNDLE_CLOSED {
               description "Bundle ID is closed.";
               value 2304;
           }
           enum ONFERR_ET_OUT_OF_BUNDLES {
               description "Too many bundles IDs.";
               value 2305;
           }
           enum ONFERR_ET_BAD_TYPE {
               description "Unsupported or unknown message control type.";
               value 2306;
           }
           enum ONFERR_ET_BAD_FLAGS {
               description "Unsupported, unknown, or inconsistent flags.";
               value 2307;
           }
           enum ONFERR_ET_MSG_BAD_LEN {
               description "Length problem in included message.";
               value 2308;
           }
           enum ONFERR_ET_MSG_BAD_XID {
               description "Inconsistent or duplicate XID.";
               value 2309;
           }
           enum ONFERR_ET_MSG_UNSUP {
               description "Unsupported message in this bundle.";
               value 2310;
           }
           enum ONFERR_ET_MSG_CONFLICT {
               description "Unsupported message combination in this bundle.";
               value 2311;
           }
           enum ONFERR_ET_MSG_TOO_MANY {
               description "Can not handle this many messages in bundle.";
               value 2312;
           }
           enum ONFERR_ET_MSG_FAILED {
               description "One message in bundle failed.";
               value 2313;
           }
           enum ONFERR_ET_TIMEOUT {
               description "Bundle is taking too long.";
               value 2314;
           }
           enum ONFERR_ET_BUNDLE_IN_PROGRESS {
               description "Bundle is locking the resource.";
               value 2315;
           }
       }
   }

Using bundles through RPCs

Defined two RPCs one for sending control message and one for sending add flow message.

    rpc control-bundle {
       description "Control bundles on openflow device.";
       input {
           uses inv:node-context-ref;
           uses onf-ext:bundle-control-grouping;
       }
   }
   rpc add-bundle-messages {
       description "Add messages into bundle on openflow device.";
       input {
           uses inv:node-context-ref;
           uses onf-ext:bundle-common-grouping;
           list messages {
               uses bundle-inner-message-grouping;
           }
       }
   }

Where bundle-inner-message-grouping is defined:

    grouping bundle-inner-message-grouping {
       choice bundle-inner-message {
           case bundle-add-flow-case {
               uses inv:node-context-ref;
               uses flow-types:flow;
           }
           case bundle-update-flow-case {
               uses inv:node-context-ref;
               uses flow-types:flow;
           }
           case bundle-remove-flow-case {
               uses inv:node-context-ref;
               uses flow-types:flow;
           }
           case bundle-add-group-case {
               uses inv:node-context-ref;
               uses group-types:group;
           }
           case bundle-update-group-case {
               uses inv:node-context-ref;
               uses group-types:group;
           }
           case bundle-remove-group-case {
               uses inv:node-context-ref;
               uses group-types:group;
           }
           case bundle-update-port-case {
               uses inv:node-context-ref;
               uses port-types:port-mod;
           }
       }
   }

There are seven cases to add flow, update flow, remove flow, add update and remove groups and update port.

Bundles extension defined as separate feature

Bundles are defined in Openflowplugin as a separate feature.

odl-openflowplugin-onf-extensions

and need to be installed.

Possible use of bundles for resynchronizations

The main feature of the bundles is to all changes are applied on switch at once. We could use this ability to synchronize switch flows after disconnect.

Problems with no bundles synchronization


Without bundles

Correct switch update after disconnect


With bundles

Issues with resync

First problem can appear if a flow is being added or changed during the resync phase, if the flow is being uploaded and not commited yet. In this case and in case the flow installed from other source is installed sooner than bundle, this flow will be deleted.


Issue during resync

  • No labels