Skip to content

Commit

Permalink
nhrpd: add json support to show nhrp vty commands
Browse files Browse the repository at this point in the history
- add json support for show nhrp vty commands.
- support for 'show dmvpn [json]' format.

Signed-off-by: Philippe Guibert <[email protected]>
  • Loading branch information
pguibert6WIND committed Mar 13, 2020
1 parent 0886f49 commit 87b9e98
Showing 1 changed file with 227 additions and 48 deletions.
275 changes: 227 additions & 48 deletions nhrpd/nhrp_vty.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "zclient.h"
#include "stream.h"
#include "filter.h"
#include "json.h"

#include "nhrpd.h"
#include "netlink.h"
Expand Down Expand Up @@ -594,29 +595,68 @@ struct info_ctx {
struct vty *vty;
afi_t afi;
int count;
struct json_object *json;
};

static void show_ip_nhrp_cache(struct nhrp_cache *c, void *pctx)
{
struct info_ctx *ctx = pctx;
struct vty *vty = ctx->vty;
char buf[2][SU_ADDRSTRLEN];
struct json_object *json = NULL;

if (ctx->afi != family2afi(sockunion_family(&c->remote_addr)))
return;

if (!ctx->count) {

if (!ctx->count && !ctx->json) {
vty_out(vty, "%-8s %-8s %-24s %-24s %-6s %s\n", "Iface", "Type",
"Protocol", "NBMA", "Flags", "Identity");
}
ctx->count++;

sockunion2str(&c->remote_addr, buf[0], sizeof(buf[0]));
if (c->cur.peer)
sockunion2str(&c->cur.peer->vc->remote.nbma,
buf[1], sizeof(buf[1]));
else
snprintf(buf[1], sizeof(buf[1]), "-");

if (json) {
json = json_object_new_object();
json_object_string_add(json, "interface", c->ifp->name);
json_object_string_add(json, "type",
nhrp_cache_type_str[c->cur.type]);
json_object_string_add(json, "protocol", buf[0]);
json_object_string_add(json, "nbma", buf[1]);

if (c->used)
json_object_boolean_true_add(json, "used");
else
json_object_boolean_false_add(json, "used");

if (c->t_timeout)
json_object_boolean_true_add(json, "timeout");
else
json_object_boolean_false_add(json, "timeout");

if (c->t_auth)
json_object_boolean_true_add(json, "auth");
else
json_object_boolean_false_add(json, "auth");

if (c->cur.peer)
json_object_string_add(json, "identity",
c->cur.peer->vc->remote.id);
else
json_object_string_add(json, "identity", "-");

json_object_array_add(ctx->json, json);
return;
}
vty_out(ctx->vty, "%-8s %-8s %-24s %-24s %c%c%c %s\n", c->ifp->name,
nhrp_cache_type_str[c->cur.type],
sockunion2str(&c->remote_addr, buf[0], sizeof(buf[0])),
c->cur.peer ? sockunion2str(&c->cur.peer->vc->remote.nbma,
buf[1], sizeof(buf[1]))
: "-",
buf[0], buf[1],
c->used ? 'U' : ' ', c->t_timeout ? 'T' : ' ',
c->t_auth ? 'A' : ' ',
c->cur.peer ? c->cur.peer->vc->remote.id : "-");
Expand All @@ -628,19 +668,35 @@ static void show_ip_nhrp_nhs(struct nhrp_nhs *n, struct nhrp_registration *reg,
struct info_ctx *ctx = pctx;
struct vty *vty = ctx->vty;
char buf[2][SU_ADDRSTRLEN];
struct json_object *json = NULL;

if (!ctx->count) {
if (!ctx->count && !ctx->json) {
vty_out(vty, "%-8s %-24s %-16s %-16s\n", "Iface", "FQDN",
"NBMA", "Protocol");
}
ctx->count++;

if (reg && reg->peer)
sockunion2str(&reg->peer->vc->remote.nbma,
buf[0], sizeof(buf[0]));
else
snprintf(buf[0], sizeof(buf[0]), "-");
sockunion2str(reg ? &reg->proto_addr : &n->proto_addr, buf[1],
sizeof(buf[1]));

if (ctx->json) {
json = json_object_new_object();
json_object_string_add(json, "interface", n->ifp->name);
json_object_string_add(json, "fqdn", n->nbma_fqdn);
json_object_string_add(json, "nbma", buf[0]);
json_object_string_add(json, "protocol", buf[1]);

json_object_array_add(ctx->json, json);
return;
}

vty_out(vty, "%-8s %-24s %-16s %-16s\n", n->ifp->name, n->nbma_fqdn,
(reg && reg->peer) ? sockunion2str(&reg->peer->vc->remote.nbma,
buf[0], sizeof(buf[0]))
: "-",
sockunion2str(reg ? &reg->proto_addr : &n->proto_addr, buf[1],
sizeof(buf[1])));
buf[0], buf[1]);
}

static void show_ip_nhrp_shortcut(struct nhrp_shortcut *s, void *pctx)
Expand All @@ -649,6 +705,7 @@ static void show_ip_nhrp_shortcut(struct nhrp_shortcut *s, void *pctx)
struct nhrp_cache *c;
struct vty *vty = ctx->vty;
char buf1[PREFIX_STRLEN], buf2[SU_ADDRSTRLEN];
struct json_object *json = NULL;

if (!ctx->count) {
vty_out(vty, "%-8s %-24s %-24s %s\n", "Type", "Prefix", "Via",
Expand All @@ -657,61 +714,128 @@ static void show_ip_nhrp_shortcut(struct nhrp_shortcut *s, void *pctx)
ctx->count++;

c = s->cache;
vty_out(ctx->vty, "%-8s %-24s %-24s %s\n", nhrp_cache_type_str[s->type],
prefix2str(s->p, buf1, sizeof(buf1)),
c ? sockunion2str(&c->remote_addr, buf2, sizeof(buf2)) : "",
if (c)
sockunion2str(&c->remote_addr, buf2, sizeof(buf2));
prefix2str(s->p, buf1, sizeof(buf1));

if (ctx->json) {
json = json_object_new_object();
json_object_string_add(json, "type",
nhrp_cache_type_str[s->type]);
json_object_string_add(json, "prefix", buf1);

if (c)
json_object_string_add(json, "via", buf2);

if (c && c->cur.peer)
json_object_string_add(json, "identity",
c->cur.peer->vc->remote.id);
else
json_object_string_add(json, "identity", "");

json_object_array_add(ctx->json, json);
return;
}

vty_out(ctx->vty, "%-8s %-24s %-24s %s\n",
nhrp_cache_type_str[s->type],
buf1, buf2,
(c && c->cur.peer) ? c->cur.peer->vc->remote.id : "");
}

static void show_ip_opennhrp_cache(struct nhrp_cache *c, void *pctx)
{
struct info_ctx *ctx = pctx;
char buf[SU_ADDRSTRLEN];
char buf[3][SU_ADDRSTRLEN];
struct json_object *json = NULL;


if (ctx->afi != family2afi(sockunion_family(&c->remote_addr)))
return;

sockunion2str(&c->remote_addr, buf[0], sizeof(buf[0]));
if (c->cur.peer)
sockunion2str(&c->cur.peer->vc->remote.nbma, buf[1],
sizeof(buf[1]));
if (sockunion_family(&c->cur.remote_nbma_natoa) != AF_UNSPEC)
sockunion2str(&c->cur.remote_nbma_natoa, buf[2],
sizeof(buf[2]));
if (ctx->json) {
json = json_object_new_object();
json_object_string_add(json, "type",
nhrp_cache_type_str[c->cur.type]);

if (c->cur.peer && c->cur.peer->online)
json_object_boolean_true_add(json, "up");
else
json_object_boolean_false_add(json, "up");

if (c->used)
json_object_boolean_true_add(json, "used");
else
json_object_boolean_false_add(json, "used");

json_object_string_add(json, "protocolAddress", buf[0]);
json_object_int_add(json, "protocolAddressSize",
8 * family2addrsize(sockunion_family
(&c->remote_addr)));

if (c->cur.peer)
json_object_string_add(json, "nbmaAddress", buf[1]);

if (sockunion_family(&c->cur.remote_nbma_natoa) != AF_UNSPEC)
json_object_string_add(json, "nbmaNatOaAddress",
buf[2]);

json_object_array_add(ctx->json, json);
return;
}
vty_out(ctx->vty,
"Type: %s\n"
"Flags:%s%s\n"
"Protocol-Address: %s/%zu\n",
nhrp_cache_type_str[c->cur.type],
(c->cur.peer && c->cur.peer->online) ? " up" : "",
c->used ? " used" : "",
sockunion2str(&c->remote_addr, buf, sizeof(buf)),
buf[0],
8 * family2addrsize(sockunion_family(&c->remote_addr)));

if (c->cur.peer) {
vty_out(ctx->vty, "NBMA-Address: %s\n",
sockunion2str(&c->cur.peer->vc->remote.nbma, buf,
sizeof(buf)));
}
if (c->cur.peer)
vty_out(ctx->vty, "NBMA-Address: %s\n", buf[1]);

if (sockunion_family(&c->cur.remote_nbma_natoa) != AF_UNSPEC) {
vty_out(ctx->vty, "NBMA-NAT-OA-Address: %s\n",
sockunion2str(&c->cur.remote_nbma_natoa, buf,
sizeof(buf)));
}
if (sockunion_family(&c->cur.remote_nbma_natoa) != AF_UNSPEC)
vty_out(ctx->vty, "NBMA-NAT-OA-Address: %s\n", buf[2]);

vty_out(ctx->vty, "\n\n");
}

DEFUN(show_ip_nhrp, show_ip_nhrp_cmd,
"show " AFI_CMD " nhrp [cache|nhs|shortcut|opennhrp]",
"show " AFI_CMD " nhrp [cache|nhs|shortcut|opennhrp] [json]",
SHOW_STR
AFI_STR
"NHRP information\n"
"Forwarding cache information\n"
"Next hop server information\n"
"Shortcut information\n"
"opennhrpctl style cache dump\n")
"opennhrpctl style cache dump\n"
JSON_STR)
{
struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
struct interface *ifp;
struct info_ctx ctx = {
.vty = vty, .afi = cmd_to_afi(argv[1]),
.vty = vty, .afi = cmd_to_afi(argv[1]), .json = NULL
};

bool uj = use_json(argc, argv);
struct json_object *json_path = NULL;
struct json_object *json_vrf = NULL, *json_vrf_path = NULL;
int ret = CMD_SUCCESS;

if (uj) {
json_vrf = json_object_new_object();
json_vrf_path = json_object_new_object();
json_path = json_object_new_array();
ctx.json = json_path;
}
if (argc <= 3 || argv[3]->text[0] == 'c') {
FOR_ALL_INTERFACES (vrf, ifp)
nhrp_cache_foreach(ifp, show_ip_nhrp_cache, &ctx);
Expand All @@ -721,42 +845,97 @@ DEFUN(show_ip_nhrp, show_ip_nhrp_cmd,
} else if (argv[3]->text[0] == 's') {
nhrp_shortcut_foreach(ctx.afi, show_ip_nhrp_shortcut, &ctx);
} else {
vty_out(vty, "Status: ok\n\n");
if (!ctx.json)
vty_out(vty, "Status: ok\n\n");
else
json_object_string_add(json_vrf, "status", "ok");

ctx.count++;
FOR_ALL_INTERFACES (vrf, ifp)
nhrp_cache_foreach(ifp, show_ip_opennhrp_cache, &ctx);
}

if (uj)
json_object_int_add(json_vrf, "entriesCount", ctx.count);
if (!ctx.count) {
vty_out(vty, "%% No entries\n");
return CMD_WARNING;
if (!ctx.json)
vty_out(vty, "%% No entries\n");
ret = CMD_WARNING;
}

return CMD_SUCCESS;
if (uj) {
json_object_object_add(json_vrf_path, "attr", json_vrf);
json_object_object_add(json_vrf_path, "table", ctx.json);
vty_out(vty, "%s",
json_object_to_json_string_ext(
json_vrf_path, JSON_C_TO_STRING_PRETTY));
json_object_free(json_vrf_path);
}
return ret;
}

struct dmvpn_cfg {
struct vty *vty;
struct json_object *json;
};

static void show_dmvpn_entry(struct nhrp_vc *vc, void *ctx)
{
struct vty *vty = ctx;
struct dmvpn_cfg *ctxt = ctx;
struct vty *vty;
char buf[2][SU_ADDRSTRLEN];
struct json_object *json = NULL;

if (!ctxt || !ctxt->vty)
return;
vty = ctxt->vty;
sockunion2str(&vc->local.nbma, buf[0], sizeof(buf[0]));
sockunion2str(&vc->remote.nbma, buf[1], sizeof(buf[1]));
if (ctxt->json) {
json = json_object_new_object();
json_object_string_add(json, "src", buf[0]);
json_object_string_add(json, "dst", buf[1]);

if (notifier_active(&vc->notifier_list))
json_object_boolean_true_add(json, "notifierActive");
else
json_object_boolean_false_add(json, "notifierActive");

vty_out(vty, "%-24s %-24s %c %-4d %-24s\n",
sockunion2str(&vc->local.nbma, buf[0], sizeof(buf[0])),
sockunion2str(&vc->remote.nbma, buf[1], sizeof(buf[1])),
notifier_active(&vc->notifier_list) ? 'n' : ' ', vc->ipsec,
vc->remote.id);
json_object_int_add(json, "sas", vc->ipsec);
json_object_string_add(json, "identity", vc->remote.id);
json_object_array_add(ctxt->json, json);
} else {
vty_out(vty, "%-24s %-24s %c %-4d %-24s\n",
buf[0], buf[1], notifier_active(&vc->notifier_list) ?
'n' : ' ', vc->ipsec, vc->remote.id);
}
}

DEFUN(show_dmvpn, show_dmvpn_cmd,
"show dmvpn",
"show dmvpn [json]",
SHOW_STR
"DMVPN information\n")
"DMVPN information\n"
JSON_STR)
{
vty_out(vty, "%-24s %-24s %-6s %-4s %-24s\n", "Src", "Dst", "Flags",
"SAs", "Identity");

nhrp_vc_foreach(show_dmvpn_entry, vty);

bool uj = use_json(argc, argv);
struct dmvpn_cfg ctxt;
struct json_object *json_path = NULL;

ctxt.vty = vty;
if (!uj) {
ctxt.json = NULL;
vty_out(vty, "%-24s %-24s %-6s %-4s %-24s\n",
"Src", "Dst", "Flags", "SAs", "Identity");
} else {
json_path = json_object_new_array();
ctxt.json = json_path;
}
nhrp_vc_foreach(show_dmvpn_entry, &ctxt);
if (uj) {
vty_out(vty, "%s",
json_object_to_json_string_ext(
json_path, JSON_C_TO_STRING_PRETTY));
json_object_free(json_path);
}
return CMD_SUCCESS;
}

Expand Down

0 comments on commit 87b9e98

Please sign in to comment.