diff options
| -rw-r--r-- | bgpd/bgp_evpn.c | 32 | ||||
| -rw-r--r-- | bgpd/bgp_evpn.h | 19 | ||||
| -rw-r--r-- | bgpd/bgp_evpn_mh.c | 45 | ||||
| -rw-r--r-- | bgpd/bgp_evpn_private.h | 16 | ||||
| -rw-r--r-- | bgpd/bgp_flowspec_vty.c | 12 | ||||
| -rw-r--r-- | bgpd/bgp_memory.c | 3 | ||||
| -rw-r--r-- | bgpd/bgp_memory.h | 3 | ||||
| -rw-r--r-- | bgpd/bgp_mpath.c | 9 | ||||
| -rw-r--r-- | bgpd/bgp_mplsvpn.c | 161 | ||||
| -rw-r--r-- | bgpd/bgp_mplsvpn.h | 7 | ||||
| -rw-r--r-- | bgpd/bgp_nht.c | 5 | ||||
| -rw-r--r-- | bgpd/bgp_pbr.c | 16 | ||||
| -rw-r--r-- | bgpd/bgp_route.c | 163 | ||||
| -rw-r--r-- | bgpd/bgp_route.h | 104 | ||||
| -rw-r--r-- | bgpd/bgp_routemap.c | 9 | ||||
| -rw-r--r-- | bgpd/bgp_vty.c | 23 | ||||
| -rw-r--r-- | bgpd/bgp_zebra.c | 55 | ||||
| -rw-r--r-- | bgpd/bgp_zebra.h | 7 | ||||
| -rw-r--r-- | bgpd/rfapi/rfapi_vty.c | 21 | 
19 files changed, 330 insertions, 380 deletions
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index a33f59cf5b..35f2438929 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -1924,7 +1924,8 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,  		/* Mark route as self type-2 route */  		if (flags && CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_SVI_IP)) -			tmp_pi->extra->af_flags = BGP_EVPN_MACIP_TYPE_SVI_IP; +			tmp_pi->extra->evpn->af_flags = +				BGP_EVPN_MACIP_TYPE_SVI_IP;  		bgp_path_info_add(dest, tmp_pi);  	} else {  		tmp_pi = local_pi; @@ -2390,7 +2391,8 @@ void bgp_evpn_update_type2_route_entry(struct bgp *bgp, struct bgpevpn *vpn,  			attr.router_flag = 1;  	}  	memcpy(&attr.esi, &local_pi->attr->esi, sizeof(esi_t)); -	bgp_evpn_get_rmac_nexthop(vpn, &evp, &attr, local_pi->extra->af_flags); +	bgp_evpn_get_rmac_nexthop(vpn, &evp, &attr, +				  local_pi->extra->evpn->af_flags);  	vni2label(vpn->vni, &(attr.label));  	/* Add L3 VNI RTs and RMAC for non IPv6 link-local if  	 * using L3 VNI for type-2 routes also. @@ -2829,7 +2831,11 @@ bgp_create_evpn_bgp_path_info(struct bgp_path_info *parent_pi,  		       attr_new, dest);  	SET_FLAG(pi->flags, BGP_PATH_VALID);  	bgp_path_info_extra_get(pi); -	pi->extra->parent = bgp_path_info_lock(parent_pi); +	if (!pi->extra->vrfleak) +		pi->extra->vrfleak = +			XCALLOC(MTYPE_BGP_ROUTE_EXTRA_VRFLEAK, +				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, @@ -2935,8 +2941,9 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,  	/* Check if route entry is already present. */  	for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) -		if (pi->extra -		    && (struct bgp_path_info *)pi->extra->parent == parent_pi) +		if (pi->extra && pi->extra->vrfleak && +		    (struct bgp_path_info *)pi->extra->vrfleak->parent == +			    parent_pi)  			break;  	if (!pi) { @@ -3031,8 +3038,9 @@ static int install_evpn_route_entry_in_vni_common(  	/* Check if route entry is already present. */  	for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) -		if (pi->extra -		    && (struct bgp_path_info *)pi->extra->parent == parent_pi) +		if (pi->extra && pi->extra->vrfleak && +		    (struct bgp_path_info *)pi->extra->vrfleak->parent == +			    parent_pi)  			break;  	if (!pi) { @@ -3127,8 +3135,9 @@ static int uninstall_evpn_route_entry_in_vni_common(  	/* Find matching route entry. */  	for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) -		if (pi->extra && -		    (struct bgp_path_info *)pi->extra->parent == parent_pi) +		if (pi->extra && pi->extra->vrfleak && +		    (struct bgp_path_info *)pi->extra->vrfleak->parent == +			    parent_pi)  			break;  	if (!pi) @@ -3305,8 +3314,9 @@ static int uninstall_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,  	/* Find matching route entry. */  	for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) -		if (pi->extra -		    && (struct bgp_path_info *)pi->extra->parent == parent_pi) +		if (pi->extra && pi->extra->vrfleak && +		    (struct bgp_path_info *)pi->extra->vrfleak->parent == +			    parent_pi)  			break;  	if (!pi) { diff --git a/bgpd/bgp_evpn.h b/bgpd/bgp_evpn.h index 076248c9f7..55474464e5 100644 --- a/bgpd/bgp_evpn.h +++ b/bgpd/bgp_evpn.h @@ -51,15 +51,15 @@ get_route_parent_evpn(struct bgp_path_info *ri)  	struct bgp_path_info *parent_ri;  	/* If not imported (or doesn't have a parent), bail. */ -	if (ri->sub_type != BGP_ROUTE_IMPORTED || -	    !ri->extra || -	    !ri->extra->parent) +	if (ri->sub_type != BGP_ROUTE_IMPORTED || !ri->extra || +	    !ri->extra->vrfleak || !ri->extra->vrfleak->parent)  		return NULL;  	/* Determine parent recursively */ -	for (parent_ri = ri->extra->parent; -	     parent_ri->extra && parent_ri->extra->parent; -	     parent_ri = parent_ri->extra->parent) +	for (parent_ri = ri->extra->vrfleak->parent; +	     parent_ri->extra && parent_ri->extra->vrfleak && +	     parent_ri->extra->vrfleak->parent; +	     parent_ri = parent_ri->extra->vrfleak->parent)  		;  	return parent_ri; @@ -103,12 +103,11 @@ static inline bool is_route_injectable_into_evpn(struct bgp_path_info *pi)  	struct bgp_table *table;  	struct bgp_dest *dest; -	if (pi->sub_type != BGP_ROUTE_IMPORTED || -	    !pi->extra || -	    !pi->extra->parent) +	if (pi->sub_type != BGP_ROUTE_IMPORTED || !pi->extra || +	    !pi->extra->vrfleak || !pi->extra->vrfleak->parent)  		return true; -	parent_pi = (struct bgp_path_info *)pi->extra->parent; +	parent_pi = (struct bgp_path_info *)pi->extra->vrfleak->parent;  	dest = parent_pi->net;  	if (!dest)  		return true; diff --git a/bgpd/bgp_evpn_mh.c b/bgpd/bgp_evpn_mh.c index efadda17b8..36bf752d48 100644 --- a/bgpd/bgp_evpn_mh.c +++ b/bgpd/bgp_evpn_mh.c @@ -185,8 +185,9 @@ static int bgp_evpn_es_route_install(struct bgp *bgp,  	/* Check if route entry is already present. */  	for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) -		if (pi->extra && -		    (struct bgp_path_info *)pi->extra->parent == parent_pi) +		if (pi->extra && pi->extra->vrfleak && +		    (struct bgp_path_info *)pi->extra->vrfleak->parent == +			    parent_pi)  			break;  	if (!pi) { @@ -198,7 +199,11 @@ static int bgp_evpn_es_route_install(struct bgp *bgp,  			       parent_pi->peer, attr_new, dest);  		SET_FLAG(pi->flags, BGP_PATH_VALID);  		bgp_path_info_extra_get(pi); -		pi->extra->parent = bgp_path_info_lock(parent_pi); +		if (!pi->extra->vrfleak) +			pi->extra->vrfleak = +				XCALLOC(MTYPE_BGP_ROUTE_EXTRA_VRFLEAK, +					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);  		bgp_path_info_add(dest, pi);  	} else { @@ -253,9 +258,9 @@ static int bgp_evpn_es_route_uninstall(struct bgp *bgp, struct bgp_evpn_es *es,  	/* Find matching route entry. */  	for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) -		if (pi->extra -				&& (struct bgp_path_info *)pi->extra->parent == -				parent_pi) +		if (pi->extra && pi->extra->vrfleak && +		    (struct bgp_path_info *)pi->extra->vrfleak->parent == +			    parent_pi)  			break;  	if (!pi) { @@ -1548,10 +1553,11 @@ bgp_evpn_path_es_info_new(struct bgp_path_info *pi, vni_t vni)  	e = bgp_path_info_extra_get(pi);  	/* If mh_info doesn't exist allocate it */ -	mh_info = e->mh_info; +	mh_info = e->evpn->mh_info;  	if (!mh_info) -		e->mh_info = mh_info = XCALLOC(MTYPE_BGP_EVPN_PATH_MH_INFO, -					       sizeof(struct bgp_path_mh_info)); +		e->evpn->mh_info = mh_info = +			XCALLOC(MTYPE_BGP_EVPN_PATH_MH_INFO, +				sizeof(struct bgp_path_mh_info));  	/* If es_info doesn't exist allocate it */  	es_info = mh_info->es_info; @@ -1604,8 +1610,8 @@ void bgp_evpn_path_es_link(struct bgp_path_info *pi, vni_t vni, esi_t *esi)  	struct bgp_evpn_es *es;  	struct bgp *bgp_evpn; -	es_info = (pi->extra && pi->extra->mh_info) -			  ? pi->extra->mh_info->es_info +	es_info = (pi->extra && pi->extra->evpn && pi->extra->evpn->mh_info) +			  ? pi->extra->evpn->mh_info->es_info  			  : NULL;  	/* if the esi is zero just unlink the path from the old es */  	if (!esi || !memcmp(esi, zero_esi, sizeof(*esi))) { @@ -3163,7 +3169,7 @@ bool bgp_evpn_path_es_use_nhg(struct bgp *bgp_vrf, struct bgp_path_info *pi,  	*nhg_p = 0;  	/* we don't support NHG for routes leaked from another VRF yet */ -	if (pi->extra && pi->extra->bgp_orig) +	if (pi->extra && pi->extra->vrfleak && pi->extra->vrfleak->bgp_orig)  		return false;  	parent_pi = get_route_parent_evpn(pi); @@ -4670,10 +4676,11 @@ bgp_evpn_path_nh_info_new(struct bgp_path_info *pi)  	e = bgp_path_info_extra_get(pi);  	/* If mh_info doesn't exist allocate it */ -	mh_info = e->mh_info; +	mh_info = e->evpn->mh_info;  	if (!mh_info) -		e->mh_info = mh_info = XCALLOC(MTYPE_BGP_EVPN_PATH_MH_INFO, -					       sizeof(struct bgp_path_mh_info)); +		e->evpn->mh_info = mh_info = +			XCALLOC(MTYPE_BGP_EVPN_PATH_MH_INFO, +				sizeof(struct bgp_path_mh_info));  	/* If nh_info doesn't exist allocate it */  	nh_info = mh_info->nh_info; @@ -4738,8 +4745,8 @@ static void bgp_evpn_path_nh_link(struct bgp *bgp_vrf, struct bgp_path_info *pi)  		return;  	} -	nh_info = (pi->extra && pi->extra->mh_info) -			  ? pi->extra->mh_info->nh_info +	nh_info = (pi->extra && pi->extra->evpn && pi->extra->evpn->mh_info) +			  ? pi->extra->evpn->mh_info->nh_info  			  : NULL;  	/* if NHG is not being used for this path we don't need to manage the @@ -4805,8 +4812,8 @@ void bgp_evpn_path_nh_del(struct bgp *bgp_vrf, struct bgp_path_info *pi)  {  	struct bgp_path_evpn_nh_info *nh_info; -	nh_info = (pi->extra && pi->extra->mh_info) -			  ? pi->extra->mh_info->nh_info +	nh_info = (pi->extra && pi->extra->evpn && pi->extra->evpn->mh_info) +			  ? pi->extra->evpn->mh_info->nh_info  			  : NULL;  	if (!nh_info) diff --git a/bgpd/bgp_evpn_private.h b/bgpd/bgp_evpn_private.h index 8cee048b69..f141ddd6ef 100644 --- a/bgpd/bgp_evpn_private.h +++ b/bgpd/bgp_evpn_private.h @@ -581,32 +581,32 @@ evpn_type2_prefix_vni_mac_copy(struct prefix_evpn *vni_p,  static inline struct ethaddr *  evpn_type2_path_info_get_mac(const struct bgp_path_info *local_pi)  { -	assert(local_pi->extra); -	return &local_pi->extra->vni_info.mac; +	assert(local_pi->extra && local_pi->extra->evpn); +	return &local_pi->extra->evpn->vni_info.mac;  }  /* Get IP of path_info prefix */  static inline struct ipaddr *  evpn_type2_path_info_get_ip(const struct bgp_path_info *local_pi)  { -	assert(local_pi->extra); -	return &local_pi->extra->vni_info.ip; +	assert(local_pi->extra && local_pi->extra->evpn); +	return &local_pi->extra->evpn->vni_info.ip;  }  /* Set MAC of path_info prefix */  static inline void evpn_type2_path_info_set_mac(struct bgp_path_info *local_pi,  						const struct ethaddr mac)  { -	assert(local_pi->extra); -	local_pi->extra->vni_info.mac = mac; +	assert(local_pi->extra && local_pi->extra->evpn); +	local_pi->extra->evpn->vni_info.mac = mac;  }  /* Set IP of path_info prefix */  static inline void evpn_type2_path_info_set_ip(struct bgp_path_info *local_pi,  					       const struct ipaddr ip)  { -	assert(local_pi->extra); -	local_pi->extra->vni_info.ip = ip; +	assert(local_pi->extra && local_pi->extra->evpn); +	local_pi->extra->evpn->vni_info.ip = ip;  }  /* Is the IP empty for the RT's dest? */ diff --git a/bgpd/bgp_flowspec_vty.c b/bgpd/bgp_flowspec_vty.c index 7df1423e59..a295ec5a14 100644 --- a/bgpd/bgp_flowspec_vty.c +++ b/bgpd/bgp_flowspec_vty.c @@ -355,7 +355,8 @@ void route_vty_out_flowspec(struct vty *vty, const struct prefix *p,  			bgp_path_info_extra_get(path);  		bool list_began = false; -		if (extra->bgp_fs_pbr && listcount(extra->bgp_fs_pbr)) { +		if (extra->flowspec && extra->flowspec->bgp_fs_pbr && +		    listcount(extra->flowspec->bgp_fs_pbr)) {  			struct listnode *node;  			struct bgp_pbr_match_entry *bpme;  			struct bgp_pbr_match *bpm; @@ -363,8 +364,8 @@ void route_vty_out_flowspec(struct vty *vty, const struct prefix *p,  			list_bpm = list_new();  			vty_out(vty, "\tinstalled in PBR"); -			for (ALL_LIST_ELEMENTS_RO(extra->bgp_fs_pbr, -						  node, bpme)) { +			for (ALL_LIST_ELEMENTS_RO(extra->flowspec->bgp_fs_pbr, node, +						  bpme)) {  				bpm = bpme->backpointer;  				if (listnode_lookup(list_bpm, bpm))  					continue; @@ -378,13 +379,14 @@ void route_vty_out_flowspec(struct vty *vty, const struct prefix *p,  			}  			list_delete(&list_bpm);  		} -		if (extra->bgp_fs_iprule && listcount(extra->bgp_fs_iprule)) { +		if (extra->flowspec && extra->flowspec->bgp_fs_iprule && +		    listcount(extra->flowspec->bgp_fs_iprule)) {  			struct listnode *node;  			struct bgp_pbr_rule *bpr;  			if (!list_began)  				vty_out(vty, "\tinstalled in PBR"); -			for (ALL_LIST_ELEMENTS_RO(extra->bgp_fs_iprule, +			for (ALL_LIST_ELEMENTS_RO(extra->flowspec->bgp_fs_iprule,  						  node, bpr)) {  				if (!bpr->action)  					continue; diff --git a/bgpd/bgp_memory.c b/bgpd/bgp_memory.c index d7b18de676..edaaef6021 100644 --- a/bgpd/bgp_memory.c +++ b/bgpd/bgp_memory.c @@ -37,6 +37,9 @@ DEFINE_MTYPE(BGPD, BGP_TABLE, "BGP table");  DEFINE_MTYPE(BGPD, BGP_NODE, "BGP node");  DEFINE_MTYPE(BGPD, BGP_ROUTE, "BGP route");  DEFINE_MTYPE(BGPD, BGP_ROUTE_EXTRA, "BGP ancillary route info"); +DEFINE_MTYPE(BGPD, BGP_ROUTE_EXTRA_EVPN, "BGP extra info for EVPN"); +DEFINE_MTYPE(BGPD, BGP_ROUTE_EXTRA_FS, "BGP extra info for flowspec"); +DEFINE_MTYPE(BGPD, BGP_ROUTE_EXTRA_VRFLEAK, "BGP extra info for vrf leaking");  DEFINE_MTYPE(BGPD, BGP_CONN, "BGP connected");  DEFINE_MTYPE(BGPD, BGP_STATIC, "BGP static");  DEFINE_MTYPE(BGPD, BGP_ADVERTISE_ATTR, "BGP adv attr"); diff --git a/bgpd/bgp_memory.h b/bgpd/bgp_memory.h index 7b00497714..1256eafd00 100644 --- a/bgpd/bgp_memory.h +++ b/bgpd/bgp_memory.h @@ -33,6 +33,9 @@ DECLARE_MTYPE(BGP_TABLE);  DECLARE_MTYPE(BGP_NODE);  DECLARE_MTYPE(BGP_ROUTE);  DECLARE_MTYPE(BGP_ROUTE_EXTRA); +DECLARE_MTYPE(BGP_ROUTE_EXTRA_EVPN); +DECLARE_MTYPE(BGP_ROUTE_EXTRA_FS); +DECLARE_MTYPE(BGP_ROUTE_EXTRA_VRFLEAK);  DECLARE_MTYPE(BGP_CONN);  DECLARE_MTYPE(BGP_STATIC);  DECLARE_MTYPE(BGP_ADVERTISE_ATTR); diff --git a/bgpd/bgp_mpath.c b/bgpd/bgp_mpath.c index e920d5753e..f2d1ee0bf3 100644 --- a/bgpd/bgp_mpath.c +++ b/bgpd/bgp_mpath.c @@ -173,10 +173,11 @@ int bgp_path_info_nexthop_cmp(struct bgp_path_info *bpi1,  	 * if they belong to same VRF  	 */  	if (!compare && bpi1->attr->nh_type != NEXTHOP_TYPE_BLACKHOLE) { -		if (bpi1->extra && bpi1->extra->bgp_orig && bpi2->extra -		    && bpi2->extra->bgp_orig) { -			if (bpi1->extra->bgp_orig->vrf_id -			    != bpi2->extra->bgp_orig->vrf_id) { +		if (bpi1->extra && bpi1->extra->vrfleak && +		    bpi1->extra->vrfleak->bgp_orig && bpi2->extra && +		    bpi2->extra->vrfleak && bpi2->extra->vrfleak->bgp_orig) { +			if (bpi1->extra->vrfleak->bgp_orig->vrf_id != +			    bpi2->extra->vrfleak->bgp_orig->vrf_id) {  				compare = 1;  			}  		} diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index da599688ea..ad66720512 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -996,41 +996,6 @@ static void setlabels(struct bgp_path_info *bpi,  	extra->num_labels = num_labels;  } -/* - * make encoded route SIDs match specified encoded sid set - */ -static void setsids(struct bgp_path_info *bpi, -		      struct in6_addr *sid, -		      uint32_t num_sids) -{ -	uint32_t i; -	struct bgp_path_info_extra *extra; - -	if (num_sids) -		assert(sid); -	assert(num_sids <= BGP_MAX_SIDS); - -	if (!num_sids) { -		if (bpi->extra) -			bpi->extra->num_sids = 0; -		return; -	} - -	extra = bgp_path_info_extra_get(bpi); -	for (i = 0; i < num_sids; i++) -		memcpy(&extra->sid[i].sid, &sid[i], sizeof(struct in6_addr)); -	extra->num_sids = num_sids; -} - -static void unsetsids(struct bgp_path_info *bpi) -{ -	struct bgp_path_info_extra *extra; - -	extra = bgp_path_info_extra_get(bpi); -	extra->num_sids = 0; -	memset(extra->sid, 0, sizeof(extra->sid)); -} -  static bool leak_update_nexthop_valid(struct bgp *to_bgp, struct bgp_dest *bn,  				      struct attr *new_attr, afi_t afi,  				      safi_t safi, @@ -1045,8 +1010,8 @@ static bool leak_update_nexthop_valid(struct bgp *to_bgp, struct bgp_dest *bn,  	bpi_ultimate = bgp_get_imported_bpi_ultimate(source_bpi); -	if (bpi->extra && bpi->extra->bgp_orig) -		bgp_nexthop = bpi->extra->bgp_orig; +	if (bpi->extra && bpi->extra->vrfleak && bpi->extra->vrfleak->bgp_orig) +		bgp_nexthop = bpi->extra->vrfleak->bgp_orig;  	else  		bgp_nexthop = bgp_orig; @@ -1098,12 +1063,8 @@ leak_update(struct bgp *to_bgp, struct bgp_dest *bn,  	struct bgp_path_info *bpi;  	struct bgp_path_info *new;  	struct bgp_path_info_extra *extra; -	uint32_t num_sids = 0;  	struct bgp_path_info *parent = source_bpi; -	if (new_attr->srv6_l3vpn || new_attr->srv6_vpn) -		num_sids = 1; -  	if (debug)  		zlog_debug(  			"%s: entry: leak-to=%s, p=%pBD, type=%d, sub_type=%d", @@ -1132,7 +1093,8 @@ leak_update(struct bgp *to_bgp, struct bgp_dest *bn,  	 * match parent  	 */  	for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next) { -		if (bpi->extra && bpi->extra->parent == parent) +		if (bpi->extra && bpi->extra->vrfleak && +		    bpi->extra->vrfleak->parent == parent)  			break;  	} @@ -1200,34 +1162,6 @@ leak_update(struct bgp *to_bgp, struct bgp_dest *bn,  		if (!labelssame)  			setlabels(bpi, label, num_labels); -		/* -		 * rewrite sid -		 */ -		if (num_sids) { -			if (new_attr->srv6_l3vpn) { -				setsids(bpi, &new_attr->srv6_l3vpn->sid, -					num_sids); - -				extra = bgp_path_info_extra_get(bpi); - -				extra->sid[0].loc_block_len = -					new_attr->srv6_l3vpn->loc_block_len; -				extra->sid[0].loc_node_len = -					new_attr->srv6_l3vpn->loc_node_len; -				extra->sid[0].func_len = -					new_attr->srv6_l3vpn->func_len; -				extra->sid[0].arg_len = -					new_attr->srv6_l3vpn->arg_len; -				extra->sid[0].transposition_len = -					new_attr->srv6_l3vpn->transposition_len; -				extra->sid[0].transposition_offset = -					new_attr->srv6_l3vpn -						->transposition_offset; -			} else if (new_attr->srv6_vpn) -				setsids(bpi, &new_attr->srv6_vpn->sid, -					num_sids); -		} else -			unsetsids(bpi);  		if (nexthop_self_flag)  			bgp_path_info_set_flag(bn, bpi, BGP_PATH_ANNC_NH_SELF); @@ -1267,9 +1201,15 @@ leak_update(struct bgp *to_bgp, struct bgp_dest *bn,  	new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_IMPORTED, 0,  			to_bgp->peer_self, new_attr, bn); +	bgp_path_info_extra_get(new); +	if (!new->extra->vrfleak) +		new->extra->vrfleak = +			XCALLOC(MTYPE_BGP_ROUTE_EXTRA_VRFLEAK, +				sizeof(struct bgp_path_info_extra_vrfleak)); +  	if (source_bpi->peer) {  		extra = bgp_path_info_extra_get(new); -		extra->peer_orig = peer_lock(source_bpi->peer); +		extra->vrfleak->peer_orig = peer_lock(source_bpi->peer);  	}  	if (nexthop_self_flag) @@ -1278,42 +1218,16 @@ 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); -	bgp_path_info_extra_get(new); - -	/* -	 * rewrite sid -	 */ -	if (num_sids) { -		if (new_attr->srv6_l3vpn) { -			setsids(new, &new_attr->srv6_l3vpn->sid, num_sids); - -			extra = bgp_path_info_extra_get(new); - -			extra->sid[0].loc_block_len = -				new_attr->srv6_l3vpn->loc_block_len; -			extra->sid[0].loc_node_len = -				new_attr->srv6_l3vpn->loc_node_len; -			extra->sid[0].func_len = new_attr->srv6_l3vpn->func_len; -			extra->sid[0].arg_len = new_attr->srv6_l3vpn->arg_len; -			extra->sid[0].transposition_len = -				new_attr->srv6_l3vpn->transposition_len; -			extra->sid[0].transposition_offset = -				new_attr->srv6_l3vpn->transposition_offset; -		} else if (new_attr->srv6_vpn) -			setsids(new, &new_attr->srv6_vpn->sid, num_sids); -	} else -		unsetsids(new); -  	if (num_labels)  		setlabels(new, label, num_labels); -	new->extra->parent = bgp_path_info_lock(parent); +	new->extra->vrfleak->parent = bgp_path_info_lock(parent);  	bgp_dest_lock_node(  		(struct bgp_dest *)parent->net);  	if (bgp_orig) -		new->extra->bgp_orig = bgp_lock(bgp_orig); +		new->extra->vrfleak->bgp_orig = bgp_lock(bgp_orig);  	if (nexthop_orig) -		new->extra->nexthop_orig = *nexthop_orig; +		new->extra->vrfleak->nexthop_orig = *nexthop_orig;  	if (leak_update_nexthop_valid(to_bgp, bn, new_attr, afi, safi,  				      source_bpi, new, bgp_orig, p, debug)) @@ -1554,8 +1468,8 @@ vpn_leak_from_vrf_get_per_nexthop_label(afi_t afi, struct bgp_path_info *pi,  	/* Check the next-hop reachability.  	 * Get the bgp instance where the bgp_path_info originates.  	 */ -	if (pi->extra && pi->extra->bgp_orig) -		bgp_nexthop = pi->extra->bgp_orig; +	if (pi->extra && pi->extra->vrfleak && pi->extra->vrfleak->bgp_orig) +		bgp_nexthop = pi->extra->vrfleak->bgp_orig;  	else  		bgp_nexthop = from_bgp; @@ -1986,7 +1900,8 @@ void vpn_leak_from_vrf_withdraw(struct bgp *to_bgp,		/* to */  	 * match original bpi imported from  	 */  	for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next) { -		if (bpi->extra && bpi->extra->parent == path_vrf) { +		if (bpi->extra && bpi->extra->vrfleak && +		    bpi->extra->vrfleak->parent == path_vrf) {  			break;  		}  	} @@ -2039,9 +1954,9 @@ void vpn_leak_from_vrf_withdraw_all(struct bgp *to_bgp, struct bgp *from_bgp,  						   bpi->sub_type);  				if (bpi->sub_type != BGP_ROUTE_IMPORTED)  					continue; -				if (!bpi->extra) +				if (!bpi->extra || !bpi->extra->vrfleak)  					continue; -				if ((struct bgp *)bpi->extra->bgp_orig == +				if ((struct bgp *)bpi->extra->vrfleak->bgp_orig ==  				    from_bgp) {  					/* delete route */  					if (debug) @@ -2055,7 +1970,7 @@ void vpn_leak_from_vrf_withdraw_all(struct bgp *to_bgp, struct bgp *from_bgp,  					bgp_path_info_delete(bn, bpi);  					bgp_process(to_bgp, bn, afi, safi);  					bgp_mplsvpn_path_nh_label_unlink( -						bpi->extra->parent); +						bpi->extra->vrfleak->parent);  				}  			}  		} @@ -2162,8 +2077,9 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp,   /* to */  	 */  	struct bgp *src_bgp = bgp_lookup_by_rd(path_vpn, prd, afi); -	if (path_vpn->extra && path_vpn->extra->bgp_orig) -		src_vrf = path_vpn->extra->bgp_orig; +	if (path_vpn->extra && path_vpn->extra->vrfleak && +	    path_vpn->extra->vrfleak->bgp_orig) +		src_vrf = path_vpn->extra->vrfleak->bgp_orig;  	else if (src_bgp)  		src_vrf = src_bgp;  	else @@ -2429,9 +2345,8 @@ void vpn_leak_to_vrf_update(struct bgp *from_bgp,  	/* Loop over VRFs */  	for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) { - -		if (!path_vpn->extra -		    || path_vpn->extra->bgp_orig != bgp) { /* no loop */ +		if (!path_vpn->extra || !path_vpn->extra->vrfleak || +		    path_vpn->extra->vrfleak->bgp_orig != bgp) { /* no loop */  			vpn_leak_to_vrf_update_onevrf(bgp, from_bgp, path_vpn,  						      prd);  		} @@ -2504,9 +2419,9 @@ void vpn_leak_to_vrf_withdraw(struct bgp_path_info *path_vpn)  		for (bpi = bgp_dest_get_bgp_path_info(bn); bpi;  		     bpi = bpi->next) { -			if (bpi->extra -			    && (struct bgp_path_info *)bpi->extra->parent -				       == path_vpn) { +			if (bpi->extra && bpi->extra->vrfleak && +			    (struct bgp_path_info *)bpi->extra->vrfleak->parent == +				    path_vpn) {  				break;  			}  		} @@ -2540,10 +2455,10 @@ void vpn_leak_to_vrf_withdraw_all(struct bgp *to_bgp, afi_t afi)  		for (bpi = bgp_dest_get_bgp_path_info(bn); bpi;  		     bpi = bpi->next) { -			if (bpi->extra && bpi->extra->bgp_orig != to_bgp && -			    bpi->extra->parent && -			    is_pi_family_vpn(bpi->extra->parent)) { - +			if (bpi->extra && bpi->extra->vrfleak && +			    bpi->extra->vrfleak->bgp_orig != to_bgp && +			    bpi->extra->vrfleak->parent && +			    is_pi_family_vpn(bpi->extra->vrfleak->parent)) {  				/* delete route */  				bgp_aggregate_decrement(to_bgp,  							bgp_dest_get_prefix(bn), @@ -2580,9 +2495,8 @@ void vpn_leak_no_retain(struct bgp *to_bgp, struct bgp *vpn_from, afi_t afi)  		for (bn = bgp_table_top(table); bn; bn = bgp_route_next(bn)) {  			for (bpi = bgp_dest_get_bgp_path_info(bn); bpi;  			     bpi = bpi->next) { - -				if (bpi->extra && -				    bpi->extra->bgp_orig == to_bgp) +				if (bpi->extra && bpi->extra->vrfleak && +				    bpi->extra->vrfleak->bgp_orig == to_bgp)  					continue;  				if (bpi->sub_type != BGP_ROUTE_NORMAL) @@ -2627,9 +2541,8 @@ void vpn_leak_to_vrf_update_all(struct bgp *to_bgp, struct bgp *vpn_from,  			for (bpi = bgp_dest_get_bgp_path_info(bn); bpi;  			     bpi = bpi->next) { - -				if (bpi->extra && -				    bpi->extra->bgp_orig == to_bgp) +				if (bpi->extra && bpi->extra->vrfleak && +				    bpi->extra->vrfleak->bgp_orig == to_bgp)  					continue;  				vpn_leak_to_vrf_update_onevrf(to_bgp, vpn_from, diff --git a/bgpd/bgp_mplsvpn.h b/bgpd/bgp_mplsvpn.h index dcde42146c..62748a9e56 100644 --- a/bgpd/bgp_mplsvpn.h +++ b/bgpd/bgp_mplsvpn.h @@ -298,12 +298,11 @@ static inline bool is_route_injectable_into_vpn(struct bgp_path_info *pi)  	struct bgp_table *table;  	struct bgp_dest *dest; -	if (pi->sub_type != BGP_ROUTE_IMPORTED || -	    !pi->extra || -	    !pi->extra->parent) +	if (pi->sub_type != BGP_ROUTE_IMPORTED || !pi->extra || +	    !pi->extra->vrfleak || !pi->extra->vrfleak->parent)  		return true; -	parent_pi = (struct bgp_path_info *)pi->extra->parent; +	parent_pi = (struct bgp_path_info *)pi->extra->vrfleak->parent;  	dest = parent_pi->net;  	if (!dest)  		return true; diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index 02cfd9c2af..bbc30365c7 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -56,10 +56,11 @@ static int bgp_isvalid_nexthop_for_ebgp(struct bgp_nexthop_cache *bnc,  	struct bgp_interface *iifp;  	struct peer *peer; -	if (!path->extra || !path->extra->peer_orig) +	if (!path->extra || !path->extra->vrfleak || +	    !path->extra->vrfleak->peer_orig)  		return false; -	peer = path->extra->peer_orig; +	peer = path->extra->vrfleak->peer_orig;  	/* only connected ebgp peers are valid */  	if (peer->sort != BGP_PEER_EBGP || peer->ttl != BGP_DEFAULT_TTL || diff --git a/bgpd/bgp_pbr.c b/bgpd/bgp_pbr.c index bc9ecff7d9..43682de413 100644 --- a/bgpd/bgp_pbr.c +++ b/bgpd/bgp_pbr.c @@ -1667,8 +1667,8 @@ static void bgp_pbr_flush_iprule(struct bgp *bgp, struct bgp_pbr_action *bpa,  			/* unlink path to bpme */  			path = (struct bgp_path_info *)bpr->path;  			extra = bgp_path_info_extra_get(path); -			if (extra->bgp_fs_iprule) -				listnode_delete(extra->bgp_fs_iprule, bpr); +			if (extra->flowspec && extra->flowspec->bgp_fs_iprule) +				listnode_delete(extra->flowspec->bgp_fs_iprule, bpr);  			bpr->path = NULL;  		}  	} @@ -1696,8 +1696,8 @@ static void bgp_pbr_flush_entry(struct bgp *bgp, struct bgp_pbr_action *bpa,  			/* unlink path to bpme */  			path = (struct bgp_path_info *)bpme->path;  			extra = bgp_path_info_extra_get(path); -			if (extra->bgp_fs_pbr) -				listnode_delete(extra->bgp_fs_pbr, bpme); +			if (extra->flowspec && extra->flowspec->bgp_fs_pbr) +				listnode_delete(extra->flowspec->bgp_fs_pbr, bpme);  			bpme->path = NULL;  		}  	} @@ -2342,8 +2342,8 @@ static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp,  			struct bgp_path_info_extra *extra =  				bgp_path_info_extra_get(path); -			if (extra && -			    listnode_lookup_nocheck(extra->bgp_fs_iprule, +			if (extra && extra->flowspec && +			    listnode_lookup_nocheck(extra->flowspec->bgp_fs_iprule,  						    bpr)) {  				if (BGP_DEBUG(pbr, PBR_ERROR))  					zlog_err("%s: entry %p/%p already installed in bgp pbr iprule", @@ -2501,8 +2501,8 @@ static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp,  		struct bgp_path_info_extra *extra =  			bgp_path_info_extra_get(path); -		if (extra && -		    listnode_lookup_nocheck(extra->bgp_fs_pbr, bpme)) { +		if (extra && extra->flowspec && +		    listnode_lookup_nocheck(extra->flowspec->bgp_fs_pbr, bpme)) {  			if (BGP_DEBUG(pbr, PBR_ERROR))  				zlog_err(  					"%s: entry %p/%p already installed in bgp pbr", diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 5f923c598f..839f6d3669 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -188,8 +188,7 @@ static struct bgp_path_info_extra *bgp_path_info_extra_new(void)  		      sizeof(struct bgp_path_info_extra));  	new->label[0] = MPLS_INVALID_LABEL;  	new->num_labels = 0; -	new->bgp_fs_pbr = NULL; -	new->bgp_fs_iprule = NULL; +	new->flowspec = NULL;  	return new;  } @@ -206,8 +205,9 @@ void bgp_path_info_extra_free(struct bgp_path_info_extra **extra)  				   e->damp_info->safi);  	e->damp_info = NULL; -	if (e->parent) { -		struct bgp_path_info *bpi = (struct bgp_path_info *)e->parent; +	if (e->vrfleak && e->vrfleak->parent) { +		struct bgp_path_info *bpi = +			(struct bgp_path_info *)e->vrfleak->parent;  		if (bpi->net) {  			/* FIXME: since multiple e may have the same e->parent @@ -227,26 +227,34 @@ void bgp_path_info_extra_free(struct bgp_path_info_extra **extra)  				bpi->net = NULL;  			bgp_path_info_unlock(bpi);  		} -		bgp_path_info_unlock(e->parent); -		e->parent = NULL; +		bgp_path_info_unlock(e->vrfleak->parent); +		e->vrfleak->parent = NULL;  	} -	if (e->bgp_orig) -		bgp_unlock(e->bgp_orig); +	if (e->vrfleak && e->vrfleak->bgp_orig) +		bgp_unlock(e->vrfleak->bgp_orig); -	if (e->peer_orig) -		peer_unlock(e->peer_orig); +	if (e->vrfleak && e->vrfleak->peer_orig) +		peer_unlock(e->vrfleak->peer_orig);  	if (e->aggr_suppressors)  		list_delete(&e->aggr_suppressors); -	if (e->mh_info) -		bgp_evpn_path_mh_info_free(e->mh_info); +	if (e->evpn && e->evpn->mh_info) +		bgp_evpn_path_mh_info_free(e->evpn->mh_info); + +	if ((*extra)->flowspec && (*extra)->flowspec->bgp_fs_iprule) +		list_delete(&((*extra)->flowspec->bgp_fs_iprule)); +	if ((*extra)->flowspec && (*extra)->flowspec->bgp_fs_pbr) +		list_delete(&((*extra)->flowspec->bgp_fs_pbr)); + +	if (e->evpn) +		XFREE(MTYPE_BGP_ROUTE_EXTRA_EVPN, e->evpn); +	if (e->flowspec) +		XFREE(MTYPE_BGP_ROUTE_EXTRA_FS, e->flowspec); +	if (e->vrfleak) +		XFREE(MTYPE_BGP_ROUTE_EXTRA_VRFLEAK, e->vrfleak); -	if ((*extra)->bgp_fs_iprule) -		list_delete(&((*extra)->bgp_fs_iprule)); -	if ((*extra)->bgp_fs_pbr) -		list_delete(&((*extra)->bgp_fs_pbr));  	XFREE(MTYPE_BGP_ROUTE_EXTRA, *extra);  } @@ -257,6 +265,10 @@ struct bgp_path_info_extra *bgp_path_info_extra_get(struct bgp_path_info *pi)  {  	if (!pi->extra)  		pi->extra = bgp_path_info_extra_new(); +	if (!pi->extra->evpn && pi->net && pi->net->p.family == AF_EVPN) +		pi->extra->evpn = +			XCALLOC(MTYPE_BGP_ROUTE_EXTRA_EVPN, +				sizeof(struct bgp_path_info_extra_evpn));  	return pi->extra;  } @@ -570,8 +582,9 @@ struct bgp_path_info *bgp_get_imported_bpi_ultimate(struct bgp_path_info *info)  		return info;  	for (bpi_ultimate = info; -	     bpi_ultimate->extra && bpi_ultimate->extra->parent; -	     bpi_ultimate = bpi_ultimate->extra->parent) +	     bpi_ultimate->extra && bpi_ultimate->extra->vrfleak && +	     bpi_ultimate->extra->vrfleak->parent; +	     bpi_ultimate = bpi_ultimate->extra->vrfleak->parent)  		;  	return bpi_ultimate; @@ -4674,49 +4687,6 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,  				bgp_set_valid_label(&extra->label[0]);  		} -		/* Update SRv6 SID */ -		if (attr->srv6_l3vpn) { -			extra = bgp_path_info_extra_get(pi); -			if (sid_diff(&extra->sid[0].sid, -				     &attr->srv6_l3vpn->sid)) { -				sid_copy(&extra->sid[0].sid, -					 &attr->srv6_l3vpn->sid); -				extra->num_sids = 1; - -				extra->sid[0].loc_block_len = 0; -				extra->sid[0].loc_node_len = 0; -				extra->sid[0].func_len = 0; -				extra->sid[0].arg_len = 0; -				extra->sid[0].transposition_len = 0; -				extra->sid[0].transposition_offset = 0; - -				if (attr->srv6_l3vpn->loc_block_len != 0) { -					extra->sid[0].loc_block_len = -						attr->srv6_l3vpn->loc_block_len; -					extra->sid[0].loc_node_len = -						attr->srv6_l3vpn->loc_node_len; -					extra->sid[0].func_len = -						attr->srv6_l3vpn->func_len; -					extra->sid[0].arg_len = -						attr->srv6_l3vpn->arg_len; -					extra->sid[0].transposition_len = -						attr->srv6_l3vpn -							->transposition_len; -					extra->sid[0].transposition_offset = -						attr->srv6_l3vpn -							->transposition_offset; -				} -			} -		} else if (attr->srv6_vpn) { -			extra = bgp_path_info_extra_get(pi); -			if (sid_diff(&extra->sid[0].sid, -				     &attr->srv6_vpn->sid)) { -				sid_copy(&extra->sid[0].sid, -					 &attr->srv6_vpn->sid); -				extra->num_sids = 1; -			} -		} -  #ifdef ENABLE_BGP_VNC  		if ((afi == AFI_IP || afi == AFI_IP6)  		    && (safi == SAFI_UNICAST)) { @@ -4771,8 +4741,9 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,  			struct bgp *bgp_nexthop = bgp; -			if (pi->extra && pi->extra->bgp_orig) -				bgp_nexthop = pi->extra->bgp_orig; +			if (pi->extra && pi->extra->vrfleak && +			    pi->extra->vrfleak->bgp_orig) +				bgp_nexthop = pi->extra->vrfleak->bgp_orig;  			nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr); @@ -4901,29 +4872,6 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,  			bgp_set_valid_label(&extra->label[0]);  	} -	/* Update SRv6 SID */ -	if (safi == SAFI_MPLS_VPN) { -		extra = bgp_path_info_extra_get(new); -		if (attr->srv6_l3vpn) { -			sid_copy(&extra->sid[0].sid, &attr->srv6_l3vpn->sid); -			extra->num_sids = 1; - -			extra->sid[0].loc_block_len = -				attr->srv6_l3vpn->loc_block_len; -			extra->sid[0].loc_node_len = -				attr->srv6_l3vpn->loc_node_len; -			extra->sid[0].func_len = attr->srv6_l3vpn->func_len; -			extra->sid[0].arg_len = attr->srv6_l3vpn->arg_len; -			extra->sid[0].transposition_len = -				attr->srv6_l3vpn->transposition_len; -			extra->sid[0].transposition_offset = -				attr->srv6_l3vpn->transposition_offset; -		} else if (attr->srv6_vpn) { -			sid_copy(&extra->sid[0].sid, &attr->srv6_vpn->sid); -			extra->num_sids = 1; -		} -	} -  	/* Nexthop reachability check. */  	if (((afi == AFI_IP || afi == AFI_IP6) &&  	     (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST || @@ -9167,26 +9115,27 @@ void route_vty_out(struct vty *vty, const struct prefix *p,  	 * If vrf id of nexthop is different from that of prefix,  	 * set up printable string to append  	 */ -	if (path->extra && path->extra->bgp_orig) { +	if (path->extra && path->extra->vrfleak && +	    path->extra->vrfleak->bgp_orig) {  		const char *self = "";  		if (nexthop_self)  			self = "<";  		nexthop_othervrf = true; -		nexthop_vrfid = path->extra->bgp_orig->vrf_id; +		nexthop_vrfid = path->extra->vrfleak->bgp_orig->vrf_id; -		if (path->extra->bgp_orig->vrf_id == VRF_UNKNOWN) +		if (path->extra->vrfleak->bgp_orig->vrf_id == VRF_UNKNOWN)  			snprintf(vrf_id_str, sizeof(vrf_id_str),  				"@%s%s", VRFID_NONE_STR, self);  		else  			snprintf(vrf_id_str, sizeof(vrf_id_str), "@%u%s", -				 path->extra->bgp_orig->vrf_id, self); +				 path->extra->vrfleak->bgp_orig->vrf_id, self); -		if (path->extra->bgp_orig->inst_type -		    != BGP_INSTANCE_TYPE_DEFAULT) +		if (path->extra->vrfleak->bgp_orig->inst_type != +		    BGP_INSTANCE_TYPE_DEFAULT) -			nexthop_vrfname = path->extra->bgp_orig->name; +			nexthop_vrfname = path->extra->vrfleak->bgp_orig->name;  	} else {  		const char *self = ""; @@ -10301,11 +10250,13 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,  		vty_out(vty, "\n"); -	if (path->extra && path->extra->parent && !json_paths) { +	if (path->extra && path->extra->vrfleak && +	    path->extra->vrfleak->parent && !json_paths) {  		struct bgp_path_info *parent_ri;  		struct bgp_dest *dest, *pdest; -		parent_ri = (struct bgp_path_info *)path->extra->parent; +		parent_ri = +			(struct bgp_path_info *)path->extra->vrfleak->parent;  		dest = parent_ri->net;  		if (dest && dest->pdest) {  			pdest = dest->pdest; @@ -10608,17 +10559,18 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,  	/*  	 * Note when vrfid of nexthop is different from that of prefix  	 */ -	if (path->extra && path->extra->bgp_orig) { -		vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id; +	if (path->extra && path->extra->vrfleak && +	    path->extra->vrfleak->bgp_orig) { +		vrf_id_t nexthop_vrfid = path->extra->vrfleak->bgp_orig->vrf_id;  		if (json_paths) {  			const char *vn; -			if (path->extra->bgp_orig->inst_type -			    == BGP_INSTANCE_TYPE_DEFAULT) +			if (path->extra->vrfleak->bgp_orig->inst_type == +			    BGP_INSTANCE_TYPE_DEFAULT)  				vn = VRF_DEFAULT_NAME;  			else -				vn = path->extra->bgp_orig->name; +				vn = path->extra->vrfleak->bgp_orig->name;  			json_object_string_add(json_path, "nhVrfName", vn); @@ -11013,13 +10965,16 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,  	}  	/* Remote SID */ -	if (path->extra && path->extra->num_sids > 0 && safi != SAFI_EVPN) { +	if ((path->attr->srv6_l3vpn || path->attr->srv6_vpn) && +	    safi != SAFI_EVPN) { +		struct in6_addr *sid_tmp = +			path->attr->srv6_l3vpn ? (&path->attr->srv6_l3vpn->sid) +					       : (&path->attr->srv6_vpn->sid);  		if (json_paths)  			json_object_string_addf(json_path, "remoteSid", "%pI6", -						&path->extra->sid[0].sid); +						sid_tmp);  		else -			vty_out(vty, "      Remote SID: %pI6\n", -				&path->extra->sid[0].sid); +			vty_out(vty, "      Remote SID: %pI6\n", sid_tmp);  	}  	/* Label Index */ diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 265587c424..0a6f535b22 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -145,6 +145,54 @@ struct bgp_sid_info {  	uint8_t transposition_offset;  }; +/* new structure for EVPN */ +struct bgp_path_info_extra_evpn { +#define BGP_EVPN_MACIP_TYPE_SVI_IP (1 << 0) +	/* af specific flags */ +	uint16_t af_flags; +	union { +		struct ethaddr mac; /* MAC set here for VNI IP table */ +		struct ipaddr ip;   /* IP set here for VNI MAC table */ +	} vni_info; +	/* Destination Ethernet Segment links for EVPN MH */ +	struct bgp_path_mh_info *mh_info; +}; + +/* new structure for flowspec*/ +struct bgp_path_info_extra_fs { +	/* presence of FS pbr firewall based entry */ +	struct list *bgp_fs_pbr; +	/* presence of FS pbr iprule based entry */ +	struct list *bgp_fs_iprule; +}; + +/* new structure for vrfleak*/ +struct bgp_path_info_extra_vrfleak { +	void *parent; /* parent from global table */ +	/* +	 * Original bgp instance for imported routes. Needed for: +	 * 1. Find all routes from a specific vrf for deletion +	 * 2. vrf context of original nexthop +	 * +	 * Store pointer to bgp instance rather than bgp->vrf_id because +	 * bgp->vrf_id is not always valid (or may change?). +	 * +	 * Set to NULL if route is not imported from another bgp instance. +	 */ +	struct bgp *bgp_orig; +	/* +	 * Original bgp session to know if the session is a +	 * connected EBGP session or not +	 */ +	struct peer *peer_orig; +	/* +	 * Nexthop in context of original bgp instance. Needed +	 * for label resolution of core mpls routes exported to a vrf. +	 * Set nexthop_orig.family to 0 if not valid. +	 */ +	struct prefix nexthop_orig; +}; +  /* Ancillary information to struct bgp_path_info,   * used for uncommonly used data (aggregation, MPLS, etc.)   * and lazily allocated to save memory. @@ -163,13 +211,8 @@ struct bgp_path_info_extra {  	mpls_label_t label[BGP_MAX_LABELS];  	uint32_t num_labels; -	/* af specific flags */ -	uint16_t af_flags; -#define BGP_EVPN_MACIP_TYPE_SVI_IP (1 << 0) - -	/* SRv6 SID(s) for SRv6-VPN */ -	struct bgp_sid_info sid[BGP_MAX_SIDS]; -	uint32_t num_sids; +	/*For EVPN*/ +	struct bgp_path_info_extra_evpn *evpn;  #ifdef ENABLE_BGP_VNC  	union { @@ -200,50 +243,11 @@ struct bgp_path_info_extra {  	} vnc;  #endif -	/* -	 * For imported routes into a VNI (or VRF) -	 */ -	void *parent;	    /* parent from global table */ -	union { -		struct ethaddr mac; /* MAC set here for VNI IP table */ -		struct ipaddr ip;   /* IP set here for VNI MAC table */ -	} vni_info; - -	/* -	 * Some tunnelish parameters follow. Maybe consolidate into an -	 * internal tunnel structure? -	 */ - -	/* -	 * Original bgp instance for imported routes. Needed for: -	 * 1. Find all routes from a specific vrf for deletion -	 * 2. vrf context of original nexthop -	 * -	 * Store pointer to bgp instance rather than bgp->vrf_id because -	 * bgp->vrf_id is not always valid (or may change?). -	 * -	 * Set to NULL if route is not imported from another bgp instance. -	 */ -	struct bgp *bgp_orig; - -	/* -	 * Original bgp session to know if the session is a -	 * connected EBGP session or not -	 */ -	struct peer *peer_orig; +	/* For flowspec*/ +	struct bgp_path_info_extra_fs *flowspec; -	/* -	 * Nexthop in context of original bgp instance. Needed -	 * for label resolution of core mpls routes exported to a vrf. -	 * Set nexthop_orig.family to 0 if not valid. -	 */ -	struct prefix nexthop_orig; -	/* presence of FS pbr firewall based entry */ -	struct list *bgp_fs_pbr; -	/* presence of FS pbr iprule based entry */ -	struct list *bgp_fs_iprule; -	/* Destination Ethernet Segment links for EVPN MH */ -	struct bgp_path_mh_info *mh_info; +	/* For vrf leaking*/ +	struct bgp_path_info_extra_vrfleak *vrfleak;  };  struct bgp_mplsvpn_label_nh { diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index 0990567776..8fa0a4d4f3 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -1313,12 +1313,13 @@ route_match_vrl_source_vrf(void *rule, const struct prefix *prefix,  	if (strncmp(vrf_name, "n/a", VRF_NAMSIZ) == 0)  		return RMAP_NOMATCH; -	if (path->extra == NULL || path->extra->bgp_orig == NULL) +	if (path->extra == NULL || path->extra->vrfleak == NULL || +	    path->extra->vrfleak->bgp_orig == NULL)  		return RMAP_NOMATCH; -	if (strncmp(vrf_name, vrf_id_to_name(path->extra->bgp_orig->vrf_id), -		    VRF_NAMSIZ) -	    == 0) +	if (strncmp(vrf_name, +		    vrf_id_to_name(path->extra->vrfleak->bgp_orig->vrf_id), +		    VRF_NAMSIZ) == 0)  		return RMAP_MATCH;  	return RMAP_NOMATCH; diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 4f773f21a5..f5bee8110e 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -10959,6 +10959,29 @@ DEFUN (show_bgp_memory,  				memstrbuf, sizeof(memstrbuf),  				count * sizeof(struct bgp_path_info_extra))); +	count = mtype_stats_alloc(MTYPE_BGP_ROUTE_EXTRA_EVPN); +	if (count) +		vty_out(vty, "%ld BGP extra info for EVPN, using %s of memory\n", +			count, +			mtype_memstr(memstrbuf, sizeof(memstrbuf), +				     count * sizeof(struct bgp_path_info_extra_evpn))); + +	count = mtype_stats_alloc(MTYPE_BGP_ROUTE_EXTRA_FS); +	if (count) +		vty_out(vty, +			"%ld BGP extra info for flowspec, using %s of memory\n", +			count, +			mtype_memstr(memstrbuf, sizeof(memstrbuf), +				     count * sizeof(struct bgp_path_info_extra_fs))); + +	count = mtype_stats_alloc(MTYPE_BGP_ROUTE_EXTRA_VRFLEAK); +	if (count) +		vty_out(vty, +			"%ld BGP extra info for vrf leaking, using %s of memory\n", +			count, +			mtype_memstr(memstrbuf, sizeof(memstrbuf), +				     count * sizeof(struct bgp_path_info_extra_vrfleak))); +  	if ((count = mtype_stats_alloc(MTYPE_BGP_STATIC)))  		vty_out(vty, "%ld Static routes, using %s of memory\n", count,  			mtype_memstr(memstrbuf, sizeof(memstrbuf), diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index becd99167f..ac5aef6515 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1308,7 +1308,6 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p,  	struct bgp_path_info local_info;  	struct bgp_path_info *mpinfo_cp = &local_info;  	route_tag_t tag; -	struct bgp_sid_info *sid_info;  	mpls_label_t *labels;  	uint32_t num_labels = 0;  	mpls_label_t nh_label; @@ -1348,7 +1347,8 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p,  	/*  	 * vrf leaking support (will have only one nexthop)  	 */ -	if (info->extra && info->extra->bgp_orig) +	if (info->extra && info->extra->vrfleak && +	    info->extra->vrfleak->bgp_orig)  		nh_othervrf = 1;  	/* Make Zebra API structure. */ @@ -1364,8 +1364,10 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p,  	    && info->sub_type == BGP_ROUTE_IMPORTED) {  		/* Obtain peer from parent */ -		if (info->extra && info->extra->parent) -			peer = ((struct bgp_path_info *)(info->extra->parent)) +		if (info->extra && info->extra->vrfleak && +		    info->extra->vrfleak->parent) +			peer = ((struct bgp_path_info *)(info->extra->vrfleak +								 ->parent))  				       ->peer;  	} @@ -1553,15 +1555,21 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p,  		api_nh->weight = nh_weight; -		if (mpinfo->extra && !is_evpn && -		    bgp_is_valid_label(&labels[0]) && -		    !sid_zero(&mpinfo->extra->sid[0].sid)) { -			sid_info = &mpinfo->extra->sid[0]; - -			memcpy(&api_nh->seg6_segs, &sid_info->sid, +		if (((mpinfo->attr->srv6_l3vpn && +		      !sid_zero(&mpinfo->attr->srv6_l3vpn->sid)) || +		     (mpinfo->attr->srv6_vpn && +		      !sid_zero(&mpinfo->attr->srv6_vpn->sid))) && +		    !is_evpn && bgp_is_valid_label(&labels[0])) { +			struct in6_addr *sid_tmp = +				mpinfo->attr->srv6_l3vpn +					? (&mpinfo->attr->srv6_l3vpn->sid) +					: (&mpinfo->attr->srv6_vpn->sid); + +			memcpy(&api_nh->seg6_segs, sid_tmp,  			       sizeof(api_nh->seg6_segs)); -			if (sid_info->transposition_len != 0) { +			if (mpinfo->attr->srv6_l3vpn && +			    mpinfo->attr->srv6_l3vpn->transposition_len != 0) {  				mpls_lse_decode(labels[0], &nh_label, &ttl,  						&exp, &bos); @@ -1573,8 +1581,10 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p,  				}  				transpose_sid(&api_nh->seg6_segs, nh_label, -					      sid_info->transposition_offset, -					      sid_info->transposition_len); +					      mpinfo->attr->srv6_l3vpn +						      ->transposition_offset, +					      mpinfo->attr->srv6_l3vpn +						      ->transposition_len);  			}  			SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_SEG6); @@ -2436,8 +2446,14 @@ static int rule_notify_owner(ZAPI_CALLBACK_ARGS)  			/* link bgp_info to bgp_pbr */  			path = (struct bgp_path_info *)bgp_pbr->path;  			extra = bgp_path_info_extra_get(path); -			listnode_add_force(&extra->bgp_fs_iprule, -					   bgp_pbr); +			if (!extra->flowspec) { +				extra->flowspec = +					XCALLOC(MTYPE_BGP_ROUTE_EXTRA_FS, +						sizeof(struct bgp_path_info_extra_fs)); +				extra->flowspec->bgp_fs_iprule = NULL; +				extra->flowspec->bgp_fs_pbr = NULL; +			} +			listnode_add_force(&extra->flowspec->bgp_fs_iprule, bgp_pbr);  		}  		if (BGP_DEBUG(zebra, ZEBRA))  			zlog_debug("%s: Received RULE_INSTALLED", __func__); @@ -2539,7 +2555,14 @@ static int ipset_entry_notify_owner(ZAPI_CALLBACK_ARGS)  		/* link bgp_path_info to bpme */  		path = (struct bgp_path_info *)bgp_pbime->path;  		extra = bgp_path_info_extra_get(path); -		listnode_add_force(&extra->bgp_fs_pbr, bgp_pbime); +		if (!extra->flowspec) { +			extra->flowspec = +				XCALLOC(MTYPE_BGP_ROUTE_EXTRA_FS, +					sizeof(struct bgp_path_info_extra_fs)); +			extra->flowspec->bgp_fs_iprule = NULL; +			extra->flowspec->bgp_fs_pbr = NULL; +		} +		listnode_add_force(&extra->flowspec->bgp_fs_pbr, bgp_pbime);  		}  		break;  	case ZAPI_IPSET_ENTRY_FAIL_REMOVE: diff --git a/bgpd/bgp_zebra.h b/bgpd/bgp_zebra.h index a0f7819460..ed2d5e669d 100644 --- a/bgpd/bgp_zebra.h +++ b/bgpd/bgp_zebra.h @@ -10,9 +10,10 @@  /* Macro to update bgp_original based on bpg_path_info */  #define BGP_ORIGINAL_UPDATE(_bgp_orig, _mpinfo, _bgp)                          \ -	((_mpinfo->extra && _mpinfo->extra->bgp_orig                           \ -	  && _mpinfo->sub_type == BGP_ROUTE_IMPORTED)                          \ -		 ? (_bgp_orig = _mpinfo->extra->bgp_orig)                      \ +	((_mpinfo->extra && _mpinfo->extra->vrfleak &&                        \ +	  _mpinfo->extra->vrfleak->bgp_orig &&                                \ +	  _mpinfo->sub_type == BGP_ROUTE_IMPORTED)                             \ +		 ? (_bgp_orig = _mpinfo->extra->vrfleak->bgp_orig)            \  		 : (_bgp_orig = _bgp))  /* Default weight for next hop, if doing weighted ECMP. */ diff --git a/bgpd/rfapi/rfapi_vty.c b/bgpd/rfapi/rfapi_vty.c index 29698846c3..252b6d632a 100644 --- a/bgpd/rfapi/rfapi_vty.c +++ b/bgpd/rfapi/rfapi_vty.c @@ -420,15 +420,20 @@ void rfapi_vty_out_vncinfo(struct vty *vty, const struct prefix *p,  			vty_out(vty, " label=%u",  				decode_label(&bpi->extra->label[0])); -		if (bpi->extra->num_sids) { -			vty_out(vty, " sid=%pI6", &bpi->extra->sid[0].sid); - -			if (bpi->extra->sid[0].loc_block_len != 0) { +		if (bpi->attr->srv6_l3vpn || bpi->attr->srv6_vpn) { +			struct in6_addr *sid_tmp = +				bpi->attr->srv6_l3vpn +					? (&bpi->attr->srv6_l3vpn->sid) +					: (&bpi->attr->srv6_vpn->sid); +			vty_out(vty, " sid=%pI6", sid_tmp); + +			if (bpi->attr->srv6_l3vpn && +			    bpi->attr->srv6_l3vpn->loc_block_len != 0) {  				vty_out(vty, " sid_structure=[%d,%d,%d,%d]", -					bpi->extra->sid[0].loc_block_len, -					bpi->extra->sid[0].loc_node_len, -					bpi->extra->sid[0].func_len, -					bpi->extra->sid[0].arg_len); +					bpi->attr->srv6_l3vpn->loc_block_len, +					bpi->attr->srv6_l3vpn->loc_node_len, +					bpi->attr->srv6_l3vpn->func_len, +					bpi->attr->srv6_l3vpn->arg_len);  			}  		}  	}  | 
