diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 09:53:30 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 09:53:30 +0000 |
commit | 2c7cac91ed6e7db0f6937923d2b57f97dbdbc337 (patch) | |
tree | c05dc0f8e6aa3accc84e3e5cffc933ed94941383 /tests/topotests/ospf_topo1 | |
parent | Initial commit. (diff) | |
download | frr-upstream/8.4.4.tar.xz frr-upstream/8.4.4.zip |
Adding upstream version 8.4.4.upstream/8.4.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/topotests/ospf_topo1')
36 files changed, 1141 insertions, 0 deletions
diff --git a/tests/topotests/ospf_topo1/__init__.py b/tests/topotests/ospf_topo1/__init__.py new file mode 100755 index 0000000..e69de29 --- /dev/null +++ b/tests/topotests/ospf_topo1/__init__.py diff --git a/tests/topotests/ospf_topo1/r1/ospf6d.conf b/tests/topotests/ospf_topo1/r1/ospf6d.conf new file mode 100644 index 0000000..ca3497b --- /dev/null +++ b/tests/topotests/ospf_topo1/r1/ospf6d.conf @@ -0,0 +1,13 @@ +! +router ospf6 + ospf6 router-id 10.0.255.1 + redistribute kernel + redistribute connected + redistribute static + interface r1-eth0 area 0.0.0.0 + interface r1-eth1 area 0.0.0.0 +! +int r1-eth1 + ipv6 ospf6 dead-interval 10 + ipv6 ospf6 hello-interval 2 +! diff --git a/tests/topotests/ospf_topo1/r1/ospf6route.txt b/tests/topotests/ospf_topo1/r1/ospf6route.txt new file mode 100644 index 0000000..d01511c --- /dev/null +++ b/tests/topotests/ospf_topo1/r1/ospf6route.txt @@ -0,0 +1,13 @@ +*N IA 2001:db8:1::/64 :: r1-eth0 00:02:11 +*N IA 2001:db8:2::/64 fe80::b038:bcff:fe27:e2d6 r1-eth1 00:02:06 + N E2 2001:db8:2::/64 fe80::b038:bcff:fe27:e2d6 r1-eth1 00:02:06 +*N IA 2001:db8:3::/64 :: r1-eth1 00:02:11 + N E2 2001:db8:3::/64 fe80::50b7:d8ff:fe5f:8ff0 r1-eth1 00:02:06 + N E2 2001:db8:3::/64 fe80::b038:bcff:fe27:e2d6 r1-eth1 00:02:06 +*N IA 2001:db8:100::/64 fe80::50b7:d8ff:fe5f:8ff0 r1-eth1 00:02:06 + N E2 2001:db8:100::/64 fe80::50b7:d8ff:fe5f:8ff0 r1-eth1 00:02:06 +*N IE 2001:db8:200::/64 fe80::50b7:d8ff:fe5f:8ff0 r1-eth1 00:02:06 + N E2 2001:db8:200::/64 fe80::50b7:d8ff:fe5f:8ff0 r1-eth1 00:02:06 + N E2 2001:db8:200::/64 fe80::50b7:d8ff:fe5f:8ff0 r1-eth1 00:02:04 +*N IE 2001:db8:300::/64 fe80::50b7:d8ff:fe5f:8ff0 r1-eth1 00:02:04 + N E2 2001:db8:300::/64 fe80::50b7:d8ff:fe5f:8ff0 r1-eth1 00:02:04 diff --git a/tests/topotests/ospf_topo1/r1/ospf6route_down.txt b/tests/topotests/ospf_topo1/r1/ospf6route_down.txt new file mode 100644 index 0000000..57113d0 --- /dev/null +++ b/tests/topotests/ospf_topo1/r1/ospf6route_down.txt @@ -0,0 +1,5 @@ +*N IA 2001:db8:1::/64 :: r1-eth0 00:01:51 +*N IA 2001:db8:2::/64 fe80::281a:23ff:fe22:8a40 r1-eth1 00:00:52 + N E2 2001:db8:2::/64 fe80::281a:23ff:fe22:8a40 r1-eth1 00:00:52 +*N IA 2001:db8:3::/64 :: r1-eth1 00:00:52 + N E2 2001:db8:3::/64 fe80::281a:23ff:fe22:8a40 r1-eth1 00:00:52 diff --git a/tests/topotests/ospf_topo1/r1/ospf6route_ecmp.txt b/tests/topotests/ospf_topo1/r1/ospf6route_ecmp.txt new file mode 100644 index 0000000..48e9209 --- /dev/null +++ b/tests/topotests/ospf_topo1/r1/ospf6route_ecmp.txt @@ -0,0 +1,13 @@ +*N IA 2001:db8:1::/64 :: r1-eth0 00:06:13 +*N IA 2001:db8:2::/64 fe80::e8bb:62ff:fee8:7022 r1-eth1 00:06:08 + N E2 2001:db8:2::/64 fe80::e8bb:62ff:fee8:7022 r1-eth1 00:06:08 +*N IA 2001:db8:3::/64 :: r1-eth1 00:06:13 + N E2 2001:db8:3::/64 fe80::400f:dff:fe35:a1e7 r1-eth1 00:06:08 + fe80::e8bb:62ff:fee8:7022 r1-eth1 +*N IA 2001:db8:100::/64 fe80::400f:dff:fe35:a1e7 r1-eth1 00:06:08 + N E2 2001:db8:100::/64 fe80::400f:dff:fe35:a1e7 r1-eth1 00:06:08 +*N IE 2001:db8:200::/64 fe80::400f:dff:fe35:a1e7 r1-eth1 00:06:08 + N E2 2001:db8:200::/64 fe80::400f:dff:fe35:a1e7 r1-eth1 00:06:08 + N E2 2001:db8:200::/64 fe80::400f:dff:fe35:a1e7 r1-eth1 00:06:07 +*N IE 2001:db8:300::/64 fe80::400f:dff:fe35:a1e7 r1-eth1 00:06:07 + N E2 2001:db8:300::/64 fe80::400f:dff:fe35:a1e7 r1-eth1 00:06:07 diff --git a/tests/topotests/ospf_topo1/r1/ospfd.conf b/tests/topotests/ospf_topo1/r1/ospfd.conf new file mode 100644 index 0000000..3b5aa19 --- /dev/null +++ b/tests/topotests/ospf_topo1/r1/ospfd.conf @@ -0,0 +1,13 @@ +! +router ospf + ospf router-id 10.0.255.1 + redistribute kernel + redistribute connected + redistribute static + network 10.0.1.0/24 area 0 + network 10.0.3.0/24 area 0 +! +int r1-eth1 + ip ospf hello-interval 2 + ip ospf dead-interval 10 +! diff --git a/tests/topotests/ospf_topo1/r1/ospfroute.txt b/tests/topotests/ospf_topo1/r1/ospfroute.txt new file mode 100644 index 0000000..db64872 --- /dev/null +++ b/tests/topotests/ospf_topo1/r1/ospfroute.txt @@ -0,0 +1,23 @@ +============ OSPF network routing table ============ +N 10.0.1.0/24 [10] area: 0.0.0.0 + directly attached to r1-eth0 +N 10.0.2.0/24 [20] area: 0.0.0.0 + via 10.0.3.3, r1-eth1 +N 10.0.3.0/24 [10] area: 0.0.0.0 + directly attached to r1-eth1 +N 10.0.10.0/24 [20] area: 0.0.0.0 + via 10.0.3.1, r1-eth1 +N IA 172.16.0.0/24 [20] area: 0.0.0.0 + via 10.0.3.1, r1-eth1 +N IA 172.16.1.0/24 [30] area: 0.0.0.0 + via 10.0.3.1, r1-eth1 + +============ OSPF router routing table ============= +R 10.0.255.2 [10] area: 0.0.0.0, ASBR + via 10.0.3.3, r1-eth1 +R 10.0.255.3 [10] area: 0.0.0.0, ABR, ASBR + via 10.0.3.1, r1-eth1 +R 10.0.255.4 IA [20] area: 0.0.0.0, ASBR + via 10.0.3.1, r1-eth1 + +============ OSPF external routing table =========== diff --git a/tests/topotests/ospf_topo1/r1/ospfroute_down.txt b/tests/topotests/ospf_topo1/r1/ospfroute_down.txt new file mode 100644 index 0000000..5c07d81 --- /dev/null +++ b/tests/topotests/ospf_topo1/r1/ospfroute_down.txt @@ -0,0 +1,13 @@ +============ OSPF network routing table ============ +N 10.0.1.0/24 [10] area: 0.0.0.0 + directly attached to r1-eth0 +N 10.0.2.0/24 [20] area: 0.0.0.0 + via 10.0.3.3, r1-eth1 +N 10.0.3.0/24 [10] area: 0.0.0.0 + directly attached to r1-eth1 + +============ OSPF router routing table ============= +R 10.0.255.2 [10] area: 0.0.0.0, ASBR + via 10.0.3.3, r1-eth1 + +============ OSPF external routing table =========== diff --git a/tests/topotests/ospf_topo1/r1/zebra.conf b/tests/topotests/ospf_topo1/r1/zebra.conf new file mode 100644 index 0000000..f6e8efe --- /dev/null +++ b/tests/topotests/ospf_topo1/r1/zebra.conf @@ -0,0 +1,11 @@ +! +interface r1-eth0 + ip address 10.0.1.1/24 + ipv6 address 2001:db8:1::1/64 +! +interface r1-eth1 + ip address 10.0.3.2/24 + ipv6 address 2001:db8:3::2/64 +! +ip forwarding +! diff --git a/tests/topotests/ospf_topo1/r2/ospf6d.conf b/tests/topotests/ospf_topo1/r2/ospf6d.conf new file mode 100644 index 0000000..44047e1 --- /dev/null +++ b/tests/topotests/ospf_topo1/r2/ospf6d.conf @@ -0,0 +1,17 @@ +! +router ospf6 + ospf6 router-id 10.0.255.2 + redistribute kernel + redistribute connected + redistribute static + interface r2-eth0 area 0.0.0.0 + interface r2-eth1 area 0.0.0.0 +! +int r2-eth0 + ipv6 ospf6 hello-interval 2 + ipv6 ospf6 dead-interval 10 +! +int r2-eth1 + ipv6 ospf6 hello-interval 2 + ipv6 ospf6 dead-interval 10 +! diff --git a/tests/topotests/ospf_topo1/r2/ospf6route.txt b/tests/topotests/ospf_topo1/r2/ospf6route.txt new file mode 100644 index 0000000..71c84d2 --- /dev/null +++ b/tests/topotests/ospf_topo1/r2/ospf6route.txt @@ -0,0 +1,13 @@ +*N IA 2001:db8:1::/64 fe80::b49b:4cff:fe80:4e87 r2-eth1 00:03:34 + N E2 2001:db8:1::/64 fe80::b49b:4cff:fe80:4e87 r2-eth1 00:03:34 +*N IA 2001:db8:2::/64 :: r2-eth0 00:03:39 +*N IA 2001:db8:3::/64 :: r2-eth1 00:03:34 + N E2 2001:db8:3::/64 fe80::b49b:4cff:fe80:4e87 r2-eth1 00:03:34 + N E2 2001:db8:3::/64 fe80::50b7:d8ff:fe5f:8ff0 r2-eth1 00:03:34 +*N IA 2001:db8:100::/64 fe80::50b7:d8ff:fe5f:8ff0 r2-eth1 00:03:34 + N E2 2001:db8:100::/64 fe80::50b7:d8ff:fe5f:8ff0 r2-eth1 00:03:34 +*N IE 2001:db8:200::/64 fe80::50b7:d8ff:fe5f:8ff0 r2-eth1 00:03:34 + N E2 2001:db8:200::/64 fe80::50b7:d8ff:fe5f:8ff0 r2-eth1 00:03:34 + N E2 2001:db8:200::/64 fe80::50b7:d8ff:fe5f:8ff0 r2-eth1 00:03:32 +*N IE 2001:db8:300::/64 fe80::50b7:d8ff:fe5f:8ff0 r2-eth1 00:03:32 + N E2 2001:db8:300::/64 fe80::50b7:d8ff:fe5f:8ff0 r2-eth1 00:03:32 diff --git a/tests/topotests/ospf_topo1/r2/ospf6route_down.txt b/tests/topotests/ospf_topo1/r2/ospf6route_down.txt new file mode 100644 index 0000000..a1f0412 --- /dev/null +++ b/tests/topotests/ospf_topo1/r2/ospf6route_down.txt @@ -0,0 +1,5 @@ +*N IA 2001:db8:1::/64 fe80::fc0b:daff:fe31:6791 r2-eth1 00:06:19 + N E2 2001:db8:1::/64 fe80::fc0b:daff:fe31:6791 r2-eth1 00:06:19 +*N IA 2001:db8:2::/64 :: r2-eth0 00:07:17 +*N IA 2001:db8:3::/64 :: r2-eth1 00:06:27 + N E2 2001:db8:3::/64 fe80::fc0b:daff:fe31:6791 r2-eth1 00:06:19 diff --git a/tests/topotests/ospf_topo1/r2/ospf6route_ecmp.txt b/tests/topotests/ospf_topo1/r2/ospf6route_ecmp.txt new file mode 100644 index 0000000..0c06d23 --- /dev/null +++ b/tests/topotests/ospf_topo1/r2/ospf6route_ecmp.txt @@ -0,0 +1,13 @@ +*N IA 2001:db8:1::/64 fe80::98cd:28ff:fe5e:3d93 r2-eth1 00:07:04 + N E2 2001:db8:1::/64 fe80::98cd:28ff:fe5e:3d93 r2-eth1 00:07:04 +*N IA 2001:db8:2::/64 :: r2-eth0 00:07:09 +*N IA 2001:db8:3::/64 :: r2-eth1 00:07:04 + N E2 2001:db8:3::/64 fe80::400f:dff:fe35:a1e7 r2-eth1 00:07:04 + fe80::98cd:28ff:fe5e:3d93 r2-eth1 +*N IA 2001:db8:100::/64 fe80::400f:dff:fe35:a1e7 r2-eth1 00:07:04 + N E2 2001:db8:100::/64 fe80::400f:dff:fe35:a1e7 r2-eth1 00:07:04 +*N IE 2001:db8:200::/64 fe80::400f:dff:fe35:a1e7 r2-eth1 00:07:04 + N E2 2001:db8:200::/64 fe80::400f:dff:fe35:a1e7 r2-eth1 00:07:04 + N E2 2001:db8:200::/64 fe80::400f:dff:fe35:a1e7 r2-eth1 00:07:03 +*N IE 2001:db8:300::/64 fe80::400f:dff:fe35:a1e7 r2-eth1 00:07:03 + N E2 2001:db8:300::/64 fe80::400f:dff:fe35:a1e7 r2-eth1 00:07:03 diff --git a/tests/topotests/ospf_topo1/r2/ospfd.conf b/tests/topotests/ospf_topo1/r2/ospfd.conf new file mode 100644 index 0000000..1a7ccdf --- /dev/null +++ b/tests/topotests/ospf_topo1/r2/ospfd.conf @@ -0,0 +1,13 @@ +! +router ospf + ospf router-id 10.0.255.2 + redistribute kernel + redistribute connected + redistribute static + network 10.0.2.0/24 area 0 + network 10.0.3.0/24 area 0 +! +int r2-eth1 + ip ospf hello-interval 2 + ip ospf dead-interval 10 +! diff --git a/tests/topotests/ospf_topo1/r2/ospfroute.txt b/tests/topotests/ospf_topo1/r2/ospfroute.txt new file mode 100644 index 0000000..79b389b --- /dev/null +++ b/tests/topotests/ospf_topo1/r2/ospfroute.txt @@ -0,0 +1,23 @@ +============ OSPF network routing table ============ +N 10.0.1.0/24 [20] area: 0.0.0.0 + via 10.0.3.2, r2-eth1 +N 10.0.2.0/24 [10] area: 0.0.0.0 + directly attached to r2-eth0 +N 10.0.3.0/24 [10] area: 0.0.0.0 + directly attached to r2-eth1 +N 10.0.10.0/24 [20] area: 0.0.0.0 + via 10.0.3.1, r2-eth1 +N IA 172.16.0.0/24 [20] area: 0.0.0.0 + via 10.0.3.1, r2-eth1 +N IA 172.16.1.0/24 [30] area: 0.0.0.0 + via 10.0.3.1, r2-eth1 + +============ OSPF router routing table ============= +R 10.0.255.1 [10] area: 0.0.0.0, ASBR + via 10.0.3.2, r2-eth1 +R 10.0.255.3 [10] area: 0.0.0.0, ABR, ASBR + via 10.0.3.1, r2-eth1 +R 10.0.255.4 IA [20] area: 0.0.0.0, ASBR + via 10.0.3.1, r2-eth1 + +============ OSPF external routing table =========== diff --git a/tests/topotests/ospf_topo1/r2/ospfroute_down.txt b/tests/topotests/ospf_topo1/r2/ospfroute_down.txt new file mode 100644 index 0000000..b8411e1 --- /dev/null +++ b/tests/topotests/ospf_topo1/r2/ospfroute_down.txt @@ -0,0 +1,13 @@ +============ OSPF network routing table ============ +N 10.0.1.0/24 [20] area: 0.0.0.0 + via 10.0.3.2, r2-eth1 +N 10.0.2.0/24 [10] area: 0.0.0.0 + directly attached to r2-eth0 +N 10.0.3.0/24 [10] area: 0.0.0.0 + directly attached to r2-eth1 + +============ OSPF router routing table ============= +R 10.0.255.1 [10] area: 0.0.0.0, ASBR + via 10.0.3.2, r2-eth1 + +============ OSPF external routing table =========== diff --git a/tests/topotests/ospf_topo1/r2/zebra.conf b/tests/topotests/ospf_topo1/r2/zebra.conf new file mode 100644 index 0000000..407416c --- /dev/null +++ b/tests/topotests/ospf_topo1/r2/zebra.conf @@ -0,0 +1,11 @@ +! +interface r2-eth0 + ip address 10.0.2.1/24 + ipv6 address 2001:db8:2::1/64 +! +interface r2-eth1 + ip address 10.0.3.3/24 + ipv6 address 2001:db8:3::3/64 +! +ip forwarding +! diff --git a/tests/topotests/ospf_topo1/r3/ospf6d.conf b/tests/topotests/ospf_topo1/r3/ospf6d.conf new file mode 100644 index 0000000..13ad9a7 --- /dev/null +++ b/tests/topotests/ospf_topo1/r3/ospf6d.conf @@ -0,0 +1,22 @@ +! +router ospf6 + ospf6 router-id 10.0.255.3 + redistribute kernel + redistribute connected + redistribute static + interface r3-eth0 area 0.0.0.0 + interface r3-eth1 area 0.0.0.0 + interface r3-eth2 area 0.0.0.1 +! +int r3-eth0 + ipv6 ospf6 hello-interval 2 + ipv6 ospf6 dead-interval 10 +! +int r3-eth1 + ipv6 ospf6 hello-interval 2 + ipv6 ospf6 dead-interval 10 +! +int r3-eth2 + ipv6 ospf6 hello-interval 2 + ipv6 ospf6 dead-interval 10 +! diff --git a/tests/topotests/ospf_topo1/r3/ospf6route.txt b/tests/topotests/ospf_topo1/r3/ospf6route.txt new file mode 100644 index 0000000..69c99b4 --- /dev/null +++ b/tests/topotests/ospf_topo1/r3/ospf6route.txt @@ -0,0 +1,12 @@ +*N IA 2001:db8:1::/64 fe80::b49b:4cff:fe80:4e87 r3-eth0 00:04:03 + N E2 2001:db8:1::/64 fe80::b49b:4cff:fe80:4e87 r3-eth0 00:04:03 +*N IA 2001:db8:2::/64 fe80::b038:bcff:fe27:e2d6 r3-eth0 00:04:03 + N E2 2001:db8:2::/64 fe80::b038:bcff:fe27:e2d6 r3-eth0 00:04:03 +*N IA 2001:db8:3::/64 :: r3-eth0 00:04:08 + N E2 2001:db8:3::/64 fe80::b49b:4cff:fe80:4e87 r3-eth0 00:04:03 + N E2 2001:db8:3::/64 fe80::b038:bcff:fe27:e2d6 r3-eth0 00:04:03 +*N IA 2001:db8:100::/64 :: r3-eth1 00:04:08 +*N IA 2001:db8:200::/64 :: r3-eth2 00:04:05 + N E2 2001:db8:200::/64 fe80::78e0:deff:feb1:ec0 r3-eth2 00:04:00 +*N IA 2001:db8:300::/64 fe80::78e0:deff:feb1:ec0 r3-eth2 00:04:00 + N E2 2001:db8:300::/64 fe80::78e0:deff:feb1:ec0 r3-eth2 00:04:00 diff --git a/tests/topotests/ospf_topo1/r3/ospf6route_down.txt b/tests/topotests/ospf_topo1/r3/ospf6route_down.txt new file mode 100644 index 0000000..645ee0b --- /dev/null +++ b/tests/topotests/ospf_topo1/r3/ospf6route_down.txt @@ -0,0 +1,5 @@ +*N IA 2001:db8:100::/64 :: r3-eth1 00:08:06 +*N IA 2001:db8:200::/64 :: r3-eth2 00:08:04 + N E2 2001:db8:200::/64 fe80::80a6:c3ff:fea9:88be r3-eth2 00:07:59 +*N IA 2001:db8:300::/64 fe80::80a6:c3ff:fea9:88be r3-eth2 00:07:59 + N E2 2001:db8:300::/64 fe80::80a6:c3ff:fea9:88be r3-eth2 00:07:59 diff --git a/tests/topotests/ospf_topo1/r3/ospf6route_ecmp.txt b/tests/topotests/ospf_topo1/r3/ospf6route_ecmp.txt new file mode 100644 index 0000000..ecd51be --- /dev/null +++ b/tests/topotests/ospf_topo1/r3/ospf6route_ecmp.txt @@ -0,0 +1,12 @@ +*N IA 2001:db8:1::/64 fe80::98cd:28ff:fe5e:3d93 r3-eth0 00:08:58 + N E2 2001:db8:1::/64 fe80::98cd:28ff:fe5e:3d93 r3-eth0 00:08:58 +*N IA 2001:db8:2::/64 fe80::e8bb:62ff:fee8:7022 r3-eth0 00:08:58 + N E2 2001:db8:2::/64 fe80::e8bb:62ff:fee8:7022 r3-eth0 00:08:58 +*N IA 2001:db8:3::/64 :: r3-eth0 00:09:03 + N E2 2001:db8:3::/64 fe80::98cd:28ff:fe5e:3d93 r3-eth0 00:08:58 + fe80::e8bb:62ff:fee8:7022 r3-eth0 +*N IA 2001:db8:100::/64 :: r3-eth1 00:09:03 +*N IA 2001:db8:200::/64 :: r3-eth2 00:09:02 + N E2 2001:db8:200::/64 fe80::d0dc:aff:fec5:5973 r3-eth2 00:08:57 +*N IA 2001:db8:300::/64 fe80::d0dc:aff:fec5:5973 r3-eth2 00:08:57 + N E2 2001:db8:300::/64 fe80::d0dc:aff:fec5:5973 r3-eth2 00:08:57 diff --git a/tests/topotests/ospf_topo1/r3/ospfd.conf b/tests/topotests/ospf_topo1/r3/ospfd.conf new file mode 100644 index 0000000..3b378c0 --- /dev/null +++ b/tests/topotests/ospf_topo1/r3/ospfd.conf @@ -0,0 +1,18 @@ +! +router ospf + ospf router-id 10.0.255.3 + redistribute kernel + redistribute connected + redistribute static + network 10.0.3.0/24 area 0 + network 10.0.10.0/24 area 0 + network 172.16.0.0/24 area 1 +! +int r3-eth0 + ip ospf hello-interval 2 + ip ospf dead-interval 10 +! +int r3-eth2 + ip ospf hello-interval 2 + ip ospf dead-interval 10 +! diff --git a/tests/topotests/ospf_topo1/r3/ospfroute.txt b/tests/topotests/ospf_topo1/r3/ospfroute.txt new file mode 100644 index 0000000..c779906 --- /dev/null +++ b/tests/topotests/ospf_topo1/r3/ospfroute.txt @@ -0,0 +1,23 @@ +============ OSPF network routing table ============ +N 10.0.1.0/24 [20] area: 0.0.0.0 + via 10.0.3.2, r3-eth0 +N 10.0.2.0/24 [20] area: 0.0.0.0 + via 10.0.3.3, r3-eth0 +N 10.0.3.0/24 [10] area: 0.0.0.0 + directly attached to r3-eth0 +N 10.0.10.0/24 [10] area: 0.0.0.0 + directly attached to r3-eth1 +N 172.16.0.0/24 [10] area: 0.0.0.1 + directly attached to r3-eth2 +N 172.16.1.0/24 [20] area: 0.0.0.1 + via 172.16.0.1, r3-eth2 + +============ OSPF router routing table ============= +R 10.0.255.1 [10] area: 0.0.0.0, ASBR + via 10.0.3.2, r3-eth0 +R 10.0.255.2 [10] area: 0.0.0.0, ASBR + via 10.0.3.3, r3-eth0 +R 10.0.255.4 [10] area: 0.0.0.1, ASBR + via 172.16.0.1, r3-eth2 + +============ OSPF external routing table =========== diff --git a/tests/topotests/ospf_topo1/r3/ospfroute_down.txt b/tests/topotests/ospf_topo1/r3/ospfroute_down.txt new file mode 100644 index 0000000..692a74a --- /dev/null +++ b/tests/topotests/ospf_topo1/r3/ospfroute_down.txt @@ -0,0 +1,13 @@ +============ OSPF network routing table ============ +N 10.0.10.0/24 [10] area: 0.0.0.0 + directly attached to r3-eth1 +N 172.16.0.0/24 [10] area: 0.0.0.1 + directly attached to r3-eth2 +N 172.16.1.0/24 [20] area: 0.0.0.1 + via 172.16.0.1, r3-eth2 + +============ OSPF router routing table ============= +R 10.0.255.4 [10] area: 0.0.0.1, ASBR + via 172.16.0.1, r3-eth2 + +============ OSPF external routing table =========== diff --git a/tests/topotests/ospf_topo1/r3/zebra.conf b/tests/topotests/ospf_topo1/r3/zebra.conf new file mode 100644 index 0000000..a635a88 --- /dev/null +++ b/tests/topotests/ospf_topo1/r3/zebra.conf @@ -0,0 +1,15 @@ +! +interface r3-eth0 + ip address 10.0.3.1/24 + ipv6 address 2001:db8:3::1/64 +! +interface r3-eth1 + ip address 10.0.10.1/24 + ipv6 address 2001:db8:100::1/64 +! +interface r3-eth2 + ip address 172.16.0.2/24 + ipv6 address 2001:db8:200::2/64 +! +ip forwarding +! diff --git a/tests/topotests/ospf_topo1/r4/ospf6d.conf b/tests/topotests/ospf_topo1/r4/ospf6d.conf new file mode 100644 index 0000000..f9bde0e --- /dev/null +++ b/tests/topotests/ospf_topo1/r4/ospf6d.conf @@ -0,0 +1,17 @@ +! +router ospf6 + ospf6 router-id 10.0.255.4 + redistribute kernel + redistribute connected + redistribute static + interface r4-eth0 area 0.0.0.1 + interface r4-eth1 area 0.0.0.1 +! +int r4-eth0 + ipv6 ospf6 hello-interval 2 + ipv6 ospf6 dead-interval 10 +! +int r4-eth1 + ipv6 ospf6 hello-interval 2 + ipv6 ospf6 dead-interval 10 +! diff --git a/tests/topotests/ospf_topo1/r4/ospf6route.txt b/tests/topotests/ospf_topo1/r4/ospf6route.txt new file mode 100644 index 0000000..3a4f5ef --- /dev/null +++ b/tests/topotests/ospf_topo1/r4/ospf6route.txt @@ -0,0 +1,13 @@ +*N IE 2001:db8:1::/64 fe80::987b:baff:fe8a:c864 r4-eth0 00:04:25 + N E2 2001:db8:1::/64 fe80::987b:baff:fe8a:c864 r4-eth0 00:04:25 +*N IE 2001:db8:2::/64 fe80::987b:baff:fe8a:c864 r4-eth0 00:04:25 + N E2 2001:db8:2::/64 fe80::987b:baff:fe8a:c864 r4-eth0 00:04:25 +*N IE 2001:db8:3::/64 fe80::987b:baff:fe8a:c864 r4-eth0 00:04:25 + N E2 2001:db8:3::/64 fe80::987b:baff:fe8a:c864 r4-eth0 00:04:25 + N E2 2001:db8:3::/64 fe80::987b:baff:fe8a:c864 r4-eth0 00:04:25 + N E2 2001:db8:3::/64 fe80::987b:baff:fe8a:c864 r4-eth0 00:04:25 +*N IE 2001:db8:100::/64 fe80::987b:baff:fe8a:c864 r4-eth0 00:04:25 + N E2 2001:db8:100::/64 fe80::987b:baff:fe8a:c864 r4-eth0 00:04:25 +*N IA 2001:db8:200::/64 :: r4-eth0 00:04:30 + N E2 2001:db8:200::/64 fe80::987b:baff:fe8a:c864 r4-eth0 00:04:25 +*N IA 2001:db8:300::/64 :: r4-eth1 00:04:30 diff --git a/tests/topotests/ospf_topo1/r4/ospf6route_down.txt b/tests/topotests/ospf_topo1/r4/ospf6route_down.txt new file mode 100644 index 0000000..165f8db --- /dev/null +++ b/tests/topotests/ospf_topo1/r4/ospf6route_down.txt @@ -0,0 +1,5 @@ +*N IE 2001:db8:100::/64 fe80::b44b:a1ff:fe48:3d69 r4-eth0 00:01:45 + N E2 2001:db8:100::/64 fe80::b44b:a1ff:fe48:3d69 r4-eth0 00:01:45 +*N IA 2001:db8:200::/64 :: r4-eth0 00:01:50 + N E2 2001:db8:200::/64 fe80::b44b:a1ff:fe48:3d69 r4-eth0 00:01:45 +*N IA 2001:db8:300::/64 :: r4-eth1 00:01:50 diff --git a/tests/topotests/ospf_topo1/r4/ospf6route_ecmp.txt b/tests/topotests/ospf_topo1/r4/ospf6route_ecmp.txt new file mode 100644 index 0000000..d0d72a8 --- /dev/null +++ b/tests/topotests/ospf_topo1/r4/ospf6route_ecmp.txt @@ -0,0 +1,12 @@ +*N IE 2001:db8:1::/64 fe80::78fe:fcff:fe51:9afc r4-eth0 00:09:13 + N E2 2001:db8:1::/64 fe80::78fe:fcff:fe51:9afc r4-eth0 00:09:13 +*N IE 2001:db8:2::/64 fe80::78fe:fcff:fe51:9afc r4-eth0 00:09:13 + N E2 2001:db8:2::/64 fe80::78fe:fcff:fe51:9afc r4-eth0 00:09:13 +*N IE 2001:db8:3::/64 fe80::78fe:fcff:fe51:9afc r4-eth0 00:09:13 + N E2 2001:db8:3::/64 fe80::78fe:fcff:fe51:9afc r4-eth0 00:09:13 + N E2 2001:db8:3::/64 fe80::78fe:fcff:fe51:9afc r4-eth0 00:09:13 +*N IE 2001:db8:100::/64 fe80::78fe:fcff:fe51:9afc r4-eth0 00:09:13 + N E2 2001:db8:100::/64 fe80::78fe:fcff:fe51:9afc r4-eth0 00:09:13 +*N IA 2001:db8:200::/64 :: r4-eth0 00:09:17 + N E2 2001:db8:200::/64 fe80::78fe:fcff:fe51:9afc r4-eth0 00:09:13 +*N IA 2001:db8:300::/64 :: r4-eth1 00:09:18 diff --git a/tests/topotests/ospf_topo1/r4/ospfd.conf b/tests/topotests/ospf_topo1/r4/ospfd.conf new file mode 100644 index 0000000..52d2932 --- /dev/null +++ b/tests/topotests/ospf_topo1/r4/ospfd.conf @@ -0,0 +1,13 @@ +! +router ospf + ospf router-id 10.0.255.4 + redistribute kernel + redistribute connected + redistribute static + network 172.16.0.0/24 area 1 + network 172.16.1.0/24 area 1 +! +int r4-eth0 + ip ospf hello-interval 2 + ip ospf dead-interval 10 +! diff --git a/tests/topotests/ospf_topo1/r4/ospfroute.txt b/tests/topotests/ospf_topo1/r4/ospfroute.txt new file mode 100644 index 0000000..b582ef0 --- /dev/null +++ b/tests/topotests/ospf_topo1/r4/ospfroute.txt @@ -0,0 +1,23 @@ +============ OSPF network routing table ============ +N IA 10.0.1.0/24 [30] area: 0.0.0.1 + via 172.16.0.2, r4-eth0 +N IA 10.0.2.0/24 [30] area: 0.0.0.1 + via 172.16.0.2, r4-eth0 +N IA 10.0.3.0/24 [20] area: 0.0.0.1 + via 172.16.0.2, r4-eth0 +N IA 10.0.10.0/24 [20] area: 0.0.0.1 + via 172.16.0.2, r4-eth0 +N 172.16.0.0/24 [10] area: 0.0.0.1 + directly attached to r4-eth0 +N 172.16.1.0/24 [10] area: 0.0.0.1 + directly attached to r4-eth1 + +============ OSPF router routing table ============= +R 10.0.255.1 IA [20] area: 0.0.0.1, ASBR + via 172.16.0.2, r4-eth0 +R 10.0.255.2 IA [20] area: 0.0.0.1, ASBR + via 172.16.0.2, r4-eth0 +R 10.0.255.3 [10] area: 0.0.0.1, ABR, ASBR + via 172.16.0.2, r4-eth0 + +============ OSPF external routing table =========== diff --git a/tests/topotests/ospf_topo1/r4/ospfroute_down.txt b/tests/topotests/ospf_topo1/r4/ospfroute_down.txt new file mode 100644 index 0000000..b0bd0ee --- /dev/null +++ b/tests/topotests/ospf_topo1/r4/ospfroute_down.txt @@ -0,0 +1,13 @@ +============ OSPF network routing table ============ +N IA 10.0.10.0/24 [20] area: 0.0.0.1 + via 172.16.0.2, r4-eth0 +N 172.16.0.0/24 [10] area: 0.0.0.1 + directly attached to r4-eth0 +N 172.16.1.0/24 [10] area: 0.0.0.1 + directly attached to r4-eth1 + +============ OSPF router routing table ============= +R 10.0.255.3 [10] area: 0.0.0.1, ABR, ASBR + via 172.16.0.2, r4-eth0 + +============ OSPF external routing table =========== diff --git a/tests/topotests/ospf_topo1/r4/zebra.conf b/tests/topotests/ospf_topo1/r4/zebra.conf new file mode 100644 index 0000000..39ecbb2 --- /dev/null +++ b/tests/topotests/ospf_topo1/r4/zebra.conf @@ -0,0 +1,11 @@ +! +interface r4-eth0 + ip address 172.16.0.1/24 + ipv6 address 2001:db8:200::1/64 +! +interface r4-eth1 + ip address 172.16.1.100/24 + ipv6 address 2001:db8:300::100/64 +! +ip forwarding +! diff --git a/tests/topotests/ospf_topo1/test_ospf_topo1.dot b/tests/topotests/ospf_topo1/test_ospf_topo1.dot new file mode 100644 index 0000000..469a7ea --- /dev/null +++ b/tests/topotests/ospf_topo1/test_ospf_topo1.dot @@ -0,0 +1,104 @@ +## 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 ospf_topo1 { + label="ospf topo1"; + + # Routers + r1 [ + label="r1\nrtr-id 10.0.255.1/32", + shape=doubleoctagon, + fillcolor="#f08080", + style=filled, + ]; + r2 [ + label="r2\nrtr-id 10.0.255.2/32", + shape=doubleoctagon, + fillcolor="#f08080", + style=filled, + ]; + r3 [ + label="r3\nrtr-id 10.0.255.3/32", + shape=doubleoctagon, + fillcolor="#f08080", + style=filled, + ]; + r4 [ + label="r4\nrtr-id 10.0.255.4/32", + shape=doubleoctagon, + fillcolor="#f08080", + style=filled, + ]; + + # Switches + s1 [ + label="s1\n10.0.1.0/24\n2001:db8:1::/64", + shape=oval, + fillcolor="#d0e0d0", + style=filled, + ]; + s2 [ + label="s2\n10.0.2.0/24\n2001:db8:2::/64", + shape=oval, + fillcolor="#d0e0d0", + style=filled, + ]; + s3 [ + label="s3\n10.0.3.0/24\n2001:db8:3::/64", + shape=oval, + fillcolor="#d0e0d0", + style=filled, + ]; + s4 [ + label="s4\n10.0.10.0/24\n2001:db8:100::/64", + shape=oval, + fillcolor="#d0e0d0", + style=filled, + ]; + s5 [ + label="s5\n172.16.0.0/24\n2001:db8:200::/64", + shape=oval, + fillcolor="#d0e0d0", + style=filled, + ]; + s6 [ + label="s6\n172.16.1.0/24\n2001:db8:300::/64", + shape=oval, + fillcolor="#d0e0d0", + style=filled, + ]; + + # Connections + subgraph cluster0 { + label="area 0" + + r1 -- s1 [label="eth0\n.1\n::1"]; + r1 -- s3 [label="eth1\n.2\n::2"]; + + r2 -- s2 [label="eth0\n.1\n::1"]; + r2 -- s3 [label="eth1\n.3\n::3"]; + + r3 -- s3 [label="eth0\n.1\n::1"]; + r3 -- s4 [label="eth1\n.1\n::1"]; + } + + subgraph cluster1 { + label="area 1" + + r3 -- s5 [label="eth2\n.2\n::2"]; + + r4 -- s5 [label="eth0\n.1\n::1"]; + r4 -- s6 [label="eth1\n.100\n::100"]; + } +} diff --git a/tests/topotests/ospf_topo1/test_ospf_topo1.jpg b/tests/topotests/ospf_topo1/test_ospf_topo1.jpg Binary files differnew file mode 100644 index 0000000..1e93170 --- /dev/null +++ b/tests/topotests/ospf_topo1/test_ospf_topo1.jpg diff --git a/tests/topotests/ospf_topo1/test_ospf_topo1.py b/tests/topotests/ospf_topo1/test_ospf_topo1.py new file mode 100644 index 0000000..37facfc --- /dev/null +++ b/tests/topotests/ospf_topo1/test_ospf_topo1.py @@ -0,0 +1,598 @@ +#!/usr/bin/env python + +# +# test_ospf_topo1.py +# Part of NetDEF Topology Tests +# +# Copyright (c) 2017 by +# Network Device Education Foundation, Inc. ("NetDEF") +# +# 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_ospf_topo1.py: Test the FRR OSPF routing daemon. +""" + +import os +import re +import sys +from functools import partial +from time import sleep +import pytest + +# Save the Current Working Directory to find configuration files. +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# pylint: disable=C0413 +# Import topogen and topotest helpers +from lib import topotest +from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topolog import logger + +# Required to instantiate the topology builder class. + +pytestmark = [pytest.mark.ospfd] + + +def build_topo(tgen): + "Build function" + + # Create 4 routers + for routern in range(1, 5): + tgen.add_router("r{}".format(routern)) + + # Create a empty network for router 1 + switch = tgen.add_switch("s1") + switch.add_link(tgen.gears["r1"]) + + # Create a empty network for router 2 + switch = tgen.add_switch("s2") + switch.add_link(tgen.gears["r2"]) + + # Interconect router 1, 2 and 3 + switch = tgen.add_switch("s3") + switch.add_link(tgen.gears["r1"]) + switch.add_link(tgen.gears["r2"]) + switch.add_link(tgen.gears["r3"]) + + # Create empty netowrk for router3 + switch = tgen.add_switch("s4") + switch.add_link(tgen.gears["r3"]) + + # Interconect router 3 and 4 + switch = tgen.add_switch("s5") + switch.add_link(tgen.gears["r3"]) + switch.add_link(tgen.gears["r4"]) + + # Create a empty network for router 4 + switch = tgen.add_switch("s6") + switch.add_link(tgen.gears["r4"]) + + +def setup_module(mod): + "Sets up the pytest environment" + tgen = Topogen(build_topo, mod.__name__) + tgen.start_topology() + + ospf6_config = "ospf6d.conf" + + router_list = tgen.routers() + for rname, router in router_list.items(): + router.load_config( + TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) + ) + router.load_config( + TopoRouter.RD_OSPF, os.path.join(CWD, "{}/ospfd.conf".format(rname)) + ) + router.load_config( + TopoRouter.RD_OSPF6, os.path.join(CWD, "{}/{}".format(rname, ospf6_config)) + ) + + # Initialize all routers. + tgen.start_router() + + +def teardown_module(mod): + "Teardown the pytest environment" + tgen = get_topogen() + tgen.stop_topology() + + +def test_wait_protocol_convergence(): + "Wait for OSPFv2/OSPFv3 to converge" + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("waiting for protocols to converge") + + def expect_ospfv2_neighbor_full(router, neighbor): + "Wait until OSPFv2 convergence." + logger.info("waiting OSPFv2 router '{}'".format(router)) + + def run_command_and_expect(): + """ + Function that runs command and expect the following outcomes: + * Full/DR + * Full/DROther + * Full/Backup + """ + result = tgen.gears[router].vtysh_cmd( + "show ip ospf neighbor json", isjson=True + ) + if ( + topotest.json_cmp( + result, {"neighbors": {neighbor: [{"converged": "Full"}]}} + ) + is None + ): + return None + + if ( + topotest.json_cmp( + result, {"neighbors": {neighbor: [{"converged": "Full"}]}} + ) + is None + ): + return None + + return topotest.json_cmp( + result, {"neighbors": {neighbor: [{"converged": "Full"}]}} + ) + + _, result = topotest.run_and_expect( + run_command_and_expect, None, count=130, wait=1 + ) + assertmsg = '"{}" convergence failure'.format(router) + assert result is None, assertmsg + + def expect_ospfv3_neighbor_full(router, neighbor): + "Wait until OSPFv3 convergence." + logger.info("waiting OSPFv3 router '{}'".format(router)) + test_func = partial( + topotest.router_json_cmp, + tgen.gears[router], + "show ipv6 ospf6 neighbor json", + {"neighbors": [{"neighborId": neighbor, "state": "Full"}]}, + ) + _, result = topotest.run_and_expect(test_func, None, count=130, wait=1) + assertmsg = '"{}" convergence failure'.format(router) + assert result is None, assertmsg + + # Wait for OSPFv2 convergence + expect_ospfv2_neighbor_full("r1", "10.0.255.2") + expect_ospfv2_neighbor_full("r1", "10.0.255.3") + expect_ospfv2_neighbor_full("r2", "10.0.255.1") + expect_ospfv2_neighbor_full("r2", "10.0.255.3") + expect_ospfv2_neighbor_full("r3", "10.0.255.1") + expect_ospfv2_neighbor_full("r3", "10.0.255.2") + expect_ospfv2_neighbor_full("r3", "10.0.255.4") + expect_ospfv2_neighbor_full("r4", "10.0.255.3") + + # Wait for OSPFv3 convergence + expect_ospfv3_neighbor_full("r1", "10.0.255.2") + expect_ospfv3_neighbor_full("r1", "10.0.255.3") + expect_ospfv3_neighbor_full("r2", "10.0.255.1") + expect_ospfv3_neighbor_full("r2", "10.0.255.3") + expect_ospfv3_neighbor_full("r3", "10.0.255.1") + expect_ospfv3_neighbor_full("r3", "10.0.255.2") + expect_ospfv3_neighbor_full("r3", "10.0.255.4") + expect_ospfv3_neighbor_full("r4", "10.0.255.3") + + +def compare_show_ipv6_ospf6(rname, expected): + """ + Calls 'show ipv6 ospf6 route' for router `rname` and compare the obtained + result with the expected output. + """ + tgen = get_topogen() + current = tgen.gears[rname].vtysh_cmd("show ipv6 ospf6 route") + + # Remove the link addresses + current = re.sub(r"fe80::[^ ]+", "fe80::xxxx:xxxx:xxxx:xxxx", current) + expected = re.sub(r"fe80::[^ ]+", "fe80::xxxx:xxxx:xxxx:xxxx", expected) + + # Remove the time + current = re.sub(r"\d+:\d{2}:\d{2}", "", current) + expected = re.sub(r"\d+:\d{2}:\d{2}", "", expected) + + return topotest.difflines( + topotest.normalize_text(current), + topotest.normalize_text(expected), + title1="Current output", + title2="Expected output", + ) + + +def test_ospf_convergence(): + "Test OSPF daemon convergence" + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip("skipped because of router(s) failure") + + for router, rnode in tgen.routers().items(): + logger.info('Waiting for router "%s" convergence', router) + + # Load expected results from the command + reffile = os.path.join(CWD, "{}/ospfroute.txt".format(router)) + expected = open(reffile).read() + + # Run test function until we get an result. Wait at most 80 seconds. + test_func = partial( + topotest.router_output_cmp, rnode, "show ip ospf route", expected + ) + result, diff = topotest.run_and_expect(test_func, "", count=160, wait=0.5) + assert result, "OSPF did not converge on {}:\n{}".format(router, diff) + + +def test_ospf_kernel_route(): + "Test OSPF kernel route installation" + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip("skipped because of router(s) failure") + + rlist = tgen.routers().values() + for router in rlist: + logger.info('Checking OSPF IPv4 kernel routes in "%s"', router.name) + + routes = topotest.ip4_route(router) + expected = { + "10.0.1.0/24": {}, + "10.0.2.0/24": {}, + "10.0.3.0/24": {}, + "10.0.10.0/24": {}, + "172.16.0.0/24": {}, + "172.16.1.0/24": {}, + } + assertmsg = 'OSPF IPv4 route mismatch in router "{}"'.format(router.name) + assert topotest.json_cmp(routes, expected) is None, assertmsg + + +def test_ospf6_convergence(): + "Test OSPF6 daemon convergence" + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip("skipped because of router(s) failure") + + ospf6route_file = "{}/ospf6route_ecmp.txt" + for rnum in range(1, 5): + router = "r{}".format(rnum) + + logger.info('Waiting for router "%s" IPv6 OSPF convergence', router) + + # Load expected results from the command + reffile = os.path.join(CWD, ospf6route_file.format(router)) + expected = open(reffile).read() + + # Run test function until we get an result. Wait at most 60 seconds. + test_func = partial(compare_show_ipv6_ospf6, router, expected) + result, diff = topotest.run_and_expect(test_func, "", count=25, wait=3) + if (not result) and (rnum == 1): + # Didn't match the new ECMP version - try the old pre-ECMP format + ospf6route_file = "{}/ospf6route.txt" + + # Load expected results from the command + reffile = os.path.join(CWD, ospf6route_file.format(router)) + expected = open(reffile).read() + + test_func = partial(compare_show_ipv6_ospf6, router, expected) + result, diff = topotest.run_and_expect(test_func, "", count=1, wait=3) + if not result: + # Didn't match the old version - switch back to new ECMP version + # and fail + ospf6route_file = "{}/ospf6route_ecmp.txt" + + # Load expected results from the command + reffile = os.path.join(CWD, ospf6route_file.format(router)) + expected = open(reffile).read() + + test_func = partial(compare_show_ipv6_ospf6, router, expected) + result, diff = topotest.run_and_expect(test_func, "", count=1, wait=3) + + assert result, "OSPF6 did not converge on {}:\n{}".format(router, diff) + + +def test_ospf6_kernel_route(): + "Test OSPF kernel route installation" + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip("skipped because of router(s) failure") + + rlist = tgen.routers().values() + for router in rlist: + logger.info('Checking OSPF IPv6 kernel routes in "%s"', router.name) + + def _routes_in_fib6(): + routes = topotest.ip6_route(router) + expected = { + "2001:db8:1::/64": {}, + "2001:db8:2::/64": {}, + "2001:db8:3::/64": {}, + "2001:db8:100::/64": {}, + "2001:db8:200::/64": {}, + "2001:db8:300::/64": {}, + } + logger.info("Routes:") + logger.info(routes) + logger.info(topotest.json_cmp(routes, expected)) + logger.info("ENd:") + return topotest.json_cmp(routes, expected) + + _, result = topotest.run_and_expect(_routes_in_fib6, None, count=20, wait=1) + + assertmsg = 'OSPF IPv6 route mismatch in router "{}"'.format(router.name) + assert result is None, assertmsg + + +def test_ospf_json(): + "Test 'show ip ospf json' output for coherency." + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip("skipped because of router(s) failure") + + for rnum in range(1, 5): + router = tgen.gears["r{}".format(rnum)] + logger.info(router.vtysh_cmd("show ip ospf database")) + logger.info('Comparing router "%s" "show ip ospf json" output', router.name) + expected = { + "routerId": "10.0.255.{}".format(rnum), + "tosRoutesOnly": True, + "rfc2328Conform": True, + "spfScheduleDelayMsecs": 0, + "holdtimeMinMsecs": 50, + "holdtimeMaxMsecs": 5000, + "lsaMinIntervalMsecs": 5000, + "lsaMinArrivalMsecs": 1000, + "writeMultiplier": 20, + "refreshTimerMsecs": 10000, + "asbrRouter": "injectingExternalRoutingInformation", + "attachedAreaCounter": 1, + "areas": {}, + } + # Area specific additional checks + if router.name == "r1" or router.name == "r2" or router.name == "r3": + expected["areas"]["0.0.0.0"] = { + "areaIfActiveCounter": 2, + "areaIfTotalCounter": 2, + "authentication": "authenticationNone", + "backbone": True, + "lsaAsbrNumber": 1, + "lsaNetworkNumber": 1, + "lsaNssaNumber": 0, + "lsaNumber": 7, + "lsaOpaqueAreaNumber": 0, + "lsaOpaqueLinkNumber": 0, + "lsaRouterNumber": 3, + "lsaSummaryNumber": 2, + "nbrFullAdjacentCounter": 2, + } + if router.name == "r3" or router.name == "r4": + expected["areas"]["0.0.0.1"] = { + "areaIfActiveCounter": 1, + "areaIfTotalCounter": 1, + "authentication": "authenticationNone", + "lsaAsbrNumber": 2, + "lsaNetworkNumber": 1, + "lsaNssaNumber": 0, + "lsaNumber": 9, + "lsaOpaqueAreaNumber": 0, + "lsaOpaqueLinkNumber": 0, + "lsaRouterNumber": 2, + "lsaSummaryNumber": 4, + "nbrFullAdjacentCounter": 1, + } + # r4 has more interfaces for area 0.0.0.1 + if router.name == "r4": + expected["areas"]["0.0.0.1"].update( + { + "areaIfActiveCounter": 2, + "areaIfTotalCounter": 2, + } + ) + + # router 3 has an additional area + if router.name == "r3": + expected["attachedAreaCounter"] = 2 + + output = router.vtysh_cmd("show ip ospf json", isjson=True) + result = topotest.json_cmp(output, expected) + assert result is None, '"{}" JSON output mismatches the expected result'.format( + router.name + ) + + +def test_ospf_link_down(): + "Test OSPF convergence after a link goes down" + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip("skipped because of router(s) failure") + + # Simulate a network down event on router3 switch3 interface. + router3 = tgen.gears["r3"] + router3.peer_link_enable("r3-eth0", False) + + # Expect convergence on all routers + for router, rnode in tgen.routers().items(): + logger.info('Waiting for router "%s" convergence after link failure', router) + # Load expected results from the command + reffile = os.path.join(CWD, "{}/ospfroute_down.txt".format(router)) + expected = open(reffile).read() + + # Run test function until we get an result. Wait at most 80 seconds. + test_func = partial( + topotest.router_output_cmp, rnode, "show ip ospf route", expected + ) + result, diff = topotest.run_and_expect(test_func, "", count=140, wait=0.5) + assert result, "OSPF did not converge on {}:\n{}".format(router, diff) + + +def test_ospf_link_down_kernel_route(): + "Test OSPF kernel route installation" + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip("skipped because of router(s) failure") + + rlist = tgen.routers().values() + for router in rlist: + logger.info( + 'Checking OSPF IPv4 kernel routes in "%s" after link down', router.name + ) + + routes = topotest.ip4_route(router) + expected = { + "10.0.1.0/24": {}, + "10.0.2.0/24": {}, + "10.0.3.0/24": {}, + "10.0.10.0/24": {}, + "172.16.0.0/24": {}, + "172.16.1.0/24": {}, + } + if router.name == "r1" or router.name == "r2": + expected.update( + { + "10.0.10.0/24": None, + "172.16.0.0/24": None, + "172.16.1.0/24": None, + } + ) + elif router.name == "r3" or router.name == "r4": + expected.update( + { + "10.0.1.0/24": None, + "10.0.2.0/24": None, + } + ) + # Route '10.0.3.0' is no longer available for r4 since it is down. + if router.name == "r4": + expected.update( + { + "10.0.3.0/24": None, + } + ) + assertmsg = 'OSPF IPv4 route mismatch in router "{}" after link down'.format( + router.name + ) + count = 0 + not_found = True + while not_found and count < 10: + not_found = topotest.json_cmp(routes, expected) + if not_found: + sleep(1) + routes = topotest.ip4_route(router) + count += 1 + else: + not_found = False + break + assert not_found is False, assertmsg + + +def test_ospf6_link_down(): + "Test OSPF6 daemon convergence after link goes down" + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip("skipped because of router(s) failure") + + for rnum in range(1, 5): + router = "r{}".format(rnum) + + logger.info( + 'Waiting for router "%s" IPv6 OSPF convergence after link down', router + ) + + # Load expected results from the command + reffile = os.path.join(CWD, "{}/ospf6route_down.txt".format(router)) + expected = open(reffile).read() + + # Run test function until we get an result. Wait at most 60 seconds. + test_func = partial(compare_show_ipv6_ospf6, router, expected) + result, diff = topotest.run_and_expect(test_func, "", count=25, wait=3) + assert result, "OSPF6 did not converge on {}:\n{}".format(router, diff) + + +def test_ospf6_link_down_kernel_route(): + "Test OSPF kernel route installation" + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip("skipped because of router(s) failure") + + rlist = tgen.routers().values() + for router in rlist: + logger.info( + 'Checking OSPF IPv6 kernel routes in "%s" after link down', router.name + ) + + routes = topotest.ip6_route(router) + expected = { + "2001:db8:1::/64": {}, + "2001:db8:2::/64": {}, + "2001:db8:3::/64": {}, + "2001:db8:100::/64": {}, + "2001:db8:200::/64": {}, + "2001:db8:300::/64": {}, + } + if router.name == "r1" or router.name == "r2": + expected.update( + { + "2001:db8:100::/64": None, + "2001:db8:200::/64": None, + "2001:db8:300::/64": None, + } + ) + elif router.name == "r3" or router.name == "r4": + expected.update( + { + "2001:db8:1::/64": None, + "2001:db8:2::/64": None, + } + ) + # Route '2001:db8:3::/64' is no longer available for r4 since it is down. + if router.name == "r4": + expected.update( + { + "2001:db8:3::/64": None, + } + ) + assertmsg = 'OSPF IPv6 route mismatch in router "{}" after link down'.format( + router.name + ) + count = 0 + not_found = True + while not_found and count < 10: + not_found = topotest.json_cmp(routes, expected) + if not_found: + sleep(1) + routes = topotest.ip6_route(router) + count += 1 + else: + not_found = False + break + + assert not_found is False, 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)) |