diff options
author | ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp> | 2014-07-02 18:17:11 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2014-07-03 00:09:23 +0900 |
commit | df7f57e4feded17cfac8c48ec45dbab37f3c35df (patch) | |
tree | 3d01bf619849a0a72c20339b7338452dd0c687bf | |
parent | 972bce0234c706633857fb760801d7a86664488d (diff) |
ospf: add segment routing opaque types
Signed-off-by: ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
-rw-r--r-- | ryu/lib/packet/ospf.py | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/ryu/lib/packet/ospf.py b/ryu/lib/packet/ospf.py index c2d33b96..11be9614 100644 --- a/ryu/lib/packet/ospf.py +++ b/ryu/lib/packet/ospf.py @@ -25,6 +25,7 @@ from ryu.lib.packet import packet_utils from ryu.lib.packet import stream_parser from ryu.lib import addrconv +import logging _VERSION = 2 @@ -68,6 +69,12 @@ ROUTER_LSA_SHORTCUT = 0x20 # Shortcut-ABR specific flag AS_EXTERNAL_METRIC = 0x80 OSPF_OPAQUE_TYPE_UNKNOWN = 0 +OSPF_OPAQUE_TYPE_EXTENDED_PREFIX_LSA = 7 +OSPF_OPAQUE_TYPE_EXTENDED_LINK_LSA = 8 + +OSPF_EXTENDED_PREFIX_TLV = 1 +OSPF_EXTENDED_PREFIX_SID_SUBTLV = 2 + class InvalidChecksum(Exception): pass @@ -415,6 +422,78 @@ class NSSAExternalLSA(LSA): pass +class ExtendedPrefixTLV(StringifyMixin, _TypeDisp): + pass + + +@ExtendedPrefixTLV.register_type(OSPF_EXTENDED_PREFIX_TLV) +class ExtendedPrefixTLV(ExtendedPrefixTLV): + _VALUE_PACK_STR = '!HHBBBB4s' + _VALUE_PACK_LEN = struct.calcsize(_VALUE_PACK_STR) + _VALUE_FIELDS = ['route_type', 'prefix_length', 'address_family', '_pad' + 'prefix'] + + def __init__(self, type_=OSPF_EXTENDED_PREFIX_TLV, length=0, route_type=0, + prefix_length=0, address_family=0, prefix='0.0.0.0'): + self.type_ = type_ + self.length = length + self.route_type = route_type + self.prefix_length = prefix_length + self.address_family = address_family + self.prefix = prefix + + @classmethod + def parser(cls, buf): + rest = buf[cls._VALUE_PACK_LEN:] + buf = buf[:cls._VALUE_PACK_LEN] + (type_, length, route_type, prefix_length, address_family, _pad, + prefix) = struct.unpack_from(cls._VALUE_PACK_STR, buf) + + prefix = addrconv.ipv4.bin_to_text(prefix) + return cls(type_, length, route_type, prefix_length, address_family, + prefix), rest + + def serialize(self): + prefix = addrconv.ipv4.text_to_bin(self.prefix) + return struct.pack(self._VALUE_PACK_STR, OSPF_EXTENDED_PREFIX_TLV, + self._VALUE_PACK_LEN - 4, self.route_type, + self.prefix_length, self.address_family, 0, prefix) + + +@ExtendedPrefixTLV.register_type(OSPF_EXTENDED_PREFIX_SID_SUBTLV) +class PrefixSIDSubTLV(ExtendedPrefixTLV): + _VALUE_PACK_STR = '!HHBBBBHHI' + _VALUE_PACK_LEN = struct.calcsize(_VALUE_PACK_STR) + _VALUE_FIELDS = ['flags', 'mt_id', 'algorithm', '_pad', 'range_size', + '_pad', 'index'] + + def __init__(self, type_=OSPF_EXTENDED_PREFIX_SID_SUBTLV, length=0, + flags=0, mt_id=0, algorithm=0, range_size=0, index=0): + self.type_ = type_ + self.length = length + self.flags = flags + self.mt_id = mt_id + self.algorithm = algorithm + self.range_size = range_size + self.index = index + + @classmethod + def parser(cls, buf): + rest = buf[cls._VALUE_PACK_LEN:] + buf = buf[:cls._VALUE_PACK_LEN] + (type_, length, flags, mt_id, algorithm, _pad, range_size, _pad, + index) = struct.unpack_from(cls._VALUE_PACK_STR, buf) + + return cls(type_, length, flags, mt_id, algorithm, range_size, + index), rest + + def serialize(self): + return struct.pack(self._VALUE_PACK_STR, + OSPF_EXTENDED_PREFIX_SID_SUBTLV, + self._VALUE_PACK_LEN - 4, self.flags, self.mt_id, + self.algorithm, 0, self.range_size, 0, self.index) + + class OpaqueBody(StringifyMixin, _TypeDisp): def __init__(self, tlvs=[]): self.tlvs = tlvs @@ -424,6 +503,44 @@ class OpaqueBody(StringifyMixin, _TypeDisp): (tlv.serialize() for tlv in self.tlvs)) +@OpaqueBody.register_type(OSPF_OPAQUE_TYPE_EXTENDED_PREFIX_LSA) +class ExtendedPrefixOpaqueBody(OpaqueBody): + @classmethod + def parser(cls, buf): + buf = buffer(buf) + tlvs = [] + while buf: + (type_, length) = struct.unpack_from('!HH', buf) + if len(buf[struct.calcsize('!HH'):]) < length: + raise stream_parser.StreamParser.TooSmallException( + '%d < %d' % (len(buf), length)) + tlvcls = ExtendedPrefixTLV._lookup_type(type_) + if tlvcls: + tlv, buf = tlvcls.parser(buf) + tlvs.append(tlv) + + return cls(tlvs) + + +@OpaqueBody.register_type(OSPF_OPAQUE_TYPE_EXTENDED_LINK_LSA) +class ExtendedLinkOpaqueBody(OpaqueBody): + @classmethod + def parser(cls, buf): + buf = buffer(buf) + tlvs = [] + while buf: + (type_, length) = struct.unpack_from('!HH', buf) + if len(buf[struct.calcsize('!HH'):]) < length: + raise stream_parser.StreamParser.TooSmallException( + '%d < %d' % (len(buf), length)) + tlvcls = ExtendedLinkTLV._lookup_type(type_) + if tlvcls: + tlv, buf = tlvcls.parser(buf) + tlvs.append(tlv) + + return cls(tlvs) + + class OpaqueLSA(LSA): @classmethod def parser(cls, buf, opaque_type=OSPF_OPAQUE_TYPE_UNKNOWN): |