summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_labelpool.c
diff options
context:
space:
mode:
authorDonatas Abraitis <donatas@opensourcerouting.org>2023-06-12 16:09:52 +0200
committerDonatas Abraitis <donatas@opensourcerouting.org>2023-06-20 19:50:10 +0200
commit0043ebab996e4a72541776d4a7753fca5f0de95b (patch)
tree683b87b5bbc0ae895c72a2b7f7a530dca688b89d /bgpd/bgp_labelpool.c
parenttests: Adjust tests for BGP LU labelpool output (diff)
downloadfrr-0043ebab996e4a72541776d4a7753fca5f0de95b.tar.xz
frr-0043ebab996e4a72541776d4a7753fca5f0de95b.zip
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.c119
1 files changed, 54 insertions, 65 deletions
diff --git a/bgpd/bgp_labelpool.c b/bgpd/bgp_labelpool.c
index 137e88ade..16314597c 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,