summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_labelpool.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_labelpool.c')
-rw-r--r--bgpd/bgp_labelpool.c32
1 files changed, 24 insertions, 8 deletions
diff --git a/bgpd/bgp_labelpool.c b/bgpd/bgp_labelpool.c
index 8833386..23e0c19 100644
--- a/bgpd/bgp_labelpool.c
+++ b/bgpd/bgp_labelpool.c
@@ -36,6 +36,8 @@ static void lptest_init(void);
static void lptest_finish(void);
#endif
+static void bgp_sync_label_manager(struct event *e);
+
/*
* Remember where pool data are kept
*/
@@ -448,13 +450,16 @@ void bgp_lp_get(
if (lp_fifo_count(&lp->requests) > lp->pending_count) {
if (!bgp_zebra_request_label_range(MPLS_LABEL_BASE_ANY,
- lp->next_chunksize))
+ lp->next_chunksize, true))
return;
lp->pending_count += lp->next_chunksize;
if ((lp->next_chunksize << 1) <= LP_CHUNK_SIZE_MAX)
lp->next_chunksize <<= 1;
}
+
+ event_add_timer(bm->master, bgp_sync_label_manager, NULL, 1,
+ &bm->t_bgp_sync_label_manager);
}
void bgp_lp_release(
@@ -494,8 +499,18 @@ void bgp_lp_release(
bf_release_index(chunk->allocated_map, index);
chunk->nfree += 1;
deallocated = true;
+ break;
}
assert(deallocated);
+ if (deallocated &&
+ chunk->nfree == chunk->last - chunk->first + 1 &&
+ lp_fifo_count(&lp->requests) == 0) {
+ bgp_zebra_release_label_range(chunk->first,
+ chunk->last);
+ list_delete_node(lp->chunks, node);
+ lp_chunk_free(chunk);
+ lp->next_chunksize = LP_CHUNK_SIZE_MIN;
+ }
}
}
}
@@ -547,6 +562,10 @@ static void bgp_sync_label_manager(struct event *e)
zlog_debug("%s: out of labels, await more",
__func__);
}
+
+ lp_fifo_add_tail(&lp->requests, lf);
+ event_add_timer(bm->master, bgp_sync_label_manager,
+ NULL, 1, &bm->t_bgp_sync_label_manager);
break;
}
@@ -572,9 +591,6 @@ static void bgp_sync_label_manager(struct event *e)
finishedrequest:
XFREE(MTYPE_BGP_LABEL_FIFO, lf);
}
-
- event_add_timer(bm->master, bgp_sync_label_manager, NULL, 1,
- &bm->t_bgp_sync_label_manager);
}
void bgp_lp_event_chunk(uint32_t first, uint32_t last)
@@ -642,7 +658,7 @@ void bgp_lp_event_zebra_up(void)
}
/* round up */
- chunks_needed = (labels_needed / lp->next_chunksize) + 1;
+ chunks_needed = (labels_needed + lp->next_chunksize - 1) / lp->next_chunksize;
labels_needed = chunks_needed * lp->next_chunksize;
/*
@@ -650,10 +666,10 @@ void bgp_lp_event_zebra_up(void)
*/
list_delete_all_node(lp->chunks);
- if (!bgp_zebra_request_label_range(MPLS_LABEL_BASE_ANY, labels_needed))
+ if (labels_needed && !bgp_zebra_request_label_range(MPLS_LABEL_BASE_ANY,
+ labels_needed, true))
return;
-
- lp->pending_count = labels_needed;
+ lp->pending_count += labels_needed;
/*
* Invalidate any existing labels and requeue them as requests