mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-04 06:32:57 +00:00
Merge pull request #18079 from donaldsharp/labelpool_crash
bgpd: Fix crash in bgp_labelpool
This commit is contained in:
commit
52a3239b26
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user