From 6f86321528112b7ff40abf4a9add3f34c0880410 Mon Sep 17 00:00:00 2001 From: Kuldeep Kashyap Date: Tue, 3 Nov 2020 09:21:35 +0000 Subject: [PATCH] tests: Add multicast-pim-bsm-topo2 suite 1. Added 7 testcases to verify PIM BSM functionality. Here we have used Scapy to send raw packet, generated using Cisco and FRR. Raw packets are kept in Signed-off-by: Kuldeep Kashyap --- .../mcast_pim_bsmp_02.json | 238 ++++ .../test_mcast_pim_bsmp_02.py | 1115 +++++++++++++++++ 2 files changed, 1353 insertions(+) create mode 100644 tests/topotests/multicast-pim-bsm-topo2/mcast_pim_bsmp_02.json create mode 100644 tests/topotests/multicast-pim-bsm-topo2/test_mcast_pim_bsmp_02.py diff --git a/tests/topotests/multicast-pim-bsm-topo2/mcast_pim_bsmp_02.json b/tests/topotests/multicast-pim-bsm-topo2/mcast_pim_bsmp_02.json new file mode 100644 index 0000000000..14cb0bee1d --- /dev/null +++ b/tests/topotests/multicast-pim-bsm-topo2/mcast_pim_bsmp_02.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-topo2/test_mcast_pim_bsmp_02.py b/tests/topotests/multicast-pim-bsm-topo2/test_mcast_pim_bsmp_02.py new file mode 100644 index 0000000000..459afb5a02 --- /dev/null +++ b/tests/topotests/multicast-pim-bsm-topo2/test_mcast_pim_bsmp_02.py @@ -0,0 +1,1115 @@ +#!/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 (*,G) mroute detail on FRR router after BSM rp installed +2. Verify group to RP updated correctly on FRR router, when BSR advertising + the overlapping group address +3. Verify group to RP info is updated correctly, when BSR advertising the + same RP with different priority +4. Verify group to RP mapping in FRR node when 2 BSR are present in the network + and both are having same BSR priority +5. Verify RP is selected based on hash function, when BSR advertising the group + to RP mapping with same priority +6. Verify fragmentation of bootstrap message +7. Verify when candidate RP advertised with 32 mask length + and contain all the contacts +""" + +import os +import sys +import json +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 mininet.topo import Topo + +from lib.common_config import ( + start_topology, + write_test_header, + write_test_footer, + step, + addKernelRoute, + create_static_routes, + iperfSendIGMPJoin, + stop_router, + start_router, + shutdown_bringup_interface, + kill_router_daemons, + start_router_daemons, + reset_config_on_routers, + do_countdown, + apply_raw_config, + kill_iperf, + run_frr_cmd, + required_linux_kernel_version, + topo_daemons, +) + +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_ip_mroutes, + verify_join_state_and_timer, + verify_pim_state, + verify_upstream_iif, + verify_igmp_groups, + verify_ip_pim_upstream_rpf, + enable_disable_pim_unicast_bsm, + enable_disable_pim_bsm, + clear_ip_mroute, + clear_ip_pim_interface_traffic, + verify_pim_interface_traffic, +) +from lib.topolog import logger +from lib.topojson import build_topo_from_json, build_config_from_json + +# Reading the data from JSON File for topology creation +jsonFile = "{}/mcast_pim_bsmp_02.json".format(CWD) +try: + with open(jsonFile, "r") as topoJson: + topo = json.load(topoJson) +except IOError: + assert False, "Could not read file {}".format(jsonFile) + +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" + + +class CreateTopo(Topo): + """ + Test BasicTopo - topology 1 + + * `Topo`: Topology object + """ + + def build(self, *_args, **_opts): + """Build function""" + tgen = get_topogen(self) + + # Building topology from json file + build_topo_from_json(tgen, topo) + + +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... + tgen = Topogen(CreateTopo, mod.__name__) + # ... 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 deamons 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) + + logger.info("Running setup_module() done") + + +def teardown_module(): + """Teardown the pytest environment""" + + logger.info("Running teardown_module to delete topology") + + tgen = get_topogen() + + # 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 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 = { + fhr: {"static_routes": [{"network": bsr_route, "next_hop": next_hop}]}, + 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) + + # Add kernal route for source + group = topo["routers"][bsr]["bsm"]["bsr_packets"][packet]["pkt_dst"] + bsr_interface = topo["routers"][bsr]["links"][fhr]["interface"] + result = addKernelRoute(tgen, bsr, bsr_interface, group) + 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 kernal 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 kernal routes for sender + s_interface = topo["routers"][sender]["links"][fhr]["interface"] + result = addKernelRoute(tgen, sender, s_interface, group) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # Add kernal routes for receiver + r_interface = topo["routers"][receiver]["links"][lhr]["interface"] + result = addKernelRoute(tgen, receiver, r_interface, group) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # 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) + + 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) + return True + + +##################################################### +# +# Testcases +# +##################################################### + + +def test_starg_mroute_p0(request): + """ + 1. Verify (*,G) mroute detail on FRR router after BSM rp installed + + 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) + + kill_iperf(tgen) + clear_ip_mroute(tgen) + reset_config_on_routers(tgen) + clear_ip_pim_interface_traffic(tgen, topo) + + # Don"t run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + reset_config_on_routers(tgen) + + 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 = "226.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 = iperfSendIGMPJoin(tgen, "r1", GROUP_ADDRESS, join_interval=1) + 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 = "226.1.1.1/32" + src_addr = "*" + + # Find the elected rp from bsrp-info + step("Find the elected rp from bsrp-info in LHR in 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 in 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 in l1") + iif = "l1-i1-eth0" + 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 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 + step("Verify ip mroute in l1") + src_addr = "*" + result = verify_ip_mroutes(tgen, dut, src_addr, GROUP_ADDRESS, iif, oil) + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + # Remove the group rp mapping and send bsm + step("Remove the grp-rp mapping by sending bsm with hold time 0 for grp-rp") + result = scapy_send_bsr_raw_packet(tgen, topo, "b1", "f1", "packet2") + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # Check RP unreachable + step("Check RP unreachability 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 that it is not installed + step("Verify that iif is not installed in l1") + 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 in l1") + result = verify_ip_mroutes( + tgen, dut, src_addr, GROUP_ADDRESS, iif, oil, wait=20, expected=False + ) + assert result is not True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + # Send BSM again to configure rp + step("Add back RP by sending BSM 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 that (*,G) installed in mroute again + iif = "l1-i1-eth0" + result = verify_ip_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) + + +def test_overlapping_group_p0(request): + """ + Verify group to RP updated correctly on FRR router, when BSR advertising + the overlapping group 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) + + kill_iperf(tgen) + clear_ip_mroute(tgen) + reset_config_on_routers(tgen) + clear_ip_pim_interface_traffic(tgen, topo) + + # Don"t run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + reset_config_on_routers(tgen) + + 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", "packet4") + 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 = iperfSendIGMPJoin(tgen, "r1", GROUP_ADDRESS, join_interval=1) + 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" + group1 = "225.1.1.1/32" + # Find the elected rp from bsrp-info fro group 225.1.1.1/32 + step("Find the elected rp from bsrp-info in LHR for 225.1.1.1/32") + rp1 = find_rp_from_bsrp_info(tgen, dut, bsr_ip, group1) + assert rp1 is not {}, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + group2 = "225.1.1.0/24" + # Find the elected rp from bsrp-info fro group 225.1.1.0/24 + step("Find the elected rp from bsrp-info in LHR for 225.1.1.0/24") + rp2 = find_rp_from_bsrp_info(tgen, dut, bsr_ip, group2) + assert rp2 is not {}, "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 rp1 in l1") + result = verify_ip_pim_upstream_rpf(tgen, topo, dut, iif, GROUP_ADDRESS, rp1) + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + # Send BSR packet from b1 with rp for 225.1.1.1/32 removed + step("Send BSR packet from b1 with rp for 225.1.1.1/32 removed") + result = scapy_send_bsr_raw_packet(tgen, topo, "b1", "f1", "packet5") + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # Verify upstream rpf for 225.1.1.1 is chosen as rp1 + step("Verify upstream rpf for 225.1.1.1 is chosen as rp2 in l1") + result = verify_ip_pim_upstream_rpf(tgen, topo, dut, iif, GROUP_ADDRESS, rp2) + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + # Verify IIF/OIL in pim state + step("Verify iif is installed after rp change in l1") + 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) + + step("clear BSM database before moving to next case") + clear_bsrp_data(tgen, topo) + + write_test_footer(tc_name) + + +def test_RP_priority_p0(request): + """ + Verify group to RP info is updated correctly, when BSR advertising the + same RP with different priority + + 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) + + kill_iperf(tgen) + clear_ip_mroute(tgen) + reset_config_on_routers(tgen) + clear_ip_pim_interface_traffic(tgen, topo) + + # Don"t run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + reset_config_on_routers(tgen) + + 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 = iperfSendIGMPJoin(tgen, "r1", GROUP_ADDRESS, join_interval=1) + 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: {} RP2 new: {} ".format(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) + + # Send BSR packet from b1 after putting back high prio rp for 225.1.1.0/24 + step("Send BSM from b1 to FHR put back old 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, + ) + + # 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_add1) + 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_election_p0(request): + """ + Verify group to RP mapping in FRR node when 2 BSR are present in the network + and both are having same BSR priority + + 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) + + kill_iperf(tgen) + clear_ip_mroute(tgen) + reset_config_on_routers(tgen) + clear_ip_pim_interface_traffic(tgen, topo) + + # Don"t run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + reset_config_on_routers(tgen) + + 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", "packet3") + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + bsr_ip1 = topo["routers"]["b1"]["bsm"]["bsr_packets"]["packet1"]["bsr"].split("/")[ + 0 + ] + time.sleep(1) + + result = iperfSendIGMPJoin(tgen, "r1", GROUP_ADDRESS, join_interval=1) + 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_ip1) + 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 in l1") + rp = find_rp_from_bsrp_info(tgen, dut, bsr_ip1, 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) + + # Send BSR packet from b2 with same priority + step("Send BSR packet from b2 to FHR with same priority") + result = scapy_send_bsr_raw_packet(tgen, topo, "b2", "f1", "packet1") + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + bsr_ip2 = topo["routers"]["b2"]["bsm"]["bsr_packets"]["packet2"]["bsr"].split("/")[ + 0 + ] + time.sleep(1) + + logger.info("BSR b1:" + bsr_ip1 + " BSR b2:" + bsr_ip2) + # Verify bsr state in FHR + step("Verify if b2 is not chosen as bsr in f1") + result = verify_pim_bsr(tgen, topo, "f1", bsr_ip2, expected=False) + assert result is not True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # Verify if b1 is still chosen as bsr + step("Verify if b1 is still chosen as bsr in f1") + result = verify_pim_bsr(tgen, topo, "f1", bsr_ip1) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # Verify if that rp is installed + step("Verify that same RP in istalled 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_RP_hash_p0(request): + """ + Verify RP is selected based on hash function, when BSR advertising the group + to RP mapping with same priority + + 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) + + kill_iperf(tgen) + clear_ip_mroute(tgen) + reset_config_on_routers(tgen) + clear_ip_pim_interface_traffic(tgen, topo) + + # Don"t run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + reset_config_on_routers(tgen) + + 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", "packet7") + 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 = iperfSendIGMPJoin(tgen, "r1", GROUP_ADDRESS, join_interval=1) + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + dut = "l1" + + # 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) + + group = "225.1.1.0/24" + + # 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) + + # Verify if RP with highest hash value is chosen + step("Verify if RP(2.2.2.2) with highest hash value is chosen in l1") + if rp[group] == "2.2.2.2": + result = True + else: + result = "rp expected: 2.2.2.2 got:" + rp[group] + + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + # Check RP detail in LHR + 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_BSM_fragmentation_p1(request): + """ + Verify fragmentation of bootstrap message + + 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) + + kill_iperf(tgen) + clear_ip_mroute(tgen) + reset_config_on_routers(tgen) + clear_ip_pim_interface_traffic(tgen, topo) + + reset_config_on_routers(tgen) + + # Don"t run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + 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] + + step("Send BSM and verify if all routers have same bsrp before fragment") + result = scapy_send_bsr_raw_packet(tgen, topo, "b1", "f1", "packet1") + # 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) + + fhr_node = tgen.routers()["f1"] + inter_node = tgen.routers()["i1"] + lhr_node = tgen.routers()["l1"] + + # Verify if bsrp list is same across f1, i1 and l1 + step("Verify if bsrp list is same across f1, i1 and l1") + bsrp_f1 = fhr_node.vtysh_cmd("show ip pim bsrp-info json", isjson=True) + logger.info("show_ip_pim_bsrp_info_json f1: \n %s", bsrp_f1) + bsrp_i1 = inter_node.vtysh_cmd("show ip pim bsrp-info json", isjson=True) + logger.info("show_ip_pim_bsrp_info_json i1: \n %s", bsrp_i1) + bsrp_l1 = lhr_node.vtysh_cmd("show ip pim bsrp-info json", isjson=True) + logger.info("show_ip_pim_bsrp_info_json l1: \n %s", bsrp_l1) + + if bsrp_f1 == bsrp_l1: + result = True + else: + result = "bsrp info in f1 is not same in l1" + + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # set mtu of fhr(f1) to i1 interface to 100 so that bsm fragments + step("set mtu of fhr(f1) to i1 interface to 100 so that bsm fragments") + fhr_node.run("ifconfig f1-i1-eth2 mtu 100") + inter_node.run("ifconfig i1-f1-eth0 mtu 100") + + # Use scapy to send pre-defined packet from senser to receiver + result = scapy_send_bsr_raw_packet(tgen, topo, "b1", "f1", "packet2") + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + result = iperfSendIGMPJoin(tgen, "r1", GROUP_ADDRESS, join_interval=1) + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + # Verify bsr state in FHR + step("Verify if b1 chosen as BSR") + result = verify_pim_bsr(tgen, topo, "f1", bsr_ip) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # Verify if bsrp list is same across f1, i1 and l1 + step("Verify if bsrp list is same across f1, i1 and l1 after fragmentation") + bsrp_f1 = fhr_node.vtysh_cmd("show ip pim bsrp-info json", isjson=True) + logger.info("show_ip_pim_bsrp_info_json f1: \n %s", bsrp_f1) + bsrp_i1 = inter_node.vtysh_cmd("show ip pim bsrp-info json", isjson=True) + logger.info("show_ip_pim_bsrp_info_json i1: \n %s", bsrp_i1) + bsrp_l1 = lhr_node.vtysh_cmd("show ip pim bsrp-info json", isjson=True) + logger.info("show_ip_pim_bsrp_info_json l1: \n %s", bsrp_l1) + + if bsrp_f1 == bsrp_l1: + result = True + else: + result = "bsrp info in f1 is not same in l1" + + 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_RP_with_all_ip_octet_p1(request): + """ + Verify when candidate RP advertised with 32 mask length + and contain all the contacts + + 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) + + kill_iperf(tgen) + clear_ip_mroute(tgen) + reset_config_on_routers(tgen) + clear_ip_pim_interface_traffic(tgen, topo) + + # Don"t run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + step("pre-configure BSM packet") + 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("Send the IGMP group (225.100.100.100) from receiver connected to FRR") + GROUP_ADDRESS = "225.200.100.100" + + # Use scapy to send pre-defined packet from senser to receiver + step("Configure cisco-1 as BSR1") + result = scapy_send_bsr_raw_packet(tgen, topo, "b1", "f1", "packet8") + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + bsr_ip = topo["routers"]["b1"]["bsm"]["bsr_packets"]["packet8"]["bsr"].split("/")[0] + time.sleep(1) + + result = iperfSendIGMPJoin(tgen, "r1", GROUP_ADDRESS, join_interval=1) + assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result) + + dut = "l1" + step( + "Groups are shown with candidate RP with correct mask length 'show ip pim bsrp-info'" + ) + 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) + + 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, 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) + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) -- 2.39.5