]>
git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/msdp_topo1/test_msdp_topo1.py
2 # SPDX-License-Identifier: ISC
6 # Part of NetDEF Topology Tests
8 # Copyright (c) 2021 by
9 # Network Device Education Foundation, Inc. ("NetDEF")
13 test_msdp_topo1.py: Test the FRR PIM MSDP peer.
19 from functools
import partial
22 # Save the Current Working Directory to find configuration files.
23 CWD
= os
.path
.dirname(os
.path
.realpath(__file__
))
24 sys
.path
.append(os
.path
.join(CWD
, "../"))
26 # pylint: disable=C0413
27 # Import topogen and topotest helpers
28 from lib
import topotest
30 # Required to instantiate the topology builder class.
31 from lib
.topogen
import Topogen
, TopoRouter
, get_topogen
32 from lib
.topolog
import logger
34 from lib
.pim
import McastTesterHelper
36 pytestmark
= [pytest
.mark
.bgpd
, pytest
.mark
.pimd
]
38 app_helper
= McastTesterHelper()
45 for routern
in range(1, 5):
46 tgen
.add_router("r{}".format(routern
))
48 switch
= tgen
.add_switch("s1")
49 switch
.add_link(tgen
.gears
["r1"])
50 switch
.add_link(tgen
.gears
["r2"])
52 switch
= tgen
.add_switch("s2")
53 switch
.add_link(tgen
.gears
["r1"])
54 switch
.add_link(tgen
.gears
["r3"])
56 switch
= tgen
.add_switch("s3")
57 switch
.add_link(tgen
.gears
["r2"])
58 switch
.add_link(tgen
.gears
["r4"])
60 switch
= tgen
.add_switch("s4")
61 # switch.add_link(tgen.gears["r3"])
62 switch
.add_link(tgen
.gears
["r4"])
64 switch
= tgen
.add_switch("s5")
65 switch
.add_link(tgen
.gears
["r4"])
67 # Create a host connected and direct at r4:
68 tgen
.add_host("h1", "192.168.4.100/24", "via 192.168.4.1")
69 switch
.add_link(tgen
.gears
["h1"])
71 # Create a host connected and direct at r1:
72 switch
= tgen
.add_switch("s6")
73 tgen
.add_host("h2", "192.168.10.100/24", "via 192.168.10.1")
74 switch
.add_link(tgen
.gears
["r1"])
75 switch
.add_link(tgen
.gears
["h2"])
78 def setup_module(mod
):
79 "Sets up the pytest environment"
80 tgen
= Topogen(build_topo
, mod
.__name
__)
83 router_list
= tgen
.routers()
84 for rname
, router
in router_list
.items():
86 daemon_file
= "{}/{}/zebra.conf".format(CWD
, rname
)
87 if os
.path
.isfile(daemon_file
):
88 router
.load_config(TopoRouter
.RD_ZEBRA
, daemon_file
)
90 daemon_file
= "{}/{}/bgpd.conf".format(CWD
, rname
)
91 if os
.path
.isfile(daemon_file
):
92 router
.load_config(TopoRouter
.RD_BGP
, daemon_file
)
94 daemon_file
= "{}/{}/pimd.conf".format(CWD
, rname
)
95 if os
.path
.isfile(daemon_file
):
96 router
.load_config(TopoRouter
.RD_PIM
, daemon_file
)
98 # Initialize all routers.
101 app_helper
.init(tgen
)
104 def teardown_module(mod
):
105 "Teardown the pytest environment"
111 def test_bgp_convergence():
112 "Wait for BGP protocol convergence"
114 if tgen
.routers_have_failure():
115 pytest
.skip(tgen
.errors
)
117 logger
.info("waiting for protocols to converge")
119 def expect_loopback_route(router
, iptype
, route
, proto
):
120 "Wait until route is present on RIB for protocol."
121 logger
.info("waiting route {} in {}".format(route
, router
))
123 topotest
.router_json_cmp
,
125 "show {} route json".format(iptype
),
126 {route
: [{"protocol": proto
}]},
128 _
, result
= topotest
.run_and_expect(test_func
, None, count
=130, wait
=1)
129 assertmsg
= '"{}" convergence failure'.format(router
)
130 assert result
is None, assertmsg
133 expect_loopback_route("r1", "ip", "10.254.254.2/32", "bgp")
134 expect_loopback_route("r1", "ip", "10.254.254.3/32", "bgp")
135 expect_loopback_route("r1", "ip", "10.254.254.4/32", "bgp")
138 expect_loopback_route("r2", "ip", "10.254.254.1/32", "bgp")
139 expect_loopback_route("r2", "ip", "10.254.254.3/32", "bgp")
140 expect_loopback_route("r2", "ip", "10.254.254.4/32", "bgp")
143 expect_loopback_route("r3", "ip", "10.254.254.1/32", "bgp")
144 expect_loopback_route("r3", "ip", "10.254.254.2/32", "bgp")
145 expect_loopback_route("r3", "ip", "10.254.254.4/32", "bgp")
148 expect_loopback_route("r4", "ip", "10.254.254.1/32", "bgp")
149 expect_loopback_route("r4", "ip", "10.254.254.2/32", "bgp")
150 expect_loopback_route("r4", "ip", "10.254.254.3/32", "bgp")
153 def _test_mroute_install():
154 "Test that multicast routes propagated and installed"
156 if tgen
.routers_have_failure():
157 pytest
.skip(tgen
.errors
)
168 "r1-eth0": {"source": "192.168.10.100", "group": "229.1.2.3"},
174 # Create a deep copy of `expect_1`.
175 expect_2
= json
.loads(json
.dumps(expect_1
))
176 # The route will be either via R2 or R3.
177 expect_2
["229.1.2.3"]["192.168.10.100"]["oil"]["r1-eth0"] = None
178 expect_2
["229.1.2.3"]["192.168.10.100"]["oil"]["r1-eth1"] = {
179 "source": "192.168.10.100",
180 "group": "229.1.2.3",
183 def test_r1_mroute():
184 "Test r1 multicast routing table function"
185 out
= tgen
.gears
["r1"].vtysh_cmd("show ip mroute json", isjson
=True)
186 if topotest
.json_cmp(out
, expect_1
) is None:
188 return topotest
.json_cmp(out
, expect_2
)
190 logger
.info("Waiting for R1 multicast routes")
191 _
, val
= topotest
.run_and_expect(test_r1_mroute
, None, count
=55, wait
=2)
192 assert val
is None, "multicast route convergence failure"
195 # Test routers 2 and 3.
197 # NOTE: only one of the paths will get the multicast route.
206 "source": "192.168.10.100",
207 "group": "229.1.2.3",
220 "source": "192.168.10.100",
221 "group": "229.1.2.3",
228 def test_r2_r3_mroute():
229 "Test r2/r3 multicast routing table function"
230 r2_out
= tgen
.gears
["r2"].vtysh_cmd("show ip mroute json", isjson
=True)
231 r3_out
= tgen
.gears
["r3"].vtysh_cmd("show ip mroute json", isjson
=True)
233 if topotest
.json_cmp(r2_out
, expect_r2
) is not None:
234 return topotest
.json_cmp(r3_out
, expect_r3
)
236 return topotest
.json_cmp(r2_out
, expect_r2
)
238 logger
.info("Waiting for R2 and R3 multicast routes")
239 _
, val
= topotest
.run_and_expect(test_r2_r3_mroute
, None, count
=55, wait
=2)
240 assert val
is None, "multicast route convergence failure"
253 "group": "229.1.2.3",
254 "inboundInterface": "lo",
255 "outboundInterface": "pimreg",
259 "group": "229.1.2.3",
260 "inboundInterface": "lo",
261 "outboundInterface": "r4-eth2",
270 "source": "192.168.10.100",
271 "group": "229.1.2.3",
272 "inboundInterface": "r4-eth0",
273 "outboundInterface": "r4-eth2",
281 topotest
.router_json_cmp
,
283 "show ip mroute json",
286 logger
.info("Waiting for R4 multicast routes")
287 _
, val
= topotest
.run_and_expect(test_func
, None, count
=55, wait
=2)
288 assert val
is None, "multicast route convergence failure"
291 def test_mroute_install():
294 if tgen
.routers_have_failure():
295 pytest
.skip(tgen
.errors
)
297 logger
.info("Starting helper1")
298 mcastaddr
= "229.1.2.3"
299 app_helper
.run("h1", [mcastaddr
, "h1-eth0"])
301 logger
.info("Starting helper2")
302 app_helper
.run("h2", ["--send=0.7", mcastaddr
, "h2-eth0"])
304 _test_mroute_install()
309 Test MSDP convergence.
311 MSDP non meshed groups must propagate the whole SA database (not just
312 their own) to all peers because not all peers talk with each other.
314 This setup leads to a potential loop that can be prevented by checking
315 the route's first AS in AS path: it must match the remote eBGP AS number.
318 if tgen
.routers_have_failure():
319 pytest
.skip(tgen
.errors
)
323 "peer": "192.168.0.2",
324 "local": "192.168.0.1",
325 "state": "established",
328 "peer": "192.168.1.2",
329 "local": "192.168.1.1",
330 "state": "established",
336 "source": "192.168.10.100",
337 "group": "229.1.2.3",
346 "peer": "192.168.0.1",
347 "local": "192.168.0.2",
348 "state": "established",
351 "peer": "192.168.2.2",
352 "local": "192.168.2.1",
353 "state": "established",
356 # Only R2 or R3 will get this SA.
360 "source": "192.168.10.100",
361 "group": "229.1.2.3",
370 "peer": "192.168.1.1",
371 "local": "192.168.1.2",
372 "state": "established",
375 # "peer": "192.168.3.2",
376 # "local": "192.168.3.1",
377 # "state": "established"
382 "peer": "192.168.2.1",
383 "local": "192.168.2.2",
384 "state": "established",
387 # "peer": "192.168.3.1",
388 # "local": "192.168.3.2",
389 # "state": "established"
395 "source": "192.168.10.100",
396 "group": "229.1.2.3",
405 ("r1", r1_expect
, r1_sa_expect
),
406 ("r2", r2_expect
, r2_r3_sa_expect
),
407 ("r3", r3_expect
, r2_r3_sa_expect
),
408 ("r4", r4_expect
, r4_sa_expect
),
411 topotest
.router_json_cmp
,
412 tgen
.gears
[router
[0]],
413 "show ip msdp peer json",
416 logger
.info("Waiting for {} msdp peer data".format(router
[0]))
417 _
, val
= topotest
.run_and_expect(test_func
, None, count
=30, wait
=1)
418 assert val
is None, "multicast route convergence failure"
421 topotest
.router_json_cmp
,
422 tgen
.gears
[router
[0]],
423 "show ip msdp sa json",
426 logger
.info("Waiting for {} msdp SA data".format(router
[0]))
427 _
, val
= topotest
.run_and_expect(test_func
, None, count
=30, wait
=1)
428 assert val
is None, "multicast route convergence failure"
431 def test_memory_leak():
432 "Run the memory leak test and report results."
434 if not tgen
.is_memleak_enabled():
435 pytest
.skip("Memory leak test/report is disabled")
437 tgen
.report_memory_leaks()
440 if __name__
== "__main__":
441 args
= ["-s"] + sys
.argv
[1:]
442 sys
.exit(pytest
.main(args
))