mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-07-13 22:16:43 +00:00
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:
commit
5518a8c916
@ -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);
|
||||
|
||||
|
@ -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(
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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."
|
||||
|
@ -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(
|
||||
|
Loading…
Reference in New Issue
Block a user