Skip to content

Commit

Permalink
ofproto_v1_3: Add bundle extension
Browse files Browse the repository at this point in the history
Signed-off-by: IWAMOTO Toshihiro <iwamoto@valinux.co.jp>
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
  • Loading branch information
toshiiw authored and fujita committed Dec 11, 2017
1 parent 98ea902 commit 9fa0b58
Show file tree
Hide file tree
Showing 2 changed files with 200 additions and 1 deletion.
33 changes: 33 additions & 0 deletions ryu/ofproto/ofproto_v1_3.py
Expand Up @@ -866,6 +866,39 @@
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
Expand Down
168 changes: 167 additions & 1 deletion ryu/ofproto/ofproto_v1_3_parser.py
Expand Up @@ -21,6 +21,7 @@
"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
Expand All @@ -30,7 +31,6 @@
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.
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand All @@ -417,6 +428,13 @@ def parser(cls, datapath, version, msg_type, msg_len, xid, buf):
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

Expand Down Expand Up @@ -6245,6 +6263,154 @@ def _serialize_body(self):
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'
Expand Down

0 comments on commit 9fa0b58

Please sign in to comment.