diff options
| author | G. Paul Ziemba <paulz@labn.net> | 2018-04-07 11:13:07 -0700 |
|---|---|---|
| committer | G. Paul Ziemba <paulz@labn.net> | 2018-04-11 23:18:28 -0700 |
| commit | 955bfd984ffdf25de5748c404ee9796de7fd30be (patch) | |
| tree | 2cbf34a64c17bd530af22eb4f8162cd8bb67a66d /bgpd/bgp_zebra.c | |
| parent | bb04824d89541151f8636e846cf3ddafee5fc603 (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 'bgpd/bgp_zebra.c')
| -rw-r--r-- | bgpd/bgp_zebra.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 023a866315..30ec0e96a6 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -55,6 +55,7 @@ #endif #include "bgpd/bgp_evpn.h" #include "bgpd/bgp_mplsvpn.h" +#include "bgpd/bgp_labelpool.h" /* All information about zebra. */ struct zclient *zclient = NULL; @@ -1876,6 +1877,9 @@ static void bgp_zebra_connected(struct zclient *zclient) /* Send the client registration */ bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER); + /* tell label pool that zebra is connected */ + lp_event_zebra_up(); + /* TODO - What if we have peers and networks configured, do we have to * kick-start them? */ @@ -2042,6 +2046,41 @@ static void bgp_zebra_process_local_ip_prefix(int cmd, struct zclient *zclient, } } +static void bgp_zebra_process_label_chunk( + int cmd, + struct zclient *zclient, + zebra_size_t length, + vrf_id_t vrf_id) +{ + struct stream *s = NULL; + uint8_t response_keep; + uint32_t first; + uint32_t last; + + s = zclient->ibuf; + STREAM_GETC(s, response_keep); + STREAM_GETL(s, first); + STREAM_GETL(s, last); + + if (first > last || + first < MPLS_LABEL_UNRESERVED_MIN || + last > MPLS_LABEL_UNRESERVED_MAX) { + + zlog_err("%s: Invalid Label chunk: %u - %u", + __func__, first, last); + return; + } + if (BGP_DEBUG(zebra, ZEBRA)) { + zlog_debug("Label Chunk assign: %u - %u (%u) ", + first, last, response_keep); + } + + lp_event_chunk(response_keep, first, last); + +stream_failure: /* for STREAM_GETX */ + return; +} + extern struct zebra_privs_t bgpd_privs; void bgp_zebra_init(struct thread_master *master) @@ -2076,6 +2115,7 @@ void bgp_zebra_init(struct thread_master *master) zclient->local_l3vni_del = bgp_zebra_process_local_l3vni; zclient->local_ip_prefix_add = bgp_zebra_process_local_ip_prefix; zclient->local_ip_prefix_del = bgp_zebra_process_local_ip_prefix; + zclient->label_chunk = bgp_zebra_process_label_chunk; } void bgp_zebra_destroy(void) |
