diff --git a/doc/user/zebra.rst b/doc/user/zebra.rst index 74564c94b9..242d616a5f 100644 --- a/doc/user/zebra.rst +++ b/doc/user/zebra.rst @@ -1287,6 +1287,25 @@ IPv6 example for OSPFv3. Set the delay before any route-maps are processed in zebra. The default time for this is 5 seconds. + +.. _zebra-table-import: + +zebra Table Import +================== + +Zebra supports importing an alternate routing table into the main unicast RIB (URIB). +An imported table will continously sync all changes to the main URIB as routes are +added or deleted from the alternate table. +Zebra also supports importing into the main multicast RIB (MRIB) which can be used +to affect how multicast RPF lookups are performed as described in :ref: `_pim-multicast-rib`. + +.. clicmd:: ip import-table (1-252) [mrib] [distance (1-255)] [route-map RMAP_NAME] + + Import table, by given table id, into the main URIB (or MRIB). Optional distance can override + the default distance when importing routes from the alternate table. An optional route map + can be provided to filter routes that are imported into the main table. + + .. _zebra-fib-push-interface: zebra FIB push interface diff --git a/tests/topotests/zebra_rib/r1/frr-import.conf b/tests/topotests/zebra_rib/r1/frr-import.conf new file mode 100644 index 0000000000..d07433144f --- /dev/null +++ b/tests/topotests/zebra_rib/r1/frr-import.conf @@ -0,0 +1,18 @@ +! +hostname r1 +password zebra +log file /tmp/r1-frr.log +! +interface r1-eth0 + ip address 10.0.0.1/24 +! +interface r1-eth1 + ip address 10.10.0.1/24 +! +ip route 10.1.0.0/24 10.0.0.2 table 10 +ip route 10.2.0.0/24 10.0.0.2 table 10 +ip route 10.3.0.0/24 10.10.0.2 table 10 +ip route 10.4.0.0/24 10.10.0.2 table 10 +! +ip forwarding +! \ No newline at end of file diff --git a/tests/topotests/zebra_rib/r1/import_init_mrib_table.json b/tests/topotests/zebra_rib/r1/import_init_mrib_table.json new file mode 100644 index 0000000000..a6807d2cdd --- /dev/null +++ b/tests/topotests/zebra_rib/r1/import_init_mrib_table.json @@ -0,0 +1,126 @@ +{ + "10.0.0.0/24": [ + { + "prefix": "10.0.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 3, + "installedNexthopGroupId": 3, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.0.0.1/32": [ + { + "prefix": "10.0.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 3, + "installedNexthopGroupId": 3, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.0/24": [ + { + "prefix": "10.10.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 4, + "installedNexthopGroupId": 4, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.1/32": [ + { + "prefix": "10.10.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 4, + "installedNexthopGroupId": 4, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/topotests/zebra_rib/r1/import_init_table.json b/tests/topotests/zebra_rib/r1/import_init_table.json new file mode 100644 index 0000000000..a6807d2cdd --- /dev/null +++ b/tests/topotests/zebra_rib/r1/import_init_table.json @@ -0,0 +1,126 @@ +{ + "10.0.0.0/24": [ + { + "prefix": "10.0.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 3, + "installedNexthopGroupId": 3, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.0.0.1/32": [ + { + "prefix": "10.0.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 3, + "installedNexthopGroupId": 3, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.0/24": [ + { + "prefix": "10.10.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 4, + "installedNexthopGroupId": 4, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.1/32": [ + { + "prefix": "10.10.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 4, + "installedNexthopGroupId": 4, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/topotests/zebra_rib/r1/import_mrib_table_2.json b/tests/topotests/zebra_rib/r1/import_mrib_table_2.json new file mode 100644 index 0000000000..0a7915df0f --- /dev/null +++ b/tests/topotests/zebra_rib/r1/import_mrib_table_2.json @@ -0,0 +1,258 @@ +{ + "10.0.0.0/24": [ + { + "prefix": "10.0.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 3, + "installedNexthopGroupId": 3, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.0.0.1/32": [ + { + "prefix": "10.0.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 3, + "installedNexthopGroupId": 3, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.1.0.0/24": [ + { + "prefix": "10.1.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 7, + "installedNexthopGroupId": 7, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.0.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.2.0.0/24": [ + { + "prefix": "10.2.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 7, + "installedNexthopGroupId": 7, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.0.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.3.0.0/24": [ + { + "prefix": "10.3.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 8, + "installedNexthopGroupId": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.10.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.4.0.0/24": [ + { + "prefix": "10.4.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 8, + "installedNexthopGroupId": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.10.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.0/24": [ + { + "prefix": "10.10.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 4, + "installedNexthopGroupId": 4, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.1/32": [ + { + "prefix": "10.10.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 4, + "installedNexthopGroupId": 4, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/topotests/zebra_rib/r1/import_mrib_table_3.json b/tests/topotests/zebra_rib/r1/import_mrib_table_3.json new file mode 100644 index 0000000000..11bbcf8ec8 --- /dev/null +++ b/tests/topotests/zebra_rib/r1/import_mrib_table_3.json @@ -0,0 +1,291 @@ +{ + "10.0.0.0/24": [ + { + "prefix": "10.0.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 3, + "installedNexthopGroupId": 3, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.0.0.1/32": [ + { + "prefix": "10.0.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 3, + "installedNexthopGroupId": 3, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.1.0.0/24": [ + { + "prefix": "10.1.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 7, + "installedNexthopGroupId": 7, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.0.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.2.0.0/24": [ + { + "prefix": "10.2.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 7, + "installedNexthopGroupId": 7, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.0.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.3.0.0/24": [ + { + "prefix": "10.3.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 8, + "installedNexthopGroupId": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.10.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.4.0.0/24": [ + { + "prefix": "10.4.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 8, + "installedNexthopGroupId": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.10.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.0/24": [ + { + "prefix": "10.10.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 4, + "installedNexthopGroupId": 4, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.1/32": [ + { + "prefix": "10.10.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 4, + "installedNexthopGroupId": 4, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.20.0.0/24": [ + { + "prefix": "10.20.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 8, + "installedNexthopGroupId": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.10.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/topotests/zebra_rib/r1/import_mrib_table_4.json b/tests/topotests/zebra_rib/r1/import_mrib_table_4.json new file mode 100644 index 0000000000..4375b9cde6 --- /dev/null +++ b/tests/topotests/zebra_rib/r1/import_mrib_table_4.json @@ -0,0 +1,258 @@ +{ + "10.0.0.0/24": [ + { + "prefix": "10.0.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 3, + "installedNexthopGroupId": 3, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.0.0.1/32": [ + { + "prefix": "10.0.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 3, + "installedNexthopGroupId": 3, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.1.0.0/24": [ + { + "prefix": "10.1.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 123, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 7, + "installedNexthopGroupId": 7, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.0.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.2.0.0/24": [ + { + "prefix": "10.2.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 123, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 7, + "installedNexthopGroupId": 7, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.0.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.3.0.0/24": [ + { + "prefix": "10.3.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 123, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 8, + "installedNexthopGroupId": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.10.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.4.0.0/24": [ + { + "prefix": "10.4.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 123, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 8, + "installedNexthopGroupId": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.10.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.0/24": [ + { + "prefix": "10.10.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 4, + "installedNexthopGroupId": 4, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.1/32": [ + { + "prefix": "10.10.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 4, + "installedNexthopGroupId": 4, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/topotests/zebra_rib/r1/import_table_2.json b/tests/topotests/zebra_rib/r1/import_table_2.json new file mode 100644 index 0000000000..0a7915df0f --- /dev/null +++ b/tests/topotests/zebra_rib/r1/import_table_2.json @@ -0,0 +1,258 @@ +{ + "10.0.0.0/24": [ + { + "prefix": "10.0.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 3, + "installedNexthopGroupId": 3, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.0.0.1/32": [ + { + "prefix": "10.0.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 3, + "installedNexthopGroupId": 3, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.1.0.0/24": [ + { + "prefix": "10.1.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 7, + "installedNexthopGroupId": 7, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.0.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.2.0.0/24": [ + { + "prefix": "10.2.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 7, + "installedNexthopGroupId": 7, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.0.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.3.0.0/24": [ + { + "prefix": "10.3.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 8, + "installedNexthopGroupId": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.10.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.4.0.0/24": [ + { + "prefix": "10.4.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 8, + "installedNexthopGroupId": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.10.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.0/24": [ + { + "prefix": "10.10.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 4, + "installedNexthopGroupId": 4, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.1/32": [ + { + "prefix": "10.10.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 4, + "installedNexthopGroupId": 4, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/topotests/zebra_rib/r1/import_table_3.json b/tests/topotests/zebra_rib/r1/import_table_3.json new file mode 100644 index 0000000000..11bbcf8ec8 --- /dev/null +++ b/tests/topotests/zebra_rib/r1/import_table_3.json @@ -0,0 +1,291 @@ +{ + "10.0.0.0/24": [ + { + "prefix": "10.0.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 3, + "installedNexthopGroupId": 3, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.0.0.1/32": [ + { + "prefix": "10.0.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 3, + "installedNexthopGroupId": 3, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.1.0.0/24": [ + { + "prefix": "10.1.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 7, + "installedNexthopGroupId": 7, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.0.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.2.0.0/24": [ + { + "prefix": "10.2.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 7, + "installedNexthopGroupId": 7, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.0.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.3.0.0/24": [ + { + "prefix": "10.3.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 8, + "installedNexthopGroupId": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.10.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.4.0.0/24": [ + { + "prefix": "10.4.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 8, + "installedNexthopGroupId": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.10.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.0/24": [ + { + "prefix": "10.10.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 4, + "installedNexthopGroupId": 4, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.1/32": [ + { + "prefix": "10.10.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 4, + "installedNexthopGroupId": 4, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.20.0.0/24": [ + { + "prefix": "10.20.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 15, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 8, + "installedNexthopGroupId": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.10.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/topotests/zebra_rib/r1/import_table_4.json b/tests/topotests/zebra_rib/r1/import_table_4.json new file mode 100644 index 0000000000..4375b9cde6 --- /dev/null +++ b/tests/topotests/zebra_rib/r1/import_table_4.json @@ -0,0 +1,258 @@ +{ + "10.0.0.0/24": [ + { + "prefix": "10.0.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 3, + "installedNexthopGroupId": 3, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.0.0.1/32": [ + { + "prefix": "10.0.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 3, + "installedNexthopGroupId": 3, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.1.0.0/24": [ + { + "prefix": "10.1.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 123, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 7, + "installedNexthopGroupId": 7, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.0.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.2.0.0/24": [ + { + "prefix": "10.2.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 123, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 7, + "installedNexthopGroupId": 7, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.0.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth0", + "active": true, + "weight": 1 + } + ] + } + ], + "10.3.0.0/24": [ + { + "prefix": "10.3.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 123, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 8, + "installedNexthopGroupId": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.10.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.4.0.0/24": [ + { + "prefix": "10.4.0.0/24", + "prefixLen": 24, + "protocol": "table", + "instance": 10, + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 123, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 8, + "installedNexthopGroupId": 8, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "10.10.0.2", + "afi": "ipv4", + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.0/24": [ + { + "prefix": "10.10.0.0/24", + "prefixLen": 24, + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 4, + "installedNexthopGroupId": 4, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ], + "10.10.0.1/32": [ + { + "prefix": "10.10.0.1/32", + "prefixLen": 32, + "protocol": "local", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthopGroupId": 4, + "installedNexthopGroupId": 4, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-eth1", + "active": true, + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/topotests/zebra_rib/test_zebra_import.py b/tests/topotests/zebra_rib/test_zebra_import.py new file mode 100644 index 0000000000..7819548ad2 --- /dev/null +++ b/tests/topotests/zebra_rib/test_zebra_import.py @@ -0,0 +1,280 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC +# +# test_zebra_import.py +# +# Copyright (c) 2024 ATCorp +# Nathan Bahr +# + +import os +import sys +from functools import partial +import pytest +import json +import platform + +# pylint: disable=C0413 +# Import topogen and topotest helpers +from lib import topotest +from lib.topogen import Topogen, get_topogen +from lib.topolog import logger +from lib.common_config import step, write_test_header + +""" +test_zebra_import.py: Test zebra table import functionality +""" + +TOPOLOGY = """ + Single router zebra functionality + + +---+---+ + 10.0.0.1/24 | | 10.10.0.1/24 + <--->+ R1 +<---> + | | + +---+---+ +""" + +# Save the Current Working Directory to find configuration files. +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +pytestmark = [pytest.mark.sharpd] +krel = platform.release() + +def build_topo(tgen): + "Build function" + + tgen.add_router("r1") + sw1 = tgen.add_switch("sw1") + sw2 = tgen.add_switch("sw2") + sw1.add_link(tgen.gears["r1"], "r1-eth0") + sw2.add_link(tgen.gears["r1"], "r1-eth1") + +def setup_module(mod): + "Sets up the pytest environment" + + tgen = Topogen(build_topo, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + for rname, router in router_list.items(): + logger.info("Loading router %s" % rname) + router.load_frr_config(os.path.join(CWD, "{}/frr-import.conf".format(rname))) + + # Initialize all routers. + tgen.start_router() + for router in router_list.values(): + if router.has_version("<", "4.0"): + tgen.set_error("unsupported version") + + +def teardown_module(): + "Teardown the pytest environment" + tgen = get_topogen() + tgen.stop_topology() + + +def test_zebra_urib_import(request): + "Verify router starts with the initial URIB" + tgen = get_topogen() + tc_name = request.node.name + write_test_header(tc_name) + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r1 = tgen.gears["r1"] + + step("Verify initial main routing table") + initial_json_file = "{}/r1/import_init_table.json".format(CWD) + expected = json.loads(open(initial_json_file).read()) + test_func = partial( + topotest.router_json_cmp, r1, "show ip route json", expected + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, '"r1" JSON output mismatches' + + r1.vtysh_cmd( + """ + conf term + ip import-table 10 + """) + + import_json_file = "{}/r1/import_table_2.json".format(CWD) + expected = json.loads(open(import_json_file).read()) + test_func = partial( + topotest.router_json_cmp, r1, "show ip route json", expected + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, '"r1" JSON output mismatches' + + step("Add a new static route and verify it gets added") + r1.vtysh_cmd( + """ + conf term + ip route 10.20.0.0/24 10.10.0.2 table 10 + """ + ) + + sync_json_file = "{}/r1/import_table_3.json".format(CWD) + expected = json.loads(open(sync_json_file).read()) + test_func = partial( + topotest.router_json_cmp, r1, "show ip route json", expected + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, '"r1" JSON output mismatches' + + step("Remove the static route and verify it gets removed") + r1.vtysh_cmd( + """ + conf term + no ip route 10.20.0.0/24 10.10.0.2 table 10 + """ + ) + + expected = json.loads(open(import_json_file).read()) + test_func = partial( + topotest.router_json_cmp, r1, "show ip route json", expected + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, '"r1" JSON output mismatches' + + step("Disable table import and verify it goes back to the initial table") + r1.vtysh_cmd( + """ + conf term + no ip import-table 10 + """ + ) + + expected = json.loads(open(initial_json_file).read()) + test_func = partial( + topotest.router_json_cmp, r1, "show ip route json", expected + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, '"r1" JSON output mismatches' + + step("Re-import with distance and verify correct distance") + r1.vtysh_cmd( + """ + conf term + ip import-table 10 distance 123 + """) + + import_json_file = "{}/r1/import_table_4.json".format(CWD) + expected = json.loads(open(import_json_file).read()) + test_func = partial( + topotest.router_json_cmp, r1, "show ip route json", expected + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, '"r1" JSON output mismatches' + +def test_zebra_mrib_import(request): + "Verify router starts with the initial MRIB" + tgen = get_topogen() + tc_name = request.node.name + write_test_header(tc_name) + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r1 = tgen.gears["r1"] + + step("Verify initial main MRIB routing table") + initial_json_file = "{}/r1/import_init_mrib_table.json".format(CWD) + expected = json.loads(open(initial_json_file).read()) + test_func = partial( + topotest.router_json_cmp, r1, "show ip rpf json", expected + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, '"r1" JSON output mismatches' + + r1.vtysh_cmd( + """ + conf term + ip import-table 10 mrib + """) + + import_json_file = "{}/r1/import_mrib_table_2.json".format(CWD) + expected = json.loads(open(import_json_file).read()) + test_func = partial( + topotest.router_json_cmp, r1, "show ip rpf json", expected + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, '"r1" JSON output mismatches' + + step("Add a new static route and verify it gets added") + r1.vtysh_cmd( + """ + conf term + ip route 10.20.0.0/24 10.10.0.2 table 10 + """ + ) + + sync_json_file = "{}/r1/import_mrib_table_3.json".format(CWD) + expected = json.loads(open(sync_json_file).read()) + test_func = partial( + topotest.router_json_cmp, r1, "show ip rpf json", expected + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, '"r1" JSON output mismatches' + + step("Remove the static route and verify it gets removed") + r1.vtysh_cmd( + """ + conf term + no ip route 10.20.0.0/24 10.10.0.2 table 10 + """ + ) + + expected = json.loads(open(import_json_file).read()) + test_func = partial( + topotest.router_json_cmp, r1, "show ip rpf json", expected + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, '"r1" JSON output mismatches' + + step("Disable table import and verify it goes back to the initial table") + r1.vtysh_cmd( + """ + conf term + no ip import-table 10 mrib + """ + ) + + expected = json.loads(open(initial_json_file).read()) + test_func = partial( + topotest.router_json_cmp, r1, "show ip rpf json", expected + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, '"r1" JSON output mismatches' + + step("Re-import with distance and verify correct distance") + r1.vtysh_cmd( + """ + conf term + ip import-table 10 mrib distance 123 + """) + + import_json_file = "{}/r1/import_mrib_table_4.json".format(CWD) + expected = json.loads(open(import_json_file).read()) + test_func = partial( + topotest.router_json_cmp, r1, "show ip rpf json", expected + ) + _, result = topotest.run_and_expect(test_func, None) + assert result is None, '"r1" JSON output mismatches' + + +def test_memory_leak(): + "Run the memory leak test and report results." + tgen = get_topogen() + if not tgen.is_memleak_enabled(): + pytest.skip("Memory leak test/report is disabled") + + tgen.report_memory_leaks() + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/zebra/redistribute.c b/zebra/redistribute.c index 2de0917a7e..66dc5b4b5f 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -35,10 +35,10 @@ /* array holding redistribute info about table redistribution */ /* bit AFI is set if that AFI is redistributing routes from this table */ -static int zebra_import_table_used[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX]; -static uint32_t zebra_import_table_distance[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX]; +static int zebra_import_table_used[AFI_MAX][SAFI_MAX][ZEBRA_KERNEL_TABLE_MAX]; +static uint32_t zebra_import_table_distance[AFI_MAX][SAFI_MAX][ZEBRA_KERNEL_TABLE_MAX]; -int is_zebra_import_table_enabled(afi_t afi, vrf_id_t vrf_id, uint32_t table_id) +int is_zebra_import_table_enabled(afi_t afi, safi_t safi, vrf_id_t vrf_id, uint32_t table_id) { /* * Make sure that what we are called with actualy makes sense @@ -46,9 +46,12 @@ int is_zebra_import_table_enabled(afi_t afi, vrf_id_t vrf_id, uint32_t table_id) if (afi == AFI_MAX) return 0; + if (safi == SAFI_MAX) + return 0; + if (is_zebra_valid_kernel_table(table_id) && table_id < ZEBRA_KERNEL_TABLE_MAX) - return zebra_import_table_used[afi][table_id]; + return zebra_import_table_used[afi][safi][table_id]; return 0; } @@ -687,7 +690,7 @@ void zebra_interface_vrf_update_add(struct interface *ifp, vrf_id_t old_vrf_id) } } -int zebra_add_import_table_entry(struct zebra_vrf *zvrf, struct route_node *rn, +int zebra_add_import_table_entry(struct zebra_vrf *zvrf, safi_t safi, struct route_node *rn, struct route_entry *re, const char *rmap_name) { struct route_entry *newre; @@ -705,7 +708,7 @@ int zebra_add_import_table_entry(struct zebra_vrf *zvrf, struct route_node *rn, if (ret != RMAP_PERMITMATCH) { UNSET_FLAG(re->flags, ZEBRA_FLAG_SELECTED); - zebra_del_import_table_entry(zvrf, rn, re); + zebra_del_import_table_entry(zvrf, safi, rn, re); return 0; } @@ -724,26 +727,26 @@ int zebra_add_import_table_entry(struct zebra_vrf *zvrf, struct route_node *rn, if (same) { UNSET_FLAG(same->flags, ZEBRA_FLAG_SELECTED); - zebra_del_import_table_entry(zvrf, rn, same); + zebra_del_import_table_entry(zvrf, safi, rn, same); } UNSET_FLAG(re->flags, ZEBRA_FLAG_RR_USE_DISTANCE); - newre = zebra_rib_route_entry_new( - 0, ZEBRA_ROUTE_TABLE, re->table, re->flags, re->nhe_id, - zvrf->table_id, re->metric, re->mtu, - zebra_import_table_distance[afi][re->table], re->tag); + newre = zebra_rib_route_entry_new(0, ZEBRA_ROUTE_TABLE, re->table, re->flags, re->nhe_id, + zvrf->table_id, re->metric, re->mtu, + zebra_import_table_distance[afi][safi][re->table], + re->tag); ng = nexthop_group_new(); copy_nexthops(&ng->nexthop, re->nhe->nhg.nexthop, NULL); - rib_add_multipath(afi, SAFI_UNICAST, &p, NULL, newre, ng, false); + rib_add_multipath(afi, safi, &p, NULL, newre, ng, false); nexthop_group_delete(&ng); return 0; } -int zebra_del_import_table_entry(struct zebra_vrf *zvrf, struct route_node *rn, +int zebra_del_import_table_entry(struct zebra_vrf *zvrf, safi_t safi, struct route_node *rn, struct route_entry *re) { struct prefix p; @@ -752,17 +755,16 @@ int zebra_del_import_table_entry(struct zebra_vrf *zvrf, struct route_node *rn, afi = family2afi(rn->p.family); prefix_copy(&p, &rn->p); - rib_delete(afi, SAFI_UNICAST, zvrf->vrf->vrf_id, ZEBRA_ROUTE_TABLE, - re->table, re->flags, &p, NULL, re->nhe->nhg.nexthop, - re->nhe_id, zvrf->table_id, re->metric, re->distance, + rib_delete(afi, safi, zvrf->vrf->vrf_id, ZEBRA_ROUTE_TABLE, re->table, re->flags, &p, NULL, + re->nhe->nhg.nexthop, re->nhe_id, zvrf->table_id, re->metric, re->distance, false); return 0; } /* Assuming no one calls this with the main routing table */ -int zebra_import_table(afi_t afi, vrf_id_t vrf_id, uint32_t table_id, - uint32_t distance, const char *rmap_name, int add) +int zebra_import_table(afi_t afi, safi_t safi, vrf_id_t vrf_id, uint32_t table_id, + uint32_t distance, const char *rmap_name, bool add) { struct route_table *table; struct route_entry *re; @@ -776,38 +778,39 @@ int zebra_import_table(afi_t afi, vrf_id_t vrf_id, uint32_t table_id, if (afi >= AFI_MAX) return -1; + if (safi >= SAFI_MAX) + return -1; + + /* Always import from the URIB sub-table */ table = zebra_vrf_get_table_with_table_id(afi, SAFI_UNICAST, vrf_id, table_id); if (table == NULL) { return 0; } else if (IS_ZEBRA_DEBUG_RIB) { - zlog_debug("%s routes from table %d", - add ? "Importing" : "Unimporting", table_id); + zlog_debug("%s routes from table %d into %s", add ? "Importing" : "Unimporting", + table_id, safi2str(safi)); } if (add) { if (rmap_name) - zebra_add_import_table_route_map(afi, rmap_name, - table_id); + zebra_add_import_table_route_map(afi, safi, rmap_name, table_id); else { - rmap_name = - zebra_get_import_table_route_map(afi, table_id); + rmap_name = zebra_get_import_table_route_map(afi, safi, table_id); if (rmap_name) { - zebra_del_import_table_route_map(afi, table_id); + zebra_del_import_table_route_map(afi, safi, table_id); rmap_name = NULL; } } - zebra_import_table_used[afi][table_id] = 1; - zebra_import_table_distance[afi][table_id] = distance; + zebra_import_table_used[afi][safi][table_id] = 1; + zebra_import_table_distance[afi][safi][table_id] = distance; } else { - zebra_import_table_used[afi][table_id] = 0; - zebra_import_table_distance[afi][table_id] = - ZEBRA_TABLE_DISTANCE_DEFAULT; + zebra_import_table_used[afi][safi][table_id] = 0; + zebra_import_table_distance[afi][safi][table_id] = ZEBRA_TABLE_DISTANCE_DEFAULT; - rmap_name = zebra_get_import_table_route_map(afi, table_id); + rmap_name = zebra_get_import_table_route_map(afi, safi, table_id); if (rmap_name) { - zebra_del_import_table_route_map(afi, table_id); + zebra_del_import_table_route_map(afi, safi, table_id); rmap_name = NULL; } } @@ -831,10 +834,9 @@ int zebra_import_table(afi_t afi, vrf_id_t vrf_id, uint32_t table_id, if (((afi == AFI_IP) && (rn->p.family == AF_INET)) || ((afi == AFI_IP6) && (rn->p.family == AF_INET6))) { if (add) - zebra_add_import_table_entry(zvrf, rn, re, - rmap_name); + zebra_add_import_table_entry(zvrf, safi, rn, re, rmap_name); else - zebra_del_import_table_entry(zvrf, rn, re); + zebra_del_import_table_entry(zvrf, safi, rn, re); } } return 0; @@ -844,26 +846,27 @@ int zebra_import_table_config(struct vty *vty, vrf_id_t vrf_id) { int i; afi_t afi; + safi_t safi; int write = 0; char afi_str[AFI_MAX][10] = {"", "ip", "ipv6", "ethernet"}; const char *rmap_name; - for (afi = AFI_IP; afi < AFI_MAX; afi++) { + FOREACH_AFI_SAFI (afi, safi) { for (i = 1; i < ZEBRA_KERNEL_TABLE_MAX; i++) { - if (!is_zebra_import_table_enabled(afi, vrf_id, i)) + if (!is_zebra_import_table_enabled(afi, safi, vrf_id, i)) continue; - if (zebra_import_table_distance[afi][i] - != ZEBRA_TABLE_DISTANCE_DEFAULT) { - vty_out(vty, "%s import-table %d distance %d", - afi_str[afi], i, - zebra_import_table_distance[afi][i]); + if (zebra_import_table_distance[afi][safi][i] != + ZEBRA_TABLE_DISTANCE_DEFAULT) { + vty_out(vty, "%s import-table %d %sdistance %d", afi_str[afi], i, + (safi == SAFI_MULTICAST ? "mrib " : ""), + zebra_import_table_distance[afi][safi][i]); } else { - vty_out(vty, "%s import-table %d", afi_str[afi], - i); + vty_out(vty, "%s import-table %d%s", afi_str[afi], i, + (safi == SAFI_MULTICAST ? " mrib" : "")); } - rmap_name = zebra_get_import_table_route_map(afi, i); + rmap_name = zebra_get_import_table_route_map(afi, safi, i); if (rmap_name) vty_out(vty, " route-map %s", rmap_name); @@ -875,21 +878,19 @@ int zebra_import_table_config(struct vty *vty, vrf_id_t vrf_id) return write; } -static void zebra_import_table_rm_update_vrf_afi(struct zebra_vrf *zvrf, - afi_t afi, int table_id, - const char *rmap) +static void zebra_import_table_rm_update_vrf_afi(struct zebra_vrf *zvrf, afi_t afi, safi_t safi, + int table_id, const char *rmap) { struct route_table *table; struct route_entry *re; struct route_node *rn; const char *rmap_name; - rmap_name = zebra_get_import_table_route_map(afi, table_id); + rmap_name = zebra_get_import_table_route_map(afi, safi, table_id); if ((!rmap_name) || (strcmp(rmap_name, rmap) != 0)) return; - table = zebra_vrf_get_table_with_table_id(afi, SAFI_UNICAST, - zvrf->vrf->vrf_id, table_id); + table = zebra_vrf_get_table_with_table_id(afi, safi, zvrf->vrf->vrf_id, table_id); if (!table) { if (IS_ZEBRA_DEBUG_RIB_DETAILED) zlog_debug("%s: Table id=%d not found", __func__, @@ -916,7 +917,7 @@ static void zebra_import_table_rm_update_vrf_afi(struct zebra_vrf *zvrf, if (((afi == AFI_IP) && (rn->p.family == AF_INET)) || ((afi == AFI_IP6) && (rn->p.family == AF_INET6))) - zebra_add_import_table_entry(zvrf, rn, re, rmap_name); + zebra_add_import_table_entry(zvrf, safi, rn, re, rmap_name); } return; @@ -926,16 +927,15 @@ static void zebra_import_table_rm_update_vrf(struct zebra_vrf *zvrf, const char *rmap) { afi_t afi; + safi_t safi; int i; - for (afi = AFI_IP; afi < AFI_MAX; afi++) { + FOREACH_AFI_SAFI (afi, safi) { for (i = 1; i < ZEBRA_KERNEL_TABLE_MAX; i++) { - if (!is_zebra_import_table_enabled( - afi, zvrf->vrf->vrf_id, i)) + if (!is_zebra_import_table_enabled(afi, safi, zvrf->vrf->vrf_id, i)) continue; - zebra_import_table_rm_update_vrf_afi(zvrf, afi, i, - rmap); + zebra_import_table_rm_update_vrf_afi(zvrf, afi, safi, i, rmap); } } } diff --git a/zebra/redistribute.h b/zebra/redistribute.h index 4347454eb7..7fb31f01cf 100644 --- a/zebra/redistribute.h +++ b/zebra/redistribute.h @@ -56,19 +56,14 @@ extern void zebra_interface_vrf_update_del(struct interface *ifp, extern void zebra_interface_vrf_update_add(struct interface *ifp, vrf_id_t old_vrf_id); -extern int zebra_import_table(afi_t afi, vrf_id_t vrf_id, - uint32_t table_id, uint32_t distance, - const char *rmap_name, int add); +extern int zebra_import_table(afi_t afi, safi_t safi, vrf_id_t vrf_id, uint32_t table_id, + uint32_t distance, const char *rmap_name, bool add); -extern int zebra_add_import_table_entry(struct zebra_vrf *zvrf, - struct route_node *rn, - struct route_entry *re, - const char *rmap_name); -extern int zebra_del_import_table_entry(struct zebra_vrf *zvrf, - struct route_node *rn, +extern int zebra_add_import_table_entry(struct zebra_vrf *zvrf, safi_t safi, struct route_node *rn, + struct route_entry *re, const char *rmap_name); +extern int zebra_del_import_table_entry(struct zebra_vrf *zvrf, safi_t safi, struct route_node *rn, struct route_entry *re); -extern int is_zebra_import_table_enabled(afi_t, vrf_id_t vrf_id, - uint32_t table_id); +extern int is_zebra_import_table_enabled(afi_t, safi_t safi, vrf_id_t vrf_id, uint32_t table_id); extern int zebra_import_table_config(struct vty *, vrf_id_t vrf_id); diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index aea39b8ecf..59e7696ed2 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -4014,6 +4014,7 @@ static void rib_link(struct route_node *rn, struct route_entry *re, int process) { rib_dest_t *dest; afi_t afi; + safi_t safi; const char *rmap_name; assert(re && rn); @@ -4031,11 +4032,13 @@ static void rib_link(struct route_node *rn, struct route_entry *re, int process) afi = (rn->p.family == AF_INET) ? AFI_IP : (rn->p.family == AF_INET6) ? AFI_IP6 : AFI_MAX; - if (is_zebra_import_table_enabled(afi, re->vrf_id, re->table)) { - struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(re->vrf_id); + for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) { + if (is_zebra_import_table_enabled(afi, safi, re->vrf_id, re->table)) { + struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(re->vrf_id); - rmap_name = zebra_get_import_table_route_map(afi, re->table); - zebra_add_import_table_entry(zvrf, rn, re, rmap_name); + rmap_name = zebra_get_import_table_route_map(afi, safi, re->table); + zebra_add_import_table_entry(zvrf, safi, rn, re, rmap_name); + } } if (process) @@ -4093,6 +4096,7 @@ void rib_unlink(struct route_node *rn, struct route_entry *re) void rib_delnode(struct route_node *rn, struct route_entry *re) { afi_t afi; + safi_t safi; if (IS_ZEBRA_DEBUG_RIB) rnode_debug(rn, re->vrf_id, "rn %p, re %p, removing", @@ -4106,15 +4110,17 @@ void rib_delnode(struct route_node *rn, struct route_entry *re) afi = (rn->p.family == AF_INET) ? AFI_IP : (rn->p.family == AF_INET6) ? AFI_IP6 : AFI_MAX; - if (is_zebra_import_table_enabled(afi, re->vrf_id, re->table)) { - struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(re->vrf_id); + for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) { + if (is_zebra_import_table_enabled(afi, safi, re->vrf_id, re->table)) { + struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(re->vrf_id); - zebra_del_import_table_entry(zvrf, rn, re); - /* Just clean up if non main table */ - if (IS_ZEBRA_DEBUG_RIB) - zlog_debug("%s(%u):%pRN: Freeing route rn %p, re %p (%s)", - vrf_id_to_name(re->vrf_id), re->vrf_id, rn, - rn, re, zebra_route_string(re->type)); + zebra_del_import_table_entry(zvrf, safi, rn, re); + /* Just clean up if non main table */ + if (IS_ZEBRA_DEBUG_RIB) + zlog_debug("%s %s(%u):%pRN: Freeing route rn %p, re %p (%s)", + safi2str(safi), vrf_id_to_name(re->vrf_id), re->vrf_id, + rn, rn, re, zebra_route_string(re->type)); + } } rib_queue_add(rn); diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c index 46afbcecfa..29bbf6023d 100644 --- a/zebra/zebra_routemap.c +++ b/zebra/zebra_routemap.c @@ -29,7 +29,7 @@ static uint32_t zebra_rmap_update_timer = ZEBRA_RMAP_DEFAULT_UPDATE_TIMER; static struct event *zebra_t_rmap_update = NULL; -char *zebra_import_table_routemap[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX]; +char *zebra_import_table_routemap[AFI_MAX][SAFI_MAX][ZEBRA_KERNEL_TABLE_MAX]; struct zebra_rmap_obj { struct nexthop *nexthop; @@ -1235,21 +1235,19 @@ route_map_result_t zebra_route_map_check(afi_t family, struct route_entry *re, return (ret); } -char *zebra_get_import_table_route_map(afi_t afi, uint32_t table) +char *zebra_get_import_table_route_map(afi_t afi, safi_t safi, uint32_t table) { - return zebra_import_table_routemap[afi][table]; + return zebra_import_table_routemap[afi][safi][table]; } -void zebra_add_import_table_route_map(afi_t afi, const char *rmap_name, - uint32_t table) +void zebra_add_import_table_route_map(afi_t afi, safi_t safi, const char *rmap_name, uint32_t table) { - zebra_import_table_routemap[afi][table] = - XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name); + zebra_import_table_routemap[afi][safi][table] = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name); } -void zebra_del_import_table_route_map(afi_t afi, uint32_t table) +void zebra_del_import_table_route_map(afi_t afi, safi_t safi, uint32_t table) { - XFREE(MTYPE_ROUTE_MAP_NAME, zebra_import_table_routemap[afi][table]); + XFREE(MTYPE_ROUTE_MAP_NAME, zebra_import_table_routemap[afi][safi][table]); } route_map_result_t zebra_import_table_route_map_check(int family, diff --git a/zebra/zebra_routemap.h b/zebra/zebra_routemap.h index 2039e80e3a..fca9752285 100644 --- a/zebra/zebra_routemap.h +++ b/zebra/zebra_routemap.h @@ -14,10 +14,10 @@ extern "C" { #endif extern void zebra_route_map_init(void); -extern char *zebra_get_import_table_route_map(afi_t afi, uint32_t table); -extern void zebra_add_import_table_route_map(afi_t afi, const char *rmap_name, +extern char *zebra_get_import_table_route_map(afi_t afi, safi_t safi, uint32_t table); +extern void zebra_add_import_table_route_map(afi_t afi, safi_t safi, const char *rmap_name, uint32_t table); -extern void zebra_del_import_table_route_map(afi_t afi, uint32_t table); +extern void zebra_del_import_table_route_map(afi_t afi, safi_t safi, uint32_t table); extern route_map_result_t zebra_import_table_route_map_check( int family, struct route_entry *re, const struct prefix *p, diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 309cde9a35..8c0d6df68a 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -3594,54 +3594,34 @@ static int zebra_ip_config(struct vty *vty) return write; } -DEFUN (ip_zebra_import_table_distance, +DEFPY (ip_zebra_import_table_distance, ip_zebra_import_table_distance_cmd, - "ip import-table (1-252) [distance (1-255)] [route-map RMAP_NAME]", + "ip import-table (1-252)$table_id [mrib]$mrib [distance (1-255)$distance] [route-map RMAP_NAME$rmap]", IP_STR "import routes from non-main kernel table\n" "kernel routing table id\n" + "Import into the MRIB instead of the URIB\n" "Distance for imported routes\n" "Default distance value\n" "route-map for filtering\n" "route-map name\n") { - uint32_t table_id = 0; + safi_t safi = mrib ? SAFI_MULTICAST : SAFI_UNICAST; - table_id = strtoul(argv[2]->arg, NULL, 10); - int distance = ZEBRA_TABLE_DISTANCE_DEFAULT; - char *rmap = - strmatch(argv[argc - 2]->text, "route-map") - ? XSTRDUP(MTYPE_ROUTE_MAP_NAME, argv[argc - 1]->arg) - : NULL; - int ret; - - if (argc == 7 || (argc == 5 && !rmap)) - distance = strtoul(argv[4]->arg, NULL, 10); + if (distance_str == NULL) + distance = ZEBRA_TABLE_DISTANCE_DEFAULT; if (!is_zebra_valid_kernel_table(table_id)) { - vty_out(vty, - "Invalid routing table ID, %d. Must be in range 1-252\n", - table_id); - if (rmap) - XFREE(MTYPE_ROUTE_MAP_NAME, rmap); + vty_out(vty, "Invalid routing table ID, %ld. Must be in range 1-252\n", table_id); return CMD_WARNING; } if (is_zebra_main_routing_table(table_id)) { - vty_out(vty, - "Invalid routing table ID, %d. Must be non-default table\n", - table_id); - if (rmap) - XFREE(MTYPE_ROUTE_MAP_NAME, rmap); + vty_out(vty, "Invalid routing table ID, %ld. Must be non-default table\n", table_id); return CMD_WARNING; } - ret = zebra_import_table(AFI_IP, VRF_DEFAULT, table_id, - distance, rmap, 1); - if (rmap) - XFREE(MTYPE_ROUTE_MAP_NAME, rmap); - - return ret; + return zebra_import_table(AFI_IP, safi, VRF_DEFAULT, table_id, distance, rmap, true); } DEFUN_HIDDEN (zebra_packet_process, @@ -3700,20 +3680,20 @@ DEFUN_HIDDEN (no_zebra_workqueue_timer, return CMD_SUCCESS; } -DEFUN (no_ip_zebra_import_table, +DEFPY (no_ip_zebra_import_table, no_ip_zebra_import_table_cmd, - "no ip import-table (1-252) [distance (1-255)] [route-map NAME]", + "no ip import-table (1-252)$table_id [mrib]$mrib [distance (1-255)] [route-map NAME]", NO_STR IP_STR "import routes from non-main kernel table\n" "kernel routing table id\n" + "Import into the MRIB instead of the URIB\n" "Distance for imported routes\n" "Default distance value\n" "route-map for filtering\n" "route-map name\n") { - uint32_t table_id = 0; - table_id = strtoul(argv[3]->arg, NULL, 10); + safi_t safi = mrib ? SAFI_MULTICAST : SAFI_UNICAST; if (!is_zebra_valid_kernel_table(table_id)) { vty_out(vty, @@ -3722,16 +3702,14 @@ DEFUN (no_ip_zebra_import_table, } if (is_zebra_main_routing_table(table_id)) { - vty_out(vty, - "Invalid routing table ID, %d. Must be non-default table\n", - table_id); + vty_out(vty, "Invalid routing table ID, %ld. Must be non-default table\n", table_id); return CMD_WARNING; } - if (!is_zebra_import_table_enabled(AFI_IP, VRF_DEFAULT, table_id)) + if (!is_zebra_import_table_enabled(AFI_IP, safi, VRF_DEFAULT, table_id)) return CMD_SUCCESS; - return (zebra_import_table(AFI_IP, VRF_DEFAULT, table_id, 0, NULL, 0)); + return (zebra_import_table(AFI_IP, safi, VRF_DEFAULT, table_id, 0, NULL, false)); } DEFPY (zebra_nexthop_group_keep,