diff options
Diffstat (limited to 'ldpd/ldp_vty_exec.c')
| -rw-r--r-- | ldpd/ldp_vty_exec.c | 1012 |
1 files changed, 620 insertions, 392 deletions
diff --git a/ldpd/ldp_vty_exec.c b/ldpd/ldp_vty_exec.c index 061bbeaa5e..afc709ff49 100644 --- a/ldpd/ldp_vty_exec.c +++ b/ldpd/ldp_vty_exec.c @@ -42,67 +42,75 @@ enum show_command { SHOW_L2VPN_BINDING }; -struct show_filter { +struct show_params { int family; union ldpd_addr addr; uint8_t prefixlen; + int json; }; #define LDPBUFSIZ 65535 static int show_interface_msg(struct vty *, struct imsg *, - struct show_filter *, json_object *); + struct show_params *); +static int show_interface_msg_json(struct imsg *, + struct show_params *, json_object *); static void show_discovery_adj(struct vty *, char *, - struct ctl_adj *, json_object *); + struct ctl_adj *); static int show_discovery_msg(struct vty *, struct imsg *, - struct show_filter *, json_object *); -static void show_nbr_adj(struct vty *, char *, struct ctl_adj *, - json_object *); + struct show_params *); +static void show_discovery_adj_json(json_object *, + struct ctl_adj *); +static int show_discovery_msg_json(struct imsg *, + struct show_params *, json_object *); +static void show_nbr_adj(struct vty *, char *, struct ctl_adj *); static int show_nbr_msg(struct vty *, struct imsg *, - struct show_filter *, json_object *, struct in_addr *); + struct show_params *); +static void show_nbr_adj_json(struct ctl_adj *, json_object *); +static int show_nbr_msg_json(struct imsg *, struct show_params *, + json_object *); static int show_lib_msg(struct vty *, struct imsg *, - struct show_filter *, json_object *); -static int show_l2vpn_binding_msg(struct vty *, struct imsg *); -static int show_l2vpn_pw_msg(struct vty *, struct imsg *); + struct show_params *); +static int show_lib_msg_json(struct imsg *, struct show_params *, + json_object *); +static int show_l2vpn_binding_msg(struct vty *, struct imsg *, + struct show_params *); +static int show_l2vpn_binding_msg_json(struct imsg *, + struct show_params *, json_object *); +static int show_l2vpn_pw_msg(struct vty *, struct imsg *, + struct show_params *); +static int show_l2vpn_pw_msg_json(struct imsg *, + struct show_params *, json_object *); static int ldp_vty_connect(struct imsgbuf *); +static int ldp_vty_dispatch_msg(struct vty *, struct imsg *, + enum show_command, struct show_params *, + json_object *); static int ldp_vty_dispatch(struct vty *, struct imsgbuf *, - enum show_command, struct show_filter *, u_char); + enum show_command, struct show_params *); static int ldp_vty_get_af(const char *, int *); static int show_interface_msg(struct vty *vty, struct imsg *imsg, - struct show_filter *filter, json_object *json) + struct show_params *params) { struct ctl_iface *iface; char timers[BUFSIZ]; - json_object *json_iface = NULL; switch (imsg->hdr.type) { case IMSG_CTL_SHOW_INTERFACE: iface = imsg->data; - if (filter->family != AF_UNSPEC && filter->family != iface->af) + if (params->family != AF_UNSPEC && params->family != iface->af) break; - if (json) { - json_iface = json_object_new_object(); - json_object_string_add(json_iface, "addressFamily", af_name(iface->af)); - json_object_string_add(json_iface, "state", if_state_name(iface->state)); - json_object_string_add(json_iface, "uptime", log_time(iface->uptime)); - json_object_int_add(json_iface, "helloInterval", iface->hello_interval); - json_object_int_add(json_iface, "holdtime", iface->hello_holdtime); - json_object_int_add(json_iface, "adjacencyCount", iface->adj_cnt); - json_object_object_add(json, iface->name, json_iface); - } else { - snprintf(timers, sizeof(timers), "%u/%u", - iface->hello_interval, iface->hello_holdtime); - - vty_out(vty, "%-4s %-11s %-6s %-8s %-12s %3u%s", - af_name(iface->af), iface->name, - if_state_name(iface->state), iface->uptime == 0 ? - "00:00:00" : log_time(iface->uptime), timers, - iface->adj_cnt, VTY_NEWLINE); - } + snprintf(timers, sizeof(timers), "%u/%u", + iface->hello_interval, iface->hello_holdtime); + + vty_out(vty, "%-4s %-11s %-6s %-8s %-12s %3u%s", + af_name(iface->af), iface->name, + if_state_name(iface->state), iface->uptime == 0 ? + "00:00:00" : log_time(iface->uptime), timers, + iface->adj_cnt, VTY_NEWLINE); break; case IMSG_CTL_END: vty_out(vty, "%s", VTY_NEWLINE); @@ -114,53 +122,65 @@ show_interface_msg(struct vty *vty, struct imsg *imsg, return (0); } +static int +show_interface_msg_json(struct imsg *imsg, struct show_params *params, + json_object *json) +{ + struct ctl_iface *iface; + json_object *json_iface; + char key_name[64]; + + switch (imsg->hdr.type) { + case IMSG_CTL_SHOW_INTERFACE: + iface = imsg->data; + + if (params->family != AF_UNSPEC && params->family != iface->af) + break; + + json_iface = json_object_new_object(); + json_object_string_add(json_iface, "name", iface->name); + json_object_string_add(json_iface, "addressFamily", + af_name(iface->af)); + json_object_string_add(json_iface, "state", + if_state_name(iface->state)); + json_object_string_add(json_iface, "upTime", + log_time(iface->uptime)); + json_object_int_add(json_iface, "helloInterval", + iface->hello_interval); + json_object_int_add(json_iface, "helloHoldtime", + iface->hello_holdtime); + json_object_int_add(json_iface, "adjacencyCount", + iface->adj_cnt); + + sprintf(key_name, "%s: %s", iface->name, af_name(iface->af)); + json_object_object_add(json, key_name, json_iface); + break; + case IMSG_CTL_END: + return (1); + default: + break; + } + + return (0); +} + static void -show_discovery_adj(struct vty *vty, char *buffer, struct ctl_adj *adj, json_object *json) +show_discovery_adj(struct vty *vty, char *buffer, struct ctl_adj *adj) { size_t buflen = strlen(buffer); - json_object *json_adj = NULL; - json_object *json_array = NULL; - - if (json) { - switch(adj->type) { - case HELLO_LINK: - json_object_object_get_ex(json, "adjacencyLink", &json_array); - - if (!json_array) { - json_array = json_object_new_array(); - json_object_object_add(json, "adjacencyLink", json_array); - } - break; - case HELLO_TARGETED: - json_object_object_get_ex(json, "adjacencyTargeted", &json_array); - - if (!json_array) { - json_array = json_object_new_array(); - json_object_object_add(json, "adjacencyTargeted", json_array); - } - break; - } - - json_adj = json_object_new_object(); - json_object_string_add(json_adj, "id", inet_ntoa(adj->id)); - json_object_string_add(json_adj, "transportAddress", log_addr(adj->af, &adj->trans_addr)); - json_object_int_add(json_adj, "holdtime", adj->holdtime); - json_object_array_add(json_array, json_adj); - - } else { - snprintf(buffer + buflen, LDPBUFSIZ - buflen, - " LDP Id: %s:0, Transport address: %s%s", - inet_ntoa(adj->id), log_addr(adj->af, - &adj->trans_addr), VTY_NEWLINE); - buflen = strlen(buffer); - snprintf(buffer + buflen, LDPBUFSIZ - buflen, - " Hold time: %u sec%s", adj->holdtime, VTY_NEWLINE); - } + + snprintf(buffer + buflen, LDPBUFSIZ - buflen, + " LDP Id: %s:0, Transport address: %s%s", + inet_ntoa(adj->id), log_addr(adj->af, + &adj->trans_addr), VTY_NEWLINE); + buflen = strlen(buffer); + snprintf(buffer + buflen, LDPBUFSIZ - buflen, + " Hold time: %u sec%s", adj->holdtime, VTY_NEWLINE); } static int show_discovery_msg(struct vty *vty, struct imsg *imsg, - struct show_filter *filter, json_object *json) + struct show_params *params) { struct ctl_adj *adj; struct ctl_disc_if *iface; @@ -170,10 +190,6 @@ show_discovery_msg(struct vty *vty, struct imsg *imsg, size_t buflen; static char ifaces_buffer[LDPBUFSIZ]; static char tnbrs_buffer[LDPBUFSIZ]; - json_object *json_interface = NULL; - json_object *json_interfaces = NULL; - json_object *json_target = NULL; - json_object *json_targets = NULL; switch (imsg->hdr.type) { case IMSG_CTL_SHOW_DISCOVERY: @@ -183,97 +199,161 @@ show_discovery_msg(struct vty *vty, struct imsg *imsg, case IMSG_CTL_SHOW_DISC_IFACE: iface = imsg->data; - if (filter->family != AF_UNSPEC && - ((filter->family == AF_INET && !iface->active_v4) || - (filter->family == AF_INET6 && !iface->active_v6))) + if (params->family != AF_UNSPEC && + ((params->family == AF_INET && !iface->active_v4) || + (params->family == AF_INET6 && !iface->active_v6))) break; - if (json) { - json_object_object_get_ex(json, "interfaces", &json_interfaces); + buflen = strlen(ifaces_buffer); + snprintf(ifaces_buffer + buflen, LDPBUFSIZ - buflen, + " %s: %s%s", iface->name, (iface->no_adj) ? + "xmit" : "xmit/recv", VTY_NEWLINE); + break; + case IMSG_CTL_SHOW_DISC_TNBR: + tnbr = imsg->data; - if (!json_interfaces) { - json_interfaces = json_object_new_object(); - json_object_object_add(json, "interfaces", json_interfaces); - } + if (params->family != AF_UNSPEC && params->family != tnbr->af) + break; - json_interface = json_object_new_object(); - json_object_boolean_true_add(json_interface, "transmit"); + trans_addr = &(ldp_af_conf_get(ldpd_conf, + tnbr->af))->trans_addr; + buflen = strlen(tnbrs_buffer); + snprintf(tnbrs_buffer + buflen, LDPBUFSIZ - buflen, + " %s -> %s: %s%s", log_addr(tnbr->af, trans_addr), + log_addr(tnbr->af, &tnbr->addr), (tnbr->no_adj) ? "xmit" : + "xmit/recv", VTY_NEWLINE); + break; + case IMSG_CTL_SHOW_DISC_ADJ: + adj = imsg->data; - if (iface->no_adj) - json_object_boolean_true_add(json_interface, "receive"); + if (params->family != AF_UNSPEC && params->family != adj->af) + break; - json_object_object_add(json_interfaces, iface->name, json_interface); + switch(adj->type) { + case HELLO_LINK: + show_discovery_adj(vty, ifaces_buffer, adj); + break; + case HELLO_TARGETED: + show_discovery_adj(vty, tnbrs_buffer, adj); + break; + } + break; + case IMSG_CTL_END: + rtr_id.s_addr = ldp_rtr_id_get(ldpd_conf); + vty_out(vty, "Local LDP Identifier: %s:0%s", inet_ntoa(rtr_id), + VTY_NEWLINE); + vty_out(vty, "Discovery Sources:%s", VTY_NEWLINE); + vty_out(vty, " Interfaces:%s", VTY_NEWLINE); + vty_out(vty, "%s", ifaces_buffer); + vty_out(vty, " Targeted Hellos:%s", VTY_NEWLINE); + vty_out(vty, "%s", tnbrs_buffer); + vty_out(vty, "%s", VTY_NEWLINE); + return (1); + default: + break; + } - } else { - buflen = strlen(ifaces_buffer); - snprintf(ifaces_buffer + buflen, LDPBUFSIZ - buflen, - " %s: %s%s", iface->name, (iface->no_adj) ? - "xmit" : "xmit/recv", VTY_NEWLINE); - } + return (0); +} + +static void +show_discovery_adj_json(json_object *json, struct ctl_adj *adj) +{ + json_object *json_adj; + json_object *json_array; + + json_object_object_get_ex(json, "adjacencies", &json_array); + if (!json_array) { + json_array = json_object_new_array(); + json_object_object_add(json, "adjacencies", json_array); + } + + json_adj = json_object_new_object(); + json_object_string_add(json_adj, "id", inet_ntoa(adj->id)); + json_object_string_add(json_adj, "transportAddress", log_addr(adj->af, + &adj->trans_addr)); + json_object_int_add(json_adj, "holdtime", adj->holdtime); + json_object_array_add(json_array, json_adj); +} + +static int +show_discovery_msg_json(struct imsg *imsg, struct show_params *params, + json_object *json) +{ + struct ctl_adj *adj; + struct ctl_disc_if *iface; + struct ctl_disc_tnbr *tnbr; + struct in_addr rtr_id; + union ldpd_addr *trans_addr; + json_object *json_interface; + json_object *json_target; + static json_object *json_interfaces; + static json_object *json_targets; + static json_object *json_container; + + switch (imsg->hdr.type) { + case IMSG_CTL_SHOW_DISCOVERY: + rtr_id.s_addr = ldp_rtr_id_get(ldpd_conf); + json_object_string_add(json, "id", inet_ntoa(rtr_id)); + json_interfaces = json_object_new_object(); + json_object_object_add(json, "interfaces", json_interfaces); + json_targets = json_object_new_object(); + json_object_object_add(json, "targetedHellos", json_targets); + json_container = NULL; break; - case IMSG_CTL_SHOW_DISC_TNBR: - tnbr = imsg->data; + case IMSG_CTL_SHOW_DISC_IFACE: + iface = imsg->data; - if (filter->family != AF_UNSPEC && filter->family != tnbr->af) + if (params->family != AF_UNSPEC && + ((params->family == AF_INET && !iface->active_v4) || + (params->family == AF_INET6 && !iface->active_v6))) break; - trans_addr = &(ldp_af_conf_get(ldpd_conf, tnbr->af))->trans_addr; + json_interface = json_object_new_object(); + json_object_boolean_true_add(json_interface, "transmit"); + if (!iface->no_adj) + json_object_boolean_true_add(json_interface, "receive"); - if (json) { - json_object_object_get_ex(json, "targeted", &json_targets); + json_object_object_add(json_interfaces, iface->name, + json_interface); + json_container = json_interface; + break; + case IMSG_CTL_SHOW_DISC_TNBR: + tnbr = imsg->data; - if (!json_targets) { - json_targets = json_object_new_array(); - json_object_object_add(json, "targeted", json_targets); - } + if (params->family != AF_UNSPEC && params->family != tnbr->af) + break; - json_target = json_object_new_object(); - json_object_string_add(json_target, "sourceAddress", log_addr(tnbr->af, trans_addr)); - json_object_boolean_true_add(json_target, "transmit"); + trans_addr = &(ldp_af_conf_get(ldpd_conf, tnbr->af))->trans_addr; - if (tnbr->no_adj) - json_object_boolean_true_add(json_target, "receive"); + json_target = json_object_new_object(); + json_object_string_add(json_target, "sourceAddress", + log_addr(tnbr->af, trans_addr)); + json_object_boolean_true_add(json_target, "transmit"); + if (!tnbr->no_adj) + json_object_boolean_true_add(json_target, "receive"); - json_object_object_add(json_targets, log_addr(tnbr->af, &tnbr->addr), json_interface); - } else { - buflen = strlen(tnbrs_buffer); - snprintf(tnbrs_buffer + buflen, LDPBUFSIZ - buflen, - " %s -> %s: %s%s", log_addr(tnbr->af, trans_addr), - log_addr(tnbr->af, &tnbr->addr), (tnbr->no_adj) ? "xmit" : - "xmit/recv", VTY_NEWLINE); - } + json_object_object_add(json_targets, log_addr(tnbr->af, + &tnbr->addr), json_target); + json_container = json_target; break; case IMSG_CTL_SHOW_DISC_ADJ: adj = imsg->data; - if (filter->family != AF_UNSPEC && filter->family != adj->af) + if (params->family != AF_UNSPEC && params->family != adj->af) break; switch(adj->type) { case HELLO_LINK: - show_discovery_adj(vty, ifaces_buffer, adj, json); + show_discovery_adj_json(json_container, adj); break; case HELLO_TARGETED: - show_discovery_adj(vty, tnbrs_buffer, adj, json); + show_discovery_adj_json(json_container, adj); break; } break; case IMSG_CTL_END: - rtr_id.s_addr = ldp_rtr_id_get(ldpd_conf); - - if (json) { - json_object_string_add(json, "id", inet_ntoa(rtr_id)); - } else { - vty_out(vty, "Local LDP Identifier: %s:0%s", inet_ntoa(rtr_id), - VTY_NEWLINE); - vty_out(vty, "Discovery Sources:%s", VTY_NEWLINE); - vty_out(vty, " Interfaces:%s", VTY_NEWLINE); - vty_out(vty, "%s", ifaces_buffer); - vty_out(vty, " Targeted Hellos:%s", VTY_NEWLINE); - vty_out(vty, "%s", tnbrs_buffer); - vty_out(vty, "%s", VTY_NEWLINE); - } - return (1); + return (1); default: break; } @@ -282,131 +362,168 @@ show_discovery_msg(struct vty *vty, struct imsg *imsg, } static void -show_nbr_adj(struct vty *vty, char *buffer, struct ctl_adj *adj, json_object *json_nbr) +show_nbr_adj(struct vty *vty, char *buffer, struct ctl_adj *adj) { size_t buflen = strlen(buffer); - json_object *json_adj_link = NULL; - json_object *json_adj_targeted = NULL; switch (adj->type) { case HELLO_LINK: - if (json_nbr) { - json_object_object_get_ex(json_nbr, "adjacencyLink", &json_adj_link); - - if (!json_adj_link) { - json_adj_link = json_object_new_array(); - json_object_object_add(json_nbr, "adjacencyLink", json_adj_link); - } - - json_object_array_add(json_adj_link, json_object_new_string(adj->ifname)); - } else { - snprintf(buffer + buflen, LDPBUFSIZ - buflen, - " Interface: %s%s", adj->ifname, VTY_NEWLINE); - } + snprintf(buffer + buflen, LDPBUFSIZ - buflen, + " Interface: %s%s", adj->ifname, VTY_NEWLINE); break; case HELLO_TARGETED: - if (json_nbr) { - json_object_object_get_ex(json_nbr, "adjacencyTargeted", &json_adj_targeted); - - if (!json_adj_targeted) { - json_adj_targeted = json_object_new_array(); - json_object_object_add(json_nbr, "adjacencyTargeted", json_adj_targeted); - } - - json_object_array_add(json_adj_targeted, - json_object_new_string(log_addr(adj->af, &adj->src_addr))); - } else { - snprintf(buffer + buflen, LDPBUFSIZ - buflen, - " Targeted Hello: %s%s", log_addr(adj->af, - &adj->src_addr), VTY_NEWLINE); - } + snprintf(buffer + buflen, LDPBUFSIZ - buflen, + " Targeted Hello: %s%s", log_addr(adj->af, + &adj->src_addr), VTY_NEWLINE); break; } } static int -show_nbr_msg(struct vty *vty, struct imsg *imsg, struct show_filter *filter, - json_object *json, struct in_addr *nbr_id) +show_nbr_msg(struct vty *vty, struct imsg *imsg, struct show_params *params) { - struct ctl_adj *adj; struct ctl_nbr *nbr; + struct ctl_adj *adj; static char v4adjs_buffer[LDPBUFSIZ]; static char v6adjs_buffer[LDPBUFSIZ]; - json_object *json_nbr = NULL; switch (imsg->hdr.type) { case IMSG_CTL_SHOW_NBR: nbr = imsg->data; - if (json) { - /* Remember the nbr->id so when we are in the other - * case statements below we know what nbr we are - * dealing with - */ - *nbr_id = nbr->id; - json_nbr = json_object_new_object(); - json_object_string_add(json_nbr, "peerId", inet_ntoa(nbr->id)); - json_object_string_add(json_nbr, "tcpLocalAddress", log_addr(nbr->af, &nbr->laddr)); - json_object_int_add(json_nbr, "tcpLocalPort", ntohs(nbr->lport)); - json_object_string_add(json_nbr, "tcpRemoteAddress", log_addr(nbr->af, &nbr->raddr)); - json_object_int_add(json_nbr, "tcpRemotePort", ntohs(nbr->rport)); - json_object_int_add(json_nbr, "holdtime", nbr->holdtime); - json_object_string_add(json_nbr, "state", nbr_state_name(nbr->nbr_state)); - json_object_boolean_true_add(json_nbr, "downstreamUnsolicited"); - json_object_string_add(json_nbr, "upTime", log_time(nbr->uptime)); - json_object_object_add(json, inet_ntoa(nbr->id), json_nbr); - - } else { - v4adjs_buffer[0] = '\0'; - v6adjs_buffer[0] = '\0'; - vty_out(vty, "Peer LDP Identifier: %s:0%s", inet_ntoa(nbr->id), - VTY_NEWLINE); - vty_out(vty, " TCP connection: %s:%u - %s:%u%s", - log_addr(nbr->af, &nbr->laddr), ntohs(nbr->lport), - log_addr(nbr->af, &nbr->raddr), ntohs(nbr->rport), - VTY_NEWLINE); - vty_out(vty, " Session Holdtime: %u sec%s", nbr->holdtime, - VTY_NEWLINE); - vty_out(vty, " State: %s; Downstream-Unsolicited%s", - nbr_state_name(nbr->nbr_state), VTY_NEWLINE); - vty_out(vty, " Up time: %s%s", log_time(nbr->uptime), - VTY_NEWLINE); - } + v4adjs_buffer[0] = '\0'; + v6adjs_buffer[0] = '\0'; + vty_out(vty, "Peer LDP Identifier: %s:0%s", inet_ntoa(nbr->id), + VTY_NEWLINE); + vty_out(vty, " TCP connection: %s:%u - %s:%u%s", + log_addr(nbr->af, &nbr->laddr), ntohs(nbr->lport), + log_addr(nbr->af, &nbr->raddr), ntohs(nbr->rport), + VTY_NEWLINE); + vty_out(vty, " Session Holdtime: %u sec%s", nbr->holdtime, + VTY_NEWLINE); + vty_out(vty, " State: %s; Downstream-Unsolicited%s", + nbr_state_name(nbr->nbr_state), VTY_NEWLINE); + vty_out(vty, " Up time: %s%s", log_time(nbr->uptime), + VTY_NEWLINE); break; case IMSG_CTL_SHOW_NBR_DISC: adj = imsg->data; - /* get the json_nbr by looking for the nbr_id key */ - if (json) - json_object_object_get_ex(json, inet_ntoa(*nbr_id), &json_nbr); - switch (adj->af) { case AF_INET: - show_nbr_adj(vty, v4adjs_buffer, adj, json_nbr); + show_nbr_adj(vty, v4adjs_buffer, adj); break; case AF_INET6: - show_nbr_adj(vty, v6adjs_buffer, adj, json_nbr); + show_nbr_adj(vty, v6adjs_buffer, adj); break; default: fatalx("show_nbr_msg: unknown af"); - } + } + break; + case IMSG_CTL_SHOW_NBR_END: + vty_out(vty, " LDP Discovery Sources:%s", VTY_NEWLINE); + if (v4adjs_buffer[0] != '\0') { + vty_out(vty, " IPv4:%s", VTY_NEWLINE); + vty_out(vty, "%s", v4adjs_buffer); + } + if (v6adjs_buffer[0] != '\0') { + vty_out(vty, " IPv6:%s", VTY_NEWLINE); + vty_out(vty, "%s", v6adjs_buffer); + } + vty_out(vty, "%s", VTY_NEWLINE); + break; + case IMSG_CTL_END: + return (1); + default: + break; + } + + return (0); +} + +static void +show_nbr_adj_json(struct ctl_adj *adj, json_object *adj_list) +{ + char adj_string[128]; + + switch (adj->type) { + case HELLO_LINK: + strlcpy(adj_string, "interface: ", sizeof(adj_string)); + strlcat(adj_string, adj->ifname, sizeof(adj_string)); + break; + case HELLO_TARGETED: + strlcpy(adj_string, "targetedHello: ", sizeof(adj_string)); + strlcat(adj_string, log_addr(adj->af, &adj->src_addr), + sizeof(adj_string)); + break; + } + + json_object_array_add(adj_list, json_object_new_string(adj_string)); +} + +static int +show_nbr_msg_json(struct imsg *imsg, struct show_params *params, + json_object *json) +{ + struct ctl_nbr *nbr; + struct ctl_adj *adj; + json_object *json_nbr; + static json_object *json_nbr_sources; + static json_object *json_v4adjs; + static json_object *json_v6adjs; + + switch (imsg->hdr.type) { + case IMSG_CTL_SHOW_NBR: + nbr = imsg->data; + + json_nbr = json_object_new_object(); + json_object_string_add(json_nbr, "peerId", inet_ntoa(nbr->id)); + json_object_string_add(json_nbr, "tcpLocalAddress", + log_addr(nbr->af, &nbr->laddr)); + json_object_int_add(json_nbr, "tcpLocalPort", + ntohs(nbr->lport)); + json_object_string_add(json_nbr, "tcpRemoteAddress", + log_addr(nbr->af, &nbr->raddr)); + json_object_int_add(json_nbr, "tcpRemotePort", + ntohs(nbr->rport)); + json_object_int_add(json_nbr, "holdtime", nbr->holdtime); + json_object_string_add(json_nbr, "state", + nbr_state_name(nbr->nbr_state)); + json_object_string_add(json_nbr, "upTime", + log_time(nbr->uptime)); + json_object_object_add(json, inet_ntoa(nbr->id), json_nbr); + + json_nbr_sources = json_object_new_object(); + json_object_object_add(json_nbr, "discoverySources", + json_nbr_sources); + json_v4adjs = NULL; + json_v6adjs = NULL; + break; + case IMSG_CTL_SHOW_NBR_DISC: + adj = imsg->data; + + switch (adj->af) { + case AF_INET: + if (!json_v4adjs) { + json_v4adjs = json_object_new_array(); + json_object_object_add(json_nbr_sources, "ipv4", + json_v4adjs); + } + show_nbr_adj_json(adj, json_v4adjs); + break; + case AF_INET6: + if (!json_v6adjs) { + json_v6adjs = json_object_new_array(); + json_object_object_add(json_nbr_sources, "ipv6", + json_v6adjs); + } + show_nbr_adj_json(adj, json_v6adjs); + break; + default: + fatalx("show_nbr_msg_json: unknown af"); + } break; case IMSG_CTL_SHOW_NBR_END: - /* For the json scenario the adjacencies were already added - * in show_nbr_adj - */ - if (!json) { - vty_out(vty, " LDP Discovery Sources:%s", VTY_NEWLINE); - if (v4adjs_buffer[0] != '\0') { - vty_out(vty, " IPv4:%s", VTY_NEWLINE); - vty_out(vty, "%s", v4adjs_buffer); - } - if (v6adjs_buffer[0] != '\0') { - vty_out(vty, " IPv6:%s", VTY_NEWLINE); - vty_out(vty, "%s", v6adjs_buffer); - } - vty_out(vty, "%s", VTY_NEWLINE); - } break; case IMSG_CTL_END: return (1); @@ -418,66 +535,40 @@ show_nbr_msg(struct vty *vty, struct imsg *imsg, struct show_filter *filter, } static int -show_lib_msg(struct vty *vty, struct imsg *imsg, struct show_filter *filter, json_object *json) +show_lib_msg(struct vty *vty, struct imsg *imsg, struct show_params *params) { struct ctl_rt *rt; char dstnet[BUFSIZ]; - json_object *json_binding = NULL; - json_object *json_remote_label = NULL; - json_object *json_remote_labels = NULL; switch (imsg->hdr.type) { case IMSG_CTL_SHOW_LIB: rt = imsg->data; - if (filter->family != AF_UNSPEC && filter->family != rt->af) + if (params->family != AF_UNSPEC && params->family != rt->af) break; snprintf(dstnet, sizeof(dstnet), "%s/%d", - log_addr(rt->af, &rt->prefix), rt->prefixlen); - - if (json) { - if (rt->first) { - json_binding = json_object_new_object(); - json_object_string_add(json_binding, "localLabel", log_label(rt->local_label)); - - json_remote_labels = json_object_new_array(); - json_object_object_add(json_binding, "remoteLabel", json_remote_labels); - - json_object_object_add(json, dstnet, json_binding); - } else { - json_object_object_get_ex(json, dstnet, &json_binding); - } - - if (rt->remote_label != NO_LABEL) { - json_object_object_get_ex(json_binding, "remoteLabel", &json_remote_labels); - json_remote_label = json_object_new_object(); - json_object_string_add(json_remote_label, "nexthop", inet_ntoa(rt->nexthop)); - json_object_string_add(json_remote_label, "label", log_label(rt->remote_label)); - json_object_array_add(json_remote_labels, json_remote_label); - } - - } else { - if (rt->first) { - vty_out(vty, "%s%s", dstnet, VTY_NEWLINE); - vty_out(vty, "%-8sLocal binding: label: %s%s", "", - log_label(rt->local_label), VTY_NEWLINE); - - if (rt->remote_label != NO_LABEL) { - vty_out(vty, "%-8sRemote bindings:%s", "", - VTY_NEWLINE); - vty_out(vty, "%-12sPeer Label%s", - "", VTY_NEWLINE); - vty_out(vty, "%-12s----------------- " - "---------%s", "", VTY_NEWLINE); - } else - vty_out(vty, "%-8sNo remote bindings%s", "", - VTY_NEWLINE); - } - if (rt->remote_label != NO_LABEL) - vty_out(vty, "%12s%-20s%s%s", "", inet_ntoa(rt->nexthop), - log_label(rt->remote_label), VTY_NEWLINE); - } + log_addr(rt->af, &rt->prefix), rt->prefixlen); + + if (rt->first) { + vty_out(vty, "%s%s", dstnet, VTY_NEWLINE); + vty_out(vty, "%-8sLocal binding: label: %s%s", "", + log_label(rt->local_label), VTY_NEWLINE); + + if (rt->remote_label != NO_LABEL) { + vty_out(vty, "%-8sRemote bindings:%s", "", + VTY_NEWLINE); + vty_out(vty, "%-12sPeer Label%s", + "", VTY_NEWLINE); + vty_out(vty, "%-12s----------------- " + "---------%s", "", VTY_NEWLINE); + } else + vty_out(vty, "%-8sNo remote bindings%s", "", + VTY_NEWLINE); + } + if (rt->remote_label != NO_LABEL) + vty_out(vty, "%12s%-20s%s%s", "", inet_ntoa(rt->nexthop), + log_label(rt->remote_label), VTY_NEWLINE); break; case IMSG_CTL_END: vty_out(vty, "%s", VTY_NEWLINE); @@ -490,7 +581,58 @@ show_lib_msg(struct vty *vty, struct imsg *imsg, struct show_filter *filter, jso } static int -show_l2vpn_binding_msg(struct vty *vty, struct imsg *imsg) +show_lib_msg_json(struct imsg *imsg, struct show_params *params, + json_object *json) +{ + struct ctl_rt *rt; + char dstnet[BUFSIZ]; + static json_object *json_binding; + static json_object *json_remote_labels; + json_object *json_remote_label; + + switch (imsg->hdr.type) { + case IMSG_CTL_SHOW_LIB: + rt = imsg->data; + + if (params->family != AF_UNSPEC && params->family != rt->af) + break; + + snprintf(dstnet, sizeof(dstnet), "%s/%d", + log_addr(rt->af, &rt->prefix), rt->prefixlen); + + if (rt->first) { + json_binding = json_object_new_object(); + json_object_string_add(json_binding, "localLabel", + log_label(rt->local_label)); + + json_remote_labels = json_object_new_array(); + json_object_object_add(json_binding, "remoteLabels", + json_remote_labels); + json_object_object_add(json, dstnet, json_binding); + } + + if (rt->remote_label != NO_LABEL) { + json_remote_label = json_object_new_object(); + json_object_string_add(json_remote_label, "nexthop", + inet_ntoa(rt->nexthop)); + json_object_string_add(json_remote_label, "label", + log_label(rt->remote_label)); + json_object_array_add(json_remote_labels, + json_remote_label); + } + break; + case IMSG_CTL_END: + return (1); + default: + break; + } + + return (0); +} + +static int +show_l2vpn_binding_msg(struct vty *vty, struct imsg *imsg, + struct show_params *params) { struct ctl_pw *pw; @@ -540,7 +682,68 @@ show_l2vpn_binding_msg(struct vty *vty, struct imsg *imsg) } static int -show_l2vpn_pw_msg(struct vty *vty, struct imsg *imsg) +show_l2vpn_binding_msg_json(struct imsg *imsg, struct show_params *params, + json_object *json) +{ + struct ctl_pw *pw; + json_object *json_pw; + char key_name[64]; + + switch (imsg->hdr.type) { + case IMSG_CTL_SHOW_L2VPN_BINDING: + pw = imsg->data; + + json_pw = json_object_new_object(); + json_object_string_add(json_pw, "destination", + inet_ntoa(pw->lsr_id)); + json_object_int_add(json_pw, "vcId", pw->pwid); + + /* local binding */ + if (pw->local_label != NO_LABEL) { + json_object_int_add(json_pw, "localLabel", + pw->local_label); + json_object_int_add(json_pw, "localControlWord", + pw->local_cword); + json_object_string_add(json_pw, "localVcType", + pw_type_name(pw->type)); + json_object_int_add(json_pw, "localGroupID", + pw->local_gid); + json_object_int_add(json_pw, "localIfMtu", + pw->local_ifmtu); + } else + json_object_string_add(json_pw, "localLabel", + "unassigned"); + + /* remote binding */ + if (pw->remote_label != NO_LABEL) { + json_object_int_add(json_pw, "remoteLabel", + pw->remote_label); + json_object_int_add(json_pw, "remoteControlWord", + pw->remote_cword); + json_object_string_add(json_pw, "remoteVcType", + pw_type_name(pw->type)); + json_object_int_add(json_pw, "remoteGroupID", + pw->remote_gid); + json_object_int_add(json_pw, "remoteIfMtu", + pw->remote_ifmtu); + } else + json_object_string_add(json_pw, "remoteLabel", + "unassigned"); + + sprintf(key_name, "%s: %u", inet_ntoa(pw->lsr_id), pw->pwid); + json_object_object_add(json, key_name, json_pw); + break; + case IMSG_CTL_END: + return (1); + default: + break; + } + + return (0); +} + +static int +show_l2vpn_pw_msg(struct vty *vty, struct imsg *imsg, struct show_params *params) { struct ctl_pw *pw; @@ -563,6 +766,36 @@ show_l2vpn_pw_msg(struct vty *vty, struct imsg *imsg) } static int +show_l2vpn_pw_msg_json(struct imsg *imsg, struct show_params *params, + json_object *json) +{ + struct ctl_pw *pw; + json_object *json_pw; + + switch (imsg->hdr.type) { + case IMSG_CTL_SHOW_L2VPN_PW: + pw = imsg->data; + + json_pw = json_object_new_object(); + json_object_string_add(json_pw, "peerId", inet_ntoa(pw->lsr_id)); + json_object_int_add(json_pw, "vcId", pw->pwid); + json_object_string_add(json_pw, "VpnName", pw->l2vpn_name); + if (pw->status) + json_object_string_add(json_pw, "status", "up"); + else + json_object_string_add(json_pw, "status", "down"); + json_object_object_add(json, pw->ifname, json_pw); + break; + case IMSG_CTL_END: + return (1); + default: + break; + } + + return (0); +} + +static int ldp_vty_connect(struct imsgbuf *ibuf) { struct sockaddr_un s_un; @@ -589,13 +822,46 @@ ldp_vty_connect(struct imsgbuf *ibuf) } static int +ldp_vty_dispatch_msg(struct vty *vty, struct imsg *imsg, enum show_command cmd, + struct show_params *params, json_object *json) +{ + switch (cmd) { + case SHOW_IFACE: + if (json) + return (show_interface_msg_json(imsg, params, json)); + return (show_interface_msg(vty, imsg, params)); + case SHOW_DISC: + if (json) + return (show_discovery_msg_json(imsg, params, json)); + return (show_discovery_msg(vty, imsg, params)); + case SHOW_NBR: + if (json) + return (show_nbr_msg_json(imsg, params, json)); + return (show_nbr_msg(vty, imsg, params)); + case SHOW_LIB: + if (json) + return (show_lib_msg_json(imsg, params, json)); + return (show_lib_msg(vty, imsg, params)); + case SHOW_L2VPN_PW: + if (json) + return (show_l2vpn_pw_msg_json(imsg, params, json)); + return (show_l2vpn_pw_msg(vty, imsg, params)); + case SHOW_L2VPN_BINDING: + if (json) + return (show_l2vpn_binding_msg_json(imsg, params, json)); + return (show_l2vpn_binding_msg(vty, imsg, params)); + default: + return (0); + } +} + +static int ldp_vty_dispatch(struct vty *vty, struct imsgbuf *ibuf, enum show_command cmd, - struct show_filter *filter, u_char uj) + struct show_params *params) { struct imsg imsg; - int n, done = 0; - struct in_addr nbr_id; - json_object *json = NULL; + int n, done = 0, ret = CMD_SUCCESS; + json_object *json = NULL; while (ibuf->w.queued) if (msgbuf_write(&ibuf->w) <= 0 && errno != EAGAIN) { @@ -604,83 +870,44 @@ ldp_vty_dispatch(struct vty *vty, struct imsgbuf *ibuf, enum show_command cmd, return (CMD_WARNING); } - if (uj) - json = json_object_new_object(); + if (params->json) + json = json_object_new_object(); while (!done) { if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN) { log_warnx("imsg_read error"); - close(ibuf->fd); - if (json) { - vty_out (vty, "%s%s", - json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), - VTY_NEWLINE); - json_object_free(json); - } - return (CMD_WARNING); + ret = CMD_WARNING; + goto done; } if (n == 0) { log_warnx("pipe closed"); - close(ibuf->fd); - if (json) { - vty_out (vty, "%s%s", - json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), - VTY_NEWLINE); - json_object_free(json); - } - return (CMD_WARNING); + ret = CMD_WARNING; + goto done; } while (!done) { if ((n = imsg_get(ibuf, &imsg)) == -1) { log_warnx("imsg_get error"); - close(ibuf->fd); - if (json) { - vty_out (vty, "%s%s", - json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), - VTY_NEWLINE); - json_object_free(json); - } - return (CMD_WARNING); + ret = CMD_WARNING; + goto done; } if (n == 0) break; - switch (cmd) { - case SHOW_IFACE: - done = show_interface_msg(vty, &imsg, filter, json); - break; - case SHOW_DISC: - done = show_discovery_msg(vty, &imsg, filter, json); - break; - case SHOW_NBR: - done = show_nbr_msg(vty, &imsg, filter, json, &nbr_id); - break; - case SHOW_LIB: - done = show_lib_msg(vty, &imsg, filter, json); - break; - case SHOW_L2VPN_PW: - done = show_l2vpn_pw_msg(vty, &imsg); - break; - case SHOW_L2VPN_BINDING: - done = show_l2vpn_binding_msg(vty, &imsg); - break; - default: - break; - } + done = ldp_vty_dispatch_msg(vty, &imsg, cmd, params, + json); imsg_free(&imsg); } } + done: close(ibuf->fd); + if (json) { + vty_out(vty, "%s%s", json_object_to_json_string_ext(json, + JSON_C_TO_STRING_PRETTY), VTY_NEWLINE); + json_object_free(json); + } - if (json) { - vty_out (vty, "%s%s", - json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), - VTY_NEWLINE); - json_object_free(json); - } - - return (CMD_SUCCESS); + return (ret); } static int @@ -701,56 +928,56 @@ ldp_vty_get_af(const char *str, int *af) } int -ldp_vty_show_binding(struct vty *vty, struct vty_arg *args[], u_char uj) +ldp_vty_show_binding(struct vty *vty, struct vty_arg *args[]) { struct imsgbuf ibuf; - struct show_filter filter; + struct show_params params; const char *af_str; int af; if (ldp_vty_connect(&ibuf) < 0) return (CMD_WARNING); - imsg_compose(&ibuf, IMSG_CTL_SHOW_LIB, 0, 0, -1, NULL, 0); - af_str = vty_get_arg_value(args, "address-family"); if (ldp_vty_get_af(af_str, &af) < 0) return (CMD_ERR_NO_MATCH); - memset(&filter, 0, sizeof(filter)); - filter.family = af; + memset(¶ms, 0, sizeof(params)); + params.family = af; + params.json = vty_get_arg_value(args, "json") ? 1 : 0; - return (ldp_vty_dispatch(vty, &ibuf, SHOW_LIB, &filter, uj)); + imsg_compose(&ibuf, IMSG_CTL_SHOW_LIB, 0, 0, -1, NULL, 0); + return (ldp_vty_dispatch(vty, &ibuf, SHOW_LIB, ¶ms)); } int -ldp_vty_show_discovery(struct vty *vty, struct vty_arg *args[], u_char uj) +ldp_vty_show_discovery(struct vty *vty, struct vty_arg *args[]) { struct imsgbuf ibuf; - struct show_filter filter; + struct show_params params; const char *af_str; int af; if (ldp_vty_connect(&ibuf) < 0) return (CMD_WARNING); - imsg_compose(&ibuf, IMSG_CTL_SHOW_DISCOVERY, 0, 0, -1, NULL, 0); - af_str = vty_get_arg_value(args, "address-family"); if (ldp_vty_get_af(af_str, &af) < 0) return (CMD_ERR_NO_MATCH); - memset(&filter, 0, sizeof(filter)); - filter.family = af; + memset(¶ms, 0, sizeof(params)); + params.family = af; + params.json = vty_get_arg_value(args, "json") ? 1 : 0; - return (ldp_vty_dispatch(vty, &ibuf, SHOW_DISC, &filter, uj)); + imsg_compose(&ibuf, IMSG_CTL_SHOW_DISCOVERY, 0, 0, -1, NULL, 0); + return (ldp_vty_dispatch(vty, &ibuf, SHOW_DISC, ¶ms)); } int -ldp_vty_show_interface(struct vty *vty, struct vty_arg *args[], u_char uj) +ldp_vty_show_interface(struct vty *vty, struct vty_arg *args[]) { struct imsgbuf ibuf; - struct show_filter filter; + struct show_params params; unsigned int ifidx = 0; const char *af_str; int af; @@ -758,81 +985,82 @@ ldp_vty_show_interface(struct vty *vty, struct vty_arg *args[], u_char uj) if (ldp_vty_connect(&ibuf) < 0) return (CMD_WARNING); - imsg_compose(&ibuf, IMSG_CTL_SHOW_INTERFACE, 0, 0, -1, &ifidx, - sizeof(ifidx)); - af_str = vty_get_arg_value(args, "address-family"); if (ldp_vty_get_af(af_str, &af) < 0) return (CMD_ERR_NO_MATCH); - memset(&filter, 0, sizeof(filter)); - filter.family = af; + memset(¶ms, 0, sizeof(params)); + params.family = af; + params.json = vty_get_arg_value(args, "json") ? 1 : 0; /* header */ - if (!uj) { - vty_out(vty, "%-4s %-11s %-6s %-8s %-12s %3s%s", "AF", - "Interface", "State", "Uptime", "Hello Timers", "ac", VTY_NEWLINE); - } + if (!params.json) { + vty_out(vty, "%-4s %-11s %-6s %-8s %-12s %3s%s", "AF", + "Interface", "State", "Uptime", "Hello Timers", "ac", + VTY_NEWLINE); + } - return (ldp_vty_dispatch(vty, &ibuf, SHOW_IFACE, &filter, uj)); + imsg_compose(&ibuf, IMSG_CTL_SHOW_INTERFACE, 0, 0, -1, &ifidx, + sizeof(ifidx)); + return (ldp_vty_dispatch(vty, &ibuf, SHOW_IFACE, ¶ms)); } int -ldp_vty_show_neighbor(struct vty *vty, struct vty_arg *args[], u_char uj) +ldp_vty_show_neighbor(struct vty *vty, struct vty_arg *args[]) { struct imsgbuf ibuf; - struct show_filter filter; + struct show_params params; if (ldp_vty_connect(&ibuf) < 0) return (CMD_WARNING); - imsg_compose(&ibuf, IMSG_CTL_SHOW_NBR, 0, 0, -1, NULL, 0); - - /* not used */ - memset(&filter, 0, sizeof(filter)); + memset(¶ms, 0, sizeof(params)); + params.json = vty_get_arg_value(args, "json") ? 1 : 0; - return (ldp_vty_dispatch(vty, &ibuf, SHOW_NBR, &filter, uj)); + imsg_compose(&ibuf, IMSG_CTL_SHOW_NBR, 0, 0, -1, NULL, 0); + return (ldp_vty_dispatch(vty, &ibuf, SHOW_NBR, ¶ms)); } int ldp_vty_show_atom_binding(struct vty *vty, struct vty_arg *args[]) { struct imsgbuf ibuf; - struct show_filter filter; + struct show_params params; if (ldp_vty_connect(&ibuf) < 0) return (CMD_WARNING); - imsg_compose(&ibuf, IMSG_CTL_SHOW_L2VPN_BINDING, 0, 0, -1, NULL, 0); - - /* not used */ - memset(&filter, 0, sizeof(filter)); + memset(¶ms, 0, sizeof(params)); + params.json = vty_get_arg_value(args, "json") ? 1 : 0; - return (ldp_vty_dispatch(vty, &ibuf, SHOW_L2VPN_BINDING, &filter, 0)); + imsg_compose(&ibuf, IMSG_CTL_SHOW_L2VPN_BINDING, 0, 0, -1, NULL, 0); + return (ldp_vty_dispatch(vty, &ibuf, SHOW_L2VPN_BINDING, ¶ms)); } int ldp_vty_show_atom_vc(struct vty *vty, struct vty_arg *args[]) { struct imsgbuf ibuf; - struct show_filter filter; + struct show_params params; if (ldp_vty_connect(&ibuf) < 0) return (CMD_WARNING); - imsg_compose(&ibuf, IMSG_CTL_SHOW_L2VPN_PW, 0, 0, -1, NULL, 0); - - /* not used */ - memset(&filter, 0, sizeof(filter)); - - /* header */ - vty_out(vty, "%-9s %-15s %-10s %-16s %-10s%s", - "Interface", "Peer ID", "VC ID", "Name", "Status", VTY_NEWLINE); - vty_out(vty, "%-9s %-15s %-10s %-16s %-10s%s", - "---------", "---------------", "----------", - "----------------", "----------", VTY_NEWLINE); + memset(¶ms, 0, sizeof(params)); + params.json = vty_get_arg_value(args, "json") ? 1 : 0; + + if (!params.json) { + /* header */ + vty_out(vty, "%-9s %-15s %-10s %-16s %-10s%s", + "Interface", "Peer ID", "VC ID", "Name", "Status", + VTY_NEWLINE); + vty_out(vty, "%-9s %-15s %-10s %-16s %-10s%s", + "---------", "---------------", "----------", + "----------------", "----------", VTY_NEWLINE); + } - return (ldp_vty_dispatch(vty, &ibuf, SHOW_L2VPN_PW, &filter, 0)); + imsg_compose(&ibuf, IMSG_CTL_SHOW_L2VPN_PW, 0, 0, -1, NULL, 0); + return (ldp_vty_dispatch(vty, &ibuf, SHOW_L2VPN_PW, ¶ms)); } int |
