Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bgpd: fix interface of routes leaked from another VRF #15255

Merged
merged 7 commits into from
Feb 8, 2024

Conversation

louis-6wind
Copy link
Contributor

The interface of routes leaked from another VRF is incorrect in the following cases:

  1. the route originates from the "network" statement, the nexthop interface is unknown

> B 192.0.2.0/24 [20/0] is directly connected, unknown (vrf r1-cust1) inactive, weight 1, 00:03:40

  1. the route originates from "redistribute connected", the nexthop interface is the interface from the source VRF, which is unknown in the destination VRF.

> B>* 172.16.29.0/24 [20/0] is directly connected, r1-eth4 (vrf r1-cust1), weight 1, 00:00:02

The expected output is:

> B>* 192.0.2.0/24 [20/0] is directly connected, r1-cust1 (vrf r1-cust1) inactive, weight 1, 00:03:40
> B>* 172.16.29.0/24 [20/0] is directly connected, r1-cust1 (vrf r1-cust1), weight 1, 00:00:02

Copy link
Member

@riw777 riw777 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good

@riw777
Copy link
Member

riw777 commented Jan 30, 2024

this failure might be in the test rewrite ... might need to be looked at

@Jafaral Jafaral added this to the 10.0 milestone Jan 30, 2024
@github-actions github-actions bot added size/M and removed size/S labels Jan 31, 2024
@louis-6wind
Copy link
Contributor Author

this failure might be in the test rewrite ... might need to be looked at

fixed. The current CI error is unrelated

Copy link
Member

@ton31337 ton31337 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have a topotest that covers unknown VRF scenario with network?

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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this loopback? Is this sort of VRF's loopback that will be resolved to r2-eth1 or how it's supposed to work here?

Copy link
Contributor Author

@louis-6wind louis-6wind Feb 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added a commit "topotests: test leak from default vrf"

VRF interfaces are the equivalent of the lo interface for the VRFs.

In this example, if the route to 10.0.20.0/24 were active, it would not be operational with r2-eth1 interface nexthop because r2-eth1 is unknown from vrf ray. It would be operational with lo instead. lo would reroute to r2-eth1 using the default VRF routing table

louis-6wind and others added 6 commits February 1, 2024 10:21
Leaked routes from prefixes defined with 'network <prefix>' are inactive
because they have no valid nexthop interface.

> vrf r1-cust1
>  ip route 172.16.29.0/24 192.168.1.2
> router bgp 5227 vrf r1-cust1
>  no bgp network import-check
>  address-family ipv4 unicast
>   network 172.16.29.0/24
>   rd vpn export 10:1
>   rt vpn import 52:100
>   rt vpn export 52:101
>   export vpn
>   import vpn
>  exit-address-family
> exit
> !
> router bgp 5227 vrf r1-cust4
>  bgp router-id 192.168.1.1
> !
>  address-family ipv4 unicast
>   network 192.0.2/24
>   rd vpn export 10:1
>   rt vpn import 52:101
>   rt vpn export 52:100
>   export vpn
>   import vpn
>  exit-address-family
> exit

Extract from the routing table:

> VRF r1-cust1:
> S>* 172.16.29.0/24 [1/0] via 192.168.1.2, r1-eth4, weight 1, 00:47:53
>
> VRF r1-cust4:
> B   172.16.29.0/24 [20/0] is directly connected, unknown (vrf r1-cust1) inactive, weight 1, 00:03:40

Routes imported through the "network" command, as opposed to those
redistributed from the routing table, do not associate with any specific
interface.

When leaking prefix from other VRFs, if the route was imported from the
network statement (ie. static sub-type), set nh_ifindex to the index of
the VRF master interface of the incoming BGP instance.

The result is:

> VRF r1-cust4:
> B>* 172.16.29.0/24 [20/0] is directly connected, r1-cust1 (vrf r1-cust1), weight 1, 00:00:08

Signed-off-by: Louis Scalbert <[email protected]>
In the target VRF's Routing Information Base (RIB), routes that are
leaked and originate from the 'redistribute connected' command have
their next-hop interface set as the interface from the source VRF.
This prevents the IP address of the connected interface from being
reachable from the target VRF.

> router bgp 5227 vrf r1-cust1
>  address-family ipv4 unicast
>   redistribute connected
>   rd vpn export 10:1
>   rt vpn import 52:100
>   rt vpn export 52:101
>   export vpn
>   import vpn
>  exit-address-family
> exit
> !
> router bgp 5227 vrf r1-cust4
>  address-family ipv4 unicast
>   network 192.0.2.0/24
>   rd vpn export 10:1
>   rt vpn import 52:101
>   rt vpn export 52:100
>   export vpn
>   import vpn
>  exit-address-family
> exit
> !
> vrf r1-cust1
>  ip route 192.0.2.0/24 r1-cust4 nexthop-vrf r1-cust4

Extract from the routing table:
> VRF r1-cust1:
> C>* 172.16.29.0/24 is directly connected, r1-eth4, 00:44:15
> S>* 192.0.2.0/24 [1/0] is directly connected, r1-cust4 (vrf r1-cust4), weight 1, 00:00:30
>
> VRF r1-cust4:
> B>* 172.16.29.0/24 [20/0] is directly connected, r1-eth4 (vrf r1-cust1), weight 1, 00:00:02

In r1-cust4 VRF, the nexthop interface of 172.16.29.0/24 is r1-eth4,
which is unknown in the context. The following ping does not work:

> # tcpdump -lnni r1-cust1 'icmp' &
> # ip vrf exec r1-cust4 ping -c1 -I 192.0.2.1 172.16.29.1
> PING 172.16.29.1 (172.16.29.1) 56(84) bytes of data.
PING 172.16.29.1 (172.16.29.1) from 192.0.2.1 : 56(84) bytes of data.
18:49:20.635638 IP 192.0.2.1 > 172.16.29.1: ICMP echo request, id 15897, seq 1, length 64
18:49:27.113827 IP 192.0.2.1 > 192.0.2.1: ICMP host 172.16.29.1 unreachable, length 92

Fix the issue by setting nh_ifindex to the index of the VRF master
interface of the incoming BGP instance. The result is:

> VRF r1-cust4:
> C>* 192.0.2.0/24 is directly connected, r1-cust5, 00:27:40
> B>* 172.16.29.0/24 [20/0] is directly connected, r1-cust1 (vrf r1-cust1), weight 1, 00:00:08

> # tcpdump -lnni r1-cust1 'icmp' &
> # ping -c1 172.16.29.1 -I 192.0.2.1
> PING 172.16.29.1 (172.16.29.1) from 192.0.2.1 : 56(84) bytes of data.
> 18:48:32.506281 IP 192.0.2.1 > 172.16.29.1: ICMP echo request, id 15870, seq 1, length 64
> 64 bytes from 172.16.29.1: icmp_seq=1 ttl=64 time=0.050 ms
> 18:48:32.506304 IP 172.16.29.1 > 192.0.2.1: ICMP echo reply, id 15870, seq 1, length 64

Signed-off-by: Louis Scalbert <[email protected]>
Leaked connected routes have now the following nexthop interfaces:
- lo for routes imported from the default VRF
- or the VRF interface for routes imported from the other VRFs.

Signed-off-by: Louis Scalbert <[email protected]>
Previously, routes leaked from one VRF to another VRF were associated
with the original nexthop interface.

Due to this change, the `bgp_srv6l3vpn_route_leak` topotest always fails
because it still expects the nexthop interface.

This commit fixes the expected interface name in the
`bgp_srv6l3vpn_route_leak` topotest.

Signed-off-by: Carmine Scarpitta <[email protected]>
Signed-off-by: Louis Scalbert <[email protected]>
Update bgp_vrf_route_leak_basic to set up the VRF interfaces. Otherwise
the routes to the VRF interface are inactives.

Signed-off-by: Louis Scalbert <[email protected]>
Add a test in bgp_vrf_route_leak_basic topotest to check that route
leaking from a non existing VRF results in an inactive route.

Signed-off-by: Louis Scalbert <[email protected]>
@louis-6wind
Copy link
Contributor Author

louis-6wind commented Feb 1, 2024

Do we have a topotest that covers unknown VRF scenario with network?

Done. See the commit "topotests: test leak from unknown vrf"

Add tests in bgp_vrf_route_leak_basic topotest to check that route
leaking from the default VRF results in an operational route.

Signed-off-by: Louis Scalbert <[email protected]>
@louis-6wind louis-6wind requested a review from ton31337 February 6, 2024 08:45
@donaldsharp donaldsharp merged commit afa07a7 into FRRouting:master Feb 8, 2024
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants