summaryrefslogtreecommitdiff
path: root/bgpd/bgp_advertise.c
diff options
context:
space:
mode:
authorPhilippe Guibert <philippe.guibert@6wind.com>2023-01-13 15:59:52 +0100
committerLouis Scalbert <louis.scalbert@6wind.com>2024-06-05 13:11:29 +0200
commit9fd26c1aa5348bc1d73b92feab2f4e96196c00e3 (patch)
tree970577b831716c39d5cee962c6f8b68c48090b32 /bgpd/bgp_advertise.c
parentb80499339406dbfed0ffee32e1fb2d6505c23679 (diff)
bgpd: fix labels in adj-rib-in
In a BGP L3VPN context using ADJ-RIB-IN (ie. enabled with 'soft-reconfiguration inbound'), after applying a deny route-map and removing it, the remote MPLS label information is lost. As a result, BGP is unable to re-install the related routes in the RIB. For example, > router bgp 65500 > [..] > neighbor 192.0.2.2 remote-as 65501 > address-family ipv4 vpn > neighbor 192.0.2.2 activate > neighbor 192.0.2.2 soft-reconfiguration inbound The 192.168.0.0/24 prefix has a remote label value of 102 in the BGP RIB. > # show bgp ipv4 vpn 192.168.0.0/24 > BGP routing table entry for 444:1:192.168.0.0/24, version 2 > [..] > 192.168.0.0 from 192.0.2.2 > Origin incomplete, metric 0, valid, external, best (First path received) > Extended Community: RT:52:100 > Remote label: 102 A route-map now filter all incoming BGP updates: > route-map rmap deny 1 > router bgp 65500 > address-family ipv4 vpn > neighbor 192.0.2.2 route-map rmap in The prefix is now filtered: > # show bgp ipv4 vpn 192.168.0.0/24 > # The route-map is detached: > router bgp 65500 > address-family ipv4 vpn > no neighbor 192.168.0.1 route-map rmap in The BGP RIB entry is present but the remote label is lost: > # show bgp ipv4 vpn 192.168.0.0/24 > BGP routing table entry for 444:1:192.168.0.0/24, version 2 > [..] > 192.168.0.0 from 192.0.2.2 > Origin incomplete, metric 0, valid, external, best (First path received) > Extended Community: RT:52:100 The reason for the loose is that labels are stored within struct attr -> struct extra -> struct bgp_labels but not in the struct bgp_adj_in. Reference the bgp_labels pointer in struct bgp_adj_in and use its values when doing a soft reconfiguration of the BGP table. Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com> Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
Diffstat (limited to 'bgpd/bgp_advertise.c')
-rw-r--r--bgpd/bgp_advertise.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/bgpd/bgp_advertise.c b/bgpd/bgp_advertise.c
index d519749f6b..d5c7e1887b 100644
--- a/bgpd/bgp_advertise.c
+++ b/bgpd/bgp_advertise.c
@@ -163,7 +163,7 @@ bool bgp_adj_out_lookup(struct peer *peer, struct bgp_dest *dest,
void bgp_adj_in_set(struct bgp_dest *dest, struct peer *peer, struct attr *attr,
- uint32_t addpath_id)
+ uint32_t addpath_id, struct bgp_labels *labels)
{
struct bgp_adj_in *adj;
@@ -173,6 +173,10 @@ void bgp_adj_in_set(struct bgp_dest *dest, struct peer *peer, struct attr *attr,
bgp_attr_unintern(&adj->attr);
adj->attr = bgp_attr_intern(attr);
}
+ if (!bgp_labels_cmp(adj->labels, labels)) {
+ bgp_labels_unintern(&adj->labels);
+ adj->labels = bgp_labels_intern(labels);
+ }
return;
}
}
@@ -181,6 +185,7 @@ void bgp_adj_in_set(struct bgp_dest *dest, struct peer *peer, struct attr *attr,
adj->attr = bgp_attr_intern(attr);
adj->uptime = monotime(NULL);
adj->addpath_rx_id = addpath_id;
+ adj->labels = bgp_labels_intern(labels);
BGP_ADJ_IN_ADD(dest, adj);
peer->stat_pfx_adj_rib_in++;
bgp_dest_lock_node(dest);
@@ -189,6 +194,7 @@ void bgp_adj_in_set(struct bgp_dest *dest, struct peer *peer, struct attr *attr,
void bgp_adj_in_remove(struct bgp_dest **dest, struct bgp_adj_in *bai)
{
bgp_attr_unintern(&bai->attr);
+ bgp_labels_unintern(&bai->labels);
if (bai->peer)
bai->peer->stat_pfx_adj_rib_in--;
BGP_ADJ_IN_DEL(*dest, bai);