diff options
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 |
