mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-13 19:39:28 +00:00
bgpd: add show commands for bgp labelpool
These commands allow the bgp labelpool lists and counts to be viewed for debug purposes. Signed-off-by: Pat Ruddy <pat@voltanet.io>
This commit is contained in:
parent
a7f52fb0f7
commit
e3ea65039e
@ -538,6 +538,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 +608,370 @@ 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_path_info *pi;
|
||||
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 **)&pi, (void **)&lcb,
|
||||
&cursor);
|
||||
!rc; rc = skiplist_next(lp->ledger, (void **)&pi, (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(pi->flags, BGP_PATH_VALID))
|
||||
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(pi->net);
|
||||
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_path_info *pi;
|
||||
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 **)&pi,
|
||||
&cursor);
|
||||
!rc; rc = skiplist_next(lp->ledger, (void **)&label, (void **)&pi,
|
||||
&cursor)) {
|
||||
if (skiplist_search(lp->ledger, pi, (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(pi->flags, BGP_PATH_VALID))
|
||||
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(pi->net);
|
||||
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_path_info *pi;
|
||||
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);
|
||||
pi = 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(pi->flags, BGP_PATH_VALID)) {
|
||||
if (uj)
|
||||
json_object_string_add(
|
||||
json_elem, "prefix", "INVALID");
|
||||
else
|
||||
vty_out(vty, "INVALID\n");
|
||||
} else {
|
||||
p = bgp_dest_get_prefix(pi->net);
|
||||
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);
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ struct labelpool {
|
||||
struct lp_fifo_head requests; /* blocked on zebra */
|
||||
struct work_queue *callback_q;
|
||||
uint32_t pending_count; /* requested from zebra */
|
||||
uint32_t reconnect_count; /* zebra reconnections */
|
||||
};
|
||||
|
||||
extern void bgp_lp_init(struct thread_master *master, struct labelpool *pool);
|
||||
@ -50,5 +51,6 @@ extern void bgp_lp_release(int type, void *labelid, mpls_label_t label);
|
||||
extern void bgp_lp_event_chunk(uint8_t keep, uint32_t first, uint32_t last);
|
||||
extern void bgp_lp_event_zebra_down(void);
|
||||
extern void bgp_lp_event_zebra_up(void);
|
||||
extern void bgp_lp_vty_init(void);
|
||||
|
||||
#endif /* _FRR_BGP_LABELPOOL_H */
|
||||
|
@ -7613,6 +7613,8 @@ void bgp_init(unsigned short instance)
|
||||
/* BFD init */
|
||||
bgp_bfd_init();
|
||||
|
||||
bgp_lp_vty_init();
|
||||
|
||||
cmd_variable_handler_register(bgp_viewvrf_var_handlers);
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@ vtysh_scan += \
|
||||
bgpd/bgp_evpn_mh.c \
|
||||
bgpd/bgp_evpn_vty.c \
|
||||
bgpd/bgp_filter.c \
|
||||
bgpd/bgp_labelpool.c \
|
||||
bgpd/bgp_mplsvpn.c \
|
||||
bgpd/bgp_nexthop.c \
|
||||
bgpd/bgp_route.c \
|
||||
|
@ -3373,6 +3373,32 @@ attribute.
|
||||
|
||||
If ``json`` option is specified, output is displayed in JSON format.
|
||||
|
||||
.. index:: show bgp labelpool <chunks|inuse|ledger|requests|summary> [json]
|
||||
.. clicmd:: show bgp labelpool <chunks|inuse|ledger|requests|summary> [json]
|
||||
|
||||
These commands display information about the BGP labelpool used for
|
||||
the association of MPLS labels with routes for L3VPN and Labeled Unicast
|
||||
|
||||
If ``chunks`` option is specified, output shows the current list of label
|
||||
chunks granted to BGP by Zebra, indicating the start and end label in
|
||||
each chunk
|
||||
|
||||
If ``inuse`` option is specified, output shows the current inuse list of
|
||||
label to prefix mappings
|
||||
|
||||
If ``ledger`` option is specified, output shows ledger list of all
|
||||
label requests made per prefix
|
||||
|
||||
If ``requests`` option is specified, output shows current list of label
|
||||
requests which have not yet been fulfilled by the labelpool
|
||||
|
||||
If ``summary`` option is specified, output is a summary of the counts for
|
||||
the chunks, inuse, ledger and requests list along with the count of
|
||||
outstanding chunk requests to Zebra and the nummber of zebra reconnects
|
||||
that have happened
|
||||
|
||||
If ``json`` option is specified, output is displayed in JSON format.
|
||||
|
||||
.. _bgp-display-routes-by-lcommunity:
|
||||
|
||||
Displaying Routes by Large Community Attribute
|
||||
|
Loading…
Reference in New Issue
Block a user