From a04f1c42ebe1c0824962dbaa507491ec9b269f5e Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Mon, 2 Jan 2023 15:11:31 +0100 Subject: [PATCH] bgpd: imported vpn entries get appropriate distance MPLS VPN networks can either peer with iBGP or eBGP. When calculating the distance to send to zebra, the imported prefix is never sent with distance information, even if the vty command is used under the ipv4 unicast address family: router bgp 65505 vrf vrf1 address-family ipv4 unicast distance bgp 26 27 28 [vpn config] The observation is that the distance sent to zebra for an imported prefix is still 20: [..] VRF vrf1: B> 192.168.0.0/24 [20/0] via 2.2.2.2 (vrf default) (recursive), label 20, weight 1, 00:00:12 * via 10.125.0.6, ntfp3 (vrf default), label implicit-null/20, weight 1, 00:00:12 The expectation is that the incoming prefix has to follow the distance that is configured, or the distance derived from the peer relationship established by the parent prefix. In the case, an iBGP relationship is done, and no distance configuration is done, the below show is expected: [..] VRF vrf1: B*> 192.168.0.0/24 [200/0] via 192.168.0.2, r1-gre0 (vrf default), label 20, weight 1, 00:00:12 In the case an iBGP relationship is done, and distance configuration is performed as below: [..] distance bgp 21 201 41 [..] Then the below show is expected: [..] VRF vrf1: B*> 192.168.0.0/24 [201/0] via 192.168.0.2, r1-gre0 (vrf default), label 20, weight 1, 00:00:12 To get this behaviour, get the peer origin where the prefix is coming from. Signed-off-by: Philippe Guibert --- bgpd/bgp_route.c | 7 +++++++ tests/topotests/bgp_vpnv4_gre/r1/bgpd.conf | 1 + tests/topotests/bgp_vpnv4_gre/r1/ipv4_routes.json | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 87871573f0..9d776788ee 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -15012,6 +15012,7 @@ uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo, struct bgp_distance *bdistance; struct access_list *alist; struct bgp_static *bgp_static; + struct bgp_path_info *bpi_ultimate; if (!bgp) return 0; @@ -15021,6 +15022,12 @@ uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo, if (pinfo->attr->distance) return pinfo->attr->distance; + /* get peer origin to calculate appropriate distance */ + if (pinfo->sub_type == BGP_ROUTE_IMPORTED) { + bpi_ultimate = bgp_get_imported_bpi_ultimate(pinfo); + peer = bpi_ultimate->peer; + } + /* Check source address. * Note: for aggregate route, peer can have unspec af type. */ diff --git a/tests/topotests/bgp_vpnv4_gre/r1/bgpd.conf b/tests/topotests/bgp_vpnv4_gre/r1/bgpd.conf index 0e2d3a8248..295811bfd0 100644 --- a/tests/topotests/bgp_vpnv4_gre/r1/bgpd.conf +++ b/tests/topotests/bgp_vpnv4_gre/r1/bgpd.conf @@ -14,6 +14,7 @@ router bgp 65500 vrf vrf1 bgp router-id 192.0.2.1 address-family ipv4 unicast redistribute connected + distance bgp 21 201 41 label vpn export 101 rd vpn export 444:1 rt vpn both 52:100 diff --git a/tests/topotests/bgp_vpnv4_gre/r1/ipv4_routes.json b/tests/topotests/bgp_vpnv4_gre/r1/ipv4_routes.json index 5f2732aab0..e57e21bb12 100644 --- a/tests/topotests/bgp_vpnv4_gre/r1/ipv4_routes.json +++ b/tests/topotests/bgp_vpnv4_gre/r1/ipv4_routes.json @@ -7,7 +7,7 @@ "vrfName": "vrf1", "selected": true, "destSelected": true, - "distance": 20, + "distance": 201, "metric": 0, "nexthops": [ { -- 2.39.5