Example #1
0
def get_llip(onrouter, intf):
    """
    API to get the link local ipv6 address of a perticular interface

    Parameters
    ----------
    * `fromnode`: Source node
    * `tonode` : interface for which link local ip needs to be returned.

    Usage
    -----
    result = get_llip('r1', 'r2-link0')

    Returns
    -------
    1) link local ipv6 address from the interface.
    2) errormsg - when link local ip not found.
    """
    tgen = get_topogen()
    intf = topo["routers"][onrouter]["links"][intf]["interface"]
    llip = get_frr_ipv6_linklocal(tgen, onrouter, intf)
    if llip:
        logger.info("llip ipv6 address to be set as NH is %s", llip)
        return llip
    return None
def next_hop_per_address_family(tgen, dut, peer, addr_type, next_hop_dict):
    """
    This function returns link_local or global next_hop per address-family
    """

    intferface = topo["routers"][peer]["links"]["{}-link1".format(dut)]["interface"]
    if addr_type == "ipv6" and "link_local" in PREFERRED_NEXT_HOP:
        next_hop = get_frr_ipv6_linklocal(tgen, peer, intf=intferface)
    else:
        next_hop = next_hop_dict[addr_type]

    return next_hop
def test_BGP_GR_chaos_33_p1(request):
    """
    Test Objective : Helper router receives same prefixes from two
    different routers (GR-restarting and GR-disabled). Keeps the
    stale entry only for GR-restarting node(next-hop is correct).
    """

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

    # Check router status
    check_router_status(tgen)

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

    # Creating configuration from JSON
    reset_config_on_routers(tgen)

    logger.info(
        " Test Case : test_BGP_GR_chaos_33 "
        "BGP GR "
        "[Restart Mode]R1--R3[Helper Mode]--R4[Disabled Mode]"
    )

    # Configure graceful-restart
    input_dict = {
        "r1": {
            "bgp": {
                "address_family": {
                    "ipv4": {
                        "unicast": {
                            "neighbor": {
                                "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
                            }
                        }
                    },
                    "ipv6": {
                        "unicast": {
                            "neighbor": {
                                "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
                            }
                        }
                    },
                }
            }
        },
        "r3": {
            "bgp": {
                "address_family": {
                    "ipv4": {
                        "unicast": {
                            "neighbor": {
                                "r1": {
                                    "dest_link": {
                                        "r3": {"graceful-restart-helper": True}
                                    }
                                }
                            }
                        }
                    },
                    "ipv6": {
                        "unicast": {
                            "neighbor": {
                                "r1": {
                                    "dest_link": {
                                        "r3": {"graceful-restart-helper": True}
                                    }
                                }
                            }
                        }
                    },
                }
            }
        },
        "r4": {
            "bgp": {
                "address_family": {
                    "ipv4": {
                        "unicast": {
                            "neighbor": {
                                "r3": {
                                    "dest_link": {
                                        "r4": {"graceful-restart-disable": True}
                                    }
                                }
                            }
                        }
                    },
                    "ipv6": {
                        "unicast": {
                            "neighbor": {
                                "r3": {
                                    "dest_link": {
                                        "r4": {"graceful-restart-disable": True}
                                    }
                                }
                            }
                        }
                    },
                }
            }
        },
    }

    configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r3")

    for addr_type in ADDR_TYPES:
        result = verify_graceful_restart(
            tgen, topo, addr_type, input_dict, dut="r1", peer="r3"
        )
        assert result is True, "Testcase {} : Failed \n Error {}".format(
            tc_name, result
        )

    logger.info("[Step 2] : Advertise same networks from R1 and R4..")

    # Api call to delete advertised networks
    input_dict_2 = {
        "r1": {
            "bgp": {
                "address_family": {
                    "ipv4": {
                        "unicast": {
                            "advertise_networks": [
                                {
                                    "network": "200.0.20.1/32",
                                    "no_of_network": 2,
                                }
                            ]
                        }
                    },
                    "ipv6": {
                        "unicast": {
                            "advertise_networks": [
                                {"network": "2001::1/128", "no_of_network": 2}
                            ]
                        }
                    },
                }
            }
        },
        "r4": {
            "bgp": {
                "address_family": {
                    "ipv4": {
                        "unicast": {
                            "advertise_networks": [
                                {"network": "200.0.20.1/32", "no_of_network": 2}
                            ]
                        }
                    },
                    "ipv6": {
                        "unicast": {
                            "advertise_networks": [
                                {"network": "2001::1/128", "no_of_network": 2}
                            ]
                        }
                    },
                }
            }
        },
    }

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

    for addr_type in ADDR_TYPES:
        # Verifying RIB routes
        dut = "r3"
        peer1 = "r1"
        peer2 = "r4"
        intf1 = topo["routers"][peer1]["links"][dut]["interface"]
        intf2 = topo["routers"][peer2]["links"][dut]["interface"]

        if addr_type == "ipv4":
            next_hop_4 = NEXT_HOP_4
            result = verify_rib(tgen, addr_type, dut, input_dict_2, next_hop_4)
            assert result is True, "Testcase {} : Failed \n Error {}".format(
                tc_name, result
            )

        if addr_type == "ipv6":
            if "link_local" in PREFERRED_NEXT_HOP:
                next_hop1 = get_frr_ipv6_linklocal(tgen, peer1, intf=intf1)
                next_hop2 = get_frr_ipv6_linklocal(tgen, peer2, intf=intf2)

                next_hop_6 = [next_hop1, next_hop2]
            else:
                next_hop_6 = NEXT_HOP_6

            result = verify_rib(tgen, addr_type, dut, input_dict_2, next_hop_6)
            assert result is True, "Testcase {} : Failed \n Error {}".format(
                tc_name, result
            )

    logger.info("[Step 3] : Kill BGPd daemon on R1 and R4..")

    # Kill BGPd daemon on R1
    kill_router_daemons(tgen, "r1", ["bgpd"])

    # Kill BGPd daemon on R4
    kill_router_daemons(tgen, "r4", ["bgpd"])

    for addr_type in ADDR_TYPES:
        # Verifying RIB routes
        next_hop_6 = ["fd00:0:0:1::1"]
        if addr_type == "ipv4":
            next_hop_4 = NEXT_HOP_4[0]

            result = verify_rib(tgen, addr_type, dut, input_dict_2, next_hop_4)
            assert result is True, "Testcase {} : Failed \n Error {}".format(
                tc_name, result
            )

        if addr_type == "ipv6":
            if "link_local" in PREFERRED_NEXT_HOP:
                next_hop_6 = get_frr_ipv6_linklocal(tgen, peer1, intf=intf1)
            else:
                next_hop_6 = NEXT_HOP_6[0]

            result = verify_rib(tgen, addr_type, dut, input_dict_2, next_hop_6)

        # Verifying RIB routes
        if addr_type == "ipv4":
            next_hop_4 = NEXT_HOP_4[1]
            result = verify_rib(
                tgen, addr_type, dut, input_dict_2, next_hop_4, expected=False
            )
            assert result is not True, (
                "Testcase {} : Failed \n "
                "r3: routes are still present in BGP RIB\n Error: {}".format(
                    tc_name, result
                )
            )
            logger.info(" Expected behavior: {}".format(result))

        if addr_type == "ipv6":
            if "link_local" in PREFERRED_NEXT_HOP:
                next_hop_6 = get_frr_ipv6_linklocal(tgen, peer2, intf=intf2)
            else:
                next_hop_6 = NEXT_HOP_6[1]

            result = verify_rib(
                tgen, addr_type, dut, input_dict_2, next_hop_6, expected=False
            )
            assert result is not True, (
                "Testcase {} : Failed \n "
                "r3: routes are still present in ZEBRA\n Error: {}".format(
                    tc_name, result
                )
            )
            logger.info(" Expected behavior: {}".format(result))

    logger.info("[Step 4] : Start BGPd daemon on R1 and R4..")

    # Start BGPd daemon on R1
    start_router_daemons(tgen, "r1", ["bgpd"])

    # Start BGPd daemon on R4
    start_router_daemons(tgen, "r4", ["bgpd"])

    write_test_footer(tc_name)
def test_bgp_best_path_with_dynamic_import_p0(request):
    """
    TC6_FUNC_6:
    1.5.6. Verify BGP best path selection algorithm works fine when
    routes are imported from ISR to default vrf and vice versa.
    """

    tgen = get_topogen()
    tc_name = request.node.name
    write_test_header(tc_name)
    build_config_from_json(tgen, topo)

    if tgen.routers_have_failure():
        check_router_status(tgen)

    for addr_type in ADDR_TYPES:

        step("Redistribute configured static routes into BGP process"
             " on R1/R2 and R3")

        input_dict_1 = {}
        DUT = ["r1", "r2", "r3", "r4"]
        VRFS = ["ISR", "ISR", "default", "default"]
        AS_NUM = [100, 100, 300, 400]

        for dut, vrf, as_num in zip(DUT, VRFS, AS_NUM):
            temp = {dut: {"bgp": []}}
            input_dict_1.update(temp)

            temp[dut]["bgp"].append({
                "local_as": as_num,
                "vrf": vrf,
                "address_family": {
                    addr_type: {
                        "unicast": {
                            "redistribute": [{
                                "redist_type": "static"
                            }]
                        }
                    }
                },
            })

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

    for addr_type in ADDR_TYPES:

        step("Import from default vrf into vrf ISR on R1 and R2 as below")

        input_dict_vrf = {}
        DUT = ["r1", "r2"]
        VRFS = ["ISR", "ISR"]
        AS_NUM = [100, 100]

        for dut, vrf, as_num in zip(DUT, VRFS, AS_NUM):
            temp = {dut: {"bgp": []}}
            input_dict_vrf.update(temp)

            temp[dut]["bgp"].append({
                "local_as": as_num,
                "vrf": vrf,
                "address_family": {
                    addr_type: {
                        "unicast": {
                            "import": {
                                "vrf": "default"
                            }
                        }
                    }
                },
            })

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

        input_dict_default = {}
        DUT = ["r1", "r2"]
        VRFS = ["default", "default"]
        AS_NUM = [100, 100]

        for dut, vrf, as_num in zip(DUT, VRFS, AS_NUM):
            temp = {dut: {"bgp": []}}
            input_dict_default.update(temp)

            temp[dut]["bgp"].append({
                "local_as": as_num,
                "vrf": vrf,
                "address_family": {
                    addr_type: {
                        "unicast": {
                            "import": {
                                "vrf": "ISR"
                            }
                        }
                    }
                },
            })

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

    step("Verify ECMP/Next-hop/Imported routes Vs Locally originated "
         "routes/eBGP routes vs iBGP routes --already covered in almost"
         " all tests")

    for addr_type in ADDR_TYPES:

        step("Verify Pre-emption")

        input_routes_r3 = {
            "r3": {
                "static_routes": [{
                    "network": [NETWORK3_3[addr_type]]
                }]
            }
        }

        intf_r3_r1 = topo["routers"]["r3"]["links"]["r1-link1"]["interface"]
        intf_r4_r1 = topo["routers"]["r4"]["links"]["r1-link1"]["interface"]

        if addr_type == "ipv6" and "link_local" in PREFERRED_NEXT_HOP:
            nh_r3_r1 = get_frr_ipv6_linklocal(tgen, "r3", intf=intf_r3_r1)
            nh_r4_r1 = get_frr_ipv6_linklocal(tgen, "r4", intf=intf_r4_r1)
        else:
            nh_r3_r1 = topo["routers"]["r3"]["links"]["r1-link1"][
                addr_type].split("/")[0]
            nh_r4_r1 = topo["routers"]["r4"]["links"]["r1-link1"][
                addr_type].split("/")[0]

        result = verify_bgp_rib(tgen,
                                addr_type,
                                "r1",
                                input_routes_r3,
                                next_hop=[nh_r4_r1])
        assert result is True, "Testcase {} : Failed \n Error {}".format(
            tc_name, result)

    step("Shutdown interface connected to r1 from r4:")
    shutdown_bringup_interface(tgen, "r4", intf_r4_r1, False)

    for addr_type in ADDR_TYPES:

        input_routes_r3 = {
            "r3": {
                "static_routes": [{
                    "network": [NETWORK3_3[addr_type]]
                }]
            }
        }

        intf_r3_r1 = topo["routers"]["r3"]["links"]["r1-link1"]["interface"]
        intf_r4_r1 = topo["routers"]["r4"]["links"]["r1-link1"]["interface"]

        if addr_type == "ipv6" and "link_local" in PREFERRED_NEXT_HOP:
            nh_r3_r1 = get_frr_ipv6_linklocal(tgen, "r3", intf=intf_r3_r1)
            nh_r4_r1 = get_frr_ipv6_linklocal(tgen, "r4", intf=intf_r4_r1)
        else:
            nh_r3_r1 = topo["routers"]["r3"]["links"]["r1-link1"][
                addr_type].split("/")[0]
            nh_r4_r1 = topo["routers"]["r4"]["links"]["r1-link1"][
                addr_type].split("/")[0]

        step("Verify next-hop is changed")
        result = verify_bgp_rib(tgen,
                                addr_type,
                                "r1",
                                input_routes_r3,
                                next_hop=[nh_r3_r1])
        assert result is True, "Testcase {} : Failed \n Error {}".format(
            tc_name, result)

    step("Bringup interface connected to r1 from r4:")
    shutdown_bringup_interface(tgen, "r4", intf_r4_r1, True)

    for addr_type in ADDR_TYPES:

        input_routes_r3 = {
            "r3": {
                "static_routes": [{
                    "network": [NETWORK3_3[addr_type]]
                }]
            }
        }

        intf_r3_r1 = topo["routers"]["r3"]["links"]["r1-link1"]["interface"]
        intf_r4_r1 = topo["routers"]["r4"]["links"]["r1-link1"]["interface"]

        if addr_type == "ipv6" and "link_local" in PREFERRED_NEXT_HOP:
            nh_r3_r1 = get_frr_ipv6_linklocal(tgen, "r3", intf=intf_r3_r1)
            nh_r4_r1 = get_frr_ipv6_linklocal(tgen, "r4", intf=intf_r4_r1)
        else:
            nh_r3_r1 = topo["routers"]["r3"]["links"]["r1-link1"][
                addr_type].split("/")[0]
            nh_r4_r1 = topo["routers"]["r4"]["links"]["r1-link1"][
                addr_type].split("/")[0]

        step("Verify next-hop is not chnaged aftr shutdown:")
        result = verify_bgp_rib(tgen,
                                addr_type,
                                "r1",
                                input_routes_r3,
                                next_hop=[nh_r3_r1])
        assert result is True, "Testcase {} : Failed \n Error {}".format(
            tc_name, result)

    step("Active-Standby scenario(as-path prepend and Local pref)")

    for addr_type in ADDR_TYPES:

        step("Create prefix-list")

        input_dict_pf = {
            "r1": {
                "prefix_lists": {
                    addr_type: {
                        "pf_ls_{}".format(addr_type): [{
                            "seqid":
                            10,
                            "network":
                            NETWORK3_4[addr_type],
                            "action":
                            "permit",
                        }]
                    }
                }
            }
        }
        result = create_prefix_lists(tgen, input_dict_pf)
        assert result is True, "Testcase {} : Failed \n Error: {}".format(
            tc_name, result)

    for addr_type in ADDR_TYPES:

        step("Create route-map to match prefix-list and set localpref 500")

        input_dict_rm = {
            "r1": {
                "route_maps": {
                    "rmap_PATH1_{}".format(addr_type): [{
                        "action": "permit",
                        "seq_id": 10,
                        "match": {
                            addr_type: {
                                "prefix_lists": "pf_ls_{}".format(addr_type)
                            }
                        },
                        "set": {
                            "locPrf": 500
                        },
                    }]
                }
            }
        }

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

        step("Create route-map to match prefix-list and set localpref 600")

        input_dict_rm = {
            "r1": {
                "route_maps": {
                    "rmap_PATH2_{}".format(addr_type): [{
                        "action": "permit",
                        "seq_id": 20,
                        "match": {
                            addr_type: {
                                "prefix_lists": "pf_ls_{}".format(addr_type)
                            }
                        },
                        "set": {
                            "locPrf": 600
                        },
                    }]
                }
            }
        }

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

        input_dict_rma = {
            "r1": {
                "bgp": [{
                    "local_as": "100",
                    "address_family": {
                        addr_type: {
                            "unicast": {
                                "neighbor": {
                                    "r3": {
                                        "dest_link": {
                                            "r1-link1": {
                                                "route_maps": [{
                                                    "name":
                                                    "rmap_PATH1_{}".format(
                                                        addr_type),
                                                    "direction":
                                                    "in",
                                                }]
                                            }
                                        }
                                    },
                                    "r4": {
                                        "dest_link": {
                                            "r1-link1": {
                                                "route_maps": [{
                                                    "name":
                                                    "rmap_PATH2_{}".format(
                                                        addr_type),
                                                    "direction":
                                                    "in",
                                                }]
                                            }
                                        }
                                    },
                                }
                            }
                        }
                    },
                }]
            }
        }

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

    dut = "r1"
    attribute = "locPrf"

    for addr_type in ADDR_TYPES:

        step("Verify bestpath is installed as per highest localpref")

        input_routes_r3 = {
            "r3": {
                "static_routes": [{
                    "network": [NETWORK3_3[addr_type], NETWORK3_4[addr_type]]
                }]
            }
        }

        result = verify_best_path_as_per_bgp_attribute(tgen, addr_type, dut,
                                                       input_routes_r3,
                                                       attribute)
        assert result is True, "Testcase {} : Failed \n Error: {}".format(
            tc_name, result)

    for addr_type in ADDR_TYPES:

        step("Create route-map to match prefix-list and set localpref 700")

        input_dict_rm = {
            "r1": {
                "route_maps": {
                    "rmap_PATH1_{}".format(addr_type): [{
                        "action": "permit",
                        "seq_id": 10,
                        "match": {
                            addr_type: {
                                "prefix_lists": "pf_ls_{}".format(addr_type)
                            }
                        },
                        "set": {
                            "locPrf": 700
                        },
                    }]
                }
            }
        }

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

    for addr_type in ADDR_TYPES:

        step("Verify bestpath is changed as per highest localpref")

        input_routes_r3 = {
            "r3": {
                "static_routes": [{
                    "network": [NETWORK3_3[addr_type], NETWORK3_4[addr_type]]
                }]
            }
        }

        result = verify_best_path_as_per_bgp_attribute(tgen, addr_type, dut,
                                                       input_routes_r3,
                                                       attribute)
        assert result is True, "Testcase {} : Failed \n Error: {}".format(
            tc_name, result)

    for addr_type in ADDR_TYPES:

        step("Create route-map to match prefix-list and set as-path prepend")

        input_dict_rm = {
            "r1": {
                "route_maps": {
                    "rmap_PATH2_{}".format(addr_type): [{
                        "action": "permit",
                        "seq_id": 20,
                        "match": {
                            addr_type: {
                                "prefix_lists": "pf_ls_{}".format(addr_type)
                            }
                        },
                        "set": {
                            "localpref": 700,
                            "path": {
                                "as_num": "111",
                                "as_action": "prepend"
                            },
                        },
                    }]
                }
            }
        }

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

    attribute = "path"

    for addr_type in ADDR_TYPES:

        step("Verify bestpath is changed as per shortest as-path")

        input_routes_r3 = {
            "r3": {
                "static_routes": [{
                    "network": [NETWORK3_3[addr_type], NETWORK3_4[addr_type]]
                }]
            }
        }

        result = verify_best_path_as_per_bgp_attribute(tgen, addr_type, dut,
                                                       input_routes_r3,
                                                       attribute)
        assert result is True, "Testcase {} : Failed \n Error: {}".format(
            tc_name, result)

    write_test_footer(tc_name)