diff options
| author | harios_niral <hari@niralnetworks.com> | 2020-09-01 00:56:44 -0700 |
|---|---|---|
| committer | harios_niral <hari@niralnetworks.com> | 2020-09-01 00:56:44 -0700 |
| commit | 9375b5aa24b94ba49282c569c98d598a6ec8ed9c (patch) | |
| tree | 2591e3e25c4aa51bff08571ae64bd8f2ec9ad7a6 | |
| parent | 65251ce80f02a61cfa06d752aa914bffd8493918 (diff) | |
topotests : Topotest for different VRF in isisd
1. Topotest for isis-vrf is added for ipv4 and ipv6.
2. Test case for checking isis topology.
3. Test case for checking zebra isis routes.
4. Test case for checking linux vrf routes.
5. 2 new API's written in topotest/lib for checking vrf routes.
Co-authored-by: Kaushik <kaushik@niralnetworks.com>"
Signed-off-by: harios_niral <hari@niralnetworks.com>
40 files changed, 2297 insertions, 0 deletions
diff --git a/tests/topotests/isis-topo1-vrf/__init__.py b/tests/topotests/isis-topo1-vrf/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-topo1-vrf/__init__.py diff --git a/tests/topotests/isis-topo1-vrf/r1/isisd.conf b/tests/topotests/isis-topo1-vrf/r1/isisd.conf new file mode 100755 index 0000000000..4ac4597015 --- /dev/null +++ b/tests/topotests/isis-topo1-vrf/r1/isisd.conf @@ -0,0 +1,15 @@ +hostname r1 +debug isis adj-packets +debug isis events +debug isis update-packets +interface r1-eth0 + ip router isis 1 vrf r1-cust1 + ipv6 router isis 1 vrf r1-cust1 + isis circuit-type level-2-only +! +router isis 1 vrf r1-cust1 + net 10.0000.0000.0000.0000.0000.0000.0000.0000.0000.00 + metric-style wide + redistribute ipv4 connected level-2 + redistribute ipv6 connected level-2 +! diff --git a/tests/topotests/isis-topo1-vrf/r1/r1_route.json b/tests/topotests/isis-topo1-vrf/r1/r1_route.json new file mode 100644 index 0000000000..790808f2cd --- /dev/null +++ b/tests/topotests/isis-topo1-vrf/r1/r1_route.json @@ -0,0 +1,57 @@ +{ + "10.0.10.0/24": [ + { + "distance": 115, + "metric": 20, + "nexthops": [ + { + "active": true, + "afi": "ipv4", + "fib": true, + "interfaceIndex": 2, + "interfaceName": "r1-eth0", + "ip": "10.0.20.1" + } + ], + "prefix": "10.0.10.0/24", + "protocol": "isis", + "selected": true, + "vrfId": 3, + "vrfName": "r1-cust1" + } + ], + "10.0.20.0/24": [ + { + "distance": 115, + "metric": 20, + "nexthops": [ + { + "afi": "ipv4", + "interfaceIndex": 2, + "interfaceName": "r1-eth0", + "ip": "10.0.20.1" + } + ], + "prefix": "10.0.20.0/24", + "protocol": "isis", + "vrfId": 3, + "vrfName": "r1-cust1" + }, + { + "nexthops": [ + { + "active": true, + "directlyConnected": true, + "fib": true, + "interfaceIndex": 2, + "interfaceName": "r1-eth0" + } + ], + "prefix": "10.0.20.0/24", + "protocol": "connected", + "selected": true, + "vrfId": 3, + "vrfName": "r1-cust1" + } + ] +} diff --git a/tests/topotests/isis-topo1-vrf/r1/r1_route6.json b/tests/topotests/isis-topo1-vrf/r1/r1_route6.json new file mode 100644 index 0000000000..332cbb3290 --- /dev/null +++ b/tests/topotests/isis-topo1-vrf/r1/r1_route6.json @@ -0,0 +1,40 @@ +{ + "2001:db8:1:1::/64": [ + { + "nexthops": [ + { + "active": true, + "directlyConnected": true, + "fib": true, + "interfaceIndex": 2, + "interfaceName": "r1-eth0" + } + ], + "prefix": "2001:db8:1:1::/64", + "protocol": "connected", + "selected": true, + "vrfId": 3, + "vrfName": "r1-cust1" + } + ], + "2001:db8:2:1::/64": [ + { + "distance": 115, + "metric": 20, + "nexthops": [ + { + "active": true, + "afi": "ipv6", + "fib": true, + "interfaceIndex": 2, + "interfaceName": "r1-eth0" + } + ], + "prefix": "2001:db8:2:1::/64", + "protocol": "isis", + "selected": true, + "vrfId": 3, + "vrfName": "r1-cust1" + } + ] +} diff --git a/tests/topotests/isis-topo1-vrf/r1/r1_route6_linux.json b/tests/topotests/isis-topo1-vrf/r1/r1_route6_linux.json new file mode 100755 index 0000000000..d1ace402ba --- /dev/null +++ b/tests/topotests/isis-topo1-vrf/r1/r1_route6_linux.json @@ -0,0 +1,14 @@ +{ + "2001:db8:1:1::/64": { + "dev": "r1-eth0", + "metric": "256", + "pref": "medium", + "proto": "kernel" + }, + "2001:db8:2:1::/64": { + "dev": "r1-eth0", + "metric": "20", + "pref": "medium", + "proto": "187" + } +} diff --git a/tests/topotests/isis-topo1-vrf/r1/r1_route_linux.json b/tests/topotests/isis-topo1-vrf/r1/r1_route_linux.json new file mode 100755 index 0000000000..6af22297e9 --- /dev/null +++ b/tests/topotests/isis-topo1-vrf/r1/r1_route_linux.json @@ -0,0 +1,13 @@ +{ + "10.0.10.0/24": { + "dev": "r1-eth0", + "metric": "20", + "proto": "187", + "via": "10.0.20.1" + }, + "10.0.20.0/24": { + "dev": "r1-eth0", + "proto": "kernel", + "scope": "link" + } +} diff --git a/tests/topotests/isis-topo1-vrf/r1/r1_topology.json b/tests/topotests/isis-topo1-vrf/r1/r1_topology.json new file mode 100644 index 0000000000..8e3cdc7bd6 --- /dev/null +++ b/tests/topotests/isis-topo1-vrf/r1/r1_topology.json @@ -0,0 +1,80 @@ +{ + "1": { + "level-1": { + "ipv4": [ + { + "vertex": "r1" + } + ], + "ipv6": [ + { + "vertex": "r1" + } + ] + }, + "level-2": { + "ipv4": [ + { + "vertex": "r1" + }, + { + "metric": "internal", + "parent": "0", + "type": "IP", + "vertex": "10.0.20.0/24" + }, + { + "interface": "r1-eth0", + "metric": "10", + "next-hop": "r3", + "parent": "r1(4)", + "type": "TE-IS", + "vertex": "r3" + }, + { + "interface": "r3", + "metric": "TE", + "next-hop": "20", + "parent": "r1-eth0", + "type": "IP", + "vertex": "10.0.20.0/24" + }, + { + "interface": "r3", + "metric": "TE", + "next-hop": "20", + "parent": "r1-eth0", + "type": "IP", + "vertex": "10.0.10.0/24" + } + ], + "ipv6": [ + { + "vertex": "r1" + }, + { + "metric": "internal", + "parent": "0", + "type": "IP6", + "vertex": "2001:db8:1:1::/64" + }, + { + "interface": "r1-eth0", + "metric": "10", + "next-hop": "r3", + "parent": "r1(4)", + "type": "TE-IS", + "vertex": "r3" + }, + { + "interface": "r3", + "metric": "internal", + "next-hop": "20", + "parent": "r1-eth0", + "type": "IP6", + "vertex": "2001:db8:2:1::/64" + } + ] + } + } +} diff --git a/tests/topotests/isis-topo1-vrf/r1/zebra.conf b/tests/topotests/isis-topo1-vrf/r1/zebra.conf new file mode 100755 index 0000000000..fa1c02e5f8 --- /dev/null +++ b/tests/topotests/isis-topo1-vrf/r1/zebra.conf @@ -0,0 +1,9 @@ +hostname r1 +interface r1-eth0 vrf r1-cust1 + ip address 10.0.20.2/24 + ipv6 address 2001:db8:1:1::2/64 +! +interface lo + ip address 10.254.0.1/32 + ipv6 address 2001:db8:F::1/128 +! diff --git a/tests/topotests/isis-topo1-vrf/r2/isisd.conf b/tests/topotests/isis-topo1-vrf/r2/isisd.conf new file mode 100755 index 0000000000..4c68540265 --- /dev/null +++ b/tests/topotests/isis-topo1-vrf/r2/isisd.conf @@ -0,0 +1,15 @@ +hostname r2 +debug isis adj-packets +debug isis events +debug isis update-packets +interface r2-eth0 + ip router isis 1 vrf r2-cust1 + ipv6 router isis 1 vrf r2-cust1 + isis circuit-type level-2-only +! +router isis 1 vrf r2-cust1 + net 10.0000.0000.0000.0000.0000.0000.0000.0000.0001.00 + metric-style wide + redistribute ipv4 connected level-2 + redistribute ipv6 connected level-2 +! diff --git a/tests/topotests/isis-topo1-vrf/r2/r2_route.json b/tests/topotests/isis-topo1-vrf/r2/r2_route.json new file mode 100644 index 0000000000..b3ac86d218 --- /dev/null +++ b/tests/topotests/isis-topo1-vrf/r2/r2_route.json @@ -0,0 +1,57 @@ +{ + "10.0.11.0/24": [ + { + "distance": 115, + "metric": 20, + "nexthops": [ + { + "active": true, + "afi": "ipv4", + "fib": true, + "interfaceIndex": 2, + "interfaceName": "r2-eth0", + "ip": "10.0.21.1" + } + ], + "prefix": "10.0.11.0/24", + "protocol": "isis", + "selected": true, + "vrfId": 3, + "vrfName": "r2-cust1" + } + ], + "10.0.21.0/24": [ + { + "distance": 115, + "metric": 20, + "nexthops": [ + { + "afi": "ipv4", + "interfaceIndex": 2, + "interfaceName": "r2-eth0", + "ip": "10.0.21.1" + } + ], + "prefix": "10.0.21.0/24", + "protocol": "isis", + "vrfId": 3, + "vrfName": "r2-cust1" + }, + { + "nexthops": [ + { + "active": true, + "directlyConnected": true, + "fib": true, + "interfaceIndex": 2, + "interfaceName": "r2-eth0" + } + ], + "prefix": "10.0.21.0/24", + "protocol": "connected", + "selected": true, + "vrfId": 3, + "vrfName": "r2-cust1" + } + ] +} diff --git a/tests/topotests/isis-topo1-vrf/r2/r2_route6.json b/tests/topotests/isis-topo1-vrf/r2/r2_route6.json new file mode 100644 index 0000000000..c8d11b4922 --- /dev/null +++ b/tests/topotests/isis-topo1-vrf/r2/r2_route6.json @@ -0,0 +1,40 @@ +{ + "2001:db8:1:2::/64": [ + { + "nexthops": [ + { + "active": true, + "directlyConnected": true, + "fib": true, + "interfaceIndex": 2, + "interfaceName": "r2-eth0" + } + ], + "prefix": "2001:db8:1:2::/64", + "protocol": "connected", + "selected": true, + "vrfId": 3, + "vrfName": "r2-cust1" + } + ], + "2001:db8:2:2::/64": [ + { + "distance": 115, + "metric": 20, + "nexthops": [ + { + "active": true, + "afi": "ipv6", + "fib": true, + "interfaceIndex": 2, + "interfaceName": "r2-eth0" + } + ], + "prefix": "2001:db8:2:2::/64", + "protocol": "isis", + "selected": true, + "vrfId": 3, + "vrfName": "r2-cust1" + } + ] +} diff --git a/tests/topotests/isis-topo1-vrf/r2/r2_route6_linux.json b/tests/topotests/isis-topo1-vrf/r2/r2_route6_linux.json new file mode 100755 index 0000000000..27423e1936 --- /dev/null +++ b/tests/topotests/isis-topo1-vrf/r2/r2_route6_linux.json @@ -0,0 +1,14 @@ +{ + "2001:db8:1:2::/64": { + "dev": "r2-eth0", + "metric": "256", + "pref": "medium", + "proto": "kernel" + }, + "2001:db8:2:2::/64": { + "dev": "r2-eth0", + "metric": "20", + "pref": "medium", + "proto": "187" + } +} diff --git a/tests/topotests/isis-topo1-vrf/r2/r2_route_linux.json b/tests/topotests/isis-topo1-vrf/r2/r2_route_linux.json new file mode 100755 index 0000000000..744b0780f3 --- /dev/null +++ b/tests/topotests/isis-topo1-vrf/r2/r2_route_linux.json @@ -0,0 +1,13 @@ +{ + "10.0.11.0/24": { + "dev": "r2-eth0", + "metric": "20", + "proto": "187", + "via": "10.0.21.1" + }, + "10.0.21.0/24": { + "dev": "r2-eth0", + "proto": "kernel", + "scope": "link" + } +} diff --git a/tests/topotests/isis-topo1-vrf/r2/r2_topology.json b/tests/topotests/isis-topo1-vrf/r2/r2_topology.json new file mode 100644 index 0000000000..72022a8167 --- /dev/null +++ b/tests/topotests/isis-topo1-vrf/r2/r2_topology.json @@ -0,0 +1,80 @@ +{ + "1": { + "level-1": { + "ipv4": [ + { + "vertex": "r2" + } + ], + "ipv6": [ + { + "vertex": "r2" + } + ] + }, + "level-2": { + "ipv4": [ + { + "vertex": "r2" + }, + { + "metric": "internal", + "parent": "0", + "type": "IP", + "vertex": "10.0.21.0/24" + }, + { + "interface": "r2-eth0", + "metric": "10", + "next-hop": "r4", + "parent": "r2(4)", + "type": "TE-IS", + "vertex": "r4" + }, + { + "interface": "r4", + "metric": "TE", + "next-hop": "20", + "parent": "r2-eth0", + "type": "IP", + "vertex": "10.0.21.0/24" + }, + { + "interface": "r4", + "metric": "TE", + "next-hop": "20", + "parent": "r2-eth0", + "type": "IP", + "vertex": "10.0.11.0/24" + } + ], + "ipv6": [ + { + "vertex": "r2" + }, + { + "metric": "internal", + "parent": "0", + "type": "IP6", + "vertex": "2001:db8:1:2::/64" + }, + { + "interface": "r2-eth0", + "metric": "10", + "next-hop": "r4", + "parent": "r2(4)", + "type": "TE-IS", + "vertex": "r4" + }, + { + "interface": "r4", + "metric": "internal", + "next-hop": "20", + "parent": "r2-eth0", + "type": "IP6", + "vertex": "2001:db8:2:2::/64" + } + ] + } + } +}
\ No newline at end of file diff --git a/tests/topotests/isis-topo1-vrf/r2/zebra.conf b/tests/topotests/isis-topo1-vrf/r2/zebra.conf new file mode 100755 index 0000000000..a62af1749e --- /dev/null +++ b/tests/topotests/isis-topo1-vrf/r2/zebra.conf @@ -0,0 +1,9 @@ +hostname r2 +interface r2-eth0 vrf r2-cust1 + ip address 10.0.21.2/24 + ipv6 address 2001:db8:1:2::2/64 +! +interface lo + ip address 10.254.0.2/32 + ipv6 address 2001:db8:F::2/128 +! diff --git a/tests/topotests/isis-topo1-vrf/r3/isisd.conf b/tests/topotests/isis-topo1-vrf/r3/isisd.conf new file mode 100755 index 0000000000..ca01876690 --- /dev/null +++ b/tests/topotests/isis-topo1-vrf/r3/isisd.conf @@ -0,0 +1,22 @@ +hostname r3 +debug isis adj-packets +debug isis events +debug isis update-packets +interface r3-eth0 + ip router isis 1 vrf r3-cust1 + ipv6 router isis 1 vrf r3-cust1 + isis circuit-type level-2-only +! +interface r3-eth1 + ip router isis 1 vrf r3-cust1 + ipv6 router isis 1 vrf r3-cust1 + isis circuit-type level-1 +! +router isis 1 vrf r3-cust1 + net 10.0000.0000.0000.0000.0000.0000.0000.0000.0002.00 + metric-style wide + redistribute ipv4 connected level-1 + redistribute ipv4 connected level-2 + redistribute ipv6 connected level-1 + redistribute ipv6 connected level-2 +! diff --git a/tests/topotests/isis-topo1-vrf/r3/r3_route.json b/tests/topotests/isis-topo1-vrf/r3/r3_route.json new file mode 100644 index 0000000000..709d6b9aeb --- /dev/null +++ b/tests/topotests/isis-topo1-vrf/r3/r3_route.json @@ -0,0 +1,112 @@ +{ + "10.0.10.0/24": [ + { + "distance": 115, + "metric": 20, + "nexthops": [ + { + "afi": "ipv4", + "interfaceIndex": 3, + "interfaceName": "r3-eth1", + "ip": "10.0.10.1" + } + ], + "prefix": "10.0.10.0/24", + "protocol": "isis", + "vrfId": 4, + "vrfName": "r3-cust1" + }, + { + "nexthops": [ + { + "active": true, + "directlyConnected": true, + "fib": true, + "interfaceIndex": 3, + "interfaceName": "r3-eth1" + } + ], + "prefix": "10.0.10.0/24", + "protocol": "connected", + "selected": true, + "vrfId": 4, + "vrfName": "r3-cust1" + } + ], + "10.0.11.0/24": [ + { + "distance": 115, + "metric": 20, + "nexthops": [ + { + "active": true, + "afi": "ipv4", + "fib": true, + "interfaceIndex": 3, + "interfaceName": "r3-eth1", + "ip": "10.0.10.1" + } + ], + "prefix": "10.0.11.0/24", + "protocol": "isis", + "selected": true, + "vrfId": 4, + "vrfName": "r3-cust1" + } + ], + "10.0.20.0/24": [ + { + "distance": 115, + "metric": 20, + "nexthops": [ + { + "afi": "ipv4", + "interfaceIndex": 2, + "interfaceName": "r3-eth0", + "ip": "10.0.20.2" + } + ], + "prefix": "10.0.20.0/24", + "protocol": "isis", + "vrfId": 4, + "vrfName": "r3-cust1" + }, + { + "nexthops": [ + { + "active": true, + "directlyConnected": true, + "fib": true, + "interfaceIndex": 2, + "interfaceName": "r3-eth0" + } + ], + "prefix": "10.0.20.0/24", + "protocol": "connected", + "selected": true, + "vrfId": 4, + "vrfName": "r3-cust1" + } + ], + "10.0.21.0/24": [ + { + "distance": 115, + "metric": 30, + "nexthops": [ + { + "active": true, + "afi": "ipv4", + "fib": true, + "interfaceIndex": 3, + "interfaceName": "r3-eth1", + "ip": "10.0.10.1" + } + ], + "prefix": "10.0.21.0/24", + "protocol": "isis", + "selected": true, + "vrfId": 4, + "vrfName": "r3-cust1" + } + ] +} diff --git a/tests/topotests/isis-topo1-vrf/r3/r3_route6.json b/tests/topotests/isis-topo1-vrf/r3/r3_route6.json new file mode 100644 index 0000000000..3a7c3861fa --- /dev/null +++ b/tests/topotests/isis-topo1-vrf/r3/r3_route6.json @@ -0,0 +1,78 @@ +{ + "2001:db8:1:1::/64": [ + { + "nexthops": [ + { + "active": true, + "directlyConnected": true, + "fib": true, + "interfaceIndex": 2, + "interfaceName": "r3-eth0" + } + ], + "prefix": "2001:db8:1:1::/64", + "protocol": "connected", + "selected": true, + "vrfId": 4, + "vrfName": "r3-cust1" + } + ], + "2001:db8:1:2::/64": [ + { + "distance": 115, + "metric": 30, + "nexthops": [ + { + "active": true, + "afi": "ipv6", + "fib": true, + "interfaceIndex": 3, + "interfaceName": "r3-eth1" + } + ], + "prefix": "2001:db8:1:2::/64", + "protocol": "isis", + "selected": true, + "vrfId": 4, + "vrfName": "r3-cust1" + } + ], + "2001:db8:2:1::/64": [ + { + "nexthops": [ + { + "active": true, + "directlyConnected": true, + "fib": true, + "interfaceIndex": 3, + "interfaceName": "r3-eth1" + } + ], + "prefix": "2001:db8:2:1::/64", + "protocol": "connected", + "selected": true, + "vrfId": 4, + "vrfName": "r3-cust1" + } + ], + "2001:db8:2:2::/64": [ + { + "distance": 115, + "metric": 20, + "nexthops": [ + { + "active": true, + "afi": "ipv6", + "fib": true, + "interfaceIndex": 3, + "interfaceName": "r3-eth1" + } + ], + "prefix": "2001:db8:2:2::/64", + "protocol": "isis", + "selected": true, + "vrfId": 4, + "vrfName": "r3-cust1" + } + ] +} diff --git a/tests/topotests/isis-topo1-vrf/r3/r3_route6_linux.json b/tests/topotests/isis-topo1-vrf/r3/r3_route6_linux.json new file mode 100755 index 0000000000..bc527d2e1e --- /dev/null +++ b/tests/topotests/isis-topo1-vrf/r3/r3_route6_linux.json @@ -0,0 +1,26 @@ +{ + "2001:db8:1:1::/64": { + "dev": "r3-eth0", + "metric": "256", + "pref": "medium", + "proto": "kernel" + }, + "2001:db8:1:2::/64": { + "dev": "r3-eth1", + "metric": "20", + "pref": "medium", + "proto": "187" + }, + "2001:db8:2:1::/64": { + "dev": "r3-eth1", + "metric": "256", + "pref": "medium", + "proto": "kernel" + }, + "2001:db8:2:2::/64": { + "dev": "r3-eth1", + "metric": "20", + "pref": "medium", + "proto": "187" + } +} diff --git a/tests/topotests/isis-topo1-vrf/r3/r3_route_linux.json b/tests/topotests/isis-topo1-vrf/r3/r3_route_linux.json new file mode 100755 index 0000000000..515d376475 --- /dev/null +++ b/tests/topotests/isis-topo1-vrf/r3/r3_route_linux.json @@ -0,0 +1,24 @@ +{ + "10.0.10.0/24": { + "dev": "r3-eth1", + "proto": "kernel", + "scope": "link" + }, + "10.0.11.0/24": { + "dev": "r3-eth1", + "metric": "20", + "proto": "187", + "via": "10.0.10.1" + }, + "10.0.20.0/24": { + "dev": "r3-eth0", + "proto": "kernel", + "scope": "link" + }, + "10.0.21.0/24": { + "dev": "r3-eth1", + "metric": "20", + "proto": "187", + "via": "10.0.10.1" + } +} diff --git a/tests/topotests/isis-topo1-vrf/r3/r3_topology.json b/tests/topotests/isis-topo1-vrf/r3/r3_topology.json new file mode 100644 index 0000000000..62b895766e --- /dev/null +++ b/tests/topotests/isis-topo1-vrf/r3/r3_topology.json @@ -0,0 +1,132 @@ +{ + "1": { + "level-1": { + "ipv4": [ + { + "vertex": "r3" + }, + { + "metric": "internal", + "parent": "0", + "type": "IP", + "vertex": "10.0.10.0/24" + }, + { + "interface": "r3-eth1", + "metric": "10", + "next-hop": "r5", + "parent": "r3(4)", + "type": "TE-IS", + "vertex": "r5" + }, + { + "interface": "r5", + "metric": "TE", + "next-hop": "20", + "parent": "r3-eth1", + "type": "IP", + "vertex": "10.0.10.0/24" + }, + { + "interface": "r5", + "metric": "TE", + "next-hop": "20", + "parent": "r3-eth1", + "type": "IP", + "vertex": "10.0.11.0/24" + }, + { + "interface": "r5", + "metric": "TE", + "next-hop": "30", + "parent": "r3-eth1", + "type": "IP", + "vertex": "10.0.21.0/24" + } + ], + "ipv6": [ + { + "vertex": "r3" + }, + { + "metric": "internal", + "parent": "0", + "type": "IP6", + "vertex": "2001:db8:2:1::/64" + }, + { + "interface": "r3-eth1", + "metric": "10", + "next-hop": "r5", + "parent": "r3(4)", + "type": "TE-IS", + "vertex": "r5" + }, + { + "interface": "r5", + "metric": "internal", + "next-hop": "20", + "parent": "r3-eth1", + "type": "IP6", + "vertex": "2001:db8:2:2::/64" + }, + { + "interface": "r5", + "metric": "internal", + "next-hop": "30", + "parent": "r3-eth1", + "type": "IP6", + "vertex": "2001:db8:1:2::/64" + } + ] + }, + "level-2": { + "ipv4": [ + { + "vertex": "r3" + }, + { + "metric": "internal", + "parent": "0", + "type": "IP", + "vertex": "10.0.20.0/24" + }, + { + "interface": "r3-eth0", + "metric": "10", + "next-hop": "r3", + "parent": "r3(4)", + "type": "TE-IS", + "vertex": "r3" + }, + { + "interface": "r3", + "metric": "TE", + "next-hop": "20", + "parent": "r3-eth0", + "type": "IP", + "vertex": "10.0.20.0/24" + } + ], + "ipv6": [ + { + "vertex": "r3" + }, + { + "metric": "internal", + "parent": "0", + "type": "IP6", + "vertex": "2001:db8:1:1::/64" + }, + { + "interface": "r3-eth0", + "metric": "10", + "next-hop": "r3", + "parent": "r3(4)", + "type": "TE-IS", + "vertex": "r3" + } + ] + } + } +} diff --git a/tests/topotests/isis-topo1-vrf/r3/zebra.conf b/tests/topotests/isis-topo1-vrf/r3/zebra.conf new file mode 100755 index 0000000000..ac0b810fce --- /dev/null +++ b/tests/topotests/isis-topo1-vrf/r3/zebra.conf @@ -0,0 +1,13 @@ +hostname r3 +interface r3-eth0 vrf r3-cust1 + ip address 10.0.20.1/24 + ipv6 address 2001:db8:1:1::1/64 +! +interface r3-eth1 vrf r3-cust1 + ip address 10.0.10.2/24 + ipv6 address 2001:db8:2:1::2/64 +! +interface lo + ip address 10.254.0.3/32 + ipv6 address 2001:db8:F::3/128 +! diff --git a/tests/topotests/isis-topo1-vrf/r4/isisd.conf b/tests/topotests/isis-topo1-vrf/r4/isisd.conf new file mode 100755 index 0000000000..74b1603d85 --- /dev/null +++ b/tests/topotests/isis-topo1-vrf/r4/isisd.conf @@ -0,0 +1,25 @@ +hostname r4 +debug isis adj-packets +debug isis events +debug isis update-packets +debug isis lsp-gen +debug isis lsp-sched + +interface r4-eth0 + ip router isis 1 vrf r4-cust1 + ipv6 router isis 1 vrf r4-cust1 + isis circuit-type level-2-only +! +interface r4-eth1 + ip router isis 1 vrf r4-cust1 + ipv6 router isis 1 vrf r4-cust1 + isis circuit-type level-1 +! +router isis 1 vrf r4-cust1 + net 10.0000.0000.0000.0000.0000.0000.0000.0000.0004.00 + metric-style wide + redistribute ipv4 connected level-1 + redistribute ipv4 connected level-2 + redistribute ipv6 connected level-1 + redistribute ipv6 connected level-2 +! diff --git a/tests/topotests/isis-topo1-vrf/r4/r4_route.json b/tests/topotests/isis-topo1-vrf/r4/r4_route.json new file mode 100644 index 0000000000..c464607a2b --- /dev/null +++ b/tests/topotests/isis-topo1-vrf/r4/r4_route.json @@ -0,0 +1,105 @@ +{ + "10.0.10.0/24": [ + { + "metric": 20, + "nexthops": [ + { + "active": true, + "afi": "ipv4", + "fib": true, + "interfaceIndex": 3, + "interfaceName": "r4-eth1", + "ip": "10.0.11.1" + } + ], + "prefix": "10.0.10.0/24", + "protocol": "isis", + "selected": true, + "vrfId": 4, + "vrfName": "r4-cust1" + } + ], + "10.0.11.0/24": [ + { + "nexthops": [ + { + "afi": "ipv4", + "interfaceIndex": 3, + "interfaceName": "r4-eth1", + "ip": "10.0.11.1" + } + ], + "prefix": "10.0.11.0/24", + "protocol": "isis", + "vrfId": 4, + "vrfName": "r4-cust1" + }, + { + "nexthops": [ + { + "active": true, + "directlyConnected": true, + "fib": true, + "interfaceIndex": 3, + "interfaceName": "r4-eth1" + } + ], + "prefix": "10.0.11.0/24", + "protocol": "connected", + "selected": true, + "vrfId": 4, + "vrfName": "r4-cust1" + } + ], + "10.0.20.0/24": [ + { + "nexthops": [ + { + "active": true, + "afi": "ipv4", + "fib": true, + "interfaceIndex": 3, + "interfaceName": "r4-eth1", + "ip": "10.0.11.1" + } + ], + "prefix": "10.0.20.0/24", + "protocol": "isis", + "selected": true, + "vrfId": 4, + "vrfName": "r4-cust1" + } + ], + "10.0.21.0/24": [ + { + "nexthops": [ + { + "afi": "ipv4", + "interfaceIndex": 2, + "interfaceName": "r4-eth0", + "ip": "10.0.21.2" + } + ], + "prefix": "10.0.21.0/24", + "protocol": "isis", + "vrfId": 4, + "vrfName": "r4-cust1" + }, + { + "nexthops": [ + { + "active": true, + "directlyConnected": true, + "fib": true, + "interfaceIndex": 2, + "interfaceName": "r4-eth0" + } + ], + "prefix": "10.0.21.0/24", + "protocol": "connected", + "selected": true, + "vrfId": 4, + "vrfName": "r4-cust1" + } + ] +} diff --git a/tests/topotests/isis-topo1-vrf/r4/r4_route6.json b/tests/topotests/isis-topo1-vrf/r4/r4_route6.json new file mode 100644 index 0000000000..8d3ea570f0 --- /dev/null +++ b/tests/topotests/isis-topo1-vrf/r4/r4_route6.json @@ -0,0 +1,78 @@ +{ + "2001:db8:1:1::/64": [ + { + "distance": 115, + "metric": 30, + "nexthops": [ + { + "active": true, + "afi": "ipv6", + "fib": true, + "interfaceIndex": 3, + "interfaceName": "r4-eth1" + } + ], + "prefix": "2001:db8:1:1::/64", + "protocol": "isis", + "selected": true, + "vrfId": 4, + "vrfName": "r4-cust1" + } + ], + "2001:db8:1:2::/64": [ + { + "nexthops": [ + { + "active": true, + "directlyConnected": true, + "fib": true, + "interfaceIndex": 2, + "interfaceName": "r4-eth0" + } + ], + "prefix": "2001:db8:1:2::/64", + "protocol": "connected", + "selected": true, + "vrfId": 4, + "vrfName": "r4-cust1" + } + ], + "2001:db8:2:1::/64": [ + { + "distance": 115, + "metric": 20, + "nexthops": [ + { + "active": true, + "afi": "ipv6", + "fib": true, + "interfaceIndex": 3, + "interfaceName": "r4-eth1" + } + ], + "prefix": "2001:db8:2:1::/64", + "protocol": "isis", + "selected": true, + "vrfId": 4, + "vrfName": "r4-cust1" + } + ], + "2001:db8:2:2::/64": [ + { + "nexthops": [ + { + "active": true, + "directlyConnected": true, + "fib": true, + "interfaceIndex": 3, + "interfaceName": "r4-eth1" + } + ], + "prefix": "2001:db8:2:2::/64", + "protocol": "connected", + "selected": true, + "vrfId": 4, + "vrfName": "r4-cust1" + } + ] +} diff --git a/tests/topotests/isis-topo1-vrf/r4/r4_route6_linux.json b/tests/topotests/isis-topo1-vrf/r4/r4_route6_linux.json new file mode 100755 index 0000000000..b1cd5b9db9 --- /dev/null +++ b/tests/topotests/isis-topo1-vrf/r4/r4_route6_linux.json @@ -0,0 +1,26 @@ +{ + "2001:db8:1:1::/64": { + "dev": "r4-eth1", + "metric": "20", + "pref": "medium", + "proto": "187" + }, + "2001:db8:1:2::/64": { + "dev": "r4-eth0", + "metric": "256", + "pref": "medium", + "proto": "kernel" + }, + "2001:db8:2:1::/64": { + "dev": "r4-eth1", + "metric": "20", + "pref": "medium", + "proto": "187" + }, + "2001:db8:2:2::/64": { + "dev": "r4-eth1", + "metric": "256", + "pref": "medium", + "proto": "kernel" + } +} diff --git a/tests/topotests/isis-topo1-vrf/r4/r4_route_linux.json b/tests/topotests/isis-topo1-vrf/r4/r4_route_linux.json new file mode 100755 index 0000000000..3198b85789 --- /dev/null +++ b/tests/topotests/isis-topo1-vrf/r4/r4_route_linux.json @@ -0,0 +1,24 @@ +{ + "10.0.10.0/24": { + "dev": "r4-eth1", + "metric": "20", + "proto": "187", + "via": "10.0.11.1" + }, + "10.0.11.0/24": { + "dev": "r4-eth1", + "proto": "kernel", + "scope": "link" + }, + "10.0.20.0/24": { + "dev": "r4-eth1", + "metric": "20", + "proto": "187", + "via": "10.0.11.1" + }, + "10.0.21.0/24": { + "dev": "r4-eth0", + "proto": "kernel", + "scope": "link" + } +} diff --git a/tests/topotests/isis-topo1-vrf/r4/r4_topology.json b/tests/topotests/isis-topo1-vrf/r4/r4_topology.json new file mode 100644 index 0000000000..0d69550cad --- /dev/null +++ b/tests/topotests/isis-topo1-vrf/r4/r4_topology.json @@ -0,0 +1,132 @@ +{ + "1": { + "level-1": { + "ipv4": [ + { + "vertex": "r4" + }, + { + "metric": "internal", + "parent": "0", + "type": "IP", + "vertex": "10.0.11.0/24" + }, + { + "interface": "r4-eth1", + "metric": "10", + "next-hop": "r5", + "parent": "r4(4)", + "type": "TE-IS", + "vertex": "r5" + }, + { + "interface": "r5", + "metric": "TE", + "next-hop": "20", + "parent": "r4-eth1", + "type": "IP", + "vertex": "10.0.10.0/24" + }, + { + "interface": "r5", + "metric": "TE", + "next-hop": "20", + "parent": "r4-eth1", + "type": "IP", + "vertex": "10.0.11.0/24" + }, + { + "interface": "r5", + "metric": "TE", + "next-hop": "30", + "parent": "r4-eth1", + "type": "IP", + "vertex": "10.0.20.0/24" + } + ], + "ipv6": [ + { + "vertex": "r4" + }, + { + "metric": "internal", + "parent": "0", + "type": "IP6", + "vertex": "2001:db8:2:2::/64" + }, + { + "interface": "r4-eth1", + "metric": "10", + "next-hop": "r5", + "parent": "r4(4)", + "type": "TE-IS", + "vertex": "r5" + }, + { + "interface": "r5", + "metric": "internal", + "next-hop": "20", + "parent": "r4-eth1", + "type": "IP6", + "vertex": "2001:db8:2:1::/64" + }, + { + "interface": "r5", + "metric": "internal", + "next-hop": "30", + "parent": "r4-eth1", + "type": "IP6", + "vertex": "2001:db8:1:1::/64" + } + ] + }, + "level-2": { + "ipv4": [ + { + "vertex": "r4" + }, + { + "metric": "internal", + "parent": "0", + "type": "IP", + "vertex": "10.0.21.0/24" + }, + { + "interface": "r4-eth0", + "metric": "10", + "next-hop": "r2", + "parent": "r4(4)", + "type": "TE-IS", + "vertex": "r2" + }, + { + "interface": "r2", + "metric": "TE", + "next-hop": "20", + "parent": "r4-eth0", + "type": "IP", + "vertex": "10.0.21.0/24" + } + ], + "ipv6": [ + { + "vertex": "r4" + }, + { + "metric": "internal", + "parent": "0", + "type": "IP6", + "vertex": "2001:db8:1:2::/64" + }, + { + "interface": "r4-eth0", + "metric": "10", + "next-hop": "r2", + "parent": "r4(4)", + "type": "TE-IS", + "vertex": "r2" + } + ] + } + } +} diff --git a/tests/topotests/isis-topo1-vrf/r4/zebra.conf b/tests/topotests/isis-topo1-vrf/r4/zebra.conf new file mode 100755 index 0000000000..9c8941f7a5 --- /dev/null +++ b/tests/topotests/isis-topo1-vrf/r4/zebra.conf @@ -0,0 +1,13 @@ +hostname r4 +interface r4-eth0 vrf r4-cust1 + ip address 10.0.21.1/24 + ipv6 address 2001:db8:1:2::1/64 +! +interface r4-eth1 vrf r4-cust1 + ip address 10.0.11.2/24 + ipv6 address 2001:db8:2:2::2/64 +! +interface lo + ip address 10.254.0.4/32 + ipv6 address 2001:db8:F::4/128 +! diff --git a/tests/topotests/isis-topo1-vrf/r5/isisd.conf b/tests/topotests/isis-topo1-vrf/r5/isisd.conf new file mode 100755 index 0000000000..9e9b030455 --- /dev/null +++ b/tests/topotests/isis-topo1-vrf/r5/isisd.conf @@ -0,0 +1,21 @@ +hostname r5 +debug isis adj-packets +debug isis events +debug isis update-packets +interface r5-eth0 + ip router isis 1 vrf r5-cust1 + ipv6 router isis 1 vrf r5-cust1 + isis circuit-type level-1 +! +interface r5-eth1 + ip router isis 1 vrf r5-cust1 + ipv6 router isis 1 vrf r5-cust1 + isis circuit-type level-1 +! +router isis 1 vrf r5-cust1 + net 10.0000.0000.0000.0000.0000.0000.0000.0000.0005.00 + metric-style wide + is-type level-1 + redistribute ipv4 connected level-1 + redistribute ipv6 connected level-1 +! diff --git a/tests/topotests/isis-topo1-vrf/r5/r5_route.json b/tests/topotests/isis-topo1-vrf/r5/r5_route.json new file mode 100644 index 0000000000..58aee5ddcc --- /dev/null +++ b/tests/topotests/isis-topo1-vrf/r5/r5_route.json @@ -0,0 +1,106 @@ +{ + "10.0.10.0/24": [ + { + "distance": 115, + "metric": 20, + "nexthops": [ + { + "afi": "ipv4", + "interfaceIndex": 2, + "interfaceName": "r5-eth0", + "ip": "10.0.10.2" + } + ], + "prefix": "10.0.10.0/24", + "protocol": "isis", + "vrfId": 4, + "vrfName": "r5-cust1" + }, + { + "nexthops": [ + { + "active": true, + "directlyConnected": true, + "fib": true, + "interfaceIndex": 2, + "interfaceName": "r5-eth0" + } + ], + "prefix": "10.0.10.0/24", + "protocol": "connected", + "selected": true, + "vrfId": 4, + "vrfName": "r5-cust1" + } + ], + "10.0.11.0/24": [ + { + "nexthops": [ + { + "afi": "ipv4", + "interfaceIndex": 3, + "interfaceName": "r5-eth1", + "ip": "10.0.11.2" + } + ], + "prefix": "10.0.11.0/24", + "protocol": "isis", + "vrfId": 4, + "vrfName": "r5-cust1" + }, + { + "nexthops": [ + { + "active": true, + "directlyConnected": true, + "fib": true, + "interfaceIndex": 3, + "interfaceName": "r5-eth1" + } + ], + "prefix": "10.0.11.0/24", + "protocol": "connected", + "selected": true, + "vrfId": 4, + "vrfName": "r5-cust1" + } + ], + "10.0.20.0/24": [ + { + "nexthops": [ + { + "active": true, + "afi": "ipv4", + "fib": true, + "interfaceIndex": 2, + "interfaceName": "r5-eth0", + "ip": "10.0.10.2" + } + ], + "prefix": "10.0.20.0/24", + "protocol": "isis", + "selected": true, + "vrfId": 4, + "vrfName": "r5-cust1" + } + ], + "10.0.21.0/24": [ + { + "nexthops": [ + { + "active": true, + "afi": "ipv4", + "fib": true, + "interfaceIndex": 3, + "interfaceName": "r5-eth1", + "ip": "10.0.11.2" + } + ], + "prefix": "10.0.21.0/24", + "protocol": "isis", + "selected": true, + "vrfId": 4, + "vrfName": "r5-cust1" + } + ] +} diff --git a/tests/topotests/isis-topo1-vrf/r5/r5_route6.json b/tests/topotests/isis-topo1-vrf/r5/r5_route6.json new file mode 100644 index 0000000000..e32bbcc2c1 --- /dev/null +++ b/tests/topotests/isis-topo1-vrf/r5/r5_route6.json @@ -0,0 +1,78 @@ +{ + "2001:db8:1:1::/64": [ + { + "distance": 115, + "metric": 20, + "nexthops": [ + { + "active": true, + "afi": "ipv6", + "fib": true, + "interfaceIndex": 2, + "interfaceName": "r5-eth0" + } + ], + "prefix": "2001:db8:1:1::/64", + "protocol": "isis", + "selected": true, + "vrfId": 4, + "vrfName": "r5-cust1" + } + ], + "2001:db8:1:2::/64": [ + { + "distance": 115, + "metric": 20, + "nexthops": [ + { + "active": true, + "afi": "ipv6", + "fib": true, + "interfaceIndex": 3, + "interfaceName": "r5-eth1" + } + ], + "prefix": "2001:db8:1:2::/64", + "protocol": "isis", + "selected": true, + "vrfId": 4, + "vrfName": "r5-cust1" + } + ], + "2001:db8:2:1::/64": [ + { + "nexthops": [ + { + "active": true, + "directlyConnected": true, + "fib": true, + "interfaceIndex": 2, + "interfaceName": "r5-eth0" + } + ], + "prefix": "2001:db8:2:1::/64", + "protocol": "connected", + "selected": true, + "vrfId": 4, + "vrfName": "r5-cust1" + } + ], + "2001:db8:2:2::/64": [ + { + "nexthops": [ + { + "active": true, + "directlyConnected": true, + "fib": true, + "interfaceIndex": 3, + "interfaceName": "r5-eth1" + } + ], + "prefix": "2001:db8:2:2::/64", + "protocol": "connected", + "selected": true, + "vrfId": 4, + "vrfName": "r5-cust1" + } + ] +} diff --git a/tests/topotests/isis-topo1-vrf/r5/r5_route6_linux.json b/tests/topotests/isis-topo1-vrf/r5/r5_route6_linux.json new file mode 100755 index 0000000000..3db3c93ea6 --- /dev/null +++ b/tests/topotests/isis-topo1-vrf/r5/r5_route6_linux.json @@ -0,0 +1,26 @@ +{ + "2001:db8:1:1::/64": { + "dev": "r5-eth0", + "metric": "20", + "pref": "medium", + "proto": "187" + }, + "2001:db8:1:2::/64": { + "dev": "r5-eth1", + "metric": "20", + "pref": "medium", + "proto": "187" + }, + "2001:db8:2:1::/64": { + "dev": "r5-eth0", + "metric": "256", + "pref": "medium", + "proto": "kernel" + }, + "2001:db8:2:2::/64": { + "dev": "r5-eth1", + "metric": "256", + "pref": "medium", + "proto": "kernel" + } +} diff --git a/tests/topotests/isis-topo1-vrf/r5/r5_route_linux.json b/tests/topotests/isis-topo1-vrf/r5/r5_route_linux.json new file mode 100755 index 0000000000..6a38ba864a --- /dev/null +++ b/tests/topotests/isis-topo1-vrf/r5/r5_route_linux.json @@ -0,0 +1,24 @@ +{ + "10.0.10.0/24": { + "dev": "r5-eth0", + "proto": "kernel", + "scope": "link" + }, + "10.0.11.0/24": { + "dev": "r5-eth1", + "proto": "kernel", + "scope": "link" + }, + "10.0.20.0/24": { + "dev": "r5-eth0", + "metric": "20", + "proto": "187", + "via": "10.0.10.2" + }, + "10.0.21.0/24": { + "dev": "r5-eth1", + "metric": "20", + "proto": "187", + "via": "10.0.11.2" + } +} diff --git a/tests/topotests/isis-topo1-vrf/r5/r5_topology.json b/tests/topotests/isis-topo1-vrf/r5/r5_topology.json new file mode 100644 index 0000000000..b4ed6a069d --- /dev/null +++ b/tests/topotests/isis-topo1-vrf/r5/r5_topology.json @@ -0,0 +1,124 @@ +{ + "1": { + "level-1": { + "ipv4": [ + { + "vertex": "r5" + }, + { + "metric": "internal", + "parent": "0", + "type": "IP", + "vertex": "10.0.10.0/24" + }, + { + "metric": "internal", + "parent": "0", + "type": "IP", + "vertex": "10.0.11.0/24" + }, + { + "interface": "r5-eth0", + "metric": "10", + "next-hop": "r3", + "parent": "r5(4)", + "type": "TE-IS", + "vertex": "r3" + }, + { + "interface": "r5-eth1", + "metric": "10", + "next-hop": "r4", + "parent": "r5(4)", + "type": "TE-IS", + "vertex": "r4" + }, + { + "interface": "r3", + "metric": "TE", + "next-hop": "20", + "parent": "r5-eth0", + "type": "IP", + "vertex": "10.0.20.0/24" + }, + { + "interface": "r3", + "metric": "TE", + "next-hop": "20", + "parent": "r5-eth0", + "type": "IP", + "vertex": "10.0.10.0/24" + }, + { + "interface": "r4", + "metric": "TE", + "next-hop": "20", + "parent": "r5-eth1", + "type": "IP", + "vertex": "10.0.21.0/24" + }, + { + "interface": "r4", + "metric": "TE", + "next-hop": "20", + "parent": "r5-eth1", + "type": "IP", + "vertex": "10.0.11.0/24" + } + ], + "ipv6": [ + { + "vertex": "r5" + }, + { + "metric": "internal", + "parent": "0", + "type": "IP6", + "vertex": "2001:db8:2:1::/64" + }, + { + "metric": "internal", + "parent": "0", + "type": "IP6", + "vertex": "2001:db8:2:2::/64" + }, + { + "interface": "r5-eth0", + "metric": "10", + "next-hop": "r3", + "parent": "r5(4)", + "type": "TE-IS", + "vertex": "r3" + }, + { + "interface": "r5-eth1", + "metric": "10", + "next-hop": "r4", + "parent": "r5(4)", + "type": "TE-IS", + "vertex": "r4" + }, + { + "interface": "r3", + "metric": "internal", + "next-hop": "20", + "parent": "r5-eth0", + "type": "IP6", + "vertex": "2001:db8:1:1::/64" + }, + { + "interface": "r4", + "metric": "internal", + "next-hop": "20", + "parent": "r5-eth1", + "type": "IP6", + "vertex": "2001:db8:1:2::/64" + } + ] + }, + "level-2": { + "ipv4": [], + "ipv6": [] + } + } +}
\ No newline at end of file diff --git a/tests/topotests/isis-topo1-vrf/r5/zebra.conf b/tests/topotests/isis-topo1-vrf/r5/zebra.conf new file mode 100755 index 0000000000..c6bc6302fc --- /dev/null +++ b/tests/topotests/isis-topo1-vrf/r5/zebra.conf @@ -0,0 +1,13 @@ +hostname r5 +interface r5-eth0 vrf r5-cust1 + ip address 10.0.10.1/24 + ipv6 address 2001:db8:2:1::1/64 +! +interface r5-eth1 vrf r5-cust1 + ip address 10.0.11.1/24 + ipv6 address 2001:db8:2:2::1/64 +! +interface lo + ip address 10.254.0.5/32 + ipv6 address 2001:db8:F::5/128 +! diff --git a/tests/topotests/isis-topo1-vrf/test_isis_topo1_vrf.dot b/tests/topotests/isis-topo1-vrf/test_isis_topo1_vrf.dot new file mode 100755 index 0000000000..01f9ba780f --- /dev/null +++ b/tests/topotests/isis-topo1-vrf/test_isis_topo1_vrf.dot @@ -0,0 +1,100 @@ +## Color coding: +######################### +## Main FRR: #f08080 red +## Switches: #d0e0d0 gray +## RIP: #19e3d9 Cyan +## RIPng: #fcb314 dark yellow +## OSPFv2: #32b835 Green +## OSPFv3: #19e3d9 Cyan +## ISIS IPv4 #fcb314 dark yellow +## ISIS IPv6 #9a81ec purple +## BGP IPv4 #eee3d3 beige +## BGP IPv6 #fdff00 yellow +##### Colors (see http://www.color-hex.com/) + +graph template { + label="isis topo1"; + + # Routers + r1 [ + shape=doubleoctagon, + label="r1\n10.254.0.1\n2001:DB8:F::1", + fillcolor="#f08080", + style=filled, + ]; + r2 [ + shape=doubleoctagon + label="r2\n10.254.0.2\n2001:DB8:F::2", + fillcolor="#f08080", + style=filled, + ]; + r3 [ + shape=doubleoctagon + label="r3\n10.254.0.3\n2001:DB8:F::3", + fillcolor="#f08080", + style=filled, + ]; + r4 [ + shape=doubleoctagon + label="r4\n10.254.0.4\n2001:DB8:F::4", + fillcolor="#f08080", + style=filled, + ]; + r5 [ + shape=doubleoctagon + label="r5\n10.254.0.5\n2001:DB8:F::5", + fillcolor="#f08080", + style=filled, + ]; + + # Switches + sw1 [ + shape=oval, + label="sw1\n10.0.20.0/24\n2001:DB8:1:1::/64", + fillcolor="#d0e0d0", + style=filled, + ]; + sw2 [ + shape=oval, + label="sw2\n10.0.21.0/24\n2001:DB8:1:2::/64", + fillcolor="#d0e0d0", + style=filled, + ]; + sw3 [ + shape=oval, + label="sw3\n10.0.10.0/24\n2001:DB8:2:1::/64", + fillcolor="#d0e0d0", + style=filled, + ]; + sw4 [ + shape=oval, + label="sw4\n10.0.11.0/24\n2001:DB8:2:2::/64", + fillcolor="#d0e0d0", + style=filled, + ]; + + # Connections + subgraph cluster0 { + label="level 2"; + + r1 -- sw1 [label="eth0\n.2"]; + r2 -- sw2 [label="eth0\n.2"]; + } + + subgraph cluster1 { + label="level 1/2"; + + r3 -- sw1 [label="eth0\n.1"]; + r3 -- sw3 [label="eth1\n.2"]; + + r4 -- sw4 [label="eth1\n.2"]; + r4 -- sw2 [label="eth0\n.1"]; + } + + subgraph cluster2 { + label="level 1"; + + r5 -- sw3 [label="eth0\n.1"]; + r5 -- sw4 [label="eth1\n.1"]; + } +} diff --git a/tests/topotests/isis-topo1-vrf/test_isis_topo1_vrf.jpg b/tests/topotests/isis-topo1-vrf/test_isis_topo1_vrf.jpg Binary files differnew file mode 100755 index 0000000000..4ad730f2a0 --- /dev/null +++ b/tests/topotests/isis-topo1-vrf/test_isis_topo1_vrf.jpg diff --git a/tests/topotests/isis-topo1-vrf/test_isis_topo1_vrf.py b/tests/topotests/isis-topo1-vrf/test_isis_topo1_vrf.py new file mode 100755 index 0000000000..a0e34b71b0 --- /dev/null +++ b/tests/topotests/isis-topo1-vrf/test_isis_topo1_vrf.py @@ -0,0 +1,455 @@ +#!/usr/bin/env python + +# +# Copyright (c) 2020 by Niral Networks, Inc. ("Niral Networks") +# Used Copyright (c) 2018 by Network Device Education Foundation, +# Inc. ("NetDEF") in this file. +# +# Permission to use, copy, modify, and/or distribute this software +# for any purpose with or without fee is hereby granted, provided +# that the above copyright notice and this permission notice appear +# in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +""" +test_isis_topo1_vrf.py: Test ISIS vrf topology. +""" + +import collections +import functools +import json +import os +import re +import sys +import pytest +import platform + +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# pylint: disable=C0413 +from lib import topotest +from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topolog import logger + +from mininet.topo import Topo + + +class ISISTopo1(Topo): + "Simple two layer ISIS vrf topology" + + def build(self, *_args, **_opts): + "Build function" + tgen = get_topogen(self) + + # Add ISIS routers: + # r1 r2 + # | sw1 | sw2 + # r3 r4 + # | | + # sw3 sw4 + # \ / + # r5 + for routern in range(1, 6): + tgen.add_router("r{}".format(routern)) + + # r1 <- sw1 -> r3 + sw = tgen.add_switch("sw1") + sw.add_link(tgen.gears["r1"]) + sw.add_link(tgen.gears["r3"]) + + # r2 <- sw2 -> r4 + sw = tgen.add_switch("sw2") + sw.add_link(tgen.gears["r2"]) + sw.add_link(tgen.gears["r4"]) + + # r3 <- sw3 -> r5 + sw = tgen.add_switch("sw3") + sw.add_link(tgen.gears["r3"]) + sw.add_link(tgen.gears["r5"]) + + # r4 <- sw4 -> r5 + sw = tgen.add_switch("sw4") + sw.add_link(tgen.gears["r4"]) + sw.add_link(tgen.gears["r5"]) + +def setup_module(mod): + "Sets up the pytest environment" + tgen = Topogen(ISISTopo1, mod.__name__) + tgen.start_topology() + + logger.info("Testing with VRF Lite support") + krel = platform.release() + + # May need to adjust handling of vrf traffic depending on kernel version + l3mdev_accept = 0 + if ( + topotest.version_cmp(krel, "4.15") >= 0 + and topotest.version_cmp(krel, "4.18") <= 0 + ): + l3mdev_accept = 1 + + if topotest.version_cmp(krel, "5.0") >= 0: + l3mdev_accept = 1 + + logger.info( + "krel '{0}' setting net.ipv4.tcp_l3mdev_accept={1}".format(krel, l3mdev_accept) + ) + + cmds = [ + "ip link add {0}-cust1 type vrf table 1001", + "ip link add loop1 type dummy", + "ip link set {0}-eth0 master {0}-cust1", + "ip link set {0}-eth1 master {0}-cust1", + ] + + # For all registered routers, load the zebra configuration file + for rname, router in tgen.routers().iteritems(): + # create VRF rx-cust1 and link rx-eth0 to rx-cust1 + for cmd in cmds: + output = tgen.net[rname].cmd(cmd.format(rname)) + output = tgen.net[rname].cmd("sysctl -n net.ipv4.tcp_l3mdev_accept") + logger.info( + "router {0}: existing tcp_l3mdev_accept was {1}".format(rname, output) + ) + + if l3mdev_accept: + output = tgen.net[rname].cmd( + "sysctl -w net.ipv4.tcp_l3mdev_accept={}".format(l3mdev_accept) + ) + + for rname, router in tgen.routers().iteritems(): + router.load_config( + TopoRouter.RD_ZEBRA, + os.path.join(CWD, "{}/zebra.conf".format(rname)) + ) + router.load_config( + TopoRouter.RD_ISIS, + os.path.join(CWD, "{}/isisd.conf".format(rname)) + ) + # After loading the configurations, this function loads configured daemons. + tgen.start_router() + + has_version_20 = False + for router in tgen.routers().values(): + if router.has_version("<", "4"): + has_version_20 = True + + if has_version_20: + logger.info("Skipping ISIS vrf tests for FRR 2.0") + tgen.set_error("ISIS has convergence problems with IPv6") + +def teardown_module(mod): + "Teardown the pytest environment" + tgen = get_topogen() + # move back rx-eth0 to default VRF + # delete rx-vrf + tgen.stop_topology() + +def test_isis_convergence(): + "Wait for the protocol to converge before starting to test" + tgen = get_topogen() + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("waiting for ISIS protocol to converge") + + for rname, router in tgen.routers().iteritems(): + filename = "{0}/{1}/{1}_topology.json".format(CWD, rname) + expected = json.loads(open(filename).read()) + def compare_isis_topology(router, expected): + "Helper function to test ISIS vrf topology convergence." + actual = show_isis_topology(router) + + return topotest.json_cmp(actual, expected) + + test_func = functools.partial(compare_isis_topology, router, expected) + (result, diff) = topotest.run_and_expect(test_func, None, wait=0.5, count=120) + assert result, "ISIS did not converge on {}:\n{}".format(rname, diff) + +def test_isis_route_installation(): + "Check whether all expected routes are present" + tgen = get_topogen() + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("Checking routers for installed ISIS vrf routes") + # Check for routes in 'show ip route vrf {}-cust1 json' + for rname, router in tgen.routers().iteritems(): + filename = "{0}/{1}/{1}_route.json".format(CWD, rname) + expected = json.loads(open(filename, "r").read()) + actual = router.vtysh_cmd("show ip route vrf {0}-cust1 json".format(rname) , isjson=True) + # Older FRR versions don't list interfaces in some ISIS routes + if router.has_version("<", "3.1"): + for network, routes in expected.iteritems(): + for route in routes: + if route["protocol"] != "isis": + continue + + for nexthop in route["nexthops"]: + nexthop.pop("interfaceIndex", None) + nexthop.pop("interfaceName", None) + + assertmsg = "Router '{}' routes mismatch".format(rname) + assert topotest.json_cmp(actual, expected) is None, assertmsg + + +def test_isis_linux_route_installation(): + + dist = platform.dist() + + if (dist[1] == "16.04"): + pytest.skip("Kernel not supported for vrf") + + "Check whether all expected routes are present and installed in the OS" + tgen = get_topogen() + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("Checking routers for installed ISIS vrf routes in OS") + # Check for routes in `ip route show vrf {}-cust1` + for rname, router in tgen.routers().iteritems(): + filename = "{0}/{1}/{1}_route_linux.json".format(CWD, rname) + expected = json.loads(open(filename, "r").read()) + actual = topotest.ip4_vrf_route(router) + + # Older FRR versions install routes using different proto + if router.has_version("<", "3.1"): + for network, netoptions in expected.iteritems(): + if "proto" in netoptions and netoptions["proto"] == "187": + netoptions["proto"] = "zebra" + + assertmsg = "Router '{}' OS routes mismatch".format(rname) + assert topotest.json_cmp(actual, expected) is None, assertmsg + +def test_isis_route6_installation(): + "Check whether all expected routes are present" + tgen = get_topogen() + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("Checking routers for installed ISIS vrf IPv6 routes") + # Check for routes in 'show ipv6 route vrf {}-cust1 json' + for rname, router in tgen.routers().iteritems(): + filename = "{0}/{1}/{1}_route6.json".format(CWD, rname) + expected = json.loads(open(filename, "r").read()) + actual = router.vtysh_cmd("show ipv6 route vrf {}-cust1 json".format(rname) , isjson=True) + + # Older FRR versions don't list interfaces in some ISIS routes + if router.has_version("<", "3.1"): + for network, routes in expected.iteritems(): + for route in routes: + if route["protocol"] != "isis": + continue + + for nexthop in route["nexthops"]: + nexthop.pop("interfaceIndex", None) + nexthop.pop("interfaceName", None) + + assertmsg = "Router '{}' routes mismatch".format(rname) + assert topotest.json_cmp(actual, expected) is None, assertmsg + +def test_isis_linux_route6_installation(): + + dist = platform.dist() + + if (dist[1] == "16.04"): + pytest.skip("Kernel not supported for vrf") + + "Check whether all expected routes are present and installed in the OS" + tgen = get_topogen() + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("Checking routers for installed ISIS vrf IPv6 routes in OS") + # Check for routes in `ip -6 route show vrf {}-cust1` + for rname, router in tgen.routers().iteritems(): + filename = "{0}/{1}/{1}_route6_linux.json".format(CWD, rname) + expected = json.loads(open(filename, "r").read()) + actual = topotest.ip6_vrf_route(router) + + # Older FRR versions install routes using different proto + if router.has_version("<", "3.1"): + for network, netoptions in expected.iteritems(): + if "proto" in netoptions and netoptions["proto"] == "187": + netoptions["proto"] = "zebra" + + assertmsg = "Router '{}' OS routes mismatch".format(rname) + assert topotest.json_cmp(actual, expected) is None, assertmsg + +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)) + + +# +# Auxiliary functions +# + + +def dict_merge(dct, merge_dct): + """ + Recursive dict merge. Inspired by :meth:``dict.update()``, instead of + updating only top-level keys, dict_merge recurses down into dicts nested + to an arbitrary depth, updating keys. The ``merge_dct`` is merged into + ``dct``. + :param dct: dict onto which the merge is executed + :param merge_dct: dct merged into dct + :return: None + + Source: + https://gist.github.com/angstwad/bf22d1822c38a92ec0a9 + """ + for k, v in merge_dct.iteritems(): + if ( + k in dct + and isinstance(dct[k], dict) + and isinstance(merge_dct[k], collections.Mapping) + ): + dict_merge(dct[k], merge_dct[k]) + else: + dct[k] = merge_dct[k] + + +def parse_topology(lines, level): + """ + Parse the output of 'show isis topology level-X' into a Python dict. + """ + areas = {} + area = None + ipv = None + + for line in lines: + area_match = re.match(r"Area (.+):", line) + if area_match: + area = area_match.group(1) + if area not in areas: + areas[area] = {level: {"ipv4": [], "ipv6": []}} + ipv = None + continue + elif area is None: + continue + + if re.match(r"IS\-IS paths to level-. routers that speak IPv6", line): + ipv = "ipv6" + continue + if re.match(r"IS\-IS paths to level-. routers that speak IP", line): + ipv = "ipv4" + continue + + item_match = re.match(r"([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+)", line) + if item_match is not None: + # Skip header + if ( + item_match.group(1) == "Vertex" + and item_match.group(2) == "Type" + and item_match.group(3) == "Metric" + and item_match.group(4) == "Next-Hop" + and item_match.group(5) == "Interface" + and item_match.group(6) == "Parent" + ): + continue + + areas[area][level][ipv].append( + { + "vertex": item_match.group(1), + "type": item_match.group(2), + "metric": item_match.group(3), + "next-hop": item_match.group(4), + "interface": item_match.group(5), + "parent": item_match.group(6), + } + ) + continue + + item_match = re.match(r"([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+)", line) + if item_match is not None: + areas[area][level][ipv].append( + { + "vertex": item_match.group(1), + "type": item_match.group(2), + "metric": item_match.group(3), + "parent": item_match.group(4), + } + ) + continue + + item_match = re.match(r"([^ ]+)", line) + if item_match is not None: + areas[area][level][ipv].append({"vertex": item_match.group(1)}) + continue + + return areas + + +def show_isis_topology(router): + """ + Get the ISIS vrf topology in a dictionary format. + + Sample: + { + 'area-name': { + 'level-1': [ + { + 'vertex': 'r1' + } + ], + 'level-2': [ + { + 'vertex': '10.0.0.1/24', + 'type': 'IP', + 'parent': '0', + 'metric': 'internal' + } + ] + }, + 'area-name-2': { + 'level-2': [ + { + "interface": "rX-ethY", + "metric": "Z", + "next-hop": "rA", + "parent": "rC(B)", + "type": "TE-IS", + "vertex": "rD" + } + ] + } + } + """ + l1out = topotest.normalize_text( + router.vtysh_cmd("show isis vrf {}-cust1 topology level-1".format(router.name)) + ).splitlines() + l2out = topotest.normalize_text( + router.vtysh_cmd("show isis vrf {}-cust1 topology level-2".format(router.name)) + ).splitlines() + + l1 = parse_topology(l1out, "level-1") + l2 = parse_topology(l2out, "level-2") + + dict_merge(l1, l2) + return l1 + diff --git a/tests/topotests/lib/topotest.py b/tests/topotests/lib/topotest.py index 766ab71ed1..5acec83b6e 100644 --- a/tests/topotests/lib/topotest.py +++ b/tests/topotests/lib/topotest.py @@ -721,6 +721,49 @@ def ip4_route(node): return result +def ip4_vrf_route(node): + """ + Gets a structured return of the command 'ip route show vrf {0}-cust1'. + It can be used in conjuction with json_cmp() to provide accurate assert explanations. + + Return example: + { + '10.0.1.0/24': { + 'dev': 'eth0', + 'via': '172.16.0.1', + 'proto': '188', + }, + '10.0.2.0/24': { + 'dev': 'eth1', + 'proto': 'kernel', + } + } + """ + output = normalize_text( + node.run("ip route show vrf {0}-cust1".format(node.name))).splitlines() + + result = {} + for line in output: + columns = line.split(" ") + route = result[columns[0]] = {} + prev = None + for column in columns: + if prev == "dev": + route["dev"] = column + if prev == "via": + route["via"] = column + if prev == "proto": + # translate protocol names back to numbers + route["proto"] = proto_name_to_number(column) + if prev == "metric": + route["metric"] = column + if prev == "scope": + route["scope"] = column + prev = column + + return result + + def ip6_route(node): """ Gets a structured return of the command 'ip -6 route'. It can be used in @@ -761,6 +804,47 @@ def ip6_route(node): return result +def ip6_vrf_route(node): + """ + Gets a structured return of the command 'ip -6 route show vrf {0}-cust1'. + It can be used in conjuction with json_cmp() to provide accurate assert explanations. + + Return example: + { + '2001:db8:1::/64': { + 'dev': 'eth0', + 'proto': '188', + }, + '2001:db8:2::/64': { + 'dev': 'eth1', + 'proto': 'kernel', + } + } + """ + output = normalize_text( + node.run("ip -6 route show vrf {0}-cust1".format(node.name))).splitlines() + result = {} + for line in output: + columns = line.split(" ") + route = result[columns[0]] = {} + prev = None + for column in columns: + if prev == "dev": + route["dev"] = column + if prev == "via": + route["via"] = column + if prev == "proto": + # translate protocol names back to numbers + route["proto"] = proto_name_to_number(column) + if prev == "metric": + route["metric"] = column + if prev == "pref": + route["pref"] = column + prev = column + + return result + + def ip_rules(node): """ Gets a structured return of the command 'ip rule'. It can be used in |
