]> git.proxmox.com Git - mirror_frr.git/blobdiff - isisd/isis_vty_fabricd.c
Merge pull request #5280 from qlyoung/doc-clean-topotest-json
[mirror_frr.git] / isisd / isis_vty_fabricd.c
index 0dcf12aa051089bd39c27c914dff05f037310177..24e5c519478c9a8384c4ed7dc079f1e5815c41be 100644 (file)
@@ -23,8 +23,9 @@
 
 #include "command.h"
 
+#include "lib/bfd.h"
+#include "isisd/isis_bfd.h"
 #include "isisd/isisd.h"
-#include "isisd/isis_vty_common.h"
 #include "isisd/fabricd.h"
 #include "isisd/isis_tlvs.h"
 #include "isisd/isis_misc.h"
 #include "isisd/isis_csm.h"
 #include "isisd/isis_circuit.h"
 #include "lib/spf_backoff.h"
+#include "isisd/isis_mt.h"
+
+static struct isis_circuit *isis_circuit_lookup(struct vty *vty)
+{
+       struct interface *ifp = VTY_GET_CONTEXT(interface);
+       struct isis_circuit *circuit;
+
+       if (!ifp) {
+               vty_out(vty, "Invalid interface \n");
+               return NULL;
+       }
+
+       circuit = circuit_scan_by_ifp(ifp);
+       if (!circuit) {
+               vty_out(vty, "ISIS is not enabled on circuit %s\n", ifp->name);
+               return NULL;
+       }
+
+       return circuit;
+}
 
 DEFUN (fabric_tier,
        fabric_tier_cmd,
@@ -160,13 +181,14 @@ DEFUN (show_lsp_flooding,
        struct isis_area *area;
 
        for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
-               dict_t *lspdb = area->lspdb[ISIS_LEVEL2 - 1];
+               struct lspdb_head *head = &area->lspdb[ISIS_LEVEL2 - 1];
+               struct isis_lsp *lsp;
 
                vty_out(vty, "Area %s:\n", area->area_tag ?
                        area->area_tag : "null");
 
                if (lspid) {
-                       struct isis_lsp *lsp = lsp_for_arg(lspid, lspdb);
+                       lsp = lsp_for_arg(head, lspid);
 
                        if (lsp)
                                lsp_print_flooding(vty, lsp);
@@ -174,9 +196,8 @@ DEFUN (show_lsp_flooding,
                        continue;
                }
 
-               for (dnode_t *dnode = dict_first(lspdb); dnode;
-                    dnode = dict_next(lspdb, dnode)) {
-                       lsp_print_flooding(vty, dnode_get(dnode));
+               frr_each (lspdb, head, lsp) {
+                       lsp_print_flooding(vty, lsp);
                        vty_out(vty, "\n");
                }
        }
@@ -287,6 +308,49 @@ DEFUN (no_ip_router_isis,
        return CMD_SUCCESS;
 }
 
+DEFUN (isis_bfd,
+       isis_bfd_cmd,
+       PROTO_NAME " bfd",
+       PROTO_HELP
+       "Enable BFD support\n")
+{
+       struct isis_circuit *circuit = isis_circuit_lookup(vty);
+
+       if (!circuit)
+               return CMD_ERR_NO_MATCH;
+
+       if (circuit->bfd_info
+           && CHECK_FLAG(circuit->bfd_info->flags, BFD_FLAG_PARAM_CFG)) {
+               return CMD_SUCCESS;
+       }
+
+       isis_bfd_circuit_param_set(circuit, BFD_DEF_MIN_RX,
+                                  BFD_DEF_MIN_TX, BFD_DEF_DETECT_MULT, true);
+
+       return CMD_SUCCESS;
+}
+
+DEFUN (no_isis_bfd,
+       no_isis_bfd_cmd,
+       "no " PROTO_NAME " bfd",
+       NO_STR
+       PROTO_HELP
+       "Disables BFD support\n"
+)
+{
+       struct isis_circuit *circuit = isis_circuit_lookup(vty);
+
+       if (!circuit)
+               return CMD_ERR_NO_MATCH;
+
+       if (!circuit->bfd_info)
+               return CMD_SUCCESS;
+
+       isis_bfd_circuit_cmd(circuit, ZEBRA_BFD_DEST_DEREGISTER);
+       bfd_info_free(&circuit->bfd_info);
+       return CMD_SUCCESS;
+}
+
 DEFUN (set_overload_bit,
        set_overload_bit_cmd,
        "set-overload-bit",
@@ -770,6 +834,268 @@ DEFUN (no_isis_passwd,
        return CMD_SUCCESS;
 }
 
+DEFUN (isis_metric,
+       isis_metric_cmd,
+       PROTO_NAME " metric (0-16777215)",
+       PROTO_HELP
+       "Set default metric for circuit\n"
+       "Default metric value\n")
+{
+       int idx_number = 2;
+       int met;
+       struct isis_circuit *circuit = isis_circuit_lookup(vty);
+       if (!circuit)
+               return CMD_ERR_NO_MATCH;
+
+       met = atoi(argv[idx_number]->arg);
+
+       /* RFC3787 section 5.1 */
+       if (circuit->area && circuit->area->oldmetric == 1
+           && met > MAX_NARROW_LINK_METRIC) {
+               vty_out(vty,
+                       "Invalid metric %d - should be <0-63> "
+                       "when narrow metric type enabled\n",
+                       met);
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
+       /* RFC4444 */
+       if (circuit->area && circuit->area->newmetric == 1
+           && met > MAX_WIDE_LINK_METRIC) {
+               vty_out(vty,
+                       "Invalid metric %d - should be <0-16777215> "
+                       "when wide metric type enabled\n",
+                       met);
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
+       CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_1, met),
+                       "Failed to set L1 metric: $ERR");
+       CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_2, met),
+                       "Failed to set L2 metric: $ERR");
+       return CMD_SUCCESS;
+}
+
+DEFUN (no_isis_metric,
+       no_isis_metric_cmd,
+       "no " PROTO_NAME " metric [(0-16777215)]",
+       NO_STR
+       PROTO_HELP
+       "Set default metric for circuit\n"
+       "Default metric value\n")
+{
+       struct isis_circuit *circuit = isis_circuit_lookup(vty);
+       if (!circuit)
+               return CMD_ERR_NO_MATCH;
+
+       CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_1,
+                                               DEFAULT_CIRCUIT_METRIC),
+                       "Failed to set L1 metric: $ERR");
+       CMD_FERR_RETURN(isis_circuit_metric_set(circuit, IS_LEVEL_2,
+                                               DEFAULT_CIRCUIT_METRIC),
+                       "Failed to set L2 metric: $ERR");
+       return CMD_SUCCESS;
+}
+
+DEFUN (isis_hello_interval,
+       isis_hello_interval_cmd,
+       PROTO_NAME " hello-interval (1-600)",
+       PROTO_HELP
+       "Set Hello interval\n"
+       "Holdtime 1 seconds, interval depends on multiplier\n")
+{
+       uint32_t interval = atoi(argv[2]->arg);
+       struct isis_circuit *circuit = isis_circuit_lookup(vty);
+       if (!circuit)
+               return CMD_ERR_NO_MATCH;
+
+       circuit->hello_interval[0] = interval;
+       circuit->hello_interval[1] = interval;
+
+       return CMD_SUCCESS;
+}
+
+DEFUN (no_isis_hello_interval,
+       no_isis_hello_interval_cmd,
+       "no " PROTO_NAME " hello-interval [(1-600)]",
+       NO_STR
+       PROTO_HELP
+       "Set Hello interval\n"
+       "Holdtime 1 second, interval depends on multiplier\n")
+{
+       struct isis_circuit *circuit = isis_circuit_lookup(vty);
+       if (!circuit)
+               return CMD_ERR_NO_MATCH;
+
+       circuit->hello_interval[0] = DEFAULT_HELLO_INTERVAL;
+       circuit->hello_interval[1] = DEFAULT_HELLO_INTERVAL;
+
+       return CMD_SUCCESS;
+}
+
+DEFUN (isis_hello_multiplier,
+       isis_hello_multiplier_cmd,
+       PROTO_NAME " hello-multiplier (2-100)",
+       PROTO_HELP
+       "Set multiplier for Hello holding time\n"
+       "Hello multiplier value\n")
+{
+       uint16_t mult = atoi(argv[2]->arg);
+       struct isis_circuit *circuit = isis_circuit_lookup(vty);
+       if (!circuit)
+               return CMD_ERR_NO_MATCH;
+
+       circuit->hello_multiplier[0] = mult;
+       circuit->hello_multiplier[1] = mult;
+
+       return CMD_SUCCESS;
+}
+
+DEFUN (no_isis_hello_multiplier,
+       no_isis_hello_multiplier_cmd,
+       "no " PROTO_NAME " hello-multiplier [(2-100)]",
+       NO_STR
+       PROTO_HELP
+       "Set multiplier for Hello holding time\n"
+       "Hello multiplier value\n")
+{
+       struct isis_circuit *circuit = isis_circuit_lookup(vty);
+       if (!circuit)
+               return CMD_ERR_NO_MATCH;
+
+       circuit->hello_multiplier[0] = DEFAULT_HELLO_MULTIPLIER;
+       circuit->hello_multiplier[1] = DEFAULT_HELLO_MULTIPLIER;
+
+       return CMD_SUCCESS;
+}
+
+DEFUN (csnp_interval,
+       csnp_interval_cmd,
+       PROTO_NAME " csnp-interval (1-600)",
+       PROTO_HELP
+       "Set CSNP interval in seconds\n"
+       "CSNP interval value\n")
+{
+       uint16_t interval = atoi(argv[2]->arg);
+       struct isis_circuit *circuit = isis_circuit_lookup(vty);
+       if (!circuit)
+               return CMD_ERR_NO_MATCH;
+
+       circuit->csnp_interval[0] = interval;
+       circuit->csnp_interval[1] = interval;
+
+       return CMD_SUCCESS;
+}
+
+DEFUN (no_csnp_interval,
+       no_csnp_interval_cmd,
+       "no " PROTO_NAME " csnp-interval [(1-600)]",
+       NO_STR
+       PROTO_HELP
+       "Set CSNP interval in seconds\n"
+       "CSNP interval value\n")
+{
+       struct isis_circuit *circuit = isis_circuit_lookup(vty);
+       if (!circuit)
+               return CMD_ERR_NO_MATCH;
+
+       circuit->csnp_interval[0] = DEFAULT_CSNP_INTERVAL;
+       circuit->csnp_interval[1] = DEFAULT_CSNP_INTERVAL;
+
+       return CMD_SUCCESS;
+}
+
+DEFUN (psnp_interval,
+       psnp_interval_cmd,
+       PROTO_NAME " psnp-interval (1-120)",
+       PROTO_HELP
+       "Set PSNP interval in seconds\n"
+       "PSNP interval value\n")
+{
+       uint16_t interval = atoi(argv[2]->arg);
+       struct isis_circuit *circuit = isis_circuit_lookup(vty);
+       if (!circuit)
+               return CMD_ERR_NO_MATCH;
+
+       circuit->psnp_interval[0] = interval;
+       circuit->psnp_interval[1] = interval;
+
+       return CMD_SUCCESS;
+}
+
+DEFUN (no_psnp_interval,
+       no_psnp_interval_cmd,
+       "no " PROTO_NAME " psnp-interval [(1-120)]",
+       NO_STR
+       PROTO_HELP
+       "Set PSNP interval in seconds\n"
+       "PSNP interval value\n")
+{
+       struct isis_circuit *circuit = isis_circuit_lookup(vty);
+       if (!circuit)
+               return CMD_ERR_NO_MATCH;
+
+       circuit->psnp_interval[0] = DEFAULT_PSNP_INTERVAL;
+       circuit->psnp_interval[1] = DEFAULT_PSNP_INTERVAL;
+
+       return CMD_SUCCESS;
+}
+
+DEFUN (circuit_topology,
+       circuit_topology_cmd,
+       PROTO_NAME " topology " ISIS_MT_NAMES,
+       PROTO_HELP
+       "Configure interface IS-IS topologies\n"
+       ISIS_MT_DESCRIPTIONS)
+{
+       struct isis_circuit *circuit = isis_circuit_lookup(vty);
+       if (!circuit)
+               return CMD_ERR_NO_MATCH;
+       const char *arg = argv[2]->arg;
+       uint16_t mtid = isis_str2mtid(arg);
+
+       if (circuit->area && circuit->area->oldmetric) {
+               vty_out(vty,
+                       "Multi topology IS-IS can only be used with wide metrics\n");
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
+       if (mtid == (uint16_t)-1) {
+               vty_out(vty, "Don't know topology '%s'\n", arg);
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
+       return isis_circuit_mt_enabled_set(circuit, mtid, true);
+}
+
+DEFUN (no_circuit_topology,
+       no_circuit_topology_cmd,
+       "no " PROTO_NAME " topology " ISIS_MT_NAMES,
+       NO_STR
+       PROTO_HELP
+       "Configure interface IS-IS topologies\n"
+       ISIS_MT_DESCRIPTIONS)
+{
+       struct isis_circuit *circuit = isis_circuit_lookup(vty);
+       if (!circuit)
+               return CMD_ERR_NO_MATCH;
+       const char *arg = argv[3]->arg;
+       uint16_t mtid = isis_str2mtid(arg);
+
+       if (circuit->area && circuit->area->oldmetric) {
+               vty_out(vty,
+                       "Multi topology IS-IS can only be used with wide metrics\n");
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
+       if (mtid == (uint16_t)-1) {
+               vty_out(vty, "Don't know topology '%s'\n", arg);
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
+       return isis_circuit_mt_enabled_set(circuit, mtid, false);
+}
+
 void isis_vty_daemon_init(void)
 {
        install_element(ROUTER_NODE, &fabric_tier_cmd);
@@ -782,6 +1108,8 @@ void isis_vty_daemon_init(void)
        install_element(INTERFACE_NODE, &ip_router_isis_cmd);
        install_element(INTERFACE_NODE, &ip6_router_isis_cmd);
        install_element(INTERFACE_NODE, &no_ip_router_isis_cmd);
+       install_element(INTERFACE_NODE, &isis_bfd_cmd);
+       install_element(INTERFACE_NODE, &no_isis_bfd_cmd);
 
        install_element(ROUTER_NODE, &set_overload_bit_cmd);
        install_element(ROUTER_NODE, &no_set_overload_bit_cmd);
@@ -814,4 +1142,22 @@ void isis_vty_daemon_init(void)
 
        install_element(INTERFACE_NODE, &isis_passwd_cmd);
        install_element(INTERFACE_NODE, &no_isis_passwd_cmd);
+
+       install_element(INTERFACE_NODE, &isis_metric_cmd);
+       install_element(INTERFACE_NODE, &no_isis_metric_cmd);
+
+       install_element(INTERFACE_NODE, &isis_hello_interval_cmd);
+       install_element(INTERFACE_NODE, &no_isis_hello_interval_cmd);
+
+       install_element(INTERFACE_NODE, &isis_hello_multiplier_cmd);
+       install_element(INTERFACE_NODE, &no_isis_hello_multiplier_cmd);
+
+       install_element(INTERFACE_NODE, &csnp_interval_cmd);
+       install_element(INTERFACE_NODE, &no_csnp_interval_cmd);
+
+       install_element(INTERFACE_NODE, &psnp_interval_cmd);
+       install_element(INTERFACE_NODE, &no_psnp_interval_cmd);
+
+       install_element(INTERFACE_NODE, &circuit_topology_cmd);
+       install_element(INTERFACE_NODE, &no_circuit_topology_cmd);
 }