mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-05-28 15:33:34 +00:00
Merge pull request #15255 from louis-6wind/bgp-leak-interface
bgpd: fix interface of routes leaked from another VRF
This commit is contained in:
commit
afa07a7f3a
@ -2209,12 +2209,22 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp, /* to */
|
||||
/* If the path has accept-own community and the source VRF
|
||||
* is valid, reset next-hop to self, to allow importing own
|
||||
* routes between different VRFs on the same node.
|
||||
* Set the nh ifindex to VRF's interface, not the real interface.
|
||||
*/
|
||||
|
||||
if (src_bgp)
|
||||
subgroup_announce_reset_nhop(nhfamily, &static_attr);
|
||||
|
||||
bpi_ultimate = bgp_get_imported_bpi_ultimate(path_vpn);
|
||||
|
||||
/* The nh ifindex may not be defined (when the route is
|
||||
* imported from the network statement => BGP_ROUTE_STATIC)
|
||||
* or to the real interface.
|
||||
* Rewrite the nh ifindex to VRF's interface.
|
||||
* Let the kernel to decide with double lookup the real next-hop
|
||||
* interface when installing the route.
|
||||
*/
|
||||
if (src_bgp) {
|
||||
subgroup_announce_reset_nhop(nhfamily, &static_attr);
|
||||
if (src_bgp || bpi_ultimate->sub_type == BGP_ROUTE_STATIC ||
|
||||
bpi_ultimate->sub_type == BGP_ROUTE_REDISTRIBUTE) {
|
||||
ifp = if_get_vrf_loopback(src_vrf->vrf_id);
|
||||
if (ifp)
|
||||
static_attr.nh_ifindex = ifp->ifindex;
|
||||
@ -2300,9 +2310,6 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp, /* to */
|
||||
*/
|
||||
if (!CHECK_FLAG(to_bgp->af_flags[afi][safi],
|
||||
BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
|
||||
/* work back to original route */
|
||||
bpi_ultimate = bgp_get_imported_bpi_ultimate(path_vpn);
|
||||
|
||||
/*
|
||||
* if original route was unicast,
|
||||
* then it did not arrive over vpn
|
||||
|
@ -12,7 +12,7 @@
|
||||
{
|
||||
"fib": true,
|
||||
"directlyConnected": true,
|
||||
"interfaceName": "eth0",
|
||||
"interfaceName": "vrf10",
|
||||
"vrf": "vrf10",
|
||||
"active": true
|
||||
}
|
||||
|
@ -1,10 +1,19 @@
|
||||
hostname r1
|
||||
|
||||
router bgp 99
|
||||
no bgp ebgp-requires-policy
|
||||
address-family ipv4 unicast
|
||||
redistribute connected
|
||||
import vrf DONNA
|
||||
!
|
||||
!
|
||||
router bgp 99 vrf DONNA
|
||||
no bgp ebgp-requires-policy
|
||||
address-family ipv4 unicast
|
||||
redistribute connected
|
||||
import vrf EVA
|
||||
import vrf NOTEXISTING
|
||||
import vrf default
|
||||
!
|
||||
!
|
||||
router bgp 99 vrf EVA
|
||||
@ -12,5 +21,13 @@ router bgp 99 vrf EVA
|
||||
address-family ipv4 unicast
|
||||
redistribute connected
|
||||
import vrf DONNA
|
||||
import vrf NOTEXISTING
|
||||
!
|
||||
!
|
||||
router bgp 99 vrf NOTEXISTING
|
||||
no bgp ebgp-requires-policy
|
||||
no bgp network import-check
|
||||
address-family ipv4 unicast
|
||||
network 172.16.101.0/24
|
||||
!
|
||||
!
|
||||
|
@ -1,5 +1,9 @@
|
||||
hostname r1
|
||||
|
||||
int dummy0
|
||||
ip address 10.0.4.1/24
|
||||
no shut
|
||||
!
|
||||
int dummy1
|
||||
ip address 10.0.0.1/24
|
||||
no shut
|
||||
@ -16,3 +20,9 @@ int dummy4
|
||||
ip address 10.0.3.1/24
|
||||
no shut
|
||||
!
|
||||
int EVA
|
||||
no shut
|
||||
!
|
||||
int DONNA
|
||||
no shut
|
||||
!
|
||||
|
@ -3,6 +3,7 @@
|
||||
ip link add DONNA type vrf table 1001
|
||||
ip link add EVA type vrf table 1002
|
||||
|
||||
ip link add dummy0 type dummy # vrf default
|
||||
ip link add dummy1 type dummy
|
||||
ip link add dummy2 type dummy
|
||||
ip link add dummy3 type dummy
|
||||
|
@ -64,7 +64,7 @@ def teardown_module(mod):
|
||||
tgen.stop_topology()
|
||||
|
||||
|
||||
def test_vrf_route_leak():
|
||||
def test_vrf_route_leak_donna():
|
||||
logger.info("Ensure that routes are leaked back and forth")
|
||||
tgen = get_topogen()
|
||||
# Don't run this test if we have any failure.
|
||||
@ -81,11 +81,59 @@ def test_vrf_route_leak():
|
||||
}
|
||||
],
|
||||
"10.0.1.0/24": [
|
||||
{"protocol": "bgp", "selected": True, "nexthops": [{"fib": True}]}
|
||||
{
|
||||
"protocol": "bgp",
|
||||
"selected": True,
|
||||
"nexthops": [
|
||||
{
|
||||
"fib": True,
|
||||
"interfaceName": "EVA",
|
||||
"vrf": "EVA",
|
||||
"active": True,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
"10.0.2.0/24": [{"protocol": "connected"}],
|
||||
"10.0.3.0/24": [
|
||||
{"protocol": "bgp", "selected": True, "nexthops": [{"fib": True}]}
|
||||
{
|
||||
"protocol": "bgp",
|
||||
"selected": True,
|
||||
"nexthops": [
|
||||
{
|
||||
"fib": True,
|
||||
"interfaceName": "EVA",
|
||||
"vrf": "EVA",
|
||||
"active": True,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
"10.0.4.0/24": [
|
||||
{
|
||||
"protocol": "bgp",
|
||||
"selected": True,
|
||||
"nexthops": [
|
||||
{
|
||||
"fib": True,
|
||||
"interfaceName": "lo",
|
||||
"vrf": "default",
|
||||
"active": True,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
"172.16.101.0/24": [
|
||||
{
|
||||
"protocol": "bgp",
|
||||
"nexthops": [
|
||||
{
|
||||
"interfaceIndex": 0,
|
||||
"interfaceName": "unknown",
|
||||
"vrf": "Unknown",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
@ -95,10 +143,31 @@ def test_vrf_route_leak():
|
||||
result, diff = topotest.run_and_expect(test_func, None, count=10, wait=0.5)
|
||||
assert result, "BGP VRF DONNA check failed:\n{}".format(diff)
|
||||
|
||||
|
||||
def test_vrf_route_leak_eva():
|
||||
logger.info("Ensure that routes are leaked back and forth")
|
||||
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"]
|
||||
|
||||
# Test EVA VRF.
|
||||
expect = {
|
||||
"10.0.0.0/24": [
|
||||
{"protocol": "bgp", "selected": True, "nexthops": [{"fib": True}]}
|
||||
{
|
||||
"protocol": "bgp",
|
||||
"selected": True,
|
||||
"nexthops": [
|
||||
{
|
||||
"fib": True,
|
||||
"interfaceName": "DONNA",
|
||||
"vrf": "DONNA",
|
||||
"active": True,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
"10.0.1.0/24": [
|
||||
{
|
||||
@ -106,13 +175,36 @@ def test_vrf_route_leak():
|
||||
}
|
||||
],
|
||||
"10.0.2.0/24": [
|
||||
{"protocol": "bgp", "selected": True, "nexthops": [{"fib": True}]}
|
||||
{
|
||||
"protocol": "bgp",
|
||||
"selected": True,
|
||||
"nexthops": [
|
||||
{
|
||||
"fib": True,
|
||||
"interfaceName": "DONNA",
|
||||
"vrf": "DONNA",
|
||||
"active": True,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
"10.0.3.0/24": [
|
||||
{
|
||||
"protocol": "connected",
|
||||
}
|
||||
],
|
||||
"172.16.101.0/24": [
|
||||
{
|
||||
"protocol": "bgp",
|
||||
"nexthops": [
|
||||
{
|
||||
"interfaceIndex": 0,
|
||||
"interfaceName": "unknown",
|
||||
"vrf": "Unknown",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
test_func = partial(
|
||||
@ -122,6 +214,217 @@ def test_vrf_route_leak():
|
||||
assert result, "BGP VRF EVA check failed:\n{}".format(diff)
|
||||
|
||||
|
||||
def test_vrf_route_leak_donna():
|
||||
logger.info("Ensure that routes are leaked back and forth")
|
||||
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"]
|
||||
|
||||
# Test DONNA VRF.
|
||||
expect = {
|
||||
"10.0.0.0/24": [
|
||||
{
|
||||
"protocol": "connected",
|
||||
}
|
||||
],
|
||||
"10.0.1.0/24": [
|
||||
{
|
||||
"protocol": "bgp",
|
||||
"selected": True,
|
||||
"nexthops": [
|
||||
{
|
||||
"fib": True,
|
||||
"interfaceName": "EVA",
|
||||
"vrf": "EVA",
|
||||
"active": True,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
"10.0.2.0/24": [{"protocol": "connected"}],
|
||||
"10.0.3.0/24": [
|
||||
{
|
||||
"protocol": "bgp",
|
||||
"selected": True,
|
||||
"nexthops": [
|
||||
{
|
||||
"fib": True,
|
||||
"interfaceName": "EVA",
|
||||
"vrf": "EVA",
|
||||
"active": True,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
"10.0.4.0/24": [
|
||||
{
|
||||
"protocol": "bgp",
|
||||
"selected": True,
|
||||
"nexthops": [
|
||||
{
|
||||
"fib": True,
|
||||
"interfaceName": "lo",
|
||||
"vrf": "default",
|
||||
"active": True,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
"172.16.101.0/24": [
|
||||
{
|
||||
"protocol": "bgp",
|
||||
"nexthops": [
|
||||
{
|
||||
"interfaceIndex": 0,
|
||||
"interfaceName": "unknown",
|
||||
"vrf": "Unknown",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
test_func = partial(
|
||||
topotest.router_json_cmp, r1, "show ip route vrf DONNA json", expect
|
||||
)
|
||||
result, diff = topotest.run_and_expect(test_func, None, count=10, wait=0.5)
|
||||
assert result, "BGP VRF DONNA check failed:\n{}".format(diff)
|
||||
|
||||
|
||||
def test_vrf_route_leak_eva():
|
||||
logger.info("Ensure that routes are leaked back and forth")
|
||||
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"]
|
||||
|
||||
# Test EVA VRF.
|
||||
expect = {
|
||||
"10.0.0.0/24": [
|
||||
{
|
||||
"protocol": "bgp",
|
||||
"selected": True,
|
||||
"nexthops": [
|
||||
{
|
||||
"fib": True,
|
||||
"interfaceName": "DONNA",
|
||||
"vrf": "DONNA",
|
||||
"active": True,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
"10.0.1.0/24": [
|
||||
{
|
||||
"protocol": "connected",
|
||||
}
|
||||
],
|
||||
"10.0.2.0/24": [
|
||||
{
|
||||
"protocol": "bgp",
|
||||
"selected": True,
|
||||
"nexthops": [
|
||||
{
|
||||
"fib": True,
|
||||
"interfaceName": "DONNA",
|
||||
"vrf": "DONNA",
|
||||
"active": True,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
"10.0.3.0/24": [
|
||||
{
|
||||
"protocol": "connected",
|
||||
}
|
||||
],
|
||||
"172.16.101.0/24": [
|
||||
{
|
||||
"protocol": "bgp",
|
||||
"nexthops": [
|
||||
{
|
||||
"interfaceIndex": 0,
|
||||
"interfaceName": "unknown",
|
||||
"vrf": "Unknown",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
def test_vrf_route_leak_default():
|
||||
logger.info("Ensure that routes are leaked back and forth")
|
||||
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"]
|
||||
|
||||
# Test default VRF.
|
||||
expect = {
|
||||
"10.0.0.0/24": [
|
||||
{
|
||||
"protocol": "bgp",
|
||||
"selected": True,
|
||||
"nexthops": [
|
||||
{
|
||||
"fib": True,
|
||||
"interfaceName": "DONNA",
|
||||
"vrf": "DONNA",
|
||||
"active": True,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
"10.0.2.0/24": [
|
||||
{
|
||||
"protocol": "bgp",
|
||||
"selected": True,
|
||||
"nexthops": [
|
||||
{
|
||||
"fib": True,
|
||||
"interfaceName": "DONNA",
|
||||
"vrf": "DONNA",
|
||||
"active": True,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
"10.0.4.0/24": [
|
||||
{
|
||||
"protocol": "connected",
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
test_func = partial(topotest.router_json_cmp, r1, "show ip route json", expect)
|
||||
result, diff = topotest.run_and_expect(test_func, None, count=10, wait=0.5)
|
||||
assert result, "BGP VRF default check failed:\n{}".format(diff)
|
||||
|
||||
|
||||
def test_ping():
|
||||
"Simple ping tests"
|
||||
|
||||
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"]
|
||||
|
||||
logger.info("Ping from default to DONNA")
|
||||
output = r1.run("ping -c 4 -w 4 -I 10.0.4.1 10.0.0.1")
|
||||
assert " 0% packet loss" in output, "Ping default->DONNA FAILED"
|
||||
|
||||
|
||||
def test_memory_leak():
|
||||
"Run the memory leak test and report results."
|
||||
tgen = get_topogen()
|
||||
|
@ -7,5 +7,5 @@ O>* 10.0.4.0/24 [110/20] via 10.0.20.2, r1-eth1, weight 1, XX:XX:XX
|
||||
O 10.0.20.0/24 [110/10] is directly connected, r1-eth1, weight 1, XX:XX:XX
|
||||
C>* 10.0.20.0/24 is directly connected, r1-eth1, XX:XX:XX
|
||||
L>* 10.0.20.1/32 is directly connected, r1-eth1, XX:XX:XX
|
||||
B>* 10.0.30.0/24 [20/0] is directly connected, r1-eth2 (vrf neno), weight 1, XX:XX:XX
|
||||
B>* 10.0.30.0/24 [20/0] is directly connected, neno (vrf neno), weight 1, XX:XX:XX
|
||||
O>* 10.0.40.0/24 [110/20] via 10.0.20.2, r1-eth1, weight 1, XX:XX:XX
|
||||
|
@ -9,4 +9,4 @@ O 10.0.20.0/24 [110/10] is directly connected, r2-eth1, weight 1, XX:XX:XX
|
||||
C>* 10.0.20.0/24 is directly connected, r2-eth1, XX:XX:XX
|
||||
L>* 10.0.20.2/32 is directly connected, r2-eth1, XX:XX:XX
|
||||
O>* 10.0.30.0/24 [110/20] via 10.0.20.1, r2-eth1, weight 1, XX:XX:XX
|
||||
B>* 10.0.40.0/24 [20/0] is directly connected, r2-eth2 (vrf ray), weight 1, XX:XX:XX
|
||||
B>* 10.0.40.0/24 [20/0] is directly connected, ray (vrf ray), weight 1, XX:XX:XX
|
||||
|
@ -1,9 +1,9 @@
|
||||
VRF ray:
|
||||
B 10.0.1.0/24 [20/20] via 10.0.20.1, r2-eth1 (vrf default) inactive, weight 1, XX:XX:XX
|
||||
B 10.0.2.0/24 [20/0] is directly connected, r2-eth0 (vrf default) inactive, weight 1, XX:XX:XX
|
||||
B 10.0.2.0/24 [20/0] is directly connected, lo (vrf default) inactive, weight 1, XX:XX:XX
|
||||
B>* 10.0.3.0/24 [20/20] via 10.0.20.1, r2-eth1 (vrf default), weight 1, XX:XX:XX
|
||||
O>* 10.0.4.0/24 [110/20] via 10.0.40.4, r2-eth2, weight 1, XX:XX:XX
|
||||
B 10.0.20.0/24 [20/0] is directly connected, r2-eth1 (vrf default) inactive, weight 1, XX:XX:XX
|
||||
B 10.0.20.0/24 [20/0] is directly connected, lo (vrf default) inactive, weight 1, XX:XX:XX
|
||||
B>* 10.0.30.0/24 [20/20] via 10.0.20.1, r2-eth1 (vrf default), weight 1, XX:XX:XX
|
||||
O 10.0.40.0/24 [110/10] is directly connected, r2-eth2, weight 1, XX:XX:XX
|
||||
C>* 10.0.40.0/24 is directly connected, r2-eth2, XX:XX:XX
|
||||
|
Loading…
Reference in New Issue
Block a user