zebra: add label chunk allocation in the dynamic block range

This commit adds support for the label chunk allocation in
the configured dynamic block range.

An additional check ensures the upper bound does not go
over the upper bound of the dynamic-block.
Otherwise, a chunk is created with the lower bound set
to the first label element available in the defined
range.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
This commit is contained in:
Philippe Guibert 2023-10-03 10:22:05 +02:00
parent 7a7c4bc80a
commit fccda55eac

View File

@ -400,6 +400,7 @@ assign_label_chunk(uint8_t proto, unsigned short instance, uint32_t session_id,
struct label_manager_chunk *lmc; struct label_manager_chunk *lmc;
struct listnode *node; struct listnode *node;
uint32_t prev_end = lbl_mgr.dynamic_block_start - 1; uint32_t prev_end = lbl_mgr.dynamic_block_start - 1;
struct label_manager_chunk *lmc_block_last = NULL;
/* handle chunks request with a specific base label /* handle chunks request with a specific base label
* - static label requests: BGP hardset value, Pathd * - static label requests: BGP hardset value, Pathd
@ -416,7 +417,9 @@ assign_label_chunk(uint8_t proto, unsigned short instance, uint32_t session_id,
for (ALL_LIST_ELEMENTS_RO(lbl_mgr.lc_list, node, lmc)) { for (ALL_LIST_ELEMENTS_RO(lbl_mgr.lc_list, node, lmc)) {
if (lmc->start <= prev_end) if (lmc->start <= prev_end)
continue; continue;
if (lmc->proto == NO_PROTO && lmc->end - lmc->start + 1 == size) { if (lmc->proto == NO_PROTO &&
lmc->end - lmc->start + 1 == size &&
lmc->end <= lbl_mgr.dynamic_block_end) {
lmc->proto = proto; lmc->proto = proto;
lmc->instance = instance; lmc->instance = instance;
lmc->session_id = session_id; lmc->session_id = session_id;
@ -426,7 +429,8 @@ assign_label_chunk(uint8_t proto, unsigned short instance, uint32_t session_id,
} }
/* check if we hadve a "hole" behind us that we can squeeze into /* check if we hadve a "hole" behind us that we can squeeze into
*/ */
if (lmc->start - prev_end > size) { if (lmc->start - prev_end > size &&
prev_end + 1 + size <= lbl_mgr.dynamic_block_end) {
lmc = create_label_chunk(proto, instance, session_id, lmc = create_label_chunk(proto, instance, session_id,
keep, prev_end + 1, keep, prev_end + 1,
prev_end + size, true); prev_end + size, true);
@ -434,17 +438,19 @@ assign_label_chunk(uint8_t proto, unsigned short instance, uint32_t session_id,
return lmc; return lmc;
} }
prev_end = lmc->end; prev_end = lmc->end;
/* check if we have a chunk that goes over the end block */
if (lmc->end > lbl_mgr.dynamic_block_end)
continue;
lmc_block_last = lmc;
} }
/* otherwise create a new one */ /* otherwise create a new one */
uint32_t start_free; uint32_t start_free;
if (list_isempty(lbl_mgr.lc_list)) if (lmc_block_last == NULL)
start_free = lbl_mgr.dynamic_block_start; start_free = lbl_mgr.dynamic_block_start;
else else
start_free = ((struct label_manager_chunk *)listgetdata( start_free = lmc_block_last->end + 1;
listtail(lbl_mgr.lc_list)))
->end
+ 1;
if (start_free > lbl_mgr.dynamic_block_end - size + 1) { if (start_free > lbl_mgr.dynamic_block_end - size + 1) {
flog_err(EC_ZEBRA_LM_EXHAUSTED_LABELS, flog_err(EC_ZEBRA_LM_EXHAUSTED_LABELS,