summaryrefslogtreecommitdiff
path: root/lib/zclient.c
diff options
context:
space:
mode:
authorG. Paul Ziemba <paulz@labn.net>2018-04-07 11:13:07 -0700
committerG. Paul Ziemba <paulz@labn.net>2018-04-11 23:18:28 -0700
commit955bfd984ffdf25de5748c404ee9796de7fd30be (patch)
tree2cbf34a64c17bd530af22eb4f8162cd8bb67a66d /lib/zclient.c
parentbb04824d89541151f8636e846cf3ddafee5fc603 (diff)
bgpd: dynamic mpls label pool
MPLS label pool backed by allocations from the zebra label manager. A caller requests a label (e.g., in support of an "auto" label specification in the CLI) via lp_get(), supplying a unique ID and a callback function. The callback function is invoked at a later time with the unique ID and a label value to inform the requestor of the assigned label. Requestors may release their labels back to the pool via lp_release(). The label pool is stocked with labels allocated by the zebra label manager. The interaction with zebra is asynchronous so that bgpd is not blocked while awaiting a label allocation from zebra. The label pool implementation allows for bgpd operation before (or without) zebra, and gracefully handles loss and reconnection of zebra. Of course, before initial connection with zebra, no labels are assigned to requestors. If the zebra connection is lost and regained, callbacks to requestors will invalidate old assignments and then assign new labels. Signed-off-by: G. Paul Ziemba <paulz@labn.net>
Diffstat (limited to 'lib/zclient.c')
-rw-r--r--lib/zclient.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/lib/zclient.c b/lib/zclient.c
index d23f62dcd7..07029c1f5d 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -1991,6 +1991,40 @@ int lm_label_manager_connect(struct zclient *zclient)
return (int)result;
}
+/*
+ * Asynchronous label chunk request
+ *
+ * @param zclient Zclient used to connect to label manager (zebra)
+ * @param keep Avoid garbage collection
+ * @param chunk_size Amount of labels requested
+ * @result 0 on success, -1 otherwise
+ */
+int zclient_send_get_label_chunk(
+ struct zclient *zclient,
+ uint8_t keep,
+ uint32_t chunk_size)
+{
+ struct stream *s;
+
+ if (zclient_debug)
+ zlog_debug("Getting Label Chunk");
+
+ if (zclient->sock < 0)
+ return -1;
+
+ s = zclient->obuf;
+ stream_reset(s);
+
+ zclient_create_header(s, ZEBRA_GET_LABEL_CHUNK, VRF_DEFAULT);
+ stream_putc(s, keep);
+ stream_putl(s, chunk_size);
+
+ /* Put length at the first point of the stream. */
+ stream_putw_at(s, 0, stream_get_endp(s));
+
+ return zclient_send_message(zclient);
+}
+
/**
* Function to request a label chunk in a syncronous way
*
@@ -2604,6 +2638,12 @@ static int zclient_read(struct thread *thread)
if (zclient->rule_notify_owner)
(*zclient->rule_notify_owner)(command, zclient, length,
vrf_id);
+ break;
+ case ZEBRA_GET_LABEL_CHUNK:
+ if (zclient->label_chunk)
+ (*zclient->label_chunk)(command, zclient, length,
+ vrf_id);
+ break;
default:
break;
}