]> git.proxmox.com Git - mirror_frr.git/commitdiff
isisd: Add json to show isis interface command.
authorJavier Garcia <javier.martin.garcia@ibm.com>
Wed, 23 Feb 2022 15:51:07 +0000 (16:51 +0100)
committerJavier Garcia <javier.martin.garcia@ibm.com>
Fri, 25 Feb 2022 11:36:17 +0000 (12:36 +0100)
Signed-off-by: Javier Garcia <javier.martin.garcia@ibm.com>
doc/user/isisd.rst
isisd/isis_circuit.c
isisd/isis_circuit.h
isisd/isisd.c

index 2bb45a37f3e28f31bf6e603dc9e34082c170b6e0..d9497ea6ec96e74917909e61293607f7a778f98b 100644 (file)
@@ -280,7 +280,7 @@ Showing ISIS information
 
    Show information about ISIS node.
 
-.. clicmd:: show isis interface [detail] [IFNAME]
+.. clicmd:: show isis [vrf <NAME|all>] interface [detail] [IFNAME] [json]
 
    Show state and configuration of ISIS specified interface, or all interfaces
    if no interface is given with or without details.
index 1b0447226d975dde895dc5fe76427f27359e5d7e..da75f196ba5526de6538be5b80c8e123a134939a 100644 (file)
@@ -933,6 +933,151 @@ void circuit_update_nlpids(struct isis_circuit *circuit)
        return;
 }
 
+void isis_circuit_print_json(struct isis_circuit *circuit,
+                            struct json_object *json, char detail)
+{
+       int level;
+       json_object *iface_json, *ipv4_addr_json, *ipv6_link_json,
+               *ipv6_non_link_json, *hold_json, *lan_prio_json, *levels_json,
+               *level_json;
+       char buf_prx[INET6_BUFSIZ];
+       char buf[255];
+
+       snprintfrr(buf, sizeof(buf), "0x%x", circuit->circuit_id);
+       if (detail == ISIS_UI_LEVEL_BRIEF) {
+               iface_json = json_object_new_object();
+               json_object_object_add(json, "interface", iface_json);
+               json_object_string_add(iface_json, "name",
+                                      circuit->interface->name);
+               json_object_string_add(iface_json, "circuit-id", buf);
+               json_object_string_add(iface_json, "state",
+                                      circuit_state2string(circuit->state));
+               json_object_string_add(iface_json, "type",
+                                      circuit_type2string(circuit->circ_type));
+               json_object_string_add(iface_json, "level",
+                                      circuit_t2string(circuit->is_type));
+       }
+
+       if (detail == ISIS_UI_LEVEL_DETAIL) {
+               struct listnode *node;
+               struct prefix *ip_addr;
+
+               iface_json = json_object_new_object();
+               json_object_object_add(json, "interface", iface_json);
+               json_object_string_add(iface_json, "name",
+                                      circuit->interface->name);
+               json_object_string_add(iface_json, "state",
+                                      circuit_state2string(circuit->state));
+               if (circuit->is_passive)
+                       json_object_string_add(iface_json, "is-passive",
+                                              "passive");
+               else
+                       json_object_string_add(iface_json, "is-passive",
+                                              "active");
+               json_object_string_add(iface_json, "circuit-id", buf);
+               json_object_string_add(iface_json, "type",
+                                      circuit_type2string(circuit->circ_type));
+               json_object_string_add(iface_json, "level",
+                                      circuit_t2string(circuit->is_type));
+               if (circuit->circ_type == CIRCUIT_T_BROADCAST)
+                       json_object_string_add(iface_json, "snpa",
+                                              snpa_print(circuit->u.bc.snpa));
+
+
+               levels_json = json_object_new_array();
+               json_object_object_add(iface_json, "levels", levels_json);
+               for (level = ISIS_LEVEL1; level <= ISIS_LEVELS; level++) {
+                       if ((circuit->is_type & level) == 0)
+                               continue;
+                       level_json = json_object_new_object();
+                       json_object_string_add(level_json, "level",
+                                              circuit_t2string(level));
+                       if (circuit->area->newmetric)
+                               json_object_int_add(level_json, "metric",
+                                                   circuit->te_metric[0]);
+                       else
+                               json_object_int_add(level_json, "metric",
+                                                   circuit->metric[0]);
+                       if (!circuit->is_passive) {
+                               json_object_int_add(level_json,
+                                                   "active-neighbors",
+                                                   circuit->upadjcount[0]);
+                               json_object_int_add(level_json,
+                                                   "hello-interval",
+                                                   circuit->hello_interval[0]);
+                               hold_json = json_object_new_object();
+                               json_object_object_add(level_json, "holddown",
+                                                      hold_json);
+                               json_object_int_add(
+                                       hold_json, "count",
+                                       circuit->hello_multiplier[0]);
+                               json_object_string_add(
+                                       hold_json, "pad",
+                                       (circuit->pad_hellos ? "yes" : "no"));
+                               json_object_int_add(level_json, "cnsp-interval",
+                                                   circuit->csnp_interval[0]);
+                               json_object_int_add(level_json, "psnp-interval",
+                                                   circuit->psnp_interval[0]);
+                               if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
+                                       lan_prio_json =
+                                               json_object_new_object();
+                                       json_object_object_add(level_json,
+                                                              "lan",
+                                                              lan_prio_json);
+                                       json_object_int_add(
+                                               lan_prio_json, "priority",
+                                               circuit->priority[0]);
+                                       json_object_string_add(
+                                               lan_prio_json, "is-dis",
+                                               (circuit->u.bc.is_dr[0]
+                                                        ? "yes"
+                                                        : "no"));
+                               }
+                       }
+                       json_object_array_add(levels_json, level_json);
+               }
+
+               if (circuit->ip_addrs && listcount(circuit->ip_addrs) > 0) {
+                       ipv4_addr_json = json_object_new_object();
+                       json_object_object_add(iface_json, "ip-prefix",
+                                              ipv4_addr_json);
+                       for (ALL_LIST_ELEMENTS_RO(circuit->ip_addrs, node,
+                                                 ip_addr)) {
+                               snprintfrr(buf_prx, INET6_BUFSIZ, "%pFX",
+                                          ip_addr);
+                               json_object_string_add(ipv4_addr_json, "ip",
+                                                      buf_prx);
+                       }
+               }
+               if (circuit->ipv6_link && listcount(circuit->ipv6_link) > 0) {
+                       ipv6_link_json = json_object_new_object();
+                       json_object_object_add(iface_json, "ipv6-link-locals",
+                                              ipv6_link_json);
+                       for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_link, node,
+                                                 ip_addr)) {
+                               snprintfrr(buf_prx, INET6_BUFSIZ, "%pFX",
+                                          ip_addr);
+                               json_object_string_add(ipv6_link_json, "ipv6",
+                                                      buf_prx);
+                       }
+               }
+               if (circuit->ipv6_non_link &&
+                   listcount(circuit->ipv6_non_link) > 0) {
+                       ipv6_non_link_json = json_object_new_object();
+                       json_object_object_add(iface_json, "ipv6-prefixes",
+                                              ipv6_non_link_json);
+                       for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_non_link, node,
+                                                 ip_addr)) {
+                               snprintfrr(buf_prx, INET6_BUFSIZ, "%pFX",
+                                          ip_addr);
+                               json_object_string_add(ipv6_non_link_json,
+                                                      "ipv6", buf_prx);
+                       }
+               }
+       }
+       return;
+}
+
 void isis_circuit_print_vty(struct isis_circuit *circuit, struct vty *vty,
                            char detail)
 {
index 7465780848a02b186e4caa86b7cdab961cbaceda..5ff0390c26bf1fed78935430e4813f60211d747d 100644 (file)
@@ -206,6 +206,8 @@ void isis_circuit_down(struct isis_circuit *);
 void circuit_update_nlpids(struct isis_circuit *circuit);
 void isis_circuit_print_vty(struct isis_circuit *circuit, struct vty *vty,
                            char detail);
+void isis_circuit_print_json(struct isis_circuit *circuit,
+                            struct json_object *json, char detail);
 size_t isis_circuit_pdu_size(struct isis_circuit *circuit);
 void isis_circuit_stream(struct isis_circuit *circuit, struct stream **stream);
 
index 99bf7674a8dcd03e075f6afbb9d7d50e59df4520..5f9985ae831e9591735c0787d94db29bd7908a32 100644 (file)
@@ -109,12 +109,17 @@ DEFINE_HOOK(isis_hook_db_overload, (const struct isis_area *area), (area));
 int isis_area_get(struct vty *, const char *);
 int area_net_title(struct vty *, const char *);
 int area_clear_net_title(struct vty *, const char *);
-int show_isis_interface_common(struct vty *, const char *ifname, char,
-                              const char *vrf_name, bool all_vrf);
 int show_isis_neighbor_common(struct vty *, const char *id, char,
                              const char *vrf_name, bool all_vrf);
 int clear_isis_neighbor_common(struct vty *, const char *id, const char *vrf_name,
+int show_isis_interface_common(struct vty *, struct json_object *json,
+                              const char *ifname, char, const char *vrf_name,
                               bool all_vrf);
+int show_isis_interface_common_vty(struct vty *, const char *ifname, char,
+                                  const char *vrf_name, bool all_vrf);
+int show_isis_interface_common_json(struct json_object *json,
+                                   const char *ifname, char,
+                                   const char *vrf_name, bool all_vrf);
 
 /* Link ISIS instance to VRF. */
 void isis_vrf_link(struct isis *isis, struct vrf *vrf)
@@ -933,9 +938,101 @@ int area_clear_net_title(struct vty *vty, const char *net_title)
 /*
  * 'show isis interface' command
  */
-
-int show_isis_interface_common(struct vty *vty, const char *ifname, char detail,
+int show_isis_interface_common(struct vty *vty, struct json_object *json,
+                              const char *ifname, char detail,
                               const char *vrf_name, bool all_vrf)
+{
+       if (json) {
+               return show_isis_interface_common_json(json, ifname, detail,
+                                                      vrf_name, all_vrf);
+       } else {
+               return show_isis_interface_common_vty(vty, ifname, detail,
+                                                     vrf_name, all_vrf);
+       }
+}
+
+int show_isis_interface_common_json(struct json_object *json,
+                                   const char *ifname, char detail,
+                                   const char *vrf_name, bool all_vrf)
+{
+       struct listnode *anode, *cnode, *inode;
+       struct isis_area *area;
+       struct isis_circuit *circuit;
+       struct isis *isis;
+       struct json_object *areas_json, *area_json;
+       if (!im) {
+               // IS-IS Routing Process not enabled
+               json_object_string_add(json, "is-is-routing-process-enabled",
+                                      "no");
+               return CMD_SUCCESS;
+       }
+       if (vrf_name) {
+               if (all_vrf) {
+                       for (ALL_LIST_ELEMENTS_RO(im->isis, inode, isis)) {
+                               areas_json = json_object_new_array();
+                               json_object_object_add(json, "areas",
+                                                      areas_json);
+                               for (ALL_LIST_ELEMENTS_RO(isis->area_list,
+                                                         anode, area)) {
+                                       area_json = json_object_new_object();
+                                       json_object_string_add(
+                                               area_json, "area",
+                                               area->area_tag ? area->area_tag
+                                                              : "null");
+
+                                       for (ALL_LIST_ELEMENTS_RO(
+                                                    area->circuit_list, cnode,
+                                                    circuit))
+                                               if (!ifname)
+                                                       isis_circuit_print_json(
+                                                               circuit,
+                                                               area_json,
+                                                               detail);
+                                               else if (strcmp(circuit->interface->name, ifname) == 0)
+                                                       isis_circuit_print_json(
+                                                               circuit,
+                                                               area_json,
+                                                               detail);
+                                       json_object_array_add(areas_json,
+                                                             area_json);
+                               }
+                       }
+                       return CMD_SUCCESS;
+               }
+               isis = isis_lookup_by_vrfname(vrf_name);
+               if (isis != NULL) {
+                       areas_json = json_object_new_array();
+                       json_object_object_add(json, "areas", areas_json);
+                       for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode,
+                                                 area)) {
+                               area_json = json_object_new_object();
+                               json_object_string_add(area_json, "area",
+                                                      area->area_tag
+                                                              ? area->area_tag
+                                                              : "null");
+
+                               for (ALL_LIST_ELEMENTS_RO(area->circuit_list,
+                                                         cnode, circuit))
+                                       if (!ifname)
+                                               isis_circuit_print_json(
+                                                       circuit, area_json,
+                                                       detail);
+                                       else if (
+                                               strcmp(circuit->interface->name,
+                                                      ifname) == 0)
+                                               isis_circuit_print_json(
+                                                       circuit, area_json,
+                                                       detail);
+                               json_object_array_add(areas_json, area_json);
+                       }
+               }
+       }
+       return CMD_SUCCESS;
+}
+
+int show_isis_interface_common_vty(struct vty *vty, const char *ifname,
+                                  char detail, const char *vrf_name,
+                                  bool all_vrf)
 {
        struct listnode *anode, *cnode, *inode;
        struct isis_area *area;
@@ -990,8 +1087,7 @@ int show_isis_interface_common(struct vty *vty, const char *ifname, char detail,
                                                        circuit, vty, detail);
                                        else if (
                                                strcmp(circuit->interface->name,
-                                                      ifname)
-                                               == 0)
+                                                      ifname) == 0)
                                                isis_circuit_print_vty(
                                                        circuit, vty, detail);
                        }
@@ -1003,63 +1099,90 @@ int show_isis_interface_common(struct vty *vty, const char *ifname, char detail,
 
 DEFUN(show_isis_interface,
       show_isis_interface_cmd,
-      "show " PROTO_NAME " [vrf <NAME|all>] interface",
+      "show " PROTO_NAME " [vrf <NAME|all>] interface [json]",
       SHOW_STR
       PROTO_HELP 
       VRF_CMD_HELP_STR
       "All VRFs\n"
+      "json output\n"
       "IS-IS interface\n")
 {
+       int res = CMD_SUCCESS;
        const char *vrf_name = VRF_DEFAULT_NAME;
        bool all_vrf = false;
        int idx_vrf = 0;
+       bool uj = use_json(argc, argv);
+       json_object *json = NULL;
 
        ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
-       return show_isis_interface_common(vty, NULL, ISIS_UI_LEVEL_BRIEF,
-                                         vrf_name, all_vrf);
+       if (uj)
+               json = json_object_new_object();
+       res = show_isis_interface_common(vty, json, NULL, ISIS_UI_LEVEL_BRIEF,
+                                        vrf_name, all_vrf);
+       if (uj)
+               vty_json(vty, json);
+       return res;
 }
 
 DEFUN(show_isis_interface_detail,
       show_isis_interface_detail_cmd,
-      "show " PROTO_NAME " [vrf <NAME|all>] interface detail",
+      "show " PROTO_NAME " [vrf <NAME|all>] interface detail [json]",
       SHOW_STR
       PROTO_HELP
       VRF_CMD_HELP_STR
       "All VRFs\n"
       "IS-IS interface\n"
-      "show detailed information\n")
+      "show detailed information\n"
+      "json output\n")
 {
+       int res = CMD_SUCCESS;
        const char *vrf_name = VRF_DEFAULT_NAME;
        bool all_vrf = false;
        int idx_vrf = 0;
+       bool uj = use_json(argc, argv);
+       json_object *json = NULL;
 
        ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
-       return show_isis_interface_common(vty, NULL, ISIS_UI_LEVEL_DETAIL,
-                                         vrf_name, all_vrf);
+       if (uj)
+               json = json_object_new_object();
+       res = show_isis_interface_common(vty, json, NULL, ISIS_UI_LEVEL_DETAIL,
+                                        vrf_name, all_vrf);
+       if (uj)
+               vty_json(vty, json);
+       return res;
 }
 
 DEFUN(show_isis_interface_arg,
       show_isis_interface_arg_cmd,
-      "show " PROTO_NAME " [vrf <NAME|all>] interface WORD",
+      "show " PROTO_NAME " [vrf <NAME|all>] interface WORD [json]",
       SHOW_STR
       PROTO_HELP
       VRF_CMD_HELP_STR
       "All VRFs\n"
       "IS-IS interface\n"
-      "IS-IS interface name\n")
+      "IS-IS interface name\n"
+      "json output\n")
 {
+       int res = CMD_SUCCESS;
        int idx_word = 0;
        const char *vrf_name = VRF_DEFAULT_NAME;
        bool all_vrf = false;
        int idx_vrf = 0;
+       bool uj = use_json(argc, argv);
+       json_object *json = NULL;
 
        ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
+       if (uj)
+               json = json_object_new_object();
 
        char *ifname = argv_find(argv, argc, "WORD", &idx_word)
                               ? argv[idx_word]->arg
                               : NULL;
-       return show_isis_interface_common(vty, ifname, ISIS_UI_LEVEL_DETAIL,
-                                         vrf_name, all_vrf);
+       res = show_isis_interface_common(
+               vty, json, ifname, ISIS_UI_LEVEL_DETAIL, vrf_name, all_vrf);
+       if (uj)
+               vty_json(vty, json);
+       return res;
 }
 
 static int id_to_sysid(struct isis *isis, const char *id, uint8_t *sysid)