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/multicast_pim_bsm_topo1 | |
parent | Initial commit. (diff) | |
download | frr-upstream.tar.xz frr-upstream.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/multicast_pim_bsm_topo1')
-rw-r--r-- | tests/topotests/multicast_pim_bsm_topo1/mcast_pim_bsmp_01.json | 238 | ||||
-rw-r--r-- | tests/topotests/multicast_pim_bsm_topo1/test_mcast_pim_bsmp_01.py | 1787 |
2 files changed, 2025 insertions, 0 deletions
diff --git a/tests/topotests/multicast_pim_bsm_topo1/mcast_pim_bsmp_01.json b/tests/topotests/multicast_pim_bsm_topo1/mcast_pim_bsmp_01.json new file mode 100644 index 0000000..14cb0be --- /dev/null +++ b/tests/topotests/multicast_pim_bsm_topo1/mcast_pim_bsmp_01.json @@ -0,0 +1,238 @@ +{ + "ipv4base": "10.0.0.0", + "ipv4mask": 24, + "link_ip_start": {"ipv4": "10.0.0.0", "v4mask": 24}, + "lo_prefix": {"ipv4": "1.0.", "v4mask": 32}, + "routers": { + "b1": { + "links": { + "f1": {"ipv4": "auto", "pim": "enable"}, + "lo": {"ipv4": "auto", "type": "loopback", "pim": "enable"} + }, + "bsm": { + "bsr_packets": { + "packet1" : { + "data": "01005e00000d005056961165080045c000aa5af500000167372a46000001e000000d2400f5ce165b000001004600000101000018e1010100080800000100090a090a0096650001000909090a0096660001000708090a00966700010007070907009668000100070702070096690001000705020700966a0001000702020700966b0001000202020200966c0001000020e1010101010100000100050606050096000001000020e20101010101000001000909090900960000", + "src_ip": "70.0.0.1/24", + "dest_ip": "70.0.0.2/24", + "bsr": "70.0.0.1/24", + "pkt_dst": "224.0.0.13", + "rp_mapping" : { + "225.1.1.0/24": ["9.10.9.10/32", "7.8.9.10/32", + "9.9.9.10/32", "7.7.9.7/32", + "7.7.2.7/32", "7.5.2.7/32", + "7.2.2.7/32", "2.2.2.2/32"], + "225.1.1.1/32": ["5.6.6.5/32"], + "225.200.100.100/32": ["210.210.210.210/32"], + "226.1.1.1/32": ["9.9.9.9/32"] + + }, + "Desc" : "Packet with 3 group range - rp prio different" + }, + "packet2" : { + "data": "01005e00000d005056961165080045c0009420f400000167714146000001e000000d24000b3b164a000001004600000101000018e1010100080800000100020202020096640001000909090a0096640001000707020700966400010007020207009664000100070709070096640001000708090a00966400010007050207009664000100090a090a0096640001000020e20101010101000001000909090900000000", + "src_ip": "70.0.0.1/24", + "dest_ip": "70.0.0.2/24", + "bsr": "70.0.0.1/24", + "pkt_dst": "224.0.0.13", + "rp_mapping" : { + "225.1.1.0/24": ["9.10.9.10/32", "7.8.9.10/32", + "9.9.9.10/32", "7.7.9.7/32", + "7.7.2.7/32", "7.5.2.7/32", + "7.2.2.7/32", "2.2.2.2/32"] + }, + "Desc" : "Packet 1 with hold time 0 for 226.1.1.1/32" + }, + "packet3" : { + "data": "01005e00000d005056961165080045c000944d0000000167453546000001e000000d2400e52b17c3000001004600000101000018e1010100080800000100090a090a0096650001000909090a0096660001000708090a00966700010007070907009668000100070702070096690001000705020700966a0001000702020700966b0001000202020200966c0001000020e20101010101000001000909090900960000", + "src_ip": "70.0.0.1/24", + "dest_ip": "70.0.0.2/24", + "bsr": "70.0.0.1/24", + "pkt_dst": "224.0.0.13", + "rp_mapping" : { + "225.1.1.0/24": ["9.10.9.10/32", "7.8.9.10/32", + "9.9.9.10/32", "7.7.9.7/32", + "7.7.2.7/32", "7.5.2.7/32", + "7.2.2.7/32", "2.2.2.2/32"], + "226.1.1.1/32": ["9.9.9.9/32"] + }, + "Desc" : "BSR Prio - TC 4" + }, + "packet4" : { + "data": "01005e00000d005056961165080045c000aa3d1c00000167550346000001e000000d24000d671c52000001004600000101000018e1010100080800000100020202020096640001000909090a0096640001000707020700966400010007020207009664000100070709070096640001000708090a00966400010007050207009664000100090a090a0096640001000020e1010101010100000100090909090000000001000020e20101010101000001000909090900960000", + "src_ip": "70.0.0.1/24", + "dest_ip": "70.0.0.2/24", + "bsr": "70.0.0.1/24", + "pkt_dst": "224.0.0.13", + "rp_mapping" : { + "225.1.1.0/24": ["9.10.9.10/32", "7.8.9.10/32", + "9.9.9.10/32", "7.7.9.7/32", + "7.7.2.7/32", "7.5.2.7/32", + "7.2.2.7/32", "2.2.2.2/32"], + "225.1.1.1/32": ["9.9.9.9/32"], + "226.1.1.1/32": ["9.9.9.9/32"] + }, + "Desc" : "TC - 5" + }, + "packet5" : { + "data": "01005e00000d005056961165080045c000aa3d1c00000167550346000001e000000d24000d671c52000001004600000101000018e1010100080800000100020202020096640001000909090a0096640001000707020700966400010007020207009664000100070709070096640001000708090a00966400010007050207009664000100090a090a0096640001000020e1010101010100000100090909090000000001000020e20101010101000001000909090900960000", + "src_ip": "70.0.0.1/24", + "dest_ip": "70.0.0.2/24", + "bsr": "70.0.0.1/24", + "pkt_dst": "224.0.0.13", + "rp_mapping" : { + "225.1.1.0/24": ["9.10.9.10/32", "7.8.9.10/32", + "9.9.9.10/32", "7.7.9.7/32", + "7.7.2.7/32", "7.5.2.7/32", + "7.2.2.7/32", "2.2.2.2/32"], + "226.1.1.1/32": ["9.9.9.9/32"] + }, + "Desc" : "TC - 5, 225.1.1.1 with hold time 0" + }, + "packet6" : { + "data": "01005e00000d005056961165080045c0008a795e0000016718e146000001e000000d24006cc509d5000001004600000101000018e10101000707000001000909090a0096660001000708090a00966700010007070907009668000100070702070096690001000705020700966a0001000702020700966b0001000202020200966c0001000020e20101010101000001000909090900960000", + "src_ip": "70.0.0.1/24", + "dest_ip": "70.0.0.2/24", + "bsr": "70.0.0.1/24", + "pkt_dst": "224.0.0.13", + "rp_mapping" : { + "225.1.1.0/24": ["7.8.9.10/32", + "9.9.9.10/32", "7.7.9.7/32", + "7.7.2.7/32", "7.5.2.7/32", + "7.2.2.7/32", "2.2.2.2/32"], + "226.1.1.1/32": ["9.9.9.9/32"] + }, + "Desc" : "TC - 6,High prio rp removed on 225.1.1.0/24" + }, + "packet7" : { + "data": "01005e00000d005056961165080045c0007e6ebb00000167239046000001e000000d2400090810b3000001004600000101000018e1010100080800000100020202020096640001000909090a0096640001000707020700966400010007020207009664000100070709070096640001000708090a00966400010007050207009664000100090a090a00966400", + "src_ip": "70.0.0.1/24", + "dest_ip": "70.0.0.2/24", + "bsr": "70.0.0.1/24", + "pkt_dst": "224.0.0.13", + "rp_mapping" : { + "225.1.1.0/24": ["9.10.9.10/32", "7.8.9.10/32", + "9.9.9.10/32", "7.7.9.7/32", + "7.7.2.7/32", "7.5.2.7/32", + "7.2.2.7/32", "2.2.2.2/32"] + }, + "Desc" : "TC - 8, rps with same priority" + }, + + "packet8" : { + "data": "01005e00000d005056b76687080045c000383cdf0000016755b246000001e000000d24008ad51a9f000001004600000101000020e1c86464010100000100d2d2d2d200960000", + "group": "225.200.100.100/32", + "src_ip": "70.0.0.1/24", + "dest_ip": "70.0.0.2/24", + "bsr": "70.0.0.1/24", + "pkt_dst": "224.0.0.13", + "rp_mapping" : { + "225.200.100.100/32": ["210.210.210.210/32"] + }, + "Desc" : "TC - 30, grp add with all octet" + }, + + "packet9" : { + "data": "01005e00000d005056b76687080045c000387b8600000167170b46000001e000000d2400c6282245000001000101020701000020e1c86464010100000100d2d2d2d200960000", + "group": "225.200.100.100/32", + "candidate_rp": "210.210.210.210/32", + "src_ip": "70.0.0.1/24", + "dest_ip": "70.0.0.2/24", + "bsr": "1.1.2.7/32", + "pkt_dst": "224.0.0.13", + "rp_mapping" : { + "225.200.100.100/32": ["210.210.210.210/32"] + }, + "Desc" : "TC -29, BSM with preferred ip" + } + + } + } + }, + + "b2": { + "links": { + "f1": {"ipv4": "auto", "pim": "enable"}, + "lo": {"ipv4": "auto", "type": "loopback", "pim": "enable"} + }, + "bsm": { + "bsr_packets": { + "packet1" : { + "data": "01005e00000d005056b70489080045c0003865db0000016731b641000001e000000d2400659c0c6f000001004100000101000018e10101000101000001002121212100960000", + "src_ip": "65.0.0.1/24", + "dest_ip": "65.0.0.2/24", + "bsr": "65.0.0.1/24", + "pkt_dst": "224.0.0.13", + "rp_mapping" : { + "225.1.1.0/24": ["33.33.33.33/32"], + "225.200.100.100/32": ["210.210.210.210/32"] + } + }, + "packet2" : { + "data": "01005e00000d005056b70489080045c00038663000000167316141000001e000000d24006dce0433000a01004100000101000018e10101000101000001002121212100960000", + "src_ip": "65.0.0.1/24", + "dest_ip": "65.0.0.2/24", + "bsr": "65.0.0.1/24", + "pkt_dst": "224.0.0.13", + "rp_mapping" : { + "225.1.1.0/24": ["33.33.33.33/32"] + } + }, + + "packet3" : { + "data": "01005e00000d005056b76687080045c00038f5c800000167a1c841000001e000000d2400c6621a10000001000a02010101000020e1c86464010100000100d2d2d2d200960000", + "src_ip": "65.0.0.1/24", + "dest_ip": "65.0.0.2/24", + "bsr": "10.2.1.1/32", + "pkt_dst": "224.0.0.13", + "rp_mapping" : { + "225.200.100.100/32": ["210.210.210.210/32"] + } + } + + } + } + }, + + "f1": { + "links": { + "b1": {"ipv4": "auto", "pim": "enable"}, + "b2": {"ipv4": "auto", "pim": "enable"}, + "i1": {"ipv4": "auto", "pim": "enable"}, + "s1": {"ipv4": "auto", "pim": "enable"} + } + }, + "i1": { + "links": { + "lo": {"ipv4": "auto", "type": "loopback", "pim": "enable"}, + "f1": {"ipv4": "auto", "pim": "enable"}, + "l1": {"ipv4": "auto", "pim": "enable"} + } + }, + "l1": { + "links": { + "i1": {"ipv4": "auto", "pim": "enable"}, + "r1": {"ipv4": "auto", "pim": "enable"} + }, + "igmp": { + "interfaces": { + "l1-r1-eth1" :{ + "igmp":{ + "version": "2" + } + } + } + } + }, + "s1": { + "links": { + "f1": {"ipv4": "auto", "pim": "enable"} + } + }, + "r1": { + "links": { + "l1": {"ipv4": "auto", "pim": "disable"} + } + } + } +} diff --git a/tests/topotests/multicast_pim_bsm_topo1/test_mcast_pim_bsmp_01.py b/tests/topotests/multicast_pim_bsm_topo1/test_mcast_pim_bsmp_01.py new file mode 100644 index 0000000..bcf8e5b --- /dev/null +++ b/tests/topotests/multicast_pim_bsm_topo1/test_mcast_pim_bsmp_01.py @@ -0,0 +1,1787 @@ +#!/usr/bin/env python +# +# Copyright (c) 2020 by VMware, Inc. ("VMware") +# Used Copyright (c) 2018 by Network Device Education Foundation, +# Inc. ("NetDEF") in this file. +# +# 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 VMWARE DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE 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. +# + +""" +Following tests are covered to test PIM BSM processing basic functionality: + +Test steps +- Create topology (setup module) +- Bring up topology + +Tests covered in this suite +1. Verify FRR router select higher IP BSR , when 2 BSR present in the network +2. Verify BSR and RP updated correctly after configuring as black hole address +3.1 Verify when new router added to the topology, FRR node will send + unicast BSM to new router +3.2 Verify if no forwarding bit is set , FRR is not forwarding the + BSM to other PIM nbrs +3.3 Verify multicast BSM is sent to new router when unicast BSM is disabled +4.1 Verify BSM arrived on non bsm capable interface is dropped and + not processed +4.2 Verify group to RP info updated correctly in FRR node, after shut and + no-shut of BSM enable interfaces +5. Verify static RP is preferred over BSR +6.1 Verify adding/deleting the group to rp mapping and RP priority + multiple times +6.2 Verify RP and (*,G) detail after PIM process restart on FRR node +7.1 Verify BSM timeout on FRR1 +7.2 Verify RP state in FRR1 after Bootstrap timer expiry +8.1 Verify upstream interfaces(IIF) and join state are updated properly + after BSM received for FRR +8.2 Verify IIF and OIL in "show ip pim state" updated properly after + BSM received +""" + +import os +import sys +import time +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, "../")) +sys.path.append(os.path.join(CWD, "../lib/")) + +# Required to instantiate the topology builder class. + +# pylint: disable=C0413 +# Import topogen and topotest helpers +from lib.topogen import Topogen, get_topogen + +from lib.common_config import ( + start_topology, + write_test_header, + write_test_footer, + step, + addKernelRoute, + create_static_routes, + stop_router, + start_router, + shutdown_bringup_interface, + kill_router_daemons, + start_router_daemons, + reset_config_on_routers, + do_countdown, + apply_raw_config, + run_frr_cmd, + required_linux_kernel_version, + topo_daemons, + verify_rib, +) + +from lib.pim import ( + create_pim_config, + add_rp_interfaces_and_pim_config, + reconfig_interfaces, + scapy_send_bsr_raw_packet, + find_rp_from_bsrp_info, + verify_pim_grp_rp_source, + verify_pim_bsr, + verify_mroutes, + verify_join_state_and_timer, + verify_pim_state, + verify_upstream_iif, + verify_igmp_groups, + verify_pim_upstream_rpf, + enable_disable_pim_unicast_bsm, + enable_disable_pim_bsm, + clear_mroute, + clear_pim_interface_traffic, + get_pim_interface_traffic, + McastTesterHelper, + verify_pim_neighbors, +) +from lib.topolog import logger +from lib.topojson import build_config_from_json + + +pytestmark = [pytest.mark.pimd, pytest.mark.staticd] + +TOPOLOGY = """ + + b1_____ + | + | + s1-----f1-----i1-----l1----r1 + | + ______| + b2 + + b1 - BSR 1 + b2 - BSR 2 + s1 - Source + f1 - FHR + i1 - Intermediate Router (also RP) + r1 - Receiver + +""" +# Global variables +NEXT_HOP1 = "70.0.0.1" +NEXT_HOP2 = "65.0.0.1" +BSR_IP_1 = "1.1.2.7" +BSR_IP_2 = "10.2.1.1" +BSR1_ADDR = "1.1.2.7/32" +BSR2_ADDR = "10.2.1.1/32" + + +def setup_module(mod): + """ + Sets up the pytest environment + + * `mod`: module name + """ + + # Required linux kernel version for this suite to run. + result = required_linux_kernel_version("4.15") + if result is not True: + pytest.skip("Kernel requirements are not met") + + testsuite_run_time = time.asctime(time.localtime(time.time())) + logger.info("Testsuite start time: {}".format(testsuite_run_time)) + logger.info("=" * 40) + logger.info("Master Topology: \n {}".format(TOPOLOGY)) + + logger.info("Running setup_module to create topology") + + # This function initiates the topology build with Topogen... + json_file = "{}/mcast_pim_bsmp_01.json".format(CWD) + tgen = Topogen(json_file, mod.__name__) + global topo + topo = tgen.json_topo + # ... and here it calls Mininet initialization functions. + + # get list of daemons needs to be started for this suite. + daemons = topo_daemons(tgen, topo) + + # Starting topology, create tmp files which are loaded to routers + # to start daemons and then start routers + start_topology(tgen, daemons) + + # Don"t run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + # Creating configuration from JSON + build_config_from_json(tgen, topo) + + # Verify PIM neighbors + result = verify_pim_neighbors(tgen, topo) + assert result is True, " Verify PIM neighbor: Failed Error: {}".format(result) + + # XXX Replace this using "with McastTesterHelper()... " in each test if possible. + global app_helper + app_helper = McastTesterHelper(tgen) + + logger.info("Running setup_module() done") + + +def teardown_module(): + """Teardown the pytest environment""" + + logger.info("Running teardown_module to delete topology") + + tgen = get_topogen() + + app_helper.cleanup() + + # Stop toplogy and Remove tmp files + tgen.stop_topology() + + logger.info( + "Testsuite end time: {}".format(time.asctime(time.localtime(time.time()))) + ) + logger.info("=" * 40) + + +##################################################### +# +# Local APIs +# +##################################################### + + +def clear_bsrp_data(tgen, topo): + + """ + clear bsm databas after test" + Parameters + ---------- + * `tgen`: topogen object + + Usage + ----- + result = clear_bsrp_data(tgen, topo) + Returns + ------- + errormsg(str) or True + """ + + for dut in tgen.routers(): + + rnode = tgen.routers()[dut] + + logger.info("[DUT: %s]: clear_bsrp_data") + + run_frr_cmd(rnode, "clear ip pim bsr-data") + + return True + + +def verify_state_incremented(state_before, state_after): + """ + API to compare interface traffic state incrementing + + Parameters + ---------- + * `state_before` : State dictionary for any particular instance + * `state_after` : State dictionary for any particular instance + """ + + for router, state_data in state_before.items(): + for state, value in state_data.items(): + if state_before[router][state] >= state_after[router][state]: + errormsg = ( + "[DUT: %s]: state %s value has not" + " incremented, Initial value: %s, " + "Current value: %s [FAILED!!]" + % ( + router, + state, + state_before[router][state], + state_after[router][state], + ) + ) + return errormsg + + logger.info( + "[DUT: %s]: State %s value is " + "incremented, Initial value: %s, Current value: %s" + " [PASSED!!]", + router, + state, + state_before[router][state], + state_after[router][state], + ) + + return True + + +def pre_config_to_bsm(tgen, topo, tc_name, bsr, sender, receiver, fhr, rp, lhr, packet): + """ + API to do required configuration to send and receive BSR packet + """ + + # Re-configure interfaces as per BSR packet + result = reconfig_interfaces(tgen, topo, bsr, fhr, packet) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # Create static routes + if "bsr" in topo["routers"][bsr]["bsm"]["bsr_packets"][packet]: + bsr_route = topo["routers"][bsr]["bsm"]["bsr_packets"][packet]["bsr"] + next_hop = topo["routers"][bsr]["bsm"]["bsr_packets"][packet]["src_ip"].split( + "/" + )[0] + next_hop_rp = topo["routers"][fhr]["links"][rp]["ipv4"].split("/")[0] + next_hop_lhr = topo["routers"][rp]["links"][lhr]["ipv4"].split("/")[0] + + # Add static routes + input_dict = { + rp: {"static_routes": [{"network": bsr_route, "next_hop": next_hop_rp}]}, + lhr: {"static_routes": [{"network": bsr_route, "next_hop": next_hop_lhr}]}, + } + + result = create_static_routes(tgen, input_dict) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # Verifying static routes are installed + for dut, _nexthop in zip([rp, lhr], [next_hop_rp, next_hop_lhr]): + input_routes = {dut: input_dict[dut]} + result = verify_rib( + tgen, "ipv4", dut, input_routes, _nexthop, protocol="static" + ) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + # RP Mapping + rp_mapping = topo["routers"][bsr]["bsm"]["bsr_packets"][packet]["rp_mapping"] + + # Add interfaces in RP for all the RPs + result = add_rp_interfaces_and_pim_config(tgen, topo, "lo", rp, rp_mapping) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # Add kernel routes to sender and receiver + for group, rp_list in rp_mapping.items(): + mask = group.split("/")[1] + if int(mask) == 32: + group = group.split("/")[0] + + # Add static routes for RPs in FHR and LHR + next_hop_fhr = topo["routers"][rp]["links"][fhr]["ipv4"].split("/")[0] + next_hop_lhr = topo["routers"][rp]["links"][lhr]["ipv4"].split("/")[0] + input_dict = { + fhr: {"static_routes": [{"network": rp_list, "next_hop": next_hop_fhr}]}, + } + result = create_static_routes(tgen, input_dict) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # Verifying static routes are installed + result = verify_rib( + tgen, "ipv4", fhr, input_dict, next_hop_fhr, protocol="static" + ) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + input_dict = { + lhr: {"static_routes": [{"network": rp_list, "next_hop": next_hop_lhr}]}, + } + result = create_static_routes(tgen, input_dict) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # Verifying static routes are installed + result = verify_rib( + tgen, "ipv4", lhr, input_dict, next_hop_lhr, protocol="static" + ) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + return True + + +##################################################### +# +# Testcases +# +##################################################### + + +def test_BSR_higher_prefer_ip_p0(request): + """ + Verify FRR router select higher IP BSR , when 2 BSR present in the network + + Topology used: + b1_____ + | + | + s1-----f1-----i1-----l1----r1 + | + ______| + b2 + + b1 - BSR 1 + b2 - BSR 2 + s1 - Source + f1 - FHR + i1 - Intermediate Router (also RP) + r1 - Receiver + """ + + tgen = get_topogen() + tc_name = request.node.name + write_test_header(tc_name) + + # Don"t run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + app_helper.stop_all_hosts() + clear_mroute(tgen) + reset_config_on_routers(tgen) + clear_pim_interface_traffic(tgen, topo) + + step("pre-configure BSM packet") + step("Configure cisco-1 as BSR1 1.1.2.7") + result = pre_config_to_bsm( + tgen, topo, tc_name, "b1", "s1", "r1", "f1", "i1", "l1", "packet1" + ) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + step("Configure cisco-1 as BSR1 10.2.1.1") + result = pre_config_to_bsm( + tgen, topo, tc_name, "b2", "s1", "r1", "f1", "i1", "l1", "packet1" + ) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + step("configuring loopback address of b1 and b2 as BSR") + intf_lo_addr_b1 = topo["routers"]["b1"]["links"]["lo"]["ipv4"] + intf_lo_addr_b2 = topo["routers"]["b2"]["links"]["lo"]["ipv4"] + + raw_config = { + "b1": { + "raw_config": [ + "interface lo", + "no ip address {}".format(intf_lo_addr_b1), + "ip address {}".format(BSR1_ADDR), + "ip pim", + ] + }, + "b2": { + "raw_config": [ + "interface lo", + "no ip address {}".format(intf_lo_addr_b2), + "ip address {}".format(BSR2_ADDR), + "ip pim", + ] + }, + } + result = apply_raw_config(tgen, raw_config) + assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) + + GROUP_ADDRESS = "225.200.100.100" + step("configuring static routes for both the BSR") + + next_hop_rp = topo["routers"]["f1"]["links"]["i1"]["ipv4"].split("/")[0] + next_hop_lhr = topo["routers"]["i1"]["links"]["l1"]["ipv4"].split("/")[0] + + input_dict = { + "f1": { + "static_routes": [ + {"network": BSR1_ADDR, "next_hop": NEXT_HOP1}, + {"network": BSR2_ADDR, "next_hop": NEXT_HOP2}, + ] + }, + "i1": { + "static_routes": [ + {"network": BSR1_ADDR, "next_hop": next_hop_rp}, + {"network": BSR2_ADDR, "next_hop": next_hop_rp}, + ] + }, + "l1": { + "static_routes": [ + {"network": BSR1_ADDR, "next_hop": next_hop_lhr}, + {"network": BSR2_ADDR, "next_hop": next_hop_lhr}, + ] + }, + } + + result = create_static_routes(tgen, input_dict) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # Verifying static routes are installed + for dut, _nexthop in zip(["i1", "l1"], [next_hop_rp, next_hop_lhr]): + input_routes = {dut: input_dict[dut]} + result = verify_rib( + tgen, "ipv4", dut, input_routes, _nexthop, protocol="static" + ) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + for bsr_add, next_hop in zip([BSR1_ADDR, BSR2_ADDR], [NEXT_HOP1, NEXT_HOP2]): + input_routes = { + "f1": {"static_routes": [{"network": bsr_add, "next_hop": next_hop}]} + } + result = verify_rib( + tgen, "ipv4", "f1", input_routes, next_hop, protocol="static" + ) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + # Use scapy to send pre-defined packet from senser to receiver + step("Send BSR packet from b1 to FHR") + result = scapy_send_bsr_raw_packet(tgen, topo, "b1", "f1", "packet9") + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + result = app_helper.run_join("r1", GROUP_ADDRESS, "l1") + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + do_countdown(5) + + dut = "l1" + step("Verify if b1 chosen as BSR in f1") + result = verify_pim_bsr(tgen, topo, "f1", BSR_IP_1) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + group = topo["routers"]["b1"]["bsm"]["bsr_packets"]["packet9"]["group"] + step("Find the elected rp from bsrp-info in LHR l1") + rp = find_rp_from_bsrp_info(tgen, dut, BSR_IP_1, group) + assert rp is not {}, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + step("Verify RP in LHR") + result = verify_pim_grp_rp_source(tgen, topo, dut, group, "BSR", rp[group]) + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + step("Send BSR packet from b2 to FHR") + result = scapy_send_bsr_raw_packet(tgen, topo, "b2", "f1", "packet3") + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + dut = "l1" + step("Verify if b2 chosen as BSR in f1") + result = verify_pim_bsr(tgen, topo, "f1", BSR_IP_2) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + step("Find the elected rp from bsrp-info in LHR l1") + rp = find_rp_from_bsrp_info(tgen, dut, BSR_IP_2, group) + assert rp is not {}, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + step("Verify RP in LHR") + result = verify_pim_grp_rp_source(tgen, topo, dut, group, "BSR", rp[group]) + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + step("Shut higher prefer BSR2 link f1 to b2") + + f1_b2_eth1 = topo["routers"]["f1"]["links"]["b2"]["interface"] + shutdown_bringup_interface(tgen, "f1", "f1-b2-eth1", False) + + step("clearing bsr to timeout old BSR") + clear_bsrp_data(tgen, topo) + + step("Send BSR packet from b1 and b2 to FHR") + result = scapy_send_bsr_raw_packet(tgen, topo, "b1", "f1", "packet9") + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + result = scapy_send_bsr_raw_packet(tgen, topo, "b2", "f1", "packet3") + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + step("sleeping for 3 sec to leran new packet") + do_countdown(3) + step("verify BSR1 has become preferred RP") + dut = "l1" + + step("Verify if b1 chosen as BSR in f1") + result = verify_pim_bsr(tgen, topo, "f1", BSR_IP_1) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + step("Find the elected rp from bsrp-info in LHR l1") + rp = find_rp_from_bsrp_info(tgen, dut, BSR_IP_1, group) + assert rp is not {}, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + step("Verify RP in LHR") + result = verify_pim_grp_rp_source(tgen, topo, dut, group, "BSR", rp[group]) + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + step("NoShut higher prefer BSR2 link f1 to b2") + step("sleeping for 3 min to leran new packet") + do_countdown(3) + f1_b2_eth1 = topo["routers"]["f1"]["links"]["b2"]["interface"] + shutdown_bringup_interface(tgen, "f1", "f1-b2-eth1", True) + step("verify BSR2 has become preferred RP") + dut = "l1" + + step("Send BSR packet from b1 and b2 to FHR") + result = scapy_send_bsr_raw_packet(tgen, topo, "b1", "f1", "packet9") + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + result = scapy_send_bsr_raw_packet(tgen, topo, "b2", "f1", "packet3") + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + step("Verify if b2 chosen as BSR in f1") + result = verify_pim_bsr(tgen, topo, "f1", BSR_IP_2) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + step("Find the elected rp from bsrp-info in LHR l1") + rp = find_rp_from_bsrp_info(tgen, dut, BSR_IP_2, group) + assert rp is not {}, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + step("Verify RP in LHR") + result = verify_pim_grp_rp_source(tgen, topo, dut, group, "BSR", rp[group]) + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + step("Clear BSM database before moving to next case") + clear_bsrp_data(tgen, topo) + + write_test_footer(tc_name) + + +def test_BSR_CRP_with_blackhole_address_p1(request): + """ + Verify BSR and RP updated correctly after configuring as black hole address + + Topology used: + b1_____ + | + | + s1-----f1-----i1-----l1----r1 + | + ______| + b2 + + b1 - BSR 1 + b2 - BSR 2 + s1 - Source + f1 - FHR + i1 - Intermediate Router (also RP) + r1 - Receiver + """ + + tgen = get_topogen() + tc_name = request.node.name + write_test_header(tc_name) + + # Don"t run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + app_helper.stop_all_hosts() + clear_mroute(tgen) + reset_config_on_routers(tgen) + clear_pim_interface_traffic(tgen, topo) + + step("pre-configure BSM packet") + step("Configure cisco-1 as BSR1 1.1.2.7") + result = pre_config_to_bsm( + tgen, topo, tc_name, "b1", "s1", "r1", "f1", "i1", "l1", "packet1" + ) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + step("configuring loopback address of b1 and b2 as BSR") + intf_lo_addr_b1 = topo["routers"]["b1"]["links"]["lo"]["ipv4"] + + raw_config = { + "b1": { + "raw_config": [ + "interface lo", + "no ip address {}".format(intf_lo_addr_b1), + "ip address {}".format(BSR1_ADDR), + "ip pim", + ] + } + } + result = apply_raw_config(tgen, raw_config) + assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result) + + GROUP_ADDRESS = "225.200.100.100" + step("configuring static routes for both the BSR") + + next_hop_rp = topo["routers"]["f1"]["links"]["i1"]["ipv4"].split("/")[0] + next_hop_lhr = topo["routers"]["i1"]["links"]["l1"]["ipv4"].split("/")[0] + next_hop_fhr = topo["routers"]["i1"]["links"]["f1"]["ipv4"].split("/")[0] + CRP = topo["routers"]["b1"]["bsm"]["bsr_packets"]["packet9"]["candidate_rp"] + + input_dict = { + "i1": {"static_routes": [{"network": BSR1_ADDR, "next_hop": next_hop_rp}]}, + "l1": {"static_routes": [{"network": BSR1_ADDR, "next_hop": next_hop_lhr}]}, + "f1": { + "static_routes": [ + {"network": CRP, "next_hop": next_hop_fhr, "delete": True} + ] + }, + } + + result = create_static_routes(tgen, input_dict) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # Verifying static routes are installed + for dut, _nexthop in zip(["i1", "l1"], [next_hop_rp, next_hop_lhr]): + input_routes = {dut: input_dict[dut]} + result = verify_rib( + tgen, "ipv4", dut, input_routes, _nexthop, protocol="static" + ) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + input_routes = { + "f1": {"static_routes": [{"network": CRP, "next_hop": next_hop_fhr}]} + } + result = verify_rib( + tgen, "ipv4", "f1", input_routes, protocol="static", expected=False + ) + assert ( + result is not True + ), "Testcase {} : Failed \n " "Route is still present \n Error {}".format( + tc_name, result + ) + + # Use scapy to send pre-defined packet from senser to receiver + + group = topo["routers"]["b1"]["bsm"]["bsr_packets"]["packet9"]["group"] + step("waiting for BSR to timeout before configuring blackhole route") + clear_bsrp_data(tgen, topo) + + step("Configure black-hole address for BSR and candidate RP") + input_dict = { + "f1": { + "static_routes": [{"network": [BSR1_ADDR, CRP], "next_hop": "blackhole"}] + } + } + + result = create_static_routes(tgen, input_dict) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # Verifying static routes are installed + result = verify_rib(tgen, "ipv4", "f1", input_dict, protocol="static") + assert result is True, "Testcase {} : Failed \n Error {}".format(tc_name, result) + + intf_f1_i1 = topo["routers"]["f1"]["links"]["i1"]["interface"] + step("Verify bsm transit count is not increamented" "show ip pim interface traffic") + state_dict = {"f1": {intf_f1_i1: ["bsmTx"]}} + + state_before = get_pim_interface_traffic(tgen, state_dict) + assert isinstance( + state_before, dict + ), "Testcase{} : Failed \n state_before is not dictionary \n Error: {}".format( + tc_name, result + ) + + step("Sending BSR after Configure black hole address for BSR and candidate RP") + step("Send BSR packet from b1 to FHR") + result = scapy_send_bsr_raw_packet(tgen, topo, "b1", "f1", "packet9") + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + dut = "l1" + step("Find the elected rp from bsrp-info in LHR l1") + rp = find_rp_from_bsrp_info(tgen, dut, BSR_IP_1, group) + assert rp is not {}, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + step("Verify if b1 chosen as BSR in l1") + result = verify_pim_bsr(tgen, topo, "l1", BSR_IP_1, expected=False) + assert ( + result is not True + ), "Testcase {} : Failed \n " "b1 is not chosen as BSR in l1 \n Error: {}".format( + tc_name, result + ) + + state_after = get_pim_interface_traffic(tgen, state_dict) + assert isinstance( + state_after, dict + ), "Testcase{} : Failed \n state_before is not dictionary \n Error: {}".format( + tc_name, result + ) + + result = verify_state_incremented(state_before, state_after) + assert result is not True, "Testcase{} : Failed Error: {}".format(tc_name, result) + + step("Remove black-hole address for BSR and candidate RP") + input_dict = { + "f1": { + "static_routes": [ + {"network": [BSR1_ADDR, CRP], "next_hop": "blackhole", "delete": True}, + {"network": BSR1_ADDR, "next_hop": NEXT_HOP1}, + ] + } + } + + result = create_static_routes(tgen, input_dict) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # Verifying static routes are installed + input_dict = { + "f1": {"static_routes": [{"network": BSR1_ADDR, "next_hop": NEXT_HOP1}]} + } + result = verify_rib(tgen, "ipv4", "f1", input_dict, NEXT_HOP1, protocol="static") + assert result is True, "Testcase {} : Failed \n Error {}".format(tc_name, result) + + input_dict = { + "f1": { + "static_routes": [ + {"network": [BSR1_ADDR, CRP], "next_hop": "blackhole", "delete": True} + ] + } + } + result = verify_rib( + tgen, "ipv4", "f1", input_dict, protocol="static", expected=False + ) + assert result is not True, ( + "Testcase {} : Failed \n " + "Routes:[{}, {}] are still present \n Error {}".format( + tc_name, BSR1_ADDR, CRP, result + ) + ) + + step("Sending BSR after removing black-hole address for BSR and candidate RP") + step("Send BSR packet from b1 to FHR") + result = scapy_send_bsr_raw_packet(tgen, topo, "b1", "f1", "packet9") + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + step("Verify if b1 chosen as BSR in f1") + result = verify_pim_bsr(tgen, topo, "f1", BSR_IP_1) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + dut = "l1" + group = topo["routers"]["b1"]["bsm"]["bsr_packets"]["packet9"]["group"] + step("Find the elected rp from bsrp-info in LHR l1") + rp = find_rp_from_bsrp_info(tgen, dut, BSR_IP_1, group) + assert rp is not {}, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + step("Verify RP in LHR l1") + result = verify_pim_grp_rp_source(tgen, topo, dut, group, "BSR", rp[group]) + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + step("clear BSM database before moving to next case") + clear_bsrp_data(tgen, topo) + + write_test_footer(tc_name) + + +def test_new_router_fwd_p0(request): + """ + 1. Verify when new router added to the topology, FRR node will send + unicast BSM to new router + 2. Verify if no forwarding bit is set , FRR is not forwarding the + BSM to other PIM nbrs + 3. Verify multicast BSM is sent to new router when unicast BSM is disabled + + Topology used: + b1_____ + | + | + s1-----f1-----i1-----l1----r1 + | + ______| + b2 + + b1 - BSR 1 + b2 - BSR 2 + s1 - Source + f1 - FHR + i1 - Intermediate Router (also RP) + r1 - Receiver + + """ + + tgen = get_topogen() + tc_name = request.node.name + write_test_header(tc_name) + + # Don"t run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + app_helper.stop_all_hosts() + clear_mroute(tgen) + reset_config_on_routers(tgen) + clear_pim_interface_traffic(tgen, topo) + + result = pre_config_to_bsm( + tgen, topo, tc_name, "b1", "s1", "r1", "f1", "i1", "l1", "packet1" + ) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + result = pre_config_to_bsm( + tgen, topo, tc_name, "b2", "s1", "r1", "f1", "i1", "l1", "packet1" + ) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + GROUP_ADDRESS = "225.1.1.1" + + # Use scapy to send pre-defined packet from senser to receiver + result = scapy_send_bsr_raw_packet(tgen, topo, "b1", "f1", "packet1") + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + bsr_ip = topo["routers"]["b1"]["bsm"]["bsr_packets"]["packet1"]["bsr"].split("/")[0] + time.sleep(1) + + result = app_helper.run_join("r1", GROUP_ADDRESS, "l1") + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + # Verify bsr state in FHR + step("Verify if b1 chosen as BSR in f1") + result = verify_pim_bsr(tgen, topo, "f1", bsr_ip) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # Verify bsr state in i1 + step("Verify if b1 chosen as BSR in i1") + result = verify_pim_bsr(tgen, topo, "i1", bsr_ip) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # Verify ip mroute + iif = "l1-i1-eth0" + src_addr = "*" + oil = "l1-r1-eth1" + + step("Verify mroute populated on l1") + result = verify_mroutes(tgen, "l1", src_addr, GROUP_ADDRESS, iif, oil) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + # Reload i1 and l1 + step("Reloading i1 and l1. Stop both. bring up l1 and then i1") + stop_router(tgen, "i1") + start_router(tgen, "i1") + stop_router(tgen, "l1") + start_router(tgen, "l1") + + # Verify bsr state in i1 + step("Verify BSR in i1 after restart while no new bsm sent from b1") + result = verify_pim_bsr(tgen, topo, "i1", bsr_ip) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # Verify bsr state in l1 + step("Verify no BSR in l1 as i1 would not forward the no-forward bsm") + result = verify_pim_bsr(tgen, topo, "l1", bsr_ip, expected=False) + assert result is not True, ( + "Testcase {} : Failed \n " + "BSR data is present after no-forward bsm also \n Error: {}".format( + tc_name, result + ) + ) + + # unconfigure unicast bsm on f1-i1-eth2 + step("unconfigure unicast bsm on f1-i1-eth2, will forward with only mcast") + enable_disable_pim_unicast_bsm(tgen, "f1", "f1-i1-eth2", enable=False) + + # Reboot i1 to check if still bsm received with multicast address + step("Reboot i1 to check if still bsm received with multicast address") + stop_router(tgen, "i1") + start_router(tgen, "i1") + + result = app_helper.run_join("r1", GROUP_ADDRESS, "l1") + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + # Verify again if BSR is installed from bsm forwarded by f1 + step("Verify again if BSR is installed from bsm forwarded by f1") + result = verify_pim_bsr(tgen, topo, "i1", bsr_ip) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # Use scapy to send pre-defined packet from senser to receiver + step("Send another BSM packet from b1 which will reach l1(LHR)") + result = scapy_send_bsr_raw_packet(tgen, topo, "b1", "f1", "packet2") + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + do_countdown(5) + + step("Verify again if BSR is installed from bsm forwarded by i1") + result = verify_pim_bsr(tgen, topo, "l1", bsr_ip) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # Verify ip mroute populated again + step("Verify mroute again on l1 (lhr)") + result = verify_mroutes(tgen, "l1", src_addr, GROUP_ADDRESS, iif, oil) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("clear BSM database before moving to next case") + clear_bsrp_data(tgen, topo) + + write_test_footer(tc_name) + + +def test_int_bsm_config_p1(request): + """ + 1. Verify BSM arrived on non bsm capable interface is dropped and + not processed + 2. Verify group to RP info updated correctly in FRR node, after shut and + no-shut of BSM enable interfaces + + Topology used: + b1_____ + | + | + s1-----f1-----i1-----l1----r1 + | + ______| + b2 + + b1 - BSR 1 + b2 - BSR 2 + s1 - Source + f1 - FHR + i1 - Intermediate Router (also RP) + r1 - Receiver + + """ + + tgen = get_topogen() + tc_name = request.node.name + write_test_header(tc_name) + + # Don"t run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + app_helper.stop_all_hosts() + clear_mroute(tgen) + reset_config_on_routers(tgen) + clear_pim_interface_traffic(tgen, topo) + + result = pre_config_to_bsm( + tgen, topo, tc_name, "b1", "s1", "r1", "f1", "i1", "l1", "packet1" + ) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + result = pre_config_to_bsm( + tgen, topo, tc_name, "b2", "s1", "r1", "f1", "i1", "l1", "packet1" + ) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + GROUP_ADDRESS = "225.1.1.1" + + bsr_ip = topo["routers"]["b1"]["bsm"]["bsr_packets"]["packet1"]["bsr"].split("/")[0] + time.sleep(1) + + result = app_helper.run_join("r1", GROUP_ADDRESS, "l1") + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + # Use scapy to send pre-defined packet from senser to receiver + step("Send BSM packet from b1") + result = scapy_send_bsr_raw_packet(tgen, topo, "b1", "f1", "packet1") + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # Verify bsr state in i1 + step("Verify if b1 is chosen as BSR in i1") + result = verify_pim_bsr(tgen, topo, "i1", bsr_ip) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # check if mroute installed + step("check if mroute installed in i1") + iif = "lo" + src_addr = "*" + oil = "i1-l1-eth1" + + result = verify_mroutes(tgen, "i1", src_addr, GROUP_ADDRESS, iif, oil) + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + # wait till bsm rp age out + step("wait till bsm rp age out") + clear_bsrp_data(tgen, topo) + + # check if mroute uninstalled because of rp age out + step("check if mroute uninstalled because of rp age out in i1") + result = verify_mroutes( + tgen, "i1", src_addr, GROUP_ADDRESS, iif, oil, expected=False + ) + assert ( + result is not True + ), "Testcase {} : Failed \n " "Mroutes are still present \n Error: {}".format( + tc_name, result + ) + + # unconfigure bsm processing on f1 on f1-i1-eth2 + step("unconfigure bsm processing on f1 in f1-i1-eth2, will drop bsm") + result = enable_disable_pim_bsm(tgen, "f1", "f1-i1-eth2", enable=False) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # Use scapy to send pre-defined packet from senser to receiver + step("Send BSM packet from b1") + result = scapy_send_bsr_raw_packet(tgen, topo, "b1", "f1", "packet1") + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # Verify bsr state in FHR + step("Verify if b1 chosen as BSR in f1") + result = verify_pim_bsr(tgen, topo, "f1", bsr_ip) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # Verify bsr state in i1 + step("Verify if b1 is not chosen as BSR in i1") + result = verify_pim_bsr(tgen, topo, "i1", bsr_ip, expected=False) + assert ( + result is not True + ), "Testcase {} : Failed \n " "b1 is chosen as BSR in i1 \n Error: {}".format( + tc_name, result + ) + + # check if mroute still not installed because of rp not available + step("check if mroute still not installed because of rp not available") + result = verify_mroutes( + tgen, "i1", src_addr, GROUP_ADDRESS, iif, oil, expected=False + ) + assert result is not True, ( + "Testcase {} : Failed \n " + "mroute installed but rp not available \n Error: {}".format(tc_name, result) + ) + + # configure bsm processing on i1 on f1-i1-eth2 + step("configure bsm processing on f1 in f1-i1-eth2, will accept bsm") + result = enable_disable_pim_bsm(tgen, "f1", "f1-i1-eth2", enable=True) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # Use scapy to send pre-defined packet from senser to receiver + step("Send BSM packet again from b1") + result = scapy_send_bsr_raw_packet(tgen, topo, "b1", "f1", "packet2") + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # Verify again if BSR is installed from bsm forwarded by f1 + step("Verify again if BSR is installed from bsm forwarded by f1") + result = verify_pim_bsr(tgen, topo, "i1", bsr_ip) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # verify ip mroute populated + step("Verify ip mroute") + result = verify_mroutes(tgen, "i1", src_addr, GROUP_ADDRESS, iif, oil) + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + # Shut/No shut the bsm rpf interface and check mroute on lhr(l1) + step("Shut/No shut the bsm rpf interface and check mroute on lhr(l1)") + intf = "l1-i1-eth0" + shutdown_bringup_interface(tgen, "l1", intf, False) + shutdown_bringup_interface(tgen, "l1", intf, True) + + iif = "l1-i1-eth0" + oil = "l1-r1-eth1" + + result = verify_mroutes(tgen, "l1", src_addr, GROUP_ADDRESS, iif, oil) + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + step("clear BSM database before moving to next case") + clear_bsrp_data(tgen, topo) + + write_test_footer(tc_name) + + +def test_static_rp_override_p1(request): + """ + Verify static RP is preferred over BSR + + Topology used: + b1_____ + | + | + s1-----f1-----i1-----l1----r1 + | + ______| + b2 + + b1 - BSR 1 + b2 - BSR 2 + s1 - Source + f1 - FHR + i1 - Intermediate Router (also RP) + r1 - Receiver + + """ + + tgen = get_topogen() + tc_name = request.node.name + write_test_header(tc_name) + + # Don"t run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + app_helper.stop_all_hosts() + clear_mroute(tgen) + reset_config_on_routers(tgen) + clear_pim_interface_traffic(tgen, topo) + + result = pre_config_to_bsm( + tgen, topo, tc_name, "b1", "s1", "r1", "f1", "i1", "l1", "packet1" + ) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + result = pre_config_to_bsm( + tgen, topo, tc_name, "b2", "s1", "r1", "f1", "i1", "l1", "packet1" + ) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + GROUP_ADDRESS = "225.1.1.1" + # Use scapy to send pre-defined packet from senser to receiver + result = scapy_send_bsr_raw_packet(tgen, topo, "b1", "f1", "packet1") + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + bsr_ip = topo["routers"]["b1"]["bsm"]["bsr_packets"]["packet1"]["bsr"].split("/")[0] + time.sleep(1) + + result = app_helper.run_join("r1", GROUP_ADDRESS, "l1") + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + # Verify bsr state in FHR + result = verify_pim_bsr(tgen, topo, "f1", bsr_ip) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # Check igmp groups + step("Verify IGMP groups in LHR") + dut = "l1" + intf = "l1-r1-eth1" + result = verify_igmp_groups(tgen, dut, intf, GROUP_ADDRESS) + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + group = "225.1.1.1/32" + + # Find the elected rp from bsrp-info + step("Find the elected rp from bsrp-info in LHR l1") + rp = find_rp_from_bsrp_info(tgen, dut, bsr_ip, group) + assert rp is not {}, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # Check RP detail in LHR + step("Verify that BS RP in LHR l1") + result = verify_pim_grp_rp_source(tgen, topo, dut, group, "BSR", rp[group]) + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + iif = "l1-i1-eth0" + # Verify upstream rpf for 225.1.1.1 is chosen as rp1 + step("Verify upstream rpf for 225.1.1.1 is chosen as bsrp") + result = verify_pim_upstream_rpf(tgen, topo, dut, iif, GROUP_ADDRESS, rp[group]) + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + # Configure a static rp for the group 225.1.1.1/32 + step("Configure a static rp 33.33.33.33 for the group 225.1.1.1/32 in l1") + input_dict = { + "l1": { + "pim": { + "rp": [ + { + "rp_addr": "33.33.33.33", + "group_addr_range": ["225.1.1.1/32"], + } + ] + } + } + } + result = create_pim_config(tgen, topo, input_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + # Verify that static rp is configured over bsrp + static_rp = "33.33.33.33" + step("Verify that Static RP in LHR in l1") + result = verify_pim_grp_rp_source(tgen, topo, dut, group, "Static", static_rp) + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + # Verify if upstream also reflects the static rp + step("Verify upstream rpf for 225.1.1.1 is chosen as static in l1") + result = verify_pim_upstream_rpf(tgen, topo, dut, iif, GROUP_ADDRESS, static_rp) + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + # delete static rp for the group 225.1.1.1/32 + step("Delete static rp 33.33.33.33 for the group 225.1.1.1/32 in l1") + input_dict = { + "l1": { + "pim": { + "rp": [ + { + "rp_addr": "33.33.33.33", + "group_addr_range": ["225.1.1.1/32"], + "delete": True, + } + ] + } + } + } + result = create_pim_config(tgen, topo, input_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + # Verify if bsrp is installed back for the group 225.1.1.1/32 + step("Verify that BS RP in installed in LHR") + result = verify_pim_grp_rp_source(tgen, topo, dut, group, "BSR", rp[group]) + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + # Verify upstream rpf for 225.1.1.1 is chosen as bsrp + step("Verify upstream rpf for 225.1.1.1 is chosen as bsrp in l1") + result = verify_pim_upstream_rpf(tgen, topo, dut, iif, GROUP_ADDRESS, rp[group]) + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + step("clear BSM database before moving to next case") + clear_bsrp_data(tgen, topo) + + write_test_footer(tc_name) + + +def test_bsmp_stress_add_del_restart_p2(request): + """ + 1. Verify adding/deleting the group to rp mapping and RP priority + multiple times + 2. Verify RP and (*,G) detail after PIM process restart on FRR node + + Topology used: + b1_____ + | + | + s1-----f1-----i1-----l1----r1 + | + ______| + b2 + + b1 - BSR 1 + b2 - BSR 2 + s1 - Source + f1 - FHR + i1 - Intermediate Router (also RP) + r1 - Receiver + + """ + + tgen = get_topogen() + tc_name = request.node.name + write_test_header(tc_name) + + # Don"t run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + app_helper.stop_all_hosts() + clear_mroute(tgen) + reset_config_on_routers(tgen) + clear_pim_interface_traffic(tgen, topo) + + result = pre_config_to_bsm( + tgen, topo, tc_name, "b1", "s1", "r1", "f1", "i1", "l1", "packet1" + ) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + result = pre_config_to_bsm( + tgen, topo, tc_name, "b2", "s1", "r1", "f1", "i1", "l1", "packet1" + ) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + GROUP_ADDRESS = "225.1.1.1" + + # Use scapy to send pre-defined packet from senser to receiver + step("Send BSR packet from b1 to FHR") + result = scapy_send_bsr_raw_packet(tgen, topo, "b1", "f1", "packet1") + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + bsr_ip = topo["routers"]["b1"]["bsm"]["bsr_packets"]["packet1"]["bsr"].split("/")[0] + time.sleep(1) + + result = app_helper.run_join("r1", GROUP_ADDRESS, "l1") + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + # Verify bsr state in FHR + step("Verify if b1 is chosen as bsr in f1") + result = verify_pim_bsr(tgen, topo, "f1", bsr_ip) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + dut = "l1" + group = "225.1.1.0/24" + # Find the elected rp from bsrp-info + step("Find the elected rp from bsrp-info in LHR l1") + rp1 = find_rp_from_bsrp_info(tgen, dut, bsr_ip, group) + assert rp1 is not {}, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # Check RP detail in LHR + step("Verify RP in LHR l1") + result = verify_pim_grp_rp_source(tgen, topo, dut, group, "BSR", rp1[group]) + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + # Send BSR packet from b1 after deleting high prio rp for 225.1.1.0/24 + step("Send BSM from b1 to FHR deleting high prio rp for 225.1.1.0/24") + result = scapy_send_bsr_raw_packet(tgen, topo, "b1", "f1", "packet6") + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # Find the elected rp from bsrp-info + step("Find the elected rp from bsrp-info in LHR l1") + rp2 = find_rp_from_bsrp_info(tgen, dut, bsr_ip, group) + assert rp2 is not {}, "Testcase {} :Failed \n Error {}".format(tc_name, result) + logger.info("RP old: %s RP2 new: %s", rp1[group], rp2[group]) + + # Verify is the rp is different now + assert rp1[group] != rp2[group], "Testcase {} :Failed \n Error {}".format( + tc_name, result + ) + + rp_add1 = rp1[group] + rp_add2 = rp2[group] + + # Verify if that rp is installed + step("Verify new RP in LHR installed") + result = verify_pim_grp_rp_source(tgen, topo, dut, group, "BSR", rp_add2) + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + step("Change rp priority in the bsm and send multiple times") + + for i in range(4): + # Send BSR pkt from b1 after putting back high prio rp for 225.1.1.0/24 + step("Send BSM from b1 to FHR put back high prio rp for 225.1.1.0/24") + result = scapy_send_bsr_raw_packet(tgen, topo, "b1", "f1", "packet1") + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # Find the elected rp from bsrp-info + step("Find the elected rp from bsrp-info in LHR") + rp2 = find_rp_from_bsrp_info(tgen, dut, bsr_ip, group) + assert rp2 is not {}, "Testcase {} :Failed \n Error : RP not Found".format( + tc_name + ) + + # Verify is the rp is different now + step("Verify now old RP is elected again") + assert ( + rp_add1 == rp2[group] + ), "Testcase {} :Failed \n Error : rp expected {} rp received {}".format( + tc_name, rp_add1, rp2[group] + ) + + # Verify if that rp is installed + step("Verify old RP in LHR installed") + result = verify_pim_grp_rp_source(tgen, topo, dut, group, "BSR", rp_add1) + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + # Send BSR packet from b1 after deleting high prio rp for 225.1.1.0/24 + step("Send BSM from b1 to FHR deleting high prio rp for 225.1.1.0/24") + result = scapy_send_bsr_raw_packet(tgen, topo, "b1", "f1", "packet6") + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # Verify if that rp is installed + step("Verify new RP(rp2) in LHR installed") + result = verify_pim_grp_rp_source(tgen, topo, dut, group, "BSR", rp_add2) + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + # Restart pimd + step("Restarting pimd in LHR") + kill_router_daemons(tgen, "l1", ["pimd"]) + start_router_daemons(tgen, "l1", ["pimd"]) + logger.info("Restarting done") + + # Verify if that rp is installed + step("Verify old RP in LHR installed") + result = verify_pim_grp_rp_source(tgen, topo, dut, group, "BSR", rp_add2) + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + # Send IGMP join to LHR + result = app_helper.run_join("r1", GROUP_ADDRESS, "l1") + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + do_countdown(5) + + # VErify mroute created after pimd restart + step("VErify mroute created after pimd restart") + iif = "l1-i1-eth0" + src_addr = "*" + oil = "l1-r1-eth1" + result = verify_mroutes(tgen, "l1", src_addr, GROUP_ADDRESS, iif, oil) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + write_test_footer(tc_name) + + +def test_BSM_timeout_p0(request): + """ + Verify BSM timeout on FRR1 + Verify RP state in FRR1 after Bootstrap timer expiry + + Topology used: + b1_____ + | + | + s1-----f1-----i1-----l1----r1 + | + ______| + b2 + + b1 - BSR 1 + b2 - BSR 2 + s1 - Source + f1 - FHR + i1 - Intermediate Router (also RP) + r1 - Receiver + + """ + + tgen = get_topogen() + tc_name = request.node.name + write_test_header(tc_name) + + # Don"t run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + app_helper.stop_all_hosts() + clear_mroute(tgen) + reset_config_on_routers(tgen) + clear_pim_interface_traffic(tgen, topo) + + result = pre_config_to_bsm( + tgen, topo, tc_name, "b1", "s1", "r1", "f1", "i1", "l1", "packet1" + ) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + result = pre_config_to_bsm( + tgen, topo, tc_name, "b2", "s1", "r1", "f1", "i1", "l1", "packet1" + ) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + GROUP_ADDRESS = "225.1.1.1" + + bsr_ip = topo["routers"]["b1"]["bsm"]["bsr_packets"]["packet1"]["bsr"].split("/")[0] + + # Use scapy to send pre-defined packet from senser to receiver + step("send BSR packet from b1") + result = scapy_send_bsr_raw_packet(tgen, topo, "b1", "f1", "packet1") + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # Send IGMP join for group 225.1.1.1 from receiver + result = app_helper.run_join("r1", GROUP_ADDRESS, "l1") + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + # Verify bsr state in FHR + step("Verify bsr state in FHR f1") + result = verify_pim_bsr(tgen, topo, "f1", bsr_ip) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # Verify ip mroute in LHR + step(" Verify ip mroute in LHR l1") + dut = "l1" + iif = "l1-i1-eth0" + src_addr = "*" + oil = "l1-r1-eth1" + result = verify_mroutes(tgen, dut, src_addr, GROUP_ADDRESS, iif, oil) + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + # Verify join state and join timer + step("Verify join state and join timer in lhr l1") + result = verify_join_state_and_timer(tgen, dut, iif, src_addr, GROUP_ADDRESS) + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + # Verify upstream IIF interface + step("Verify upstream IIF interface in LHR l1") + result = verify_upstream_iif(tgen, dut, iif, src_addr, GROUP_ADDRESS) + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + # Verify RP mapping + dut = "l1" + group = "225.1.1.1/32" + step("Verify RP mapping in LHR l1") + rp = find_rp_from_bsrp_info(tgen, dut, bsr_ip, group) + assert rp != {}, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + logger.info("Waiting for 130 secs to check BSR timeout") + clear_bsrp_data(tgen, topo) + + # Verify if bsr has aged out + step("Verify if bsr has aged out in f1") + no_bsr_ip = "0.0.0.0" + result = verify_pim_bsr(tgen, topo, "f1", no_bsr_ip) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + result = verify_pim_grp_rp_source( + tgen, topo, "f1", group, rp_source="BSR", expected=False + ) + + assert ( + result is not True + ), "Testcase {} : Failed \n " "bsr has not aged out in f1 \n Error: {}".format( + tc_name, result + ) + + # Verify RP mapping removed after hold timer expires + group = "225.1.1.1/32" + step("Verify RP mapping removed after hold timer expires in l1") + rp = find_rp_from_bsrp_info(tgen, dut, bsr_ip, group) + assert rp == {}, "Testcase {} :Failed \n Error : RP found when not expected".format( + tc_name + ) + + # Verify iif is unknown after RP timeout + step("Verify iif is unknown after RP timeout in l1") + iif = "Unknown" + result = verify_upstream_iif( + tgen, dut, iif, src_addr, GROUP_ADDRESS, joinState="NotJoined" + ) + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + # Verify join state and join timer + step("Verify join state and join timer in l1") + iif = "l1-i1-eth0" + result = verify_join_state_and_timer( + tgen, dut, iif, src_addr, GROUP_ADDRESS, expected=False + ) + assert result is not True, ( + "Testcase {} : Failed \n " + "join state is up and join timer is running in l1 \n Error: {}".format( + tc_name, result + ) + ) + + # Verify ip mroute is not installed + step("Verify mroute not installed in l1") + result = verify_mroutes( + tgen, dut, src_addr, GROUP_ADDRESS, iif, oil, expected=False + ) + assert ( + result is not True + ), "Testcase {} : Failed \n " "mroute installed in l1 \n Error: {}".format( + tc_name, result + ) + + step("clear BSM database before moving to next case") + clear_bsrp_data(tgen, topo) + + write_test_footer(tc_name) + + +def test_iif_join_state_p0(request): + """ + 1. Verify upstream interfaces(IIF) and join state are updated properly + after BSM received for FRR + 2. Verify IIF and OIL in "show ip pim state" updated properly after + BSM received + + Topology used: + b1_____ + | + | + s1-----f1-----i1-----l1----r1 + | + ______| + b2 + + b1 - BSR 1 + b2 - BSR 2 + s1 - Source + f1 - FHR + i1 - Intermediate Router (also RP) + r1 - Receiver + + """ + + tgen = get_topogen() + tc_name = request.node.name + write_test_header(tc_name) + + # Don"t run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + app_helper.stop_all_hosts() + clear_mroute(tgen) + reset_config_on_routers(tgen) + clear_pim_interface_traffic(tgen, topo) + + result = pre_config_to_bsm( + tgen, topo, tc_name, "b1", "s1", "r1", "f1", "i1", "l1", "packet1" + ) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + result = pre_config_to_bsm( + tgen, topo, tc_name, "b2", "s1", "r1", "f1", "i1", "l1", "packet1" + ) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + GROUP_ADDRESS = "225.1.1.1" + + # Use scapy to send pre-defined packet from senser to receiver + result = scapy_send_bsr_raw_packet(tgen, topo, "b1", "f1", "packet1") + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + bsr_ip = topo["routers"]["b1"]["bsm"]["bsr_packets"]["packet1"]["bsr"].split("/")[0] + time.sleep(1) + + result = app_helper.run_join("r1", GROUP_ADDRESS, "l1") + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + # Verify bsr state in FHR + result = verify_pim_bsr(tgen, topo, "f1", bsr_ip) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # Check igmp groups + step("Verify IGMP groups in LHR l1") + dut = "l1" + intf = "l1-r1-eth1" + result = verify_igmp_groups(tgen, dut, intf, GROUP_ADDRESS) + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + group = "225.1.1.1/32" + + # Find the elected rp from bsrp-info + step("Find the elected rp from bsrp-info in LHR l1") + rp = find_rp_from_bsrp_info(tgen, dut, bsr_ip, group) + assert rp is not {}, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # Check RP detail in LHR + step("Verify RP in LHR l1") + result = verify_pim_grp_rp_source(tgen, topo, dut, group, "BSR", rp[group]) + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + # Verify join state and join timer + step("Verify join state and join timer l1") + iif = "l1-i1-eth0" + src_addr = "*" + result = verify_join_state_and_timer(tgen, dut, iif, src_addr, GROUP_ADDRESS) + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + # Verify upstream IIF interface + step("Verify upstream IIF interface l1") + result = verify_upstream_iif(tgen, dut, iif, src_addr, GROUP_ADDRESS) + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + # Verify IIF/OIL in pim state + oil = "l1-r1-eth1" + result = verify_pim_state(tgen, dut, iif, oil, GROUP_ADDRESS) + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + # Verify ip mroute + src_addr = "*" + step("Verify ip mroute in l1") + result = verify_mroutes(tgen, dut, src_addr, GROUP_ADDRESS, iif, oil) + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + # Make RP unreachanble in LHR + step("Make RP unreachanble in LHR l1") + rp = find_rp_from_bsrp_info(tgen, dut, bsr_ip, group) + assert rp is not {}, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + next_hop_lhr = topo["routers"]["i1"]["links"]["l1"]["ipv4"].split("/")[0] + + rp_ip = rp[group] + "/32" + input_dict = { + "l1": { + "static_routes": [ + {"network": rp_ip, "next_hop": next_hop_lhr, "delete": True} + ] + } + } + result = create_static_routes(tgen, input_dict) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # Verifying static routes are installed + result = verify_rib( + tgen, "ipv4", "l1", input_dict, protocol="static", expected=False + ) + assert ( + result is not True + ), "Testcase {} : Failed \n " "Routes:{} are still present \n Error {}".format( + tc_name, rp_ip, result + ) + + # Check RP unreachable + step("Check RP unreachability") + iif = "Unknown" + result = verify_upstream_iif( + tgen, dut, iif, src_addr, GROUP_ADDRESS, joinState="NotJoined" + ) + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + # Verify that it is not installed + step("Verify that it is not installed") + iif = "<iif?>" + result = verify_pim_state(tgen, dut, iif, oil, GROUP_ADDRESS, installed_fl=0) + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + # Verify mroute not installed + step("Verify mroute not installed") + result = verify_mroutes( + tgen, dut, src_addr, GROUP_ADDRESS, iif, oil, expected=False + ) + assert ( + result is not True + ), "Testcase {} : Failed \n " "mroute installed in l1 \n Error: {}".format( + tc_name, result + ) + + # Add back route for RP to make it reachable + step("Add back route for RP to make it reachable") + input_dict = { + "l1": { + "static_routes": [ + { + "network": rp_ip, + "next_hop": next_hop_lhr, + } + ] + } + } + result = create_static_routes(tgen, input_dict) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # Verifying static routes are installed + result = verify_rib(tgen, "ipv4", "l1", input_dict, next_hop_lhr, protocol="static") + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + # Verify that (*,G) installed in mroute again + iif = "l1-i1-eth0" + result = verify_mroutes(tgen, dut, src_addr, GROUP_ADDRESS, iif, oil) + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + step("clear BSM database before moving to next case") + clear_bsrp_data(tgen, topo) + + write_test_footer(tc_name) + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) |