summaryrefslogtreecommitdiff
path: root/zebra/zebra_rnh.c
diff options
context:
space:
mode:
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,