summaryrefslogtreecommitdiff
path: root/bgpd/rfapi/rfapi_rib.c
diff options
context:
space:
mode:
authorLouis Scalbert <louis.scalbert@6wind.com>2024-02-05 17:05:20 +0100
committerLouis Scalbert <louis.scalbert@6wind.com>2024-06-05 11:08:46 +0200
commit747da057e814258533ea149da804adfdb4219f27 (patch)
tree563621beaa63daf88e1f99414144bcd065edb489 /bgpd/rfapi/rfapi_rib.c
parent17e1f7c2ff94da6d554a464a316ad037d6727749 (diff)
bgpd: check and set extra num_labels
The handling of MPLS labels in BGP faces an issue due to the way labels are stored in memory. They are stored in bgp_path_info but not in bgp_adj_in and bgp_adj_out structures. As a consequence, some configuration changes result in losing labels or even a bgpd crash. For example, when retrieving routes from the Adj-RIB-in table ("soft-reconfiguration inbound" enabled), labels are missing. bgp_path_info stores the MPLS labels, as shown below: > struct bgp_path_info { > struct bgp_path_info_extra *extra; > [...] > struct bgp_path_info_extra { > mpls_label_t label[BGP_MAX_LABELS]; > uint32_t num_labels; > [...] To solve those issues, a solution would be to set label data to the bgp_adj_in and bgp_adj_out structures in addition to the bgp_path_info_extra structure. The idea is to reference a common label pointer in all these three structures. And to store the data in a hash list in order to save memory. However, an issue in the code prevents us from setting clean data without a rework. The extra->num_labels field, which is intended to indicate the number of labels in extra->label[], is not reliably checked or set. The code often incorrectly assumes that if the extra pointer is present, then a label must also be present, leading to direct access to extra->label[] without verifying extra->num_labels. This assumption usually works because extra->label[0] is set to MPLS_INVALID_LABEL when a new bgp_path_info_extra is created, but it is technically incorrect. Cleanup the label code by setting num_labels each time values are set in extra->label[] and checking extra->num_labels before accessing the labels. Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
Diffstat (limited to 'bgpd/rfapi/rfapi_rib.c')
-rw-r--r--bgpd/rfapi/rfapi_rib.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/bgpd/rfapi/rfapi_rib.c b/bgpd/rfapi/rfapi_rib.c
index 316904e45b..11dccbf1b5 100644
--- a/bgpd/rfapi/rfapi_rib.c
+++ b/bgpd/rfapi/rfapi_rib.c
@@ -691,7 +691,10 @@ static void rfapiRibBi2Ri(struct bgp_path_info *bpi, struct rfapi_info *ri,
bpi->extra->vnc->vnc.import.rd.val[1];
/* label comes from MP_REACH_NLRI label */
- vo->v.l2addr.label = decode_label(&bpi->extra->label[0]);
+ vo->v.l2addr.label =
+ bpi->extra->num_labels
+ ? decode_label(&bpi->extra->label[0])
+ : MPLS_INVALID_LABEL;
rfapi_vn_options_free(
ri->vn_options); /* maybe free old version */