From 2e4da8e329fd1e0038cb6840885d352e03e84aa0 Mon Sep 17 00:00:00 2001 From: Maria Matejka Date: Wed, 24 Jul 2024 21:04:28 +0200 Subject: [PATCH] Flock test: ospf-base stub --- flock/ospf-base/dump-0001-startup.yaml | 739 +++++++++++++++++++++++++ flock/ospf-base/template.conf | 27 + flock/ospf-base/test.py | 36 ++ python/BIRD/ShowRoute.py | 9 + python/BIRD/Test.py | 24 +- python/flock | 2 +- 6 files changed, 827 insertions(+), 10 deletions(-) create mode 100644 flock/ospf-base/dump-0001-startup.yaml create mode 100644 flock/ospf-base/template.conf create mode 100644 flock/ospf-base/test.py diff --git a/flock/ospf-base/dump-0001-startup.yaml b/flock/ospf-base/dump-0001-startup.yaml new file mode 100644 index 00000000..ac0df35a --- /dev/null +++ b/flock/ospf-base/dump-0001-startup.yaml @@ -0,0 +1,739 @@ +tables: + master4: + networks: + 192.0.2.0/28: + routes: + - args: '* I (150/10) [192.0.2.2]' + dest: unicast + nexthop: + - iface: ve31 + ospf_metric1: '10' + ospf_router_id: 192.0.2.2 + preference: '150' + proto: ospf4 + source: OSPF + 192.0.2.16/28: + routes: + - args: '* I (150/10) [192.0.2.2]' + dest: unicast + nexthop: + - iface: ve12 + ospf_metric1: '10' + ospf_router_id: 192.0.2.2 + preference: '150' + proto: ospf4 + source: OSPF + 192.0.2.32/28: + routes: + - args: '* I (150/20) [192.0.2.18]' + dest: unicast + nexthop: + - iface: ve31 weight 1 + nexthop: 192.0.2.1 + - iface: ve12 weight 1 + nexthop: 192.0.2.18 + ospf_metric1: '20' + ospf_router_id: 192.0.2.18 + preference: '150' + proto: ospf4 + source: OSPF + 192.0.2.96/28: + routes: + - args: '* I (150/20) [192.0.2.1]' + dest: unicast + nexthop: + - iface: ve31 + nexthop: 192.0.2.1 + ospf_metric1: '20' + ospf_router_id: 192.0.2.1 + preference: '150' + proto: ospf4 + source: OSPF + master5: + networks: {} + master6: + networks: + 2001:db8:0:1::/64: + routes: + - args: '* I (150/10) [192.0.2.2]' + dest: unicast + nexthop: + - iface: ve12 + ospf_metric1: '10' + ospf_router_id: 192.0.2.2 + preference: '150' + proto: ospf6 + source: OSPF + 2001:db8:0:2::/64: + routes: + - args: '* I (150/20) [192.0.2.18]' + dest: unicast + nexthop: + - iface: ve12 weight 1 + nexthop: fe80::5c38:8eff:fe25:1d68 + - iface: ve31 weight 1 + nexthop: fe80::ac55:22ff:fe32:3610 + ospf_metric1: '20' + ospf_router_id: 192.0.2.18 + preference: '150' + proto: ospf6 + source: OSPF + 2001:db8:0:6::/64: + routes: + - args: '* I (150/20) [192.0.2.1]' + dest: unicast + nexthop: + - iface: ve31 + nexthop: fe80::ac55:22ff:fe32:3610 + ospf_metric1: '20' + ospf_router_id: 192.0.2.1 + preference: '150' + proto: ospf6 + source: OSPF + 2001:db8::/64: + routes: + - args: '* I (150/10) [192.0.2.2]' + dest: unicast + nexthop: + - iface: ve31 + ospf_metric1: '10' + ospf_router_id: 192.0.2.2 + preference: '150' + proto: ospf6 + source: OSPF +--- +tables: + master4: + networks: + 192.0.2.0/28: + routes: + - args: '* I (150/20) [192.0.2.2]' + dest: unicast + nexthop: + - iface: ve12 weight 1 + nexthop: 192.0.2.17 + - iface: ve23 weight 1 + nexthop: 192.0.2.34 + ospf_metric1: '20' + ospf_router_id: 192.0.2.2 + preference: '150' + proto: ospf4 + source: OSPF + 192.0.2.16/28: + routes: + - args: '* I (150/10) [192.0.2.18]' + dest: unicast + nexthop: + - iface: ve12 + ospf_metric1: '10' + ospf_router_id: 192.0.2.18 + preference: '150' + proto: ospf4 + source: OSPF + 192.0.2.32/28: + routes: + - args: '* I (150/10) [192.0.2.18]' + dest: unicast + nexthop: + - iface: ve23 + ospf_metric1: '10' + ospf_router_id: 192.0.2.18 + preference: '150' + proto: ospf4 + source: OSPF + 192.0.2.96/28: + routes: + - args: '* I (150/20) [192.0.2.1]' + dest: unicast + nexthop: + - iface: ve23 + nexthop: 192.0.2.34 + ospf_metric1: '20' + ospf_router_id: 192.0.2.1 + preference: '150' + proto: ospf4 + source: OSPF + master5: + networks: {} + master6: + networks: + 2001:db8:0:1::/64: + routes: + - args: '* I (150/10) [192.0.2.18]' + dest: unicast + nexthop: + - iface: ve12 + ospf_metric1: '10' + ospf_router_id: 192.0.2.18 + preference: '150' + proto: ospf6 + source: OSPF + 2001:db8:0:2::/64: + routes: + - args: '* I (150/10) [192.0.2.18]' + dest: unicast + nexthop: + - iface: ve23 + ospf_metric1: '10' + ospf_router_id: 192.0.2.18 + preference: '150' + proto: ospf6 + source: OSPF + 2001:db8:0:6::/64: + routes: + - args: '* I (150/20) [192.0.2.1]' + dest: unicast + nexthop: + - iface: ve23 + nexthop: fe80::7cda:1aff:feae:9831 + ospf_metric1: '20' + ospf_router_id: 192.0.2.1 + preference: '150' + proto: ospf6 + source: OSPF + 2001:db8::/64: + routes: + - args: '* I (150/20) [192.0.2.2]' + dest: unicast + nexthop: + - iface: ve12 weight 1 + nexthop: fe80::4cfd:f0ff:fe23:167 + - iface: ve23 weight 1 + nexthop: fe80::7cda:1aff:feae:9831 + ospf_metric1: '20' + ospf_router_id: 192.0.2.2 + preference: '150' + proto: ospf6 + source: OSPF +--- +tables: + master4: + networks: + 192.0.2.0/28: + routes: + - args: '* I (150/10) [192.0.2.1]' + dest: unicast + nexthop: + - iface: ve31 + ospf_metric1: '10' + ospf_router_id: 192.0.2.1 + preference: '150' + proto: ospf4 + source: OSPF + 192.0.2.16/28: + routes: + - args: '* I (150/20) [192.0.2.18]' + dest: unicast + nexthop: + - iface: ve31 weight 1 + nexthop: 192.0.2.2 + - iface: ve23 weight 1 + nexthop: 192.0.2.33 + ospf_metric1: '20' + ospf_router_id: 192.0.2.18 + preference: '150' + proto: ospf4 + source: OSPF + 192.0.2.32/28: + routes: + - args: '* I (150/10) [192.0.2.1]' + dest: unicast + nexthop: + - iface: ve23 + ospf_metric1: '10' + ospf_router_id: 192.0.2.1 + preference: '150' + proto: ospf4 + source: OSPF + 192.0.2.96/28: + routes: + - args: '* I (150/10) [192.0.2.1]' + dest: unicast + nexthop: + - iface: multi + ospf_metric1: '10' + ospf_router_id: 192.0.2.1 + preference: '150' + proto: ospf4 + source: OSPF + master5: + networks: {} + master6: + networks: + 2001:db8:0:1::/64: + routes: + - args: '* I (150/20) [192.0.2.18]' + dest: unicast + nexthop: + - iface: ve31 weight 1 + nexthop: fe80::5c82:ccff:fe47:46df + - iface: ve23 weight 1 + nexthop: fe80::8c41:8bff:fe8f:9446 + ospf_metric1: '20' + ospf_router_id: 192.0.2.18 + preference: '150' + proto: ospf6 + source: OSPF + 2001:db8:0:2::/64: + routes: + - args: '* I (150/10) [192.0.2.1]' + dest: unicast + nexthop: + - iface: ve23 + ospf_metric1: '10' + ospf_router_id: 192.0.2.1 + preference: '150' + proto: ospf6 + source: OSPF + 2001:db8:0:6::/64: + routes: + - args: '* I (150/10) [192.0.2.1]' + dest: unicast + nexthop: + - iface: multi + ospf_metric1: '10' + ospf_router_id: 192.0.2.1 + preference: '150' + proto: ospf6 + source: OSPF + 2001:db8::/64: + routes: + - args: '* I (150/10) [192.0.2.1]' + dest: unicast + nexthop: + - iface: ve31 + ospf_metric1: '10' + ospf_router_id: 192.0.2.1 + preference: '150' + proto: ospf6 + source: OSPF +--- +tables: + master4: + networks: + 192.0.2.96/28: + routes: + - args: '* I (150/10) [192.0.2.98]' + dest: unicast + nexthop: + - iface: multi + ospf_metric1: '10' + ospf_router_id: 192.0.2.98 + preference: '150' + proto: ospf4 + source: OSPF + master5: + networks: {} + master6: + networks: + 2001:db8:0:6::/64: + routes: + - args: '* I (150/10) [192.0.2.98]' + dest: unicast + nexthop: + - iface: multi + ospf_metric1: '10' + ospf_router_id: 192.0.2.98 + preference: '150' + proto: ospf6 + source: OSPF +--- +tables: + master4: + networks: + 192.0.2.48/28: + routes: + - args: '* I (150/10) [192.0.2.49]' + dest: unicast + nexthop: + - iface: ve57 + ospf_metric1: '10' + ospf_router_id: 192.0.2.49 + preference: '150' + proto: ospf4 + source: OSPF + 192.0.2.64/28: + routes: + - args: '* I (150/20) [192.0.2.50]' + dest: unicast + nexthop: + - iface: ve57 + nexthop: 192.0.2.50 + ospf_metric1: '20' + ospf_router_id: 192.0.2.50 + preference: '150' + proto: ospf4 + source: OSPF + 192.0.2.80/28: + routes: + - args: '* I (150/30) [192.0.2.66]' + dest: unicast + nexthop: + - iface: ve57 + nexthop: 192.0.2.50 + ospf_metric1: '30' + ospf_router_id: 192.0.2.66 + preference: '150' + proto: ospf4 + source: OSPF + 192.0.2.96/28: + routes: + - args: '* I (150/10) [192.0.2.49]' + dest: unicast + nexthop: + - iface: multi + ospf_metric1: '10' + ospf_router_id: 192.0.2.49 + preference: '150' + proto: ospf4 + source: OSPF + master5: + networks: {} + master6: + networks: + 2001:db8:0:3::/64: + routes: + - args: '* I (150/10) [192.0.2.49]' + dest: unicast + nexthop: + - iface: ve57 + ospf_metric1: '10' + ospf_router_id: 192.0.2.49 + preference: '150' + proto: ospf6 + source: OSPF + 2001:db8:0:4::/64: + routes: + - args: '* I (150/20) [192.0.2.50]' + dest: unicast + nexthop: + - iface: ve57 + nexthop: fe80::9c97:afff:fe62:f695 + ospf_metric1: '20' + ospf_router_id: 192.0.2.50 + preference: '150' + proto: ospf6 + source: OSPF + 2001:db8:0:5::/64: + routes: + - args: '* I (150/30) [192.0.2.66]' + dest: unicast + nexthop: + - iface: ve57 + nexthop: fe80::9c97:afff:fe62:f695 + ospf_metric1: '30' + ospf_router_id: 192.0.2.66 + preference: '150' + proto: ospf6 + source: OSPF + 2001:db8:0:6::/64: + routes: + - args: '* I (150/10) [192.0.2.49]' + dest: unicast + nexthop: + - iface: multi + ospf_metric1: '10' + ospf_router_id: 192.0.2.49 + preference: '150' + proto: ospf6 + source: OSPF +--- +tables: + master4: + networks: + 192.0.2.48/28: + routes: + - args: '* I (150/30) [192.0.2.50]' + dest: unicast + nexthop: + - iface: ve86 + nexthop: 192.0.2.81 + ospf_metric1: '30' + ospf_router_id: 192.0.2.50 + preference: '150' + proto: ospf4 + source: OSPF + 192.0.2.64/28: + routes: + - args: '* I (150/20) [192.0.2.66]' + dest: unicast + nexthop: + - iface: ve86 + nexthop: 192.0.2.81 + ospf_metric1: '20' + ospf_router_id: 192.0.2.66 + preference: '150' + proto: ospf4 + source: OSPF + 192.0.2.80/28: + routes: + - args: '* I (150/10) [192.0.2.82]' + dest: unicast + nexthop: + - iface: ve86 + ospf_metric1: '10' + ospf_router_id: 192.0.2.82 + preference: '150' + proto: ospf4 + source: OSPF + 192.0.2.96/28: + routes: + - args: '* I (150/10) [192.0.2.82]' + dest: unicast + nexthop: + - iface: multi + ospf_metric1: '10' + ospf_router_id: 192.0.2.82 + preference: '150' + proto: ospf4 + source: OSPF + master5: + networks: {} + master6: + networks: + 2001:db8:0:3::/64: + routes: + - args: '* I (150/30) [192.0.2.50]' + dest: unicast + nexthop: + - iface: ve86 + nexthop: fe80::6cc9:f2ff:feb9:754f + ospf_metric1: '30' + ospf_router_id: 192.0.2.50 + preference: '150' + proto: ospf6 + source: OSPF + 2001:db8:0:4::/64: + routes: + - args: '* I (150/20) [192.0.2.66]' + dest: unicast + nexthop: + - iface: ve86 + nexthop: fe80::6cc9:f2ff:feb9:754f + ospf_metric1: '20' + ospf_router_id: 192.0.2.66 + preference: '150' + proto: ospf6 + source: OSPF + 2001:db8:0:5::/64: + routes: + - args: '* I (150/10) [192.0.2.82]' + dest: unicast + nexthop: + - iface: ve86 + ospf_metric1: '10' + ospf_router_id: 192.0.2.82 + preference: '150' + proto: ospf6 + source: OSPF + 2001:db8:0:6::/64: + routes: + - args: '* I (150/10) [192.0.2.82]' + dest: unicast + nexthop: + - iface: multi + ospf_metric1: '10' + ospf_router_id: 192.0.2.82 + preference: '150' + proto: ospf6 + source: OSPF +--- +tables: + master4: + networks: + 192.0.2.48/28: + routes: + - args: '* I (150/10) [192.0.2.50]' + dest: unicast + nexthop: + - iface: ve57 + ospf_metric1: '10' + ospf_router_id: 192.0.2.50 + preference: '150' + proto: ospf4 + source: OSPF + 192.0.2.64/28: + routes: + - args: '* I (150/10) [192.0.2.50]' + dest: unicast + nexthop: + - iface: ve78 + ospf_metric1: '10' + ospf_router_id: 192.0.2.50 + preference: '150' + proto: ospf4 + source: OSPF + 192.0.2.80/28: + routes: + - args: '* I (150/20) [192.0.2.66]' + dest: unicast + nexthop: + - iface: ve78 + nexthop: 192.0.2.66 + ospf_metric1: '20' + ospf_router_id: 192.0.2.66 + preference: '150' + proto: ospf4 + source: OSPF + 192.0.2.96/28: + routes: + - args: '* I (150/20) [192.0.2.49]' + dest: unicast + nexthop: + - iface: ve57 + nexthop: 192.0.2.49 + ospf_metric1: '20' + ospf_router_id: 192.0.2.49 + preference: '150' + proto: ospf4 + source: OSPF + master5: + networks: {} + master6: + networks: + 2001:db8:0:3::/64: + routes: + - args: '* I (150/10) [192.0.2.50]' + dest: unicast + nexthop: + - iface: ve57 + ospf_metric1: '10' + ospf_router_id: 192.0.2.50 + preference: '150' + proto: ospf6 + source: OSPF + 2001:db8:0:4::/64: + routes: + - args: '* I (150/10) [192.0.2.50]' + dest: unicast + nexthop: + - iface: ve78 + ospf_metric1: '10' + ospf_router_id: 192.0.2.50 + preference: '150' + proto: ospf6 + source: OSPF + 2001:db8:0:5::/64: + routes: + - args: '* I (150/20) [192.0.2.66]' + dest: unicast + nexthop: + - iface: ve78 + nexthop: fe80::8c67:1aff:fe6f:1193 + ospf_metric1: '20' + ospf_router_id: 192.0.2.66 + preference: '150' + proto: ospf6 + source: OSPF + 2001:db8:0:6::/64: + routes: + - args: '* I (150/20) [192.0.2.49]' + dest: unicast + nexthop: + - iface: ve57 + nexthop: fe80::2c33:44ff:fe0f:454b + ospf_metric1: '20' + ospf_router_id: 192.0.2.49 + preference: '150' + proto: ospf6 + source: OSPF +--- +tables: + master4: + networks: + 192.0.2.48/28: + routes: + - args: '* I (150/20) [192.0.2.50]' + dest: unicast + nexthop: + - iface: ve78 + nexthop: 192.0.2.65 + ospf_metric1: '20' + ospf_router_id: 192.0.2.50 + preference: '150' + proto: ospf4 + source: OSPF + 192.0.2.64/28: + routes: + - args: '* I (150/10) [192.0.2.66]' + dest: unicast + nexthop: + - iface: ve78 + ospf_metric1: '10' + ospf_router_id: 192.0.2.66 + preference: '150' + proto: ospf4 + source: OSPF + 192.0.2.80/28: + routes: + - args: '* I (150/10) [192.0.2.66]' + dest: unicast + nexthop: + - iface: ve86 + ospf_metric1: '10' + ospf_router_id: 192.0.2.66 + preference: '150' + proto: ospf4 + source: OSPF + 192.0.2.96/28: + routes: + - args: '* I (150/20) [192.0.2.82]' + dest: unicast + nexthop: + - iface: ve86 + nexthop: 192.0.2.82 + ospf_metric1: '20' + ospf_router_id: 192.0.2.82 + preference: '150' + proto: ospf4 + source: OSPF + master5: + networks: {} + master6: + networks: + 2001:db8:0:3::/64: + routes: + - args: '* I (150/20) [192.0.2.50]' + dest: unicast + nexthop: + - iface: ve78 + nexthop: fe80::ac21:71ff:fea9:abe + ospf_metric1: '20' + ospf_router_id: 192.0.2.50 + preference: '150' + proto: ospf6 + source: OSPF + 2001:db8:0:4::/64: + routes: + - args: '* I (150/10) [192.0.2.66]' + dest: unicast + nexthop: + - iface: ve78 + ospf_metric1: '10' + ospf_router_id: 192.0.2.66 + preference: '150' + proto: ospf6 + source: OSPF + 2001:db8:0:5::/64: + routes: + - args: '* I (150/10) [192.0.2.66]' + dest: unicast + nexthop: + - iface: ve86 + ospf_metric1: '10' + ospf_router_id: 192.0.2.66 + preference: '150' + proto: ospf6 + source: OSPF + 2001:db8:0:6::/64: + routes: + - args: '* I (150/20) [192.0.2.82]' + dest: unicast + nexthop: + - iface: ve86 + nexthop: fe80::5cf4:d5ff:fe79:c89 + ospf_metric1: '20' + ospf_router_id: 192.0.2.82 + preference: '150' + proto: ospf6 + source: OSPF diff --git a/flock/ospf-base/template.conf b/flock/ospf-base/template.conf new file mode 100644 index 00000000..32a9b67d --- /dev/null +++ b/flock/ospf-base/template.conf @@ -0,0 +1,27 @@ +log "{{ m.logs[0].name }}" all; + +ipv4 table master4; +ipv4 table master5; +ipv6 table master6; + +protocol device {} + +{% for v in (4,6) %} +protocol kernel kernel{{ v }} { + ipv{{v}} { table master{{v}}; export all; }; +} + +protocol ospf v{{(v//2)}} ospf{{v}} { + ipv{{v}} { table master{{v}}; import all; export all; }; + area 0 { + interface "ve*" { + hello 2; + type ptp; + }; + interface "multi" { + hello 2; + type bcast; + }; + }; +} +{% endfor %} diff --git a/flock/ospf-base/test.py b/flock/ospf-base/test.py new file mode 100644 index 00000000..fd13999c --- /dev/null +++ b/flock/ospf-base/test.py @@ -0,0 +1,36 @@ +#!/usr/bin/python3 + +import asyncio +from python.BIRD.Test import Test, BIRDInstance +from python.BIRD.LogChecker import LogExpectedStub + +class ThisTest(Test): + async def prepare(self): + # Set epoch + + # Prepare machines and links + await self.machines( + *[ f"m{n}" for n in range(1,9) ], + t=BIRDInstance, + ) + + for m in self.machine_index.values(): + m.conf = "template.conf" + m.default_log_checker.expected += [ + LogExpectedStub(f"{m.logprefix} Chosen router ID .*") + ] + + await asyncio.gather(*[ + self.link("ve31", "m3", "m1"), + self.link("ve12", "m1", "m2"), + self.link("ve23", "m2", "m3"), + self.link("ve57", "m5", "m7"), + self.link("ve78", "m7", "m8"), + self.link("ve86", "m8", "m6"), + self.link("multi", "m3", "m4", "m5", "m6"), + ]) + + async def test(self): + # Startup check + await self.route_dump(30, "startup") + diff --git a/python/BIRD/ShowRoute.py b/python/BIRD/ShowRoute.py index 4e599685..e330779f 100644 --- a/python/BIRD/ShowRoute.py +++ b/python/BIRD/ShowRoute.py @@ -120,6 +120,15 @@ class NextHopParser(CLIParser): def exit(self): self.parent.result["nexthop"].append(self.result) +@subparser(RouteParser) +class DevNextHopParser(CLIParser): + entryRegex = re.compile("\\s+dev ([^:]*)") + def enter(self, groups): + self.iface ,= groups + + def exit(self): + self.parent.result["nexthop"].append({ "iface": self.iface }) + @subparser(RouteParser) class AttributeParser(CLIParser): entryRegex = re.compile("\\s+([a-zA-Z_.0-9]+): (.*)$") diff --git a/python/BIRD/Test.py b/python/BIRD/Test.py index 2fe82ffb..ce6470ef 100644 --- a/python/BIRD/Test.py +++ b/python/BIRD/Test.py @@ -157,11 +157,18 @@ class BIRDInstance(CLI): self.default_log_checker.expected += exp - async with asyncio.timeout(5): - await asyncio.gather( - coro, - *[ e.done for e in exp ] - ) + main_task = asyncio.create_task(coro) + + try: + async with asyncio.timeout(5): + await asyncio.gather( + main_task, + *[ e.done for e in exp ] + ) + except TimeoutError as e: + for e in exp: + if not e.done.done(): + print(f"Not done: {e}: {e.pattern}") for e in exp: self.default_log_checker.expected.remove(e) @@ -234,6 +241,7 @@ class Test: self.name = name self.hypervisor = Hypervisor(name) self.machine_index = {} + self.link_index = {} self.mode = mode self._started = None self._starting = False @@ -299,7 +307,7 @@ class Test: raise Exception("Link with no machines? HOW?!") case 1: raise NotImplementedError("dummy link") - case 2: + case _: linfo = await self.hcom("link", name, { "machines": { m: { "name": name } for m in machines }, "ipv6": str(next(self.ipv6_pxgen)), @@ -309,11 +317,9 @@ class Test: for i in ("ipv4", "ipv6"): linfo[m][i] = ipaddress.ip_interface(linfo[m][i]) + self.link_index[name] = linfo return linfo - case _: - raise NotImplementedError("virtual bridge") - async def start(self): return await asyncio.gather(*[ v.start(test=self) for v in self.machine_index.values() ]) diff --git a/python/flock b/python/flock index c531877a..8a733f18 160000 --- a/python/flock +++ b/python/flock @@ -1 +1 @@ -Subproject commit c531877af0fb833747696ecce3dc9d5111930644 +Subproject commit 8a733f18b122470e092915013e2b2cec1cb2baec