diff options
| author | Philippe Guibert <philippe.guibert@6wind.com> | 2023-01-13 15:59:52 +0100 | 
|---|---|---|
| committer | Louis Scalbert <louis.scalbert@6wind.com> | 2024-06-05 13:11:29 +0200 | 
| commit | 9fd26c1aa5348bc1d73b92feab2f4e96196c00e3 (patch) | |
| tree | 970577b831716c39d5cee962c6f8b68c48090b32 /bgpd/bgp_advertise.c | |
| parent | b80499339406dbfed0ffee32e1fb2d6505c23679 (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.c | 8 | 
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);  | 
