Skip to content

Commit

Permalink
[show] enhance 'show ip[v6] bgp summary' command (sonic-net#754)
Browse files Browse the repository at this point in the history
* [show] enhance 'show ip[v6] bgp summary' command
* changing ipaddr to ipaddress
  • Loading branch information
rvisnu authored and pavel-shirshov committed Jan 15, 2020
1 parent fcfbc7f commit c217c0c
Show file tree
Hide file tree
Showing 5 changed files with 185 additions and 9 deletions.
30 changes: 25 additions & 5 deletions doc/Command-Reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -1354,6 +1354,26 @@ This command displays the summary of all IPv4 & IPv6 bgp neighbors that are conf
show ip bgp summary
```

- Example:
```
admin@sonic-z9264f-9251:~# show ip bgp summary
IPv4 Unicast Summary:
BGP router identifier 10.1.0.32, local AS number 65100 vrf-id 0
BGP table version 6465
RIB entries 12807, using 2001 KiB of memory
Peers 4, using 83 KiB of memory
Peer groups 2, using 128 bytes of memory
Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd NeighborName
10.0.0.57 4 64600 3995 4001 0 0 0 00:39:32 6400 Lab-T1-01
10.0.0.59 4 64600 3995 3998 0 0 0 00:39:32 6400 Lab-T1-02
10.0.0.61 4 64600 3995 4001 0 0 0 00:39:32 6400 Lab-T1-03
10.0.0.63 4 64600 3995 3998 0 0 0 00:39:32 6400 NotAvailable
Total number of neighbors 4
```

- Example:
```
admin@sonic-z9264f-9251:~# show bgp summary
Expand Down Expand Up @@ -1515,11 +1535,11 @@ This command displays the summary of all IPv6 bgp neighbors that are configured
Peers 4, using 83 KiB of memory
Peer groups 2, using 128 bytes of memory
Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
fc00::72 4 64600 3995 5208 0 0 0 00:39:30 6400
fc00::76 4 64600 3994 5208 0 0 0 00:39:30 6400
fc00::7a 4 64600 3993 5208 0 0 0 00:39:30 6400
fc00::7e 4 64600 3993 5208 0 0 0 00:39:30 6400
Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd NeighborName
fc00::72 4 64600 3995 5208 0 0 0 00:39:30 6400 Lab-T1-01
fc00::76 4 64600 3994 5208 0 0 0 00:39:30 6400 Lab-T1-02
fc00::7a 4 64600 3993 5208 0 0 0 00:39:30 6400 Lab-T1-03
fc00::7e 4 64600 3993 5208 0 0 0 00:39:30 6400 Lab-T1-04
Total number of neighbors 4
```
Expand Down
6 changes: 5 additions & 1 deletion show/bgp_frr_v6.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ def bgp():
@bgp.command()
def summary():
"""Show summarized information of IPv6 BGP state"""
run_command('sudo vtysh -c "show bgp ipv6 summary"')
try:
device_output = run_command('sudo vtysh -c "show bgp ipv6 summary"', return_cmd=True)
get_bgp_summary_extended(device_output)
except:
run_command('sudo vtysh -c "show bgp ipv6 summary"')


# 'neighbors' subcommand ("show ipv6 bgp neighbors")
Expand Down
6 changes: 5 additions & 1 deletion show/bgp_quagga_v4.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ def bgp():
@bgp.command()
def summary():
"""Show summarized information of IPv4 BGP state"""
run_command('sudo vtysh -c "show ip bgp summary"')
try:
device_output = run_command('sudo vtysh -c "show ip bgp summary"', return_cmd=True)
get_bgp_summary_extended(device_output)
except:
run_command('sudo vtysh -c "show ip bgp summary"')


# 'neighbors' subcommand ("show ip bgp neighbors")
Expand Down
6 changes: 5 additions & 1 deletion show/bgp_quagga_v6.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ def bgp():
@bgp.command()
def summary():
"""Show summarized information of IPv6 BGP state"""
run_command('sudo vtysh -c "show ipv6 bgp summary"')
try:
device_output = run_command('sudo vtysh -c "show ipv6 bgp summary"', return_cmd=True)
get_bgp_summary_extended(device_output)
except:
run_command('sudo vtysh -c "show ipv6 bgp summary"')


# 'neighbors' subcommand ("show ipv6 bgp neighbors")
Expand Down
146 changes: 145 additions & 1 deletion show/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import re
import subprocess
import sys
import ipaddr

import click
from click_default_group import DefaultGroup
Expand Down Expand Up @@ -188,7 +189,7 @@ def get_routing_stack():
routing_stack = get_routing_stack()


def run_command(command, display_cmd=False):
def run_command(command, display_cmd=False, return_cmd=False):
if display_cmd:
click.echo(click.style("Command: ", fg='cyan') + click.style(command, fg='green'))

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

while True:
if return_cmd:
output = proc.communicate()[0].decode("utf-8")
return output
output = proc.stdout.readline()
if output == "" and proc.poll() is not None:
break
Expand Down Expand Up @@ -393,6 +397,146 @@ def run_command_in_alias_mode(command):
sys.exit(rc)


def get_bgp_summary_extended(command_output):
"""
Adds Neighbor name to the show ip[v6] bgp summary command
:param command: command to get bgp summary
"""
static_neighbors, dynamic_neighbors = get_bgp_neighbors_dict()
modified_output = []
my_list = iter(command_output.splitlines())
for element in my_list:
if element.startswith("Neighbor"):
element = "{}\tNeighborName".format(element)
modified_output.append(element)
elif not element or element.startswith("Total number "):
modified_output.append(element)
elif re.match(r"(\*?([0-9A-Fa-f]{1,4}:|\d+.\d+.\d+.\d+))", element.split()[0]):
first_element = element.split()[0]
ip = first_element[1:] if first_element.startswith("*") else first_element
name = get_bgp_neighbor_ip_to_name(ip, static_neighbors, dynamic_neighbors)
if len(element.split()) == 1:
modified_output.append(element)
element = next(my_list)
element = "{}\t{}".format(element, name)
modified_output.append(element)
else:
modified_output.append(element)
click.echo("\n".join(modified_output))


def connect_config_db():
"""
Connects to config_db
"""
config_db = ConfigDBConnector()
config_db.connect()
return config_db


def get_neighbor_dict_from_table(db,table_name):
"""
returns a dict with bgp neighbor ip as key and neighbor name as value
:param table_name: config db table name
:param db: config_db
"""
neighbor_dict = {}
neighbor_data = db.get_table(table_name)
try:
for entry in neighbor_data.keys():
neighbor_dict[entry] = neighbor_data[entry].get(
'name') if 'name' in neighbor_data[entry].keys() else 'NotAvailable'
return neighbor_dict
except:
return neighbor_dict


def is_ipv4_address(ipaddress):
"""
Checks if given ip is ipv4
:param ipaddress: unicode ipv4
:return: bool
"""
try:
ipaddress.IPv4Address(ipaddress)
return True
except ipaddress.AddressValueError as err:
return False


def is_ipv6_address(ipaddress):
"""
Checks if given ip is ipv6
:param ipaddress: unicode ipv6
:return: bool
"""
try:
ipaddress.IPv6Address(ipaddress)
return True
except ipaddress.AddressValueError as err:
return False


def get_dynamic_neighbor_subnet(db):
"""
Returns dict of description and subnet info from bgp_peer_range table
:param db: config_db
"""
dynamic_neighbor = {}
v4_subnet = {}
v6_subnet = {}
neighbor_data = db.get_table('BGP_PEER_RANGE')
try:
for entry in neighbor_data.keys():
new_key = neighbor_data[entry]['ip_range'][0]
new_value = neighbor_data[entry]['name']
if is_ipv4_address(unicode(neighbor_data[entry]['src_address'])):
v4_subnet[new_key] = new_value
elif is_ipv6_address(unicode(neighbor_data[entry]['src_address'])):
v6_subnet[new_key] = new_value
dynamic_neighbor["v4"] = v4_subnet
dynamic_neighbor["v6"] = v6_subnet
return dynamic_neighbor
except:
return neighbor_data


def get_bgp_neighbors_dict():
"""
Uses config_db to get the bgp neighbors and names in dictionary format
:return:
"""
dynamic_neighbors = {}
config_db = connect_config_db()
static_neighbors = get_neighbor_dict_from_table(config_db, 'BGP_NEIGHBOR')
bgp_monitors = get_neighbor_dict_from_table(config_db, 'BGP_MONITORS')
static_neighbors.update(bgp_monitors)
dynamic_neighbors = get_dynamic_neighbor_subnet(config_db)
return static_neighbors, dynamic_neighbors


def get_bgp_neighbor_ip_to_name(ip, static_neighbors, dynamic_neighbors):
"""
return neighbor name for the ip provided
:param ip: ip address unicode
:param static_neighbors: statically defined bgp neighbors dict
:param dynamic_neighbors: subnet of dynamically defined neighbors dict
:return: name of neighbor
"""
if ip in static_neighbors.keys():
return static_neighbors[ip]
elif is_ipv4_address(unicode(ip)):
for subnet in dynamic_neighbors["v4"].keys():
if ipaddress.IPv4Address(unicode(ip)) in ipaddress.IPv4Network(unicode(subnet)):
return dynamic_neighbors["v4"][subnet]
elif is_ipv6_address(unicode(ip)):
for subnet in dynamic_neighbors["v6"].keys():
if ipaddress.IPv6Address(unicode(ip)) in ipaddress.IPv6Network(unicode(subnet)):
return dynamic_neighbors["v6"][subnet]
else:
return "NotAvailable"


CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help', '-?'])

#
Expand Down

0 comments on commit c217c0c

Please sign in to comment.