summaryrefslogtreecommitdiff
path: root/zebra/zebra_rnh.c
diff options
context:
space:
mode:
authorSindhu Parvathi Gopinathan <sgopinathan@nvidia.com>2022-11-14 19:33:56 -0800
committerChirag Shah <chirag@nvidia.com>2022-11-28 15:38:09 -0800
commit780563cc8b03cb32899440b1fa2ecb9d35c639aa (patch)
tree09570f7e26636236277abc0e71fd6f7694cf6838 /zebra/zebra_rnh.c
parente7ae04259d475fd51cb25071d8e094d9b2266adb (diff)
zebra: json support for show ip nht
show ip/ipv6 nht vrf <all | name> json support added. Commands enhanced with JSON: ---------------------------- show ip nht json show ip nht <addr> json show ipv6 nht json show ipv6 nht <addr> json show ip nht vrf <name> json show ip nht vrf all json show ipv6 nht vrf <name> json show ipv6 nht vrf all json show ip nht vrf default <addr> json show ipv6 nht vrf default <addr> json Sample JSON output: ------------------- tor-1# show ip nht vrf default json { "default":{ "nexthops":{ "27.0.0.5":{ "nhtConnected":false, "clientList":[ { "protocol":"bgp", "socket":70, "protocolFiltered":"none" } ], "gates":[ { "ip":"fe80::202:ff:fe00:2b", "interface":"uplink_1" }, { "ip":"fe80::202:ff:fe00:35", "interface":"uplink_2" } ], "resolvedProtocol":"bgp" }, "27.0.0.6":{ "nhtConnected":false, "clientList":[ { "protocol":"bgp", "socket":70, "protocolFiltered":"none" } ], "gates":[ { "ip":"fe80::202:ff:fe00:2b", "interface":"uplink_1" }, { "ip":"fe80::202:ff:fe00:35", "interface":"uplink_2" } ], "resolvedProtocol":"bgp" } } } } tor-1# show ipv6 nht vrf default json { "default": { "nexthops": { "fe80::202:ff:fe00:25": { "nhtConnected": true, "clientList": [ { "protocol": "bgp", "socket": 45, "protocolFiltered": "none" } ], "gates": [ { "interface": "swp1", "directlyConnected": true } ], "resolvedProtocol": "connected" }, "fe80::202:ff:fe00:2b": { "nhtConnected": true, "clientList": [ { "protocol": "bgp", "socket": 45, "protocolFiltered": "none" } ], "gates": [ { "interface": "swp1", "directlyConnected": true } ], "resolvedProtocol": "connected" } } } } tor-1# show ipv6 nht vrf all json { "default": { "nexthops": { "fe80::202:ff:fe00:25": { "nhtConnected": true, "clientList": [ { "protocol": "bgp", "socket": 45, "protocolFiltered": "none" } ], "gates": [ { "interface": "swp1", "directlyConnected": true } ], "resolvedProtocol": "connected" }, "fe80::202:ff:fe00:2b": { "nhtConnected": true, "clientList": [ { "protocol": "bgp", "socket": 45, "protocolFiltered": "none" } ], "gates": [ { "interface": "swp1", "directlyConnected": true } ], "resolvedProtocol": "connected" } } }, "mgmt": { "nexthops": {} }, "sym_1": { "nexthops": {} } } Ticket:#3229013 Issue:3229013 Testing Done: Unit test completed. Signed-off-by: Chirag Shah <chirag@nvidia.com> Signed-off-by: Sindhu Parvathi Gopinathan <sgopinathan@nvidia.com>
Diffstat (limited to 'zebra/zebra_rnh.c')
-rw-r--r--zebra/zebra_rnh.c185
1 files changed, 146 insertions, 39 deletions
diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c
index 7934a9d206..599c679864 100644
--- a/zebra/zebra_rnh.c
+++ b/zebra/zebra_rnh.c
@@ -62,7 +62,8 @@ static void free_state(vrf_id_t vrf_id, struct route_entry *re,
static void copy_state(struct rnh *rnh, const struct route_entry *re,
struct route_node *rn);
static bool compare_state(struct route_entry *r1, struct route_entry *r2);
-static void print_rnh(struct route_node *rn, struct vty *vty);
+static void print_rnh(struct route_node *rn, struct vty *vty,
+ json_object *json);
static int zebra_client_cleanup_rnh(struct zserv *client);
void zebra_rnh_init(void)
@@ -803,7 +804,8 @@ void zebra_evaluate_rnh(struct zebra_vrf *zvrf, afi_t afi, int force,
}
void zebra_print_rnh_table(vrf_id_t vrfid, afi_t afi, safi_t safi,
- struct vty *vty, const struct prefix *p)
+ struct vty *vty, const struct prefix *p,
+ json_object *json)
{
struct route_table *table;
struct route_node *rn;
@@ -820,7 +822,7 @@ void zebra_print_rnh_table(vrf_id_t vrfid, afi_t afi, safi_t safi,
continue;
if (rn->info)
- print_rnh(rn, vty);
+ print_rnh(rn, vty, json);
}
}
@@ -1268,73 +1270,178 @@ failure:
return -1;
}
-static void print_nh(struct nexthop *nexthop, struct vty *vty)
+static void print_nh(struct nexthop *nexthop, struct vty *vty,
+ json_object *json)
{
- char buf[BUFSIZ];
struct zebra_ns *zns = zebra_ns_lookup(nexthop->vrf_id);
switch (nexthop->type) {
case NEXTHOP_TYPE_IPV4:
case NEXTHOP_TYPE_IPV4_IFINDEX:
- vty_out(vty, " via %pI4", &nexthop->gate.ipv4);
- if (nexthop->ifindex)
- vty_out(vty, ", %s",
- ifindex2ifname_per_ns(zns, nexthop->ifindex));
+ if (json) {
+ json_object_string_addf(json, "ip", "%pI4",
+ &nexthop->gate.ipv4);
+ if (nexthop->ifindex)
+ json_object_string_add(
+ json, "interface",
+ ifindex2ifname_per_ns(
+ zns, nexthop->ifindex));
+ } else {
+ vty_out(vty, " via %pI4", &nexthop->gate.ipv4);
+ if (nexthop->ifindex)
+ vty_out(vty, ", %s",
+ ifindex2ifname_per_ns(
+ zns, nexthop->ifindex));
+ }
break;
case NEXTHOP_TYPE_IPV6:
case NEXTHOP_TYPE_IPV6_IFINDEX:
- vty_out(vty, " %s",
- inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
- if (nexthop->ifindex)
- vty_out(vty, ", via %s",
- ifindex2ifname_per_ns(zns, nexthop->ifindex));
+ if (json) {
+ json_object_string_addf(json, "ip", "%pI6",
+ &nexthop->gate.ipv6);
+ if (nexthop->ifindex)
+ json_object_string_add(
+ json, "interface",
+ ifindex2ifname_per_ns(
+ zns, nexthop->ifindex));
+ } else {
+ vty_out(vty, " %pI6", &nexthop->gate.ipv6);
+ if (nexthop->ifindex)
+ vty_out(vty, ", via %s",
+ ifindex2ifname_per_ns(
+ zns, nexthop->ifindex));
+ }
break;
case NEXTHOP_TYPE_IFINDEX:
- vty_out(vty, " is directly connected, %s",
- ifindex2ifname_per_ns(zns, nexthop->ifindex));
+ if (json) {
+ json_object_string_add(
+ json, "interface",
+ ifindex2ifname_per_ns(zns, nexthop->ifindex));
+ json_object_boolean_true_add(json, "directlyConnected");
+ } else {
+ vty_out(vty, " is directly connected, %s",
+ ifindex2ifname_per_ns(zns, nexthop->ifindex));
+ }
break;
case NEXTHOP_TYPE_BLACKHOLE:
- vty_out(vty, " is directly connected, Null0");
+ if (json) {
+ json_object_string_add(json, "interface", "Null0");
+ json_object_boolean_true_add(json, "directlyConnected");
+ } else {
+ vty_out(vty, " is directly connected, Null0");
+ }
break;
default:
break;
}
- vty_out(vty, "\n");
+
+ if (!json)
+ vty_out(vty, "\n");
}
-static void print_rnh(struct route_node *rn, struct vty *vty)
+static void print_rnh(struct route_node *rn, struct vty *vty, json_object *json)
{
struct rnh *rnh;
struct nexthop *nexthop;
struct listnode *node;
struct zserv *client;
char buf[BUFSIZ];
+ json_object *json_nht = NULL;
+ json_object *json_client_array = NULL;
+ json_object *json_client = NULL;
+ json_object *json_nexthop_array = NULL;
+ json_object *json_nexthop = NULL;
rnh = rn->info;
- vty_out(vty, "%s%s\n",
- inet_ntop(rn->p.family, &rn->p.u.prefix, buf, BUFSIZ),
- CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED) ? "(Connected)"
- : "");
- if (rnh->state) {
- vty_out(vty, " resolved via %s\n",
- zebra_route_string(rnh->state->type));
- for (nexthop = rnh->state->nhe->nhg.nexthop; nexthop;
- nexthop = nexthop->next)
- print_nh(nexthop, vty);
- } else
- vty_out(vty, " unresolved%s\n",
+
+ if (json) {
+ json_nht = json_object_new_object();
+ json_nexthop_array = json_object_new_array();
+ json_client_array = json_object_new_array();
+
+ json_object_object_add(
+ json,
+ inet_ntop(rn->p.family, &rn->p.u.prefix, buf, BUFSIZ),
+ json_nht);
+ json_object_boolean_add(
+ json_nht, "nhtConnected",
+ CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED));
+ json_object_object_add(json_nht, "clientList",
+ json_client_array);
+ json_object_object_add(json_nht, "gates", json_nexthop_array);
+ } else {
+ vty_out(vty, "%s%s\n",
+ inet_ntop(rn->p.family, &rn->p.u.prefix, buf, BUFSIZ),
CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED)
? "(Connected)"
: "");
+ }
+
+ if (rnh->state) {
+ if (json)
+ json_object_string_add(
+ json_nht, "resolvedProtocol",
+ zebra_route_string(rnh->state->type));
+ else
+ vty_out(vty, " resolved via %s\n",
+ zebra_route_string(rnh->state->type));
+
+ for (nexthop = rnh->state->nhe->nhg.nexthop; nexthop;
+ nexthop = nexthop->next) {
+ if (json) {
+ json_nexthop = json_object_new_object();
+ json_object_array_add(json_nexthop_array,
+ json_nexthop);
+ }
+ print_nh(nexthop, vty, json_nexthop);
+ }
+ } else {
+ if (json)
+ json_object_boolean_add(
+ json_nht, "unresolved",
+ CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED));
+ else
+ vty_out(vty, " unresolved%s\n",
+ CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED)
+ ? "(Connected)"
+ : "");
+ }
+
+ if (!json)
+ vty_out(vty, " Client list:");
+
+ for (ALL_LIST_ELEMENTS_RO(rnh->client_list, node, client)) {
+ if (json) {
+ json_client = json_object_new_object();
+ json_object_array_add(json_client_array, json_client);
+
+ json_object_string_add(
+ json_client, "protocol",
+ zebra_route_string(client->proto));
+ json_object_int_add(json_client, "socket",
+ client->sock);
+ json_object_string_add(json_client, "protocolFiltered",
+ (rnh->filtered[client->proto]
+ ? "(filtered)"
+ : "none"));
+ } else {
+ vty_out(vty, " %s(fd %d)%s",
+ zebra_route_string(client->proto), client->sock,
+ rnh->filtered[client->proto] ? "(filtered)"
+ : "");
+ }
+ }
+
+ if (!list_isempty(rnh->zebra_pseudowire_list)) {
+ if (json)
+ json_object_boolean_true_add(json_nht,
+ "zebraPseudowires");
+ else
+ vty_out(vty, " zebra[pseudowires]");
+ }
- vty_out(vty, " Client list:");
- for (ALL_LIST_ELEMENTS_RO(rnh->client_list, node, client))
- vty_out(vty, " %s(fd %d)%s", zebra_route_string(client->proto),
- client->sock,
- rnh->filtered[client->proto] ? "(filtered)" : "");
- if (!list_isempty(rnh->zebra_pseudowire_list))
- vty_out(vty, " zebra[pseudowires]");
- vty_out(vty, "\n");
+ if (!json)
+ vty_out(vty, "\n");
}
static int zebra_cleanup_rnh_client(vrf_id_t vrf_id, afi_t afi, safi_t safi,