diff options
Diffstat (limited to 'zebra/zebra_rnh.c')
| -rw-r--r-- | zebra/zebra_rnh.c | 185 |
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, |
