diff options
| author | Jafar Al-Gharaibeh <jafar@atcorp.com> | 2025-02-17 13:05:21 -0600 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-02-17 13:05:21 -0600 | 
| commit | 33ed0a3315682382cfbac4a6b3ff4f18b67f69d1 (patch) | |
| tree | e5e3b293bc9a2f824c32a2f69b995fca5c72af0b | |
| parent | bb22e8b24b8d785d270952f11db862479a675640 (diff) | |
| parent | ba721ac7f7606ac69e29efa70fddc6a51cb65f6a (diff) | |
Merge pull request #18143 from FRRouting/mergify/bp/dev/10.3/pr-18079
bgpd: Fix crash in bgp_labelpool (backport #18079)
| -rw-r--r-- | bgpd/bgp_label.c | 6 | ||||
| -rw-r--r-- | bgpd/bgp_labelpool.c | 24 | ||||
| -rw-r--r-- | bgpd/bgp_labelpool.h | 4 | ||||
| -rw-r--r-- | bgpd/bgp_mplsvpn.c | 7 | 
4 files changed, 26 insertions, 15 deletions
diff --git a/bgpd/bgp_label.c b/bgpd/bgp_label.c index 5db3621738..8ed9584b0a 100644 --- a/bgpd/bgp_label.c +++ b/bgpd/bgp_label.c @@ -387,6 +387,8 @@ void bgp_reg_dereg_for_label(struct bgp_dest *dest, struct bgp_path_info *pi,  			 */  			if (!have_label_to_reg) {  				SET_FLAG(dest->flags, BGP_NODE_LABEL_REQUESTED); +				struct bgp_table *table; +  				if (BGP_DEBUG(labelpool, LABELPOOL))  					zlog_debug(  						"%s: Requesting label from LP for %pFX", @@ -396,7 +398,9 @@ void bgp_reg_dereg_for_label(struct bgp_dest *dest, struct bgp_path_info *pi,  				 * the pool. This means we'll never register  				 * FECs withoutvalid labels.  				 */ -				bgp_lp_get(LP_TYPE_BGP_LU, dest, +				table = bgp_dest_table(dest); + +				bgp_lp_get(LP_TYPE_BGP_LU, dest, table->bgp->vrf_id,  					   bgp_reg_for_label_callback);  				return;  			} diff --git a/bgpd/bgp_labelpool.c b/bgpd/bgp_labelpool.c index 54a966e191..a75cbcc5d9 100644 --- a/bgpd/bgp_labelpool.c +++ b/bgpd/bgp_labelpool.c @@ -77,6 +77,7 @@ struct lp_lcb {  	mpls_label_t	label;		/* MPLS_LABEL_NONE = not allocated */  	int		type;  	void		*labelid;	/* unique ID */ +	vrf_id_t	vrf_id;  	/*  	 * callback for label allocation and loss  	 * @@ -97,6 +98,7 @@ struct lp_cbq_item {  	int		type;  	mpls_label_t	label;  	void		*labelid; +	vrf_id_t	vrf_id;  	bool		allocated;	/* false = lost */  }; @@ -105,6 +107,7 @@ static wq_item_status lp_cbq_docallback(struct work_queue *wq, void *data)  	struct lp_cbq_item *lcbq = data;  	int rc;  	int debug = BGP_DEBUG(labelpool, LABELPOOL); +	struct bgp *bgp = bgp_lookup_by_vrf_id(lcbq->vrf_id);  	if (debug)  		zlog_debug("%s: calling callback with labelid=%p label=%u allocated=%d", @@ -117,6 +120,9 @@ static wq_item_status lp_cbq_docallback(struct work_queue *wq, void *data)  		return WQ_SUCCESS;  	} +	if (!bgp) +		return WQ_SUCCESS; +  	rc = (*(lcbq->cbfunc))(lcbq->label, lcbq->labelid, lcbq->allocated);  	if (lcbq->allocated && rc) { @@ -320,10 +326,8 @@ static mpls_label_t get_label_from_pool(void *labelid)  /*   * Success indicated by value of "label" field in returned LCB   */ -static struct lp_lcb *lcb_alloc( -	int	type, -	void	*labelid, -	int	(*cbfunc)(mpls_label_t label, void *labelid, bool allocated)) +static struct lp_lcb *lcb_alloc(int type, void *labelid, vrf_id_t vrf_id, +				int (*cbfunc)(mpls_label_t label, void *labelid, bool allocated))  {  	/*  	 * Set up label control block @@ -334,6 +338,7 @@ static struct lp_lcb *lcb_alloc(  	new->label = get_label_from_pool(labelid);  	new->type = type;  	new->labelid = labelid; +	new->vrf_id = vrf_id;  	new->cbfunc = cbfunc;  	return new; @@ -365,10 +370,8 @@ static struct lp_lcb *lcb_alloc(   * Prior requests for a given labelid are detected so that requests and   * assignments are not duplicated.   */ -void bgp_lp_get( -	int	type, -	void	*labelid, -	int	(*cbfunc)(mpls_label_t label, void *labelid, bool allocated)) +void bgp_lp_get(int type, void *labelid, vrf_id_t vrf_id, +		int (*cbfunc)(mpls_label_t label, void *labelid, bool allocated))  {  	struct lp_lcb *lcb;  	int requested = 0; @@ -383,7 +386,7 @@ void bgp_lp_get(  	if (!skiplist_search(lp->ledger, labelid, (void **)&lcb)) {  		requested = 1;  	} else { -		lcb = lcb_alloc(type, labelid, cbfunc); +		lcb = lcb_alloc(type, labelid, vrf_id, cbfunc);  		if (debug)  			zlog_debug("%s: inserting lcb=%p label=%u",  				__func__, lcb, lcb->label); @@ -413,6 +416,7 @@ void bgp_lp_get(  		q->type = lcb->type;  		q->label = lcb->label;  		q->labelid = lcb->labelid; +		q->vrf_id = lcb->vrf_id;  		q->allocated = true;  		/* if this is a LU request, lock node before queueing */ @@ -580,6 +584,7 @@ static void bgp_sync_label_manager(struct event *e)  		q->type = lcb->type;  		q->label = lcb->label;  		q->labelid = lcb->labelid; +		q->vrf_id = lcb->vrf_id;  		q->allocated = true;  		if (debug) @@ -693,6 +698,7 @@ void bgp_lp_event_zebra_up(void)  				q->type = lcb->type;  				q->label = lcb->label;  				q->labelid = lcb->labelid; +				q->vrf_id = lcb->vrf_id;  				q->allocated = false;  				check_bgp_lu_cb_lock(lcb);  				work_queue_add(lp->callback_q, q); diff --git a/bgpd/bgp_labelpool.h b/bgpd/bgp_labelpool.h index a17482d112..509f9e625d 100644 --- a/bgpd/bgp_labelpool.h +++ b/bgpd/bgp_labelpool.h @@ -35,8 +35,8 @@ struct labelpool {  extern void bgp_lp_init(struct event_loop *master, struct labelpool *pool);  extern void bgp_lp_finish(void); -extern void bgp_lp_get(int type, void *labelid, -	int (*cbfunc)(mpls_label_t label, void *labelid, bool allocated)); +extern void bgp_lp_get(int type, void *labelid, vrf_id_t vrf_id, +		       int (*cbfunc)(mpls_label_t label, void *labelid, bool allocated));  extern void bgp_lp_release(int type, void *labelid, mpls_label_t label);  extern void bgp_lp_event_chunk(uint32_t first, uint32_t last);  extern void bgp_lp_event_zebra_down(void); diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index 46e529f03d..580561aa9e 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -1450,7 +1450,7 @@ _vpn_leak_from_vrf_get_per_nexthop_label(struct bgp_path_info *pi,  		/* request a label to zebra for this nexthop  		 * the response from zebra will trigger the callback  		 */ -		bgp_lp_get(LP_TYPE_NEXTHOP, blnc, +		bgp_lp_get(LP_TYPE_NEXTHOP, blnc, from_bgp->vrf_id,  			   bgp_mplsvpn_get_label_per_nexthop_cb);  	} @@ -1490,7 +1490,8 @@ static mpls_label_t bgp_mplsvpn_get_vpn_label(struct vpn_policy *bgp_policy)  {  	if (bgp_policy->tovpn_label == MPLS_LABEL_NONE &&  	    CHECK_FLAG(bgp_policy->flags, BGP_VPN_POLICY_TOVPN_LABEL_AUTO)) { -		bgp_lp_get(LP_TYPE_VRF, bgp_policy, vpn_leak_label_callback); +		bgp_lp_get(LP_TYPE_VRF, bgp_policy, bgp_policy->bgp->vrf_id, +			   vpn_leak_label_callback);  		return MPLS_INVALID_LABEL;  	}  	return bgp_policy->tovpn_label; @@ -4387,7 +4388,7 @@ void bgp_mplsvpn_nh_label_bind_register_local_label(struct bgp *bgp,  						     label);  		bmnc->bgp_vpn = bgp;  		bmnc->allocation_in_progress = true; -		bgp_lp_get(LP_TYPE_BGP_L3VPN_BIND, bmnc, +		bgp_lp_get(LP_TYPE_BGP_L3VPN_BIND, bmnc, bgp->vrf_id,  			   bgp_mplsvpn_nh_label_bind_get_local_label_cb);  	}  | 
