mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-07-26 04:54:44 +00:00
tests:add topotest for EVPN aggregate prefix route
Toptotest covers to aggregate EVPN prefix routes. Testing: tests/topotests/bgp_evpn_vxlan_svd_topo1$ sudo -E python3 -m pytest -s -vv --cli-on-error PASSED test_bgp_evpn_vxlan_svd.py::test_pe_advertise_aggr_evpn_route --------------------- live log call ------------------------------- 2024-03-04 19:59:45,340 INFO: P1: checking if daemons are running 2024-03-04 19:59:45,444 INFO: PE1: checking if daemons are running 2024-03-04 19:59:45,578 INFO: PE2: checking if daemons are running 2024-03-04 19:59:45,680 INFO: host1: checking if daemons are running 2024-03-04 19:59:45,798 INFO: host2: checking if daemons are running 2024-03-04 19:59:45,896 INFO: topo: Checking BGP EVPN route contains non-aggregate prefixes 2024-03-04 19:59:45,992 INFO: topo: Configure BGP aggregate-address summary-only under ipv4-unicast 2024-03-04 19:59:46,120 INFO: topo: Checking BGP EVPN route contains aggregated prefix PASSED ------- generated xml file: /tmp/topotests/topotests.xml ----- ======= 10 passed, 1 skipped in 47.95s ===== Signed-off-by: Chirag Shah <chirag@nvidia.com>
This commit is contained in:
parent
5cb7712b3e
commit
f345460b7e
@ -0,0 +1 @@
|
|||||||
|
{"27.3.0.85:3":{"rd":"27.3.0.85:3","[5]:[0]:[16]:[10.27.0.0]":{"prefix":"[5]:[0]:[16]:[10.27.0.0]","prefixLen":352,"paths":[[{"valid":true,"bestpath":true,"selectionReason":"First path received","pathFrom":"external","routeType":5,"ethTag":0,"ipLen":16,"ip":"10.27.0.0","metric":0,"weight":32768,"peerId":"(unspec)","path":"","origin":"incomplete","extendedCommunity":{"string":"ET:8 RT:65000:4000 Rmac:44:00:00:ff:ff:01"},"nexthops":[{"ip":"10.10.10.10","hostname":"PE1","afi":"ipv4","used":true}]}]]}},"30.0.0.3:2":{"rd":"30.0.0.3:2","[5]:[0]:[32]:[4.4.4.1]":{"prefix":"[5]:[0]:[32]:[4.4.4.1]","prefixLen":352,"paths":[[{"valid":true,"bestpath":true,"selectionReason":"First path received","pathFrom":"internal","routeType":5,"ethTag":0,"ipLen":32,"ip":"4.4.4.1","metric":0,"locPrf":100,"weight":0,"peerId":"10.30.30.30","path":"","origin":"incomplete","extendedCommunity":{"string":"RT:65000:300 ET:8 Rmac:44:20:00:ff:ff:01"},"nexthops":[{"ip":"10.30.30.30","hostname":"PE2","afi":"ipv4","used":true}]}]]}},"numPrefix":2,"numPaths":2}
|
@ -0,0 +1 @@
|
|||||||
|
{"27.3.0.85:3":{"rd":"27.3.0.85:3","[5]:[0]:[24]:[10.27.7.0]":{"prefix":"[5]:[0]:[24]:[10.27.7.0]","prefixLen":352,"paths":[[{"valid":true,"bestpath":true,"selectionReason":"First path received","pathFrom":"external","routeType":5,"ethTag":0,"ipLen":24,"ip":"10.27.7.0","metric":0,"weight":32768,"peerId":"(unspec)","path":"","origin":"incomplete","extendedCommunity":{"string":"ET:8 RT:65000:4000 Rmac:44:00:00:ff:ff:01"},"nexthops":[{"ip":"10.10.10.10","hostname":"PE1","afi":"ipv4","used":true}]}]]},"[5]:[0]:[30]:[10.27.7.8]":{"prefix":"[5]:[0]:[30]:[10.27.7.8]","prefixLen":352,"paths":[[{"valid":true,"bestpath":true,"selectionReason":"First path received","pathFrom":"external","routeType":5,"ethTag":0,"ipLen":30,"ip":"10.27.7.8","metric":0,"weight":32768,"peerId":"(unspec)","path":"","origin":"incomplete","extendedCommunity":{"string":"ET:8 RT:65000:4000 Rmac:44:00:00:ff:ff:01"},"nexthops":[{"ip":"10.10.10.10","hostname":"PE1","afi":"ipv4","used":true}]}]]},"[5]:[0]:[32]:[10.27.7.22]":{"prefix":"[5]:[0]:[32]:[10.27.7.22]","prefixLen":352,"paths":[[{"valid":true,"bestpath":true,"selectionReason":"First path received","pathFrom":"external","routeType":5,"ethTag":0,"ipLen":32,"ip":"10.27.7.22","metric":0,"weight":32768,"peerId":"(unspec)","path":"","origin":"incomplete","extendedCommunity":{"string":"ET:8 RT:65000:4000 Rmac:44:00:00:ff:ff:01"},"nexthops":[{"ip":"10.10.10.10","hostname":"PE1","afi":"ipv4","used":true}]}]]}},"30.0.0.3:2":{"rd":"30.0.0.3:2","[5]:[0]:[32]:[4.4.4.1]":{"prefix":"[5]:[0]:[32]:[4.4.4.1]","prefixLen":352,"paths":[[{"valid":true,"bestpath":true,"selectionReason":"First path received","pathFrom":"internal","routeType":5,"ethTag":0,"ipLen":32,"ip":"4.4.4.1","metric":0,"locPrf":100,"weight":0,"peerId":"10.30.30.30","path":"","origin":"incomplete","extendedCommunity":{"string":"RT:65000:300 ET:8 Rmac:44:20:00:ff:ff:01"},"nexthops":[{"ip":"10.30.30.30","hostname":"PE2","afi":"ipv4","used":true}]}]]}},"numPrefix":4,"numPaths":4}
|
@ -11,9 +11,22 @@ router bgp 65000
|
|||||||
advertise-svi-ip
|
advertise-svi-ip
|
||||||
!
|
!
|
||||||
router bgp 65000 vrf vrf-red
|
router bgp 65000 vrf vrf-red
|
||||||
|
address-family ipv4 unicast
|
||||||
|
redistribute static
|
||||||
|
exit-address-family
|
||||||
!
|
!
|
||||||
address-family l2vpn evpn
|
address-family l2vpn evpn
|
||||||
route-target import *:300
|
route-target import *:300
|
||||||
route-target import auto
|
route-target import auto
|
||||||
exit-address-family
|
exit-address-family
|
||||||
!
|
!
|
||||||
|
router bgp 65000 vrf vrf-purple
|
||||||
|
address-family ipv4 unicast
|
||||||
|
redistribute static
|
||||||
|
exit-address-family
|
||||||
|
!
|
||||||
|
address-family l2vpn evpn
|
||||||
|
advertise ipv4 unicast
|
||||||
|
exit-address-family
|
||||||
|
|
||||||
|
!
|
||||||
|
@ -5,6 +5,12 @@ vrf vrf-red
|
|||||||
vni 100
|
vni 100
|
||||||
exit-vrf
|
exit-vrf
|
||||||
!
|
!
|
||||||
|
vrf vrf-purple
|
||||||
|
vni 4000
|
||||||
|
ip route 10.27.7.0/24 blackhole
|
||||||
|
ip route 10.27.7.22/32 blackhole
|
||||||
|
ip route 10.27.7.10/30 blackhole
|
||||||
|
exit-vrf
|
||||||
!
|
!
|
||||||
interface lo
|
interface lo
|
||||||
ip address 10.10.10.10/32
|
ip address 10.10.10.10/32
|
||||||
|
@ -91,6 +91,10 @@ def setup_pe_router(tgen, pe_name, tunnel_local_ip, svi_ip, intf):
|
|||||||
pe.run("ip link add name bridge type bridge stp_state 0")
|
pe.run("ip link add name bridge type bridge stp_state 0")
|
||||||
pe.run("ip link set dev bridge type bridge vlan_filtering 1")
|
pe.run("ip link set dev bridge type bridge vlan_filtering 1")
|
||||||
pe.run("bridge vlan add vid 1 dev bridge self")
|
pe.run("bridge vlan add vid 1 dev bridge self")
|
||||||
|
if pe_name == "PE1":
|
||||||
|
pe.run("ip link set dev bridge address 44:00:00:ff:ff:01")
|
||||||
|
if pe_name == "PE2":
|
||||||
|
pe.run("ip link set dev bridge address 44:20:00:ff:ff:01")
|
||||||
pe.run("ip link set dev bridge up")
|
pe.run("ip link set dev bridge up")
|
||||||
|
|
||||||
# setup svi
|
# setup svi
|
||||||
@ -113,6 +117,18 @@ def setup_pe_router(tgen, pe_name, tunnel_local_ip, svi_ip, intf):
|
|||||||
pe.run("bridge vlan add dev vxlan0 vid 1 tunnel_info id 101")
|
pe.run("bridge vlan add dev vxlan0 vid 1 tunnel_info id 101")
|
||||||
pe.run("ip link set up dev vxlan0")
|
pe.run("ip link set up dev vxlan0")
|
||||||
|
|
||||||
|
# VRF creation
|
||||||
|
pe.run("ip link add vrf-purple type vrf table 1003")
|
||||||
|
pe.run("ip link set dev vrf-purple up")
|
||||||
|
if pe_name == "PE1":
|
||||||
|
pe.run("ip link add vrf-blue type vrf table 1002")
|
||||||
|
pe.run("ip link set dev vrf-blue up")
|
||||||
|
pe.run("ip addr add 27.2.0.85/32 dev vrf-blue")
|
||||||
|
pe.run("ip addr add 27.3.0.85/32 dev vrf-purple")
|
||||||
|
if pe_name == "PE2":
|
||||||
|
pe.run("ip link add vrf-blue type vrf table 2400")
|
||||||
|
pe.run("ip link set dev vrf-blue up")
|
||||||
|
|
||||||
# setup PE interface
|
# setup PE interface
|
||||||
pe.run("ip link set dev {0}-{1} master bridge".format(pe_name, intf))
|
pe.run("ip link set dev {0}-{1} master bridge".format(pe_name, intf))
|
||||||
pe.run("bridge vlan del vid 1 dev {0}-{1}".format(pe_name, intf))
|
pe.run("bridge vlan del vid 1 dev {0}-{1}".format(pe_name, intf))
|
||||||
@ -120,7 +136,7 @@ def setup_pe_router(tgen, pe_name, tunnel_local_ip, svi_ip, intf):
|
|||||||
pe.run("bridge vlan add vid 1 dev {0}-{1}".format(pe_name, intf))
|
pe.run("bridge vlan add vid 1 dev {0}-{1}".format(pe_name, intf))
|
||||||
pe.run("bridge vlan add vid 1 pvid untagged dev {0}-{1}".format(pe_name, intf))
|
pe.run("bridge vlan add vid 1 pvid untagged dev {0}-{1}".format(pe_name, intf))
|
||||||
|
|
||||||
# l3vni 100
|
# L3VNI 100
|
||||||
pe.run("ip link add vrf-red type vrf table 1400")
|
pe.run("ip link add vrf-red type vrf table 1400")
|
||||||
pe.run("ip link add link bridge name vlan100 type vlan id 100 protocol 802.1q")
|
pe.run("ip link add link bridge name vlan100 type vlan id 100 protocol 802.1q")
|
||||||
pe.run("ip link set dev vlan100 master vrf-blue")
|
pe.run("ip link set dev vlan100 master vrf-blue")
|
||||||
@ -129,9 +145,16 @@ def setup_pe_router(tgen, pe_name, tunnel_local_ip, svi_ip, intf):
|
|||||||
pe.run("bridge vlan add dev vxlan0 vid 100")
|
pe.run("bridge vlan add dev vxlan0 vid 100")
|
||||||
pe.run("bridge vlan add dev vxlan0 vid 100 tunnel_info id 100")
|
pe.run("bridge vlan add dev vxlan0 vid 100 tunnel_info id 100")
|
||||||
|
|
||||||
|
# L3VNI 4000
|
||||||
|
pe.run("ip link add link bridge name vlan400 type vlan id 400 protocol 802.1q")
|
||||||
|
pe.run("ip link set dev vlan400 master vrf-purple")
|
||||||
|
pe.run("ip link set dev vlan400 up")
|
||||||
|
pe.run("bridge vlan add vid 400 dev bridge self")
|
||||||
|
pe.run("bridge vlan add dev vxlan0 vid 400")
|
||||||
|
pe.run("bridge vlan add dev vxlan0 vid 400 tunnel_info id 4000")
|
||||||
|
|
||||||
# add a vrf for testing DVNI
|
# add a vrf for testing DVNI
|
||||||
if pe_name == "PE2":
|
if pe_name == "PE2":
|
||||||
pe.run("ip link add vrf-blue type vrf table 2400")
|
|
||||||
pe.run("ip link add link bridge name vlan300 type vlan id 300 protocol 802.1q")
|
pe.run("ip link add link bridge name vlan300 type vlan id 300 protocol 802.1q")
|
||||||
pe.run("ip link set dev vlan300 master vrf-blue")
|
pe.run("ip link set dev vlan300 master vrf-blue")
|
||||||
pe.run("ip link set dev vlan300 up")
|
pe.run("ip link set dev vlan300 up")
|
||||||
@ -199,6 +222,14 @@ def show_vni_json_elide_ifindex(pe, vni, expected):
|
|||||||
return topotest.json_cmp(output_json, expected)
|
return topotest.json_cmp(output_json, expected)
|
||||||
|
|
||||||
|
|
||||||
|
def show_bgp_l2vpn_evpn_route_type_prefix_json(pe, expected):
|
||||||
|
output_json = pe.vtysh_cmd(
|
||||||
|
"show bgp l2vpn evpn route type prefix json", isjson=True
|
||||||
|
)
|
||||||
|
|
||||||
|
return topotest.json_cmp(output_json, expected)
|
||||||
|
|
||||||
|
|
||||||
def check_vni_macs_present(tgen, router, vni, maclist):
|
def check_vni_macs_present(tgen, router, vni, maclist):
|
||||||
result = router.vtysh_cmd("show evpn mac vni {} json".format(vni), isjson=True)
|
result = router.vtysh_cmd("show evpn mac vni {} json".format(vni), isjson=True)
|
||||||
for rname, ifname in maclist:
|
for rname, ifname in maclist:
|
||||||
@ -331,6 +362,7 @@ def mac_test_local_remote(local, remote):
|
|||||||
remote_output_json = json.loads(remote_output)
|
remote_output_json = json.loads(remote_output)
|
||||||
local_output_vni_json = json.loads(local_output_vni)
|
local_output_vni_json = json.loads(local_output_vni)
|
||||||
|
|
||||||
|
# breakpoint()
|
||||||
for vni in local_output_json:
|
for vni in local_output_json:
|
||||||
if vni not in remote_output_json:
|
if vni not in remote_output_json:
|
||||||
continue
|
continue
|
||||||
@ -542,6 +574,42 @@ def test_dvni():
|
|||||||
# tgen.mininet_cli()
|
# tgen.mininet_cli()
|
||||||
|
|
||||||
|
|
||||||
|
def test_pe_advertise_aggr_evpn_route():
|
||||||
|
"BGP advertise aggregated Type-5 prefix route"
|
||||||
|
|
||||||
|
tgen = get_topogen()
|
||||||
|
# Don't run this test if we have any failure.
|
||||||
|
if tgen.routers_have_failure():
|
||||||
|
pytest.skip(tgen.errors)
|
||||||
|
|
||||||
|
logger.info("Checking BGP EVPN route contains non-aggregate prefixes")
|
||||||
|
pe1 = tgen.gears["PE1"]
|
||||||
|
json_file = "{}/{}/bgp.evpn.route.prefix.before.json".format(CWD, pe1.name)
|
||||||
|
expected = json.loads(open(json_file).read())
|
||||||
|
|
||||||
|
test_func = partial(show_bgp_l2vpn_evpn_route_type_prefix_json, pe1, expected)
|
||||||
|
_, result = topotest.run_and_expect(test_func, None, count=45, wait=1)
|
||||||
|
assertmsg = '"{}" JSON output mismatches'.format(pe1.name)
|
||||||
|
assert result is None, assertmsg
|
||||||
|
|
||||||
|
logger.info("Configure BGP aggregate-address summary-only under ipv4-unicast")
|
||||||
|
pe1.cmd(
|
||||||
|
'vtysh -c "config t" -c "router bgp 65000 vrf vrf-purple" '
|
||||||
|
+ ' -c "address-family ipv4 unicast" '
|
||||||
|
+ ' -c "aggregate-address 10.27.0.0/16 summary-only" '
|
||||||
|
)
|
||||||
|
|
||||||
|
logger.info("Checking BGP EVPN route contains aggregated prefix")
|
||||||
|
pe1 = tgen.gears["PE1"]
|
||||||
|
json_file = "{}/{}/bgp.evpn.route.prefix.after.json".format(CWD, pe1.name)
|
||||||
|
expected = json.loads(open(json_file).read())
|
||||||
|
|
||||||
|
test_func = partial(show_bgp_l2vpn_evpn_route_type_prefix_json, pe1, expected)
|
||||||
|
_, result = topotest.run_and_expect(test_func, None, count=45, wait=1)
|
||||||
|
assertmsg = '"{}" JSON output mismatches'.format(pe1.name)
|
||||||
|
assert result is None, assertmsg
|
||||||
|
|
||||||
|
|
||||||
def test_memory_leak():
|
def test_memory_leak():
|
||||||
"Run the memory leak test and report results."
|
"Run the memory leak test and report results."
|
||||||
tgen = get_topogen()
|
tgen = get_topogen()
|
||||||
|
Loading…
Reference in New Issue
Block a user