diff options
author | Yusuke Iwase <iwase.yusuke0@gmail.com> | 2015-09-30 15:46:58 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2015-09-30 23:06:59 +0900 |
commit | 40acc4bc82719e273a41c0bcfa8e42b7d182c3eb (patch) | |
tree | 0db531ef17c46de93f7d6b63676aabbac6dda75e | |
parent | 927cda4392f1e16f2729b37c46ed7b21e699c9b0 (diff) |
ofproto_v1_[45]_parser: Add parser() for OFPRequestForward
OFPT_REQUESTFORWARD is defined as Asynchronous Message which sent
from OF-Switch to Controller, but currently, OFPRequestForward class
does not have parser() method.
This patch adds parser() method into OFPRequestForward class and
OFPGroupMod/OFPMeterMod classes which forwarded by OFPRequestForward
message.
Signed-off-by: IWASE Yusuke <iwase.yusuke0@gmail.com>
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
-rw-r--r-- | ryu/ofproto/ofproto_v1_4_parser.py | 93 | ||||
-rw-r--r-- | ryu/ofproto/ofproto_v1_5_parser.py | 103 | ||||
-rw-r--r-- | ryu/tests/unit/ofproto/test_parser.py | 12 |
3 files changed, 154 insertions, 54 deletions
diff --git a/ryu/ofproto/ofproto_v1_4_parser.py b/ryu/ofproto/ofproto_v1_4_parser.py index f060ec30..c53909f1 100644 --- a/ryu/ofproto/ofproto_v1_4_parser.py +++ b/ryu/ofproto/ofproto_v1_4_parser.py @@ -1435,6 +1435,7 @@ class OFPMultipartRequest(MsgBase): self._serialize_stats_body() +@_register_parser @_set_msg_type(ofproto.OFPT_METER_MOD) class OFPMeterMod(MsgBase): """ @@ -1472,6 +1473,23 @@ class OFPMeterMod(MsgBase): self.meter_id = meter_id self.bands = bands + @classmethod + def parser(cls, datapath, version, msg_type, msg_len, xid, buf): + msg = super(OFPMeterMod, cls).parser( + datapath, version, msg_type, msg_len, xid, buf) + + (msg.command, msg.flags, msg.meter_id) = struct.unpack_from( + ofproto.OFP_METER_MOD_PACK_STR, buf, ofproto.OFP_HEADER_SIZE) + offset = ofproto.OFP_METER_MOD_SIZE + + msg.bands = [] + while offset < msg.msg_len: + band = OFPMeterBandHeader.parser(buf, offset) + msg.bands.append(band) + offset += band.len + + return msg + def _serialize_body(self): msg_pack_into(ofproto.OFP_METER_MOD_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, @@ -4058,6 +4076,7 @@ class OFPTableStatus(MsgBase): return msg +@_register_parser @_set_msg_type(ofproto.OFPT_REQUESTFORWARD) class OFPRequestForward(MsgInMsgBase): """ @@ -4073,36 +4092,45 @@ class OFPRequestForward(MsgInMsgBase): ================ ====================================================== Example:: + @set_ev_cls(ofp_event.EventOFPRequestForward, MAIN_DISPATCHER) + def request_forward_handler(self, ev): + msg = ev.msg + dp = msg.datapath + ofp = dp.ofproto - def send_request_forward_message(self, datapath): - ofp = datapath.ofproto - ofp_parser = datapath.ofproto_parser - - port = 1 - max_len = 2000 - actions = [ofp_parser.OFPActionOutput(port, max_len)] - - weight = 100 - watch_port = 0 - watch_group = 0 - buckets = [ofp_parser.OFPBucket(weight, watch_port, watch_group, - actions)] - - group_id = 1 - msg = ofp_parser.OFPGroupMod(datapath, ofp.OFPGC_ADD, - ofp.OFPGT_SELECT, group_id, buckets) - - req = ofp_parser.OFPRequestForward(datapath, msg) - datapath.send_msg(req) + if msg.request.msg_type == ofp.OFPT_GROUP_MOD: + self.logger.debug( + 'OFPRequestForward received: request=OFPGroupMod(' + 'command=%d, type=%d, group_id=%d, buckets=%s)', + msg.request.command, msg.request.type, + msg.request.group_id, msg.request.buckets) + elif msg.request.msg_type == ofp.OFPT_METER_MOD: + self.logger.debug( + 'OFPRequestForward received: request=OFPMeterMod(' + 'command=%d, flags=%d, meter_id=%d, bands=%s)', + msg.request.command, msg.request.flags, + msg.request.meter_id, msg.request.bands) + else: + self.logger.debug( + 'OFPRequestForward received: request=Unknown') """ - def __init__(self, datapath, request): + def __init__(self, datapath, request=None): super(OFPRequestForward, self).__init__(datapath) - assert(isinstance(request, OFPGroupMod) or - isinstance(request, OFPMeterMod)) self.request = request + @classmethod + def parser(cls, datapath, version, msg_type, msg_len, xid, buf): + msg = super(OFPRequestForward, cls).parser( + datapath, version, msg_type, msg_len, xid, buf) + req_buf = buf[ofproto.OFP_HEADER_SIZE:] + (_ver, _type, _len, _xid) = ofproto_parser.header(req_buf) + msg.request = ofproto_parser.msg( + datapath, _ver, _type, _len, _xid, req_buf) + return msg + def _serialize_body(self): - tail_buf = self.request.serialize() + assert isinstance(self.request, (OFPGroupMod, OFPMeterMod)) + self.request.serialize() self.buf += self.request.buf @@ -4957,6 +4985,7 @@ class OFPActionExperimenter(OFPAction): buf += self.data +@_register_parser @_set_msg_type(ofproto.OFPT_GROUP_MOD) class OFPGroupMod(MsgBase): """ @@ -5013,6 +5042,22 @@ class OFPGroupMod(MsgBase): self.group_id = group_id self.buckets = buckets + @classmethod + def parser(cls, datapath, version, msg_type, msg_len, xid, buf): + msg = super(OFPGroupMod, cls).parser( + datapath, version, msg_type, msg_len, xid, buf) + (msg.command, msg.type, msg.group_id) = struct.unpack_from( + ofproto.OFP_GROUP_MOD_PACK_STR, buf, ofproto.OFP_HEADER_SIZE) + offset = ofproto.OFP_GROUP_MOD_SIZE + + msg.buckets = [] + while offset < msg.msg_len: + bucket = OFPBucket.parser(buf, offset) + msg.buckets.append(bucket) + offset += bucket.len + + return msg + def _serialize_body(self): msg_pack_into(ofproto.OFP_GROUP_MOD_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, diff --git a/ryu/ofproto/ofproto_v1_5_parser.py b/ryu/ofproto/ofproto_v1_5_parser.py index cad827e9..20f3829e 100644 --- a/ryu/ofproto/ofproto_v1_5_parser.py +++ b/ryu/ofproto/ofproto_v1_5_parser.py @@ -1671,6 +1671,7 @@ class OFPMultipartRequest(MsgBase): self._serialize_stats_body() +@_register_parser @_set_msg_type(ofproto.OFPT_METER_MOD) class OFPMeterMod(MsgBase): """ @@ -1708,6 +1709,23 @@ class OFPMeterMod(MsgBase): self.meter_id = meter_id self.bands = bands + @classmethod + def parser(cls, datapath, version, msg_type, msg_len, xid, buf): + msg = super(OFPMeterMod, cls).parser( + datapath, version, msg_type, msg_len, xid, buf) + + (msg.command, msg.flags, msg.meter_id) = struct.unpack_from( + ofproto.OFP_METER_MOD_PACK_STR, buf, ofproto.OFP_HEADER_SIZE) + offset = ofproto.OFP_METER_MOD_SIZE + + msg.bands = [] + while offset < msg.msg_len: + band = OFPMeterBandHeader.parser(buf, offset) + msg.bands.append(band) + offset += band.len + + return msg + def _serialize_body(self): msg_pack_into(ofproto.OFP_METER_MOD_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, @@ -4666,6 +4684,7 @@ class OFPTableStatus(MsgBase): return msg +@_register_parser @_set_msg_type(ofproto.OFPT_REQUESTFORWARD) class OFPRequestForward(MsgInMsgBase): """ @@ -4681,36 +4700,47 @@ class OFPRequestForward(MsgInMsgBase): ================ ====================================================== Example:: + @set_ev_cls(ofp_event.EventOFPRequestForward, MAIN_DISPATCHER) + def request_forward_handler(self, ev): + msg = ev.msg + dp = msg.datapath + ofp = dp.ofproto - def send_request_forward_message(self, datapath): - ofp = datapath.ofproto - ofp_parser = datapath.ofproto_parser - - port = 1 - max_len = 2000 - actions = [ofp_parser.OFPActionOutput(port, max_len)] - - weight = 100 - watch_port = 0 - watch_group = 0 - buckets = [ofp_parser.OFPBucket(weight, watch_port, watch_group, - actions)] - - group_id = 1 - msg = ofp_parser.OFPGroupMod(datapath, ofp.OFPGC_ADD, - ofp.OFPGT_SELECT, group_id, buckets) - - req = ofp_parser.OFPRequestForward(datapath, msg) - datapath.send_msg(req) + if msg.request.msg_type == ofp.OFPT_GROUP_MOD: + self.logger.debug( + 'OFPRequestForward received: request=OFPGroupMod(' + 'command=%d, type=%d, group_id=%d, command_bucket_id=%d, ' + 'buckets=%s, properties=%s)', + msg.request.command, msg.request.type, + msg.request.group_id, msg.request.command_bucket_id, + msg.request.buckets, repr(msg.request.properties)) + elif msg.request.msg_type == ofp.OFPT_METER_MOD: + self.logger.debug( + 'OFPRequestForward received: request=OFPMeterMod(' + 'command=%d, flags=%d, meter_id=%d, bands=%s)', + msg.request.command, msg.request.flags, + msg.request.meter_id, msg.request.bands) + else: + self.logger.debug( + 'OFPRequestForward received: request=Unknown') """ - def __init__(self, datapath, request): + def __init__(self, datapath, request=None): super(OFPRequestForward, self).__init__(datapath) - assert(isinstance(request, OFPGroupMod) or - isinstance(request, OFPMeterMod)) self.request = request + @classmethod + def parser(cls, datapath, version, msg_type, msg_len, xid, buf): + msg = super(OFPRequestForward, cls).parser( + datapath, version, msg_type, msg_len, xid, buf) + req_buf = buf[ofproto.OFP_HEADER_SIZE:] + (_ver, _type, _len, _xid) = ofproto_parser.header(req_buf) + msg.request = ofproto_parser.msg( + datapath, _ver, _type, _len, _xid, req_buf) + return msg + def _serialize_body(self): - tail_buf = self.request.serialize() + assert isinstance(self.request, (OFPGroupMod, OFPMeterMod)) + self.request.serialize() self.buf += self.request.buf @@ -5940,6 +5970,7 @@ class OFPGroupPropExperimenter(OFPPropCommonExperimenter4ByteData): pass +@_register_parser @_set_msg_type(ofproto.OFPT_GROUP_MOD) class OFPGroupMod(MsgBase): """ @@ -6006,6 +6037,30 @@ class OFPGroupMod(MsgBase): self.buckets = buckets self.properties = properties + @classmethod + def parser(cls, datapath, version, msg_type, msg_len, xid, buf): + msg = super(OFPGroupMod, cls).parser( + datapath, version, msg_type, msg_len, xid, buf) + (msg.command, msg.type, msg.group_id, msg.bucket_array_len, + msg.command_bucket_id) = struct.unpack_from( + ofproto.OFP_GROUP_MOD_PACK_STR, buf, ofproto.OFP_HEADER_SIZE) + offset = ofproto.OFP_GROUP_MOD_SIZE + + bucket_buf = buf[offset:offset + msg.bucket_array_len] + msg.buckets = [] + while bucket_buf: + bucket = OFPBucket.parser(bucket_buf, 0) + msg.buckets.append(bucket) + bucket_buf = bucket_buf[bucket.len:] + offset += msg.bucket_array_len + + rest = buf[offset:offset + msg.msg_len] + while rest: + p, rest = OFPGroupProp.parse(rest) + msg.properties.append(p) + + return msg + def _serialize_body(self): offset = ofproto.OFP_GROUP_MOD_SIZE self.bucket_array_len = 0 diff --git a/ryu/tests/unit/ofproto/test_parser.py b/ryu/tests/unit/ofproto/test_parser.py index 274a6aa3..8b2b6c09 100644 --- a/ryu/tests/unit/ofproto/test_parser.py +++ b/ryu/tests/unit/ofproto/test_parser.py @@ -100,9 +100,9 @@ implemented = { ofproto_v1_4.OFPT_PORT_STATUS: (True, False), ofproto_v1_4.OFPT_PACKET_OUT: (False, True), ofproto_v1_4.OFPT_FLOW_MOD: (False, True), - ofproto_v1_4.OFPT_GROUP_MOD: (False, True), + ofproto_v1_4.OFPT_GROUP_MOD: (True, True), ofproto_v1_4.OFPT_PORT_MOD: (False, True), - ofproto_v1_4.OFPT_METER_MOD: (False, True), + ofproto_v1_4.OFPT_METER_MOD: (True, True), ofproto_v1_4.OFPT_TABLE_MOD: (False, True), ofproto_v1_4.OFPT_MULTIPART_REQUEST: (False, True), ofproto_v1_4.OFPT_MULTIPART_REPLY: (True, False), @@ -114,7 +114,7 @@ implemented = { ofproto_v1_4.OFPT_SET_ASYNC: (False, True), ofproto_v1_4.OFPT_ROLE_STATUS: (True, False), ofproto_v1_4.OFPT_TABLE_STATUS: (True, False), - ofproto_v1_4.OFPT_REQUESTFORWARD: (False, True), + ofproto_v1_4.OFPT_REQUESTFORWARD: (True, True), ofproto_v1_4.OFPT_BUNDLE_CONTROL: (False, True), ofproto_v1_4.OFPT_BUNDLE_ADD_MESSAGE: (False, True), }, @@ -130,9 +130,9 @@ implemented = { ofproto_v1_5.OFPT_PORT_STATUS: (True, False), ofproto_v1_5.OFPT_PACKET_OUT: (False, True), ofproto_v1_5.OFPT_FLOW_MOD: (False, True), - ofproto_v1_5.OFPT_GROUP_MOD: (False, True), + ofproto_v1_5.OFPT_GROUP_MOD: (True, True), ofproto_v1_5.OFPT_PORT_MOD: (False, True), - ofproto_v1_5.OFPT_METER_MOD: (False, True), + ofproto_v1_5.OFPT_METER_MOD: (True, True), ofproto_v1_5.OFPT_TABLE_MOD: (False, True), ofproto_v1_5.OFPT_MULTIPART_REQUEST: (False, True), ofproto_v1_5.OFPT_MULTIPART_REPLY: (True, False), @@ -144,7 +144,7 @@ implemented = { ofproto_v1_5.OFPT_SET_ASYNC: (False, True), ofproto_v1_5.OFPT_ROLE_STATUS: (True, False), ofproto_v1_5.OFPT_TABLE_STATUS: (True, False), - ofproto_v1_5.OFPT_REQUESTFORWARD: (False, True), + ofproto_v1_5.OFPT_REQUESTFORWARD: (True, True), ofproto_v1_5.OFPT_BUNDLE_CONTROL: (True, True), ofproto_v1_5.OFPT_BUNDLE_ADD_MESSAGE: (False, True), ofproto_v1_5.OFPT_CONTROLLER_STATUS: (True, False), |