diff options
| author | Louis Scalbert <louis.scalbert@6wind.com> | 2024-02-05 17:05:20 +0100 |
|---|---|---|
| committer | Louis Scalbert <louis.scalbert@6wind.com> | 2024-06-05 11:08:46 +0200 |
| commit | 747da057e814258533ea149da804adfdb4219f27 (patch) | |
| tree | 563621beaa63daf88e1f99414144bcd065edb489 /bgpd/rfapi/rfapi_rib.c | |
| parent | 17e1f7c2ff94da6d554a464a316ad037d6727749 (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.c | 5 |
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 */ |
