From df562823538d8a2a3824a22c2d09a1a4bd9e647a Mon Sep 17 00:00:00 2001 From: meidli Date: Tue, 24 Apr 2018 11:45:06 +0800 Subject: [PATCH] fix igp router id parse error (#76) --- yabgp/message/attribute/nlri/linkstate.py | 36 ++++++++++++++++--- .../unit/message/attribute/nlri/test_bgpls.py | 11 +++--- .../message/attribute/test_mpreachnlri.py | 14 +++++--- yabgp/tests/unit/message/test_update.py | 14 +++++--- 4 files changed, 58 insertions(+), 17 deletions(-) diff --git a/yabgp/message/attribute/nlri/linkstate.py b/yabgp/message/attribute/nlri/linkstate.py index 89cfbb9..e179576 100644 --- a/yabgp/message/attribute/nlri/linkstate.py +++ b/yabgp/message/attribute/nlri/linkstate.py @@ -111,11 +111,11 @@ def parse_nlri(cls, data): descriptor = dict() if _type == 256: # local node descriptor['type'] = 'local_node' - descriptor['value'] = cls.parse_node_descriptor(value) + descriptor['value'] = cls.parse_node_descriptor(value, proto_id) elif _type == 257: # remote node descriptor['type'] = 'remote_node' - descriptor['value'] = cls.parse_node_descriptor(value) + descriptor['value'] = cls.parse_node_descriptor(value, proto_id) # elif _type == 258: # link local/remote identifier # pass elif _type == 259: # ipv4 interface address @@ -152,7 +152,7 @@ def parse_nlri(cls, data): return proto_id, identifier, descriptor_list @classmethod - def parse_node_descriptor(cls, data): + def parse_node_descriptor(cls, data, proto): # +--------------------+-------------------+----------+ # | Sub-TLV Code Point | Description | Length | @@ -168,11 +168,37 @@ def parse_node_descriptor(cls, data): value = data[4: 4+length] data = data[4+length:] if _type == 512: - return_data['as'] = int(binascii.b2a_hex(value), 16) + return_data['as_num'] = int(binascii.b2a_hex(value), 16) elif _type == 513: return_data['bgpls_id'] = str(netaddr.IPAddress(int(binascii.b2a_hex(value), 16))) elif _type == 514: return_data['ospf_area_id'] = str(netaddr.IPAddress(int(binascii.b2a_hex(value), 16))) elif _type == 515: - return_data['igp_router_id'] = str(netaddr.IPAddress(int(binascii.b2a_hex(value), 16))) + # OSPFv2, OSPFv3 non-pseudonode + if (proto == 3 or proto == 6) and length == 4: + return_data['igp_router_id'] = { + "pseudonode": False, + "router_id": str(netaddr.IPAddress(int(binascii.b2a_hex(value), 16))) + } + # OSPFv2, OSPFv3, LAN pseudonode + if (proto == 3 or proto == 6) and length == 8: + return_data['igp_router_id'] = { + "pseudonode": True, + "router_id": str(netaddr.IPAddress(int(binascii.b2a_hex(value[:4]), 16))), + "designated_router_addr": str(netaddr.IPAddress(int(binascii.b2a_hex(value[4:]), 16))) + } + # IS-IS non-pseudonode + if (proto == 1 or proto == 2) and length == 6: + return_data['igp_router_id'] = { + "pseudonode": False, + "iso_node_id": str(binascii.b2a_hex(value)) + } + # IS-IS LAN pseudonode = ISO Node-ID + PSN + # Unpack ISO address + if (proto == 1 or proto == 2) and length == 7: + return_data['igp_router_id'] = { + "pseudonode": True, + "psn": struct.unpack('!B', value[6:7])[0], + "iso_node_id": str(binascii.b2a_hex(value[:6])) + } return return_data diff --git a/yabgp/tests/unit/message/attribute/nlri/test_bgpls.py b/yabgp/tests/unit/message/attribute/nlri/test_bgpls.py index c641def..d9d5e23 100644 --- a/yabgp/tests/unit/message/attribute/nlri/test_bgpls.py +++ b/yabgp/tests/unit/message/attribute/nlri/test_bgpls.py @@ -38,15 +38,18 @@ def test_parse(self): { 'type': 'local_node', 'value': { - 'as': 65534, + 'as_num': 65534, 'bgpls_id': '0.0.0.0', - 'igp_router_id': '0.0.0.3'}}, + 'igp_router_id': {'pseudonode': False, 'iso_node_id': '000000000003'}}}, { 'type': 'remote_node', 'value': { - 'as': 65534, + 'as_num': 65534, 'bgpls_id': '0.0.0.0', - 'igp_router_id': '0.0.0.1'}}, + 'igp_router_id': { + 'pseudonode': False, + 'iso_node_id': '000000000001' + }}}, { 'type': 'link_local_ipv4', 'value': '1.3.0.2'}, diff --git a/yabgp/tests/unit/message/attribute/test_mpreachnlri.py b/yabgp/tests/unit/message/attribute/test_mpreachnlri.py index 292d31a..3b03c9a 100644 --- a/yabgp/tests/unit/message/attribute/test_mpreachnlri.py +++ b/yabgp/tests/unit/message/attribute/test_mpreachnlri.py @@ -277,15 +277,21 @@ def test_linkstate(self): { 'type': 'local_node', 'value': { - 'as': 65534, + 'as_num': 65534, 'bgpls_id': '0.0.0.0', - 'igp_router_id': '0.0.0.1'}}, + 'igp_router_id': { + 'pseudonode': False, + 'iso_node_id': '000000000001' + }}}, { 'type': 'remote_node', 'value': { - 'as': 65534, + 'as_num': 65534, 'bgpls_id': '0.0.0.0', - 'igp_router_id': '0.0.0.3'}}, + 'igp_router_id': { + 'pseudonode': False, + 'iso_node_id': '000000000003' + }}}, {'type': 'link_local_ipv4', 'value': '1.3.0.1'}, {'type': 'link_remote_ipv4', 'value': '1.3.0.2'}]}]} self.assertEqual(data_dict, MpReachNLRI.parse(data[4:])) diff --git a/yabgp/tests/unit/message/test_update.py b/yabgp/tests/unit/message/test_update.py index b3b4a90..b9b43d1 100644 --- a/yabgp/tests/unit/message/test_update.py +++ b/yabgp/tests/unit/message/test_update.py @@ -248,17 +248,23 @@ def test_parse_link_state(self): 'type': 'local_node', 'value': { - 'as': 65534, + 'as_num': 65534, 'bgpls_id': '0.0.0.0', - 'igp_router_id': '0.0.0.1' + 'igp_router_id': { + 'pseudonode': False, + 'iso_node_id': '000000000001' + } } }, { 'type': 'remote_node', 'value': { - 'as': 65534, + 'as_num': 65534, 'bgpls_id': '0.0.0.0', - 'igp_router_id': '0.0.0.3'}}, + 'igp_router_id': { + 'pseudonode': False, + 'iso_node_id': '000000000003' + }}}, { 'type': 'link_local_ipv4', 'value': '1.3.0.1'},