Skip to content

Commit 0043eba

Browse files
committed
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 <[email protected]>
1 parent 508dead commit 0043eba

File tree

6 files changed

+154
-118
lines changed

6 files changed

+154
-118
lines changed

bgpd/bgp_labelpool.c

+54-65
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
#include "linklist.h"
1616
#include "skiplist.h"
1717
#include "workqueue.h"
18-
#include "zclient.h"
1918
#include "mpls.h"
2019

2120
#include "bgpd/bgpd.h"
@@ -32,11 +31,6 @@
3231
#include "bgpd/bgp_labelpool_clippy.c"
3332

3433

35-
/*
36-
* Definitions and external declarations.
37-
*/
38-
extern struct zclient *zclient;
39-
4034
#if BGP_LABELPOOL_ENABLE_TESTS
4135
static void lptest_init(void);
4236
static void lptest_finish(void);
@@ -223,6 +217,8 @@ void bgp_lp_finish(void)
223217
{
224218
struct lp_fifo *lf;
225219
struct work_queue_item *item, *titem;
220+
struct listnode *node;
221+
struct lp_chunk *chunk;
226222

227223
#if BGP_LABELPOOL_ENABLE_TESTS
228224
lptest_finish();
@@ -236,6 +232,9 @@ void bgp_lp_finish(void)
236232
skiplist_free(lp->inuse);
237233
lp->inuse = NULL;
238234

235+
for (ALL_LIST_ELEMENTS_RO(lp->chunks, node, chunk))
236+
bgp_zebra_release_label_range(chunk->first, chunk->last);
237+
239238
list_delete(&lp->chunks);
240239

241240
while ((lf = lp_fifo_pop(&lp->requests))) {
@@ -448,15 +447,13 @@ void bgp_lp_get(
448447
lp_fifo_add_tail(&lp->requests, lf);
449448

450449
if (lp_fifo_count(&lp->requests) > lp->pending_count) {
451-
if (!zclient || zclient->sock < 0)
450+
if (!bgp_zebra_request_label_range(MPLS_LABEL_BASE_ANY,
451+
lp->next_chunksize))
452452
return;
453-
if (zclient_send_get_label_chunk(zclient, 0, lp->next_chunksize,
454-
MPLS_LABEL_BASE_ANY) !=
455-
ZCLIENT_SEND_FAILURE) {
456-
lp->pending_count += lp->next_chunksize;
457-
if ((lp->next_chunksize << 1) <= LP_CHUNK_SIZE_MAX)
458-
lp->next_chunksize <<= 1;
459-
}
453+
454+
lp->pending_count += lp->next_chunksize;
455+
if ((lp->next_chunksize << 1) <= LP_CHUNK_SIZE_MAX)
456+
lp->next_chunksize <<= 1;
460457
}
461458
}
462459

@@ -503,46 +500,12 @@ void bgp_lp_release(
503500
}
504501
}
505502

506-
/*
507-
* zebra response giving us a chunk of labels
508-
*/
509-
void bgp_lp_event_chunk(uint8_t keep, uint32_t first, uint32_t last)
503+
static void bgp_sync_label_manager(struct event *e)
510504
{
511-
struct lp_chunk *chunk;
512505
int debug = BGP_DEBUG(labelpool, LABELPOOL);
513506
struct lp_fifo *lf;
514-
uint32_t labelcount;
515-
516-
if (last < first) {
517-
flog_err(EC_BGP_LABEL,
518-
"%s: zebra label chunk invalid: first=%u, last=%u",
519-
__func__, first, last);
520-
return;
521-
}
522507

523-
chunk = XCALLOC(MTYPE_BGP_LABEL_CHUNK, sizeof(struct lp_chunk));
524-
525-
labelcount = last - first + 1;
526-
527-
chunk->first = first;
528-
chunk->last = last;
529-
chunk->nfree = labelcount;
530-
bf_init(chunk->allocated_map, labelcount);
531-
532-
/*
533-
* Optimize for allocation by adding the new (presumably larger)
534-
* chunk at the head of the list so it is examined first.
535-
*/
536-
listnode_add_head(lp->chunks, chunk);
537-
538-
lp->pending_count -= labelcount;
539-
540-
if (debug) {
541-
zlog_debug("%s: %zu pending requests", __func__,
542-
lp_fifo_count(&lp->requests));
543-
}
544-
545-
while (labelcount && (lf = lp_fifo_first(&lp->requests))) {
508+
while ((lf = lp_fifo_pop(&lp->requests))) {
546509

547510
struct lp_lcb *lcb;
548511
void *labelid = lf->lcb.labelid;
@@ -588,8 +551,6 @@ void bgp_lp_event_chunk(uint8_t keep, uint32_t first, uint32_t last)
588551
break;
589552
}
590553

591-
labelcount -= 1;
592-
593554
/*
594555
* we filled the request from local pool.
595556
* 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)
610571
work_queue_add(lp->callback_q, q);
611572

612573
finishedrequest:
613-
lp_fifo_del(&lp->requests, lf);
614574
XFREE(MTYPE_BGP_LABEL_FIFO, lf);
575+
}
576+
577+
event_add_timer(bm->master, bgp_sync_label_manager, NULL, 1,
578+
&bm->t_bgp_label_manager);
579+
}
580+
581+
void bgp_lp_event_chunk(uint32_t first, uint32_t last)
582+
{
583+
struct lp_chunk *chunk;
584+
uint32_t labelcount;
585+
586+
if (last < first) {
587+
flog_err(EC_BGP_LABEL,
588+
"%s: zebra label chunk invalid: first=%u, last=%u",
589+
__func__, first, last);
590+
return;
615591
}
592+
593+
chunk = XCALLOC(MTYPE_BGP_LABEL_CHUNK, sizeof(struct lp_chunk));
594+
595+
labelcount = last - first + 1;
596+
597+
chunk->first = first;
598+
chunk->last = last;
599+
chunk->nfree = labelcount;
600+
bf_init(chunk->allocated_map, labelcount);
601+
602+
/*
603+
* Optimize for allocation by adding the new (presumably larger)
604+
* chunk at the head of the list so it is examined first.
605+
*/
606+
listnode_add_head(lp->chunks, chunk);
607+
608+
lp->pending_count -= labelcount;
616609
}
617610

618611
/*
@@ -634,7 +627,6 @@ void bgp_lp_event_zebra_up(void)
634627
unsigned int chunks_needed;
635628
void *labelid;
636629
struct lp_lcb *lcb;
637-
int lm_init_ok;
638630

639631
lp->reconnect_count++;
640632
/*
@@ -654,22 +646,16 @@ void bgp_lp_event_zebra_up(void)
654646
chunks_needed = (labels_needed / lp->next_chunksize) + 1;
655647
labels_needed = chunks_needed * lp->next_chunksize;
656648

657-
lm_init_ok = lm_label_manager_connect(zclient, 1) == 0;
658-
659-
if (!lm_init_ok) {
660-
zlog_err("%s: label manager connection error", __func__);
661-
return;
662-
}
663-
664-
zclient_send_get_label_chunk(zclient, 0, labels_needed,
665-
MPLS_LABEL_BASE_ANY);
666-
lp->pending_count = labels_needed;
667-
668649
/*
669650
* Invalidate current list of chunks
670651
*/
671652
list_delete_all_node(lp->chunks);
672653

654+
if (!bgp_zebra_request_label_range(MPLS_LABEL_BASE_ANY, labels_needed))
655+
return;
656+
657+
lp->pending_count = labels_needed;
658+
673659
/*
674660
* Invalidate any existing labels and requeue them as requests
675661
*/
@@ -712,6 +698,9 @@ void bgp_lp_event_zebra_up(void)
712698

713699
skiplist_delete_first(lp->inuse);
714700
}
701+
702+
event_add_timer(bm->master, bgp_sync_label_manager, NULL, 1,
703+
&bm->t_bgp_label_manager);
715704
}
716705

717706
DEFUN(show_bgp_labelpool_summary, show_bgp_labelpool_summary_cmd,

bgpd/bgp_labelpool.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ extern void bgp_lp_finish(void);
3838
extern void bgp_lp_get(int type, void *labelid,
3939
int (*cbfunc)(mpls_label_t label, void *labelid, bool allocated));
4040
extern void bgp_lp_release(int type, void *labelid, mpls_label_t label);
41-
extern void bgp_lp_event_chunk(uint8_t keep, uint32_t first, uint32_t last);
41+
extern void bgp_lp_event_chunk(uint32_t first, uint32_t last);
4242
extern void bgp_lp_event_zebra_down(void);
4343
extern void bgp_lp_event_zebra_up(void);
4444
extern void bgp_lp_vty_init(void);

0 commit comments

Comments
 (0)