Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Multi-ASIC support for show ip(v6) route #1216

Merged
merged 9 commits into from
Nov 24, 2020
Merged

Added Multi-ASIC support for show ip(v6) route #1216

merged 9 commits into from
Nov 24, 2020

Conversation

gechiang
Copy link
Contributor

@gechiang gechiang commented Nov 4, 2020

Add Multi-ASIC support to handle "show ip/ipv6 route" on multi-ASIC devices

Signed-off-by: Gen-Hwa Chiang [email protected]

- What I did

Add support for multi ASIC CLI options for "show ip/ipv6 route"
2 new options have added

[-n, --namespace] to allow user to display the information for given namespaces (ASIC)
If this option is not present the information from all the namespaces will be displayed

[-d, --display] to allow user to display ip routes related with nexthop that are going through both internal and external interfaces
If this option is not present only ip routes with external interfaces as its nexthop will be display

On single ASIC platform, this options are not valid, so the behavior remains unchanged

- How I did it

  • Request the back-end handler (FRR/Zebra) via the specified BGP docker(s) to dump out the "show ip/ipv6 route" in "json" format
  • Depends on the -d option optionally filter out those route nexthops that are via internal (back-end) interfaces.
  • If after filtering there are no next hops left, then skip that particular route from being displayed as well.
  • At the end of the filtering if user also specified "json" option, then just dump out in json format.
  • If user did not specify "json" option, then interpret the route output similar to how FRR/Zebra does and print out each route.
  • For Multi-ASIC platform if user specified "-d all" option, then the routes from all name spaces will be displayed ASIS without any filtering. Each namespace will be delimited with its own ASIC keyword first before displaying the routes for that name space. If the user requested in json format, then the json file will be formed as a dictionary of name space dictionaries of routes in json format.

- How to verify it

  • Mocked test cases were added to validate the functionality of the changes.
  • Manually tested on Multi-ASIC platform as well as pizzabox platforms.

Help menu

admin@sonic:~$ show ip route -h
Usage: show ip route [OPTIONS] [IPADDRESS] [vrf <vrf_name>] [...]

  Show IP (IPv4) routing table

Options:
  -d, --display TEXT    all|frontend
  -n, --namespace TEXT  Namespace name or all
  --verbose             Enable verbose output
  -?, -h, --help        Show this message and exit.
admin@sonic:~$

show ip route for all routes (include routes that uses internal interface as nexthop) from ASIC0 in multi ASIC device

admin@sonic:~$ show ip route -n asic0 -d all
Codes: K - kernel route, C - connected, S - static, R - RIP,
       O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
       T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
       F - PBR, f - OpenFabric,
       > - selected route, * - FIB route, q - queued route, r - rejected route

C>*10.106.0.4/31 is directly connected, PortChannel1005, 1d00h03m
B>*10.10.192.48/31 [200/0] via 10.0.107.0, PortChannel4001, 1d00h03m
  *                        via 10.0.107.2, PortChannel4002, 1d00h03m
C>*10.0.107.16/32 is directly connected, Loopback4096, 1d00h03m
B>*10.0.107.18/32 [200/0] via 10.0.107.0, PortChannel4001, 1d00h03m
  *                       via 10.0.107.2, PortChannel4002, 1d00h03m
B>*10.10.192.46/31 [200/0] via 10.0.107.0, PortChannel4001, 1d00h03m
  *                        via 10.0.107.2, PortChannel4002, 1d00h03m
B>*10.106.0.12/31 [200/0] via 10.0.107.0, PortChannel4001, 1d00h03m
  *                       via 10.0.107.2, PortChannel4002, 1d00h03m
B>*10.10.192.52/31 [200/0] via 10.0.107.0, PortChannel4001, 1d00h03m
  *                        via 10.0.107.2, PortChannel4002, 1d00h03m
B>*10.10.192.62/31 [200/0] via 10.0.107.0, PortChannel4001, 1d00h03m
  *                        via 10.0.107.2, PortChannel4002, 1d00h03m
B>*10.10.192.38/31 [200/0] via 10.0.107.0, PortChannel4001, 1d00h03m
  *                        via 10.0.107.2, PortChannel4002, 1d00h03m
K>*0.0.0.0/0 [210/0] via 240.127.1.1, eth0, 1d00h03m
B>*10.10.192.36/31 [200/0] via 10.0.107.0, PortChannel4001, 1d00h03m
  *                        via 10.0.107.2, PortChannel4002, 1d00h03m
B>*10.10.192.54/31 [200/0] via 10.0.107.0, PortChannel4001, 1d00h03m
  *                        via 10.0.107.2, PortChannel4002, 1d00h03m
B>*10.0.107.21/32 [200/0] via 10.0.107.2, PortChannel4002, 1d00h03m
B>*10.0.107.8/31 [200/0] via 10.0.107.0, PortChannel4001, 1d00h03m
  *                      via 10.0.107.2, PortChannel4002, 1d00h03m
B>*10.106.0.8/31 [200/0] via 10.0.107.0, PortChannel4001, 1d00h03m
  *                      via 10.0.107.2, PortChannel4002, 1d00h03m
C>*10.0.107.0/31 is directly connected, PortChannel4001, 1d00h03m
B>*10.10.192.44/31 [200/0] via 10.0.107.0, PortChannel4001, 1d00h03m
  *                        via 10.0.107.2, PortChannel4002, 1d00h03m
B>*10.10.192.68/31 [200/0] via 10.0.107.0, PortChannel4001, 1d00h03m
  *                        via 10.0.107.2, PortChannel4002, 1d00h03m
B>*10.0.107.10/31 [200/0] via 10.0.107.0, PortChannel4001, 1d00h03m
  *                       via 10.0.107.2, PortChannel4002, 1d00h03m
B>*10.10.192.64/31 [200/0] via 10.0.107.0, PortChannel4001, 1d00h03m
  *                        via 10.0.107.2, PortChannel4002, 1d00h03m
C>*172.16.132.64/32 is directly connected, Loopback0, 1d00h03m
B>*10.10.192.60/31 [200/0] via 10.0.107.0, PortChannel4001, 1d00h03m
  *                        via 10.0.107.2, PortChannel4002, 1d00h03m
B>*10.10.192.50/31 [200/0] via 10.0.107.0, PortChannel4001, 1d00h03m
  *                        via 10.0.107.2, PortChannel4002, 1d00h03m
B>*10.10.192.34/31 [200/0] via 10.0.107.0, PortChannel4001, 1d00h03m
  *                        via 10.0.107.2, PortChannel4002, 1d00h03m
B>*10.0.107.12/31 [200/0] via 10.0.107.0, PortChannel4001, 1d00h03m
  *                       via 10.0.107.2, PortChannel4002, 1d00h03m
C>*10.0.107.2/31 is directly connected, PortChannel4002, 1d00h03m
B>*10.0.107.17/32 [200/0] via 10.0.107.0, PortChannel4001, 1d00h03m
  *                       via 10.0.107.2, PortChannel4002, 1d00h03m
B>*10.0.107.4/31 [200/0] via 10.0.107.0, PortChannel4001, 1d00h03m
  *                      via 10.0.107.2, PortChannel4002, 1d00h03m
B>*10.10.192.42/31 [200/0] via 10.0.107.0, PortChannel4001, 1d00h03m
  *                        via 10.0.107.2, PortChannel4002, 1d00h03m
B>*10.0.107.19/32 [200/0] via 10.0.107.0, PortChannel4001, 1d00h03m
  *                       via 10.0.107.2, PortChannel4002, 1d00h03m
B>*10.0.107.14/31 [200/0] via 10.0.107.0, PortChannel4001, 1d00h03m
  *                       via 10.0.107.2, PortChannel4002, 1d00h03m
B>*10.10.192.66/31 [200/0] via 10.0.107.0, PortChannel4001, 1d00h03m
  *                        via 10.0.107.2, PortChannel4002, 1d00h03m
B>*10.10.192.70/31 [200/0] via 10.0.107.0, PortChannel4001, 1d00h03m
  *                        via 10.0.107.2, PortChannel4002, 1d00h03m
B>*10.10.192.32/31 [200/0] via 10.0.107.0, PortChannel4001, 1d00h03m
  *                        via 10.0.107.2, PortChannel4002, 1d00h03m
C>*10.106.0.0/31 is directly connected, PortChannel1002, 1d00h03m
B>*10.0.107.6/31 [200/0] via 10.0.107.0, PortChannel4001, 1d00h03m
  *                      via 10.0.107.2, PortChannel4002, 1d00h03m
B>*10.10.192.56/31 [200/0] via 10.0.107.0, PortChannel4001, 1d00h03m
  *                        via 10.0.107.2, PortChannel4002, 1d00h03m
B>*10.10.192.40/31 [200/0] via 10.0.107.0, PortChannel4001, 1d00h03m
  *                        via 10.0.107.2, PortChannel4002, 1d00h03m
B>*10.10.192.58/31 [200/0] via 10.0.107.0, PortChannel4001, 1d00h03m
  *                        via 10.0.107.2, PortChannel4002, 1d00h03m
B>*10.0.107.20/32 [200/0] via 10.0.107.0, PortChannel4001, 1d00h03m
admin@sonic:~$

show ip route (exclude routes that uses internal interface as nexthop) from ASIC0 in multi ASIC device

admin@sonic:~$ show ip route -n asic0
Codes: K - kernel route, C - connected, S - static, R - RIP,
       O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
       T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
       F - PBR, f - OpenFabric,
       > - selected route, * - FIB route, q - queued route, r - rejected route

C>*10.106.0.4/31 is directly connected, PortChannel1005, 1d00h03m
K>*0.0.0.0/0 [210/0] via 240.127.1.1, eth0, 1d00h04m
C>*10.106.0.0/31 is directly connected, PortChannel1002, 1d00h03m
C>*172.16.132.64/32 is directly connected, Loopback0, 1d00h04m
C>*10.0.107.16/32 is directly connected, Loopback4096, 1d00h04m
admin@sonic:~$

show ip route (exclude routes that uses internal interface as nexthop) from ASIC5 in multi ASIC device in json format

admin@sonic:~$ show ip route -n asic5 json
{
  "10.0.107.21/32": [
    {
      "distance": 0,
      "uptime": "1d00h06m",
      "destSelected": true,
      "protocol": "connected",
      "internalFlags": 8,
      "metric": 0,
      "selected": true,
      "installed": true,
      "internalNextHopNum": 1,
      "prefix": "10.0.107.21/32",
      "internalNextHopActiveNum": 1,
      "table": 254,
      "internalStatus": 16,
      "nexthops": [
        {
          "directlyConnected": true,
          "interfaceName": "Loopback4096",
          "interfaceIndex": 9,
          "fib": true,
          "flags": 3,
          "active": true
        }
      ]
    }
  ],
  "172.16.132.64/32": [
    {
      "distance": 0,
      "uptime": "1d00h06m",
      "destSelected": true,
      "protocol": "connected",
      "internalFlags": 8,
      "metric": 0,
      "selected": true,
      "installed": true,
      "internalNextHopNum": 1,
      "prefix": "172.16.132.64/32",
      "internalNextHopActiveNum": 1,
      "table": 254,
      "internalStatus": 16,
      "nexthops": [
        {
          "directlyConnected": true,
          "interfaceName": "Loopback0",
          "interfaceIndex": 8,
          "fib": true,
          "flags": 3,
          "active": true
        }
      ]
    }
  ],
  "10.0.107.14/31": [
    {
      "distance": 200,
      "uptime": "1d00h05m",
      "protocol": "bgp",
      "internalFlags": 5,
      "metric": 0,
      "internalStatus": 0,
      "internalNextHopNum": 1,
      "prefix": "10.0.107.14/31",
      "internalNextHopActiveNum": 0,
      "table": 254,
      "nexthops": [
        {
          "ip": "10.0.107.15",
          "flags": 0,
          "afi": "ipv4"
        }
      ]
    }
  ],
  "10.0.107.2/31": [
    {
      "distance": 200,
      "uptime": "1d00h06m",
      "protocol": "bgp",
      "internalFlags": 5,
      "metric": 0,
      "internalStatus": 0,
      "internalNextHopNum": 1,
      "prefix": "10.0.107.2/31",
      "internalNextHopActiveNum": 0,
      "table": 254,
      "nexthops": [
        {
          "ip": "10.0.107.3",
          "flags": 0,
          "afi": "ipv4"
        }
      ]
    }
  ],
  "10.0.107.10/31": [
    {
      "distance": 200,
      "uptime": "1d00h05m",
      "protocol": "bgp",
      "internalFlags": 5,
      "metric": 0,
      "internalStatus": 0,
      "internalNextHopNum": 1,
      "prefix": "10.0.107.10/31",
      "internalNextHopActiveNum": 0,
      "table": 254,
      "nexthops": [
        {
          "ip": "10.0.107.11",
          "flags": 0,
          "afi": "ipv4"
        }
      ]
    }
  ],
  "10.0.107.6/31": [
    {
      "distance": 200,
      "uptime": "1d00h06m",
      "protocol": "bgp",
      "internalFlags": 5,
      "metric": 0,
      "internalStatus": 0,
      "internalNextHopNum": 1,
      "prefix": "10.0.107.6/31",
      "internalNextHopActiveNum": 0,
      "table": 254,
      "nexthops": [
        {
          "ip": "10.0.107.7",
          "flags": 0,
          "afi": "ipv4"
        }
      ]
    }
  ],
  "0.0.0.0/0": [
    {
      "distance": 210,
      "uptime": "1d00h06m",
      "destSelected": true,
      "protocol": "kernel",
      "internalFlags": 8,
      "metric": 0,
      "selected": true,
      "installed": true,
      "internalNextHopNum": 1,
      "prefix": "0.0.0.0/0",
      "internalNextHopActiveNum": 1,
      "table": 254,
      "internalStatus": 16,
      "nexthops": [
        {
          "interfaceName": "eth0",
          "ip": "240.127.1.1",
          "interfaceIndex": 13,
          "fib": true,
          "flags": 3,
          "active": true,
          "afi": "ipv4"
        }
      ]
    }
  ]
}
admin@sonic:~$

show ip route (exclude routes that uses internal interface as nexthop) from ASIC5 in multi ASIC device

admin@sonic:~$ show ip route -n asic5
Codes: K - kernel route, C - connected, S - static, R - RIP,
       O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
       T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
       F - PBR, f - OpenFabric,
       > - selected route, * - FIB route, q - queued route, r - rejected route

C>*10.0.107.21/32 is directly connected, Loopback4096, 1d00h06m
C>*172.16.132.64/32 is directly connected, Loopback0, 1d00h06m
B 10.0.107.14/31 [200/0] via 10.0.107.15, inactive 1d00h06m
B 10.0.107.2/31 [200/0] via 10.0.107.3, inactive 1d00h06m
B 10.0.107.10/31 [200/0] via 10.0.107.11, inactive 1d00h06m
B 10.0.107.6/31 [200/0] via 10.0.107.7, inactive 1d00h06m
K>*0.0.0.0/0 [210/0] via 240.127.1.1, eth0, 1d00h07m
admin@sonic:~$

show ip route for all routes (exclude routes that uses internal interface as nexthop) from ALL ASICs in multi ASIC device

admin@sonic:~$ show ip route
Codes: K - kernel route, C - connected, S - static, R - RIP,
       O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
       T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
       F - PBR, f - OpenFabric,
       > - selected route, * - FIB route, q - queued route, r - rejected route

C>*10.106.0.4/31 is directly connected, PortChannel1005, 1d00h04m
K>*0.0.0.0/0 [210/0] via 240.127.1.1, eth0, 1d00h05m
C>*10.106.0.0/31 is directly connected, PortChannel1002, 1d00h04m
C>*172.16.132.64/32 is directly connected, Loopback0, 1d00h04m
C>*10.0.107.16/32 is directly connected, Loopback4096, 1d00h04m
C>*10.106.0.8/31 is directly connected, PortChannel1008, 1d00h04m
K>*0.0.0.0/0 [210/0] via 240.127.1.1, eth0, 1d00h05m
C>*10.106.0.12/31 is directly connected, PortChannel1011, 1d00h04m
C>*172.16.132.64/32 is directly connected, Loopback0, 1d00h04m
C>*10.0.107.17/32 is directly connected, Loopback4096, 1d00h04m
C>*10.10.192.34/31 is directly connected, PortChannel1003, 1d00h04m
C>*10.10.192.48/31 is directly connected, PortChannel1013, 1d00h04m
C>*10.10.192.36/31 is directly connected, PortChannel1004, 1d00h04m
C>*10.10.192.32/31 is directly connected, PortChannel1001, 1d00h04m
C>*10.0.107.18/32 is directly connected, Loopback4096, 1d00h04m
C>*10.10.192.46/31 is directly connected, PortChannel1012, 1d00h04m
C>*10.10.192.44/31 is directly connected, PortChannel1010, 1d00h04m
C>*10.10.192.50/31 is directly connected, PortChannel1014, 1d00h04m
C>*10.10.192.38/31 is directly connected, PortChannel1006, 1d00h04m
K>*0.0.0.0/0 [210/0] via 240.127.1.1, eth0, 1d00h04m
C>*10.10.192.40/31 is directly connected, PortChannel1007, 1d00h04m
C>*10.10.192.42/31 is directly connected, PortChannel1009, 1d00h04m
C>*172.16.132.64/32 is directly connected, Loopback0, 1d00h04m
C>*10.10.192.54/31 is directly connected, PortChannel1016, 1d00h04m
C>*10.0.107.19/32 is directly connected, Loopback4096, 1d00h04m
C>*172.16.132.64/32 is directly connected, Loopback0, 1d00h04m
C>*10.10.192.62/31 is directly connected, PortChannel1020, 1d00h04m
C>*10.10.192.60/31 is directly connected, PortChannel1019, 1d00h04m
C>*10.10.192.70/31 is directly connected, PortChannel1024, 1d00h04m
C>*10.10.192.68/31 is directly connected, PortChannel1023, 1d00h04m
C>*10.10.192.52/31 is directly connected, PortChannel1015, 1d00h04m
K>*0.0.0.0/0 [210/0] via 240.127.1.1, eth0, 1d00h05m
C>*10.10.192.66/31 is directly connected, PortChannel1022, 1d00h04m
C>*10.10.192.58/31 is directly connected, PortChannel1018, 1d00h04m
C>*10.10.192.64/31 is directly connected, PortChannel1021, 1d00h04m
C>*10.10.192.56/31 is directly connected, PortChannel1017, 1d00h04m
C>*172.16.132.64/32 is directly connected, Loopback0, 1d00h04m
B 10.0.107.8/31 [200/0] via 10.0.107.9, inactive 1d00h04m
B 10.0.107.0/31 [200/0] via 10.0.107.1, inactive 1d00h04m
B 10.0.107.12/31 [200/0] via 10.0.107.13, inactive 1d00h04m
K>*0.0.0.0/0 [210/0] via 240.127.1.1, eth0, 1d00h05m
B 10.0.107.4/31 [200/0] via 10.0.107.5, inactive 1d00h04m
C>*10.0.107.20/32 is directly connected, Loopback4096, 1d00h04m
C>*10.0.107.21/32 is directly connected, Loopback4096, 1d00h04m
C>*172.16.132.64/32 is directly connected, Loopback0, 1d00h04m
B 10.0.107.14/31 [200/0] via 10.0.107.15, inactive 1d00h04m
B 10.0.107.2/31 [200/0] via 10.0.107.3, inactive 1d00h04m
B 10.0.107.10/31 [200/0] via 10.0.107.11, inactive 1d00h04m
B 10.0.107.6/31 [200/0] via 10.0.107.7, inactive 1d00h04m
K>*0.0.0.0/0 [210/0] via 240.127.1.1, eth0, 1d00h05m
admin@sonic:~$

show ip route for all routes (include routes that uses internal interface as nexthop) from ALL ASICs in multi ASIC device

admin@SONiC:~$ show ip route -d all
Codes: K - kernel route, C - connected, S - static, R - RIP,
       O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
       T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
       F - PBR, f - OpenFabric,
       > - selected route, * - FIB route, q - queued route, r - rejected route

asic0:
K *0.0.0.0/0 [210/0] via 240.127.1.1, eth0, 1d00h13m
B>*0.0.0.0/0 [20/0] via 10.0.0.5, PortChannel0005, 23:15:00
  *                 via 10.0.0.1, PortChannel0002, 23:15:00
S 0.0.0.0/0 [200/0] via 10.3.146.1, inactive 23:15:00
C>*8.0.0.0/32 is directly connected, Loopback4096, 23:15:44
B>*8.0.0.1/32 [200/0] via 10.1.0.2, PortChannel4002, 23:12:40
  *                   via 10.1.0.0, PortChannel4001, 23:12:40
B>*8.0.0.2/32 [200/0] via 10.1.0.2, PortChannel4002, 23:12:40
  *                   via 10.1.0.0, PortChannel4001, 23:12:40
B>*8.0.0.3/32 [200/0] via 10.1.0.2, PortChannel4002, 23:12:40
  *                   via 10.1.0.0, PortChannel4001, 23:12:40
B>*8.0.0.4/32 [200/0] via 10.1.0.0, PortChannel4001, 23:13:20
B>*8.0.0.5/32 [200/0] via 10.1.0.2, PortChannel4002, 23:12:56
C>*10.0.0.0/31 is directly connected, PortChannel0002, 23:15:04
C>*10.0.0.4/31 is directly connected, PortChannel0005, 23:15:03
B>*10.0.0.8/31 [200/0] via 10.1.0.2, PortChannel4002, 23:12:40
  *                    via 10.1.0.0, PortChannel4001, 23:12:40
B>*10.0.0.12/31 [200/0] via 10.1.0.2, PortChannel4002, 23:12:40
  *                     via 10.1.0.0, PortChannel4001, 23:12:40
...
B>*200.0.1.0/26 [200/0] via 10.1.0.2, PortChannel4002, 23:12:40
  *                     via 10.1.0.0, PortChannel4001, 23:12:40

asic1:
K *0.0.0.0/0 [210/0] via 240.127.1.1, eth0, 1d00h13m
B>*0.0.0.0/0 [20/0] via 10.0.0.13, PortChannel0011, 23:15:00
  *                 via 10.0.0.9, PortChannel0008, 23:15:00
S 0.0.0.0/0 [200/0] via 10.3.146.1, inactive 23:15:00
B>*8.0.0.0/32 [200/0] via 10.1.0.6, PortChannel4004, 23:12:29
  *                   via 10.1.0.4, PortChannel4003, 23:12:29
C>*8.0.0.1/32 is directly connected, Loopback4096, 23:15:23
B>*8.0.0.2/32 [200/0] via 10.1.0.6, PortChannel4004, 23:12:28
  *                   via 10.1.0.4, PortChannel4003, 23:12:28
B>*8.0.0.3/32 [200/0] via 10.1.0.6, PortChannel4004, 23:12:28
  *                   via 10.1.0.4, PortChannel4003, 23:12:28
B>*8.0.0.4/32 [200/0] via 10.1.0.4, PortChannel4003, 23:13:22
B>*8.0.0.5/32 [200/0] via 10.1.0.6, PortChannel4004, 23:12:58
B>*10.0.0.0/31 [200/0] via 10.1.0.6, PortChannel4004, 23:12:29
  *                    via 10.1.0.4, PortChannel4003, 23:12:29
...
B>*192.168.199.241/32 [20/0] via 10.0.0.13, PortChannel0011, 23:14:57
  *                          via 10.0.0.9, PortChannel0008, 23:14:57
B>*200.0.1.0/26 [200/0] via 10.1.0.6, PortChannel4004, 23:12:28
  *                     via 10.1.0.4, PortChannel4003, 23:12:28

asic2:
K *0.0.0.0/0 [210/0] via 240.127.1.1, eth0, 1d00h14m
B>*0.0.0.0/0 [200/0] via 10.1.0.10, PortChannel4006, 23:11:15
  *                  via 10.1.0.8, PortChannel4005, 23:11:15
S 0.0.0.0/0 [200/0] via 10.3.146.1, inactive 23:11:15
B>*8.0.0.0/32 [200/0] via 10.1.0.10, PortChannel4006, 23:11:16
  *                   via 10.1.0.8, PortChannel4005, 23:11:16
B>*8.0.0.1/32 [200/0] via 10.1.0.10, PortChannel4006, 23:11:15
  *                   via 10.1.0.8, PortChannel4005, 23:11:15
C>*8.0.0.2/32 is directly connected, Loopback4096, 23:14:51
B>*8.0.0.3/32 [200/0] via 10.1.0.10, PortChannel4006, 23:11:15
  *                   via 10.1.0.8, PortChannel4005, 23:11:15
B>*8.0.0.4/32 [200/0] via 10.1.0.8, PortChannel4005, 23:13:26
B>*8.0.0.5/32 [200/0] via 10.1.0.10, PortChannel4006, 23:13:01
B>*10.0.0.0/31 [200/0] via 10.1.0.10, PortChannel4006, 23:11:16
  *                    via 10.1.0.8, PortChannel4005, 23:11:16
...
B>*192.168.199.241/32 [200/0] via 10.1.0.10, PortChannel4006, 23:11:16
  *                           via 10.1.0.8, PortChannel4005, 23:11:16
B>*200.0.1.0/26 [20/0] via 10.0.0.41, PortChannel0007, 23:14:40
  *                    via 10.0.0.37, PortChannel0004, 23:14:40

asic3:
K *0.0.0.0/0 [210/0] via 240.127.1.1, eth0, 1d00h14m
B>*0.0.0.0/0 [200/0] via 10.1.0.14, PortChannel4008, 23:11:35
  *                  via 10.1.0.12, PortChannel4007, 23:11:35
S 0.0.0.0/0 [200/0] via 10.3.146.1, inactive 23:11:35
B>*8.0.0.0/32 [200/0] via 10.1.0.14, PortChannel4008, 23:11:36
  *                   via 10.1.0.12, PortChannel4007, 23:11:36
B>*8.0.0.1/32 [200/0] via 10.1.0.14, PortChannel4008, 23:11:35
  *                   via 10.1.0.12, PortChannel4007, 23:11:35
B>*8.0.0.2/32 [200/0] via 10.1.0.14, PortChannel4008, 23:11:35
  *                   via 10.1.0.12, PortChannel4007, 23:11:35
C>*8.0.0.3/32 is directly connected, Loopback4096, 23:14:33
B>*8.0.0.4/32 [200/0] via 10.1.0.12, PortChannel4007, 23:13:26
B>*8.0.0.5/32 [200/0] via 10.1.0.14, PortChannel4008, 23:12:20
B>*10.0.0.0/31 [200/0] via 10.1.0.14, PortChannel4008, 23:11:36
  *                    via 10.1.0.12, PortChannel4007, 23:11:36
...
B>*192.168.199.241/32 [200/0] via 10.1.0.14, PortChannel4008, 23:11:36
  *                           via 10.1.0.12, PortChannel4007, 23:11:36
B>*200.0.1.0/26 [200/0] via 10.1.0.14, PortChannel4008, 23:11:35
  *                     via 10.1.0.12, PortChannel4007, 23:11:35

asic4:
K *0.0.0.0/0 [210/0] via 240.127.1.1, eth0, 1d00h14m
B>*0.0.0.0/0 [200/0] via 10.1.0.5, PortChannel4010, 23:13:34
  *                  via 10.1.0.1, PortChannel4009, 23:13:34
S 0.0.0.0/0 [200/0] via 10.3.146.1, inactive 23:13:34
B>*8.0.0.0/32 [200/0] via 10.1.0.1, PortChannel4009, 23:13:35
B>*8.0.0.1/32 [200/0] via 10.1.0.5, PortChannel4010, 23:13:34
B>*8.0.0.2/32 [200/0] via 10.1.0.9, PortChannel4011, 23:13:34
B>*8.0.0.3/32 [200/0] via 10.1.0.13, PortChannel4012, 23:13:30
C>*8.0.0.4/32 is directly connected, Loopback4096, 23:14:03
B>*10.0.0.0/31 [200/0] via 10.1.0.1, PortChannel4009, 23:13:35
B>*10.0.0.4/31 [200/0] via 10.1.0.1, PortChannel4009, 23:13:35
...
B>*192.168.199.241/32 [200/0] via 10.1.0.5, PortChannel4010, 23:13:34
  *                           via 10.1.0.1, PortChannel4009, 23:13:34
B>*200.0.1.0/26 [200/0] via 10.1.0.9, PortChannel4011, 23:13:11

asic5:
K *0.0.0.0/0 [210/0] via 240.127.1.1, eth0, 1d00h14m
B>*0.0.0.0/0 [200/0] via 10.1.0.7, PortChannel4014, 23:13:13
  *                  via 10.1.0.3, PortChannel4013, 23:13:13
S 0.0.0.0/0 [200/0] via 10.3.146.1, inactive 23:13:13
B>*8.0.0.0/32 [200/0] via 10.1.0.3, PortChannel4013, 23:13:14
B>*8.0.0.1/32 [200/0] via 10.1.0.7, PortChannel4014, 23:13:13
B>*8.0.0.2/32 [200/0] via 10.1.0.11, PortChannel4015, 23:13:13
B>*8.0.0.3/32 [200/0] via 10.1.0.15, PortChannel4016, 23:13:13
C>*8.0.0.5/32 is directly connected, Loopback4096, 23:13:46
B>*10.0.0.0/31 [200/0] via 10.1.0.3, PortChannel4013, 23:13:14
B>*10.0.0.4/31 [200/0] via 10.1.0.3, PortChannel4013, 23:13:14
...
B>*192.168.199.241/32 [200/0] via 10.1.0.7, PortChannel4014, 23:13:14
  *                           via 10.1.0.3, PortChannel4013, 23:13:14
B>*200.0.1.0/26 [200/0] via 10.1.0.11, PortChannel4015, 23:12:12

admin@SONiC:~$

show ipv6 route for specific route from all ASICs (include routes that uses internal interface as nexthop) in multi ASIC device

admin@SONiC:~$ show ipv6 route 20c0:a8c7:0:80:: -d all
asic0:
Routing entry for 20c0:a8c7:0:80::/64
  Known via "bgp", distance 20, metric 0, best
  Last update 23:29:15 ago
  * fc00::6, via PortChannel0005
  * fc00::2, via PortChannel0002


asic1:
Routing entry for 20c0:a8c7:0:80::/64
  Known via "bgp", distance 20, metric 0, best
  Last update 23:29:06 ago
  * fc00::e, via PortChannel0011
  * fc00::a, via PortChannel0008


asic2:
Routing entry for 20c0:a8c7:0:80::/64
  Known via "bgp", distance 200, metric 0, best
  Last update 23:26:20 ago
  * 2603:10e2:400:1::15, via PortChannel4006
  * 2603:10e2:400:1::11, via PortChannel4005


asic3:
Routing entry for 20c0:a8c7:0:80::/64
  Known via "bgp", distance 200, metric 0, best
  Last update 23:26:26 ago
  * 2603:10e2:400:1::1d, via PortChannel4008
  * 2603:10e2:400:1::19, via PortChannel4007


asic4:
Routing entry for 20c0:a8c7:0:80::/64
  Known via "bgp", distance 200, metric 0, best
  Last update 23:27:37 ago
  * 2603:10e2:400:1::a, via PortChannel4010
  * 2603:10e2:400:1::2, via PortChannel4009


asic5:
Routing entry for 20c0:a8c7:0:80::/64
  Known via "bgp", distance 200, metric 0, best
  Last update 23:27:12 ago
  * 2603:10e2:400:1::e, via PortChannel4014
  * 2603:10e2:400:1::6, via PortChannel4013


admin@SONiC:~$

show ip route for specific route from all ASICs and how that is combined when only front-end interface filtering applied

admin@SONiC:~$ show ip route 192.168.199.96 -d all
asic0:
Routing entry for 192.168.199.96/32
  Known via "bgp", distance 20, metric 0, best
  Last update 11:48:27 ago
  * 10.0.0.5, via PortChannel0005
  * 10.0.0.1, via PortChannel0002


asic1:
Routing entry for 192.168.199.96/32
  Known via "bgp", distance 20, metric 0, best
  Last update 11:48:34 ago
  * 10.0.0.13, via PortChannel0011
  * 10.0.0.9, via PortChannel0008


asic2:
Routing entry for 192.168.199.96/32
  Known via "bgp", distance 200, metric 0, best
  Last update 11:46:39 ago
  * 10.1.0.10, via PortChannel4006
  * 10.1.0.8, via PortChannel4005


asic3:
Routing entry for 192.168.199.96/32
  Known via "bgp", distance 200, metric 0, best
  Last update 11:46:41 ago
  * 10.1.0.14, via PortChannel4008
  * 10.1.0.12, via PortChannel4007


asic4:
Routing entry for 192.168.199.96/32
  Known via "bgp", distance 200, metric 0, best
  Last update 11:46:38 ago
  * 10.1.0.5, via PortChannel4010
  * 10.1.0.1, via PortChannel4009


asic5:
Routing entry for 192.168.199.96/32
  Known via "bgp", distance 200, metric 0, best
  Last update 11:46:41 ago
  * 10.1.0.7, via PortChannel4014
  * 10.1.0.3, via PortChannel4013


admin@SONiC:~$ show ip route 192.168.199.96 
Routing entry for 192.168.199.96/32
  Known via "bgp", distance 20, metric 0, best
  Last update 11:48:43 ago
  * 10.0.0.5, via PortChannel0005
  * 10.0.0.1, via PortChannel0002
  * 10.0.0.13, via PortChannel0011
  * 10.0.0.9, via PortChannel0008

admin@SONiC:~$ 

- Previous command output (if the output of a command-line utility has changed)

- New command output (if the output of a command-line utility has changed)

** Please Note **
This is the same PR that I raised previously "#1089" which I closed due to design was changed to handle IPV6 as well as the new "merge routes" criteria.

@lgtm-com
Copy link

lgtm-com bot commented Nov 4, 2020

This pull request introduces 10 alerts when merging e86309d into 42efc03 - view on LGTM.com

new alerts:

  • 4 for Unused import
  • 3 for Unused local variable
  • 1 for Testing equality to None
  • 1 for Except block handles 'BaseException'
  • 1 for Variable defined multiple times

combined_route.update(copy.deepcopy(new_route))

def print_show_ip_route_hdr():
# This prints out the show ip route header based on FRR 7.2 version.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you are using frr, why not use its json output. then you do not need to parse anything.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lguohan Yes. I am already getting the json output from FRR of each namespace. The parsing is needed if the display option is for front-end where user does not want to see the routes using nexthops that are associated with back-end port/LAG. Also, merging display is required where the same route may have different nexhop depends on which ASIC was obtained and for display option "front-end" we will need to merge these type of routes from all namespaces and present it to the user.

@gechiang gechiang requested a review from lguohan November 5, 2020 17:47
@lguohan
Copy link
Contributor

lguohan commented Nov 5, 2020

image

please increase the coverage to 95%.

@gechiang
Copy link
Contributor Author

gechiang commented Nov 5, 2020

image

please increase the coverage to 95%.

Yes I will be adding more testcases to improve the coverage. But most likely on another separate PR.

show/bgp_common.py Outdated Show resolved Hide resolved
@gechiang
Copy link
Contributor Author

gechiang commented Nov 6, 2020

In your CLI output I didn't find a case where the next hops are grouped (unless I missed). For e.g., how would the output for the following route look like.

admin@str2-nswitch-acs-4:~$ vtysh -n 1 -c "show ip route 10.0.0.46"
Routing entry for 10.0.0.46/31
  Known via "bgp", distance 200, metric 0, best
  Last update 3d00h06m ago
  * 10.1.0.4, via PortChannel4003
  * 10.1.0.6, via PortChannel4004

admin@str2-nswitch-acs-4:~$ vtysh -n 0 -c "show ip route 10.0.0.46"
Routing entry for 10.0.0.46/31
  Known via "bgp", distance 200, metric 0, best
  Last update 02:11:06 ago
  * 10.1.0.0, via PortChannel4001
  * 10.1.0.2, via PortChannel4002

Can you add an example for the following output:

admin@str2-nswitch-acs-4:~$ show ip route 10.0.0.46

The sample you asked actually gets filtered out completely as their nexthops are all back-end interface (LAG) so just based on these two it will not show any output when it is merged. I understood what you are looking for and I will provide a sample that shows this merged output.

@gechiang gechiang requested a review from smaheshm November 14, 2020 07:50
@sonic-net sonic-net deleted a comment from rlhui Nov 15, 2020
Copy link
Contributor

@arlakshm arlakshm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as comments

Comment on lines 350 to 352
if display is not None:
print "display option is not applicable for non-multi-asic platform"
return
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The display option argument validation is done on the top of the function. This code is duplicate ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@arlakshm Yes. it got covered at the top already. Will remove it.

for name_space, ns_route in sorted(combined_route.items()):
print "{}:".format(name_space)
print_ip_routes(ns_route, filter_by_ip)
print
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we removed this extra print

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@arlakshm Sure. I was purposely adding a line here so that there is some separation between each ASIC name space region. I will remove this print.

print_show_ip_route_hdr()
if print_ns_str:
for name_space, ns_route in sorted(combined_route.items()):
print "{}:".format(name_space)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you change all the print statement to be python3 compatible ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@arlakshm Sure. Will replace them to be python3 compatible.

Comment on lines 235 to 237
while len(additional_nh_l):
a_nh = additional_nh_l.pop()
combined_route[route][j]['nexthops'].append(a_nh)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use + operator here ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@arlakshm Agreed. will replace the while loop with + operator to combine the nexthop list.

# The following protocols do not have multi-nexthops. mbrship test with small list is faster than small set
# If other protocol are also single nexthop not in this list just add them
single_nh_proto = ["connected"]
new_info_l = copy.deepcopy(r_info_l)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do need to a deepcopy here ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@arlakshm Agreed. there is no need to have deepcopy here. will remove it.

Comment on lines 323 to 334
handling multi-ASIC by gathering the output from specified/all name space into a dictionary via
jason option and then filter out the json entries (by removing those next Hop that are
back-end ASIC if display is for front-end only). If the entry itself has no more next Hop after filtering,
then skip over that particular route entry. Once completed, if the user chose "json" option,
then just print out the dictionary in Json format accordingly. But if no "json" option specified,
then print out the header and the decoded entry representation for each route accordingly.
if user specified a namespace, then print everything.
if user did not specify name space but specified display for all (include backend), then print each namespace
without any filtering. But if display is for front-end only, then do filter and combine all output(merge same
routes from all namespace as additional nexthops)
This code is based on FRR 7.2 branch. If we moved to a new version we may need to change here as well
'''
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you move this as doc string of the function ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@arlakshm Agreed.

filter_back_end = False
filter_by_ip = False
asic_cnt = 0
if multi_asic.is_multi_asic():
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

device.get_ns_list_based_on_options() used below handles both single and multi asic devices. I don't think we need this if condition

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@arlakshm Done!

@gechiang gechiang requested a review from arlakshm November 19, 2020 02:37
@gechiang
Copy link
Contributor Author

retest default please

@gechiang
Copy link
Contributor Author

retest this please

@smaheshm
Copy link
Contributor

@gechiang looks like import failures in the test. Can you take a look.

@gechiang
Copy link
Contributor Author

Very interesting... The import bgp_common was fine previously and nothing changed in this from my last commit so not sure why it is failing... bgpcommon.py is a new file that I am adding as part of this PR so perhaps it is somehow not able to include that in the test build? It builds fine with my private build...

@gechiang
Copy link
Contributor Author

@smaheshm The failure was due to sonic-utilities recently got converted to PYTHON3 and my changes still had some python2 stuffs such as the import that python3 did not like. It is fixed now and all tests passed.
Thanks!

Copy link
Contributor

@arlakshm arlakshm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants