diff options
author | Louis Scalbert <louis.scalbert@6wind.com> | 2024-02-26 18:23:11 +0100 |
---|---|---|
committer | Louis Scalbert <louis.scalbert@6wind.com> | 2024-06-05 13:11:29 +0200 |
commit | ca32945b1fd694d10307d2885df62251f46bf581 (patch) | |
tree | 3d8c58c185062f8fe8c771bb55e3dfddf48c3572 | |
parent | bgpd: add bgp_labels hash (diff) | |
download | frr-ca32945b1fd694d10307d2885df62251f46bf581.tar.xz frr-ca32945b1fd694d10307d2885df62251f46bf581.zip |
bgpd: move labels from extra to extra->labels
Move labels from extra to extra->labels. Labels are now stored in a hash
list.
Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
-rw-r--r-- | bgpd/bgp_bmp.c | 26 | ||||
-rw-r--r-- | bgpd/bgp_evpn.c | 62 | ||||
-rw-r--r-- | bgpd/bgp_evpn_mh.c | 14 | ||||
-rw-r--r-- | bgpd/bgp_label.c | 5 | ||||
-rw-r--r-- | bgpd/bgp_label.h | 5 | ||||
-rw-r--r-- | bgpd/bgp_mac.c | 4 | ||||
-rw-r--r-- | bgpd/bgp_mplsvpn.c | 60 | ||||
-rw-r--r-- | bgpd/bgp_route.c | 73 | ||||
-rw-r--r-- | bgpd/bgp_route.h | 8 | ||||
-rw-r--r-- | bgpd/bgp_routemap.c | 2 | ||||
-rw-r--r-- | bgpd/bgp_rpki.c | 3 | ||||
-rw-r--r-- | bgpd/bgp_updgrp_packet.c | 6 | ||||
-rw-r--r-- | bgpd/bgp_zebra.c | 5 | ||||
-rw-r--r-- | bgpd/rfapi/rfapi.c | 7 | ||||
-rw-r--r-- | bgpd/rfapi/rfapi_import.c | 14 | ||||
-rw-r--r-- | bgpd/rfapi/rfapi_rib.c | 2 | ||||
-rw-r--r-- | bgpd/rfapi/rfapi_vty.c | 8 | ||||
-rw-r--r-- | bgpd/rfapi/vnc_import_bgp.c | 23 |
18 files changed, 185 insertions, 142 deletions
diff --git a/bgpd/bgp_bmp.c b/bgpd/bgp_bmp.c index bf08e3050..43f8006e2 100644 --- a/bgpd/bgp_bmp.c +++ b/bgpd/bgp_bmp.c @@ -38,6 +38,7 @@ #include "bgpd/bgp_vty.h" #include "bgpd/bgp_trace.h" #include "bgpd/bgp_network.h" +#include "bgpd/bgp_label.h" static void bmp_close(struct bmp *bmp); static struct bmp_bgp *bmp_bgp_find(struct bgp *bgp); @@ -1046,6 +1047,7 @@ static void bmp_monitor(struct bmp *bmp, struct peer *peer, uint8_t flags, static bool bmp_wrsync(struct bmp *bmp, struct pullwr *pullwr) { + uint8_t bpi_num_labels; afi_t afi; safi_t safi; @@ -1219,14 +1221,16 @@ afibreak: (safi == SAFI_MPLS_VPN)) prd = (struct prefix_rd *)bgp_dest_get_prefix(bmp->syncrdpos); + bpi_num_labels = bgp_path_info_num_labels(bpi); + if (bpi && CHECK_FLAG(bpi->flags, BGP_PATH_SELECTED) && CHECK_FLAG(bmp->targets->afimon[afi][safi], BMP_MON_LOC_RIB)) { bmp_monitor(bmp, bpi->peer, 0, BMP_PEER_TYPE_LOC_RIB_INSTANCE, bn_p, prd, bpi->attr, afi, safi, bpi && bpi->extra ? bpi->extra->bgp_rib_uptime : (time_t)(-1L), - bpi->extra ? bpi->extra->label : NULL, - bpi->extra ? bpi->extra->num_labels : 0); + bpi_num_labels ? bpi->extra->labels->label : NULL, + bpi_num_labels); } if (bpi && CHECK_FLAG(bpi->flags, BGP_PATH_VALID) && @@ -1234,8 +1238,8 @@ afibreak: bmp_monitor(bmp, bpi->peer, BMP_PEER_FLAG_L, BMP_PEER_TYPE_GLOBAL_INSTANCE, bn_p, prd, bpi->attr, afi, safi, bpi->uptime, - bpi->extra ? bpi->extra->label : NULL, - bpi->extra ? bpi->extra->num_labels : 0); + bpi_num_labels ? bpi->extra->labels->label : NULL, + bpi_num_labels); if (adjin) /* TODO: set label here when adjin supports labels */ @@ -1292,6 +1296,7 @@ static bool bmp_wrqueue_locrib(struct bmp *bmp, struct pullwr *pullwr) struct peer *peer; struct bgp_dest *bn = NULL; bool written = false; + uint8_t bpi_num_labels; bqe = bmp_pull_locrib(bmp); if (!bqe) @@ -1351,12 +1356,14 @@ static bool bmp_wrqueue_locrib(struct bmp *bmp, struct pullwr *pullwr) break; } + bpi_num_labels = bgp_path_info_num_labels(bpi); + bmp_monitor(bmp, peer, 0, BMP_PEER_TYPE_LOC_RIB_INSTANCE, &bqe->p, prd, bpi ? bpi->attr : NULL, afi, safi, bpi && bpi->extra ? bpi->extra->bgp_rib_uptime : (time_t)(-1L), - (bpi && bpi->extra) ? bpi->extra->label : NULL, - (bpi && bpi->extra) ? bpi->extra->num_labels : 0); + bpi_num_labels ? bpi->extra->labels->label : NULL, + bpi_num_labels); written = true; out: @@ -1375,6 +1382,7 @@ static bool bmp_wrqueue(struct bmp *bmp, struct pullwr *pullwr) struct peer *peer; struct bgp_dest *bn = NULL; bool written = false; + uint8_t bpi_num_labels; bqe = bmp_pull(bmp); if (!bqe) @@ -1426,12 +1434,14 @@ static bool bmp_wrqueue(struct bmp *bmp, struct pullwr *pullwr) break; } + bpi_num_labels = bgp_path_info_num_labels(bpi); + bmp_monitor(bmp, peer, BMP_PEER_FLAG_L, BMP_PEER_TYPE_GLOBAL_INSTANCE, &bqe->p, prd, bpi ? bpi->attr : NULL, afi, safi, bpi ? bpi->uptime : monotime(NULL), - (bpi && bpi->extra) ? bpi->extra->label : NULL, - (bpi && bpi->extra) ? bpi->extra->num_labels : 0); + bpi_num_labels ? bpi->extra->labels->label : NULL, + bpi_num_labels); written = true; } diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index e19d5efe3..5ce5b19b1 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -1602,7 +1602,7 @@ static int update_evpn_type5_route_entry(struct bgp *bgp_evpn, { struct attr *attr_new = NULL; struct bgp_path_info *pi = NULL; - mpls_label_t label = MPLS_INVALID_LABEL; + struct bgp_labels bgp_labels = {}; struct bgp_path_info *local_pi = NULL; struct bgp_path_info *tmp_pi = NULL; @@ -1630,9 +1630,14 @@ static int update_evpn_type5_route_entry(struct bgp *bgp_evpn, /* Type-5 routes advertise the L3-VNI */ bgp_path_info_extra_get(pi); - vni2label(bgp_vrf->l3vni, &label); - memcpy(&pi->extra->label, &label, sizeof(label)); - pi->extra->num_labels = 1; + vni2label(bgp_vrf->l3vni, &bgp_labels.label[0]); + bgp_labels.num_labels = 1; + if (!bgp_path_info_labels_same(pi, &bgp_labels.label[0], + bgp_labels.num_labels)) { + bgp_labels_unintern(&pi->extra->labels); + pi->extra->labels = bgp_labels_intern(&bgp_labels); + } + /* add the route entry to route node*/ bgp_path_info_add(dest, pi); @@ -1930,15 +1935,13 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, struct bgp_path_info *local_pi; struct attr *attr_new; struct attr local_attr; - mpls_label_t label[BGP_MAX_LABELS]; - uint8_t num_labels = 1; + struct bgp_labels bgp_labels = {}; int route_change = 1; uint8_t sticky = 0; const struct prefix_evpn *evp; *pi = NULL; evp = (const struct prefix_evpn *)bgp_dest_get_prefix(dest); - memset(&label, 0, sizeof(label)); /* See if this is an update of an existing route, or a new add. */ local_pi = bgp_evpn_route_get_local_path(bgp, dest); @@ -1980,7 +1983,8 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, bgp_path_info_extra_get(tmp_pi); /* The VNI goes into the 'label' field of the route */ - vni2label(vpn->vni, &label[0]); + vni2label(vpn->vni, &bgp_labels.label[0]); + bgp_labels.num_labels = 1; /* Type-2 routes may carry a second VNI - the L3-VNI. * Only attach second label if we are advertising two labels for @@ -1992,13 +1996,16 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, l3vni = bgpevpn_get_l3vni(vpn); if (l3vni) { - vni2label(l3vni, &label[1]); - num_labels++; + vni2label(l3vni, &bgp_labels.label[1]); + bgp_labels.num_labels++; } } - memcpy(&tmp_pi->extra->label, label, sizeof(label)); - tmp_pi->extra->num_labels = num_labels; + if (!bgp_path_info_labels_same(tmp_pi, &bgp_labels.label[0], + bgp_labels.num_labels)) { + bgp_labels_unintern(&tmp_pi->extra->labels); + tmp_pi->extra->labels = bgp_labels_intern(&bgp_labels); + } if (evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE) { if (mac) @@ -2022,7 +2029,8 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, * The attributes have changed, type-2 routes needs to * be advertised with right labels. */ - vni2label(vpn->vni, &label[0]); + vni2label(vpn->vni, &bgp_labels.label[0]); + bgp_labels.num_labels = 1; if (evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE && CHECK_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS)) { @@ -2030,12 +2038,17 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, l3vni = bgpevpn_get_l3vni(vpn); if (l3vni) { - vni2label(l3vni, &label[1]); - num_labels++; + vni2label(l3vni, &bgp_labels.label[1]); + bgp_labels.num_labels++; } } - memcpy(&tmp_pi->extra->label, label, sizeof(label)); - tmp_pi->extra->num_labels = num_labels; + if (!bgp_path_info_labels_same(tmp_pi, + &bgp_labels.label[0], + bgp_labels.num_labels)) { + bgp_labels_unintern(&tmp_pi->extra->labels); + tmp_pi->extra->labels = + bgp_labels_intern(&bgp_labels); + } if (evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE) { if (mac) @@ -2983,12 +2996,11 @@ bgp_create_evpn_bgp_path_info(struct bgp_path_info *parent_pi, sizeof(struct bgp_path_info_extra_vrfleak)); pi->extra->vrfleak->parent = bgp_path_info_lock(parent_pi); bgp_dest_lock_node((struct bgp_dest *)parent_pi->net); - if (parent_pi->extra) { - memcpy(&pi->extra->label, &parent_pi->extra->label, - sizeof(pi->extra->label)); - pi->extra->num_labels = bgp_path_info_num_labels(parent_pi); + if (parent_pi->extra) pi->extra->igpmetric = parent_pi->extra->igpmetric; - } + + if (bgp_path_info_num_labels(parent_pi)) + pi->extra->labels = bgp_labels_intern(parent_pi->extra->labels); bgp_path_info_add(dest, pi); @@ -7756,8 +7768,10 @@ vni_t bgp_evpn_path_info_get_l3vni(const struct bgp_path_info *pi) if (!pi->extra) return 0; - return label2vni(bgp_evpn_path_info_labels_get_l3vni( - pi->extra->label, pi->extra->num_labels)); + return label2vni( + bgp_evpn_path_info_labels_get_l3vni(pi->extra->labels->label, + pi->extra->labels + ->num_labels)); } /* diff --git a/bgpd/bgp_evpn_mh.c b/bgpd/bgp_evpn_mh.c index d63e01156..d557c0a8d 100644 --- a/bgpd/bgp_evpn_mh.c +++ b/bgpd/bgp_evpn_mh.c @@ -358,6 +358,7 @@ int bgp_evpn_mh_route_update(struct bgp *bgp, struct bgp_evpn_es *es, struct bgp_path_info *tmp_pi = NULL; struct bgp_path_info *local_pi = NULL; /* local route entry if any */ struct bgp_path_info *remote_pi = NULL; /* remote route entry if any */ + struct bgp_labels bgp_labels = {}; struct attr *attr_new = NULL; struct prefix_evpn *evp; @@ -404,11 +405,16 @@ int bgp_evpn_mh_route_update(struct bgp *bgp, struct bgp_evpn_es *es, if (evp->prefix.route_type == BGP_EVPN_AD_ROUTE) { bgp_path_info_extra_get(tmp_pi); - tmp_pi->extra->num_labels = 1; + bgp_labels.num_labels = 1; if (vpn) - vni2label(vpn->vni, &tmp_pi->extra->label[0]); - else - tmp_pi->extra->label[0] = 0; + vni2label(vpn->vni, &bgp_labels.label[0]); + if (!bgp_path_info_labels_same(tmp_pi, + &bgp_labels.label[0], + bgp_labels.num_labels)) { + bgp_labels_unintern(&tmp_pi->extra->labels); + tmp_pi->extra->labels = + bgp_labels_intern(&bgp_labels); + } } /* add the newly created path to the route-node */ diff --git a/bgpd/bgp_label.c b/bgpd/bgp_label.c index f967638de..839437e12 100644 --- a/bgpd/bgp_label.c +++ b/bgpd/bgp_label.c @@ -208,8 +208,9 @@ mpls_label_t bgp_adv_label(struct bgp_dest *dest, struct bgp_path_info *pi, if (!dest || !pi || !to) return MPLS_INVALID_LABEL; - remote_label = bgp_path_info_num_labels(pi) ? pi->extra->label[0] - : MPLS_INVALID_LABEL; + remote_label = bgp_path_info_num_labels(pi) + ? pi->extra->labels->label[0] + : MPLS_INVALID_LABEL; from = pi->peer; reflect = ((from->sort == BGP_PEER_IBGP) && (to->sort == BGP_PEER_IBGP)); diff --git a/bgpd/bgp_label.h b/bgpd/bgp_label.h index ecb8dd354..2ffd5b699 100644 --- a/bgpd/bgp_label.h +++ b/bgpd/bgp_label.h @@ -15,6 +15,11 @@ struct bgp_dest; struct bgp_path_info; struct peer; +/* Maximum number of labels we can process or send with a prefix. We + * really do only 1 for MPLS (BGP-LU) but we can do 2 for EVPN-VxLAN. + */ +#define BGP_MAX_LABELS 2 + /* MPLS label(s) - VNI(s) for EVPN-VxLAN */ struct bgp_labels { mpls_label_t label[BGP_MAX_LABELS]; diff --git a/bgpd/bgp_mac.c b/bgpd/bgp_mac.c index 1f70ad797..31e84d13c 100644 --- a/bgpd/bgp_mac.c +++ b/bgpd/bgp_mac.c @@ -14,6 +14,7 @@ #include "bgpd/bgpd.h" #include "bgpd/bgp_mac.h" #include "bgpd/bgp_memory.h" +#include "bgpd/bgp_label.h" #include "bgpd/bgp_route.h" #include "bgpd/bgp_packet.h" #include "bgpd/bgp_rd.h" @@ -170,7 +171,8 @@ static void bgp_process_mac_rescan_table(struct bgp *bgp, struct peer *peer, continue; num_labels = bgp_path_info_num_labels(pi); - label_pnt = num_labels ? &pi->extra->label[0] : NULL; + label_pnt = num_labels ? &pi->extra->labels->label[0] + : NULL; prd.family = AF_UNSPEC; prd.prefixlen = 64; diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index cecc91ac7..90881621b 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -964,35 +964,6 @@ void transpose_sid(struct in6_addr *sid, uint32_t label, uint8_t offset, } } -/* - * make encoded route labels match specified encoded label set - */ -static void setlabels(struct bgp_path_info *bpi, - mpls_label_t *label, /* array of labels */ - uint8_t num_labels) -{ - if (num_labels) - assert(label); - assert(num_labels <= BGP_MAX_LABELS); - - if (!num_labels) { - if (bpi->extra) - bpi->extra->num_labels = 0; - return; - } - - struct bgp_path_info_extra *extra = bgp_path_info_extra_get(bpi); - uint8_t i; - - for (i = 0; i < num_labels; ++i) { - extra->label[i] = label[i]; - if (!bgp_is_valid_label(&label[i])) { - bgp_set_valid_label(&extra->label[i]); - } - } - extra->num_labels = num_labels; -} - static bool leak_update_nexthop_valid(struct bgp *to_bgp, struct bgp_dest *bn, struct attr *new_attr, afi_t afi, safi_t safi, @@ -1079,6 +1050,9 @@ leak_update(struct bgp *to_bgp, struct bgp_dest *bn, struct bgp_path_info *new; struct bgp_path_info_extra *extra; struct bgp_path_info *parent = source_bpi; + struct bgp_labels bgp_labels = {}; + bool labelssame; + uint8_t i; if (debug) zlog_debug( @@ -1113,9 +1087,15 @@ leak_update(struct bgp *to_bgp, struct bgp_dest *bn, break; } + bgp_labels.num_labels = num_labels; + for (i = 0; i < num_labels; i++) { + bgp_labels.label[i] = label[i]; + bgp_set_valid_label(&bgp_labels.label[i]); + } + if (bpi) { - bool labelssame = bgp_path_info_labels_same(bpi, label, - num_labels); + labelssame = bgp_path_info_labels_same(bpi, bgp_labels.label, + bgp_labels.num_labels); if (CHECK_FLAG(source_bpi->flags, BGP_PATH_REMOVED) && CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) { @@ -1173,11 +1153,13 @@ leak_update(struct bgp *to_bgp, struct bgp_dest *bn, bpi->uptime = monotime(NULL); /* - * rewrite labels + * update labels */ - if (!labelssame) - setlabels(bpi, label, num_labels); - + if (!labelssame) { + bgp_path_info_extra_get(bpi); + bgp_labels_unintern(&bpi->extra->labels); + bpi->extra->labels = bgp_labels_intern(&bgp_labels); + } if (nexthop_self_flag) bgp_path_info_set_flag(bn, bpi, BGP_PATH_ANNC_NH_SELF); @@ -1235,8 +1217,8 @@ leak_update(struct bgp *to_bgp, struct bgp_dest *bn, if (CHECK_FLAG(source_bpi->flags, BGP_PATH_ACCEPT_OWN)) bgp_path_info_set_flag(bn, new, BGP_PATH_ACCEPT_OWN); - if (num_labels) - setlabels(new, label, num_labels); + if (bgp_labels.num_labels) + new->extra->labels = bgp_labels_intern(&bgp_labels); new->extra->vrfleak->parent = bgp_path_info_lock(parent); bgp_dest_lock_node( @@ -2337,7 +2319,7 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp, /* to */ num_labels = origin_local ? 0 : bgp_path_info_num_labels(path_vpn); - label_pnt = num_labels ? path_vpn->extra->label : NULL; + label_pnt = num_labels ? path_vpn->extra->labels->label : NULL; } if (debug) @@ -4221,7 +4203,7 @@ void bgp_mplsvpn_nh_label_bind_register_local_label(struct bgp *bgp, mpls_label_t label; label = bgp_path_info_num_labels(pi) - ? decode_label(&pi->extra->label[0]) + ? decode_label(&pi->extra->labels->label[0]) : MPLS_INVALID_LABEL; tree = &bgp->mplsvpn_nh_label_bind; diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 1de3707d7..919c219c6 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -305,6 +305,9 @@ void bgp_path_info_extra_free(struct bgp_path_info_extra **extra) XFREE(MTYPE_BGP_ROUTE_EXTRA_VNC, e->vnc); #endif + if (e->labels) + bgp_labels_unintern(&e->labels); + XFREE(MTYPE_BGP_ROUTE_EXTRA, *extra); } @@ -327,7 +330,7 @@ bool bgp_path_info_has_valid_label(const struct bgp_path_info *path) if (!bgp_path_info_num_labels(path)) return false; - return bgp_is_valid_label(&path->extra->label[0]); + return bgp_is_valid_label(&path->extra->labels->label[0]); } bool bgp_path_info_labels_same(const struct bgp_path_info *bpi, @@ -337,7 +340,7 @@ bool bgp_path_info_labels_same(const struct bgp_path_info *bpi, const mpls_label_t *bpi_label; bpi_num_labels = bgp_path_info_num_labels(bpi); - bpi_label = bpi_num_labels ? bpi->extra->label : NULL; + bpi_label = bpi_num_labels ? bpi->extra->labels->label : NULL; return bgp_labels_same(bpi_label, bpi_num_labels, (const mpls_label_t *)label, n); @@ -351,7 +354,10 @@ uint8_t bgp_path_info_num_labels(const struct bgp_path_info *pi) if (!pi->extra) return 0; - return pi->extra->num_labels; + if (!pi->extra->labels) + return 0; + + return pi->extra->labels->num_labels; } /* Free bgp route information. */ @@ -1871,6 +1877,7 @@ static int bgp_input_modifier(struct peer *peer, const struct prefix *p, struct bgp_filter *filter; struct bgp_path_info rmap_path = { 0 }; struct bgp_path_info_extra extra = { 0 }; + struct bgp_labels bgp_labels = {}; route_map_result_t ret; struct route_map *rmap = NULL; @@ -1902,11 +1909,12 @@ static int bgp_input_modifier(struct peer *peer, const struct prefix *p, rmap_path.attr = attr; rmap_path.extra = &extra; rmap_path.net = dest; + extra.labels = &bgp_labels; - extra.num_labels = num_labels; + bgp_labels.num_labels = num_labels; if (label && num_labels && num_labels <= BGP_MAX_LABELS) - memcpy(extra.label, label, - num_labels * sizeof(mpls_label_t)); + memcpy(bgp_labels.label, label, + num_labels * sizeof(mpls_label_t)); SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IN); @@ -2242,7 +2250,7 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, * significant and globaly useless. */ if (safi == SAFI_MPLS_VPN && bgp_path_info_num_labels(pi) && - pi->extra->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK) + pi->extra->labels->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK) return false; /* If it's labeled safi, make sure the route has a valid label. */ @@ -4539,7 +4547,6 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, struct attr *attr_new; struct bgp_path_info *pi; struct bgp_path_info *new = NULL; - struct bgp_path_info_extra *extra; const char *reason; char pfx_buf[BGP_PRD_PATH_STRLEN]; int connected = 0; @@ -4549,6 +4556,7 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, bool force_evpn_import = false; safi_t orig_safi = safi; int allowas_in = 0; + struct bgp_labels bgp_labels = {}; if (frrtrace_enabled(frr_bgp, process_update)) { char pfxprint[PREFIX2STR_BUFFER]; @@ -5056,14 +5064,18 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, /* Update MPLS label */ if (has_valid_label) { - extra = bgp_path_info_extra_get(pi); - if (!bgp_path_info_labels_same(pi, label, num_labels)) { - memcpy(&extra->label, label, - num_labels * sizeof(mpls_label_t)); - extra->num_labels = num_labels; - } + bgp_path_info_extra_get(pi); + bgp_labels.label[0] = *label; + bgp_labels.num_labels = num_labels; if (!(afi == AFI_L2VPN && safi == SAFI_EVPN)) - bgp_set_valid_label(&extra->label[0]); + bgp_set_valid_label(&bgp_labels.label[0]); + + if (!bgp_path_info_labels_same(pi, &bgp_labels.label[0], + bgp_labels.num_labels)) { + bgp_labels_unintern(&pi->extra->labels); + pi->extra->labels = + bgp_labels_intern(&bgp_labels); + } } #ifdef ENABLE_BGP_VNC @@ -5255,11 +5267,13 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, /* Update MPLS label */ if (has_valid_label) { - extra = bgp_path_info_extra_get(new); - memcpy(&extra->label, label, num_labels * sizeof(mpls_label_t)); - extra->num_labels = num_labels; + bgp_path_info_extra_get(new); + bgp_labels.label[0] = *label; + bgp_labels.num_labels = num_labels; if (!(afi == AFI_L2VPN && safi == SAFI_EVPN)) - bgp_set_valid_label(&extra->label[0]); + bgp_set_valid_label(&bgp_labels.label[0]); + + new->extra->labels = bgp_labels_intern(&bgp_labels); } /* Nexthop reachability check. */ @@ -5677,7 +5691,7 @@ static void bgp_soft_reconfig_table_update(struct peer *peer, break; num_labels = bgp_path_info_num_labels(pi); - label_pnt = num_labels ? &pi->extra->label[0] : NULL; + label_pnt = num_labels ? &pi->extra->labels->label[0] : NULL; if (pi) memcpy(&evpn, bgp_attr_get_evpn_overlay(pi->attr), sizeof(evpn)); @@ -6693,6 +6707,7 @@ void bgp_static_update(struct bgp *bgp, const struct prefix *p, #endif uint8_t num_labels = 0; struct bgp *bgp_nexthop = bgp; + struct bgp_labels labels = {}; assert(bgp_static); @@ -6844,7 +6859,7 @@ void bgp_static_update(struct bgp *bgp, const struct prefix *p, } else { if (bgp_path_info_num_labels(pi)) label = decode_label( - &pi->extra->label[0]); + &pi->extra->labels->label[0]); } #endif if (pi->extra && pi->extra->vrfleak->bgp_orig) @@ -6893,8 +6908,9 @@ void bgp_static_update(struct bgp *bgp, const struct prefix *p, SET_FLAG(new->flags, BGP_PATH_VALID); bgp_path_info_extra_get(new); if (num_labels) { - new->extra->label[0] = bgp_static->label; - new->extra->num_labels = num_labels; + labels.num_labels = num_labels; + labels.label[0] = bgp_static->label; + new->extra->labels = bgp_labels_intern(&labels); } #ifdef ENABLE_BGP_VNC label = decode_label(&bgp_static->label); @@ -10081,7 +10097,7 @@ void route_vty_out_tag(struct vty *vty, const struct prefix *p, } if (bgp_path_info_has_valid_label(path)) { - label = decode_label(&path->extra->label[0]); + label = decode_label(&path->extra->labels->label[0]); if (json) { json_object_int_add(json_out, "notag", label); json_object_array_add(json, json_out); @@ -10514,8 +10530,9 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, } if (bgp_path_info_num_labels(path)) { - bgp_evpn_label2str(path->extra->label, path->extra->num_labels, - vni_buf, sizeof(vni_buf)); + bgp_evpn_label2str(path->extra->labels->label, + path->extra->labels->num_labels, vni_buf, + sizeof(vni_buf)); } if (safi == SAFI_EVPN) { @@ -11281,8 +11298,8 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, /* Remote Label */ if (bgp_path_info_has_valid_label(path) && (safi != SAFI_EVPN && !is_route_parent_evpn(path))) { - mpls_lse_decode(path->extra->label[0], &label, &ttl, &exp, - &bos); + mpls_lse_decode(path->extra->labels->label[0], &label, &ttl, + &exp, &bos); if (json_paths) json_object_int_add(json_path, "remoteLabel", label); diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index a1c00dcb1..89449ac5b 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -69,11 +69,6 @@ enum bgp_show_adj_route_type { #define BGP_SHOW_HEADER " Network Next Hop Metric LocPrf Weight Path\n" #define BGP_SHOW_HEADER_WIDE " Network Next Hop Metric LocPrf Weight Path\n" -/* Maximum number of labels we can process or send with a prefix. We - * really do only 1 for MPLS (BGP-LU) but we can do 2 for EVPN-VxLAN. - */ -#define BGP_MAX_LABELS 2 - /* Maximum number of sids we can process or send with a prefix. */ #define BGP_MAX_SIDS 6 @@ -237,8 +232,7 @@ struct bgp_path_info_extra { uint32_t igpmetric; /* MPLS label(s) - VNI(s) for EVPN-VxLAN */ - mpls_label_t label[BGP_MAX_LABELS]; - uint8_t num_labels; + struct bgp_labels *labels; /* timestamp of the rib installation */ time_t bgp_rib_uptime; diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index 8dbe705aa..9b0ca72e4 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -1084,7 +1084,7 @@ route_match_vni(void *rule, const struct prefix *prefix, void *object) for (label_cnt = 0; label_cnt < BGP_MAX_LABELS && label_cnt < bgp_path_info_num_labels(path); label_cnt++) { - if (vni == label2vni(&path->extra->label[label_cnt])) + if (vni == label2vni(&path->extra->labels->label[label_cnt])) return RMAP_MATCH; } diff --git a/bgpd/bgp_rpki.c b/bgpd/bgp_rpki.c index ccac75454..a487f49e6 100644 --- a/bgpd/bgp_rpki.c +++ b/bgpd/bgp_rpki.c @@ -29,6 +29,7 @@ #include "bgpd/bgpd.h" #include "bgpd/bgp_table.h" #include "bgp_advertise.h" +#include "bgp_label.h" #include "bgpd/bgp_debug.h" #include "bgpd/bgp_attr.h" #include "bgpd/bgp_aspath.h" @@ -664,7 +665,7 @@ static void revalidate_bgp_node(struct bgp_dest *bgp_dest, afi_t afi, bgp_dest_get_bgp_path_info(bgp_dest); num_labels = bgp_path_info_num_labels(path); - label = num_labels ? path->extra->label : NULL; + label = num_labels ? path->extra->labels->label : NULL; (void)bgp_update(ain->peer, bgp_dest_get_prefix(bgp_dest), ain->addpath_rx_id, ain->attr, afi, safi, diff --git a/bgpd/bgp_updgrp_packet.c b/bgpd/bgp_updgrp_packet.c index be3e27afc..6e30d4f84 100644 --- a/bgpd/bgp_updgrp_packet.c +++ b/bgpd/bgp_updgrp_packet.c @@ -816,8 +816,10 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp) num_labels = 1; } else { num_labels = bgp_path_info_num_labels(path); - label_pnt = num_labels ? &path->extra->label[0] - : NULL; + label_pnt = + num_labels + ? &path->extra->labels->label[0] + : NULL; } if (stream_empty(snlri)) diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 3558ebfd2..8fab0d1c0 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1343,7 +1343,8 @@ static void bgp_zebra_announce_parse_nexthop( zlog_debug("%s: p=%pFX, bgp_is_valid_label: %d", __func__, p, bgp_is_valid_label( - &mpinfo->extra->label[0])); + &mpinfo->extra->labels + ->label[0])); } else { zlog_debug("%s: p=%pFX, no label", __func__, p); } @@ -1412,7 +1413,7 @@ static void bgp_zebra_announce_parse_nexthop( *allow_recursion = true; num_labels = bgp_path_info_num_labels(mpinfo); - labels = num_labels ? mpinfo->extra->label : NULL; + labels = num_labels ? mpinfo->extra->labels->label : NULL; if (num_labels && (is_evpn || bgp_is_valid_label(&labels[0]))) { enum lsp_types_t nh_label_type = ZEBRA_LSP_NONE; diff --git a/bgpd/rfapi/rfapi.c b/bgpd/rfapi/rfapi.c index bea9bfb61..23e3eb482 100644 --- a/bgpd/rfapi/rfapi.c +++ b/bgpd/rfapi/rfapi.c @@ -549,6 +549,7 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */ int flags) { afi_t afi; /* of the VN address */ + struct bgp_labels bgp_labels = {}; struct bgp_path_info *new; struct bgp_path_info *bpi; struct bgp_dest *bn; @@ -1021,8 +1022,9 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */ sizeof(struct bgp_path_info_extra_vnc)); new->extra->vnc->vnc.export.rfapi_handle = (void *)rfd; - encode_label(label_val, &new->extra->label[0]); - new->extra->num_labels = 1; + encode_label(label_val, &bgp_labels.label[0]); + bgp_labels.num_labels = 1; + new->extra->labels = bgp_labels_intern(&bgp_labels); /* debug */ @@ -1045,7 +1047,6 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */ bgp, prd, table, p, new); bgp_dest_unlock_node(pdest); encode_label(label_val, &bn->local_label); - new->extra->num_labels = 1; } bgp_dest_unlock_node(bn); diff --git a/bgpd/rfapi/rfapi_import.c b/bgpd/rfapi/rfapi_import.c index 7e19fb8c9..2afcb2f45 100644 --- a/bgpd/rfapi/rfapi_import.c +++ b/bgpd/rfapi/rfapi_import.c @@ -442,6 +442,7 @@ static struct bgp_path_info *rfapiBgpInfoCreate(struct attr *attr, uint32_t *label) { struct bgp_path_info *new; + struct bgp_labels bgp_labels = {}; new = info_make(type, sub_type, 0, peer, attr, NULL); @@ -455,10 +456,10 @@ static struct bgp_path_info *rfapiBgpInfoCreate(struct attr *attr, new->extra->vnc->vnc.import.create_time = monotime(NULL); } if (label && *label != MPLS_INVALID_LABEL) { - encode_label(*label, &new->extra->label[0]); - new->extra->num_labels = 1; - } else - new->extra->num_labels = 0; + encode_label(*label, &bgp_labels.label[0]); + bgp_labels.num_labels = 1; + new->extra->labels = bgp_labels_intern(&bgp_labels); + } peer_lock(peer); @@ -1272,7 +1273,7 @@ rfapiRouteInfo2NextHopEntry(struct rfapi_ip_prefix *rprefix, /* label comes from MP_REACH_NLRI label */ vo->v.l2addr.label = bgp_path_info_num_labels(bpi) - ? decode_label(&bpi->extra->label[0]) + ? decode_label(&bpi->extra->labels->label[0]) : MPLS_INVALID_LABEL; new->vn_options = vo; @@ -4168,7 +4169,8 @@ static void rfapiBgpTableFilteredImport(struct bgp *bgp, if (bgp_path_info_num_labels(bpi)) label = decode_label( - &bpi->extra->label[0]); + &bpi->extra->labels + ->label[0]); (*rfapiBgpInfoFilteredImportFunction( safi))( it, /* which import table */ diff --git a/bgpd/rfapi/rfapi_rib.c b/bgpd/rfapi/rfapi_rib.c index 5c6357672..a0bdf4961 100644 --- a/bgpd/rfapi/rfapi_rib.c +++ b/bgpd/rfapi/rfapi_rib.c @@ -693,7 +693,7 @@ static void rfapiRibBi2Ri(struct bgp_path_info *bpi, struct rfapi_info *ri, /* label comes from MP_REACH_NLRI label */ vo->v.l2addr.label = bgp_path_info_num_labels(bpi) - ? decode_label(&bpi->extra->label[0]) + ? decode_label(&bpi->extra->labels->label[0]) : MPLS_INVALID_LABEL; rfapi_vn_options_free( diff --git a/bgpd/rfapi/rfapi_vty.c b/bgpd/rfapi/rfapi_vty.c index ddf95b63f..9bfb6c4b4 100644 --- a/bgpd/rfapi/rfapi_vty.c +++ b/bgpd/rfapi/rfapi_vty.c @@ -414,11 +414,11 @@ void rfapi_vty_out_vncinfo(struct vty *vty, const struct prefix *p, } if (bgp_path_info_num_labels(bpi)) { - if (bpi->extra->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK) + if (bpi->extra->labels->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK) vty_out(vty, " label=VRF2VRF"); else vty_out(vty, " label=%u", - decode_label(&bpi->extra->label[0])); + decode_label(&bpi->extra->labels->label[0])); } if (bpi->attr->srv6_l3vpn || bpi->attr->srv6_vpn) { @@ -1053,7 +1053,7 @@ static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream, inet_ntop(pfx_vn.family, &pfx_vn.u.prefix, buf_ntop, sizeof(buf_ntop))); if (bgp_path_info_num_labels(bpi)) { - uint32_t l = decode_label(&bpi->extra->label[0]); + uint32_t l = decode_label(&bpi->extra->labels->label[0]); snprintf(buf_vn, sizeof(buf_vn), "Label: %d", l); } else /* should never happen */ { @@ -1162,7 +1162,7 @@ static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream, } } if (tun_type != BGP_ENCAP_TYPE_MPLS && bgp_path_info_num_labels(bpi)) { - uint32_t l = decode_label(&bpi->extra->label[0]); + uint32_t l = decode_label(&bpi->extra->labels->label[0]); if (!MPLS_LABEL_IS_NULL(l)) { fp(out, " Label: %d", l); diff --git a/bgpd/rfapi/vnc_import_bgp.c b/bgpd/rfapi/vnc_import_bgp.c index 255e87b09..2bb7c1b16 100644 --- a/bgpd/rfapi/vnc_import_bgp.c +++ b/bgpd/rfapi/vnc_import_bgp.c @@ -471,7 +471,7 @@ static void vnc_import_bgp_add_route_mode_resolve_nve_one_bi( ecommunity_merge(new_ecom, bgp_attr_get_ecommunity(bpi->attr)); if (bgp_path_info_num_labels(bpi)) - label = decode_label(&bpi->extra->label[0]); + label = decode_label(&bpi->extra->labels->label[0]); else label = MPLS_INVALID_LABEL; @@ -1706,7 +1706,8 @@ static void vnc_import_bgp_exterior_add_route_it( if (bgp_path_info_num_labels(bpi_interior)) label = decode_label( - &bpi_interior->extra->label[0]); + &bpi_interior->extra->labels + ->label[0]); else label = MPLS_INVALID_LABEL; @@ -1879,7 +1880,8 @@ void vnc_import_bgp_exterior_del_route( if (bgp_path_info_num_labels(bpi_interior)) label = decode_label( - &bpi_interior->extra->label[0]); + &bpi_interior->extra->labels + ->label[0]); else label = MPLS_INVALID_LABEL; @@ -2030,7 +2032,7 @@ void vnc_import_bgp_exterior_add_route_interior( if (bgp_path_info_num_labels(bpi_interior)) label = decode_label( - &bpi_interior->extra->label[0]); + &bpi_interior->extra->labels->label[0]); else label = MPLS_INVALID_LABEL; @@ -2147,7 +2149,8 @@ void vnc_import_bgp_exterior_add_route_interior( if (bgp_path_info_num_labels(bpi)) label = decode_label( - &bpi->extra->label[0]); + &bpi->extra->labels + ->label[0]); else label = MPLS_INVALID_LABEL; @@ -2173,7 +2176,8 @@ void vnc_import_bgp_exterior_add_route_interior( if (bgp_path_info_num_labels(bpi_interior)) label = decode_label( - &bpi_interior->extra->label[0]); + &bpi_interior->extra->labels + ->label[0]); else label = MPLS_INVALID_LABEL; @@ -2295,7 +2299,7 @@ void vnc_import_bgp_exterior_add_route_interior( if (bgp_path_info_num_labels(bpi_interior)) label = decode_label( - &bpi_interior->extra->label[0]); + &bpi_interior->extra->labels->label[0]); else label = MPLS_INVALID_LABEL; @@ -2406,7 +2410,8 @@ void vnc_import_bgp_exterior_del_route_interior( prd = NULL; if (bgp_path_info_num_labels(bpi_interior)) - label = decode_label(&bpi_interior->extra->label[0]); + label = decode_label( + &bpi_interior->extra->labels->label[0]); else label = MPLS_INVALID_LABEL; @@ -2488,7 +2493,7 @@ void vnc_import_bgp_exterior_del_route_interior( if (bgp_path_info_num_labels(bpi)) label = decode_label( - &bpi->extra->label[0]); + &bpi->extra->labels->label[0]); else label = MPLS_INVALID_LABEL; |