Example #1
0
def test_staticroute_with_ecmp_p0_tc3_ebgp(request):
    """
    Verify static route ECMP functionality with 8 next hop'

    """
    tc_name = request.node.name
    write_test_header(tc_name)
    tgen = get_topogen()

    # Don't run this test if we have any failure.
    if tgen.routers_have_failure():
        pytest.skip(tgen.errors)

    reset_config_on_routers(tgen)
    NEXT_HOP_IP = populate_nh()

    step("Configure 8 interfaces / links between R1 and R2,")
    step("Configure IPv4 static route in R2 with 8 next hop"
         "N1(21.1.1.2), N2(22.1.1.2), N3(23.1.1.2), N4(24.1.1.2),"
         "N5(25.1.1.2), N6(26.1.1.2), N7(27.1.1.2),N8(28.1.1.2), Static"
         "route next-hop present on R1")

    step("Configure IBGP IPv4 peering between R2 and R3 router.")

    for addr_type in ADDR_TYPES:
        # Enable static routes
        for nhp in range(1, 9):
            input_dict_4 = {
                "r2": {
                    "static_routes": [{
                        "network":
                        PREFIX1[addr_type],
                        "next_hop":
                        NEXT_HOP_IP["nh" + str(nhp)][addr_type],
                    }]
                }
            }
            logger.info("Configure static routes")
            result = create_static_routes(tgen, input_dict_4)
            assert result is True, "Testcase {} : Failed \n Error: {}".format(
                tc_name, result)
        logger.info("Verifying %s routes on r2", addr_type)
        nh = [
            NEXT_HOP_IP["nh1"][addr_type],
            NEXT_HOP_IP["nh2"][addr_type],
            NEXT_HOP_IP["nh3"][addr_type],
            NEXT_HOP_IP["nh4"][addr_type],
            NEXT_HOP_IP["nh5"][addr_type],
            NEXT_HOP_IP["nh6"][addr_type],
            NEXT_HOP_IP["nh7"][addr_type],
            NEXT_HOP_IP["nh8"][addr_type],
        ]

        dut = "r2"
        protocol = "static"
        result = verify_rib(tgen,
                            addr_type,
                            dut,
                            input_dict_4,
                            next_hop=nh,
                            protocol=protocol)
        assert (
            result is True
        ), "Testcase {} : Failed \nError: Routes are" " missing in RIB".format(
            tc_name)
    step("Configure redistribute static in BGP on R2 router")
    for addr_type in ADDR_TYPES:
        input_dict_2 = {
            "r2": {
                "bgp": {
                    "address_family": {
                        addr_type: {
                            "unicast": {
                                "redistribute": [{
                                    "redist_type": "static"
                                }]
                            }
                        }
                    }
                }
            }
        }
        result = create_router_bgp(tgen, topo, input_dict_2)
        assert result is True, "Testcase {} : Failed \n Error: {}".format(
            tc_name, result)

    step("Remove the static route configured with nexthop N1 to N8, one"
         "by one from running config")
    for addr_type in ADDR_TYPES:
        # delete static routes
        for nhp in range(1, 9):
            input_dict_4 = {
                "r2": {
                    "static_routes": [{
                        "network":
                        PREFIX1[addr_type],
                        "next_hop":
                        NEXT_HOP_IP["nh" + str(nhp)][addr_type],
                        "delete":
                        True,
                    }]
                }
            }

        logger.info("Configure static routes")
        result = create_static_routes(tgen, input_dict_4)
        assert result is True, "Testcase {} : Failed \n Error: {}".format(
            tc_name, result)

        result = verify_rib(
            tgen,
            addr_type,
            dut,
            input_dict_4,
            next_hop=nh,
            protocol=protocol,
            expected=False,
        )
        assert (
            result is not True
        ), "Testcase {} : Failed \nError: Routes are" " still present in RIB".format(
            tc_name)

    step("Configure the static route with nexthop N1 to N8, one by" "one")

    for addr_type in ADDR_TYPES:
        # add static routes
        for nhp in range(1, 9):
            input_dict_4 = {
                "r2": {
                    "static_routes": [{
                        "network":
                        PREFIX1[addr_type],
                        "next_hop":
                        NEXT_HOP_IP["nh" + str(nhp)][addr_type],
                    }]
                }
            }

        logger.info("Configure static routes")
        result = create_static_routes(tgen, input_dict_4)
        assert result is True, "Testcase {} : Failed \n Error: {}".format(
            tc_name, result)

    result = verify_rib(tgen,
                        addr_type,
                        dut,
                        input_dict_4,
                        next_hop=nh,
                        protocol=protocol)
    assert (
        result is True
    ), "Testcase {} : Failed \nError: Routes are" " missing in RIB".format(
        tc_name)

    step("Random shut of the nexthop interfaces")
    randnum = random.randint(0, 7)
    for addr_type in ADDR_TYPES:
        intf = topo["routers"]["r2"]["links"]["r1-link" +
                                              str(randnum)]["interface"]
        shutdown_bringup_interface(tgen, dut, intf, False)
        nhip = NEXT_HOP_IP["nh" + str(randnum + 1)][addr_type]
        input_dict_5 = {
            "r2": {
                "static_routes": [{
                    "network":
                    PREFIX1[addr_type],
                    "next_hop":
                    NEXT_HOP_IP["nh" + str(randnum + 1)][addr_type],
                }]
            }
        }
        result = verify_rib(
            tgen,
            addr_type,
            dut,
            input_dict_5,
            next_hop=nhip,
            protocol=protocol,
            expected=False,
        )
        assert (
            result is not True
        ), "Testcase {} : Failed \n" "Error: Routes are still present in RIB".format(
            tc_name)

    step("Random no shut of the nexthop interfaces")
    for addr_type in ADDR_TYPES:
        intf = topo["routers"]["r2"]["links"]["r1-link" +
                                              str(randnum)]["interface"]
        shutdown_bringup_interface(tgen, dut, intf, True)
        nhip = NEXT_HOP_IP["nh" + str(randnum + 1)][addr_type]
        result = verify_rib(tgen,
                            addr_type,
                            dut,
                            input_dict_5,
                            next_hop=nhip,
                            protocol=protocol)
        assert (
            result is True
        ), "Testcase {} : Failed \n" "Error: Routes are missing in RIB".format(
            tc_name)

    step("Reload the FRR router")
    # stop/start -> restart FRR router and verify
    stop_router(tgen, "r2")
    start_router(tgen, "r2")

    result = verify_rib(tgen,
                        addr_type,
                        dut,
                        input_dict_4,
                        next_hop=nh,
                        protocol=protocol)
    assert (
        result is True
    ), "Testcase {} : Failed \nError: Routes are" " missing in RIB".format(
        tc_name)

    write_test_footer(tc_name)
Example #2
0
def test_staticroute_with_ecmp_with_diff_AD_p0_tc4_ebgp(request):
    """
    Verify static route ECMP functionality with 8 next hop

    """
    tc_name = request.node.name
    write_test_header(tc_name)
    tgen = get_topogen()

    # Don't run this test if we have any failure.
    if tgen.routers_have_failure():
        pytest.skip(tgen.errors)

    reset_config_on_routers(tgen)
    NEXT_HOP_IP = populate_nh()

    step("Configure 8 interfaces / links between R1 and R2,")
    step("Configure IBGP IPv4 peering between R2 and R3 router.")
    reset_config_on_routers(tgen)
    NEXT_HOP_IP = populate_nh()
    nh_all = {}
    for addr_type in ADDR_TYPES:
        nh_all[addr_type] = []
        for nhp in range(1, 9):
            nh_all[addr_type].append(NEXT_HOP_IP["nh" + str(nhp)][addr_type])
    step("Configure IPv4 static route in R2 with 8 next hop"
         "N1(21.1.1.2) AD 10, N2(22.1.1.2) AD 20, N3(23.1.1.2) AD 30,"
         "N4(24.1.1.2) AD 40, N5(25.1.1.2) AD 50, N6(26.1.1.2) AD 60,"
         "N7(27.1.1.2) AD 70, N8(28.1.1.2) AD 80, Static route next-hop"
         "present on R1")
    for addr_type in ADDR_TYPES:
        for nhp in range(1, 9):
            input_dict_4 = {
                "r2": {
                    "static_routes": [{
                        "network":
                        PREFIX1[addr_type],
                        "next_hop":
                        NEXT_HOP_IP["nh" + str(nhp)][addr_type],
                        "admin_distance":
                        10 * nhp,
                    }]
                }
            }
            logger.info("Configure static routes")
            result = create_static_routes(tgen, input_dict_4)
            assert result is True, "Testcase {} : Failed \n Error: {}".format(
                tc_name, result)
        logger.info("Verifying %s routes on r2", addr_type)

        step("On R2, static route installed in RIB using "
             "show ip route with 8 next hop, lowest AD nexthop is active")
        step("On R2, static route with lowest AD nexthop installed in FIB")
        input_dict_4 = {
            "r2": {
                "static_routes": [{
                    "network": PREFIX1[addr_type],
                    "next_hop": NEXT_HOP_IP["nh1"][addr_type],
                    "admin_distance": 10,
                }]
            }
        }
        dut = "r2"
        protocol = "static"
        nh = NEXT_HOP_IP["nh1"][addr_type]
        result = verify_rib(tgen,
                            addr_type,
                            dut,
                            input_dict_4,
                            next_hop=nh,
                            protocol=protocol,
                            fib=True)
        assert result is True, ("Testcase {} : Failed \nError: Route with "
                                " lowest AD is missing in RIB".format(tc_name))

        nh = []
        for nhp in range(2, 9):
            nh.append(NEXT_HOP_IP["nh" + str(nhp)][addr_type])
        result = verify_rib(
            tgen,
            addr_type,
            dut,
            input_dict_4,
            next_hop=nh,
            protocol=protocol,
            fib=True,
            expected=False,
        )
        assert result is not True, (
            "Testcase {} : Failed \nError: Routes "
            " with high AD are active in RIB".format(tc_name))

    step("Configure redistribute static in BGP on R2 router")
    for addr_type in ADDR_TYPES:
        input_dict_2 = {
            "r2": {
                "bgp": {
                    "address_family": {
                        addr_type: {
                            "unicast": {
                                "redistribute": [{
                                    "redist_type": "static"
                                }]
                            }
                        }
                    }
                }
            }
        }

        logger.info("Configuring redistribute static")
        result = create_router_bgp(tgen, topo, input_dict_2)
        assert result is True, "Testcase {} : Failed \n Error: {}".format(
            tc_name, result)

        step("After configuring them, route is always active with lowest AD"
             "value and all the nexthop populated in RIB and FIB again ")
        input_dict_4 = {
            "r2": {
                "static_routes": [{
                    "network": PREFIX1[addr_type],
                    "next_hop": NEXT_HOP_IP["nh1"][addr_type],
                    "admin_distance": 10,
                }]
            }
        }
        dut = "r2"
        protocol = "static"
        nh = NEXT_HOP_IP["nh1"][addr_type]
        result = verify_rib(tgen,
                            addr_type,
                            dut,
                            input_dict_4,
                            next_hop=nh,
                            protocol=protocol,
                            fib=True)
        assert result is True, ("Testcase {} : Failed \nError: Route with "
                                " lowest AD is missing in RIB".format(tc_name))

    step("Remove the static route configured with nexthop N1 to N8, one"
         "by one from running config")

    for addr_type in ADDR_TYPES:
        # delete static routes
        for nhp in range(1, 9):
            input_dict_4 = {
                "r2": {
                    "static_routes": [{
                        "network":
                        PREFIX1[addr_type],
                        "next_hop":
                        NEXT_HOP_IP["nh" + str(nhp)][addr_type],
                        "admin_distance":
                        10 * nhp,
                        "delete":
                        True,
                    }]
                }
            }

        logger.info("Configure static routes")
        result = create_static_routes(tgen, input_dict_4)
        assert result is True, "Testcase {} : Failed \n Error: {}".format(
            tc_name, result)

    step("After removing the static route with N1 to N8 one by one, "
         "route become active with next preferred nexthop and nexthop which "
         "got removed is not shown in RIB and FIB")
    result = verify_rib(
        tgen,
        addr_type,
        dut,
        input_dict_4,
        next_hop=nh_all[addr_type],
        protocol=protocol,
        expected=False,
    )
    assert (
        result is not True
    ), "Testcase {} : Failed \nError: Routes are" " still present in RIB".format(
        tc_name)

    step("Configure the static route with nexthop N1 to N8, one by" "one")
    for addr_type in ADDR_TYPES:
        # add static routes
        for nhp in range(1, 9):
            input_dict_4 = {
                "r2": {
                    "static_routes": [{
                        "network":
                        PREFIX1[addr_type],
                        "next_hop":
                        NEXT_HOP_IP["nh" + str(nhp)][addr_type],
                        "admin_distance":
                        10 * nhp,
                    }]
                }
            }
        logger.info("Configure static routes")
        result = create_static_routes(tgen, input_dict_4)
        assert result is True, "Testcase {} : Failed \n Error: {}".format(
            tc_name, result)

        step("On R2, static route with lowest AD nexthop installed in FIB")
        input_dict_4 = {
            "r2": {
                "static_routes": [{
                    "network": PREFIX1[addr_type],
                    "next_hop": NEXT_HOP_IP["nh1"][addr_type],
                    "admin_distance": 10,
                }]
            }
        }
        dut = "r2"
        protocol = "static"
        nh = NEXT_HOP_IP["nh1"][addr_type]
        result = verify_rib(tgen,
                            addr_type,
                            dut,
                            input_dict_4,
                            next_hop=nh,
                            protocol=protocol,
                            fib=True)
        assert result is True, ("Testcase {} : Failed \nError: Route with "
                                " lowest AD is missing in RIB".format(tc_name))

        nh = []
        for nhp in range(2, 9):
            nh.append(NEXT_HOP_IP["nh" + str(nhp)][addr_type])
        result = verify_rib(
            tgen,
            addr_type,
            dut,
            input_dict_4,
            next_hop=nh,
            protocol=protocol,
            fib=True,
            expected=False,
        )
        assert result is not True, (
            "Testcase {} : Failed \nError: Routes "
            " with high AD are active in RIB".format(tc_name))

    step("Random shut of the nexthop interfaces")
    randnum = random.randint(0, 7)
    for addr_type in ADDR_TYPES:
        intf = topo["routers"]["r2"]["links"]["r1-link" +
                                              str(randnum)]["interface"]
        shutdown_bringup_interface(tgen, dut, intf, False)
        nhip = NEXT_HOP_IP["nh" + str(randnum + 1)][addr_type]
        input_dict_5 = {
            "r2": {
                "static_routes": [{
                    "network":
                    PREFIX1[addr_type],
                    "next_hop":
                    NEXT_HOP_IP["nh" + str(randnum + 1)][addr_type],
                }]
            }
        }
        result = verify_rib(
            tgen,
            addr_type,
            dut,
            input_dict_5,
            next_hop=nhip,
            protocol=protocol,
            expected=False,
        )
        assert (
            result is not True
        ), "Testcase {} : Failed \n" "Error: Routes are still present in RIB".format(
            tc_name)

    step("Random no shut of the nexthop interfaces")
    for addr_type in ADDR_TYPES:
        intf = topo["routers"]["r2"]["links"]["r1-link" +
                                              str(randnum)]["interface"]
        shutdown_bringup_interface(tgen, dut, intf, True)
        nhip = NEXT_HOP_IP["nh" + str(randnum + 1)][addr_type]
        result = verify_rib(tgen,
                            addr_type,
                            dut,
                            input_dict_5,
                            next_hop=nhip,
                            protocol=protocol)
        assert (
            result is True
        ), "Testcase {} : Failed \n" "Error: Routes are missing in RIB".format(
            tc_name)

    step("Reload the FRR router")
    # stop/start -> restart FRR router and verify
    stop_router(tgen, "r2")
    start_router(tgen, "r2")

    step("After reload of FRR router, static route installed "
         "in RIB and FIB properly .")
    for addr_type in ADDR_TYPES:
        input_dict_4 = {
            "r2": {
                "static_routes": [{
                    "network": PREFIX1[addr_type],
                    "next_hop": NEXT_HOP_IP["nh1"][addr_type],
                    "admin_distance": 10,
                }]
            }
        }
        dut = "r2"
        protocol = "static"
        nh = NEXT_HOP_IP["nh1"][addr_type]
        result = verify_rib(tgen,
                            addr_type,
                            dut,
                            input_dict_4,
                            next_hop=nh,
                            protocol=protocol,
                            fib=True)
        assert result is True, ("Testcase {} : Failed \nError: Route with "
                                " lowest AD is missing in RIB".format(tc_name))

        nh = []
        for nhp in range(2, 9):
            nh.append(NEXT_HOP_IP["nh" + str(nhp)][addr_type])
        result = verify_rib(
            tgen,
            addr_type,
            dut,
            input_dict_4,
            next_hop=nh,
            protocol=protocol,
            fib=True,
            expected=False,
        )
        assert result is not True, (
            "Testcase {} : Failed \nError: Routes "
            " with high AD are active in RIB".format(tc_name))

    write_test_footer(tc_name)
Example #3
0
def test_restart_frr_p2(request):
    """

    Test extended capability nexthop , restart frr.

    Verify IPv4 routes are intact after stop and start the FRR services
    """
    tc_name = request.node.name
    write_test_header(tc_name)
    tgen = get_topogen()
    # Don't run this test if we have any failure.
    if tgen.routers_have_failure():
        pytest.skip(tgen.errors)
    reset_config_on_routers(tgen)
    step("Configure IPv6 EBGP Unnumbered session between R1 and R2")
    step("Enable capability extended-nexthop on both the IPv6 BGP peers")
    step("Activate same IPv6 nbr from IPv4 unicast family")
    step("Enable cap ext nh on r1 and r2 and activate in ipv4 addr family")
    step("Verify bgp convergence as ipv6 nbr is enabled on ipv4 addr family.")
    bgp_convergence = verify_bgp_convergence(tgen, topo)
    assert bgp_convergence is True, "Testcase {} :Failed \n Error: {}".format(
        tc_name, bgp_convergence
    )

    step(" Configure 5 IPv4 static" " routes on R1, Nexthop as different links of R0")
    for rte in range(0, NO_OF_RTES):
        # Create Static routes
        input_dict = {
            "r1": {
                "static_routes": [
                    {
                        "network": NETWORK["ipv4"][rte],
                        "no_of_ip": 1,
                        "next_hop": NEXT_HOP["ipv4"][rte],
                    }
                ]
            }
        }
        result = create_static_routes(tgen, input_dict)
        assert result is True, "Testcase {} : Failed \n Error: {}".format(
            tc_name, result
        )

    step(
        "Advertise static routes from IPv4 unicast family and IPv6 "
        "unicast family respectively from R1 using red static cmd "
        "Advertise loopback from IPv4 unicast family using network command "
        "from R1"
    )

    configure_bgp_on_r1 = {
        "r1": {
            "bgp": {
                "address_family": {
                    "ipv4": {
                        "unicast": {
                            "redistribute": [{"redist_type": "static"}],
                            "advertise_networks": [
                                {"network": NETWORK_CMD_IP, "no_of_network": 1}
                            ],
                        }
                    },
                    "ipv6": {"unicast": {"redistribute": [{"redist_type": "static"}]}},
                }
            }
        }
    }
    result = create_router_bgp(tgen, topo, configure_bgp_on_r1)
    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
    step(
        "IPv4 routes advertised using static and network command are "
        " received on R2 BGP and routing table , "
        "verify using show ip bgp, show ip route for IPv4 routes ."
    )

    llip = get_llip("r1", "r2-link0")
    assert llip is not None, "Testcase {} : Failed \n Error: {}".format(tc_name, result)

    dut = "r2"
    protocol = "bgp"
    verify_nh_for_static_rtes = {
        "r1": {
            "static_routes": [
                {
                    "network": NETWORK["ipv4"][0],
                    "no_of_ip": NO_OF_RTES,
                    "next_hop": llip,
                }
            ]
        }
    }
    bgp_rib = verify_rib(tgen, "ipv4", dut, verify_nh_for_static_rtes, next_hop=llip)
    assert bgp_rib is True, "Testcase {} : Failed \n Error: {}".format(tc_name, bgp_rib)
    result = verify_rib(
        tgen, "ipv4", dut, verify_nh_for_static_rtes, next_hop=llip, protocol=protocol
    )
    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)

    verify_nh_for_nw_rtes = {
        "r1": {
            "static_routes": [
                {"network": NETWORK_CMD_IP, "no_of_ip": 1, "next_hop": llip}
            ]
        }
    }

    bgp_rib = verify_rib(tgen, "ipv4", dut, verify_nh_for_nw_rtes, next_hop=llip)
    assert bgp_rib is True, "Testcase {} : Failed \n Error: {}".format(tc_name, bgp_rib)
    result = verify_rib(
        tgen, "ipv4", dut, verify_nh_for_nw_rtes, next_hop=llip, protocol=protocol
    )
    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)

    # stop/start -> restart FRR router and verify
    stop_router(tgen, "r1")
    stop_router(tgen, "r2")
    start_router(tgen, "r1")
    start_router(tgen, "r2")

    step(
        "After stop/start of FRR services , verify session up and routes "
        "came up fine ,nh is proper using show bgp & show ipv6 route on R2 "
    )
    bgp_convergence = verify_bgp_convergence(tgen, topo)
    assert bgp_convergence is True, "Testcase {} :Failed \n Error: {}".format(
        tc_name, bgp_convergence
    )

    llip = get_llip("r1", "r2-link0")
    assert llip is not None, "Testcase {} : Failed \n Error: {}".format(tc_name, result)

    # verify the routes with nh as ext_nh
    verify_nh_for_static_rtes = {
        "r1": {
            "static_routes": [
                {"network": NETWORK["ipv4"][0], "no_of_ip": 1, "next_hop": llip}
            ]
        }
    }
    bgp_rib = verify_rib(tgen, "ipv4", dut, verify_nh_for_static_rtes, next_hop=llip)
    assert bgp_rib is True, "Testcase {} : Failed \n Error: {}".format(tc_name, bgp_rib)
    result = verify_rib(
        tgen, "ipv4", dut, verify_nh_for_static_rtes, next_hop=llip, protocol=protocol
    )
    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)

    # verify the routes with nh as ext_nh
    verify_nh_for_nw_rtes = {
        "r1": {
            "static_routes": [
                {"network": NETWORK_CMD_IP, "no_of_ip": 1, "next_hop": llip}
            ]
        }
    }
    bgp_rib = verify_rib(tgen, "ipv4", dut, verify_nh_for_nw_rtes, next_hop=llip)
    assert bgp_rib is True, "Testcase {} : Failed \n Error: {}".format(tc_name, bgp_rib)
    result = verify_rib(
        tgen, "ipv4", dut, verify_nh_for_nw_rtes, next_hop=llip, protocol=protocol
    )
    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
    write_test_footer(tc_name)
Example #4
0
def test_ospf_chaos_tc32_p1(request):
    """Verify ospf functionality after restart FRR service."""
    tc_name = request.node.name
    write_test_header(tc_name)
    tgen = get_topogen()
    global topo
    step("Bring up the base config as per the topology")
    reset_config_on_routers(tgen)

    step("Create static routes(10.0.20.1/32) in R1 and redistribute "
         "to OSPF using route map.")

    # Create Static routes
    input_dict = {
        "r0": {
            "static_routes": [{
                "network": NETWORK["ipv4"][0],
                "no_of_ip": 5,
                "next_hop": "Null0",
            }]
        }
    }
    result = create_static_routes(tgen, input_dict)
    assert result is True, "Testcase {} : Failed \n Error: {}".format(
        tc_name, result)

    ospf_red_r0 = {
        "r0": {
            "ospf": {
                "redistribute": [{
                    "redist_type": "static"
                }]
            }
        }
    }
    result = create_router_ospf(tgen, topo, ospf_red_r0)
    assert result is True, "Testcase {} : Failed \n Error: {}".format(
        tc_name, result)

    step("Verify OSPF neighbors after base config is done.")
    # Api call verify whether OSPF is converged
    ospf_covergence = verify_ospf_neighbor(tgen, topo)
    assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
        ospf_covergence)

    step("Verify that route is advertised to R1.")
    dut = "r1"
    protocol = "ospf"

    nh = topo["routers"]["r0"]["links"]["r1"]["ipv4"].split("/")[0]
    result = verify_ospf_rib(tgen, dut, input_dict, next_hop=nh)
    assert result is True, "Testcase {} : Failed \n Error: {}".format(
        tc_name, result)

    result = verify_rib(tgen,
                        "ipv4",
                        dut,
                        input_dict,
                        protocol=protocol,
                        next_hop=nh)
    assert result is True, "Testcase {} : Failed \n Error: {}".format(
        tc_name, result)

    step("Restart frr on R0")
    stop_router(tgen, "r0")
    start_router(tgen, "r0")

    step("Verify OSPF neighbors are up after restarting R0")
    # Api call verify whether OSPF is converged
    ospf_covergence = verify_ospf_neighbor(tgen, topo)
    assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
        ospf_covergence)

    step("All the neighbours are up and routes are installed before the"
         " restart. Verify OSPF route table and ip route table.")
    dut = "r1"
    protocol = "ospf"
    result = verify_ospf_rib(tgen, dut, input_dict, next_hop=nh)
    assert result is True, "Testcase {} : Failed \n Error: {}".format(
        tc_name, result)

    result = verify_rib(tgen,
                        "ipv4",
                        dut,
                        input_dict,
                        protocol=protocol,
                        next_hop=nh)
    assert result is True, "Testcase {} : Failed \n Error: {}".format(
        tc_name, result)

    step("Restart frr on R1")
    stop_router(tgen, "r1")
    start_router(tgen, "r1")

    step("Verify OSPF neighbors are up after restarting R1")
    # Api call verify whether OSPF is converged
    ospf_covergence = verify_ospf_neighbor(tgen, topo)
    assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
        ospf_covergence)

    step("All the neighbours are up and routes are installed before the"
         " restart. Verify OSPF route table and ip route table.")
    dut = "r1"
    protocol = "ospf"
    result = verify_ospf_rib(tgen, dut, input_dict, next_hop=nh)
    assert result is True, "Testcase {} : Failed \n Error: {}".format(
        tc_name, result)

    result = verify_rib(tgen,
                        "ipv4",
                        dut,
                        input_dict,
                        protocol=protocol,
                        next_hop=nh)
    assert result is True, "Testcase {} : Failed \n Error: {}".format(
        tc_name, result)

    write_test_footer(tc_name)
def test_static_route_2nh_admin_dist_p0_tc_2_ebgp(request):
    """
    Verify static route functionality with 2 next hop & different AD value.

    """
    tc_name = request.node.name
    write_test_header(tc_name)
    tgen = get_topogen()
    # Don't run this test if we have any failure.
    if tgen.routers_have_failure():
        pytest.skip(tgen.errors)

    reset_config_on_routers(tgen)

    step("Configure IPv4 static route (10.1.1.1) in R2 with next hop N1"
         "(28.1.1.2 ) AD 10 and N2 (29.1.1.2) AD 20 , Static route next-hop"
         "present on R1 \n ex :- ip route 10.1.1.1/24 28.1.1.2 10 & "
         "ip route 10.1.1.1/24 29.1.1.2 20")

    reset_config_on_routers(tgen)
    next_hop_ip = populate_nh()
    for addr_type in ADDR_TYPES:
        input_dict_4 = {
            "r2": {
                "static_routes": [
                    {
                        "network": NETWORK2[addr_type],
                        "next_hop": next_hop_ip["nh1"][addr_type],
                        "admin_distance": 10,
                    },
                    {
                        "network": NETWORK2[addr_type],
                        "next_hop": next_hop_ip["nh2"][addr_type],
                        "admin_distance": 20,
                    },
                ]
            }
        }
        logger.info("Configure static routes")
        result = create_static_routes(tgen, input_dict_4)
        assert result is True, "Testcase {} : Failed \n Error: {}".format(
            tc_name, result)

        step("On R2, static route installed in RIB using "
             "show ip route with 2 next hop , lowest AD nexthop is active ")
        rte1_nh1 = {
            "r2": {
                "static_routes": [{
                    "network": NETWORK2[addr_type],
                    "next_hop": next_hop_ip["nh1"][addr_type],
                    "admin_distance": 10,
                }]
            }
        }
        nh = [next_hop_ip["nh1"][addr_type]]
        dut = "r2"
        protocol = "static"
        result = verify_rib(tgen,
                            addr_type,
                            dut,
                            rte1_nh1,
                            next_hop=nh,
                            protocol=protocol,
                            fib=True)
        assert (
            result is True
        ), "Testcase {} : Failed \nError: Routes is" "missing in RIB".format(
            tc_name)

        rte2_nh2 = {
            "r2": {
                "static_routes": [{
                    "network": NETWORK2[addr_type],
                    "next_hop": next_hop_ip["nh2"][addr_type],
                    "admin_distance": 20,
                }]
            }
        }
        nh = [next_hop_ip["nh2"][addr_type]]
        dut = "r2"
        protocol = "static"
        result = verify_rib(
            tgen,
            addr_type,
            dut,
            rte2_nh2,
            next_hop=nh,
            protocol=protocol,
            fib=True,
            expected=False,
        )
        assert (
            result is not True
        ), "Testcase {} : Failed \nError: Routes is" "not active in RIB".format(
            tc_name)

        step("Configure IBGP IPv4 peering between R2 and R3 router.")
        step("Explicit route is added in R3 for R2 nexthop rechability")
        rt3_rtes = {
            "r3": {
                "static_routes": [
                    {
                        "network":
                        next_hop_ip["nh1"][addr_type] + "/32",
                        "next_hop":
                        topo["routers"]["r2"]["links"]["r3"][addr_type],
                    },
                    {
                        "network":
                        next_hop_ip["nh2"][addr_type] + "/32",
                        "next_hop":
                        topo["routers"]["r2"]["links"]["r3"][addr_type],
                    },
                ]
            }
        }
        logger.info("Configure static routes")
        result = create_static_routes(tgen, rt3_rtes)
        assert result is True, "Testcase {} : Failed \n Error: {}".format(
            tc_name, result)
        step("Configure redistribute static in BGP on R2 router")

        input_dict_2 = {
            "r2": {
                "bgp": {
                    "address_family": {
                        addr_type: {
                            "unicast": {
                                "redistribute": [{
                                    "redist_type": "static"
                                }]
                            }
                        }
                    }
                }
            }
        }
        result = create_router_bgp(tgen, topo, input_dict_2)
        assert result is True, "Testcase {} : Failed \n Error: {}".format(
            tc_name, result)

        step("Remove the static route configured with nexthop N1 from"
             "running config")
        rt1_nh1 = {
            "r2": {
                "static_routes": [{
                    "network": NETWORK[addr_type],
                    "next_hop": next_hop_ip["nh1"][addr_type],
                    "admin_distance": 10,
                    "delete": True,
                }]
            }
        }

        logger.info("Configure static routes")
        result = create_static_routes(tgen, rt1_nh1)
        assert result is True, "Testcase {} : Failed \n Error: {}".format(
            tc_name, result)

        step("On R2, after removing the static route with N1 , "
             "route become active with nexthop N2 and vice versa.")
        rte1_nh1 = {
            "r2": {
                "static_routes": [{
                    "network": NETWORK2[addr_type],
                    "next_hop": next_hop_ip["nh1"][addr_type],
                    "admin_distance": 10,
                }]
            }
        }
        nh = [next_hop_ip["nh1"][addr_type]]
        dut = "r2"
        protocol = "static"
        result = verify_rib(
            tgen,
            addr_type,
            dut,
            rte1_nh1,
            next_hop=nh,
            protocol=protocol,
            fib=True,
            expected=False,
        )
        assert (
            result is not True
        ), "Testcase {} : Failed \nError: Routes is" "missing in RIB".format(
            tc_name)

        rte2_nh2 = {
            "r2": {
                "static_routes": [{
                    "network": NETWORK2[addr_type],
                    "next_hop": next_hop_ip["nh2"][addr_type],
                    "admin_distance": 20,
                }]
            }
        }
        nh = [next_hop_ip["nh2"][addr_type]]
        result = verify_rib(tgen,
                            addr_type,
                            dut,
                            rte2_nh2,
                            next_hop=nh,
                            protocol=protocol,
                            fib=True)
        assert (
            result is True
        ), "Testcase {} : Failed \nError: Routes is" "not active in RIB".format(
            tc_name)

        step("Configure the static route with nexthop N1")
        rte1_nh1 = {
            "r2": {
                "static_routes": [{
                    "network": NETWORK[addr_type],
                    "next_hop": next_hop_ip["nh1"][addr_type],
                    "admin_distance": 10,
                }]
            }
        }
        logger.info("Configure static routes")
        result = create_static_routes(tgen, rte1_nh1)
        assert result is True, "Testcase {} : Failed \n Error: {}".format(
            tc_name, result)

        step("Remove the static route configured with nexthop N2 from"
             "running config")
        rte2_nh2 = {
            "r2": {
                "static_routes": [{
                    "network": NETWORK[addr_type],
                    "next_hop": next_hop_ip["nh2"][addr_type],
                    "admin_distance": 20,
                    "delete": True,
                }]
            }
        }
        logger.info("Configure static routes")
        result = create_static_routes(tgen, rte2_nh2)
        assert result is True, "Testcase {} : Failed \n Error: {}".format(
            tc_name, result)

        step("On R2, after removing the static route with N2 , "
             "route become active with nexthop N1 and vice versa.")
        nh = next_hop_ip["nh2"][addr_type]
        result = verify_rib(
            tgen,
            addr_type,
            dut,
            rte2_nh2,
            next_hop=nh,
            protocol=protocol,
            expected=False,
        )
        assert (
            result is not True
        ), "Testcase {} : Failed \nError: Routes is" " still present in RIB".format(
            tc_name)

        nh = [next_hop_ip["nh1"][addr_type]]
        result = verify_rib(tgen,
                            addr_type,
                            dut,
                            rte1_nh1,
                            next_hop=nh,
                            protocol=protocol)
        assert (
            result is True
        ), "Testcase {} : Failed \nError: Routes is" " missing in RIB".format(
            tc_name)

        step("Configure the static route with nexthop N2")
        rte2_nh2 = {
            "r2": {
                "static_routes": [{
                    "network": NETWORK[addr_type],
                    "next_hop": next_hop_ip["nh2"][addr_type],
                    "admin_distance": 20,
                }]
            }
        }

        logger.info("Configure static routes")
        result = create_static_routes(tgen, rte2_nh2)
        assert result is True, "Testcase {} : Failed \n Error: {}".format(
            tc_name, result)

        step("Shut nexthop interface N1")
        intf = topo["routers"]["r2"]["links"]["r1-link0"]["interface"]

        shutdown_bringup_interface(tgen, dut, intf, False)

        step("after shut of nexthop N1 , route become active with nexthop N2")

        nh = next_hop_ip["nh1"][addr_type]
        result = verify_rib(
            tgen,
            addr_type,
            dut,
            rte1_nh1,
            next_hop=nh,
            protocol=protocol,
            expected=False,
        )
        assert (
            result is not True
        ), "Testcase {} : Failed \nError: Routes is" " still present in RIB".format(
            tc_name)

        nh = [next_hop_ip["nh2"][addr_type]]
        result = verify_rib(tgen,
                            addr_type,
                            dut,
                            rte2_nh2,
                            next_hop=nh,
                            protocol=protocol,
                            fib=True)
        assert (
            result is True
        ), "Testcase {} : Failed \nError: Routes is" " missing in RIB".format(
            tc_name)

        step("No shut the nexthop interface N1")
        shutdown_bringup_interface(tgen, dut, intf, True)

        step("after shut of nexthop N1 , route become active "
             "with nexthop N2 and vice versa.")
        nh = [next_hop_ip["nh1"][addr_type]]

        result = verify_rib(tgen,
                            addr_type,
                            dut,
                            rte1_nh1,
                            next_hop=nh,
                            protocol=protocol,
                            fib=True)
        assert (
            result is True
        ), "Testcase {} : Failed \nError: Routes is" " missing in RIB".format(
            tc_name)

        step("Shut nexthop interface N2")
        intf = topo["routers"]["r2"]["links"]["r1-link1"]["interface"]

        shutdown_bringup_interface(tgen, dut, intf, False)

        step(" after shut of nexthop N1 , route become active with "
             "nexthop N2 and vice versa.")
        nh = next_hop_ip["nh2"][addr_type]

        result = verify_rib(
            tgen,
            addr_type,
            dut,
            rte2_nh2,
            next_hop=nh,
            protocol=protocol,
            expected=False,
        )
        assert (
            result is not True
        ), "Testcase {} : Failed \nError: Routes is" " still present in RIB".format(
            tc_name)

        nh = [next_hop_ip["nh1"][addr_type]]
        result = verify_rib(tgen,
                            addr_type,
                            dut,
                            rte1_nh1,
                            next_hop=nh,
                            protocol=protocol)
        assert (
            result is True
        ), "Testcase {} : Failed \nError: Routes is" " missing in RIB".format(
            tc_name)

        step("No shut nexthop interface N2")
        shutdown_bringup_interface(tgen, dut, intf, True)

        step("after shut of nexthop N1 , route become active "
             "with nexthop N2 and vice versa.")
        rte1_nh1 = {
            "r2": {
                "static_routes": [{
                    "network": NETWORK2[addr_type],
                    "next_hop": next_hop_ip["nh1"][addr_type],
                    "admin_distance": 10,
                }]
            }
        }
        nh = [next_hop_ip["nh1"][addr_type]]
        dut = "r2"
        protocol = "static"
        result = verify_rib(tgen,
                            addr_type,
                            dut,
                            rte1_nh1,
                            next_hop=nh,
                            protocol=protocol,
                            fib=True)
        assert (
            result is True
        ), "Testcase {} : Failed \nError: Routes is" "missing in RIB".format(
            tc_name)

        rte2_nh2 = {
            "r2": {
                "static_routes": [{
                    "network": NETWORK2[addr_type],
                    "next_hop": next_hop_ip["nh2"][addr_type],
                    "admin_distance": 20,
                }]
            }
        }
        nh = [next_hop_ip["nh2"][addr_type]]
        dut = "r2"
        protocol = "static"
        result = verify_rib(
            tgen,
            addr_type,
            dut,
            rte2_nh2,
            next_hop=nh,
            protocol=protocol,
            fib=True,
            expected=False,
        )
        assert (
            result is not True
        ), "Testcase {} : Failed \nError: Routes is" "not active in RIB".format(
            tc_name)

        dut = "r3"
        protocol = "bgp"

        result = verify_rib(
            tgen,
            addr_type,
            dut,
            rte2_nh2,
            next_hop=nh,
            protocol=protocol,
            fib=True,
            expected=False,
        )
        assert (
            result is not True
        ), "Testcase {} : Failed \nError: Routes is" "not active in RIB".format(
            tc_name)

        dut = "r2"
        step("Reload the FRR router")
        # stop/start -> restart FRR router and verify
        stop_router(tgen, "r2")

        start_router(tgen, "r2")

        step("After reload of FRR router , static route installed"
             " in RIB and FIB properly .")
        rte1_nh1 = {
            "r2": {
                "static_routes": [{
                    "network": NETWORK2[addr_type],
                    "next_hop": next_hop_ip["nh1"][addr_type],
                    "admin_distance": 10,
                }]
            }
        }
        nh = [next_hop_ip["nh1"][addr_type]]
        dut = "r2"
        protocol = "static"
        result = verify_rib(tgen,
                            addr_type,
                            dut,
                            rte1_nh1,
                            next_hop=nh,
                            protocol=protocol,
                            fib=True)
        assert (
            result is True
        ), "Testcase {} : Failed \nError: Routes is" "missing in RIB".format(
            tc_name)

        dut = "r3"
        protocol = "bgp"
        result = verify_bgp_rib(tgen, addr_type, dut, rte1_nh1, next_hop=nh)
        assert (
            result is True
        ), "Testcase {} : Failed \nError: Routes is" "missing in RIB".format(
            tc_name)

        rte2_nh2 = {
            "r2": {
                "static_routes": [{
                    "network": NETWORK2[addr_type],
                    "next_hop": next_hop_ip["nh2"][addr_type],
                    "admin_distance": 20,
                }]
            }
        }
        nh = [next_hop_ip["nh2"][addr_type]]
        dut = "r2"
        protocol = "static"
        result = verify_rib(
            tgen,
            addr_type,
            dut,
            rte2_nh2,
            next_hop=nh,
            protocol=protocol,
            fib=True,
            expected=False,
        )
        assert (
            result is not True
        ), "Testcase {} : Failed \nError: Routes is" "not active in RIB".format(
            tc_name)

        dut = "r3"
        protocol = "bgp"
        result = verify_bgp_rib(tgen, addr_type, dut, rte2_nh2, next_hop=nh)
        assert (
            result is True
        ), "Testcase {} : Failed \nError: Routes is" "not active in RIB".format(
            tc_name)

        result = verify_rib(
            tgen,
            addr_type,
            dut,
            rte2_nh2,
            next_hop=nh,
            protocol=protocol,
            fib=True,
            expected=False,
        )
        assert (
            result is not True
        ), "Testcase {} : Failed \nError: Routes is" "not active in RIB".format(
            tc_name)

    write_test_footer(tc_name)
Example #6
0
def test_ospf_lan_tc1_p0(request):
    """
    OSPF Hello protocol - Verify DR BDR Elections

    """
    tc_name = request.node.name
    write_test_header(tc_name)
    tgen = get_topogen()

    # Don't run this test if we have any failure.
    if tgen.routers_have_failure():
        pytest.skip(tgen.errors)

    global topo
    step("Bring up the base config as per the topology")
    reset_config_on_routers(tgen)
    step("Verify that DR BDR DRother are elected in the LAN.")
    input_dict = {
        "r0": {
            "ospf": {
                "neighbors": {
                    "r1": {
                        "state": "Full",
                        "role": "DR"
                    },
                    "r2": {
                        "state": "Full",
                        "role": "DROther"
                    },
                    "r3": {
                        "state": "Full",
                        "role": "DROther"
                    },
                }
            }
        }
    }
    dut = "r0"
    result = verify_ospf_neighbor(tgen, topo, dut, input_dict, lan=True)
    assert result is True, "Testcase {} : Failed \n Error: {}".format(
        tc_name, result)

    step("Verify that all the routers are in FULL state with DR and BDR "
         "in the topology")

    input_dict = {
        "r1": {
            "ospf": {
                "neighbors": {
                    "r0": {
                        "state": "Full",
                        "role": "Backup"
                    },
                    "r2": {
                        "state": "Full",
                        "role": "DROther"
                    },
                    "r3": {
                        "state": "Full",
                        "role": "DROther"
                    },
                }
            }
        }
    }
    dut = "r1"
    result = verify_ospf_neighbor(tgen, topo, dut, input_dict, lan=True)
    assert result is True, "Testcase {} : Failed \n Error: {}".format(
        tc_name, result)

    step("Configure DR pririty 100 on R0 and clear ospf neighbors "
         "on all the routers.")

    input_dict = {
        "r0": {
            "links": {
                "s1": {
                    "interface":
                    topo["routers"]["r0"]["links"]["s1"]["interface"],
                    "ospf": {
                        "priority": 100
                    },
                }
            }
        }
    }

    result = create_interfaces_cfg(tgen, input_dict)
    assert result is True, "Testcase {} :Failed \n Error: {}".format(
        tc_name, result)

    step("Clear ospf neighbours in all routers")
    for rtr in ["r0", "r1", "r2", "r3"]:
        clear_ospf(tgen, rtr)

    step("Verify that DR election is triggered and R0 is elected as DR")
    input_dict = {
        "r0": {
            "ospf": {
                "neighbors": {
                    "r1": {
                        "state": "Full",
                        "role": "Backup"
                    },
                    "r2": {
                        "state": "Full",
                        "role": "DROther"
                    },
                    "r3": {
                        "state": "Full",
                        "role": "DROther"
                    },
                }
            }
        }
    }
    dut = "r0"
    result = verify_ospf_neighbor(tgen, topo, dut, input_dict, lan=True)
    assert result is True, "Testcase {} : Failed \n Error: {}".format(
        tc_name, result)

    step("Configure DR pririty 150 on R0 and clear ospf neighbors "
         "on all the routers.")

    input_dict = {
        "r0": {
            "links": {
                "s1": {
                    "interface":
                    topo["routers"]["r0"]["links"]["s1"]["interface"],
                    "ospf": {
                        "priority": 150
                    },
                }
            }
        }
    }

    result = create_interfaces_cfg(tgen, input_dict)
    assert result is True, "Testcase {} :Failed \n Error: {}".format(
        tc_name, result)

    step("Clear ospf neighbours in all routers")
    for rtr in ["r0", "r1"]:
        clear_ospf(tgen, rtr)

    step("Verify that DR election is triggered and R0 is elected as DR")
    input_dict = {
        "r0": {
            "ospf": {
                "neighbors": {
                    "r1": {
                        "state": "Full",
                        "role": "Backup"
                    },
                    "r2": {
                        "state": "Full",
                        "role": "DROther"
                    },
                    "r3": {
                        "state": "Full",
                        "role": "DROther"
                    },
                }
            }
        }
    }
    dut = "r0"
    result = verify_ospf_neighbor(tgen, topo, dut, input_dict, lan=True)
    assert result is True, "Testcase {} : Failed \n Error: {}".format(
        tc_name, result)

    step("Configure DR priority 0 on R0 & Clear ospf nbrs on all the routers")

    input_dict = {
        "r0": {
            "links": {
                "s1": {
                    "interface":
                    topo["routers"]["r0"]["links"]["s1"]["interface"],
                    "ospf": {
                        "priority": 0
                    },
                }
            }
        }
    }

    result = create_interfaces_cfg(tgen, input_dict)
    assert result is True, "Testcase {} :Failed \n Error: {}".format(
        tc_name, result)

    step("Clear ospf neighbours in all routers")
    for rtr in ["r1"]:
        clear_ospf(tgen, rtr)

    step("Verify that DR election is triggered and R0 is elected as DRother")
    input_dict = {
        "r0": {
            "ospf": {
                "neighbors": {
                    "r1": {
                        "state": "Full",
                        "role": "DR"
                    },
                    "r2": {
                        "state": "2-Way",
                        "role": "DROther"
                    },
                    "r3": {
                        "state": "2-Way",
                        "role": "DROther"
                    },
                }
            }
        }
    }
    dut = "r0"
    result = verify_ospf_neighbor(tgen, topo, dut, input_dict, lan=True)
    assert result is True, "Testcase {} : Failed \n Error: {}".format(
        tc_name, result)

    step("Configure DR priority to default on R0 and Clear ospf neighbors"
         " on all the routers")

    input_dict = {
        "r0": {
            "links": {
                "s1": {
                    "interface":
                    topo["routers"]["r0"]["links"]["s1"]["interface"],
                    "ospf": {
                        "priority": 100
                    },
                }
            }
        }
    }

    result = create_interfaces_cfg(tgen, input_dict)
    assert result is True, "Testcase {} :Failed \n Error: {}".format(
        tc_name, result)

    step("Clear ospf neighbours in all routers")
    for rtr in ["r0", "r1"]:
        clear_ospf(tgen, rtr)

    step("Verify that DR election is triggered and R0 is elected as DR")
    input_dict = {
        "r0": {
            "ospf": {
                "neighbors": {
                    "r1": {
                        "state": "Full",
                        "role": "Backup"
                    },
                    "r2": {
                        "state": "Full",
                        "role": "DROther"
                    },
                    "r3": {
                        "state": "Full",
                        "role": "DROther"
                    },
                }
            }
        }
    }
    dut = "r0"
    result = verify_ospf_neighbor(tgen, topo, dut, input_dict, lan=True)
    assert result is True, "Testcase {} : Failed \n Error: {}".format(
        tc_name, result)

    step("Shut interface on R0")
    dut = "r0"
    intf = topo["routers"]["r0"]["links"]["s1"]["interface"]
    shutdown_bringup_interface(tgen, dut, intf, False)

    result = verify_ospf_neighbor(tgen, topo, dut, lan=True, expected=False)
    assert (
        result is not True
    ), "Testcase {} : Failed \n " "r0: OSPF neighbors-hip is up \n Error: {}".format(
        tc_name, result)

    step("No Shut interface on R0")
    dut = "r0"
    intf = topo["routers"]["r0"]["links"]["s1"]["interface"]
    shutdown_bringup_interface(tgen, dut, intf, True)

    input_dict = {
        "r0": {
            "ospf": {
                "neighbors": {
                    "r1": {
                        "state": "Full",
                        "role": "DR"
                    },
                    "r2": {
                        "state": "Full",
                        "role": "DROther"
                    },
                    "r3": {
                        "state": "Full",
                        "role": "DROther"
                    },
                }
            }
        }
    }
    step("Verify that after no shut ospf neighbours are full on R0.")
    result = verify_ospf_neighbor(tgen, topo, dut, input_dict, lan=True)
    assert result is True, "Testcase {} : Failed \n Error: {}".format(
        tc_name, result)

    step("Clear ospf on DR router in the topology.")
    clear_ospf(tgen, "r0")

    step("Verify that BDR is getting promoted to DR after clear.")
    step("Verify that all the nbrs are in FULL state with the elected DR.")
    result = verify_ospf_neighbor(tgen, topo, dut, input_dict, lan=True)
    assert result is True, "Testcase {} : Failed \n Error: {}".format(
        tc_name, result)

    step("Change the ip on LAN intf on R0 to other ip from the same subnet.")
    topo_modify_change_ip = deepcopy(topo)
    intf_ip = topo_modify_change_ip["routers"]["r0"]["links"]["s1"]["ipv4"]
    topo_modify_change_ip["routers"]["r0"]["links"]["s1"]["ipv4"] = str(
        IPv4Address(frr_unicode(intf_ip.split("/")[0])) + 3) + "/{}".format(
            intf_ip.split("/")[1])

    build_config_from_json(tgen, topo_modify_change_ip, save_bkup=False)

    step("Verify that OSPF is in FULL state with other routers with "
         "newly configured IP.")
    result = verify_ospf_neighbor(tgen, topo, dut, input_dict, lan=True)
    assert result is True, "Testcase {} : Failed \n Error: {}".format(
        tc_name, result)

    step("Change the ospf router id on the R0 and clear ip ospf interface.")
    change_rid = {"r0": {"ospf": {"router_id": "100.1.1.100"}}}

    result = create_router_ospf(tgen, topo, change_rid)
    assert result is True, "Testcase {} : Failed \n Error: {}".format(
        tc_name, result)
    topo["routers"]["r0"]["ospf"]["router_id"] = "100.1.1.100"
    step("Reload the FRR router")

    stop_router(tgen, "r0")
    start_router(tgen, "r0")

    step("Verify that OSPF is in FULL state with other routers with"
         " newly configured router id.")
    input_dict = {
        "r1": {
            "ospf": {
                "neighbors": {
                    "r0": {
                        "state": "Full",
                        "role": "Backup"
                    },
                    "r2": {
                        "state": "Full",
                        "role": "DROther"
                    },
                    "r3": {
                        "state": "Full",
                        "role": "DROther"
                    },
                }
            }
        }
    }
    dut = "r1"
    result = verify_ospf_neighbor(tgen, topo, dut, input_dict, lan=True)
    assert result is True, "Testcase {} : Failed \n Error: {}".format(
        tc_name, result)

    step("Reconfigure the original router id and clear ip ospf interface.")
    change_rid = {"r0": {"ospf": {"router_id": "100.1.1.0"}}}
    result = create_router_ospf(tgen, topo, change_rid)
    assert result is True, "Testcase {} : Failed \n Error: {}".format(
        tc_name, result)
    topo["routers"]["r0"]["ospf"]["router_id"] = "100.1.1.0"
    step("Reload the FRR router")
    # stop/start -> restart FRR router and verify
    stop_router(tgen, "r0")
    start_router(tgen, "r0")

    step("Verify that OSPF is enabled with router id previously configured.")
    input_dict = {
        "r1": {
            "ospf": {
                "neighbors": {
                    "r0": {
                        "state": "Full",
                        "role": "Backup"
                    },
                    "r2": {
                        "state": "Full",
                        "role": "DROther"
                    },
                    "r3": {
                        "state": "Full",
                        "role": "DROther"
                    },
                }
            }
        }
    }
    dut = "r1"
    result = verify_ospf_neighbor(tgen, topo, dut, input_dict, lan=True)
    assert result is True, "Testcase {} : Failed \n Error: {}".format(
        tc_name, result)

    write_test_footer(tc_name)
Example #7
0
def test_static_route_2nh_p0_tc_1_ibgp(request):
    """
    Verify static route ECMP functionality with 2 next hop

    """
    tc_name = request.node.name
    write_test_header(tc_name)
    tgen = get_topogen()
    # Don't run this test if we have any failure.
    if tgen.routers_have_failure():
        pytest.skip(tgen.errors)

    reset_config_on_routers(tgen)
    NEXT_HOP_IP = populate_nh()

    step("Configure IPv4 static route (10.1.1.1) in R2 with next hop N1"
         "(28.1.1.2 ) and N2 (29.1.1.2) , Static route next-hop present on"
         "R1")
    step("ex :- ip route 10.1.1.1/24 28.1.1.2 & ip route 10.1.1.1/24 29.1.1.1")
    for addr_type in ADDR_TYPES:
        input_dict_4 = {
            "r2": {
                "static_routes": [
                    {
                        "network": NETWORK[addr_type],
                        "next_hop": NEXT_HOP_IP["nh1"][addr_type],
                    },
                    {
                        "network": NETWORK[addr_type],
                        "next_hop": NEXT_HOP_IP["nh2"][addr_type],
                    },
                ]
            }
        }

        logger.info("Configure static routes")
        result = create_static_routes(tgen, input_dict_4)
        assert result is True, "Testcase {} : Failed \n Error: {}".format(
            tc_name, result)

        step("On R2, static route installed in RIB using show ip route"
             " with 2 ECMP next hop ")
        nh = [NEXT_HOP_IP["nh1"][addr_type], NEXT_HOP_IP["nh2"][addr_type]]
        dut = "r2"
        protocol = "static"
        result = verify_rib(tgen,
                            addr_type,
                            dut,
                            input_dict_4,
                            next_hop=nh,
                            protocol=protocol)
        assert (
            result is True
        ), "Testcase {} : Failed \nError: Routes is" " missing in RIB".format(
            tc_name)

        step("Configure IBGP IPv4 peering between R2 and R3 router.")
        step("Configure redistribute static in BGP on R2 router")

        input_dict_2 = {
            "r2": {
                "bgp": {
                    "address_family": {
                        addr_type: {
                            "unicast": {
                                "redistribute": [{
                                    "redist_type": "static"
                                }]
                            }
                        }
                    }
                }
            }
        }
        result = create_router_bgp(tgen, topo, input_dict_2)
        assert result is True, "Testcase {} : Failed \n Error: {}".format(
            tc_name, result)

        step(
            "Remove the static route configured with nexthop N1 from running config"
        )
        input_dict_4 = {
            "r2": {
                "static_routes": [{
                    "network": NETWORK[addr_type],
                    "next_hop": NEXT_HOP_IP["nh1"][addr_type],
                    "delete": True,
                }]
            }
        }
        logger.info("Configure static routes")
        result = create_static_routes(tgen, input_dict_4)
        assert result is True, "Testcase {} : Failed \n Error: {}".format(
            tc_name, result)

        step("On R2, after removing the static route with N1 , "
             "route become active with nexthop N2 and vice versa.")
        nh = NEXT_HOP_IP["nh1"][addr_type]
        result = verify_rib(
            tgen,
            addr_type,
            dut,
            input_dict_4,
            next_hop=nh,
            protocol=protocol,
            expected=False,
        )
        assert (
            result is not True
        ), "Testcase {} : Failed \nError: Routes is" " still present in RIB".format(
            tc_name)

        nh = [NEXT_HOP_IP["nh2"][addr_type]]
        result = verify_rib(tgen,
                            addr_type,
                            dut,
                            input_dict_4,
                            next_hop=nh,
                            protocol=protocol)
        assert (
            result is True
        ), "Testcase {} : Failed \nError: Routes is" " missing in RIB".format(
            tc_name)

        step("Configure the static route with nexthop N1")

        input_dict_4 = {
            "r2": {
                "static_routes": [{
                    "network": NETWORK[addr_type],
                    "next_hop": NEXT_HOP_IP["nh1"][addr_type],
                }]
            }
        }

        logger.info("Configure static routes")
        result = create_static_routes(tgen, input_dict_4)
        assert result is True, "Testcase {} : Failed \n Error: {}".format(
            tc_name, result)

        step(
            "Remove the static route configured with nexthop N2 from running config"
        )

        input_dict_4 = {
            "r2": {
                "static_routes": [{
                    "network": NETWORK[addr_type],
                    "next_hop": NEXT_HOP_IP["nh2"][addr_type],
                    "delete": True,
                }]
            }
        }

        logger.info("Configure static routes")
        result = create_static_routes(tgen, input_dict_4)
        assert result is True, "Testcase {} : Failed \n Error: {}".format(
            tc_name, result)

        step("On R2, after removing the static route with N2 , "
             "route become active with nexthop N1 and vice versa.")
        nh = NEXT_HOP_IP["nh2"][addr_type]
        result = verify_rib(
            tgen,
            addr_type,
            dut,
            input_dict_4,
            next_hop=nh,
            protocol=protocol,
            expected=False,
        )
        assert (
            result is not True
        ), "Testcase {} : Failed \nError: Routes is" " still present in RIB".format(
            tc_name)

        nh = [NEXT_HOP_IP["nh1"][addr_type]]
        result = verify_rib(tgen,
                            addr_type,
                            dut,
                            input_dict_4,
                            next_hop=nh,
                            protocol=protocol)
        assert (
            result is True
        ), "Testcase {} : Failed \nError: Routes is" " missing in RIB".format(
            tc_name)

        step("Configure the static route with nexthop N2")
        input_dict_4 = {
            "r2": {
                "static_routes": [{
                    "network": NETWORK[addr_type],
                    "next_hop": NEXT_HOP_IP["nh2"][addr_type],
                }]
            }
        }

        logger.info("Configure static routes")
        result = create_static_routes(tgen, input_dict_4)
        assert result is True, "Testcase {} : Failed \n Error: {}".format(
            tc_name, result)

        step("Shut nexthop interface N1")
        intf = topo["routers"]["r2"]["links"]["r1-link0"]["interface"]

        shutdown_bringup_interface(tgen, dut, intf, False)

        step("Only one the nexthops should be active in RIB.")

        nh = NEXT_HOP_IP["nh2"][addr_type]
        result = verify_rib(tgen,
                            addr_type,
                            dut,
                            input_dict_4,
                            next_hop=nh,
                            protocol=protocol)
        assert (
            result is True
        ), "Testcase {} : Failed \nError: Routes is" " missing in RIB".format(
            tc_name)

        nh = NEXT_HOP_IP["nh1"][addr_type]
        result = verify_rib(
            tgen,
            addr_type,
            dut,
            input_dict_4,
            next_hop=nh,
            protocol=protocol,
            expected=False,
        )
        assert (
            result is not True
        ), "Testcase {} : Failed \nError: Routes is" " still present in RIB".format(
            tc_name)

        dut = "r3"
        result = verify_bgp_rib(tgen,
                                addr_type,
                                dut,
                                input_dict_4,
                                next_hop=nh,
                                expected=False)
        assert (
            result is not True
        ), "Testcase {} : Failed \nError: Route is" " still present in RIB".format(
            tc_name)

        result = verify_rib(
            tgen,
            addr_type,
            dut,
            input_dict_4,
            protocol=protocol,
            next_hop=nh,
            expected=False,
        )
        assert (
            result is not True
        ), "Testcase {} : Failed \nError: Route is" " still present in RIB".format(
            tc_name)

        dut = "r2"
        nh = [NEXT_HOP_IP["nh2"][addr_type]]
        result = verify_rib(tgen,
                            addr_type,
                            dut,
                            input_dict_4,
                            next_hop=nh,
                            protocol=protocol)
        assert (
            result is True
        ), "Testcase {} : Failed \nError: Routes is" " missing in RIB".format(
            tc_name)

        dut = "r3"
        result = verify_bgp_rib(tgen, addr_type, dut, input_dict_4)
        assert (
            result is True
        ), "Testcase {} : Failed \nError: Route is" " missing in RIB".format(
            tc_name)

        result = verify_rib(tgen,
                            addr_type,
                            dut,
                            input_dict_4,
                            protocol=protocol,
                            expected=False)
        assert (
            result is not True
        ), "Testcase {} : Failed \nError: Route is" " still present in RIB".format(
            tc_name)

        dut = "r2"
        step("No shut the nexthop interface N1")
        shutdown_bringup_interface(tgen, dut, intf, True)

        step("after shut of nexthop N1 , route become active "
             "with nexthop N2 and vice versa.")
        nh = [NEXT_HOP_IP["nh1"][addr_type], NEXT_HOP_IP["nh2"][addr_type]]

        result = verify_rib(tgen,
                            addr_type,
                            dut,
                            input_dict_4,
                            next_hop=nh,
                            protocol=protocol)
        assert (
            result is True
        ), "Testcase {} : Failed \nError: Routes is" " missing in RIB".format(
            tc_name)

        step("Shut nexthop interface N2")
        intf = topo["routers"]["r2"]["links"]["r1-link1"]["interface"]
        dut = "r2"
        shutdown_bringup_interface(tgen, dut, intf, False)

        step(" after shut of nexthop N1 , route become active with "
             "nexthop N2 and vice versa.")
        nh = NEXT_HOP_IP["nh2"][addr_type]

        result = verify_rib(
            tgen,
            addr_type,
            dut,
            input_dict_4,
            next_hop=nh,
            protocol=protocol,
            expected=False,
        )
        assert (
            result is not True
        ), "Testcase {} : Failed \nError: Routes is" " still present in RIB".format(
            tc_name)

        nh = [NEXT_HOP_IP["nh1"][addr_type]]
        dut = "r2"
        protocol = "static"
        result = verify_rib(tgen,
                            addr_type,
                            dut,
                            input_dict_4,
                            next_hop=nh,
                            protocol=protocol)
        assert (
            result is True
        ), "Testcase {} : Failed \nError: Routes is" " missing in RIB".format(
            tc_name)

        dut = "r3"
        result = verify_bgp_rib(tgen, addr_type, dut, input_dict_4)
        assert (
            result is True
        ), "Testcase {} : Failed \nError: Route is" " missing in RIB".format(
            tc_name)

        result = verify_rib(tgen,
                            addr_type,
                            dut,
                            input_dict_4,
                            protocol=protocol,
                            expected=False)
        assert (
            result is not True
        ), "Testcase {} : Failed \nError: Route is" " still present in RIB".format(
            tc_name)

        step("No shut nexthop interface N2")
        dut = "r2"
        shutdown_bringup_interface(tgen, dut, intf, True)

        step("after shut of nexthop N1 , route become active "
             "with nexthop N2 and vice versa.")
        nh = [NEXT_HOP_IP["nh1"][addr_type], NEXT_HOP_IP["nh2"][addr_type]]

        result = verify_rib(tgen,
                            addr_type,
                            dut,
                            input_dict_4,
                            next_hop=nh,
                            protocol=protocol)
        assert (
            result is True
        ), "Testcase {} : Failed \nError: Routes is" " missing in RIB".format(
            tc_name)

        dut = "r3"
        result = verify_bgp_rib(tgen, addr_type, dut, input_dict_4)
        assert (
            result is True
        ), "Testcase {} : Failed \nError: Route is" " missing in RIB".format(
            tc_name)

        result = verify_rib(tgen,
                            addr_type,
                            dut,
                            input_dict_4,
                            protocol=protocol,
                            expected=False)
        assert (
            result is not True
        ), "Testcase {} : Failed \nError: Route is" " still present in RIB".format(
            tc_name)

        step("Reload the FRR router")
        # stop/start -> restart FRR router and verify
        stop_router(tgen, "r2")

        start_router(tgen, "r2")

        dut = "r2"
        step("After reload of FRR router , static route installed"
             " in RIB and FIB properly .")
        result = verify_rib(tgen,
                            addr_type,
                            dut,
                            input_dict_4,
                            next_hop=nh,
                            protocol=protocol)
        assert (
            result is True
        ), "Testcase {} : Failed \nError: Routes is" " missing in RIB".format(
            tc_name)

        dut = "r3"
        result = verify_bgp_rib(tgen, addr_type, dut, input_dict_4)
        assert (
            result is True
        ), "Testcase {} : Failed \nError: Route is" " still present in RIB".format(
            tc_name)

        result = verify_rib(tgen,
                            addr_type,
                            dut,
                            input_dict_4,
                            protocol=protocol,
                            expected=False)
        assert (
            result is not True
        ), "Testcase {} : Failed \nError: Route is" " still present in RIB".format(
            tc_name)

    write_test_footer(tc_name)
def test_pim_source_dr_functionality_while_rebooting_dr_non_dr_nodes_p1(
        request):
    """
    Verify mroute while rebooting DR /Non DR nodes( r1, r2 , r3 on all the nodes)
    """

    tgen = get_topogen()
    tc_name = request.node.name
    write_test_header(tc_name)

    # Creating configuration from JSON
    app_helper.stop_all_hosts()
    clear_mroute(tgen)
    check_router_status(tgen)
    reset_config_on_routers(tgen)
    clear_pim_interface_traffic(tgen, topo)

    # Don"t run this test if we have any failure.
    if tgen.routers_have_failure():
        pytest.skip(tgen.errors)

    result = pre_config_for_source_dr_tests(tgen, topo, tc_name, "r1", "r3")
    assert result is True, "Testcase {} : Failed Error: {}".format(
        tc_name, result)

    step("R1 is the DR , verify using 'show ip pim interface json'")

    vlan_intf_r1_s1 = "{}.{}".format(intf_r1_s1, VLAN_1)
    input_dict_dr = {
        "r1": {
            "pim": {
                "interfaces": {
                    vlan_intf_r1_s1: {
                        "drAddress": SAME_VLAN_IP_3["ip"]
                    }
                }
            }
        }
    }
    result = verify_pim_config(tgen, input_dict_dr)
    assert result is True, "Testcase {} : Failed Error: {}".format(
        tc_name, result)

    step(
        "R2 is transit router for R3 to reach R4, mroute should have (s, g) mroute with "
        "OIL towards R4, using 'show ip mroute json'")
    step("R2 (s, g) upstream should be in join state verify using "
         "'show ip pim upstream json'")
    step(
        "R1 has (S, G) mroute with NONE OIL and upstream as not joined, verify using "
        "'show ip mroute json' 'show ip pim upstream json'")

    source_i1 = SAME_VLAN_IP_4["ip"]
    input_dict_r1_r2 = [
        {
            "dut":
            "r1",
            "src_address":
            source_i1,
            "oil":
            "none",
            "iif":
            "{}.{}".format(topo["routers"]["r1"]["links"]["s1"]["interface"],
                           VLAN_1),
        },
        {
            "dut":
            "r2",
            "src_address":
            source_i1,
            "oil":
            topo["routers"]["r2"]["links"]["r4"]["interface"],
            "iif":
            "{}.{}".format(topo["routers"]["r2"]["links"]["s1"]["interface"],
                           VLAN_1),
        },
    ]

    for data in input_dict_r1_r2:
        result = verify_mroutes(
            tgen,
            data["dut"],
            data["src_address"],
            IGMP_JOIN_RANGE_1,
            data["iif"],
            data["oil"],
        )
        assert result is True, "Testcase {} : Failed Error: {}".format(
            tc_name, result)

        if data["dut"] == "r2":
            result = verify_upstream_iif(tgen, data["dut"], data["iif"],
                                         data["src_address"],
                                         IGMP_JOIN_RANGE_1)
            assert result is True, "Testcase {} : Failed Error: {}".format(
                tc_name, result)
        else:
            result = verify_upstream_iif(
                tgen,
                data["dut"],
                data["iif"],
                data["src_address"],
                IGMP_JOIN_RANGE_1,
                expected=False,
            )
            assert result is not True, (
                "Testcase {} : Failed \n "
                "Upstream is still joined state \n Error: {}".format(
                    tc_name, result))

    step("Reboot R3 node")
    stop_router(tgen, "r3")

    step(
        "After reboot of R3 verify R1 became DR, using 'show ip pim interface json'"
    )

    result = verify_pim_config(tgen, input_dict_dr)
    assert result is True, "Testcase {} : Failed Error: {}".format(
        tc_name, result)

    step("R3 should not have any mroute and upstream")
    step(
        "R2 has mroute with OIL towards R4 /R1 , verify using 'show ip mroute'"
    )
    step(
        "R2 has upstream with Join RejP state verify using 'show ip pim upstream json'"
    )
    step("R1 has mroute with none OIL and upstream with Not Join")

    for data in input_dict_r1_r2:
        result = verify_mroutes(
            tgen,
            data["dut"],
            data["src_address"],
            IGMP_JOIN_RANGE_1,
            data["iif"],
            data["oil"],
        )
        assert result is True, "Testcase {} : Failed Error: {}".format(
            tc_name, result)

        if data["dut"] == "r2":
            result = verify_upstream_iif(tgen, data["dut"], data["iif"],
                                         data["src_address"],
                                         IGMP_JOIN_RANGE_1)
            assert result is True, "Testcase {} : Failed Error: {}".format(
                tc_name, result)
        else:
            result = verify_upstream_iif(
                tgen,
                data["dut"],
                data["iif"],
                data["src_address"],
                IGMP_JOIN_RANGE_1,
                expected=False,
            )
            assert result is not True, (
                "Testcase {} : Failed \n "
                "Upstream is still joined state \n Error: {}".format(
                    tc_name, result))

    step("Reboot R2 node")
    stop_router(tgen, "r2")

    step(
        "After reboot of R2, R1 became DR verify using 'show ip pim interface json'"
    )

    result = verify_pim_config(tgen, input_dict_dr)
    assert result is True, "Testcase {} : Failed Error: {}".format(
        tc_name, result)

    step("R3 and R2 should not have any mroute and upstream , verify using "
         "'show ip mroute json' 'show ip pim upstream json'")
    step(
        "R1 has mroute created with OIL towards R4 , using 'show ip mroute json'"
    )
    step(
        "R1 has upstream with Join Rej Prune , verify using 'show ip pim upstream json'"
    )

    for data in input_dict_r1_r2:
        if data["dut"] == "r1":
            result = verify_mroutes(
                tgen,
                data["dut"],
                data["src_address"],
                IGMP_JOIN_RANGE_1,
                data["iif"],
                data["oil"],
            )
            assert result is True, "Testcase {} : Failed Error: {}".format(
                tc_name, result)

            result = verify_upstream_iif(
                tgen,
                data["dut"],
                data["iif"],
                data["src_address"],
                IGMP_JOIN_RANGE_1,
                expected=False,
            )
            assert result is not True, (
                "Testcase {} : Failed \n "
                "Upstream is still joined state \n Error: {}".format(
                    tc_name, result))

    step("Reboot R1 node using FRR stop")
    stop_router(tgen, "r1")

    step("After stop of all the routers, verify upstream and mroutes should "
         "not present in any of them")

    for data in input_dict_r1_r2:
        result = verify_mroutes(
            tgen,
            data["dut"],
            data["src_address"],
            IGMP_JOIN_RANGE_1,
            data["iif"],
            data["oil"],
            expected=False,
        )
        assert (
            result is not True
        ), "Testcase {} : Failed \n " "mroutes are still present \n Error: {}".format(
            tc_name, result)

    step("start FRR for all the nodes")
    start_router(tgen, "r1")
    start_router(tgen, "r2")
    start_router(tgen, "r3")

    step("After start of all the routers, R1 became DR")

    result = verify_pim_config(tgen, input_dict_dr)
    assert result is True, "Testcase {} : Failed Error: {}".format(
        tc_name, result)

    for data in input_dict_r1_r2:
        result = verify_mroutes(
            tgen,
            data["dut"],
            data["src_address"],
            IGMP_JOIN_RANGE_1,
            data["iif"],
            data["oil"],
        )
        assert result is True, "Testcase {} : Failed Error: {}".format(
            tc_name, result)

        if data["dut"] == "r2":
            result = verify_upstream_iif(tgen, data["dut"], data["iif"],
                                         data["src_address"],
                                         IGMP_JOIN_RANGE_1)
            assert result is True, "Testcase {} : Failed Error: {}".format(
                tc_name, result)

    write_test_footer(tc_name)
Example #9
0
def test_verify_restarting_zebra_bgpd_staticd_frr_with_eBGP_peers_p0(request):
    """
    Verify graceful-shutdown functionality when daemons bgpd/zebra/staticd and
    frr services are restarted with eBGP peers
    """

    tc_name = request.node.name
    write_test_header(tc_name)
    tgen = get_topogen()
    reset_config_on_routers(tgen)

    step("Done in base config: Configure base config as per the topology")
    step("Base config should be up, verify using BGP convergence")
    result = verify_bgp_convergence(tgen, topo)
    assert result is True, "Test case {} : Failed \n Error: {}".format(
        tc_name, result)

    step("Done in base config: Advertise prefixes from R1")
    step("Verify BGP routes are received at R3 with best path from R3 to R1")

    for addr_type in ADDR_TYPES:
        dut = "r3"
        next_hop1 = next_hop_per_address_family(tgen, "r3", "r1", addr_type,
                                                NEXT_HOP_IP_1)
        next_hop2 = next_hop_per_address_family(tgen, "r3", "r4", addr_type,
                                                NEXT_HOP_IP_2)

        input_topo = {key: topo["routers"][key] for key in ["r1"]}
        result = verify_bgp_rib(tgen,
                                addr_type,
                                dut,
                                input_topo,
                                next_hop=[next_hop1, next_hop2])
        assert result is True, "Test case {} : Failed \n Error: {}".format(
            tc_name, result)

        result = verify_rib(tgen,
                            addr_type,
                            dut,
                            input_topo,
                            next_hop=next_hop1)
        assert result is True, "Test case {} : Failed \n Error: {}".format(
            tc_name, result)

    step("On R1 configure:")
    step("Create standard bgp community-list to permit graceful-shutdown:")
    input_dict_1 = {
        "r1": {
            "bgp_community_lists": [{
                "community_type": "standard",
                "action": "permit",
                "name": "GSHUT",
                "value": "graceful-shutdown",
            }]
        }
    }

    result = create_bgp_community_lists(tgen, input_dict_1)
    assert result is True, "Test case {} : Failed \n Error: {}".format(
        tc_name, result)

    step("Create route-map to set community GSHUT in OUT direction")

    input_dict_2 = {
        "r1": {
            "route_maps": {
                "GSHUT-OUT": [{
                    "action": "permit",
                    "seq_id": "10",
                    "set": {
                        "community": {
                            "num": "graceful-shutdown"
                        }
                    },
                }]
            }
        }
    }

    result = create_route_maps(tgen, input_dict_2)
    assert result is True, "Test case {} : Failed \n Error: {}".format(
        tc_name, result)

    input_dict_3 = {
        "r1": {
            "bgp": {
                "address_family": {
                    "ipv4": {
                        "unicast": {
                            "neighbor": {
                                "r3": {
                                    "dest_link": {
                                        "r1": {
                                            "route_maps": [{
                                                "name": "GSHUT-OUT",
                                                "direction": "out",
                                            }]
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "ipv6": {
                        "unicast": {
                            "neighbor": {
                                "r3": {
                                    "dest_link": {
                                        "r1": {
                                            "route_maps": [{
                                                "name": "GSHUT-OUT",
                                                "direction": "out",
                                            }]
                                        }
                                    }
                                }
                            }
                        }
                    },
                }
            }
        }
    }

    result = create_router_bgp(tgen, topo, input_dict_3)
    assert result is True, "Test case {} : Failed \n Error: {}".format(
        tc_name, result)

    step(
        "FRR is setting local-pref to 0 by-default on receiver GSHUT community, "
        "below step is not needed, but keeping for reference")
    step("On R3, apply route-map IN direction to match GSHUT community "
         "and set local-preference to 0.")

    step("Verify BGP convergence on R3 and ensure all the neighbours state "
         "is established")

    result = verify_bgp_convergence(tgen, topo)
    assert result is True, "Test case {} : Failed \n Error: {}".format(
        tc_name, result)

    step("Verify BGP routes on R3:")
    step("local pref for routes coming from R1 is set to 0.")

    for addr_type in ADDR_TYPES:
        rmap_dict = {
            "r1": {
                "route_maps": {
                    "GSHUT-OUT": [{
                        "set": {
                            "locPrf": 0
                        }
                    }]
                }
            }
        }

        static_routes = [NETWORK[addr_type]]
        result = verify_bgp_attributes(tgen, addr_type, dut, static_routes,
                                       "GSHUT-OUT", rmap_dict)
        assert result is True, "Test case {} : Failed \n Error: {}".format(
            tc_name, result)

    step("Ensure that best path is selected from R4 to R3.")

    for addr_type in ADDR_TYPES:
        dut = "r3"
        next_hop1 = next_hop_per_address_family(tgen, "r3", "r1", addr_type,
                                                NEXT_HOP_IP_1)
        next_hop2 = next_hop_per_address_family(tgen, "r3", "r4", addr_type,
                                                NEXT_HOP_IP_2)

        input_topo = {key: topo["routers"][key] for key in ["r1"]}
        result = verify_bgp_rib(tgen,
                                addr_type,
                                dut,
                                input_topo,
                                next_hop=[next_hop1, next_hop2])
        assert result is True, "Test case {} : Failed \n Error: {}".format(
            tc_name, result)

        result = verify_rib(tgen,
                            addr_type,
                            dut,
                            input_topo,
                            next_hop=next_hop2)
        assert result is True, "Test case {} : Failed \n Error: {}".format(
            tc_name, result)

    step("Restart daemons and frr services")

    for daemon in ["bgpd", "zebra", "staticd", "frr"]:
        if daemon != "frr":
            kill_router_daemons(tgen, "r3", ["staticd"])
            start_router_daemons(tgen, "r3", ["staticd"])
        else:
            stop_router(tgen, "r3")
            start_router(tgen, "r3")

        step(
            "Verify BGP convergence on R3 and ensure all the neighbours state "
            "is established")

        result = verify_bgp_convergence(tgen, topo)
        assert result is True, "Test case {} : Failed \n Error: {}".format(
            tc_name, result)

        step("Verify BGP routes on R3:")
        step("local pref for routes coming from R1 is set to 0.")

        for addr_type in ADDR_TYPES:
            rmap_dict = {
                "r1": {
                    "route_maps": {
                        "GSHUT-OUT": [{
                            "set": {
                                "locPrf": 0
                            }
                        }]
                    }
                }
            }

            static_routes = [NETWORK[addr_type]]
            result = verify_bgp_attributes(tgen, addr_type, dut, static_routes,
                                           "GSHUT-OUT", rmap_dict)
            assert result is True, "Test case {} : Failed \n Error: {}".format(
                tc_name, result)

        step("Ensure that best path is selected from R4 to R3.")

        for addr_type in ADDR_TYPES:
            dut = "r3"
            next_hop1 = next_hop_per_address_family(tgen, "r3", "r1",
                                                    addr_type, NEXT_HOP_IP_1)
            next_hop2 = next_hop_per_address_family(tgen, "r3", "r4",
                                                    addr_type, NEXT_HOP_IP_2)

            input_topo = {key: topo["routers"][key] for key in ["r1"]}
            result = verify_bgp_rib(tgen,
                                    addr_type,
                                    dut,
                                    input_topo,
                                    next_hop=[next_hop1, next_hop2])
            assert result is True, "Test case {} : Failed \n Error: {}".format(
                tc_name, result)

            result = verify_rib(tgen,
                                addr_type,
                                dut,
                                input_topo,
                                next_hop=next_hop2)
            assert result is True, "Test case {} : Failed \n Error: {}".format(
                tc_name, result)

    write_test_footer(tc_name)