summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorIWAMOTO Toshihiro <iwamoto@valinux.co.jp>2017-12-01 17:49:03 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2017-12-11 22:35:05 +0900
commit9fa0b58199ce64c0819ebd7a7963d377bd1519bd (patch)
tree418f6c573e7d31e15f23f2e7632108c47ee3b129
parent98ea9024edec508ffdcd25cc955d4d6bac1e3668 (diff)
ofproto_v1_3: Add bundle extension
Signed-off-by: IWAMOTO Toshihiro <iwamoto@valinux.co.jp> Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
-rw-r--r--ryu/ofproto/ofproto_v1_3.py33
-rw-r--r--ryu/ofproto/ofproto_v1_3_parser.py168
2 files changed, 200 insertions, 1 deletions
diff --git a/ryu/ofproto/ofproto_v1_3.py b/ryu/ofproto/ofproto_v1_3.py
index 8a562a8d..9fedae26 100644
--- a/ryu/ofproto/ofproto_v1_3.py
+++ b/ryu/ofproto/ofproto_v1_3.py
@@ -866,6 +866,39 @@ ONFT_FLOW_MONITOR_CANCEL = 1870 # controller -> switch
ONFT_FLOW_MONITOR_PAUSED = 1871 # switch -> controller
ONFT_FLOW_MONITOR_RESUMED = 1872 # switch -> controller
+# EXT-230 Bundle extension
+
+# enum onf_exp_type
+ONF_ET_BUNDLE_CONTROL = 2300
+ONF_ET_BUNDLE_ADD_MESSAGE = 2301
+
+ONF_BUNDLE_CTRL_PACK_STR = '!IHH'
+ONF_BUNDLE_CTRL_SIZE = 8
+assert (calcsize(ONF_BUNDLE_CTRL_PACK_STR) ==
+ ONF_BUNDLE_CTRL_SIZE)
+
+ONF_BUNDLE_ADD_MSG_PACK_STR = '!I2xH'
+ONF_BUNDLE_ADD_MSG_SIZE = 16 - OFP_HEADER_SIZE
+assert (calcsize(ONF_BUNDLE_ADD_MSG_PACK_STR) ==
+ ONF_BUNDLE_ADD_MSG_SIZE)
+
+# enum onf_bundle_ctrl_type
+ONF_BCT_OPEN_REQUEST = 0
+ONF_BCT_OPEN_REPLY = 1
+ONF_BCT_CLOSE_REQUEST = 2
+ONF_BCT_CLOSE_REPLY = 3
+ONF_BCT_COMMIT_REQUEST = 4
+ONF_BCT_COMMIT_REPLY = 5
+ONF_BCT_DISCARD_REQUEST = 6
+ONF_BCT_DISCARD_REPLY = 7
+
+# enum onf_bundle_flags
+ONF_BF_ATOMIC = 1 << 0
+ONF_BF_ORDERED = 1 << 1
+
+# enum onf_bundle_prop_type
+ONF_ET_BPT_EXPERIMENTER = 0xffff
+
# struct ofp_error_msg
OFP_ERROR_MSG_PACK_STR = '!HH'
OFP_ERROR_MSG_SIZE = 12
diff --git a/ryu/ofproto/ofproto_v1_3_parser.py b/ryu/ofproto/ofproto_v1_3_parser.py
index c8f2a3d3..48b2513b 100644
--- a/ryu/ofproto/ofproto_v1_3_parser.py
+++ b/ryu/ofproto/ofproto_v1_3_parser.py
@@ -21,6 +21,7 @@ This module also implements some of extensions shown in
"OpenFlow Extensions for 1.3.X Pack 1".
Namely, the following extensions are implemented.
+ - EXT-230 Bundle Extension (without bundle properties)
- EXT-236 Bad flow entry priority error Extension
- EXT-237 Set async config error Extension
- EXT-256 PBB UCA header field Extension
@@ -30,7 +31,6 @@ Namely, the following extensions are implemented.
The following extensions are partially implemented.
- EXT-187 Flow entry notifications Extension (ONFMP_FLOW_MONITOR only)
- - EXT-230 Bundle Extension (Error codes only)
- EXT-232 Table synchronisation Extension (Error codes only)
The following extensions are not implemented yet.
@@ -79,6 +79,15 @@ def _register_parser(cls):
return cls
+def _register_exp_type(experimenter, exp_type):
+ assert exp_type not in OFPExperimenter._subtypes
+
+ def _wrapper(cls):
+ OFPExperimenter._subtypes[(experimenter, exp_type)] = cls
+ return cls
+ return _wrapper
+
+
@ofproto_parser.register_msg_parser(ofproto.OFP_VERSION)
def msg_parser(datapath, version, msg_type, msg_len, xid, buf):
parser = _MSG_PARSERS.get(msg_type)
@@ -402,6 +411,8 @@ class OFPExperimenter(MsgBase):
data Experimenter defined arbitrary additional data
============= =========================================================
"""
+ _subtypes = {}
+
def __init__(self, datapath, experimenter=None, exp_type=None, data=None):
super(OFPExperimenter, self).__init__(datapath)
self.experimenter = experimenter
@@ -417,6 +428,13 @@ class OFPExperimenter(MsgBase):
ofproto.OFP_EXPERIMENTER_HEADER_PACK_STR, msg.buf,
ofproto.OFP_HEADER_SIZE)
msg.data = msg.buf[ofproto.OFP_EXPERIMENTER_HEADER_SIZE:]
+ if (msg.experimenter, msg.exp_type) in cls._subtypes:
+ new_msg = cls._subtypes[
+ (msg.experimenter, msg.exp_type)].parser_subtype(msg)
+ new_msg.set_headers(msg.version, msg.msg_type, msg.msg_len,
+ msg.xid)
+ new_msg.set_buf(msg.buf)
+ return new_msg
return msg
@@ -6245,6 +6263,154 @@ class OFPSetAsync(MsgBase):
self.flow_removed_mask[0], self.flow_removed_mask[1])
+@_register_exp_type(ofproto_common.ONF_EXPERIMENTER_ID,
+ ofproto.ONF_ET_BUNDLE_CONTROL)
+class ONFBundleCtrlMsg(OFPExperimenter):
+ """
+ Bundle control message
+
+ The controller uses this message to create, destroy and commit bundles
+
+ ================ ======================================================
+ Attribute Description
+ ================ ======================================================
+ bundle_id Id of the bundle
+ type One of the following values.
+
+ | ONF_BCT_OPEN_REQUEST
+ | ONF_BCT_OPEN_REPLY
+ | ONF_BCT_CLOSE_REQUEST
+ | ONF_BCT_CLOSE_REPLY
+ | ONF_BCT_COMMIT_REQUEST
+ | ONF_BCT_COMMIT_REPLY
+ | ONF_BCT_DISCARD_REQUEST
+ | ONF_BCT_DISCARD_REPLY
+ flags Bitmap of the following flags.
+
+ | ONF_BF_ATOMIC
+ | ONF_BF_ORDERED
+ properties List of ``OFPBundleProp`` subclass instance
+ ================ ======================================================
+
+ Example::
+
+ def send_bundle_control(self, datapath):
+ ofp = datapath.ofproto
+ ofp_parser = datapath.ofproto_parser
+
+ req = ofp_parser.ONFBundleCtrlMsg(datapath, 7,
+ ofp.ONF_BCT_OPEN_REQUEST,
+ ofp.ONF_BF_ATOMIC, [])
+ datapath.send_msg(req)
+ """
+ def __init__(self, datapath, bundle_id=None, type_=None, flags=None,
+ properties=None):
+ super(ONFBundleCtrlMsg, self).__init__(
+ datapath, ofproto_common.ONF_EXPERIMENTER_ID,
+ ofproto.ONF_ET_BUNDLE_CONTROL)
+ self.bundle_id = bundle_id
+ self.type = type_
+ self.flags = flags
+ self.properties = properties
+
+ def _serialize_body(self):
+ bin_props = bytearray()
+ for p in self.properties:
+ bin_props += p.serialize()
+
+ msg_pack_into(ofproto.OFP_EXPERIMENTER_HEADER_PACK_STR,
+ self.buf, ofproto.OFP_HEADER_SIZE,
+ self.experimenter, self.exp_type)
+ msg_pack_into(ofproto.ONF_BUNDLE_CTRL_PACK_STR,
+ self.buf, ofproto.OFP_EXPERIMENTER_HEADER_SIZE,
+ self.bundle_id, self.type, self.flags)
+ self.buf += bin_props
+
+ @classmethod
+ def parser_subtype(cls, super_msg):
+ (bundle_id, type_, flags) = struct.unpack_from(
+ ofproto.ONF_BUNDLE_CTRL_PACK_STR, super_msg.data)
+ msg = cls(super_msg.datapath, bundle_id, type_, flags)
+ msg.properties = []
+ rest = super_msg.data[ofproto.ONF_BUNDLE_CTRL_SIZE:]
+ while rest:
+ p, rest = OFPBundleProp.parse(rest)
+ msg.properties.append(p)
+
+ return msg
+
+
+class ONFBundleAddMsg(OFPExperimenter):
+ """
+ Bundle add message
+
+ The controller uses this message to add a message to a bundle
+
+ ================ ======================================================
+ Attribute Description
+ ================ ======================================================
+ bundle_id Id of the bundle
+ flags Bitmap of the following flags.
+
+ | ONF_BF_ATOMIC
+ | ONF_BF_ORDERED
+ message ``MsgBase`` subclass instance
+ properties List of ``OFPBundleProp`` subclass instance
+ ================ ======================================================
+
+ Example::
+
+ def send_bundle_add_message(self, datapath):
+ ofp = datapath.ofproto
+ ofp_parser = datapath.ofproto_parser
+
+ msg = ofp_parser.OFPRoleRequest(datapath, ofp.OFPCR_ROLE_EQUAL, 0)
+
+ req = ofp_parser.OFPBundleAddMsg(datapath, 7, ofp.ONF_BF_ATOMIC,
+ msg, [])
+ datapath.send_msg(req)
+ """
+ def __init__(self, datapath, bundle_id, flags, message, properties):
+ super(ONFBundleAddMsg, self).__init__(
+ datapath, ofproto_common.ONF_EXPERIMENTER_ID,
+ ofproto.ONF_ET_BUNDLE_ADD_MESSAGE)
+ self.bundle_id = bundle_id
+ self.flags = flags
+ self.message = message
+ self.properties = properties
+
+ def _serialize_body(self):
+ # The xid of the inner message must be the same as
+ # that of the outer message (OF1.3 Bundle Extension 3.3)
+ if self.message.xid != self.xid:
+ self.message.set_xid(self.xid)
+
+ # Message
+ self.message.serialize()
+ tail_buf = self.message.buf
+
+ # Pad
+ if len(self.properties) > 0:
+ message_len = len(tail_buf)
+ pad_len = utils.round_up(message_len, 8) - message_len
+ msg_pack_into("%dx" % pad_len, tail_buf, message_len)
+
+ # Properties
+ for p in self.properties:
+ tail_buf += p.serialize()
+
+ # Head
+ msg_pack_into(ofproto.OFP_EXPERIMENTER_HEADER_PACK_STR,
+ self.buf, ofproto.OFP_HEADER_SIZE,
+ self.experimenter, self.exp_type)
+ msg_pack_into(ofproto.ONF_BUNDLE_ADD_MSG_PACK_STR,
+ self.buf, ofproto.OFP_EXPERIMENTER_HEADER_SIZE,
+ self.bundle_id, self.flags)
+
+ # Finish
+ self.buf += tail_buf
+
+
nx_actions.generate(
'ryu.ofproto.ofproto_v1_3',
'ryu.ofproto.ofproto_v1_3_parser'