diff options
| -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 bf08e30509..43f8006e2d 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 e19d5efe34..5ce5b19b18 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 d63e011560..d557c0a8db 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 f967638de1..839437e120 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 ecb8dd3543..2ffd5b699d 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 1f70ad7970..31e84d13c4 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 cecc91ac70..90881621b3 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 1de3707d7e..919c219c6c 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 a1c00dcb16..89449ac5b9 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 8dbe705aa5..9b0ca72e4c 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 ccac754549..a487f49e64 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 be3e27afcb..6e30d4f846 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 3558ebfd2d..8fab0d1c05 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 bea9bfb618..23e3eb4823 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 7e19fb8c97..2afcb2f45c 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 5c63576720..a0bdf4961f 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 ddf95b63fc..9bfb6c4b45 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 255e87b096..2bb7c1b161 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;  | 
