]>
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():
85 daemon_file
= "{}/{}/zebra.conf".format(CWD
, rname
)
86 if os
.path
.isfile(daemon_file
):
87 router
.load_config(TopoRouter
.RD_ZEBRA
, daemon_file
)
89 daemon_file
= "{}/{}/bgpd.conf".format(CWD
, rname
)
90 if os
.path
.isfile(daemon_file
):
91 router
.load_config(TopoRouter
.RD_BGP
, daemon_file
)
93 daemon_file
= "{}/{}/pimd.conf".format(CWD
, rname
)
94 if os
.path
.isfile(daemon_file
):
95 router
.load_config(TopoRouter
.RD_PIM
, daemon_file
)
97 # Initialize all routers.
100 app_helper
.init(tgen
)
103 def teardown_module(mod
):
104 "Teardown the pytest environment"
110 def test_bgp_convergence():
111 "Wait for BGP protocol convergence"
113 if tgen
.routers_have_failure():
114 pytest
.skip(tgen
.errors
)
116 logger
.info("waiting for protocols to converge")
118 def expect_loopback_route(router
, iptype
, route
, proto
):
119 "Wait until route is present on RIB for protocol."
120 logger
.info("waiting route {} in {}".format(route
, router
))
122 topotest
.router_json_cmp
,
124 "show {} route json".format(iptype
),
125 {route
: [{"protocol": proto
}]},
127 _
, result
= topotest
.run_and_expect(test_func
, None, count
=130, wait
=1)
128 assertmsg
= '"{}" convergence failure'.format(router
)
129 assert result
is None, assertmsg
132 expect_loopback_route("r1", "ip", "10.254.254.2/32", "bgp")
133 expect_loopback_route("r1", "ip", "10.254.254.3/32", "bgp")
134 expect_loopback_route("r1", "ip", "10.254.254.4/32", "bgp")
137 expect_loopback_route("r2", "ip", "10.254.254.1/32", "bgp")
138 expect_loopback_route("r2", "ip", "10.254.254.3/32", "bgp")
139 expect_loopback_route("r2", "ip", "10.254.254.4/32", "bgp")
142 expect_loopback_route("r3", "ip", "10.254.254.1/32", "bgp")
143 expect_loopback_route("r3", "ip", "10.254.254.2/32", "bgp")
144 expect_loopback_route("r3", "ip", "10.254.254.4/32", "bgp")
147 expect_loopback_route("r4", "ip", "10.254.254.1/32", "bgp")
148 expect_loopback_route("r4", "ip", "10.254.254.2/32", "bgp")
149 expect_loopback_route("r4", "ip", "10.254.254.3/32", "bgp")
152 def _test_mroute_install():
153 "Test that multicast routes propagated and installed"
155 if tgen
.routers_have_failure():
156 pytest
.skip(tgen
.errors
)
167 "r1-eth0": {"source": "192.168.10.100", "group": "229.1.2.3"},
173 # Create a deep copy of `expect_1`.
174 expect_2
= json
.loads(json
.dumps(expect_1
))
175 # The route will be either via R2 or R3.
176 expect_2
["229.1.2.3"]["192.168.10.100"]["oil"]["r1-eth0"] = None
177 expect_2
["229.1.2.3"]["192.168.10.100"]["oil"]["r1-eth1"] = {
178 "source": "192.168.10.100",
179 "group": "229.1.2.3",
182 def test_r1_mroute():
183 "Test r1 multicast routing table function"
184 out
= tgen
.gears
["r1"].vtysh_cmd("show ip mroute json", isjson
=True)
185 if topotest
.json_cmp(out
, expect_1
) is None:
187 return topotest
.json_cmp(out
, expect_2
)
189 logger
.info("Waiting for R1 multicast routes")
190 _
, val
= topotest
.run_and_expect(test_r1_mroute
, None, count
=55, wait
=2)
191 assert val
is None, "multicast route convergence failure"
194 # Test routers 2 and 3.
196 # NOTE: only one of the paths will get the multicast route.
205 "source": "192.168.10.100",
206 "group": "229.1.2.3",
219 "source": "192.168.10.100",
220 "group": "229.1.2.3",
227 def test_r2_r3_mroute():
228 "Test r2/r3 multicast routing table function"
229 r2_out
= tgen
.gears
["r2"].vtysh_cmd("show ip mroute json", isjson
=True)
230 r3_out
= tgen
.gears
["r3"].vtysh_cmd("show ip mroute json", isjson
=True)
232 if topotest
.json_cmp(r2_out
, expect_r2
) is not None:
233 return topotest
.json_cmp(r3_out
, expect_r3
)
235 return topotest
.json_cmp(r2_out
, expect_r2
)
237 logger
.info("Waiting for R2 and R3 multicast routes")
238 _
, val
= topotest
.run_and_expect(test_r2_r3_mroute
, None, count
=55, wait
=2)
239 assert val
is None, "multicast route convergence failure"
252 "group": "229.1.2.3",
253 "inboundInterface": "lo",
254 "outboundInterface": "pimreg",
258 "group": "229.1.2.3",
259 "inboundInterface": "lo",
260 "outboundInterface": "r4-eth2",
269 "source": "192.168.10.100",
270 "group": "229.1.2.3",
271 "inboundInterface": "r4-eth0",
272 "outboundInterface": "r4-eth2",
280 topotest
.router_json_cmp
,
282 "show ip mroute json",
285 logger
.info("Waiting for R4 multicast routes")
286 _
, val
= topotest
.run_and_expect(test_func
, None, count
=55, wait
=2)
287 assert val
is None, "multicast route convergence failure"
290 def test_mroute_install():
293 if tgen
.routers_have_failure():
294 pytest
.skip(tgen
.errors
)
296 logger
.info("Starting helper1")
297 mcastaddr
= "229.1.2.3"
298 app_helper
.run("h1", [mcastaddr
, "h1-eth0"])
300 logger
.info("Starting helper2")
301 app_helper
.run("h2", ["--send=0.7", mcastaddr
, "h2-eth0"])
303 _test_mroute_install()
308 Test MSDP convergence.
310 MSDP non meshed groups must propagate the whole SA database (not just
311 their own) to all peers because not all peers talk with each other.
313 This setup leads to a potential loop that can be prevented by checking
314 the route's first AS in AS path: it must match the remote eBGP AS number.
317 if tgen
.routers_have_failure():
318 pytest
.skip(tgen
.errors
)
322 "peer": "192.168.0.2",
323 "local": "192.168.0.1",
324 "state": "established",
327 "peer": "192.168.1.2",
328 "local": "192.168.1.1",
329 "state": "established",
335 "source": "192.168.10.100",
336 "group": "229.1.2.3",
345 "peer": "192.168.0.1",
346 "local": "192.168.0.2",
347 "state": "established",
350 "peer": "192.168.2.2",
351 "local": "192.168.2.1",
352 "state": "established",
355 # Only R2 or R3 will get this SA.
359 "source": "192.168.10.100",
360 "group": "229.1.2.3",
369 "peer": "192.168.1.1",
370 "local": "192.168.1.2",
371 "state": "established",
374 # "peer": "192.168.3.2",
375 # "local": "192.168.3.1",
376 # "state": "established"
381 "peer": "192.168.2.1",
382 "local": "192.168.2.2",
383 "state": "established",
386 # "peer": "192.168.3.1",
387 # "local": "192.168.3.2",
388 # "state": "established"
394 "source": "192.168.10.100",
395 "group": "229.1.2.3",
404 ("r1", r1_expect
, r1_sa_expect
),
405 ("r2", r2_expect
, r2_r3_sa_expect
),
406 ("r3", r3_expect
, r2_r3_sa_expect
),
407 ("r4", r4_expect
, r4_sa_expect
),
410 topotest
.router_json_cmp
,
411 tgen
.gears
[router
[0]],
412 "show ip msdp peer json",
415 logger
.info("Waiting for {} msdp peer data".format(router
[0]))
416 _
, val
= topotest
.run_and_expect(test_func
, None, count
=30, wait
=1)
417 assert val
is None, "multicast route convergence failure"
420 topotest
.router_json_cmp
,
421 tgen
.gears
[router
[0]],
422 "show ip msdp sa json",
425 logger
.info("Waiting for {} msdp SA data".format(router
[0]))
426 _
, val
= topotest
.run_and_expect(test_func
, None, count
=30, wait
=1)
427 assert val
is None, "multicast route convergence failure"
430 def test_memory_leak():
431 "Run the memory leak test and report results."
433 if not tgen
.is_memleak_enabled():
434 pytest
.skip("Memory leak test/report is disabled")
436 tgen
.report_memory_leaks()
439 if __name__
== "__main__":
440 args
= ["-s"] + sys
.argv
[1:]
441 sys
.exit(pytest
.main(args
))