Skip to content

Commit c217c0c

Browse files
rvisnupavel-shirshov
authored andcommitted
[show] enhance 'show ip[v6] bgp summary' command (sonic-net#754)
* [show] enhance 'show ip[v6] bgp summary' command * changing ipaddr to ipaddress
1 parent fcfbc7f commit c217c0c

File tree

5 files changed

+185
-9
lines changed

5 files changed

+185
-9
lines changed

doc/Command-Reference.md

+25-5
Original file line numberDiff line numberDiff line change
@@ -1354,6 +1354,26 @@ This command displays the summary of all IPv4 & IPv6 bgp neighbors that are conf
13541354
show ip bgp summary
13551355
```
13561356
1357+
- Example:
1358+
```
1359+
admin@sonic-z9264f-9251:~# show ip bgp summary
1360+
1361+
IPv4 Unicast Summary:
1362+
BGP router identifier 10.1.0.32, local AS number 65100 vrf-id 0
1363+
BGP table version 6465
1364+
RIB entries 12807, using 2001 KiB of memory
1365+
Peers 4, using 83 KiB of memory
1366+
Peer groups 2, using 128 bytes of memory
1367+
1368+
Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd NeighborName
1369+
10.0.0.57 4 64600 3995 4001 0 0 0 00:39:32 6400 Lab-T1-01
1370+
10.0.0.59 4 64600 3995 3998 0 0 0 00:39:32 6400 Lab-T1-02
1371+
10.0.0.61 4 64600 3995 4001 0 0 0 00:39:32 6400 Lab-T1-03
1372+
10.0.0.63 4 64600 3995 3998 0 0 0 00:39:32 6400 NotAvailable
1373+
1374+
Total number of neighbors 4
1375+
```
1376+
13571377
- Example:
13581378
```
13591379
admin@sonic-z9264f-9251:~# show bgp summary
@@ -1515,11 +1535,11 @@ This command displays the summary of all IPv6 bgp neighbors that are configured
15151535
Peers 4, using 83 KiB of memory
15161536
Peer groups 2, using 128 bytes of memory
15171537

1518-
Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
1519-
fc00::72 4 64600 3995 5208 0 0 0 00:39:30 6400
1520-
fc00::76 4 64600 3994 5208 0 0 0 00:39:30 6400
1521-
fc00::7a 4 64600 3993 5208 0 0 0 00:39:30 6400
1522-
fc00::7e 4 64600 3993 5208 0 0 0 00:39:30 6400
1538+
Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd NeighborName
1539+
fc00::72 4 64600 3995 5208 0 0 0 00:39:30 6400 Lab-T1-01
1540+
fc00::76 4 64600 3994 5208 0 0 0 00:39:30 6400 Lab-T1-02
1541+
fc00::7a 4 64600 3993 5208 0 0 0 00:39:30 6400 Lab-T1-03
1542+
fc00::7e 4 64600 3993 5208 0 0 0 00:39:30 6400 Lab-T1-04
15231543

15241544
Total number of neighbors 4
15251545
```

show/bgp_frr_v6.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@ def bgp():
1919
@bgp.command()
2020
def summary():
2121
"""Show summarized information of IPv6 BGP state"""
22-
run_command('sudo vtysh -c "show bgp ipv6 summary"')
22+
try:
23+
device_output = run_command('sudo vtysh -c "show bgp ipv6 summary"', return_cmd=True)
24+
get_bgp_summary_extended(device_output)
25+
except:
26+
run_command('sudo vtysh -c "show bgp ipv6 summary"')
2327

2428

2529
# 'neighbors' subcommand ("show ipv6 bgp neighbors")

show/bgp_quagga_v4.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@ def bgp():
1919
@bgp.command()
2020
def summary():
2121
"""Show summarized information of IPv4 BGP state"""
22-
run_command('sudo vtysh -c "show ip bgp summary"')
22+
try:
23+
device_output = run_command('sudo vtysh -c "show ip bgp summary"', return_cmd=True)
24+
get_bgp_summary_extended(device_output)
25+
except:
26+
run_command('sudo vtysh -c "show ip bgp summary"')
2327

2428

2529
# 'neighbors' subcommand ("show ip bgp neighbors")

show/bgp_quagga_v6.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@ def bgp():
1919
@bgp.command()
2020
def summary():
2121
"""Show summarized information of IPv6 BGP state"""
22-
run_command('sudo vtysh -c "show ipv6 bgp summary"')
22+
try:
23+
device_output = run_command('sudo vtysh -c "show ipv6 bgp summary"', return_cmd=True)
24+
get_bgp_summary_extended(device_output)
25+
except:
26+
run_command('sudo vtysh -c "show ipv6 bgp summary"')
2327

2428

2529
# 'neighbors' subcommand ("show ipv6 bgp neighbors")

show/main.py

+145-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import re
99
import subprocess
1010
import sys
11+
import ipaddr
1112

1213
import click
1314
from click_default_group import DefaultGroup
@@ -188,7 +189,7 @@ def get_routing_stack():
188189
routing_stack = get_routing_stack()
189190

190191

191-
def run_command(command, display_cmd=False):
192+
def run_command(command, display_cmd=False, return_cmd=False):
192193
if display_cmd:
193194
click.echo(click.style("Command: ", fg='cyan') + click.style(command, fg='green'))
194195

@@ -201,6 +202,9 @@ def run_command(command, display_cmd=False):
201202
proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
202203

203204
while True:
205+
if return_cmd:
206+
output = proc.communicate()[0].decode("utf-8")
207+
return output
204208
output = proc.stdout.readline()
205209
if output == "" and proc.poll() is not None:
206210
break
@@ -393,6 +397,146 @@ def run_command_in_alias_mode(command):
393397
sys.exit(rc)
394398

395399

400+
def get_bgp_summary_extended(command_output):
401+
"""
402+
Adds Neighbor name to the show ip[v6] bgp summary command
403+
:param command: command to get bgp summary
404+
"""
405+
static_neighbors, dynamic_neighbors = get_bgp_neighbors_dict()
406+
modified_output = []
407+
my_list = iter(command_output.splitlines())
408+
for element in my_list:
409+
if element.startswith("Neighbor"):
410+
element = "{}\tNeighborName".format(element)
411+
modified_output.append(element)
412+
elif not element or element.startswith("Total number "):
413+
modified_output.append(element)
414+
elif re.match(r"(\*?([0-9A-Fa-f]{1,4}:|\d+.\d+.\d+.\d+))", element.split()[0]):
415+
first_element = element.split()[0]
416+
ip = first_element[1:] if first_element.startswith("*") else first_element
417+
name = get_bgp_neighbor_ip_to_name(ip, static_neighbors, dynamic_neighbors)
418+
if len(element.split()) == 1:
419+
modified_output.append(element)
420+
element = next(my_list)
421+
element = "{}\t{}".format(element, name)
422+
modified_output.append(element)
423+
else:
424+
modified_output.append(element)
425+
click.echo("\n".join(modified_output))
426+
427+
428+
def connect_config_db():
429+
"""
430+
Connects to config_db
431+
"""
432+
config_db = ConfigDBConnector()
433+
config_db.connect()
434+
return config_db
435+
436+
437+
def get_neighbor_dict_from_table(db,table_name):
438+
"""
439+
returns a dict with bgp neighbor ip as key and neighbor name as value
440+
:param table_name: config db table name
441+
:param db: config_db
442+
"""
443+
neighbor_dict = {}
444+
neighbor_data = db.get_table(table_name)
445+
try:
446+
for entry in neighbor_data.keys():
447+
neighbor_dict[entry] = neighbor_data[entry].get(
448+
'name') if 'name' in neighbor_data[entry].keys() else 'NotAvailable'
449+
return neighbor_dict
450+
except:
451+
return neighbor_dict
452+
453+
454+
def is_ipv4_address(ipaddress):
455+
"""
456+
Checks if given ip is ipv4
457+
:param ipaddress: unicode ipv4
458+
:return: bool
459+
"""
460+
try:
461+
ipaddress.IPv4Address(ipaddress)
462+
return True
463+
except ipaddress.AddressValueError as err:
464+
return False
465+
466+
467+
def is_ipv6_address(ipaddress):
468+
"""
469+
Checks if given ip is ipv6
470+
:param ipaddress: unicode ipv6
471+
:return: bool
472+
"""
473+
try:
474+
ipaddress.IPv6Address(ipaddress)
475+
return True
476+
except ipaddress.AddressValueError as err:
477+
return False
478+
479+
480+
def get_dynamic_neighbor_subnet(db):
481+
"""
482+
Returns dict of description and subnet info from bgp_peer_range table
483+
:param db: config_db
484+
"""
485+
dynamic_neighbor = {}
486+
v4_subnet = {}
487+
v6_subnet = {}
488+
neighbor_data = db.get_table('BGP_PEER_RANGE')
489+
try:
490+
for entry in neighbor_data.keys():
491+
new_key = neighbor_data[entry]['ip_range'][0]
492+
new_value = neighbor_data[entry]['name']
493+
if is_ipv4_address(unicode(neighbor_data[entry]['src_address'])):
494+
v4_subnet[new_key] = new_value
495+
elif is_ipv6_address(unicode(neighbor_data[entry]['src_address'])):
496+
v6_subnet[new_key] = new_value
497+
dynamic_neighbor["v4"] = v4_subnet
498+
dynamic_neighbor["v6"] = v6_subnet
499+
return dynamic_neighbor
500+
except:
501+
return neighbor_data
502+
503+
504+
def get_bgp_neighbors_dict():
505+
"""
506+
Uses config_db to get the bgp neighbors and names in dictionary format
507+
:return:
508+
"""
509+
dynamic_neighbors = {}
510+
config_db = connect_config_db()
511+
static_neighbors = get_neighbor_dict_from_table(config_db, 'BGP_NEIGHBOR')
512+
bgp_monitors = get_neighbor_dict_from_table(config_db, 'BGP_MONITORS')
513+
static_neighbors.update(bgp_monitors)
514+
dynamic_neighbors = get_dynamic_neighbor_subnet(config_db)
515+
return static_neighbors, dynamic_neighbors
516+
517+
518+
def get_bgp_neighbor_ip_to_name(ip, static_neighbors, dynamic_neighbors):
519+
"""
520+
return neighbor name for the ip provided
521+
:param ip: ip address unicode
522+
:param static_neighbors: statically defined bgp neighbors dict
523+
:param dynamic_neighbors: subnet of dynamically defined neighbors dict
524+
:return: name of neighbor
525+
"""
526+
if ip in static_neighbors.keys():
527+
return static_neighbors[ip]
528+
elif is_ipv4_address(unicode(ip)):
529+
for subnet in dynamic_neighbors["v4"].keys():
530+
if ipaddress.IPv4Address(unicode(ip)) in ipaddress.IPv4Network(unicode(subnet)):
531+
return dynamic_neighbors["v4"][subnet]
532+
elif is_ipv6_address(unicode(ip)):
533+
for subnet in dynamic_neighbors["v6"].keys():
534+
if ipaddress.IPv6Address(unicode(ip)) in ipaddress.IPv6Network(unicode(subnet)):
535+
return dynamic_neighbors["v6"][subnet]
536+
else:
537+
return "NotAvailable"
538+
539+
396540
CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help', '-?'])
397541

398542
#

0 commit comments

Comments
 (0)