summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLouis Scalbert <louis.scalbert@6wind.com>2024-02-26 18:23:11 +0100
committerLouis Scalbert <louis.scalbert@6wind.com>2024-06-05 13:11:29 +0200
commitca32945b1fd694d10307d2885df62251f46bf581 (patch)
tree3d8c58c185062f8fe8c771bb55e3dfddf48c3572
parentbgpd: add bgp_labels hash (diff)
downloadfrr-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.c26
-rw-r--r--bgpd/bgp_evpn.c62
-rw-r--r--bgpd/bgp_evpn_mh.c14
-rw-r--r--bgpd/bgp_label.c5
-rw-r--r--bgpd/bgp_label.h5
-rw-r--r--bgpd/bgp_mac.c4
-rw-r--r--bgpd/bgp_mplsvpn.c60
-rw-r--r--bgpd/bgp_route.c73
-rw-r--r--bgpd/bgp_route.h8
-rw-r--r--bgpd/bgp_routemap.c2
-rw-r--r--bgpd/bgp_rpki.c3
-rw-r--r--bgpd/bgp_updgrp_packet.c6
-rw-r--r--bgpd/bgp_zebra.c5
-rw-r--r--bgpd/rfapi/rfapi.c7
-rw-r--r--bgpd/rfapi/rfapi_import.c14
-rw-r--r--bgpd/rfapi/rfapi_rib.c2
-rw-r--r--bgpd/rfapi/rfapi_vty.c8
-rw-r--r--bgpd/rfapi/vnc_import_bgp.c23
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;