Merge pull request #18079 from donaldsharp/labelpool_crash

bgpd: Fix crash in bgp_labelpool
This commit is contained in:
Philippe Guibert 2025-02-13 18:44:19 +01:00 committed by GitHub
commit 52a3239b26
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 26 additions and 15 deletions

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -1478,7 +1478,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);
}
@ -1518,7 +1518,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;
@ -4415,7 +4416,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);
}