From a7b310e1b9ee22ac30a9a7d569b428f2045930b6 Mon Sep 17 00:00:00 2001 From: Dong Zhang <41927498+dzhangalibaba@users.noreply.github.com> Date: Wed, 22 Apr 2020 19:46:23 -0700 Subject: [PATCH] [Vxlan] : adding show vnet/vxlan cmds (#880) * [Vxlan] : adding show vnet/vxlan cmds --- doc/Command-Reference.md | 187 ++++++++++++++++++++++++++ show/main.py | 284 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 471 insertions(+) diff --git a/doc/Command-Reference.md b/doc/Command-Reference.md index 5112f8a429b2..a85b672cfe7c 100644 --- a/doc/Command-Reference.md +++ b/doc/Command-Reference.md @@ -104,6 +104,11 @@ * [VLAN Config commands](#vlan-config-commands) * [FDB](#fdb) * [FDB show commands](#fdb-show-commands) +* [VxLAN & Vnet](#vxlan--vnet) + * [VxLAN](#vxlan) + * [VxLAN show commands](#vxlan-show-commands) + * [Vnet](#vnet) + * [Vnet show commands](#vnet-show-commands) * [Warm Reboot](#warm-reboot) * [Warm Restart](#warm-restart) * [Warm Restart show commands](#warm-restart-show-commands) @@ -5608,6 +5613,188 @@ Clear the FDB table Go Back To [Beginning of the document](#) or [Beginning of this section](#vlan--FDB) +## VxLAN & Vnet + +### VxLAN + +#### VxLAN show commands + +**show vxlan tunnel** + +This command displays brief information about all the vxlans configured in the device. It displays the vxlan tunnel name, source IP address, destination IP address (if configured), tunnel map name and mapping. + +- Usage: + + ``` + show vxlan tunnel + ``` + +- Example: + + ``` + admin@sonic:~$ show vxlan tunnel + vxlan tunnel name source ip destination ip tunnel map name tunnel map mapping(vni -> vlan) + ------------------- ----------- ---------------- ----------------- --------------------------------- + tunnel1 10.10.10.10 + tunnel2 10.10.10.10 20.10.10.10 tmap1 1234 -> 100 + tunnel3 10.10.10.10 30.10.10.10 tmap2 1235 -> 200 + ``` + +**show vxlan name ** + +This command displays configuration. + +- Usage: + + ``` + show vxlan name + ``` + +- Example: + + ``` + admin@sonic:~$ show vxlan name tunnel3 + vxlan tunnel name source ip destination ip tunnel map name tunnel map mapping(vni -> vlan) + ------------------- ----------- ---------------- ----------------- --------------------------------- + tunnel3 10.10.10.10 30.10.10.10 tmap2 1235 -> 200 + ``` + +Go Back To [Beginning of the document](#) or [Beginning of this section](#vxlan--vnet) + +### Vnet + +#### Vnet show commands + +**show vnet brief** + +This command displays brief information about all the vnets configured in the device. It displays the vnet name, vxlan tunnel name, vni and peer list (if configured). + +- Usage: + + ``` + show vnet brief + ``` + +- Example: + + ``` + admin@sonic:~$ show vnet brief + vnet name vxlan tunnel vni peer list + ----------- -------------- ----- ------------------ + Vnet_2000 tunnel1 2000 + Vnet_3000 tunnel1 3000 Vnet_2000,Vnet4000 + ``` + +**show vnet name ** + +This command displays brief information about configured in the device. + +- Usage: + + ``` + show vnet name + ``` + +- Example: + + ``` + admin@sonic:~$ show vnet name Vnet_3000 + vnet name vxlan tunnel vni peer list + ----------- -------------- ----- ------------------ + Vnet_3000 tunnel1 3000 Vnet_2000,Vnet4000 + ``` + +**show vnet interfaces** + +This command displays vnet interfaces information about all the vnets configured in the device. + +- Usage: + + ``` + show vnet interfaces + ``` + +- Example: + + ``` + admin@sonic:~$ show vnet interfaces + vnet name interfaces + ----------- ------------ + Vnet_2000 Ethernet1 + Vnet_3000 Vlan2000 + ``` + +**show vnet neighbors** + +This command displays vnet neighbor information about all the vnets configured in the device. It displays the vnet name, neighbor IP address, neighbor mac address (if configured) and interface. + +- Usage: + + ``` + show vnet neighbors + ``` + +- Example: + + ``` + admin@sonic:~$ show vnet neighbors + Vnet_2000 neighbor mac_address interfaces + ----------- ----------- ------------- ------------ + 11.11.11.11 Ethernet1 + 11.11.11.12 Ethernet1 + + Vnet_3000 neighbor mac_address interfaces + ----------- ----------- ----------------- ------------ + 20.20.20.20 aa:bb:cc:dd:ee:ff Vlan2000 + ``` + +**show vnet routes all** + +This command displays all routes information about all the vnets configured in the device. + +- Usage: + + ``` + show vnet routes all + ``` + +- Example: + + ``` + admin@sonic:~$ show vnet routes all + vnet name prefix nexthop interface + ----------- -------------- --------- ----------- + Vnet_2000 100.100.3.0/24 Ethernet52 + Vnet_3000 100.100.4.0/24 Vlan2000 + + vnet name prefix endpoint mac address vni + ----------- -------------- ---------- ----------------- ----- + Vnet_2000 100.100.1.1/32 10.10.10.1 + Vnet_3000 100.100.2.1/32 10.10.10.2 00:00:00:00:03:04 + ``` + +**show vnet routes tunnel** + +This command displays tunnel routes information about all the vnets configured in the device. + +- Usage: + + ``` + show vnet routes tunnel + ``` + +- Example: + + ``` + admin@sonic:~$ show vnet routes tunnel + vnet name prefix endpoint mac address vni + ----------- -------------- ---------- ----------------- ----- + Vnet_2000 100.100.1.1/32 10.10.10.1 + Vnet_3000 100.100.2.1/32 10.10.10.2 00:00:00:00:03:04 + ``` + +Go Back To [Beginning of the document](#) or [Beginning of this section](#vxlan--vnet) + ## Warm Reboot warm-reboot command initiates a warm reboot of the device. diff --git a/show/main.py b/show/main.py index 73e6fb30bd00..5fd1efd8dfc3 100755 --- a/show/main.py +++ b/show/main.py @@ -2906,5 +2906,289 @@ def autorestart(container_name): body.append([name, container_feature_table[name]['auto_restart']]) click.echo(tabulate(body, header)) +# +# 'vnet' command ("show vnet") +# +@cli.group(cls=AliasedGroup, default_if_no_args=False) +def vnet(): + """Show vnet related information""" + pass + +@vnet.command() +@click.argument('vnet_name', required=True) +def name(vnet_name): + """Show vnet name information""" + config_db = ConfigDBConnector() + config_db.connect() + header = ['vnet name', 'vxlan tunnel', 'vni', 'peer list'] + + # Fetching data from config_db for VNET + vnet_data = config_db.get_entry('VNET', vnet_name) + + def tablelize(vnet_key, vnet_data): + table = [] + if vnet_data: + r = [] + r.append(vnet_key) + r.append(vnet_data.get('vxlan_tunnel')) + r.append(vnet_data.get('vni')) + r.append(vnet_data.get('peer_list')) + table.append(r) + return table + + click.echo(tabulate(tablelize(vnet_name, vnet_data), header)) + +@vnet.command() +def brief(): + """Show vnet brief information""" + config_db = ConfigDBConnector() + config_db.connect() + header = ['vnet name', 'vxlan tunnel', 'vni', 'peer list'] + + # Fetching data from config_db for VNET + vnet_data = config_db.get_table('VNET') + vnet_keys = natsorted(vnet_data.keys()) + + def tablelize(vnet_keys, vnet_data): + table = [] + for k in vnet_keys: + r = [] + r.append(k) + r.append(vnet_data[k].get('vxlan_tunnel')) + r.append(vnet_data[k].get('vni')) + r.append(vnet_data[k].get('peer_list')) + table.append(r) + return table + + click.echo(tabulate(tablelize(vnet_keys, vnet_data), header)) + +@vnet.command() +def interfaces(): + """Show vnet interfaces information""" + config_db = ConfigDBConnector() + config_db.connect() + + header = ['vnet name', 'interfaces'] + + # Fetching data from config_db for interfaces + intfs_data = config_db.get_table("INTERFACE") + vlan_intfs_data = config_db.get_table("VLAN_INTERFACE") + + vnet_intfs = {} + for k, v in intfs_data.items(): + if 'vnet_name' in v: + vnet_name = v['vnet_name'] + if vnet_name in vnet_intfs: + vnet_intfs[vnet_name].append(k) + else: + vnet_intfs[vnet_name] = [k] + + for k, v in vlan_intfs_data.items(): + if 'vnet_name' in v: + vnet_name = v['vnet_name'] + if vnet_name in vnet_intfs: + vnet_intfs[vnet_name].append(k) + else: + vnet_intfs[vnet_name] = [k] + + table = [] + for k, v in vnet_intfs.items(): + r = [] + r.append(k) + r.append(",".join(natsorted(v))) + table.append(r) + + click.echo(tabulate(table, header)) + +@vnet.command() +def neighbors(): + """Show vnet neighbors information""" + config_db = ConfigDBConnector() + config_db.connect() + + header = ['', 'neighbor', 'mac_address', 'interfaces'] + + # Fetching data from config_db for interfaces + intfs_data = config_db.get_table("INTERFACE") + vlan_intfs_data = config_db.get_table("VLAN_INTERFACE") + + vnet_intfs = {} + for k, v in intfs_data.items(): + if 'vnet_name' in v: + vnet_name = v['vnet_name'] + if vnet_name in vnet_intfs: + vnet_intfs[vnet_name].append(k) + else: + vnet_intfs[vnet_name] = [k] + + for k, v in vlan_intfs_data.items(): + if 'vnet_name' in v: + vnet_name = v['vnet_name'] + if vnet_name in vnet_intfs: + vnet_intfs[vnet_name].append(k) + else: + vnet_intfs[vnet_name] = [k] + + appl_db = swsssdk.SonicV2Connector() + appl_db.connect(appl_db.APPL_DB) + + # Fetching data from appl_db for neighbors + nbrs = appl_db.keys(appl_db.APPL_DB, "NEIGH_TABLE*") + nbrs_data = {} + for nbr in nbrs if nbrs else []: + tbl, intf, ip = nbr.split(":", 2) + mac = appl_db.get(appl_db.APPL_DB, nbr, 'neigh') + if intf in nbrs_data: + nbrs_data[intf].append((ip, mac)) + else: + nbrs_data[intf] = [(ip, mac)] + + table = [] + for k, v in vnet_intfs.items(): + v = natsorted(v) + header[0] = k + table = [] + for intf in v: + if intf in nbrs_data: + for ip, mac in nbrs_data[intf]: + r = ["", ip, mac, intf] + table.append(r) + click.echo(tabulate(table, header)) + click.echo("\n") + +@vnet.group() +def routes(): + """Show vnet routes related information""" + pass + +@routes.command() +def all(): + """Show all vnet routes""" + appl_db = swsssdk.SonicV2Connector() + appl_db.connect(appl_db.APPL_DB) + + header = ['vnet name', 'prefix', 'nexthop', 'interface'] + + # Fetching data from appl_db for VNET ROUTES + vnet_rt_keys = appl_db.keys(appl_db.APPL_DB, "VNET_ROUTE_TABLE*") + vnet_rt_keys = natsorted(vnet_rt_keys) if vnet_rt_keys else [] + + table = [] + for k in vnet_rt_keys: + r = [] + r.extend(k.split(":", 2)[1:]) + val = appl_db.get_all(appl_db.APPL_DB, k) + r.append(val.get('nexthop')) + r.append(val.get('ifname')) + table.append(r) + + click.echo(tabulate(table, header)) + + click.echo("\n") + + header = ['vnet name', 'prefix', 'endpoint', 'mac address', 'vni'] + + # Fetching data from appl_db for VNET TUNNEL ROUTES + vnet_rt_keys = appl_db.keys(appl_db.APPL_DB, "VNET_ROUTE_TUNNEL_TABLE*") + vnet_rt_keys = natsorted(vnet_rt_keys) if vnet_rt_keys else [] + + table = [] + for k in vnet_rt_keys: + r = [] + r.extend(k.split(":", 2)[1:]) + val = appl_db.get_all(appl_db.APPL_DB, k) + r.append(val.get('endpoint')) + r.append(val.get('mac_address')) + r.append(val.get('vni')) + table.append(r) + + click.echo(tabulate(table, header)) + +@routes.command() +def tunnel(): + """Show vnet tunnel routes""" + appl_db = swsssdk.SonicV2Connector() + appl_db.connect(appl_db.APPL_DB) + + header = ['vnet name', 'prefix', 'endpoint', 'mac address', 'vni'] + + # Fetching data from appl_db for VNET TUNNEL ROUTES + vnet_rt_keys = appl_db.keys(appl_db.APPL_DB, "VNET_ROUTE_TUNNEL_TABLE*") + vnet_rt_keys = natsorted(vnet_rt_keys) if vnet_rt_keys else [] + + table = [] + for k in vnet_rt_keys: + r = [] + r.extend(k.split(":", 2)[1:]) + val = appl_db.get_all(appl_db.APPL_DB, k) + r.append(val.get('endpoint')) + r.append(val.get('mac_address')) + r.append(val.get('vni')) + table.append(r) + + click.echo(tabulate(table, header)) + +# +# 'vxlan' command ("show vxlan") +# +@cli.group(cls=AliasedGroup, default_if_no_args=False) +def vxlan(): + """Show vxlan related information""" + pass + +@vxlan.command() +@click.argument('vxlan_name', required=True) +def name(vxlan_name): + """Show vxlan name information""" + config_db = ConfigDBConnector() + config_db.connect() + header = ['vxlan tunnel name', 'source ip', 'destination ip', 'tunnel map name', 'tunnel map mapping(vni -> vlan)'] + + # Fetching data from config_db for VXLAN TUNNEL + vxlan_data = config_db.get_entry('VXLAN_TUNNEL', vxlan_name) + + table = [] + if vxlan_data: + r = [] + r.append(vxlan_name) + r.append(vxlan_data.get('src_ip')) + r.append(vxlan_data.get('dst_ip')) + vxlan_map_keys = config_db.keys(config_db.CONFIG_DB, + 'VXLAN_TUNNEL_MAP{}{}{}*'.format(config_db.KEY_SEPARATOR, vxlan_name, config_db.KEY_SEPARATOR)) + if vxlan_map_keys: + vxlan_map_mapping = config_db.get_all(config_db.CONFIG_DB, vxlan_map_keys[0]) + r.append(vxlan_map_keys[0].split(config_db.KEY_SEPARATOR, 2)[2]) + r.append("{} -> {}".format(vxlan_map_mapping.get('vni'), vxlan_map_mapping.get('vlan'))) + table.append(r) + + click.echo(tabulate(table, header)) + +@vxlan.command() +def tunnel(): + """Show vxlan tunnel information""" + config_db = ConfigDBConnector() + config_db.connect() + header = ['vxlan tunnel name', 'source ip', 'destination ip', 'tunnel map name', 'tunnel map mapping(vni -> vlan)'] + + # Fetching data from config_db for VXLAN TUNNEL + vxlan_data = config_db.get_table('VXLAN_TUNNEL') + vxlan_keys = natsorted(vxlan_data.keys()) + + table = [] + for k in vxlan_keys: + r = [] + r.append(k) + r.append(vxlan_data[k].get('src_ip')) + r.append(vxlan_data[k].get('dst_ip')) + vxlan_map_keys = config_db.keys(config_db.CONFIG_DB, + 'VXLAN_TUNNEL_MAP{}{}{}*'.format(config_db.KEY_SEPARATOR,k, config_db.KEY_SEPARATOR)) + if vxlan_map_keys: + vxlan_map_mapping = config_db.get_all(config_db.CONFIG_DB, vxlan_map_keys[0]) + r.append(vxlan_map_keys[0].split(config_db.KEY_SEPARATOR, 2)[2]) + r.append("{} -> {}".format(vxlan_map_mapping.get('vni'), vxlan_map_mapping.get('vlan'))) + table.append(r) + + click.echo(tabulate(table, header)) + if __name__ == '__main__': cli()