diff options
author | IWAMOTO Toshihiro <iwamoto@valinux.co.jp> | 2017-12-01 17:49:03 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2017-12-11 22:35:05 +0900 |
commit | 9fa0b58199ce64c0819ebd7a7963d377bd1519bd (patch) | |
tree | 418f6c573e7d31e15f23f2e7632108c47ee3b129 | |
parent | 98ea9024edec508ffdcd25cc955d4d6bac1e3668 (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.py | 33 | ||||
-rw-r--r-- | ryu/ofproto/ofproto_v1_3_parser.py | 168 |
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' |