summaryrefslogtreecommitdiff
path: root/bgpd/bgp_labelpool.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_labelpool.c')
-rw-r--r--bgpd/bgp_labelpool.c388
1 files changed, 380 insertions, 8 deletions
diff --git a/bgpd/bgp_labelpool.c b/bgpd/bgp_labelpool.c
index e8d8167c35..001340be35 100644
--- a/bgpd/bgp_labelpool.c
+++ b/bgpd/bgp_labelpool.c
@@ -182,18 +182,18 @@ void bgp_lp_init(struct thread_master *master, struct labelpool *pool)
lp->callback_q->spec.max_retries = 0;
}
-/* check if a label callback was for a BGP LU path, and if so, unlock it */
+/* check if a label callback was for a BGP LU node, and if so, unlock it */
static void check_bgp_lu_cb_unlock(struct lp_lcb *lcb)
{
if (lcb->type == LP_TYPE_BGP_LU)
- bgp_path_info_unlock(lcb->labelid);
+ bgp_dest_unlock_node(lcb->labelid);
}
-/* check if a label callback was for a BGP LU path, and if so, lock it */
+/* check if a label callback was for a BGP LU node, and if so, lock it */
static void check_bgp_lu_cb_lock(struct lp_lcb *lcb)
{
if (lcb->type == LP_TYPE_BGP_LU)
- bgp_path_info_lock(lcb->labelid);
+ bgp_dest_lock_node(lcb->labelid);
}
void bgp_lp_finish(void)
@@ -356,7 +356,7 @@ void bgp_lp_get(
q->labelid = lcb->labelid;
q->allocated = true;
- /* if this is a LU request, lock path info before queueing */
+ /* if this is a LU request, lock node before queueing */
check_bgp_lu_cb_lock(lcb);
work_queue_add(lp->callback_q, q);
@@ -384,7 +384,7 @@ void bgp_lp_get(
sizeof(struct lp_fifo));
lf->lcb = *lcb;
- /* if this is a LU request, lock path info before queueing */
+ /* if this is a LU request, lock node before queueing */
check_bgp_lu_cb_lock(lcb);
lp_fifo_add_tail(&lp->requests, lf);
@@ -394,7 +394,7 @@ void bgp_lp_get(
return;
if (zclient_send_get_label_chunk(zclient, 0, LP_CHUNK_SIZE,
MPLS_LABEL_BASE_ANY)
- == ZCLIENT_SEND_FAILURE)
+ != ZCLIENT_SEND_FAILURE)
lp->pending_count += LP_CHUNK_SIZE;
}
}
@@ -461,6 +461,9 @@ void bgp_lp_event_chunk(uint8_t keep, uint32_t first, uint32_t last)
zlog_debug("%s: labelid %p: request no longer in effect",
__func__, labelid);
}
+ /* if this was a BGP_LU request, unlock node
+ */
+ check_bgp_lu_cb_unlock(lcb);
goto finishedrequest;
}
@@ -472,7 +475,7 @@ void bgp_lp_event_chunk(uint8_t keep, uint32_t first, uint32_t last)
__func__, labelid,
lcb->label, lcb->label, lcb);
}
- /* if this was a BGP_LU request, unlock path info node
+ /* if this was a BGP_LU request, unlock node
*/
check_bgp_lu_cb_unlock(lcb);
@@ -538,6 +541,7 @@ void bgp_lp_event_zebra_up(void)
struct lp_lcb *lcb;
int lm_init_ok;
+ lp->reconnect_count++;
/*
* Get label chunk allocation request dispatched to zebra
*/
@@ -607,3 +611,371 @@ void bgp_lp_event_zebra_up(void)
skiplist_delete_first(lp->inuse);
}
}
+
+DEFUN(show_bgp_labelpool_summary, show_bgp_labelpool_summary_cmd,
+ "show bgp labelpool summary [json]",
+ SHOW_STR BGP_STR
+ "BGP Labelpool information\n"
+ "BGP Labelpool summary\n" JSON_STR)
+{
+ bool uj = use_json(argc, argv);
+ json_object *json = NULL;
+
+ if (!lp) {
+ if (uj)
+ vty_out(vty, "{}\n");
+ else
+ vty_out(vty, "No existing BGP labelpool\n");
+ return (CMD_WARNING);
+ }
+
+ if (uj) {
+ json = json_object_new_object();
+ json_object_int_add(json, "Ledger", skiplist_count(lp->ledger));
+ json_object_int_add(json, "InUse", skiplist_count(lp->inuse));
+ json_object_int_add(json, "Requests",
+ lp_fifo_count(&lp->requests));
+ json_object_int_add(json, "LabelChunks", listcount(lp->chunks));
+ json_object_int_add(json, "Pending", lp->pending_count);
+ json_object_int_add(json, "Reconnects", lp->reconnect_count);
+ vty_out(vty, "%s\n",
+ json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ } else {
+ vty_out(vty, "Labelpool Summary\n");
+ vty_out(vty, "-----------------\n");
+ vty_out(vty, "%-13s %d\n",
+ "Ledger:", skiplist_count(lp->ledger));
+ vty_out(vty, "%-13s %d\n", "InUse:", skiplist_count(lp->inuse));
+ vty_out(vty, "%-13s %zu\n",
+ "Requests:", lp_fifo_count(&lp->requests));
+ vty_out(vty, "%-13s %d\n",
+ "LabelChunks:", listcount(lp->chunks));
+ vty_out(vty, "%-13s %d\n", "Pending:", lp->pending_count);
+ vty_out(vty, "%-13s %d\n", "Reconnects:", lp->reconnect_count);
+ }
+ return CMD_SUCCESS;
+}
+
+DEFUN(show_bgp_labelpool_ledger, show_bgp_labelpool_ledger_cmd,
+ "show bgp labelpool ledger [json]",
+ SHOW_STR BGP_STR
+ "BGP Labelpool information\n"
+ "BGP Labelpool ledger\n" JSON_STR)
+{
+ bool uj = use_json(argc, argv);
+ json_object *json = NULL, *json_elem = NULL;
+ struct lp_lcb *lcb = NULL;
+ struct bgp_dest *dest;
+ void *cursor = NULL;
+ const struct prefix *p;
+ int rc, count;
+
+ if (!lp) {
+ if (uj)
+ vty_out(vty, "{}\n");
+ else
+ vty_out(vty, "No existing BGP labelpool\n");
+ return (CMD_WARNING);
+ }
+
+ if (uj) {
+ count = skiplist_count(lp->ledger);
+ if (!count) {
+ vty_out(vty, "{}\n");
+ return CMD_SUCCESS;
+ }
+ json = json_object_new_array();
+ } else {
+ vty_out(vty, "Prefix Label\n");
+ vty_out(vty, "---------------------------\n");
+ }
+
+ for (rc = skiplist_next(lp->ledger, (void **)&dest, (void **)&lcb,
+ &cursor);
+ !rc; rc = skiplist_next(lp->ledger, (void **)&dest, (void **)&lcb,
+ &cursor)) {
+ if (uj) {
+ json_elem = json_object_new_object();
+ json_object_array_add(json, json_elem);
+ }
+ switch (lcb->type) {
+ case LP_TYPE_BGP_LU:
+ if (!CHECK_FLAG(dest->flags, BGP_NODE_LABEL_REQUESTED))
+ if (uj) {
+ json_object_string_add(
+ json_elem, "prefix", "INVALID");
+ json_object_int_add(json_elem, "label",
+ lcb->label);
+ } else
+ vty_out(vty, "%-18s %u\n",
+ "INVALID", lcb->label);
+ else {
+ char buf[PREFIX2STR_BUFFER];
+ p = bgp_dest_get_prefix(dest);
+ prefix2str(p, buf, sizeof(buf));
+ if (uj) {
+ json_object_string_add(json_elem,
+ "prefix", buf);
+ json_object_int_add(json_elem, "label",
+ lcb->label);
+ } else
+ vty_out(vty, "%-18s %u\n", buf,
+ lcb->label);
+ }
+ break;
+ case LP_TYPE_VRF:
+ if (uj) {
+ json_object_string_add(json_elem, "prefix",
+ "VRF");
+ json_object_int_add(json_elem, "label",
+ lcb->label);
+ } else
+ vty_out(vty, "%-18s %u\n", "VRF",
+ lcb->label);
+
+ break;
+ }
+ }
+ if (uj) {
+ vty_out(vty, "%s\n",
+ json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ }
+ return CMD_SUCCESS;
+}
+
+DEFUN(show_bgp_labelpool_inuse, show_bgp_labelpool_inuse_cmd,
+ "show bgp labelpool inuse [json]",
+ SHOW_STR BGP_STR
+ "BGP Labelpool information\n"
+ "BGP Labelpool inuse\n" JSON_STR)
+{
+ bool uj = use_json(argc, argv);
+ json_object *json = NULL, *json_elem = NULL;
+ struct bgp_dest *dest;
+ mpls_label_t label;
+ struct lp_lcb *lcb;
+ void *cursor = NULL;
+ const struct prefix *p;
+ int rc, count;
+
+ if (!lp) {
+ vty_out(vty, "No existing BGP labelpool\n");
+ return (CMD_WARNING);
+ }
+ if (!lp) {
+ if (uj)
+ vty_out(vty, "{}\n");
+ else
+ vty_out(vty, "No existing BGP labelpool\n");
+ return (CMD_WARNING);
+ }
+
+ if (uj) {
+ count = skiplist_count(lp->inuse);
+ if (!count) {
+ vty_out(vty, "{}\n");
+ return CMD_SUCCESS;
+ }
+ json = json_object_new_array();
+ } else {
+ vty_out(vty, "Prefix Label\n");
+ vty_out(vty, "---------------------------\n");
+ }
+ for (rc = skiplist_next(lp->inuse, (void **)&label, (void **)&dest,
+ &cursor);
+ !rc; rc = skiplist_next(lp->ledger, (void **)&label,
+ (void **)&dest, &cursor)) {
+ if (skiplist_search(lp->ledger, dest, (void **)&lcb))
+ continue;
+
+ if (uj) {
+ json_elem = json_object_new_object();
+ json_object_array_add(json, json_elem);
+ }
+
+ switch (lcb->type) {
+ case LP_TYPE_BGP_LU:
+ if (!CHECK_FLAG(dest->flags, BGP_NODE_LABEL_REQUESTED))
+ if (uj) {
+ json_object_string_add(
+ json_elem, "prefix", "INVALID");
+ json_object_int_add(json_elem, "label",
+ label);
+ } else
+ vty_out(vty, "INVALID %u\n",
+ label);
+ else {
+ char buf[PREFIX2STR_BUFFER];
+ p = bgp_dest_get_prefix(dest);
+ prefix2str(p, buf, sizeof(buf));
+ if (uj) {
+ json_object_string_add(json_elem,
+ "prefix", buf);
+ json_object_int_add(json_elem, "label",
+ label);
+ } else
+ vty_out(vty, "%-18s %u\n", buf,
+ label);
+ }
+ break;
+ case LP_TYPE_VRF:
+ if (uj) {
+ json_object_string_add(json_elem, "prefix",
+ "VRF");
+ json_object_int_add(json_elem, "label", label);
+ } else
+ vty_out(vty, "%-18s %u\n", "VRF",
+ label);
+ break;
+ }
+ }
+ if (uj) {
+ vty_out(vty, "%s\n",
+ json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ }
+ return CMD_SUCCESS;
+}
+
+DEFUN(show_bgp_labelpool_requests, show_bgp_labelpool_requests_cmd,
+ "show bgp labelpool requests [json]",
+ SHOW_STR BGP_STR
+ "BGP Labelpool information\n"
+ "BGP Labelpool requests\n" JSON_STR)
+{
+ bool uj = use_json(argc, argv);
+ json_object *json = NULL, *json_elem = NULL;
+ struct bgp_dest *dest;
+ const struct prefix *p;
+ char buf[PREFIX2STR_BUFFER];
+ struct lp_fifo *item, *next;
+ int count;
+
+ if (!lp) {
+ if (uj)
+ vty_out(vty, "{}\n");
+ else
+ vty_out(vty, "No existing BGP labelpool\n");
+ return (CMD_WARNING);
+ }
+
+ if (uj) {
+ count = lp_fifo_count(&lp->requests);
+ if (!count) {
+ vty_out(vty, "{}\n");
+ return CMD_SUCCESS;
+ }
+ json = json_object_new_array();
+ } else {
+ vty_out(vty, "Prefix \n");
+ vty_out(vty, "----------------\n");
+ }
+
+ for (item = lp_fifo_first(&lp->requests); item; item = next) {
+ next = lp_fifo_next_safe(&lp->requests, item);
+ dest = item->lcb.labelid;
+ if (uj) {
+ json_elem = json_object_new_object();
+ json_object_array_add(json, json_elem);
+ }
+ switch (item->lcb.type) {
+ case LP_TYPE_BGP_LU:
+ if (!CHECK_FLAG(dest->flags,
+ BGP_NODE_LABEL_REQUESTED)) {
+ if (uj)
+ json_object_string_add(
+ json_elem, "prefix", "INVALID");
+ else
+ vty_out(vty, "INVALID\n");
+ } else {
+ p = bgp_dest_get_prefix(dest);
+ prefix2str(p, buf, sizeof(buf));
+ if (uj)
+ json_object_string_add(json_elem,
+ "prefix", buf);
+ else
+ vty_out(vty, "%-18s\n", buf);
+ }
+ break;
+ case LP_TYPE_VRF:
+ if (uj)
+ json_object_string_add(json_elem, "prefix",
+ "VRF");
+ else
+ vty_out(vty, "VRF\n");
+ break;
+ }
+ }
+ if (uj) {
+ vty_out(vty, "%s\n",
+ json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ }
+ return CMD_SUCCESS;
+}
+
+DEFUN(show_bgp_labelpool_chunks, show_bgp_labelpool_chunks_cmd,
+ "show bgp labelpool chunks [json]",
+ SHOW_STR BGP_STR
+ "BGP Labelpool information\n"
+ "BGP Labelpool chunks\n" JSON_STR)
+{
+ bool uj = use_json(argc, argv);
+ json_object *json = NULL, *json_elem;
+ struct listnode *node;
+ struct lp_chunk *chunk;
+ int count;
+
+ if (!lp) {
+ if (uj)
+ vty_out(vty, "{}\n");
+ else
+ vty_out(vty, "No existing BGP labelpool\n");
+ return (CMD_WARNING);
+ }
+
+ if (uj) {
+ count = listcount(lp->chunks);
+ if (!count) {
+ vty_out(vty, "{}\n");
+ return CMD_SUCCESS;
+ }
+ json = json_object_new_array();
+ } else {
+ vty_out(vty, "First Last\n");
+ vty_out(vty, "--------------\n");
+ }
+
+ for (ALL_LIST_ELEMENTS_RO(lp->chunks, node, chunk)) {
+ if (uj) {
+ json_elem = json_object_new_object();
+ json_object_array_add(json, json_elem);
+ json_object_int_add(json_elem, "first", chunk->first);
+ json_object_int_add(json_elem, "last", chunk->last);
+ } else
+ vty_out(vty, "%-10u %-10u\n", chunk->first,
+ chunk->last);
+ }
+ if (uj) {
+ vty_out(vty, "%s\n",
+ json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ }
+ return CMD_SUCCESS;
+}
+
+void bgp_lp_vty_init(void)
+{
+ install_element(VIEW_NODE, &show_bgp_labelpool_summary_cmd);
+ install_element(VIEW_NODE, &show_bgp_labelpool_ledger_cmd);
+ install_element(VIEW_NODE, &show_bgp_labelpool_inuse_cmd);
+ install_element(VIEW_NODE, &show_bgp_labelpool_requests_cmd);
+ install_element(VIEW_NODE, &show_bgp_labelpool_chunks_cmd);
+}