From f47570f75e09c34dfbe0f06abf2cf8646cc59182 Mon Sep 17 00:00:00 2001 From: Urs Baumann Date: Wed, 18 Oct 2023 18:13:02 +0200 Subject: [PATCH 1/4] Fix IPv6 Regex for ios and nxos_ssh in get_bgp_neighbors --- napalm/ios/ios.py | 2 +- napalm/nxos_ssh/nxos_ssh.py | 4 +- .../ipv6/expected_result.json | 55 +++++++++++++++++++ .../ipv6/show_bgp_all_summary_vrf_all.txt | 16 ++++++ 4 files changed, 74 insertions(+), 3 deletions(-) create mode 100644 test/nxos_ssh/mocked_data/test_get_bgp_neighbors/ipv6/expected_result.json create mode 100644 test/nxos_ssh/mocked_data/test_get_bgp_neighbors/ipv6/show_bgp_all_summary_vrf_all.txt diff --git a/napalm/ios/ios.py b/napalm/ios/ios.py index df7a78400..322962c70 100644 --- a/napalm/ios/ios.py +++ b/napalm/ios/ios.py @@ -59,7 +59,7 @@ IP_ADDR_REGEX = r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}" IPV4_ADDR_REGEX = IP_ADDR_REGEX IPV6_ADDR_REGEX_1 = r"::" -IPV6_ADDR_REGEX_2 = r"[0-9a-fA-F:]{1,39}::[0-9a-fA-F:]{1,39}" +IPV6_ADDR_REGEX_2 = r"[0-9a-fA-F:]{0,39}::[0-9a-fA-F:]{0,39}" IPV6_ADDR_REGEX_3 = ( r"[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}:" "[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}" diff --git a/napalm/nxos_ssh/nxos_ssh.py b/napalm/nxos_ssh/nxos_ssh.py index bdb01f5a9..18a055c27 100644 --- a/napalm/nxos_ssh/nxos_ssh.py +++ b/napalm/nxos_ssh/nxos_ssh.py @@ -38,7 +38,7 @@ IP_ADDR_REGEX = r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}" IPV4_ADDR_REGEX = IP_ADDR_REGEX IPV6_ADDR_REGEX_1 = r"::" -IPV6_ADDR_REGEX_2 = r"[0-9a-fA-F:]{1,39}::[0-9a-fA-F:]{1,39}" +IPV6_ADDR_REGEX_2 = r"[0-9a-fA-F:]{0,39}::[0-9a-fA-F:]{0,39}" IPV6_ADDR_REGEX_3 = ( r"[0-9a-fA-F]{1,3}:[0-9a-fA-F]{1,3}:[0-9a-fA-F]{1,3}:[0-9a-fA-F]{1,3}:" r"[0-9a-fA-F]{1,3}:[0-9a-fA-F]{1,3}:[0-9a-fA-F]{1,3}:[0-9a-fA-F]{1,3}" @@ -268,7 +268,7 @@ def bgp_normalize_table_data(bgp_table): Normalize this so the line wrap doesn't exit. """ bgp_table = bgp_table.strip() - bgp_multiline_pattern = r"({})\s*\n".format(IPV4_OR_IPV6_REGEX) + bgp_multiline_pattern = r"({})(\s*\d*){0,3}\s*\n".format(IPV4_OR_IPV6_REGEX) # Strip out the newline return re.sub(bgp_multiline_pattern, r"\1", bgp_table) diff --git a/test/nxos_ssh/mocked_data/test_get_bgp_neighbors/ipv6/expected_result.json b/test/nxos_ssh/mocked_data/test_get_bgp_neighbors/ipv6/expected_result.json new file mode 100644 index 000000000..0578cac20 --- /dev/null +++ b/test/nxos_ssh/mocked_data/test_get_bgp_neighbors/ipv6/expected_result.json @@ -0,0 +1,55 @@ +{ + "RED3": { + "router_id": "10.1.0.18", + "peers": { + "2001:db8:4:701::2": { + "is_enabled": true, + "uptime": 1987200, + "remote_as": 65535, + "address_family": { + "ipv6": { + "sent_prefixes": -1, + "accepted_prefixes": -1, + "received_prefixes": 3 + } + }, + "is_up": true, + "remote_id": "0.0.0.0", + "local_as": 65535, + "description": "" + }, + "2001:db8:e0:df::": { + "is_enabled": true, + "uptime": 1900800, + "remote_as": 10, + "address_family": { + "ipv6": { + "sent_prefixes": -1, + "accepted_prefixes": -1, + "received_prefixes": 4 + } + }, + "is_up": true, + "remote_id": "0.0.0.0", + "local_as": 65535, + "description": "" + }, + "2001:db8:e0:dd::1": { + "is_enabled": true, + "uptime": 1900800, + "remote_as": 10, + "address_family": { + "ipv6": { + "sent_prefixes": -1, + "accepted_prefixes": -1, + "received_prefixes": 4 + } + }, + "is_up": true, + "remote_id": "0.0.0.0", + "local_as": 65535, + "description": "" + } + } + } +} diff --git a/test/nxos_ssh/mocked_data/test_get_bgp_neighbors/ipv6/show_bgp_all_summary_vrf_all.txt b/test/nxos_ssh/mocked_data/test_get_bgp_neighbors/ipv6/show_bgp_all_summary_vrf_all.txt new file mode 100644 index 000000000..fdc870fdb --- /dev/null +++ b/test/nxos_ssh/mocked_data/test_get_bgp_neighbors/ipv6/show_bgp_all_summary_vrf_all.txt @@ -0,0 +1,16 @@ +BGP summary information for VRF RED3, address family IPv6 Unicast +BGP router identifier 10.1.0.18, local AS number 65535 +BGP table version is 145, IPv6 Unicast config peers 3, capable peers 3 +12 network entries and 15 paths using 2136 bytes of memory +BGP attribute entries [16/2304], BGP AS path entries [6/72] +BGP community entries [295/10792], BGP clusterlist entries [0/0] +11 received paths for inbound soft reconfiguration +3 identical, 8 modified, 0 filtered received paths using 64 bytes + +Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd +2001:db8:4:701::2 + 4 65535 163664 163693 145 0 0 3w2d 3 +2001:db8:e0:dd::1 + 4 10 327491 327278 145 0 0 3w1d 4 +2001:db8:e0:df:: 4 12345678 + 327465 327268 145 0 0 3w1d 4 From 0b7b84ec64808d03d27b2ae4b7d6ff8e54375851 Mon Sep 17 00:00:00 2001 From: Urs Baumann Date: Wed, 18 Oct 2023 18:20:56 +0200 Subject: [PATCH 2/4] Escape "{}" in .format string --- napalm/nxos_ssh/nxos_ssh.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/napalm/nxos_ssh/nxos_ssh.py b/napalm/nxos_ssh/nxos_ssh.py index 18a055c27..9ba632d98 100644 --- a/napalm/nxos_ssh/nxos_ssh.py +++ b/napalm/nxos_ssh/nxos_ssh.py @@ -268,7 +268,7 @@ def bgp_normalize_table_data(bgp_table): Normalize this so the line wrap doesn't exit. """ bgp_table = bgp_table.strip() - bgp_multiline_pattern = r"({})(\s*\d*){0,3}\s*\n".format(IPV4_OR_IPV6_REGEX) + bgp_multiline_pattern = r"({})(\s*\d*){{0,3}}\s*\n".format(IPV4_OR_IPV6_REGEX) # Strip out the newline return re.sub(bgp_multiline_pattern, r"\1", bgp_table) From 17d3b184acabe7696c867d79d0a86ffeafb20d56 Mon Sep 17 00:00:00 2001 From: Urs Baumann Date: Wed, 18 Oct 2023 23:43:04 +0200 Subject: [PATCH 3/4] Update nxos bgp_normalize_table to support line breakt after long AS --- napalm/nxos_ssh/nxos_ssh.py | 9 ++- .../ipv6/expected_result.json | 68 ++++++++++--------- .../ipv6/show_bgp_all_summary_vrf_all.txt | 23 +++++-- 3 files changed, 61 insertions(+), 39 deletions(-) diff --git a/napalm/nxos_ssh/nxos_ssh.py b/napalm/nxos_ssh/nxos_ssh.py index 9ba632d98..2ceea3030 100644 --- a/napalm/nxos_ssh/nxos_ssh.py +++ b/napalm/nxos_ssh/nxos_ssh.py @@ -264,13 +264,18 @@ def bgp_normalize_table_data(bgp_table): 4 65535 163664 163693 145 0 0 3w2d 3 2001:db8:e0:dd::1 4 10 327491 327278 145 0 0 3w1d 4 + 2001:db8:e0:df:: + 4 12345678 + 327465 327268 145 0 0 3w1d 4 Normalize this so the line wrap doesn't exit. """ bgp_table = bgp_table.strip() - bgp_multiline_pattern = r"({})(\s*\d*){{0,3}}\s*\n".format(IPV4_OR_IPV6_REGEX) + bgp_multiline_pattern = r"({})\s*\n(((\s*\d*){{1,4}})\s*\n)?".format( + IPV4_OR_IPV6_REGEX + ) # Strip out the newline - return re.sub(bgp_multiline_pattern, r"\1", bgp_table) + return re.sub(bgp_multiline_pattern, r"\1\3", bgp_table) def bgp_table_parser(bgp_table): diff --git a/test/nxos_ssh/mocked_data/test_get_bgp_neighbors/ipv6/expected_result.json b/test/nxos_ssh/mocked_data/test_get_bgp_neighbors/ipv6/expected_result.json index 0578cac20..7623433ae 100644 --- a/test/nxos_ssh/mocked_data/test_get_bgp_neighbors/ipv6/expected_result.json +++ b/test/nxos_ssh/mocked_data/test_get_bgp_neighbors/ipv6/expected_result.json @@ -1,55 +1,59 @@ { "RED3": { - "router_id": "10.1.0.18", + "router_id": "10.1.0.18", "peers": { "2001:db8:4:701::2": { - "is_enabled": true, - "uptime": 1987200, - "remote_as": 65535, + "is_enabled": true, + "uptime": 1987200, + "remote_as": 65535, "address_family": { "ipv6": { - "sent_prefixes": -1, - "accepted_prefixes": -1, + "sent_prefixes": -1, + "accepted_prefixes": -1, "received_prefixes": 3 } - }, - "is_up": true, - "remote_id": "0.0.0.0", - "local_as": 65535, + }, + "is_up": true, + "remote_id": "0.0.0.0", + "local_as": 65535, "description": "" - }, + }, "2001:db8:e0:df::": { - "is_enabled": true, - "uptime": 1900800, - "remote_as": 10, + "is_enabled": true, + "uptime": 1900800, + "remote_as": 12345678, "address_family": { "ipv6": { - "sent_prefixes": -1, - "accepted_prefixes": -1, + "sent_prefixes": -1, + "accepted_prefixes": -1, "received_prefixes": 4 } - }, - "is_up": true, - "remote_id": "0.0.0.0", - "local_as": 65535, + }, + "is_up": true, + "remote_id": "0.0.0.0", + "local_as": 65535, "description": "" - }, + }, "2001:db8:e0:dd::1": { - "is_enabled": true, - "uptime": 1900800, - "remote_as": 10, + "is_enabled": true, + "uptime": 1900800, + "remote_as": 10, "address_family": { "ipv6": { - "sent_prefixes": -1, - "accepted_prefixes": -1, + "sent_prefixes": -1, + "accepted_prefixes": -1, "received_prefixes": 4 } - }, - "is_up": true, - "remote_id": "0.0.0.0", - "local_as": 65535, + }, + "is_up": true, + "remote_id": "0.0.0.0", + "local_as": 65535, "description": "" } } - } -} + }, + "global": { + "router_id": "10.1.0.16", + "peers": {} + } +} \ No newline at end of file diff --git a/test/nxos_ssh/mocked_data/test_get_bgp_neighbors/ipv6/show_bgp_all_summary_vrf_all.txt b/test/nxos_ssh/mocked_data/test_get_bgp_neighbors/ipv6/show_bgp_all_summary_vrf_all.txt index fdc870fdb..7287514bc 100644 --- a/test/nxos_ssh/mocked_data/test_get_bgp_neighbors/ipv6/show_bgp_all_summary_vrf_all.txt +++ b/test/nxos_ssh/mocked_data/test_get_bgp_neighbors/ipv6/show_bgp_all_summary_vrf_all.txt @@ -1,3 +1,15 @@ +BGP summary information for VRF default, address family IPv4 Unicast +BGP router identifier 10.1.0.16, local AS number 65535 +BGP table version is 361, IPv4 Unicast config peers 2, capable peers 2 +13 network entries and 17 paths using 2224 bytes of memory +BGP attribute entries [4/576], BGP AS path entries [1/14] +BGP community entries [295/10792], BGP clusterlist entries [0/0] +13 received paths for inbound soft reconfiguration +4 identical, 9 modified, 0 filtered received paths using 72 bytes + +Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd + + BGP summary information for VRF RED3, address family IPv6 Unicast BGP router identifier 10.1.0.18, local AS number 65535 BGP table version is 145, IPv6 Unicast config peers 3, capable peers 3 @@ -7,10 +19,11 @@ BGP community entries [295/10792], BGP clusterlist entries [0/0] 11 received paths for inbound soft reconfiguration 3 identical, 8 modified, 0 filtered received paths using 64 bytes -Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd +Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd 2001:db8:4:701::2 - 4 65535 163664 163693 145 0 0 3w2d 3 + 4 65535 163664 163693 145 0 0 3w2d 3 2001:db8:e0:dd::1 - 4 10 327491 327278 145 0 0 3w1d 4 -2001:db8:e0:df:: 4 12345678 - 327465 327268 145 0 0 3w1d 4 + 4 10 327491 327278 145 0 0 3w1d 4 +2001:db8:e0:df:: + 4 12345678 + 327465 327268 145 0 0 3w1d 4 From e88926b2f79a586d3cf03370fa0cec35743821e9 Mon Sep 17 00:00:00 2001 From: ubaumann Date: Thu, 19 Oct 2023 12:46:43 +0200 Subject: [PATCH 4/4] Change NXOS SSH BGP Multiline regex to support long as with ipv4 --- napalm/nxos_ssh/nxos_ssh.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/napalm/nxos_ssh/nxos_ssh.py b/napalm/nxos_ssh/nxos_ssh.py index 2ceea3030..6fa051937 100644 --- a/napalm/nxos_ssh/nxos_ssh.py +++ b/napalm/nxos_ssh/nxos_ssh.py @@ -271,11 +271,15 @@ def bgp_normalize_table_data(bgp_table): Normalize this so the line wrap doesn't exit. """ bgp_table = bgp_table.strip() - bgp_multiline_pattern = r"({})\s*\n(((\s*\d*){{1,4}})\s*\n)?".format( + # Remove newline after ipv6 address + bgp_ipv6_multiline_pattern = r"({})\s*\n".format(IPV4_OR_IPV6_REGEX) + bgp_table = re.sub(bgp_ipv6_multiline_pattern, r"\1", bgp_table) + # Remove newline after a long AS number + bgp_long_as_multiline_pattern = r"((?:{})\s*\d*\s*\d*)\s*\n".format( IPV4_OR_IPV6_REGEX ) - # Strip out the newline - return re.sub(bgp_multiline_pattern, r"\1\3", bgp_table) + bgp_table = re.sub(bgp_long_as_multiline_pattern, r"\1", bgp_table) + return bgp_table def bgp_table_parser(bgp_table):