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