diff options
author | Yusuke Iwase <iwase.yusuke0@gmail.com> | 2015-08-19 11:04:46 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2015-08-20 18:28:40 +0900 |
commit | 189d5d5bfd9cbc7490d98f7bd17acb1f6a30169d (patch) | |
tree | cca8d4ed417224e1341d932f7626b12c6da83472 | |
parent | ec73df506e89931dc4d1d578b5c5228354356c8a (diff) |
ofproto_v1_3_parser: Backport OFPPropBase/OFPPropCommonExperimenter4ByteData
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_3_parser.py | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/ryu/ofproto/ofproto_v1_3_parser.py b/ryu/ofproto/ofproto_v1_3_parser.py index 663344cf..19caac69 100644 --- a/ryu/ofproto/ofproto_v1_3_parser.py +++ b/ryu/ofproto/ofproto_v1_3_parser.py @@ -1518,6 +1518,123 @@ class OFPMatch(StringifyMixin): self._flow.ipv6_exthdr = hdr +class OFPPropUnknown(StringifyMixin): + def __init__(self, type_=None, length=None, buf=None): + self.buf = buf + + @classmethod + def parser(cls, buf): + return cls(buf=buf) + + +class OFPPropBase(StringifyMixin): + _PACK_STR = '!HH' + # _TYPES = {} must be an attribute of subclass + + def __init__(self, type_, length=None): + self.type = type_ + self.length = length + + @classmethod + def register_type(cls, type_): + def _register_type(subcls): + cls._TYPES[type_] = subcls + return subcls + return _register_type + + @classmethod + def parse(cls, buf): + (type_, length) = struct.unpack_from(cls._PACK_STR, buf, 0) + rest = buf[utils.round_up(length, 8):] + try: + subcls = cls._TYPES[type_] + except KeyError: + subcls = OFPPropUnknown + prop = subcls.parser(buf) + prop.type = type_ + prop.length = length + return prop, rest + + @classmethod + def get_rest(cls, buf): + (type_, length) = struct.unpack_from(cls._PACK_STR, buf, 0) + offset = struct.calcsize(cls._PACK_STR) + return buf[offset:length] + + def serialize(self): + # Body + # serialize_body should be implemented by subclass + body = bytearray() + body += self.serialize_body() + + # fixup + self.length = len(body) + struct.calcsize(self._PACK_STR) + + # Header + buf = bytearray() + msg_pack_into(self._PACK_STR, buf, 0, self.type, self.length) + buf += body + + # Pad + pad_len = utils.round_up(self.length, 8) - self.length + msg_pack_into("%dx" % pad_len, buf, len(buf)) + + return buf + + +class OFPPropCommonExperimenter4ByteData(StringifyMixin): + _PACK_STR = '!HHII' + _EXPERIMENTER_DATA_PACK_STR = '!I' + _EXPERIMENTER_DATA_SIZE = 4 + + def __init__(self, type_=None, length=None, experimenter=None, + exp_type=None, data=bytearray()): + self.type = type_ + self.length = length + self.experimenter = experimenter + self.exp_type = exp_type + self.data = data + + @classmethod + def parser(cls, buf): + (type_, length, experimenter, exp_type) = struct.unpack_from( + ofproto.OFP_PROP_EXPERIMENTER_PACK_STR, buf, 0) + + rest = buf[ofproto.OFP_PROP_EXPERIMENTER_SIZE:length] + data = [] + while rest: + (d,) = struct.unpack_from( + cls._EXPERIMENTER_DATA_PACK_STR, rest, 0) + data.append(d) + rest = rest[cls._EXPERIMENTER_DATA_SIZE:] + + return cls(type_, length, experimenter, exp_type, data) + + def serialize(self): + offset = 0 + bin_data = bytearray() + for d in self.data: + msg_pack_into(self._EXPERIMENTER_DATA_PACK_STR, + bin_data, offset, d) + offset += self._EXPERIMENTER_DATA_SIZE + + # fixup + self.length = struct.calcsize(self._PACK_STR) + self.length += len(bin_data) + + buf = bytearray() + msg_pack_into(self._PACK_STR, buf, + 0, self.type, self.length, self.experimenter, + self.exp_type) + buf += bin_data + + # Pad + pad_len = utils.round_up(self.length, 8) - self.length + msg_pack_into("%dx" % pad_len, buf, len(buf)) + + return buf + + class OFPMatchField(StringifyMixin): _FIELDS_HEADERS = {} |