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)