summaryrefslogtreecommitdiffstats
path: root/tests/topotests/multicast_pim_bsm_topo1
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 09:53:30 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 09:53:30 +0000
commit2c7cac91ed6e7db0f6937923d2b57f97dbdbc337 (patch)
treec05dc0f8e6aa3accc84e3e5cffc933ed94941383 /tests/topotests/multicast_pim_bsm_topo1
parentInitial commit. (diff)
downloadfrr-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.json238
-rw-r--r--tests/topotests/multicast_pim_bsm_topo1/test_mcast_pim_bsmp_01.py1787
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))