diff options
| author | Donatas Abraitis <donatas@opensourcerouting.org> | 2023-06-12 17:09:52 +0300 | 
|---|---|---|
| committer | Donatas Abraitis <donatas@opensourcerouting.org> | 2023-06-20 20:50:10 +0300 | 
| commit | 0043ebab996e4a72541776d4a7753fca5f0de95b (patch) | |
| tree | 683b87b5bbc0ae895c72a2b7f7a530dca688b89d /bgpd/bgp_labelpool.c | |
| parent | 508deadf3d1b82e1ecf9fe1a133234f5597951d9 (diff) | |
bgpd: Use synchronous way to get labels from Zebra
Both the label manager and table manager zapi code send data requests via zapi
to zebra and then immediately listen for a response from zebra. The problem here
is of course that the listen part is throwing away any zapi command that is not
the one it is looking for.
ISIS/OSPF and PIM all have synchronous abilities via zapi, which they all
do through a special zapi connection to zebra. BGP needs to follow this model
as well. Additionally the new zclient_sync connection that should be created,
a once a second timer should wake up and read any data on the socket to
prevent problems too much data accumulating in the socket.
```
r3# sh bgp labelpool summary
Labelpool Summary
-----------------
Ledger:       3
InUse:        3
Requests:     0
LabelChunks:  1
Pending:      128
Reconnects:   1
r3# sh bgp labelpool inuse
Prefix                Label
---------------------------
10.0.0.1/32           16
192.168.31.0/24       17
192.168.32.0/24       18
r3#
```
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
Diffstat (limited to 'bgpd/bgp_labelpool.c')
| -rw-r--r-- | bgpd/bgp_labelpool.c | 119 | 
1 files changed, 54 insertions, 65 deletions
diff --git a/bgpd/bgp_labelpool.c b/bgpd/bgp_labelpool.c index 137e88adea..16314597c7 100644 --- a/bgpd/bgp_labelpool.c +++ b/bgpd/bgp_labelpool.c @@ -15,7 +15,6 @@  #include "linklist.h"  #include "skiplist.h"  #include "workqueue.h" -#include "zclient.h"  #include "mpls.h"  #include "bgpd/bgpd.h" @@ -32,11 +31,6 @@  #include "bgpd/bgp_labelpool_clippy.c" -/* - * Definitions and external declarations. - */ -extern struct zclient *zclient; -  #if BGP_LABELPOOL_ENABLE_TESTS  static void lptest_init(void);  static void lptest_finish(void); @@ -223,6 +217,8 @@ void bgp_lp_finish(void)  {  	struct lp_fifo *lf;  	struct work_queue_item *item, *titem; +	struct listnode *node; +	struct lp_chunk *chunk;  #if BGP_LABELPOOL_ENABLE_TESTS  	lptest_finish(); @@ -236,6 +232,9 @@ void bgp_lp_finish(void)  	skiplist_free(lp->inuse);  	lp->inuse = NULL; +	for (ALL_LIST_ELEMENTS_RO(lp->chunks, node, chunk)) +		bgp_zebra_release_label_range(chunk->first, chunk->last); +  	list_delete(&lp->chunks);  	while ((lf = lp_fifo_pop(&lp->requests))) { @@ -448,15 +447,13 @@ void bgp_lp_get(  	lp_fifo_add_tail(&lp->requests, lf);  	if (lp_fifo_count(&lp->requests) > lp->pending_count) { -		if (!zclient || zclient->sock < 0) +		if (!bgp_zebra_request_label_range(MPLS_LABEL_BASE_ANY, +						   lp->next_chunksize))  			return; -		if (zclient_send_get_label_chunk(zclient, 0, lp->next_chunksize, -						 MPLS_LABEL_BASE_ANY) != -		    ZCLIENT_SEND_FAILURE) { -			lp->pending_count += lp->next_chunksize; -			if ((lp->next_chunksize << 1) <= LP_CHUNK_SIZE_MAX) -				lp->next_chunksize <<= 1; -		} + +		lp->pending_count += lp->next_chunksize; +		if ((lp->next_chunksize << 1) <= LP_CHUNK_SIZE_MAX) +			lp->next_chunksize <<= 1;  	}  } @@ -503,46 +500,12 @@ void bgp_lp_release(  	}  } -/* - * zebra response giving us a chunk of labels - */ -void bgp_lp_event_chunk(uint8_t keep, uint32_t first, uint32_t last) +static void bgp_sync_label_manager(struct event *e)  { -	struct lp_chunk *chunk;  	int debug = BGP_DEBUG(labelpool, LABELPOOL);  	struct lp_fifo *lf; -	uint32_t labelcount; - -	if (last < first) { -		flog_err(EC_BGP_LABEL, -			 "%s: zebra label chunk invalid: first=%u, last=%u", -			 __func__, first, last); -		return; -	} -	chunk = XCALLOC(MTYPE_BGP_LABEL_CHUNK, sizeof(struct lp_chunk)); - -	labelcount = last - first + 1; - -	chunk->first = first; -	chunk->last = last; -	chunk->nfree = labelcount; -	bf_init(chunk->allocated_map, labelcount); - -	/* -	 * Optimize for allocation by adding the new (presumably larger) -	 * chunk at the head of the list so it is examined first. -	 */ -	listnode_add_head(lp->chunks, chunk); - -	lp->pending_count -= labelcount; - -	if (debug) { -		zlog_debug("%s: %zu pending requests", __func__, -			lp_fifo_count(&lp->requests)); -	} - -	while (labelcount && (lf = lp_fifo_first(&lp->requests))) { +	while ((lf = lp_fifo_pop(&lp->requests))) {  		struct lp_lcb *lcb;  		void *labelid = lf->lcb.labelid; @@ -588,8 +551,6 @@ void bgp_lp_event_chunk(uint8_t keep, uint32_t first, uint32_t last)  			break;  		} -		labelcount -= 1; -  		/*  		 * we filled the request from local pool.  		 * Enqueue response work item with new label. @@ -610,9 +571,41 @@ void bgp_lp_event_chunk(uint8_t keep, uint32_t first, uint32_t last)  		work_queue_add(lp->callback_q, q);  finishedrequest: -		lp_fifo_del(&lp->requests, lf);  		XFREE(MTYPE_BGP_LABEL_FIFO, lf); +} + +event_add_timer(bm->master, bgp_sync_label_manager, NULL, 1, +		&bm->t_bgp_label_manager); +} + +void bgp_lp_event_chunk(uint32_t first, uint32_t last) +{ +	struct lp_chunk *chunk; +	uint32_t labelcount; + +	if (last < first) { +		flog_err(EC_BGP_LABEL, +			 "%s: zebra label chunk invalid: first=%u, last=%u", +			 __func__, first, last); +		return;  	} + +	chunk = XCALLOC(MTYPE_BGP_LABEL_CHUNK, sizeof(struct lp_chunk)); + +	labelcount = last - first + 1; + +	chunk->first = first; +	chunk->last = last; +	chunk->nfree = labelcount; +	bf_init(chunk->allocated_map, labelcount); + +	/* +	 * Optimize for allocation by adding the new (presumably larger) +	 * chunk at the head of the list so it is examined first. +	 */ +	listnode_add_head(lp->chunks, chunk); + +	lp->pending_count -= labelcount;  }  /* @@ -634,7 +627,6 @@ void bgp_lp_event_zebra_up(void)  	unsigned int chunks_needed;  	void *labelid;  	struct lp_lcb *lcb; -	int lm_init_ok;  	lp->reconnect_count++;  	/* @@ -654,22 +646,16 @@ void bgp_lp_event_zebra_up(void)  	chunks_needed = (labels_needed / lp->next_chunksize) + 1;  	labels_needed = chunks_needed * lp->next_chunksize; -	lm_init_ok = lm_label_manager_connect(zclient, 1) == 0; - -	if (!lm_init_ok) { -		zlog_err("%s: label manager connection error", __func__); -		return; -	} - -	zclient_send_get_label_chunk(zclient, 0, labels_needed, -				     MPLS_LABEL_BASE_ANY); -	lp->pending_count = labels_needed; -  	/*  	 * Invalidate current list of chunks  	 */  	list_delete_all_node(lp->chunks); +	if (!bgp_zebra_request_label_range(MPLS_LABEL_BASE_ANY, labels_needed)) +		return; + +	lp->pending_count = labels_needed; +  	/*  	 * Invalidate any existing labels and requeue them as requests  	 */ @@ -712,6 +698,9 @@ void bgp_lp_event_zebra_up(void)  		skiplist_delete_first(lp->inuse);  	} + +	event_add_timer(bm->master, bgp_sync_label_manager, NULL, 1, +			&bm->t_bgp_label_manager);  }  DEFUN(show_bgp_labelpool_summary, show_bgp_labelpool_summary_cmd,  | 
