mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-04-29 14:33:09 +00:00
pbrd, lib: opt. json for show pbr nexthop-group
Signed-off-by: Wesley Coakley <wcoakley@cumulusnetworks.com>
This commit is contained in:
parent
1a8cafe19c
commit
010dd8edcb
@ -56,10 +56,11 @@ listing of ECMP nexthops used to forward packets for when a pbr-map is matched.
|
|||||||
Showing Nexthop Group Information
|
Showing Nexthop Group Information
|
||||||
---------------------------------
|
---------------------------------
|
||||||
|
|
||||||
.. clicmd:: show pbr nexthop-groups [NAME]
|
.. clicmd:: show pbr nexthop-groups [NAME] [json]
|
||||||
|
|
||||||
Display information on a PBR nexthop-group. If ``NAME`` is omitted, all
|
Display information on a PBR nexthop-group. If ``NAME`` is omitted, all
|
||||||
nexthop groups are shown.
|
nexthop groups are shown. Setting ``json`` will provide the same information
|
||||||
|
in a predictable and parsable format.
|
||||||
|
|
||||||
.. _pbr-maps:
|
.. _pbr-maps:
|
||||||
|
|
||||||
|
@ -996,6 +996,60 @@ void nexthop_group_write_nexthop(struct vty *vty, struct nexthop *nh)
|
|||||||
vty_out(vty, "\n");
|
vty_out(vty, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nexthop_group_json_nexthop(json_object *j, struct nexthop *nh)
|
||||||
|
{
|
||||||
|
char buf[100];
|
||||||
|
struct vrf *vrf;
|
||||||
|
|
||||||
|
switch (nh->type) {
|
||||||
|
case NEXTHOP_TYPE_IFINDEX:
|
||||||
|
json_object_string_add(j, "nexthop",
|
||||||
|
ifindex2ifname(nh->ifindex, nh->vrf_id));
|
||||||
|
break;
|
||||||
|
case NEXTHOP_TYPE_IPV4:
|
||||||
|
json_object_string_add(j, "nexthop", inet_ntoa(nh->gate.ipv4));
|
||||||
|
break;
|
||||||
|
case NEXTHOP_TYPE_IPV4_IFINDEX:
|
||||||
|
json_object_string_add(j, "nexthop", inet_ntoa(nh->gate.ipv4));
|
||||||
|
json_object_string_add(j, "vrfId",
|
||||||
|
ifindex2ifname(nh->ifindex, nh->vrf_id));
|
||||||
|
break;
|
||||||
|
case NEXTHOP_TYPE_IPV6:
|
||||||
|
json_object_string_add(
|
||||||
|
j, "nexthop",
|
||||||
|
inet_ntop(AF_INET6, &nh->gate.ipv6, buf, sizeof(buf)));
|
||||||
|
break;
|
||||||
|
case NEXTHOP_TYPE_IPV6_IFINDEX:
|
||||||
|
json_object_string_add(
|
||||||
|
j, "nexthop",
|
||||||
|
inet_ntop(AF_INET6, &nh->gate.ipv6, buf, sizeof(buf)));
|
||||||
|
json_object_string_add(j, "vrfId",
|
||||||
|
ifindex2ifname(nh->ifindex, nh->vrf_id));
|
||||||
|
break;
|
||||||
|
case NEXTHOP_TYPE_BLACKHOLE:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nh->vrf_id != VRF_DEFAULT) {
|
||||||
|
vrf = vrf_lookup_by_id(nh->vrf_id);
|
||||||
|
json_object_string_add(j, "nexthopVrf", vrf->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nh->nh_label && nh->nh_label->num_labels > 0) {
|
||||||
|
char buf[200];
|
||||||
|
|
||||||
|
mpls_label2str(nh->nh_label->num_labels, nh->nh_label->label,
|
||||||
|
buf, sizeof(buf), 0);
|
||||||
|
json_object_string_add(j, "label", buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nh->weight)
|
||||||
|
json_object_int_add(j, "weight", nh->weight);
|
||||||
|
|
||||||
|
if (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_HAS_BACKUP))
|
||||||
|
json_object_int_add(j, "backupIdx", nh->backup_idx);
|
||||||
|
}
|
||||||
|
|
||||||
static void nexthop_group_write_nexthop_internal(struct vty *vty,
|
static void nexthop_group_write_nexthop_internal(struct vty *vty,
|
||||||
struct nexthop_hold *nh)
|
struct nexthop_hold *nh)
|
||||||
{
|
{
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#define __NEXTHOP_GROUP__
|
#define __NEXTHOP_GROUP__
|
||||||
|
|
||||||
#include <vty.h>
|
#include <vty.h>
|
||||||
|
#include "json.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -136,6 +137,8 @@ extern struct nexthop_group_cmd *nhgc_find(const char *name);
|
|||||||
|
|
||||||
extern void nexthop_group_write_nexthop(struct vty *vty, struct nexthop *nh);
|
extern void nexthop_group_write_nexthop(struct vty *vty, struct nexthop *nh);
|
||||||
|
|
||||||
|
extern void nexthop_group_json_nexthop(json_object *j, struct nexthop *nh);
|
||||||
|
|
||||||
/* Return the number of nexthops in this nhg */
|
/* Return the number of nexthops in this nhg */
|
||||||
extern uint8_t nexthop_group_nexthop_num(const struct nexthop_group *nhg);
|
extern uint8_t nexthop_group_nexthop_num(const struct nexthop_group *nhg);
|
||||||
extern uint8_t
|
extern uint8_t
|
||||||
|
@ -1030,8 +1030,22 @@ static void pbr_nht_show_nhg_nexthops(struct hash_bucket *b, void *data)
|
|||||||
nexthop_group_write_nexthop(vty, pnhc->nexthop);
|
nexthop_group_write_nexthop(vty, pnhc->nexthop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void pbr_nht_json_nhg_nexthops(struct hash_bucket *b, void *data)
|
||||||
|
{
|
||||||
|
struct pbr_nexthop_cache *pnhc = b->data;
|
||||||
|
json_object *all_hops = data;
|
||||||
|
json_object *this_hop;
|
||||||
|
|
||||||
|
this_hop = json_object_new_object();
|
||||||
|
json_object_boolean_add(this_hop, "valid", pnhc->valid);
|
||||||
|
nexthop_group_json_nexthop(this_hop, pnhc->nexthop);
|
||||||
|
|
||||||
|
json_object_array_add(all_hops, this_hop);
|
||||||
|
}
|
||||||
|
|
||||||
struct pbr_nht_show {
|
struct pbr_nht_show {
|
||||||
struct vty *vty;
|
struct vty *vty;
|
||||||
|
json_object *json;
|
||||||
const char *name;
|
const char *name;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1051,6 +1065,36 @@ static void pbr_nht_show_nhg(struct hash_bucket *b, void *data)
|
|||||||
hash_iterate(pnhgc->nhh, pbr_nht_show_nhg_nexthops, vty);
|
hash_iterate(pnhgc->nhh, pbr_nht_show_nhg_nexthops, vty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void pbr_nht_json_nhg(struct hash_bucket *b, void *data)
|
||||||
|
{
|
||||||
|
struct pbr_nexthop_group_cache *pnhgc = b->data;
|
||||||
|
struct pbr_nht_show *pns = data;
|
||||||
|
json_object *j, *this_group, *group_hops;
|
||||||
|
|
||||||
|
if (pns->name && strcmp(pns->name, pnhgc->name) != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
j = pns->json;
|
||||||
|
this_group = json_object_new_object();
|
||||||
|
|
||||||
|
if (!j || !this_group)
|
||||||
|
return;
|
||||||
|
|
||||||
|
json_object_string_add(this_group, "name", pnhgc->name);
|
||||||
|
json_object_int_add(this_group, "id", pnhgc->table_id);
|
||||||
|
json_object_boolean_add(this_group, "valid", pnhgc->valid);
|
||||||
|
json_object_boolean_add(this_group, "installed", pnhgc->installed);
|
||||||
|
|
||||||
|
group_hops = json_object_new_array();
|
||||||
|
|
||||||
|
if (group_hops) {
|
||||||
|
hash_iterate(pnhgc->nhh, pbr_nht_json_nhg_nexthops, group_hops);
|
||||||
|
json_object_object_add(this_group, "nexthops", group_hops);
|
||||||
|
}
|
||||||
|
|
||||||
|
json_object_object_add(j, pnhgc->name, this_group);
|
||||||
|
}
|
||||||
|
|
||||||
void pbr_nht_show_nexthop_group(struct vty *vty, const char *name)
|
void pbr_nht_show_nexthop_group(struct vty *vty, const char *name)
|
||||||
{
|
{
|
||||||
struct pbr_nht_show pns;
|
struct pbr_nht_show pns;
|
||||||
@ -1061,6 +1105,16 @@ void pbr_nht_show_nexthop_group(struct vty *vty, const char *name)
|
|||||||
hash_iterate(pbr_nhg_hash, pbr_nht_show_nhg, &pns);
|
hash_iterate(pbr_nhg_hash, pbr_nht_show_nhg, &pns);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pbr_nht_json_nexthop_group(json_object *j, const char *name)
|
||||||
|
{
|
||||||
|
struct pbr_nht_show pns;
|
||||||
|
|
||||||
|
pns.name = name;
|
||||||
|
pns.json = j;
|
||||||
|
|
||||||
|
hash_iterate(pbr_nhg_hash, pbr_nht_json_nhg, &pns);
|
||||||
|
}
|
||||||
|
|
||||||
void pbr_nht_init(void)
|
void pbr_nht_init(void)
|
||||||
{
|
{
|
||||||
pbr_nhg_hash = hash_create_size(
|
pbr_nhg_hash = hash_create_size(
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include <lib/nexthop_group.h>
|
#include <lib/nexthop_group.h>
|
||||||
|
|
||||||
#include "pbr_map.h"
|
#include "pbr_map.h"
|
||||||
|
#include "json.h"
|
||||||
|
|
||||||
#define PBR_NHC_NAMELEN PBR_MAP_NAMELEN + 10
|
#define PBR_NHC_NAMELEN PBR_MAP_NAMELEN + 10
|
||||||
|
|
||||||
@ -112,6 +113,7 @@ extern char *pbr_nht_nexthop_make_name(char *name, size_t l, uint32_t seqno,
|
|||||||
char *buffer);
|
char *buffer);
|
||||||
|
|
||||||
extern void pbr_nht_show_nexthop_group(struct vty *vty, const char *name);
|
extern void pbr_nht_show_nexthop_group(struct vty *vty, const char *name);
|
||||||
|
extern void pbr_nht_json_nexthop_group(json_object *j, const char *name);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When we get a callback from zebra about a nexthop changing
|
* When we get a callback from zebra about a nexthop changing
|
||||||
|
@ -733,14 +733,30 @@ DEFPY (show_pbr_map,
|
|||||||
|
|
||||||
DEFPY(show_pbr_nexthop_group,
|
DEFPY(show_pbr_nexthop_group,
|
||||||
show_pbr_nexthop_group_cmd,
|
show_pbr_nexthop_group_cmd,
|
||||||
"show pbr nexthop-groups [WORD$word]",
|
"show pbr nexthop-groups [WORD$word] [json$json]",
|
||||||
SHOW_STR
|
SHOW_STR
|
||||||
PBR_STR
|
PBR_STR
|
||||||
"Nexthop Groups\n"
|
"Nexthop Groups\n"
|
||||||
"Optional Name of the nexthop group\n")
|
"Optional Name of the nexthop group\n"
|
||||||
|
JSON_STR)
|
||||||
{
|
{
|
||||||
|
json_object *j = NULL;
|
||||||
|
|
||||||
|
if (json)
|
||||||
|
j = json_object_new_object();
|
||||||
|
|
||||||
|
if (j) {
|
||||||
|
pbr_nht_json_nexthop_group(j, word);
|
||||||
|
|
||||||
|
vty_out(vty, "%s\n",
|
||||||
|
json_object_to_json_string_ext(
|
||||||
|
j, JSON_C_TO_STRING_PRETTY));
|
||||||
|
|
||||||
|
json_object_free(j);
|
||||||
|
} else
|
||||||
pbr_nht_show_nexthop_group(vty, word);
|
pbr_nht_show_nexthop_group(vty, word);
|
||||||
|
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user