Skip to content

Commit

Permalink
ios get_bgp_neighbors vrf and safi aware (#768)
Browse files Browse the repository at this point in the history
* get_bgp_neighbors vrf support

* afi string contains afi modifier

* mocked data, minor changes

* afi string with afi modifier

* supported afis

* mocked data

* comments

* typo

* show arp vrf ios test

* black reformated
  • Loading branch information
pehruby authored and mirceaulinic committed Sep 30, 2019
1 parent 5ebc91b commit 8a03992
Show file tree
Hide file tree
Showing 27 changed files with 2,392 additions and 29 deletions.
71 changes: 54 additions & 17 deletions napalm/ios/ios.py
Original file line number Diff line number Diff line change
Expand Up @@ -1465,13 +1465,21 @@ def build_prefix_limit(af_table, limit, prefix_percent, prefix_timeout):
def get_bgp_neighbors(self):
"""BGP neighbor information.
Currently no VRF support. Supports both IPv4 and IPv6.
Supports both IPv4 and IPv6. vrf aware
"""
supported_afi = ["ipv4", "ipv6"]
supported_afi = [
"ipv4 unicast",
"ipv4 multicast",
"ipv6 unicast",
"ipv6 multicast",
"vpnv4 unicast",
"vpnv6 unicast",
"ipv4 mdt",
]

bgp_neighbor_data = dict()
bgp_neighbor_data["global"] = {}

# vrfs where bgp is configured
bgp_config_vrfs = []
# get summary output from device
cmd_bgp_all_sum = "show bgp all summary"
summary_output = self._send_command(cmd_bgp_all_sum).strip()
Expand All @@ -1482,17 +1490,29 @@ def get_bgp_neighbors(self):
# get neighbor output from device
neighbor_output = ""
for afi in supported_afi:
cmd_bgp_neighbor = "show bgp %s unicast neighbors" % afi
neighbor_output += self._send_command(cmd_bgp_neighbor).strip()
# trailing newline required for parsing
neighbor_output += "\n"
if afi in [
"ipv4 unicast",
"ipv4 multicast",
"ipv6 unicast",
"ipv6 multicast",
]:
cmd_bgp_neighbor = "show bgp %s neighbors" % afi
neighbor_output += self._send_command(cmd_bgp_neighbor).strip()
# trailing newline required for parsing
neighbor_output += "\n"
elif afi in ["vpnv4 unicast", "vpnv6 unicast", "ipv4 mdt"]:
cmd_bgp_neighbor = "show bgp %s all neighbors" % afi
neighbor_output += self._send_command(cmd_bgp_neighbor).strip()
# trailing newline required for parsing
neighbor_output += "\n"

# Regular expressions used for parsing BGP summary
parse_summary = {
"patterns": [
# For address family: IPv4 Unicast
# variable afi contains both afi and safi, i.e 'IPv4 Unicast'
{
"regexp": re.compile(r"^For address family: (?P<afi>\S+) "),
"regexp": re.compile(r"^For address family: (?P<afi>[\S ]+)$"),
"record": False,
},
# Capture router_id and local_as values, e.g.:
Expand Down Expand Up @@ -1584,6 +1604,7 @@ def get_bgp_neighbors(self):
{
"regexp": re.compile(
r"^BGP neighbor is (?P<remote_addr>({})|({})),"
r"(\s+vrf (?P<vrf>\S+),)?"
r"\s+remote AS (?P<remote_as>{}).*".format(
IPV4_ADDR_REGEX, IPV6_ADDR_REGEX, ASN_REGEX
)
Expand Down Expand Up @@ -1612,7 +1633,7 @@ def get_bgp_neighbors(self):
# Capture AFI and SAFI names, e.g.:
# For address family: IPv4 Unicast
{
"regexp": re.compile(r"^\s+For address family: (?P<afi>\S+) "),
"regexp": re.compile(r"^\s+For address family: (?P<afi>[\S ]+)$"),
"record": False,
},
# Capture current sent and accepted prefixes, e.g.:
Expand Down Expand Up @@ -1678,6 +1699,13 @@ def get_bgp_neighbors(self):
# a match was found, so update the temp entry with the match's groupdict
neighbor_data_entry.update(match.groupdict())
if item["record"]:
# update list of vrfs where bgp is configured
if not neighbor_data_entry["vrf"]:
vrf_to_add = "global"
else:
vrf_to_add = neighbor_data_entry["vrf"]
if vrf_to_add not in bgp_config_vrfs:
bgp_config_vrfs.append(vrf_to_add)
# Record indicates the last piece of data has been obtained; move
# on to next entry
neighbor_data.append(copy.deepcopy(neighbor_data_entry))
Expand All @@ -1700,9 +1728,12 @@ def get_bgp_neighbors(self):
# check the router_id looks like an ipv4 address
router_id = napalm.base.helpers.ip(router_id, version=4)

# create dict keys for vrfs where bgp is configured
for vrf in bgp_config_vrfs:
bgp_neighbor_data[vrf] = {}
bgp_neighbor_data[vrf]["router_id"] = router_id
bgp_neighbor_data[vrf]["peers"] = {}
# add parsed data to output dict
bgp_neighbor_data["global"]["router_id"] = router_id
bgp_neighbor_data["global"]["peers"] = {}
for entry in summary_data:
remote_addr = napalm.base.helpers.ip(entry["remote_addr"])
afi = entry["afi"].lower()
Expand Down Expand Up @@ -1777,8 +1808,14 @@ def get_bgp_neighbors(self):
# check the remote router_id looks like an ipv4 address
remote_id = napalm.base.helpers.ip(neighbor_entry["remote_id"], version=4)

if remote_addr not in bgp_neighbor_data["global"]["peers"]:
bgp_neighbor_data["global"]["peers"][remote_addr] = {
# get vrf name, if None use 'global'
if neighbor_entry["vrf"]:
vrf = neighbor_entry["vrf"]
else:
vrf = "global"

if remote_addr not in bgp_neighbor_data[vrf]["peers"]:
bgp_neighbor_data[vrf]["peers"][remote_addr] = {
"local_as": napalm.base.helpers.as_number(entry["local_as"]),
"remote_as": napalm.base.helpers.as_number(entry["remote_as"]),
"remote_id": remote_id,
Expand All @@ -1796,7 +1833,7 @@ def get_bgp_neighbors(self):
}
else:
# found previous data for matching remote_addr, but for different afi
existing = bgp_neighbor_data["global"]["peers"][remote_addr]
existing = bgp_neighbor_data[vrf]["peers"][remote_addr]
assert afi not in existing["address_family"]
# compare with existing values and croak if they don't match
assert existing["local_as"] == napalm.base.helpers.as_number(
Expand Down Expand Up @@ -2175,9 +2212,9 @@ def get_arp_table(self, vrf=""):
]
"""
if vrf:
command = 'show arp vrf {} | exclude Incomplete'.format(vrf)
command = "show arp vrf {} | exclude Incomplete".format(vrf)
else:
command = 'show arp | exclude Incomplete'
command = "show arp | exclude Incomplete"

arp_table = []

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
[{
"interface": "Vlan20",
"ip": "172.29.50.1",
"mac": "84:B8:02:76:AC:0E",
"age": 8.0
}, {
"interface": "Vlan20",
"ip": "172.29.50.2",
"mac": "00:19:07:25:34:4A",
"age": 221.0
}, {
"interface": "Vlan20",
"ip": "172.29.50.3",
"mac": "00:24:F7:DD:77:41",
"age": 0.0
}, {
"interface": "Vlan20",
"ip": "172.29.50.10",
"mac": "68:05:CA:12:71:C2",
"age": 37.0
}, {
"interface": "Vlan41",
"ip": "172.29.52.33",
"mac": "84:B8:02:76:AC:0E",
"age": 61.0
}, {
"interface": "Vlan41",
"ip": "172.29.52.34",
"mac": "00:24:F7:DD:77:43",
"age": 0.0
}, {
"interface": "Vlan41",
"ip": "172.29.52.40",
"mac": "A0:99:9B:1C:DF:A7",
"age": 3.0
}, {
"interface": "Vlan41",
"ip": "192.168.81.34",
"mac": "00:24:F7:DD:77:43",
"age": 0.0
}]
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Protocol Address Age (min) Hardware Addr Type Interface
Internet 172.29.50.1 8 84b8.0276.ac0e ARPA Vlan20
Internet 172.29.50.2 221 0019.0725.344a ARPA Vlan20
Internet 172.29.50.3 - 0024.f7dd.7741 ARPA Vlan20
Internet 172.29.50.10 37 6805.ca12.71c2 ARPA Vlan20
Internet 172.29.52.33 61 84b8.0276.ac0e ARPA Vlan41
Internet 172.29.52.34 - 0024.f7dd.7743 ARPA Vlan41
Internet 172.29.52.40 3 a099.9b1c.dfa7 ARPA Vlan41
Internet 192.168.81.34 - 0024.f7dd.7743 ARPA Vlan41
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
{
"global": {
"router_id": "192.168.0.2",
"peers": {
"192.168.0.1": {
"local_as": 1,
"remote_as": 1,
"remote_id": "192.168.0.1",
"is_up": true,
"is_enabled": true,
"description": "iBGP peer nx-osv-1",
"uptime": 2202,
"address_family": {
"ipv4 unicast": {
"received_prefixes": 2,
"accepted_prefixes": 2,
"sent_prefixes": 1
},
"ipv6 unicast": {
"received_prefixes": 0,
"accepted_prefixes": 0,
"sent_prefixes": 0
},
"ipv4 multicast": {
"received_prefixes": 1,
"accepted_prefixes": 1,
"sent_prefixes": 0
}
}
},
"192.168.0.3": {
"local_as": 1,
"remote_as": 1,
"remote_id": "192.168.0.3",
"is_up": true,
"is_enabled": true,
"description": "iBGP peer csr1000v-1",
"uptime": 494,
"address_family": {
"ipv4 unicast": {
"received_prefixes": 1,
"accepted_prefixes": 1,
"sent_prefixes": 1
},
"ipv6 unicast": {
"received_prefixes": 2,
"accepted_prefixes": 2,
"sent_prefixes": 0
},
"ipv4 multicast": {
"received_prefixes": 0,
"accepted_prefixes": 0,
"sent_prefixes": 0
}
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
For address family: IPv4 Unicast
BGP router identifier 192.168.0.2, local AS number 1
BGP table version is 25, main routing table version 25
4 network entries using 576 bytes of memory
4 path entries using 320 bytes of memory
3/3 BGP path/bestpath attribute entries using 456 bytes of memory
0 BGP route-map cache entries using 0 bytes of memory
0 BGP filter-list cache entries using 0 bytes of memory
BGP using 1352 total bytes of memory
BGP activity 10/3 prefixes, 18/11 paths, scan interval 60 secs

Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
192.168.0.1 4 1 46 46 25 0 0 00:36:42 2
192.168.0.3 4 1 18 16 25 0 0 00:08:14 1

For address family: IPv6 Unicast
BGP router identifier 192.168.0.2, local AS number 1
BGP table version is 1, main routing table version 1
2 network entries using 336 bytes of memory
2 path entries using 208 bytes of memory
1/0 BGP path/bestpath attribute entries using 152 bytes of memory
0 BGP route-map cache entries using 0 bytes of memory
0 BGP filter-list cache entries using 0 bytes of memory
BGP using 696 total bytes of memory
BGP activity 10/3 prefixes, 18/11 paths, scan interval 60 secs

Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
192.168.0.1 4 1 46 46 1 0 0 00:36:42 0
192.168.0.3 4 1 18 16 1 0 0 00:08:14 2

For address family: IPv4 Multicast
BGP router identifier 192.168.0.2, local AS number 1
BGP table version is 1, main routing table version 1
1 network entries using 144 bytes of memory
1 path entries using 76 bytes of memory
1/0 BGP path/bestpath attribute entries using 152 bytes of memory
0 BGP route-map cache entries using 0 bytes of memory
0 BGP filter-list cache entries using 0 bytes of memory
BGP using 372 total bytes of memory
BGP activity 10/3 prefixes, 18/11 paths, scan interval 60 secs

Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
192.168.0.1 4 1 46 46 1 0 0 00:36:42 1
192.168.0.3 4 1 18 16 1 0 0 00:08:14 0
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Loading

0 comments on commit 8a03992

Please sign in to comment.