Merge pull request #17370 from louis-6wind/fix-vpn-leaking

bgpd: fix for the validity and the presence of prefixes in the BGP VPN table.
This commit is contained in:
Russ White 2025-02-11 08:41:03 -05:00 committed by GitHub
commit 5518a8c916
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 871 additions and 136 deletions

View File

@ -1052,6 +1052,7 @@ static bool leak_update_nexthop_valid(struct bgp *to_bgp, struct bgp_dest *bn,
struct bgp_path_info *bpi_ultimate;
struct bgp *bgp_nexthop;
struct bgp_table *table;
struct interface *ifp;
bool nh_valid;
bpi_ultimate = bgp_get_imported_bpi_ultimate(source_bpi);
@ -1062,6 +1063,15 @@ static bool leak_update_nexthop_valid(struct bgp *to_bgp, struct bgp_dest *bn,
else
bgp_nexthop = bgp_orig;
/* The nexthop is invalid if its VRF does not exist */
if (bgp_nexthop->vrf_id == VRF_UNKNOWN)
return false;
/* The nexthop is invalid if its VRF interface is down*/
ifp = if_get_vrf_loopback(bgp_nexthop->vrf_id);
if (ifp && !if_is_up(ifp))
return false;
/*
* No nexthop tracking for redistributed routes, for
* EVPN-imported routes that get leaked, or for routes
@ -1126,8 +1136,8 @@ leak_update(struct bgp *to_bgp, struct bgp_dest *bn,
struct bgp_path_info *bpi;
struct bgp_path_info *new;
struct bgp_path_info_extra *extra;
struct bgp_path_info *parent = source_bpi;
struct bgp_labels bgp_labels = {};
struct bgp *bgp_nexthop;
bool labelssame;
uint8_t i;
@ -1159,8 +1169,7 @@ leak_update(struct bgp *to_bgp, struct bgp_dest *bn,
* match parent
*/
for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next) {
if (bpi->extra && bpi->extra->vrfleak &&
bpi->extra->vrfleak->parent == parent)
if (bpi->extra && bpi->extra->vrfleak && bpi->extra->vrfleak->parent == source_bpi)
break;
}
@ -1174,6 +1183,16 @@ leak_update(struct bgp *to_bgp, struct bgp_dest *bn,
labelssame = bgp_path_info_labels_same(bpi, bgp_labels.label,
bgp_labels.num_labels);
bgp_nexthop = bpi->extra->vrfleak->bgp_orig ?: bgp_orig;
if (bgp_nexthop->vrf_id == VRF_UNKNOWN) {
if (debug) {
zlog_debug("%s: ->%s(s_flags: 0x%x b_flags: 0x%x): %pFX: Found route, origin VRF does not exist, not leaking",
__func__, to_bgp->name_pretty, source_bpi->flags,
bpi->flags, p);
}
return NULL;
}
if (CHECK_FLAG(source_bpi->flags, BGP_PATH_REMOVED)
&& CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
if (debug) {
@ -1185,9 +1204,11 @@ leak_update(struct bgp *to_bgp, struct bgp_dest *bn,
return NULL;
}
if (attrhash_cmp(bpi->attr, new_attr) && labelssame
&& !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
if (attrhash_cmp(bpi->attr, new_attr) && labelssame &&
!CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED) &&
leak_update_nexthop_valid(to_bgp, bn, new_attr, afi, safi, source_bpi, bpi,
bgp_orig, p,
debug) == !!CHECK_FLAG(bpi->flags, BGP_PATH_VALID)) {
bgp_attr_unintern(&new_attr);
if (debug)
zlog_debug(
@ -1274,6 +1295,14 @@ leak_update(struct bgp *to_bgp, struct bgp_dest *bn,
return NULL;
}
if (bgp_orig->vrf_id == VRF_UNKNOWN) {
if (debug) {
zlog_debug("%s: ->%s(s_flags: 0x%x): %pFX: New route, origin VRF does not exist, not leaking",
__func__, to_bgp->name_pretty, source_bpi->flags, p);
}
return NULL;
}
new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_IMPORTED, 0,
to_bgp->peer_self, new_attr, bn);
@ -1297,9 +1326,8 @@ leak_update(struct bgp *to_bgp, struct bgp_dest *bn,
if (bgp_labels.num_labels)
new->extra->labels = bgp_labels_intern(&bgp_labels);
new->extra->vrfleak->parent = bgp_path_info_lock(parent);
bgp_dest_lock_node(
(struct bgp_dest *)parent->net);
new->extra->vrfleak->parent = bgp_path_info_lock(source_bpi);
bgp_dest_lock_node((struct bgp_dest *)source_bpi->net);
new->extra->vrfleak->bgp_orig = bgp_lock(bgp_orig);

View File

@ -78,6 +78,13 @@ def setup_module(mod):
"tcpdump -nni r1-eth0 -s 0 -w {} &".format(pcap_file), stdout=None
)
tgen.net["r2"].cmd(
"""
ip link add vrf1 type vrf table 10
ip link set vrf1 up
"""
)
for _, (rname, router) in enumerate(tgen.routers().items(), 1):
logger.info("Loading router %s" % rname)
router.load_frr_config(

View File

@ -1,3 +1,7 @@
vrf DONNA
ip route 172.16.3.0/24 10.0.0.254
exit-vrf
!
int dummy0
ip address 10.0.4.1/24
no shut
@ -28,6 +32,9 @@ ip router-id 10.0.4.1
!
router bgp 99
no bgp ebgp-requires-policy
! 10.0.4.254 peer session will not be established
! it is there just to activate the ipv4 vpn table
neighbor 10.0.4.254 remote-as external
address-family ipv4 unicast
redistribute connected
rd vpn export 10.0.4.1:1
@ -36,11 +43,14 @@ router bgp 99
export vpn
import vpn
!
address-family ipv4 vpn
neighbor 10.0.4.254 activate
!
router bgp 99 vrf DONNA
no bgp ebgp-requires-policy
address-family ipv4 unicast
redistribute connected
network 172.16.3.0/24
label vpn export 101
rd vpn export 10.0.4.1:1
rt vpn export 10.0.4.1:101

View File

@ -0,0 +1,155 @@
{
"routerId": "10.0.4.1",
"localAS": 99,
"routes": {
"routeDistinguishers": {
"10.0.4.1:1": {
"10.0.0.0/24": [
{
"valid": true,
"pathFrom": "external",
"path": "",
"origin": "incomplete",
"announceNexthopSelf": true,
"nhVrfName": "DONNA",
"nexthops": [
{
"ip": "0.0.0.0",
"hostname": "r1",
"afi": "ipv4",
"used": true
}
]
}
],
"10.0.1.0/24": [
{
"valid": true,
"pathFrom": "external",
"path": "",
"origin": "incomplete",
"announceNexthopSelf": true,
"nhVrfName": "EVA",
"nexthops": [
{
"ip": "0.0.0.0",
"hostname": "r1",
"afi": "ipv4",
"used": true
}
]
}
],
"10.0.2.0/24": [
{
"valid": true,
"pathFrom": "external",
"path": "",
"origin": "incomplete",
"announceNexthopSelf": true,
"nhVrfName": "DONNA",
"nexthops": [
{
"ip": "0.0.0.0",
"hostname": "r1",
"afi": "ipv4",
"used": true
}
]
}
],
"10.0.3.0/24": [
{
"valid": true,
"pathFrom": "external",
"path": "",
"origin": "incomplete",
"announceNexthopSelf": true,
"nhVrfName": "EVA",
"nexthops": [
{
"ip": "0.0.0.0",
"hostname": "r1",
"afi": "ipv4",
"used": true
}
]
}
],
"10.0.4.0/24": [
{
"valid": true,
"pathFrom": "external",
"path": "",
"origin": "incomplete",
"announceNexthopSelf": true,
"nhVrfName": "default",
"nexthops": [
{
"ip": "0.0.0.0",
"hostname": "r1",
"afi": "ipv4",
"used": true
}
]
}
],
"172.16.3.0/24": [
{
"valid": true,
"pathFrom": "external",
"path": "",
"origin": "IGP",
"announceNexthopSelf": true,
"nhVrfName": "DONNA",
"nexthops": [
{
"ip": "0.0.0.0",
"hostname": "r1",
"afi": "ipv4",
"used": true
}
]
}
],
"172.16.3.0/24": [
{
"valid": true,
"pathFrom": "external",
"path": "",
"origin": "IGP",
"announceNexthopSelf": true,
"nhVrfName": "DONNA",
"nexthops": [
{
"ip": "0.0.0.0",
"hostname": "r1",
"afi": "ipv4",
"used": true
}
]
}
],
"172.16.101.0/24": [
{
"valid": null,
"pathFrom": "external",
"path": "",
"origin": "IGP",
"announceNexthopSelf": true,
"nhVrfName": "ZITA",
"nexthops": [
{
"ip": "0.0.0.0",
"hostname": "r1",
"afi": "ipv4",
"used": true
}
]
}
]
}
}
}
}

View File

@ -0,0 +1,103 @@
{
"routerId": "10.0.4.1",
"localAS": 99,
"routes": {
"routeDistinguishers": {
"10.0.4.1:1": {
"10.0.0.0/24": [
{
"valid": true,
"pathFrom": "external",
"path": "",
"origin": "incomplete",
"announceNexthopSelf": true,
"nhVrfName": "DONNA",
"nexthops": [
{
"ip": "0.0.0.0",
"hostname": "r1",
"afi": "ipv4",
"used": true
}
]
}
],
"10.0.1.0/24": [
{
"valid": true,
"pathFrom": "external",
"path": "",
"origin": "incomplete",
"announceNexthopSelf": true,
"nhVrfName": "EVA",
"nexthops": [
{
"ip": "0.0.0.0",
"hostname": "r1",
"afi": "ipv4",
"used": true
}
]
}
],
"10.0.2.0/24": [
{
"valid": true,
"pathFrom": "external",
"path": "",
"origin": "incomplete",
"announceNexthopSelf": true,
"nhVrfName": "DONNA",
"nexthops": [
{
"ip": "0.0.0.0",
"hostname": "r1",
"afi": "ipv4",
"used": true
}
]
}
],
"10.0.3.0/24": [
{
"valid": true,
"pathFrom": "external",
"path": "",
"origin": "incomplete",
"announceNexthopSelf": true,
"nhVrfName": "EVA",
"nexthops": [
{
"ip": "0.0.0.0",
"hostname": "r1",
"afi": "ipv4",
"used": true
}
]
}
],
"10.0.4.0/24": [
{
"valid": true,
"pathFrom": "external",
"path": "",
"origin": "incomplete",
"announceNexthopSelf": true,
"nhVrfName": "default",
"nexthops": [
{
"ip": "0.0.0.0",
"hostname": "r1",
"afi": "ipv4",
"used": true
}
]
}
],
"172.16.3.0/24": null,
"172.16.101.0/24": null
}
}
}
}

View File

@ -0,0 +1,120 @@
{
"routerId": "10.0.4.1",
"localAS": 99,
"routes": {
"routeDistinguishers": {
"10.0.4.1:1": {
"10.0.0.0/24": [
{
"valid": true,
"pathFrom": "external",
"path": "",
"origin": "incomplete",
"announceNexthopSelf": true,
"nhVrfName": "DONNA",
"nexthops": [
{
"ip": "0.0.0.0",
"hostname": "r1",
"afi": "ipv4",
"used": true
}
]
}
],
"10.0.1.0/24": [
{
"valid": null,
"pathFrom": "external",
"path": "",
"origin": "incomplete",
"announceNexthopSelf": true,
"nhVrfName": "EVA",
"nexthops": [
{
"ip": "0.0.0.0",
"hostname": "r1",
"afi": "ipv4",
"used": true
}
]
}
],
"10.0.2.0/24": [
{
"valid": true,
"pathFrom": "external",
"path": "",
"origin": "incomplete",
"announceNexthopSelf": true,
"nhVrfName": "DONNA",
"nexthops": [
{
"ip": "0.0.0.0",
"hostname": "r1",
"afi": "ipv4",
"used": true
}
]
}
],
"10.0.3.0/24": [
{
"valid": null,
"pathFrom": "external",
"path": "",
"origin": "incomplete",
"announceNexthopSelf": true,
"nhVrfName": "EVA",
"nexthops": [
{
"ip": "0.0.0.0",
"hostname": "r1",
"afi": "ipv4",
"used": true
}
]
}
],
"10.0.4.0/24": [
{
"valid": true,
"pathFrom": "external",
"path": "",
"origin": "incomplete",
"announceNexthopSelf": true,
"nhVrfName": "default",
"nexthops": [
{
"ip": "0.0.0.0",
"hostname": "r1",
"afi": "ipv4",
"used": true
}
]
}
],
"172.16.3.0/24": [
{
"valid": true,
"pathFrom": "external",
"path": "",
"origin": "IGP",
"announceNexthopSelf": true,
"nhVrfName": "DONNA",
"nexthops": [
{
"ip": "0.0.0.0",
"hostname": "r1",
"afi": "ipv4",
"used": true
}
]
}
],
"172.16.101.0/24": null
}
}
}
}

View File

@ -0,0 +1,120 @@
{
"routerId": "10.0.4.1",
"localAS": 99,
"routes": {
"routeDistinguishers": {
"10.0.4.1:1": {
"10.0.0.0/24": [
{
"valid": true,
"pathFrom": "external",
"path": "",
"origin": "incomplete",
"announceNexthopSelf": true,
"nhVrfName": "DONNA",
"nexthops": [
{
"ip": "0.0.0.0",
"hostname": "r1",
"afi": "ipv4",
"used": true
}
]
}
],
"10.0.1.0/24": [
{
"valid": true,
"pathFrom": "external",
"path": "",
"origin": "incomplete",
"announceNexthopSelf": true,
"nhVrfName": "EVA",
"nexthops": [
{
"ip": "0.0.0.0",
"hostname": "r1",
"afi": "ipv4",
"used": true
}
]
}
],
"10.0.2.0/24": [
{
"valid": true,
"pathFrom": "external",
"path": "",
"origin": "incomplete",
"announceNexthopSelf": true,
"nhVrfName": "DONNA",
"nexthops": [
{
"ip": "0.0.0.0",
"hostname": "r1",
"afi": "ipv4",
"used": true
}
]
}
],
"10.0.3.0/24": [
{
"valid": true,
"pathFrom": "external",
"path": "",
"origin": "incomplete",
"announceNexthopSelf": true,
"nhVrfName": "EVA",
"nexthops": [
{
"ip": "0.0.0.0",
"hostname": "r1",
"afi": "ipv4",
"used": true
}
]
}
],
"10.0.4.0/24": [
{
"valid": true,
"pathFrom": "external",
"path": "",
"origin": "incomplete",
"announceNexthopSelf": true,
"nhVrfName": "default",
"nexthops": [
{
"ip": "0.0.0.0",
"hostname": "r1",
"afi": "ipv4",
"used": true
}
]
}
],
"172.16.3.0/24": [
{
"valid": true,
"pathFrom": "external",
"path": "",
"origin": "IGP",
"announceNexthopSelf": true,
"nhVrfName": "DONNA",
"nexthops": [
{
"ip": "0.0.0.0",
"hostname": "r1",
"afi": "ipv4",
"used": true
}
]
}
],
"172.16.101.0/24": null
}
}
}
}

View File

@ -0,0 +1,137 @@
{
"routerId": "10.0.4.1",
"localAS": 99,
"routes": {
"routeDistinguishers": {
"10.0.4.1:1": {
"10.0.0.0/24": [
{
"valid": true,
"pathFrom": "external",
"path": "",
"origin": "incomplete",
"announceNexthopSelf": true,
"nhVrfName": "DONNA",
"nexthops": [
{
"ip": "0.0.0.0",
"hostname": "r1",
"afi": "ipv4",
"used": true
}
]
}
],
"10.0.1.0/24": [
{
"valid": true,
"pathFrom": "external",
"path": "",
"origin": "incomplete",
"announceNexthopSelf": true,
"nhVrfName": "EVA",
"nexthops": [
{
"ip": "0.0.0.0",
"hostname": "r1",
"afi": "ipv4",
"used": true
}
]
}
],
"10.0.2.0/24": [
{
"valid": true,
"pathFrom": "external",
"path": "",
"origin": "incomplete",
"announceNexthopSelf": true,
"nhVrfName": "DONNA",
"nexthops": [
{
"ip": "0.0.0.0",
"hostname": "r1",
"afi": "ipv4",
"used": true
}
]
}
],
"10.0.3.0/24": [
{
"valid": true,
"pathFrom": "external",
"path": "",
"origin": "incomplete",
"announceNexthopSelf": true,
"nhVrfName": "EVA",
"nexthops": [
{
"ip": "0.0.0.0",
"hostname": "r1",
"afi": "ipv4",
"used": true
}
]
}
],
"10.0.4.0/24": [
{
"valid": true,
"pathFrom": "external",
"path": "",
"origin": "incomplete",
"announceNexthopSelf": true,
"nhVrfName": "default",
"nexthops": [
{
"ip": "0.0.0.0",
"hostname": "r1",
"afi": "ipv4",
"used": true
}
]
}
],
"172.16.3.0/24": [
{
"valid": true,
"pathFrom": "external",
"path": "",
"origin": "IGP",
"announceNexthopSelf": true,
"nhVrfName": "DONNA",
"nexthops": [
{
"ip": "0.0.0.0",
"hostname": "r1",
"afi": "ipv4",
"used": true
}
]
}
],
"172.16.101.0/24": [
{
"valid": true,
"pathFrom": "external",
"path": "",
"origin": "IGP",
"announceNexthopSelf": true,
"nhVrfName": "ZITA",
"nexthops": [
{
"ip": "0.0.0.0",
"hostname": "r1",
"afi": "ipv4",
"used": true
}
]
}
]
}
}
}
}

View File

@ -13,6 +13,7 @@
Test basic VPNv4 route leaking
"""
import json
import os
import sys
from functools import partial
@ -60,6 +61,22 @@ def teardown_module(mod):
tgen.stop_topology()
def test_bgp_convergence():
tgen = get_topogen()
# Don't run this test if we have any failure.
if tgen.routers_have_failure():
pytest.skip(tgen.errors)
r1 = tgen.gears["r1"]
json_file = "{}/{}/show_bgp_ipv4_vpn_init.json".format(CWD, r1.name)
expect = json.loads(open(json_file).read())
test_func = partial(topotest.router_json_cmp, r1, "show bgp ipv4 vpn json", expect)
result, diff = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
assert result, "BGP IPv4 VPN table check failed:\n{}".format(diff)
def test_vrf_route_leak_donna():
logger.info("Ensure that routes are leaked back and forth")
tgen = get_topogen()
@ -119,20 +136,20 @@ def test_vrf_route_leak_donna():
],
},
],
"172.16.101.0/24": [
"172.16.3.0/24": [
{
"protocol": "bgp",
"selected": None,
"protocol": "static",
"selected": True,
"nexthops": [
{
"fib": None,
"interfaceName": "unknown",
"vrf": "Unknown",
"active": None,
},
"fib": True,
"interfaceName": "dummy1",
"active": True,
}
],
},
],
"172.16.101.0/24": None,
}
test_func = partial(
@ -191,20 +208,21 @@ def test_vrf_route_leak_eva():
"protocol": "connected",
}
],
"172.16.101.0/24": [
"172.16.3.0/24": [
{
"protocol": "bgp",
"selected": None,
"selected": True,
"nexthops": [
{
"fib": None,
"interfaceName": "unknown",
"vrf": "Unknown",
"active": None,
},
"fib": True,
"interfaceName": "DONNA",
"vrf": "DONNA",
"active": True,
}
],
},
],
"172.16.101.0/24": None,
}
test_func = partial(
@ -258,6 +276,20 @@ def test_vrf_route_leak_default():
"protocol": "connected",
}
],
"172.16.3.0/24": [
{
"protocol": "bgp",
"selected": True,
"nexthops": [
{
"fib": True,
"interfaceName": "DONNA",
"vrf": "DONNA",
"active": True,
}
],
},
],
}
test_func = partial(topotest.router_json_cmp, r1, "show ip route json", expect)
@ -298,34 +330,8 @@ interface EVA
# Test DONNA VRF.
expect = {
"10.0.1.0/24": [
{
"protocol": "bgp",
"selected": None,
"nexthops": [
{
"fib": None,
"interfaceName": "EVA",
"vrf": "EVA",
"active": None,
},
],
},
],
"10.0.3.0/24": [
{
"protocol": "bgp",
"selected": None,
"nexthops": [
{
"fib": None,
"interfaceName": "EVA",
"vrf": "EVA",
"active": None,
},
],
},
],
"10.0.1.0/24": None,
"10.0.3.0/24": None,
}
test_func = partial(
@ -349,6 +355,14 @@ interface EVA
result, diff = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
assert result, "BGP VRF DONNA check failed:\n{}".format(diff)
# check BGP IPv4 VPN table
json_file = "{}/{}/show_bgp_ipv4_vpn_eva_down.json".format(CWD, r1.name)
expect = json.loads(open(json_file).read())
test_func = partial(topotest.router_json_cmp, r1, "show bgp ipv4 vpn json", expect)
result, diff = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
assert result, "BGP IPv4 VPN table check failed:\n{}".format(diff)
def test_vrf_route_leak_donna_after_eva_up():
logger.info("Ensure that route states change after EVA interface goes up")
@ -404,6 +418,14 @@ interface EVA
result, diff = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
assert result, "BGP VRF DONNA check failed:\n{}".format(diff)
# check BGP IPv4 VPN table
json_file = "{}/{}/show_bgp_ipv4_vpn_init.json".format(CWD, r1.name)
expect = json.loads(open(json_file).read())
test_func = partial(topotest.router_json_cmp, r1, "show bgp ipv4 vpn json", expect)
result, diff = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
assert result, "BGP IPv4 VPN table check failed:\n{}".format(diff)
def test_vrf_route_leak_donna_add_vrf_zita():
logger.info("Add VRF ZITA and ensure that the route from VRF ZITA is updated")
@ -417,20 +439,7 @@ def test_vrf_route_leak_donna_add_vrf_zita():
# Test DONNA VRF.
expect = {
"172.16.101.0/24": [
{
"protocol": "bgp",
"selected": None,
"nexthops": [
{
"fib": None,
"interfaceName": "ZITA",
"vrf": "ZITA",
"active": None,
},
],
},
],
"172.16.101.0/24": None,
}
test_func = partial(
@ -439,6 +448,14 @@ def test_vrf_route_leak_donna_add_vrf_zita():
result, diff = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
assert result, "BGP VRF DONNA check failed:\n{}".format(diff)
# check BGP IPv4 VPN table
json_file = "{}/{}/show_bgp_ipv4_vpn_add_zita.json".format(CWD, r1.name)
expect = json.loads(open(json_file).read())
test_func = partial(topotest.router_json_cmp, r1, "show bgp ipv4 vpn json", expect)
result, diff = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
assert result, "BGP IPv4 VPN table check failed:\n{}".format(diff)
def test_vrf_route_leak_donna_set_zita_up():
logger.info("Set VRF ZITA up and ensure that the route from VRF ZITA is updated")
@ -480,6 +497,14 @@ interface ZITA
result, diff = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
assert result, "BGP VRF DONNA check failed:\n{}".format(diff)
# check BGP IPv4 VPN table
json_file = "{}/{}/show_bgp_ipv4_vpn_zita_up.json".format(CWD, r1.name)
expect = json.loads(open(json_file).read())
test_func = partial(topotest.router_json_cmp, r1, "show bgp ipv4 vpn json", expect)
result, diff = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
assert result, "BGP IPv4 VPN table check failed:\n{}".format(diff)
def test_vrf_route_leak_donna_delete_vrf_zita():
logger.info("Delete VRF ZITA and ensure that the route from VRF ZITA is deleted")
@ -502,6 +527,101 @@ def test_vrf_route_leak_donna_delete_vrf_zita():
result, diff = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
assert result, "BGP VRF DONNA check failed:\n{}".format(diff)
# check BGP IPv4 VPN table
json_file = "{}/{}/show_bgp_ipv4_vpn_init.json".format(CWD, r1.name)
expect = json.loads(open(json_file).read())
test_func = partial(topotest.router_json_cmp, r1, "show bgp ipv4 vpn json", expect)
result, diff = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
assert result, "BGP IPv4 VPN table check failed:\n{}".format(diff)
def test_vrf_route_leak_default_delete_prefix():
logger.info(
"Remove BGP static prefix 172.16.3.0/24 from VRF DONNA and ensure that the route is deleted on default"
)
tgen = get_topogen()
# Don't run this test if we have any failure.
if tgen.routers_have_failure():
pytest.skip(tgen.errors)
r1 = tgen.gears["r1"]
r1.vtysh_cmd(
"""
configure
router bgp 99 vrf DONNA
address-family ipv4 unicast
no network 172.16.3.0/24
"""
)
# Test default VRF.
expect = {
"172.16.3.0/24": None,
}
test_func = partial(topotest.router_json_cmp, r1, "show ip route json", expect)
result, diff = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
assert result, "BGP VRF default check failed:\n{}".format(diff)
# check BGP IPv4 VPN table
json_file = "{}/{}/show_bgp_ipv4_vpn_del_donna_prefix.json".format(CWD, r1.name)
expect = json.loads(open(json_file).read())
test_func = partial(topotest.router_json_cmp, r1, "show bgp ipv4 vpn json", expect)
result, diff = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
assert result, "BGP IPv4 VPN table check failed:\n{}".format(diff)
def test_vrf_route_leak_default_prefix_back():
logger.info(
"Set back BGP static prefix 172.16.3.0/24 to VRF DONNA and ensure that the route is set on default"
)
tgen = get_topogen()
# Don't run this test if we have any failure.
if tgen.routers_have_failure():
pytest.skip(tgen.errors)
r1 = tgen.gears["r1"]
r1.vtysh_cmd(
"""
configure
router bgp 99 vrf DONNA
address-family ipv4 unicast
network 172.16.3.0/24
"""
)
# Test default VRF.
expect = {
"172.16.3.0/24": [
{
"protocol": "bgp",
"selected": True,
"nexthops": [
{
"fib": True,
"interfaceName": "DONNA",
"vrf": "DONNA",
"active": True,
}
],
},
],
}
test_func = partial(topotest.router_json_cmp, r1, "show ip route json", expect)
result, diff = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
assert result, "BGP VRF default check failed:\n{}".format(diff)
# check BGP IPv4 VPN table
json_file = "{}/{}/show_bgp_ipv4_vpn_init.json".format(CWD, r1.name)
expect = json.loads(open(json_file).read())
test_func = partial(topotest.router_json_cmp, r1, "show bgp ipv4 vpn json", expect)
result, diff = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
assert result, "BGP IPv4 VPN table check failed:\n{}".format(diff)
def test_memory_leak():
"Run the memory leak test and report results."

View File

@ -123,20 +123,7 @@ def test_vrf_route_leak_donna():
],
},
],
"172.16.101.0/24": [
{
"protocol": "bgp",
"selected": None,
"nexthops": [
{
"fib": None,
"interfaceName": "unknown",
"vrf": "Unknown",
"active": None,
},
],
},
],
"172.16.101.0/24": None,
}
test_func = partial(
@ -195,20 +182,7 @@ def test_vrf_route_leak_eva():
"protocol": "connected",
}
],
"172.16.101.0/24": [
{
"protocol": "bgp",
"selected": None,
"nexthops": [
{
"fib": None,
"interfaceName": "unknown",
"vrf": "Unknown",
"active": None,
},
],
},
],
"172.16.101.0/24": None,
}
test_func = partial(
@ -302,34 +276,8 @@ interface EVA
# Test DONNA VRF.
expect = {
"10.0.1.0/24": [
{
"protocol": "bgp",
"selected": None,
"nexthops": [
{
"fib": None,
"interfaceName": "EVA",
"vrf": "EVA",
"active": None,
},
],
},
],
"10.0.3.0/24": [
{
"protocol": "bgp",
"selected": None,
"nexthops": [
{
"fib": None,
"interfaceName": "EVA",
"vrf": "EVA",
"active": None,
},
],
},
],
"10.0.1.0/24": None,
"10.0.3.0/24": None,
}
test_func = partial(
@ -421,20 +369,7 @@ def test_vrf_route_leak_donna_add_vrf_zita():
# Test DONNA VRF.
expect = {
"172.16.101.0/24": [
{
"protocol": "bgp",
"selected": None,
"nexthops": [
{
"fib": None,
"interfaceName": "ZITA",
"vrf": "ZITA",
"active": None,
},
],
},
],
"172.16.101.0/24": None,
}
test_func = partial(