diff options
author | Donald Sharp <sharpd@cumulusnetworks.com> | 2015-07-22 21:35:36 +0200 |
---|---|---|
committer | Donald Sharp <sharpd@cumulusnetworks.com> | 2015-07-22 21:35:36 +0200 |
commit | 7ec4159b237ea62c903840b218bd8b12aec59fe9 (patch) | |
tree | 2e865db51073b12151053d0ed3c72e10e82f5b39 /ospfd | |
parent | Add json capability to the ospf commands: "show ip ospf" and "show ip ospf <1... (diff) | |
download | frr-7ec4159b237ea62c903840b218bd8b12aec59fe9.tar.xz frr-7ec4159b237ea62c903840b218bd8b12aec59fe9.zip |
Add json capability to the "show ip ospf interface [INTERFACE]" and "show ip ospf <1-65535> interface [INTERFACE]" commands and whatever functions that they call. Option shows up as {json}.
Diffstat (limited to 'ospfd')
-rw-r--r-- | ospfd/ospf_vty.c | 413 |
1 files changed, 296 insertions, 117 deletions
diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index ac4320d54..306697b02 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -22,6 +22,7 @@ #include <zebra.h> #include <json/json.h> +#include <string.h> #include "memory.h" #include "thread.h" @@ -3512,49 +3513,92 @@ DEFUN (show_ip_ospf_instance, } static void -show_ip_ospf_interface_sub (struct vty *vty, struct ospf *ospf, - struct interface *ifp) +show_ip_ospf_interface_sub (struct vty *vty, struct ospf *ospf, struct interface *ifp, + json_object *json_interface_sub, u_char use_json) { int is_up; struct ospf_neighbor *nbr; struct route_node *rn; /* Is interface up? */ - vty_out (vty, "%s is %s%s", ifp->name, - ((is_up = if_is_operative(ifp)) ? "up" : "down"), VTY_NEWLINE); - vty_out (vty, " ifindex %u, MTU %u bytes, BW %u Kbit %s%s", - ifp->ifindex, ifp->mtu, ifp->bandwidth, if_flag_dump(ifp->flags), - VTY_NEWLINE); + if (use_json) + { + is_up = if_is_operative(ifp); + if (is_up) + json_object_boolean_true_add(json_interface_sub, "ifUp"); + else + json_object_boolean_false_add(json_interface_sub, "ifDown"); + + json_object_int_add(json_interface_sub, "ifIndex", ifp->ifindex); + json_object_int_add(json_interface_sub, "mtuBytes", ifp->mtu); + json_object_int_add(json_interface_sub, "bandwidthKbit", ifp->bandwidth); + json_object_string_add(json_interface_sub, "ifFlags", if_flag_dump(ifp->flags)); + } + else + { + vty_out (vty, "%s is %s%s", ifp->name, + ((is_up = if_is_operative(ifp)) ? "up" : "down"), VTY_NEWLINE); + vty_out (vty, " ifindex %u, MTU %u bytes, BW %u Kbit %s%s", + ifp->ifindex, ifp->mtu, ifp->bandwidth, if_flag_dump(ifp->flags), + VTY_NEWLINE); + } /* Is interface OSPF enabled? */ - if (ospf_oi_count(ifp) == 0) + if (use_json) { - vty_out (vty, " OSPF not enabled on this interface%s", VTY_NEWLINE); - return; + if (ospf_oi_count(ifp) == 0) + { + json_object_boolean_false_add(json_interface_sub, "ospfEnabled"); + return; + } + else if (!is_up) + { + json_object_boolean_false_add(json_interface_sub, "ospfRunning"); + return; + } + else + json_object_boolean_true_add(json_interface_sub, "ospfEnabled"); } - else if (!is_up) + else { - vty_out (vty, " OSPF is enabled, but not running on this interface%s", - VTY_NEWLINE); - return; + if (ospf_oi_count(ifp) == 0) + { + vty_out (vty, " OSPF not enabled on this interface%s", VTY_NEWLINE); + return; + } + else if (!is_up) + { + vty_out (vty, " OSPF is enabled, but not running on this interface%s", + VTY_NEWLINE); + return; + } } for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn)) { struct ospf_interface *oi = rn->info; - + if (oi == NULL) - continue; - + continue; + if (CHECK_FLAG(oi->connected->flags, ZEBRA_IFA_UNNUMBERED)) { - vty_out (vty, " This interface is UNNUMBERED,"); + if (use_json) + json_object_boolean_true_add(json_interface_sub, "ifUnnumbered"); + else + vty_out (vty, " This interface is UNNUMBERED,"); } else { /* Show OSPF interface information. */ - vty_out (vty, " Internet Address %s/%d,", - inet_ntoa (oi->address->u.prefix4), oi->address->prefixlen); + if (use_json) + { + json_object_string_add(json_interface_sub, "ipAddress", inet_ntoa (oi->address->u.prefix4)); + json_object_int_add(json_interface_sub, "ipAddressPrefixlen", oi->address->prefixlen); + } + else + vty_out (vty, " Internet Address %s/%d,", + inet_ntoa (oi->address->u.prefix4), oi->address->prefixlen); if (oi->connected->destination || oi->type == OSPF_IFTYPE_VIRTUALLINK) { @@ -3568,181 +3612,316 @@ show_ip_ospf_interface_sub (struct vty *vty, struct ospf *ospf, dstr = "Broadcast"; /* For Vlinks, showing the peer address is probably more - * informative than the local interface that is being used - */ + * * * * * informative than the local interface that is being used + * * * * */ if (oi->type == OSPF_IFTYPE_VIRTUALLINK) dest = &oi->vl_data->peer_addr; else dest = &oi->connected->destination->u.prefix4; - vty_out (vty, " %s %s,", dstr, inet_ntoa (*dest)); + if (use_json) + { + json_object_string_add(json_interface_sub, "ospfIfType", dstr); + if (oi->type == OSPF_IFTYPE_VIRTUALLINK) + json_object_string_add(json_interface_sub, "vlinkPeer", inet_ntoa (*dest)); + else + json_object_string_add(json_interface_sub, "localIfUsed", inet_ntoa (*dest)); + } + else + vty_out (vty, " %s %s,", dstr, inet_ntoa (*dest)); } } + if (use_json) + { + json_object_string_add(json_interface_sub, "area", ospf_area_desc_string (oi->area)); + if (OSPF_IF_PARAM(oi, mtu_ignore)) + json_object_boolean_true_add(json_interface_sub, "mtuMismatchDetect"); + json_object_string_add(json_interface_sub, "routerId", inet_ntoa (ospf->router_id)); + json_object_string_add(json_interface_sub, "networkType", ospf_network_type_str[oi->type]); + json_object_int_add(json_interface_sub, "cost", oi->output_cost); + json_object_int_add(json_interface_sub, "transmitDelayMsecs", 1000 / OSPF_IF_PARAM (oi,transmit_delay)); + json_object_string_add(json_interface_sub, "state", LOOKUP (ospf_ism_state_msg, oi->state)); + json_object_int_add(json_interface_sub, "priority", PRIORITY (oi)); + } + else + { + vty_out (vty, " Area %s%s", ospf_area_desc_string (oi->area), + VTY_NEWLINE); - vty_out (vty, " Area %s%s", ospf_area_desc_string (oi->area), - VTY_NEWLINE); - - vty_out (vty, " MTU mismatch detection:%s%s", - OSPF_IF_PARAM(oi, mtu_ignore) ? "disabled" : "enabled", VTY_NEWLINE); + vty_out (vty, " MTU mismatch detection:%s%s", + OSPF_IF_PARAM(oi, mtu_ignore) ? "disabled" : "enabled", VTY_NEWLINE); - vty_out (vty, " Router ID %s, Network Type %s, Cost: %d%s", - inet_ntoa (ospf->router_id), ospf_network_type_str[oi->type], - oi->output_cost, VTY_NEWLINE); + vty_out (vty, " Router ID %s, Network Type %s, Cost: %d%s", + inet_ntoa (ospf->router_id), ospf_network_type_str[oi->type], + oi->output_cost, VTY_NEWLINE); - vty_out (vty, " Transmit Delay is %d sec, State %s, Priority %d%s", - OSPF_IF_PARAM (oi,transmit_delay), LOOKUP (ospf_ism_state_msg, oi->state), - PRIORITY (oi), VTY_NEWLINE); + vty_out (vty, " Transmit Delay is %d sec, State %s, Priority %d%s", + OSPF_IF_PARAM (oi,transmit_delay), LOOKUP (ospf_ism_state_msg, oi->state), + PRIORITY (oi), VTY_NEWLINE); + } /* Show DR information. */ if (DR (oi).s_addr == 0) - vty_out (vty, " No designated router on this network%s", VTY_NEWLINE); - else - { - nbr = ospf_nbr_lookup_by_addr (oi->nbrs, &DR (oi)); - if (nbr == NULL) - vty_out (vty, " No designated router on this network%s", VTY_NEWLINE); - else - { - vty_out (vty, " Designated Router (ID) %s,", - inet_ntoa (nbr->router_id)); - vty_out (vty, " Interface Address %s%s", - inet_ntoa (nbr->address.u.prefix4), VTY_NEWLINE); - } - } - - /* Show BDR information. */ - if (BDR (oi).s_addr == 0) - vty_out (vty, " No backup designated router on this network%s", - VTY_NEWLINE); + { + if (!use_json) + vty_out (vty, " No backup designated router on this network%s", + VTY_NEWLINE); + } else - { - nbr = ospf_nbr_lookup_by_addr (oi->nbrs, &BDR (oi)); - if (nbr == NULL) - vty_out (vty, " No backup designated router on this network%s", - VTY_NEWLINE); - else - { - vty_out (vty, " Backup Designated Router (ID) %s,", - inet_ntoa (nbr->router_id)); - vty_out (vty, " Interface Address %s%s", - inet_ntoa (nbr->address.u.prefix4), VTY_NEWLINE); - } - } + { + nbr = ospf_nbr_lookup_by_addr (oi->nbrs, &BDR (oi)); + if (nbr == NULL) + { + if (!use_json) + vty_out (vty, " No backup designated router on this network%s", + VTY_NEWLINE); + } + else + { + if (use_json) + { + json_object_string_add(json_interface_sub, "bdrId", inet_ntoa (nbr->router_id)); + json_object_string_add(json_interface_sub, "bdrAddress", inet_ntoa (nbr->address.u.prefix4)); + } + else + { + vty_out (vty, " Backup Designated Router (ID) %s,", + inet_ntoa (nbr->router_id)); + vty_out (vty, " Interface Address %s%s", + inet_ntoa (nbr->address.u.prefix4), VTY_NEWLINE); + } + } + } /* Next network-LSA sequence number we'll use, if we're elected DR */ - if (oi->params && ntohl (oi->params->network_lsa_seqnum) - != OSPF_INITIAL_SEQUENCE_NUMBER) - vty_out (vty, " Saved Network-LSA sequence number 0x%x%s", - ntohl (oi->params->network_lsa_seqnum), VTY_NEWLINE); - - vty_out (vty, " Multicast group memberships:"); - if (OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS) - || OI_MEMBER_CHECK(oi, MEMBER_DROUTERS)) + if (oi->params && ntohl (oi->params->network_lsa_seqnum) != OSPF_INITIAL_SEQUENCE_NUMBER) { - if (OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS)) - vty_out (vty, " OSPFAllRouters"); - if (OI_MEMBER_CHECK(oi, MEMBER_DROUTERS)) - vty_out (vty, " OSPFDesignatedRouters"); + if (use_json) + json_object_int_add(json_interface_sub, "networkLsaSequence", ntohl (oi->params->network_lsa_seqnum)); + else + vty_out (vty, " Saved Network-LSA sequence number 0x%x%s", + ntohl (oi->params->network_lsa_seqnum), VTY_NEWLINE); + } + + if (use_json) + { + if (OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS) + || OI_MEMBER_CHECK(oi, MEMBER_DROUTERS)) + { + if (OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS)) + json_object_boolean_true_add(json_interface_sub, "mcastMemberOspfAllRouters"); + if (OI_MEMBER_CHECK(oi, MEMBER_DROUTERS)) + json_object_boolean_true_add(json_interface_sub, "mcastMemberOspfDesignatedRouters"); + } } else - vty_out (vty, " <None>"); - vty_out (vty, "%s", VTY_NEWLINE); + { + vty_out (vty, " Multicast group memberships:"); + if (OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS) + || OI_MEMBER_CHECK(oi, MEMBER_DROUTERS)) + { + if (OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS)) + vty_out (vty, " OSPFAllRouters"); + if (OI_MEMBER_CHECK(oi, MEMBER_DROUTERS)) + vty_out (vty, " OSPFDesignatedRouters"); + } + else + vty_out (vty, " <None>"); + vty_out (vty, "%s", VTY_NEWLINE); + } - vty_out (vty, " Timer intervals configured,"); - vty_out (vty, " Hello "); - if (OSPF_IF_PARAM (oi, fast_hello) == 0) - vty_out (vty, "%ds,", OSPF_IF_PARAM (oi, v_hello)); + if (use_json) + { + if (OSPF_IF_PARAM (oi, fast_hello) == 0) + json_object_int_add(json_interface_sub, "timerMsecs", 1000 /OSPF_IF_PARAM (oi, v_hello)); + else + json_object_int_add(json_interface_sub, "timerMsecs", 1000 / OSPF_IF_PARAM (oi, fast_hello)); + json_object_int_add(json_interface_sub, "timerDeadMsecs", 1000 / OSPF_IF_PARAM (oi, v_wait)); + json_object_int_add(json_interface_sub, "timerWaitMsecs", 1000 / OSPF_IF_PARAM (oi, v_wait)); + json_object_int_add(json_interface_sub, "timerRetransmit", 1000 / OSPF_IF_PARAM (oi, retransmit_interval)); + } else - vty_out (vty, "%dms,", 1000 / OSPF_IF_PARAM (oi, fast_hello)); - vty_out (vty, " Dead %ds, Wait %ds, Retransmit %d%s", - OSPF_IF_PARAM (oi, v_wait), - OSPF_IF_PARAM (oi, v_wait), - OSPF_IF_PARAM (oi, retransmit_interval), - VTY_NEWLINE); - + { + vty_out (vty, " Timer intervals configured,"); + vty_out (vty, " Hello "); + if (OSPF_IF_PARAM (oi, fast_hello) == 0) + vty_out (vty, "%ds,", OSPF_IF_PARAM (oi, v_hello)); + else + vty_out (vty, "%dms,", 1000 / OSPF_IF_PARAM (oi, fast_hello)); + vty_out (vty, " Dead %ds, Wait %ds, Retransmit %d%s", + OSPF_IF_PARAM (oi, v_wait), + OSPF_IF_PARAM (oi, v_wait), + OSPF_IF_PARAM (oi, retransmit_interval), + VTY_NEWLINE); + } + if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_ACTIVE) { - char timebuf[OSPF_TIME_DUMP_SIZE]; - vty_out (vty, " Hello due in %s%s", - ospf_timer_dump (oi->t_hello, timebuf, sizeof(timebuf)), - VTY_NEWLINE); + char timebuf[OSPF_TIME_DUMP_SIZE]; + if (use_json) + { + struct timeval result; + unsigned long time_store = 0; + result = tv_sub (oi->t_hello->u.sands, recent_relative_time()); + time_store = (1000 * result.tv_sec) + (result.tv_usec / 1000); + json_object_int_add(json_interface_sub, "timerHelloInMsecs", time_store); + } + else + vty_out (vty, " Hello due in %s%s", + ospf_timer_dump (oi->t_hello, timebuf, sizeof(timebuf)), + VTY_NEWLINE); } else /* passive-interface is set */ - vty_out (vty, " No Hellos (Passive interface)%s", VTY_NEWLINE); - - vty_out (vty, " Neighbor Count is %d, Adjacent neighbor count is %d%s", - ospf_nbr_count (oi, 0), ospf_nbr_count (oi, NSM_Full), - VTY_NEWLINE); + { + if (use_json) + json_object_boolean_true_add(json_interface_sub, "timerPassiveIface"); + else + vty_out (vty, " No Hellos (Passive interface)%s", VTY_NEWLINE); + } + + if (use_json) + { + json_object_int_add(json_interface_sub, "nbrCount", ospf_nbr_count (oi, 0)); + json_object_int_add(json_interface_sub, "nbrAdjacentCount", ospf_nbr_count (oi, NSM_Full)); + } + else + vty_out (vty, " Neighbor Count is %d, Adjacent neighbor count is %d%s", + ospf_nbr_count (oi, 0), ospf_nbr_count (oi, NSM_Full), + VTY_NEWLINE); } } static int -show_ip_ospf_interface_common (struct vty *vty, struct ospf *ospf, int arg_base, - int argc, const char **argv) +show_ip_ospf_interface_common (struct vty *vty, struct ospf *ospf, int argc, + const char **argv, int iface_argv, u_char use_json) { struct interface *ifp; struct listnode *node; + json_object *json = NULL; + json_object *json_interface_sub = NULL; + + if (use_json) + { + json = json_object_new_object(); + json_interface_sub = json_object_new_object(); + } if (ospf->instance) - vty_out (vty, "%sOSPF Instance: %d%s%s", VTY_NEWLINE, ospf->instance, - VTY_NEWLINE, VTY_NEWLINE); + { + if (use_json) + json_object_int_add(json, "ospfInstance", ospf->instance); + else + vty_out (vty, "%sOSPF Instance: %d%s%s", VTY_NEWLINE, ospf->instance, + VTY_NEWLINE, VTY_NEWLINE); + } - if (argc == arg_base + 0) + if (argc == (iface_argv + 1)) + { + /* Show All Interfaces.*/ + for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp)) + { + if (ospf_oi_count(ifp)) + { + show_ip_ospf_interface_sub (vty, ospf, ifp, json_interface_sub, use_json); + } + } + } + else if (argv[iface_argv] && strcmp(argv[iface_argv], "json") == 0) { /* Show All Interfaces. */ for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp)) - if (ospf_oi_count(ifp)) - show_ip_ospf_interface_sub (vty, ospf, ifp); + { + if (ospf_oi_count(ifp)) + { + show_ip_ospf_interface_sub (vty, ospf, ifp, json_interface_sub, use_json); + json_object_object_add(json, ifp->name, json_interface_sub); + } + } } else { /* Interface name is specified. */ - if ((ifp = if_lookup_by_name (argv[arg_base + 0])) == NULL) - vty_out (vty, "No such interface name%s", VTY_NEWLINE); + if ((ifp = if_lookup_by_name (argv[iface_argv])) == NULL) + { + if (use_json) + json_object_boolean_true_add(json, "noSuchIface"); + else + vty_out (vty, "No such interface name%s", VTY_NEWLINE); + } else - show_ip_ospf_interface_sub (vty, ospf, ifp); + { + show_ip_ospf_interface_sub (vty, ospf, ifp, json_interface_sub, use_json); + if (use_json) + json_object_object_add(json, ifp->name, json_interface_sub); + } } - vty_out (vty, "%s", VTY_NEWLINE); + if (use_json) + { + vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE); + json_object_free(json); + } + else + vty_out (vty, "%s", VTY_NEWLINE); return CMD_SUCCESS; } DEFUN (show_ip_ospf_interface, show_ip_ospf_interface_cmd, - "show ip ospf interface [INTERFACE]", + "show ip ospf interface [INTERFACE] {json}", SHOW_STR IP_STR "OSPF information\n" "Interface information\n" - "Interface name\n") + "Interface name\n" + "JavaScript Object Notation\n") { struct ospf *ospf; + u_char use_json; + + if (argc == 1) + use_json = 0; + else if ((argv[0] && strcmp(argv[0] ,"json") == 0) || + (argv[1] && strcmp(argv[1] ,"json") == 0)) + use_json = 1; + else + use_json = 0; if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running) return CMD_SUCCESS; - return show_ip_ospf_interface_common(vty, ospf, 0, argc, argv); + return show_ip_ospf_interface_common(vty, ospf, argc, argv, 0, use_json); } DEFUN (show_ip_ospf_instance_interface, show_ip_ospf_instance_interface_cmd, - "show ip ospf <1-65535> interface [INTERFACE]", + "show ip ospf <1-65535> interface [INTERFACE] {json}", SHOW_STR IP_STR "OSPF information\n" "Instance ID\n" "Interface information\n" - "Interface name\n") + "Interface name\n" + "JavaScript Object Notation\n") { struct ospf *ospf; u_short instance = 0; + u_char use_json; + + if (argc == 2) + use_json = 0; + else if ((argv[1] && strcmp(argv[1] ,"json") == 0) || + (argv[2] && strcmp(argv[2] ,"json") == 0)) + use_json = 1; + else + use_json = 0; VTY_GET_INTEGER ("Instance", instance, argv[0]); if ((ospf = ospf_lookup_instance (instance)) == NULL || !ospf->oi_running) return CMD_SUCCESS; - return show_ip_ospf_interface_common(vty, ospf, 1, argc, argv); + return show_ip_ospf_interface_common(vty, ospf, argc, argv, 1, use_json); } static void |