diff --git a/tests/topotests/bgp_path_selection/r1/bgpd.conf b/tests/topotests/bgp_path_selection/r1/bgpd.conf index 08eb8675c246..2f1563798627 100644 --- a/tests/topotests/bgp_path_selection/r1/bgpd.conf +++ b/tests/topotests/bgp_path_selection/r1/bgpd.conf @@ -15,6 +15,11 @@ router bgp 65001 neighbor 192.0.2.2 activate neighbor 192.0.2.3 activate exit-address-family + address-family l2vpn evpn + neighbor 192.0.2.2 activate + neighbor 192.0.2.3 activate + advertise-all-vni + exit-address-family ! router bgp 65001 vrf vrf1 bgp router-id 192.0.2.1 @@ -24,5 +29,13 @@ router bgp 65001 vrf vrf1 rt vpn both 52:100 import vpn export vpn +! +router bgp 65001 vrf vrf2 + bgp router-id 192.0.2.1 + address-family ipv4 unicast + redistribute connected + address-family l2vpn evpn + autort rfc8365-compatible + rd 65001:100 exit-address-family -! \ No newline at end of file +! diff --git a/tests/topotests/bgp_path_selection/r1/zebra.conf b/tests/topotests/bgp_path_selection/r1/zebra.conf index e860d6e524be..32598984f307 100644 --- a/tests/topotests/bgp_path_selection/r1/zebra.conf +++ b/tests/topotests/bgp_path_selection/r1/zebra.conf @@ -1,4 +1,8 @@ ! +vrf vrf2 + vni 100 + exit-vrf +! interface lo ip address 192.0.2.1/32 ip address 172.16.255.1/32 @@ -8,4 +12,4 @@ interface r1-eth0 ! interface r1-eth1 ip address 192.168.2.1/24 -! +! \ No newline at end of file diff --git a/tests/topotests/bgp_path_selection/r2/bgpd.conf b/tests/topotests/bgp_path_selection/r2/bgpd.conf index cc878d83b98a..a1307db5d754 100644 --- a/tests/topotests/bgp_path_selection/r2/bgpd.conf +++ b/tests/topotests/bgp_path_selection/r2/bgpd.conf @@ -10,6 +10,10 @@ router bgp 65002 address-family ipv4 vpn neighbor 192.168.1.1 activate exit-address-family + address-family l2vpn evpn + neighbor 192.168.1.1 activate + advertise-all-vni + exit-address-family ! router bgp 65002 vrf vrf1 bgp router-id 192.0.2.2 @@ -22,4 +26,15 @@ router bgp 65002 vrf vrf1 import vpn export vpn exit-address-family -! \ No newline at end of file +! +router bgp 65002 vrf vrf2 + bgp router-id 192.0.2.2 + no bgp ebgp-requires-policy + address-family ipv4 unicast + redistribute connected + address-family l2vpn evpn + autort rfc8365-compatible + advertise ipv4 unicast + rd 65002:100 + exit-address-family +! diff --git a/tests/topotests/bgp_path_selection/r2/zebra.conf b/tests/topotests/bgp_path_selection/r2/zebra.conf index 40dfa9854c27..11328f43653e 100644 --- a/tests/topotests/bgp_path_selection/r2/zebra.conf +++ b/tests/topotests/bgp_path_selection/r2/zebra.conf @@ -1,4 +1,8 @@ ! +vrf vrf2 + vni 100 + exit-vrf +! int lo ip address 192.0.2.2/32 ! diff --git a/tests/topotests/bgp_path_selection/r3/bgpd.conf b/tests/topotests/bgp_path_selection/r3/bgpd.conf index ca8d27a2c574..74fe66d613d1 100644 --- a/tests/topotests/bgp_path_selection/r3/bgpd.conf +++ b/tests/topotests/bgp_path_selection/r3/bgpd.conf @@ -10,6 +10,10 @@ router bgp 65002 address-family ipv4 vpn neighbor 192.168.2.1 activate exit-address-family + address-family l2vpn evpn + neighbor 192.168.2.1 activate + advertise-all-vni + exit-address-family ! router bgp 65002 vrf vrf1 bgp router-id 192.0.2.3 @@ -22,4 +26,15 @@ router bgp 65002 vrf vrf1 import vpn export vpn exit-address-family -! \ No newline at end of file +! +router bgp 65002 vrf vrf2 + bgp router-id 192.0.2.3 + no bgp ebgp-requires-policy + address-family ipv4 unicast + redistribute connected + address-family l2vpn evpn + autort rfc8365-compatible + advertise ipv4 unicast + rd 65002:100 + exit-address-family +! diff --git a/tests/topotests/bgp_path_selection/r3/zebra.conf b/tests/topotests/bgp_path_selection/r3/zebra.conf index a0473b63ad2e..6fba9e2e1800 100644 --- a/tests/topotests/bgp_path_selection/r3/zebra.conf +++ b/tests/topotests/bgp_path_selection/r3/zebra.conf @@ -1,4 +1,8 @@ ! +vrf vrf2 + vni 100 + exit-vrf +! int lo ip address 192.0.2.3/32 ! diff --git a/tests/topotests/bgp_path_selection/test_bgp_path_selection.py b/tests/topotests/bgp_path_selection/test_bgp_path_selection.py index 50b71d8627ab..948950a79b38 100644 --- a/tests/topotests/bgp_path_selection/test_bgp_path_selection.py +++ b/tests/topotests/bgp_path_selection/test_bgp_path_selection.py @@ -62,10 +62,31 @@ def setup_module(mod): for routern in range(1, 4): tgen.gears["r{}".format(routern)].cmd("ip link add vrf1 type vrf table 10") tgen.gears["r{}".format(routern)].cmd("ip link set vrf1 up") - tgen.gears["r{}".format(routern)].cmd("ip address add dev vrf1 {}.{}.{}.{}/32".format(routern, routern, routern,routern)) + tgen.gears["r{}".format(routern)].cmd( + "ip address add dev vrf1 {}.{}.{}.{}/32".format( + routern, routern, routern, routern + ) + ) + tgen.gears["r{}".format(routern)].cmd("ip link add vrf2 type vrf table 20") + tgen.gears["r{}".format(routern)].cmd("ip link set vrf2 up") + tgen.gears["r{}".format(routern)].cmd( + "ip address add dev vrf2 192.0.2.{}/32".format(routern) + ) + tgen.gears["r{}".format(routern)].cmd("ip link add br1 type bridge") + tgen.gears["r{}".format(routern)].cmd( + "ip link add vxl1 type vxlan id 100 dev lo local 192.0.2.{}".format(routern) + ) + tgen.gears["r{}".format(routern)].cmd("ip link set dev vxl1 master br1") + tgen.gears["r{}".format(routern)].cmd("ip link set dev br1 master vrf2") + tgen.gears["r{}".format(routern)].cmd("ip link set dev br1 up") + tgen.gears["r{}".format(routern)].cmd("ip link set dev vxl1 up") + tgen.gears["r2"].cmd("ip address add dev vrf1 192.0.2.8/32") tgen.gears["r3"].cmd("ip address add dev vrf1 192.0.2.8/32") + tgen.gears["r2"].cmd("ip address add dev vrf2 192.0.4.8/32") + tgen.gears["r3"].cmd("ip address add dev vrf2 192.0.4.8/32") + for i, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) @@ -87,6 +108,7 @@ def teardown_module(mod): tgen = get_topogen() tgen.stop_topology() + def test_bgp_path_selection_ecmp(): tgen = get_topogen() @@ -110,7 +132,7 @@ def _bgp_check_path_selection_ecmp(): "aspath": {"string": "65002"}, "multipath": True, "nexthops": [{"ip": "192.0.2.3", "metric": 20}], - } + }, ] } @@ -130,7 +152,9 @@ def test_bgp_path_selection_vpn_ecmp(): def _bgp_check_path_selection_vpn_ecmp(): output = json.loads( - tgen.gears["r1"].vtysh_cmd("show bgp vrf vrf1 ipv4 unicast 192.0.2.8/32 json") + tgen.gears["r1"].vtysh_cmd( + "show bgp vrf vrf1 ipv4 unicast 192.0.2.8/32 json" + ) ) expected = { "paths": [ @@ -145,7 +169,7 @@ def _bgp_check_path_selection_vpn_ecmp(): "aspath": {"string": "65002"}, "multipath": True, "nexthops": [{"ip": "192.0.2.3", "metric": 20}], - } + }, ] } @@ -157,6 +181,58 @@ def _bgp_check_path_selection_vpn_ecmp(): assert result is None, "Failed to see BGP prefixes on R1" +def test_bgp_path_selection_evpn_r5_ecmp(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + def _bgp_check_path_selection_evpn_r5_ecmp(): + output = json.loads( + tgen.gears["r1"].vtysh_cmd("show ip route vrf vrf2 192.0.4.8/32 json") + ) + expected = { + "192.0.4.8/32": [ + { + "prefix": "192.0.4.8/32", + "protocol": "bgp", + "vrfName": "vrf2", + "selected": True, + "installed": True, + "internalNextHopNum": 2, + "internalNextHopActiveNum": 2, + "nexthops": [ + { + "fib": True, + "ip": "192.0.2.2", + "afi": "ipv4", + "interfaceName": "br1", + "active": True, + "onLink": True, + "weight": 1, + }, + { + "fib": True, + "ip": "192.0.2.3", + "afi": "ipv4", + "interfaceName": "br1", + "active": True, + "onLink": True, + "weight": 1, + }, + ], + } + ] + } + + return topotest.json_cmp(output, expected) + + step("Check if two ECMP paths are present") + test_func = functools.partial(_bgp_check_path_selection_evpn_r5_ecmp) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert result is None, "Failed to see BGP prefixes on R1" + + def test_bgp_path_selection_metric(): tgen = get_topogen() @@ -173,13 +249,13 @@ def _bgp_check_path_selection_metric(): "valid": True, "aspath": {"string": "65002"}, "nexthops": [{"ip": "192.0.2.2", "metric": 10}], - "bestpath":{ "selectionReason":"IGP Metric"}, + "bestpath": {"selectionReason": "IGP Metric"}, }, { "valid": True, "aspath": {"string": "65002"}, "nexthops": [{"ip": "192.0.2.3", "metric": 20}], - } + }, ] } @@ -202,7 +278,9 @@ def test_bgp_path_selection_vpn_metric(): def _bgp_check_path_selection_vpn_metric(): output = json.loads( - tgen.gears["r1"].vtysh_cmd("show bgp vrf vrf1 ipv4 unicast 192.0.2.8/32 json") + tgen.gears["r1"].vtysh_cmd( + "show bgp vrf vrf1 ipv4 unicast 192.0.2.8/32 json" + ) ) expected = { "paths": [ @@ -210,13 +288,13 @@ def _bgp_check_path_selection_vpn_metric(): "valid": True, "aspath": {"string": "65002"}, "nexthops": [{"ip": "192.0.2.2", "metric": 10}], - "bestpath":{ "selectionReason":"IGP Metric"}, + "bestpath": {"selectionReason": "IGP Metric"}, }, { "valid": True, "aspath": {"string": "65002"}, "nexthops": [{"ip": "192.0.2.3", "metric": 20}], - } + }, ] } @@ -228,6 +306,49 @@ def _bgp_check_path_selection_vpn_metric(): assert result is None, "Failed to see BGP prefixes on R1" +def test_bgp_path_selection_evpn_r5_metric(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + def _bgp_check_path_selection_evpn_r5_metric(): + output = json.loads( + tgen.gears["r1"].vtysh_cmd("show ip route vrf vrf2 192.0.4.8/32 json") + ) + expected = { + "192.0.4.8/32": [ + { + "prefix": "192.0.4.8/32", + "protocol": "bgp", + "vrfName": "vrf2", + "selected": True, + "installed": True, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": True, + "ip": "192.0.2.2", + "afi": "ipv4", + "interfaceName": "br1", + "active": True, + "onLink": True, + "weight": 1, + } + ], + } + ] + } + + return topotest.json_cmp(output, expected) + + step("Check if IGP metric best path is selected") + test_func = functools.partial(_bgp_check_path_selection_evpn_r5_metric) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert result is None, "Failed to see BGP prefixes on R1" + + if __name__ == "__main__": args = ["-s"] + sys.argv[1:] sys.exit(pytest.main(args))