]>
Commit | Line | Data |
---|---|---|
7ce53cf7 KK |
1 | #!/usr/bin/env python |
2 | # SPDX-License-Identifier: ISC | |
3 | ||
4 | # | |
5 | # Copyright (c) 2022 by VMware, Inc. ("VMware") | |
6 | # Used Copyright (c) 2018 by Network Device Education Foundation, | |
7 | # Inc. ("NetDEF") in this file. | |
8 | # | |
9 | ||
10 | """ | |
11 | Following tests are covered to test multicast pim6 sm: | |
12 | ||
13 | Test steps | |
14 | - Create topology (setup module) | |
15 | - Bring up topology | |
16 | ||
17 | Following tests are covered: | |
18 | 1. Verify (*,G) and (S,G) entry populated again after clear the | |
19 | PIM nbr and mroute from FRR node | |
20 | 2. Verify SPT switchover working when RPT and SPT path is | |
21 | different | |
22 | """ | |
23 | ||
24 | import os | |
25 | import sys | |
26 | import json | |
27 | import time | |
28 | import datetime | |
29 | import pytest | |
30 | ||
31 | # Save the Current Working Directory to find configuration files. | |
32 | CWD = os.path.dirname(os.path.realpath(__file__)) | |
33 | sys.path.append(os.path.join(CWD, "../")) | |
34 | sys.path.append(os.path.join(CWD, "../lib/")) | |
35 | ||
36 | # Required to instantiate the topology builder class. | |
37 | ||
38 | # pylint: disable=C0413 | |
39 | # Import topogen and topotest helpers | |
40 | from lib.topogen import Topogen, get_topogen | |
41 | ||
42 | from lib.common_config import ( | |
43 | start_topology, | |
44 | write_test_header, | |
45 | write_test_footer, | |
46 | step, | |
47 | reset_config_on_routers, | |
48 | shutdown_bringup_interface, | |
49 | start_router, | |
50 | stop_router, | |
51 | create_static_routes, | |
52 | required_linux_kernel_version, | |
53 | socat_send_mld_join, | |
54 | socat_send_pim6_traffic, | |
55 | get_frr_ipv6_linklocal, | |
56 | ) | |
57 | from lib.bgp import create_router_bgp | |
58 | from lib.pim import ( | |
59 | create_pim_config, | |
60 | create_mld_config, | |
61 | verify_mld_groups, | |
62 | verify_mroutes, | |
63 | clear_pim6_interface_traffic, | |
64 | verify_upstream_iif, | |
65 | clear_pim6_mroute, | |
66 | verify_pim_interface_traffic, | |
67 | verify_pim_state, | |
68 | McastTesterHelper, | |
69 | verify_pim_join, | |
70 | verify_mroute_summary, | |
71 | verify_pim_nexthop, | |
72 | verify_sg_traffic, | |
73 | verify_mld_config, | |
74 | ) | |
75 | ||
76 | from lib.topolog import logger | |
77 | from lib.topojson import build_config_from_json | |
78 | ||
79 | # Global variables | |
80 | GROUP_RANGE = "ff00::/8" | |
81 | ||
82 | GROUP_RANGE_1 = [ | |
83 | "ffaa::1/128", | |
84 | "ffaa::2/128", | |
85 | "ffaa::3/128", | |
86 | "ffaa::4/128", | |
87 | "ffaa::5/128", | |
88 | ] | |
89 | MLD_JOIN_RANGE_1 = ["ffaa::1", "ffaa::2", "ffaa::3", "ffaa::4", "ffaa::5"] | |
90 | ||
91 | GROUP_RANGE_2 = [ | |
92 | "ffbb::1/128", | |
93 | "ffbb::2/128", | |
94 | "ffbb::3/128", | |
95 | "ffbb::4/128", | |
96 | "ffbb::5/128", | |
97 | ] | |
98 | MLD_JOIN_RANGE_2 = ["ffbb::1", "ffbb::2", "ffbb::3", "ffbb::4", "ffbb::5"] | |
99 | GROUP_RANGE_3 = [ | |
100 | "ffcc::1/128", | |
101 | "ffcc::2/128", | |
102 | "ffcc::3/128", | |
103 | "ffcc::4/128", | |
104 | "ffcc::5/128", | |
105 | ] | |
106 | MLD_JOIN_RANGE_3 = ["ffcc::1", "ffcc::2", "ffcc::3", "ffcc::4", "ffcc::5"] | |
107 | ||
108 | HELLO_TIMER = 1 | |
109 | HOLD_TIMER = 3 | |
110 | PREFERRED_NEXT_HOP = "link_local" | |
111 | ASSERT_MSG = "Testcase {} : Failed Error: {}" | |
112 | ||
113 | pytestmark = [pytest.mark.pim6d] | |
114 | ||
115 | ||
116 | def setup_module(mod): | |
117 | """ | |
118 | Sets up the pytest environment | |
119 | ||
120 | * `mod`: module name | |
121 | """ | |
122 | ||
123 | # Required linux kernel version for this suite to run. | |
124 | result = required_linux_kernel_version("4.19") | |
125 | if result is not True: | |
126 | pytest.skip("Kernel requirements are not met") | |
127 | ||
128 | testsuite_run_time = time.asctime(time.localtime(time.time())) | |
129 | logger.info("Testsuite start time: {}".format(testsuite_run_time)) | |
130 | logger.info("=" * 40) | |
131 | ||
132 | logger.info("Running setup_module to create topology") | |
133 | ||
134 | testdir = os.path.dirname(os.path.realpath(__file__)) | |
135 | json_file = "{}/multicast_pim6_sm_topo1.json".format(testdir) | |
136 | tgen = Topogen(json_file, mod.__name__) | |
137 | global topo | |
138 | topo = tgen.json_topo | |
139 | # ... and here it calls Mininet initialization functions. | |
140 | ||
141 | # Starting topology, create tmp files which are loaded to routers | |
142 | # to start deamons and then start routers | |
143 | start_topology(tgen) | |
144 | ||
145 | # Don"t run this test if we have any failure. | |
146 | if tgen.routers_have_failure(): | |
147 | pytest.skip(tgen.errors) | |
148 | ||
149 | # Creating configuration from JSON | |
150 | build_config_from_json(tgen, tgen.json_topo) | |
151 | ||
152 | # XXX Replace this using "with McastTesterHelper()... " in each test if possible. | |
153 | global app_helper | |
154 | app_helper = McastTesterHelper(tgen) | |
155 | ||
156 | logger.info("Running setup_module() done") | |
157 | ||
158 | ||
159 | def teardown_module(): | |
160 | """Teardown the pytest environment""" | |
161 | ||
162 | logger.info("Running teardown_module to delete topology") | |
163 | ||
164 | tgen = get_topogen() | |
165 | ||
166 | app_helper.cleanup() | |
167 | ||
168 | # Stop toplogy and Remove tmp files | |
169 | tgen.stop_topology() | |
170 | ||
171 | logger.info( | |
172 | "Testsuite end time: {}".format(time.asctime(time.localtime(time.time()))) | |
173 | ) | |
174 | logger.info("=" * 40) | |
175 | ||
176 | ||
177 | ##################################################### | |
178 | # | |
179 | # Local APIs | |
180 | # | |
181 | ##################################################### | |
182 | ||
183 | ||
184 | def verify_state_incremented(state_before, state_after): | |
185 | """ | |
186 | API to compare interface traffic state incrementing | |
187 | ||
188 | Parameters | |
189 | ---------- | |
190 | * `state_before` : State dictionary for any particular instance | |
191 | * `state_after` : State dictionary for any particular instance | |
192 | """ | |
193 | ||
194 | for router, state_data in state_before.items(): | |
195 | for state, value in state_data.items(): | |
196 | if state_before[router][state] >= state_after[router][state]: | |
197 | errormsg = ( | |
198 | "[DUT: %s]: state %s value has not" | |
199 | " incremented, Initial value: %s, " | |
200 | "Current value: %s [FAILED!!]" | |
201 | % ( | |
202 | router, | |
203 | state, | |
204 | state_before[router][state], | |
205 | state_after[router][state], | |
206 | ) | |
207 | ) | |
208 | return errormsg | |
209 | ||
210 | logger.info( | |
211 | "[DUT: %s]: State %s value is " | |
212 | "incremented, Initial value: %s, Current value: %s" | |
213 | " [PASSED!!]", | |
214 | router, | |
215 | state, | |
216 | state_before[router][state], | |
217 | state_after[router][state], | |
218 | ) | |
219 | ||
220 | return True | |
221 | ||
222 | ||
223 | ##################################################### | |
224 | # | |
225 | # Testcases | |
226 | # | |
227 | ##################################################### | |
228 | ||
229 | ||
230 | def test_clear_mroute_and_verify_multicast_data_p0(request): | |
231 | """ | |
232 | Verify (*,G) and (S,G) entry populated again after clear the | |
233 | PIM nbr and mroute from FRR node | |
234 | """ | |
235 | tgen = get_topogen() | |
236 | tc_name = request.node.name | |
237 | write_test_header(tc_name) | |
238 | ||
239 | # Creating configuration from JSON | |
240 | reset_config_on_routers(tgen) | |
241 | ||
242 | # Don"t run this test if we have any failure. | |
243 | if tgen.routers_have_failure(): | |
244 | pytest.skip(tgen.errors) | |
245 | ||
246 | step("Configure static RP on r4 for group (ffcc::1-5)") | |
247 | input_dict = { | |
248 | "r4": { | |
249 | "pim6": { | |
250 | "rp": [ | |
251 | { | |
252 | "rp_addr": topo["routers"]["r4"]["links"]["lo"]["ipv6"].split( | |
253 | "/" | |
254 | )[0], | |
255 | "group_addr_range": GROUP_RANGE_1, | |
256 | } | |
257 | ] | |
258 | } | |
259 | } | |
260 | } | |
261 | ||
262 | result = create_pim_config(tgen, topo, input_dict) | |
263 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) | |
264 | ||
265 | step( | |
266 | "Enable mld on FRR1 interface and send mld join ffaa::1 " | |
267 | "to ffaa::5 from different interfaces" | |
268 | ) | |
269 | ||
270 | step("send mld join (ffaa::1-5) to R1") | |
271 | intf = topo["routers"]["i1"]["links"]["r1"]["interface"] | |
272 | intf_ip = topo["routers"]["i1"]["links"]["r1"]["ipv6"].split("/")[0] | |
273 | result = socat_send_mld_join( | |
274 | tgen, "i1", "UDP6-RECV", MLD_JOIN_RANGE_1, intf, intf_ip | |
275 | ) | |
276 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) | |
277 | ||
278 | step("Send multicast traffic from FRR3 to all the receivers" "ffaa::1-5") | |
279 | ||
280 | intf_ip = topo["routers"]["i2"]["links"]["r3"]["ipv6"].split("/")[0] | |
281 | intf = topo["routers"]["i2"]["links"]["r3"]["interface"] | |
282 | result = socat_send_pim6_traffic(tgen, "i2", "UDP6-SEND", MLD_JOIN_RANGE_1, intf) | |
283 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) | |
284 | ||
285 | step("Clear the mroute on r1, wait for 5 sec") | |
286 | result = clear_pim6_mroute(tgen, "r1") | |
287 | assert result is True, "Testcase{}: Failed Error: {}".format(tc_name, result) | |
288 | ||
289 | step( | |
290 | "After clear ip mroute (*,g) entries are re-populated again" | |
291 | " with same OIL and IIF, verify using 'show ipv6 mroute' and " | |
292 | " 'show ipv6 pim upstream' " | |
293 | ) | |
294 | ||
295 | source = topo["routers"]["i2"]["links"]["r3"]["ipv6"].split("/")[0] | |
296 | input_dict = [ | |
297 | { | |
298 | "dut": "r1", | |
299 | "src_address": "*", | |
300 | "iif": topo["routers"]["r1"]["links"]["r4"]["interface"], | |
301 | "oil": topo["routers"]["r1"]["links"]["i1"]["interface"], | |
302 | } | |
303 | ] | |
304 | ||
305 | for data in input_dict: | |
306 | result = verify_mroutes( | |
307 | tgen, | |
308 | data["dut"], | |
309 | data["src_address"], | |
310 | MLD_JOIN_RANGE_1, | |
311 | data["iif"], | |
312 | data["oil"], | |
313 | ) | |
314 | assert result is True, "Testcase{} : Failed Error: {}".format(tc_name, result) | |
315 | ||
316 | step( | |
317 | "Verify 'show ipv6 pim upstream' showing correct OIL and IIF" | |
318 | " on all the nodes" | |
319 | ) | |
320 | for data in input_dict: | |
321 | result = verify_upstream_iif( | |
322 | tgen, data["dut"], data["iif"], data["src_address"], MLD_JOIN_RANGE_1 | |
323 | ) | |
324 | assert result is True, "Testcase{} : Failed Error: {}".format(tc_name, result) | |
325 | ||
326 | step("Clear the mroute on r3, wait for 5 sec") | |
327 | result = clear_pim6_mroute(tgen, "r3") | |
328 | assert result is True, "Testcase{}: Failed Error: {}".format(tc_name, result) | |
329 | ||
330 | step( | |
331 | "Verify 'show ipv6 mroute' showing correct RPF and OIF" | |
332 | " interface for (*,G) and (S,G) entries on all the nodes" | |
333 | ) | |
334 | ||
335 | input_dict = [ | |
336 | { | |
337 | "dut": "r3", | |
338 | "src_address": source, | |
339 | "iif": topo["routers"]["r3"]["links"]["i2"]["interface"], | |
340 | "oil": topo["routers"]["r3"]["links"]["r2"]["interface"], | |
341 | } | |
342 | ] | |
343 | ||
344 | for data in input_dict: | |
345 | result = verify_mroutes( | |
346 | tgen, | |
347 | data["dut"], | |
348 | data["src_address"], | |
349 | MLD_JOIN_RANGE_1, | |
350 | data["iif"], | |
351 | data["oil"], | |
352 | ) | |
353 | assert result is True, "Testcase{} : Failed Error: {}".format(tc_name, result) | |
354 | ||
355 | step( | |
356 | "Verify 'show ipv6 pim upstream' showing correct OIL and IIF" | |
357 | " on all the nodes" | |
358 | ) | |
359 | for data in input_dict: | |
360 | result = verify_upstream_iif( | |
361 | tgen, data["dut"], data["iif"], data["src_address"], MLD_JOIN_RANGE_1 | |
362 | ) | |
363 | assert result is True, "Testcase{} : Failed Error: {}".format(tc_name, result) | |
364 | ||
365 | step("Clear the mroute on r2, wait for 5 sec") | |
366 | result = clear_pim6_mroute(tgen, "r2") | |
367 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) | |
368 | ||
369 | step( | |
370 | "Verify 'show ipv6 mroute' showing correct RPF and OIF" | |
371 | " interface for (*,G) and (S,G) entries on all the nodes" | |
372 | ) | |
373 | ||
374 | input_dict = [ | |
375 | { | |
376 | "dut": "r2", | |
377 | "src_address": source, | |
378 | "iif": topo["routers"]["r2"]["links"]["r3"]["interface"], | |
379 | "oil": topo["routers"]["r2"]["links"]["r1"]["interface"], | |
380 | } | |
381 | ] | |
382 | ||
383 | for data in input_dict: | |
384 | result = verify_mroutes( | |
385 | tgen, | |
386 | data["dut"], | |
387 | data["src_address"], | |
388 | MLD_JOIN_RANGE_1, | |
389 | data["iif"], | |
390 | data["oil"], | |
391 | ) | |
392 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) | |
393 | ||
394 | step( | |
395 | "Verify 'show ipv6 pim upstream' showing correct OIL and IIF" | |
396 | " on all the nodes" | |
397 | ) | |
398 | for data in input_dict: | |
399 | result = verify_upstream_iif( | |
400 | tgen, data["dut"], data["iif"], data["src_address"], MLD_JOIN_RANGE_1 | |
401 | ) | |
402 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) | |
403 | ||
404 | step("Clear the mroute on r1, r3, wait for 5 sec") | |
405 | result = clear_pim6_mroute(tgen, "r1") | |
406 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) | |
407 | ||
408 | result = clear_pim6_mroute(tgen, "r3") | |
409 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) | |
410 | ||
411 | step( | |
412 | "Verify 'show ipv6 mroute' showing correct RPF and OIF" | |
413 | " interface for (*,G) and (S,G) entries on all the nodes" | |
414 | ) | |
415 | ||
416 | input_dict = [ | |
417 | { | |
418 | "dut": "r1", | |
419 | "src_address": "*", | |
420 | "iif": topo["routers"]["r1"]["links"]["r4"]["interface"], | |
421 | "oil": topo["routers"]["r1"]["links"]["i1"]["interface"], | |
422 | }, | |
423 | { | |
424 | "dut": "r3", | |
425 | "src_address": source, | |
426 | "iif": topo["routers"]["r3"]["links"]["i2"]["interface"], | |
427 | "oil": topo["routers"]["r3"]["links"]["r2"]["interface"], | |
428 | }, | |
429 | ] | |
430 | ||
431 | for data in input_dict: | |
432 | result = verify_mroutes( | |
433 | tgen, | |
434 | data["dut"], | |
435 | data["src_address"], | |
436 | MLD_JOIN_RANGE_1, | |
437 | data["iif"], | |
438 | data["oil"], | |
439 | ) | |
440 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) | |
441 | ||
442 | step( | |
443 | "Verify 'show ipv6 pim upstream' showing correct OIL and IIF" | |
444 | " on all the nodes" | |
445 | ) | |
446 | for data in input_dict: | |
447 | result = verify_upstream_iif( | |
448 | tgen, data["dut"], data["iif"], data["src_address"], MLD_JOIN_RANGE_1 | |
449 | ) | |
450 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) | |
451 | ||
452 | step( | |
453 | "multicast traffic is resume for all the receivers using " | |
454 | " 'show ip multicast' " | |
455 | ) | |
456 | result = verify_sg_traffic(tgen, "r1", MLD_JOIN_RANGE_1, source, "ipv6") | |
457 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) | |
458 | ||
459 | write_test_footer(tc_name) | |
460 | ||
461 | ||
462 | def test_verify_SPT_switchover_when_RPT_and_SPT_path_is_different_p0(request): | |
463 | """ | |
464 | Verify SPT switchover working when RPT and SPT path is | |
465 | different | |
466 | """ | |
467 | ||
468 | tgen = get_topogen() | |
469 | tc_name = request.node.name | |
470 | write_test_header(tc_name) | |
471 | ||
472 | # Creating configuration from JSON | |
473 | reset_config_on_routers(tgen) | |
474 | ||
475 | # Don"t run this test if we have any failure. | |
476 | if tgen.routers_have_failure(): | |
477 | pytest.skip(tgen.errors) | |
478 | ||
479 | step("Configure static RP for (ffcc::1-5) and " "(ffbb::1-5) in r5") | |
480 | ||
481 | _GROUP_RANGE = GROUP_RANGE_2 + GROUP_RANGE_3 | |
482 | _MLD_JOIN_RANGE = MLD_JOIN_RANGE_2 + MLD_JOIN_RANGE_3 | |
483 | ||
484 | input_dict = { | |
485 | "r5": { | |
486 | "pim6": { | |
487 | "rp": [ | |
488 | { | |
489 | "rp_addr": topo["routers"]["r5"]["links"]["lo"]["ipv6"].split( | |
490 | "/" | |
491 | )[0], | |
492 | "group_addr_range": _GROUP_RANGE, | |
493 | } | |
494 | ] | |
495 | } | |
496 | } | |
497 | } | |
498 | ||
499 | result = create_pim_config(tgen, topo, input_dict) | |
500 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) | |
501 | ||
502 | step("send mld join (ffbb::1-5, ffcc::1-5) to R1") | |
503 | intf = topo["routers"]["i1"]["links"]["r1"]["interface"] | |
504 | intf_ip = topo["routers"]["i1"]["links"]["r1"]["ipv6"].split("/")[0] | |
505 | result = socat_send_mld_join( | |
506 | tgen, "i1", "UDP6-RECV", _MLD_JOIN_RANGE, intf, intf_ip | |
507 | ) | |
508 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) | |
509 | ||
510 | step("registerRx and registerStopTx value before traffic sent") | |
511 | intf_r5 = topo["routers"]["r5"]["links"]["r3"]["interface"] | |
512 | state_dict = {"r5": {intf_r5: ["registerRx", "registerStopTx"]}} | |
513 | state_before = verify_pim_interface_traffic(tgen, state_dict, addr_type="ipv6") | |
514 | assert isinstance( | |
515 | state_before, dict | |
516 | ), "Testcase {} : Failed \n state_before is not dictionary \n " "Error: {}".format( | |
517 | tc_name, result | |
518 | ) | |
519 | ||
520 | step( | |
521 | "Send multicast traffic from FRR3 to all the receivers" "ffbb::1-5 , ffcc::1-5" | |
522 | ) | |
523 | intf_ip = topo["routers"]["i2"]["links"]["r3"]["ipv6"].split("/")[0] | |
524 | intf = topo["routers"]["i2"]["links"]["r3"]["interface"] | |
525 | result = socat_send_pim6_traffic(tgen, "i2", "UDP6-SEND", _MLD_JOIN_RANGE, intf) | |
526 | assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result) | |
527 | ||
528 | step( | |
529 | "Verify in FRR3 sending initial packet to RP using" | |
530 | " 'show ipv6 mroute' and mroute OIL is towards RP." | |
531 | ) | |
532 | ||
533 | source = topo["routers"]["i2"]["links"]["r3"]["ipv6"].split("/")[0] | |
534 | ||
535 | r3_i2 = topo["routers"]["r3"]["links"]["i2"]["interface"] | |
536 | r3_r5 = topo["routers"]["r3"]["links"]["r5"]["interface"] | |
537 | r3_r2 = topo["routers"]["r3"]["links"]["r2"]["interface"] | |
538 | r1_r2 = topo["routers"]["r1"]["links"]["r2"]["interface"] | |
539 | r1_i1 = topo["routers"]["r1"]["links"]["i1"]["interface"] | |
540 | ||
541 | result = verify_mroutes(tgen, "r3", source, _MLD_JOIN_RANGE, r3_i2, [r3_r5, r3_r2]) | |
542 | assert result is True, "Testcase {} : " "Failed Error: {}".format(tc_name, result) | |
543 | ||
544 | result = verify_mroutes(tgen, "r3", source, _MLD_JOIN_RANGE, r3_i2, r3_r2) | |
545 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) | |
546 | ||
547 | step( | |
548 | " After spt switchover traffic is flowing between" | |
549 | " (LHR(FRR1)-FHR(FRR3)) and (S,G) OIL is updated toward FRR1" | |
550 | " 'show mroute' and 'show pim upstream'" | |
551 | ) | |
552 | ||
553 | input_dict = [ | |
554 | {"dut": "r3", "src_address": source, "iif": r3_i2, "oil": r3_r2}, | |
555 | {"dut": "r1", "src_address": source, "iif": r1_r2, "oil": r1_i1}, | |
556 | ] | |
557 | for data in input_dict: | |
558 | result = verify_mroutes( | |
559 | tgen, | |
560 | data["dut"], | |
561 | data["src_address"], | |
562 | _MLD_JOIN_RANGE, | |
563 | data["iif"], | |
564 | data["oil"], | |
565 | ) | |
566 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) | |
567 | ||
568 | for data in input_dict: | |
569 | result = verify_upstream_iif( | |
570 | tgen, data["dut"], data["iif"], data["src_address"], _MLD_JOIN_RANGE | |
571 | ) | |
572 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) | |
573 | ||
574 | step("Stop the traffic to all the receivers") | |
575 | dut = "i2" | |
576 | intf = topo["routers"]["i2"]["links"]["r3"]["interface"] | |
577 | shutdown_bringup_interface(tgen, dut, intf, False) | |
578 | ||
579 | step( | |
580 | "Null register packet being send periodically from FRR3 to RP, " | |
581 | "verify using show ipv6 mroute on RP, have (S, G) entries null OIL" | |
582 | " 'show ipv6 mroute' and verify show ip pim interface traffic" | |
583 | "(In RP Register msg should be received and Register stop should" | |
584 | " be transmitted)" | |
585 | ) | |
586 | ||
587 | result = verify_upstream_iif( | |
588 | tgen, "r3", "Unknown", source, _MLD_JOIN_RANGE, joinState="NotJoined" | |
589 | ) | |
590 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) | |
591 | ||
592 | step("registerRx and registerStopTx value after traffic sent") | |
593 | state_after = verify_pim_interface_traffic(tgen, state_dict, addr_type="ipv6") | |
594 | assert isinstance( | |
595 | state_after, dict | |
596 | ), "Testcase {} : Failed \n state_before is not dictionary \n " "Error: {}".format( | |
597 | tc_name, result | |
598 | ) | |
599 | ||
600 | result = verify_state_incremented(state_before, state_after) | |
601 | assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) | |
602 | ||
603 | write_test_footer(tc_name) | |
604 | ||
605 | ||
606 | if __name__ == "__main__": | |
607 | args = ["-s"] + sys.argv[1:] | |
608 | sys.exit(pytest.main(args)) |