diff options
-rw-r--r-- | ryu/lib/packet/bgp.py | 51 | ||||
-rw-r--r-- | ryu/tests/unit/packet/test_bgp.py | 12 |
2 files changed, 56 insertions, 7 deletions
diff --git a/ryu/lib/packet/bgp.py b/ryu/lib/packet/bgp.py index 6f23b460..4a52fd86 100644 --- a/ryu/lib/packet/bgp.py +++ b/ryu/lib/packet/bgp.py @@ -3073,25 +3073,66 @@ class BGPEvpnEsiLabelExtendedCommunity(_ExtendedCommunity): # | Reserved=0 | ESI Label | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ _VALUE_PACK_STR = '!BB2x3s' - _VALUE_FIELDS = ['subtype', 'flags', 'esi_label'] + _VALUE_FIELDS = ['subtype', 'flags'] - def __init__(self, **kwargs): + def __init__(self, label=None, mpls_label=None, vni=None, **kwargs): super(BGPEvpnEsiLabelExtendedCommunity, self).__init__() self.do_init(BGPEvpnEsiLabelExtendedCommunity, self, kwargs) + if label: + # If binary type label field value is specified, stores it + # and decodes as MPLS label and VNI. + self._label = label + self._mpls_label, _ = mpls.label_from_bin(label) + self._vni = vxlan.vni_from_bin(label) + else: + # If either MPLS label or VNI is specified, stores it + # and encodes into binary type label field value. + self._label = self._serialize_label(mpls_label, vni) + self._mpls_label = mpls_label + self._vni = vni + + def _serialize_label(self, mpls_label, vni): + if mpls_label: + return mpls.label_to_bin(mpls_label, is_bos=True) + elif vni: + return vxlan.vni_to_bin(vni) + else: + return b'\x00' * 3 + @classmethod def parse_value(cls, buf): (subtype, flags, - esi_label) = struct.unpack_from(cls._VALUE_PACK_STR, buf) + label) = struct.unpack_from(cls._VALUE_PACK_STR, buf) return { 'subtype': subtype, 'flags': flags, - 'esi_label': type_desc.Int3.to_user(esi_label), + 'label': label, } def serialize_value(self): return struct.pack(self._VALUE_PACK_STR, self.subtype, self.flags, - type_desc.Int3.from_user(self.esi_label)) + self._label) + + @property + def mpls_label(self): + return self._mpls_label + + @mpls_label.setter + def mpls_label(self, mpls_label): + self._label = mpls.label_to_bin(mpls_label, is_bos=True) + self._mpls_label = mpls_label + self._vni = None # disables VNI + + @property + def vni(self): + return self._vni + + @vni.setter + def vni(self, vni): + self._label = vxlan.vni_to_bin(vni) + self._mpls_label = None # disables ESI label + self._vni = vni @_ExtendedCommunity.register_type(_ExtendedCommunity.EVPN_ES_IMPORT_RT) diff --git a/ryu/tests/unit/packet/test_bgp.py b/ryu/tests/unit/packet/test_bgp.py index 0d28e6a8..760e01b7 100644 --- a/ryu/tests/unit/packet/test_bgp.py +++ b/ryu/tests/unit/packet/test_bgp.py @@ -133,7 +133,11 @@ class Test_bgp(unittest.TestCase): bgp.BGPEvpnMacMobilityExtendedCommunity( subtype=0, flags=0xff, sequence_number=0x11223344), bgp.BGPEvpnEsiLabelExtendedCommunity( - subtype=1, flags=0xff, esi_label=0x112233), + subtype=1, flags=0xff, label=b'\xFF\xFF\xFF'), + bgp.BGPEvpnEsiLabelExtendedCommunity( + subtype=1, flags=0xff, mpls_label=0xfffff), + bgp.BGPEvpnEsiLabelExtendedCommunity( + subtype=1, flags=0xff, vni=0xffffff), bgp.BGPEvpnEsImportRTExtendedCommunity( subtype=2, es_import="aa:bb:cc:dd:ee:ff"), bgp.BGPUnknownExtendedCommunity(type_=99, value=b'abcdefg'), @@ -329,7 +333,11 @@ class Test_bgp(unittest.TestCase): bgp.BGPEvpnMacMobilityExtendedCommunity( subtype=0, flags=0xff, sequence_number=0x11223344), bgp.BGPEvpnEsiLabelExtendedCommunity( - subtype=1, flags=0xff, esi_label=0x112233), + subtype=1, flags=0xff, label=b'\xFF\xFF\xFF'), + bgp.BGPEvpnEsiLabelExtendedCommunity( + subtype=1, flags=0xff, mpls_label=0xfffff), + bgp.BGPEvpnEsiLabelExtendedCommunity( + subtype=1, flags=0xff, vni=0xffffff), bgp.BGPEvpnEsImportRTExtendedCommunity( subtype=2, es_import="aa:bb:cc:dd:ee:ff"), bgp.BGPUnknownExtendedCommunity(type_=99, value=b'abcdefg'), |