]> git.puffer.fish Git - mirror/frr.git/commitdiff
isisd: retrofit 'router isis' and 'ip router isis' cmds
authorEmanuele Di Pascale <emanuele@voltanet.io>
Tue, 13 Nov 2018 16:19:10 +0000 (17:19 +0100)
committerEmanuele Di Pascale <emanuele@voltanet.io>
Tue, 18 Dec 2018 14:20:20 +0000 (15:20 +0100)
These are complex commands to retrofit, partly due to the number of
different callbacks they touch. Additionally, in FRR adding
an interface to an IS-IS area that does not exist also creates that
area. To make sure that this behavior is kept, while at the same
time keeping the northbound api consistent, we need to take extra
care to call the appropriate callbacks to update the YANG tree.

Note that many callbacks rely on the existence of the corresponding
IS-IS area; when these callbacks are joined together in a single
transaction, we need to ensure that the area creation is performed
first, or the config will fail. For this reason, the isis instance
create callback has been given a slightly lower priority than the
others.

Signed-off-by: Emanuele Di Pascale <emanuele@voltanet.io>
isisd/isis_cli.c
isisd/isis_cli.h
isisd/isis_northbound.c
isisd/isis_vty_common.c
isisd/isis_vty_fabricd.c
isisd/isisd.c
isisd/isisd.h

index 9f82d858102ce591e453376b971f183a11fdcf86..2650c5bcb79dd3d4d5fa518bed23377ca03b3ffe 100644 (file)
 
 #ifndef FABRICD
 
+/*
+ * XPath: /frr-isisd:isis/instance
+ */
+DEFPY_NOSH(router_isis, router_isis_cmd, "router isis WORD$tag",
+          ROUTER_STR
+          "ISO IS-IS\n"
+          "ISO Routing area tag\n")
+{
+       int ret;
+       char base_xpath[XPATH_MAXLEN];
+
+       snprintf(base_xpath, XPATH_MAXLEN,
+                "/frr-isisd:isis/instance[area-tag='%s']", tag);
+       nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
+       /* default value in yang for is-type is level-1, but in FRR
+        * the first instance is assigned is-type level-1-2. We
+        * need to make sure to set it in the yang model so that it
+        * is consistent with what FRR sees.
+        */
+       if (listcount(isis->area_list) == 0)
+               nb_cli_enqueue_change(vty, "./is-type", NB_OP_MODIFY,
+                                     "level-1-2");
+       ret = nb_cli_apply_changes(vty, base_xpath);
+       if (ret == CMD_SUCCESS)
+               VTY_PUSH_XPATH(ISIS_NODE, base_xpath);
+
+       return ret;
+}
+
+DEFPY(no_router_isis, no_router_isis_cmd, "no router isis WORD$tag",
+      NO_STR ROUTER_STR
+      "ISO IS-IS\n"
+      "ISO Routing area tag\n")
+{
+       char temp_xpath[XPATH_MAXLEN];
+       struct listnode *node, *nnode;
+       struct isis_circuit *circuit = NULL;
+       struct isis_area *area = NULL;
+
+       area = isis_area_lookup(tag);
+       if (!area) {
+               vty_out(vty, "ISIS area %s not found.\n", tag);
+               return CMD_ERR_NOTHING_TODO;
+       }
+
+       nb_cli_enqueue_change(vty, ".", NB_OP_DELETE, NULL);
+       if (area->circuit_list && listcount(area->circuit_list)) {
+               for (ALL_LIST_ELEMENTS(area->circuit_list, node, nnode,
+                                      circuit)) {
+                       /* add callbacks to delete each of the circuits listed
+                        */
+                       const char *vrf_name =
+                               vrf_lookup_by_id(circuit->interface->vrf_id)
+                                       ->name;
+                       snprintf(
+                               temp_xpath, XPATH_MAXLEN,
+                               "/frr-interface:lib/interface[name='%s'][vrf='%s']/frr-isisd:isis",
+                               circuit->interface->name, vrf_name);
+                       nb_cli_enqueue_change(vty, temp_xpath, NB_OP_DELETE,
+                                             NULL);
+               }
+       }
+
+       return nb_cli_apply_changes(
+               vty, "/frr-isisd:isis/instance[area-tag='%s']", tag);
+}
+
+void cli_show_router_isis(struct vty *vty, struct lyd_node *dnode,
+                         bool show_defaults)
+{
+       vty_out(vty, "!\n");
+       vty_out(vty, "router isis %s\n",
+               yang_dnode_get_string(dnode, "./area-tag"));
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/ipv4-routing
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/ipv6-routing
+ * XPath: /frr-isisd:isis/instance
+ */
+DEFPY(ip_router_isis, ip_router_isis_cmd, "ip router isis WORD$tag",
+      "Interface Internet Protocol config commands\n"
+      "IP router interface commands\n"
+      "IS-IS routing protocol\n"
+      "Routing process tag\n")
+{
+       char temp_xpath[XPATH_MAXLEN];
+       const char *circ_type;
+       struct isis_area *area;
+
+       /* area will be created if it is not present. make sure the yang model
+        * is synced with FRR and call the appropriate NB cb.
+        */
+       area = isis_area_lookup(tag);
+       if (!area) {
+               snprintf(temp_xpath, XPATH_MAXLEN,
+                        "/frr-isisd:isis/instance[area-tag='%s']", tag);
+               nb_cli_enqueue_change(vty, temp_xpath, NB_OP_CREATE, tag);
+               snprintf(temp_xpath, XPATH_MAXLEN,
+                        "/frr-isisd:isis/instance[area-tag='%s']/is-type",
+                        tag);
+               nb_cli_enqueue_change(
+                       vty, temp_xpath, NB_OP_MODIFY,
+                       listcount(isis->area_list) == 0 ? "level-1-2" : NULL);
+               nb_cli_enqueue_change(vty, "./frr-isisd:isis", NB_OP_CREATE,
+                                     NULL);
+               nb_cli_enqueue_change(vty, "./frr-isisd:isis/area-tag",
+                                     NB_OP_MODIFY, tag);
+               nb_cli_enqueue_change(vty, "./frr-isisd:isis/ipv4-routing",
+                                     NB_OP_CREATE, NULL);
+               nb_cli_enqueue_change(
+                       vty, "./frr-isisd:isis/circuit-type", NB_OP_MODIFY,
+                       listcount(isis->area_list) == 0 ? "level-1-2"
+                                                       : "level-1");
+       } else {
+               /* area exists, circuit type defaults to its area's is_type */
+               switch (area->is_type) {
+               case IS_LEVEL_1:
+                       circ_type = "level-1";
+                       break;
+               case IS_LEVEL_2:
+                       circ_type = "level-2";
+                       break;
+               case IS_LEVEL_1_AND_2:
+                       circ_type = "level-1-2";
+                       break;
+               }
+               nb_cli_enqueue_change(vty, "./frr-isisd:isis", NB_OP_CREATE,
+                                     NULL);
+               nb_cli_enqueue_change(vty, "./frr-isisd:isis/area-tag",
+                                     NB_OP_MODIFY, tag);
+               nb_cli_enqueue_change(vty, "./frr-isisd:isis/ipv4-routing",
+                                     NB_OP_CREATE, NULL);
+               nb_cli_enqueue_change(vty, "./frr-isisd:isis/circuit-type",
+                                     NB_OP_MODIFY, circ_type);
+       }
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(ip6_router_isis, ip6_router_isis_cmd, "ipv6 router isis WORD$tag",
+      "Interface Internet Protocol config commands\n"
+      "IP router interface commands\n"
+      "IS-IS routing protocol\n"
+      "Routing process tag\n")
+{
+       char temp_xpath[XPATH_MAXLEN];
+       const char *circ_type;
+       struct isis_area *area;
+
+       /* area will be created if it is not present. make sure the yang model
+        * is synced with FRR and call the appropriate NB cb.
+        */
+       area = isis_area_lookup(tag);
+       if (!area) {
+               snprintf(temp_xpath, XPATH_MAXLEN,
+                        "/frr-isisd:isis/instance[area-tag='%s']", tag);
+               nb_cli_enqueue_change(vty, temp_xpath, NB_OP_CREATE, tag);
+               snprintf(temp_xpath, XPATH_MAXLEN,
+                        "/frr-isisd:isis/instance[area-tag='%s']/is-type",
+                        tag);
+               nb_cli_enqueue_change(
+                       vty, temp_xpath, NB_OP_MODIFY,
+                       listcount(isis->area_list) == 0 ? "level-1-2" : NULL);
+               nb_cli_enqueue_change(vty, "./frr-isisd:isis", NB_OP_CREATE,
+                                     NULL);
+               nb_cli_enqueue_change(vty, "./frr-isisd:isis/area-tag",
+                                     NB_OP_MODIFY, tag);
+               nb_cli_enqueue_change(vty, "./frr-isisd:isis/ipv6-routing",
+                                     NB_OP_CREATE, NULL);
+               nb_cli_enqueue_change(
+                       vty, "./frr-isisd:isis/circuit-type", NB_OP_MODIFY,
+                       listcount(isis->area_list) == 0 ? "level-1-2"
+                                                       : "level-1");
+       } else {
+               /* area exists, circuit type defaults to its area's is_type */
+               switch (area->is_type) {
+               case IS_LEVEL_1:
+                       circ_type = "level-1";
+                       break;
+               case IS_LEVEL_2:
+                       circ_type = "level-2";
+                       break;
+               case IS_LEVEL_1_AND_2:
+                       circ_type = "level-1-2";
+                       break;
+               }
+               nb_cli_enqueue_change(vty, "./frr-isisd:isis", NB_OP_CREATE,
+                                     NULL);
+               nb_cli_enqueue_change(vty, "./frr-isisd:isis/area-tag",
+                                     NB_OP_MODIFY, tag);
+               nb_cli_enqueue_change(vty, "./frr-isisd:isis/ipv6-routing",
+                                     NB_OP_CREATE, NULL);
+               nb_cli_enqueue_change(vty, "./frr-isisd:isis/circuit-type",
+                                     NB_OP_MODIFY, circ_type);
+       }
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY(no_ip_router_isis, no_ip_router_isis_cmd,
+      "no <ip|ipv6>$ip router isis [WORD]$tag",
+      NO_STR
+      "Interface Internet Protocol config commands\n"
+      "IP router interface commands\n"
+      "IP router interface commands\n"
+      "IS-IS routing protocol\n"
+      "Routing process tag\n")
+{
+       const struct lyd_node *dnode =
+               yang_dnode_get(running_config->dnode, VTY_CURR_XPATH);
+       struct interface *ifp;
+       struct isis_circuit *circuit = NULL;
+
+       /* check for the existance of a circuit */
+       if (dnode) {
+               ifp = yang_dnode_get_entry(dnode, false);
+               if (ifp)
+                       circuit = circuit_scan_by_ifp(ifp);
+       }
+
+       /* if both ipv4 and ipv6 are off delete the interface isis container too
+        */
+       if (!strncmp(ip, "ipv6", strlen("ipv6"))) {
+               if (circuit && !circuit->ip_router)
+                       nb_cli_enqueue_change(vty, "./frr-isisd:isis",
+                                             NB_OP_DELETE, NULL);
+               else
+                       nb_cli_enqueue_change(vty,
+                                             "./frr-isisd:isis/ipv6-routing",
+                                             NB_OP_DELETE, NULL);
+       } else { /* no ipv4  */
+               if (circuit && !circuit->ipv6_router)
+                       nb_cli_enqueue_change(vty, "./frr-isisd:isis",
+                                             NB_OP_DELETE, NULL);
+               else
+                       nb_cli_enqueue_change(vty,
+                                             "./frr-isisd:isis/ipv4-routing",
+                                             NB_OP_DELETE, NULL);
+       }
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_ip_isis_ipv4(struct vty *vty, struct lyd_node *dnode,
+                          bool show_defaults)
+{
+       vty_out(vty, " ip router isis %s\n",
+               yang_dnode_get_string(dnode, "../area-tag"));
+}
+
+void cli_show_ip_isis_ipv6(struct vty *vty, struct lyd_node *dnode,
+                          bool show_defaults)
+{
+       vty_out(vty, " ipv6 router isis %s\n",
+               yang_dnode_get_string(dnode, "../area-tag"));
+}
+
 void isis_cli_init(void)
 {
+       install_element(CONFIG_NODE, &router_isis_cmd);
+       install_element(CONFIG_NODE, &no_router_isis_cmd);
+
+       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);
 }
 
 #endif /* ifndef FABRICD */
index 952bd9d7446aef2848dae46b5090c66ef58a28c0..e986087595b00326fa1309232528bf83d485b79d 100644 (file)
 #define ISISD_ISIS_CLI_H_
 
 /* add cli_show declarations here as externs */
+void cli_show_router_isis(struct vty *vty, struct lyd_node *dnode,
+                         bool show_defaults);
+void cli_show_ip_isis_ipv4(struct vty *vty, struct lyd_node *dnode,
+                          bool show_defaults);
+void cli_show_ip_isis_ipv6(struct vty *vty, struct lyd_node *dnode,
+                          bool show_defaults);
 
 #endif /* ISISD_ISIS_CLI_H_ */
index 23c4fec4ff7cad8306c200fb5b913f36b32e2753..71145123457fca1c68442a8387eaf53ae8f4611d 100644 (file)
@@ -54,14 +54,35 @@ static int isis_instance_create(enum nb_event event,
                                const struct lyd_node *dnode,
                                union nb_resource *resource)
 {
-       /* TODO: implement me. */
+       struct isis_area *area;
+       const char *area_tag;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       area_tag = yang_dnode_get_string(dnode, "./area-tag");
+       area = isis_area_lookup(area_tag);
+       if (area)
+               return NB_ERR_INCONSISTENCY;
+
+       area = isis_area_create(area_tag);
+       /* save area in dnode to avoid looking it up all the time */
+       yang_dnode_set_entry(dnode, area);
+
        return NB_OK;
 }
 
 static int isis_instance_delete(enum nb_event event,
                                const struct lyd_node *dnode)
 {
-       /* TODO: implement me. */
+       const char *area_tag;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       area_tag = yang_dnode_get_string(dnode, "./area-tag");
+       isis_area_destroy(area_tag);
+
        return NB_OK;
 }
 
@@ -72,7 +93,16 @@ static int isis_instance_is_type_modify(enum nb_event event,
                                        const struct lyd_node *dnode,
                                        union nb_resource *resource)
 {
-       /* TODO: implement me. */
+       struct isis_area *area;
+       int type;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       area = yang_dnode_get_entry(dnode, true);
+       type = yang_dnode_get_enum(dnode, NULL);
+       isis_area_is_type_set(area, type);
+
        return NB_OK;
 }
 
@@ -1003,14 +1033,63 @@ static int lib_interface_isis_create(enum nb_event event,
                                     const struct lyd_node *dnode,
                                     union nb_resource *resource)
 {
-       /* TODO: implement me. */
+       struct isis_area *area;
+       struct interface *ifp;
+       struct isis_circuit *circuit;
+       const char *area_tag = yang_dnode_get_string(dnode, "./area-tag");
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       area = isis_area_lookup(area_tag);
+       /* The area should have already be created. We are
+        * setting the priority of the global isis area creation
+        * slightly lower, so it should be executed first, but I
+        * cannot rely on that so here I have to check.
+        */
+       if (!area) {
+               flog_err(
+                       EC_LIB_NB_CB_CONFIG_APPLY,
+                       "%s: attempt to create circuit for area %s before the area has been created",
+                       __func__, area_tag);
+               abort();
+       }
+
+       ifp = yang_dnode_get_entry(dnode, true);
+       circuit = isis_circuit_create(area, ifp);
+       assert(circuit->state == C_STATE_CONF || circuit->state == C_STATE_UP);
+       yang_dnode_set_entry(dnode, circuit);
+
        return NB_OK;
 }
 
 static int lib_interface_isis_delete(enum nb_event event,
                                     const struct lyd_node *dnode)
 {
-       /* TODO: implement me. */
+       struct isis_circuit *circuit;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       circuit = yang_dnode_get_entry(dnode, true);
+       if (!circuit)
+               return NB_ERR_INCONSISTENCY;
+       /* delete circuit through csm changes */
+       switch (circuit->state) {
+       case C_STATE_UP:
+               isis_csm_state_change(IF_DOWN_FROM_Z, circuit,
+                                     circuit->interface);
+               isis_csm_state_change(ISIS_DISABLE, circuit, circuit->area);
+               break;
+       case C_STATE_CONF:
+               isis_csm_state_change(ISIS_DISABLE, circuit, circuit->area);
+               break;
+       case C_STATE_INIT:
+               isis_csm_state_change(IF_DOWN_FROM_Z, circuit,
+                                     circuit->interface);
+               break;
+       }
+
        return NB_OK;
 }
 
@@ -1021,7 +1100,32 @@ static int lib_interface_isis_area_tag_modify(enum nb_event event,
                                              const struct lyd_node *dnode,
                                              union nb_resource *resource)
 {
-       /* TODO: implement me. */
+       struct isis_circuit *circuit;
+       struct interface *ifp;
+       struct vrf *vrf;
+       const char *area_tag, *ifname, *vrfname;
+
+       if (event == NB_EV_VALIDATE) {
+               /* libyang doesn't like relative paths across module boundaries
+                */
+               ifname = yang_dnode_get_string(dnode->parent->parent, "./name");
+               vrfname = yang_dnode_get_string(dnode->parent->parent, "./vrf");
+               vrf = vrf_lookup_by_name(vrfname);
+               assert(vrf);
+               ifp = if_lookup_by_name(ifname, vrf->vrf_id);
+               if (!ifp)
+                       return NB_OK;
+               circuit = circuit_lookup_by_ifp(ifp, isis->init_circ_list);
+               area_tag = yang_dnode_get_string(dnode, NULL);
+               if (circuit && circuit->area && circuit->area->area_tag
+                   && strcmp(circuit->area->area_tag, area_tag)) {
+                       flog_warn(EC_LIB_NB_CB_CONFIG_VALIDATE,
+                                 "ISIS circuit is already defined on %s",
+                                 circuit->area->area_tag);
+                       return NB_ERR_VALIDATION;
+               }
+       }
+
        return NB_OK;
 }
 
@@ -1032,7 +1136,42 @@ static int lib_interface_isis_circuit_type_modify(enum nb_event event,
                                                  const struct lyd_node *dnode,
                                                  union nb_resource *resource)
 {
-       /* TODO: implement me. */
+       int circ_type = yang_dnode_get_enum(dnode, NULL);
+       struct isis_circuit *circuit;
+       struct interface *ifp;
+       struct vrf *vrf;
+       const char *ifname, *vrfname;
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+               /* libyang doesn't like relative paths across module boundaries
+                */
+               ifname = yang_dnode_get_string(dnode->parent->parent, "./name");
+               vrfname = yang_dnode_get_string(dnode->parent->parent, "./vrf");
+               vrf = vrf_lookup_by_name(vrfname);
+               assert(vrf);
+               ifp = if_lookup_by_name(ifname, vrf->vrf_id);
+               if (!ifp)
+                       break;
+               circuit = circuit_lookup_by_ifp(ifp, isis->init_circ_list);
+               if (circuit && circuit->state == C_STATE_UP
+                   && circuit->area->is_type != IS_LEVEL_1_AND_2
+                   && circuit->area->is_type != circ_type) {
+                       flog_warn(EC_LIB_NB_CB_CONFIG_VALIDATE,
+                                 "Invalid circuit level for area %s",
+                                 circuit->area->area_tag);
+                       return NB_ERR_VALIDATION;
+               }
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               circuit = yang_dnode_get_entry(dnode, true);
+               isis_circuit_is_type_set(circuit, circ_type);
+               break;
+       }
+
        return NB_OK;
 }
 
@@ -1043,14 +1182,34 @@ static int lib_interface_isis_ipv4_routing_create(enum nb_event event,
                                                  const struct lyd_node *dnode,
                                                  union nb_resource *resource)
 {
-       /* TODO: implement me. */
+       bool ipv6;
+       struct isis_circuit *circuit;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       circuit = yang_dnode_get_entry(dnode, true);
+       ipv6 = yang_dnode_exists(dnode, "../ipv6-routing");
+       isis_circuit_af_set(circuit, true, ipv6);
+
        return NB_OK;
 }
 
 static int lib_interface_isis_ipv4_routing_delete(enum nb_event event,
                                                  const struct lyd_node *dnode)
 {
-       /* TODO: implement me. */
+       bool ipv6;
+       struct isis_circuit *circuit;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       circuit = yang_dnode_get_entry(dnode, true);
+       if (circuit && circuit->area) {
+               ipv6 = yang_dnode_exists(dnode, "../ipv6-routing");
+               isis_circuit_af_set(circuit, false, ipv6);
+       }
+
        return NB_OK;
 }
 
@@ -1061,14 +1220,34 @@ static int lib_interface_isis_ipv6_routing_create(enum nb_event event,
                                                  const struct lyd_node *dnode,
                                                  union nb_resource *resource)
 {
-       /* TODO: implement me. */
+       bool ipv4;
+       struct isis_circuit *circuit;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       circuit = yang_dnode_get_entry(dnode, true);
+       ipv4 = yang_dnode_exists(dnode, "../ipv6-routing");
+       isis_circuit_af_set(circuit, ipv4, true);
+
        return NB_OK;
 }
 
 static int lib_interface_isis_ipv6_routing_delete(enum nb_event event,
                                                  const struct lyd_node *dnode)
 {
-       /* TODO: implement me. */
+       bool ipv4;
+       struct isis_circuit *circuit;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       circuit = yang_dnode_get_entry(dnode, true);
+       if (circuit->area) {
+               ipv4 = yang_dnode_exists(dnode, "../ipv4-routing");
+               isis_circuit_af_set(circuit, ipv4, false);
+       }
+
        return NB_OK;
 }
 
@@ -1415,6 +1594,8 @@ const struct frr_yang_module_info frr_isisd_info = {
                        .xpath = "/frr-isisd:isis/instance",
                        .cbs.create = isis_instance_create,
                        .cbs.delete = isis_instance_delete,
+                       .cbs.cli_show = cli_show_router_isis,
+                       .priority = NB_DFLT_PRIORITY - 1,
                },
                {
                        .xpath = "/frr-isisd:isis/instance/is-type",
@@ -1705,11 +1886,13 @@ const struct frr_yang_module_info frr_isisd_info = {
                        .xpath = "/frr-interface:lib/interface/frr-isisd:isis/ipv4-routing",
                        .cbs.create = lib_interface_isis_ipv4_routing_create,
                        .cbs.delete = lib_interface_isis_ipv4_routing_delete,
+                       .cbs.cli_show = cli_show_ip_isis_ipv4,
                },
                {
                        .xpath = "/frr-interface:lib/interface/frr-isisd:isis/ipv6-routing",
                        .cbs.create = lib_interface_isis_ipv6_routing_create,
                        .cbs.delete = lib_interface_isis_ipv6_routing_delete,
+                       .cbs.cli_show = cli_show_ip_isis_ipv6,
                },
                {
                        .xpath = "/frr-interface:lib/interface/frr-isisd:isis/csnp-interval/level-1",
index c211763042821b8f2664b5bcf4a5e2df1eb59a87..f5ca9c1dd3dfa73167d7cf061b6b591fc093ee15 100644 (file)
@@ -57,109 +57,6 @@ struct isis_circuit *isis_circuit_lookup(struct vty *vty)
        return circuit;
 }
 
-DEFUN (ip_router_isis,
-       ip_router_isis_cmd,
-       "ip router " PROTO_NAME " WORD",
-       "Interface Internet Protocol config commands\n"
-       "IP router interface commands\n"
-       PROTO_HELP
-       "Routing process tag\n")
-{
-       int idx_afi = 0;
-       int idx_word = 3;
-       VTY_DECLVAR_CONTEXT(interface, ifp);
-       struct isis_circuit *circuit;
-       struct isis_area *area;
-       const char *af = argv[idx_afi]->arg;
-       const char *area_tag = argv[idx_word]->arg;
-
-       /* Prevent more than one area per circuit */
-       circuit = circuit_scan_by_ifp(ifp);
-       if (circuit && circuit->area) {
-               if (strcmp(circuit->area->area_tag, area_tag)) {
-                       vty_out(vty, "ISIS circuit is already defined on %s\n",
-                               circuit->area->area_tag);
-                       return CMD_ERR_NOTHING_TODO;
-               }
-       }
-
-       area = isis_area_lookup(area_tag);
-       if (!area)
-               area = isis_area_create(area_tag);
-
-       if (!circuit || !circuit->area) {
-               circuit = isis_circuit_create(area, ifp);
-
-               if (circuit->state != C_STATE_CONF
-                   && circuit->state != C_STATE_UP) {
-                       vty_out(vty,
-                               "Couldn't bring up interface, please check log.\n");
-                       return CMD_WARNING_CONFIG_FAILED;
-               }
-       }
-
-       bool ip = circuit->ip_router, ipv6 = circuit->ipv6_router;
-       if (af[2] != '\0')
-               ipv6 = true;
-       else
-               ip = true;
-
-       isis_circuit_af_set(circuit, ip, ipv6);
-       return CMD_SUCCESS;
-}
-
-DEFUN (ip6_router_isis,
-       ip6_router_isis_cmd,
-       "ipv6 router " PROTO_NAME " WORD",
-       "Interface Internet Protocol config commands\n"
-       "IP router interface commands\n"
-       PROTO_HELP
-       "Routing process tag\n")
-{
-       return ip_router_isis(self, vty, argc, argv);
-}
-
-DEFUN (no_ip_router_isis,
-       no_ip_router_isis_cmd,
-       "no <ip|ipv6> router " PROTO_NAME " WORD",
-       NO_STR
-       "Interface Internet Protocol config commands\n"
-       "IP router interface commands\n"
-       "IP router interface commands\n"
-       PROTO_HELP
-       "Routing process tag\n")
-{
-       int idx_afi = 1;
-       int idx_word = 4;
-       VTY_DECLVAR_CONTEXT(interface, ifp);
-       struct isis_area *area;
-       struct isis_circuit *circuit;
-       const char *af = argv[idx_afi]->arg;
-       const char *area_tag = argv[idx_word]->arg;
-
-       area = isis_area_lookup(area_tag);
-       if (!area) {
-               vty_out(vty, "Can't find ISIS instance %s\n",
-                       area_tag);
-               return CMD_ERR_NO_MATCH;
-       }
-
-       circuit = circuit_lookup_by_ifp(ifp, area->circuit_list);
-       if (!circuit) {
-               vty_out(vty, "ISIS is not enabled on circuit %s\n", ifp->name);
-               return CMD_ERR_NO_MATCH;
-       }
-
-       bool ip = circuit->ip_router, ipv6 = circuit->ipv6_router;
-       if (af[2] != '\0')
-               ipv6 = false;
-       else
-               ip = false;
-
-       isis_circuit_af_set(circuit, ip, ipv6);
-       return CMD_SUCCESS;
-}
-
 DEFUN (isis_passive,
        isis_passive_cmd,
        PROTO_NAME " passive",
@@ -947,10 +844,6 @@ DEFUN (no_domain_passwd,
 
 void isis_vty_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_passive_cmd);
        install_element(INTERFACE_NODE, &no_isis_passive_cmd);
 
index aa48fe1d3a2123dec505097c784b2adee94cdc52..819b61dc7ef1478349673de9aff91b96ad47fd9d 100644 (file)
@@ -29,6 +29,7 @@
 #include "isisd/isis_tlvs.h"
 #include "isisd/isis_misc.h"
 #include "isisd/isis_lsp.h"
+#include "isisd/isis_csm.h"
 
 DEFUN (fabric_tier,
        fabric_tier_cmd,
@@ -181,6 +182,109 @@ DEFUN (show_lsp_flooding,
        return CMD_SUCCESS;
 }
 
+DEFUN (ip_router_isis,
+       ip_router_isis_cmd,
+       "ip router " PROTO_NAME " WORD",
+       "Interface Internet Protocol config commands\n"
+       "IP router interface commands\n"
+       PROTO_HELP
+       "Routing process tag\n")
+{
+       int idx_afi = 0;
+       int idx_word = 3;
+       VTY_DECLVAR_CONTEXT(interface, ifp);
+       struct isis_circuit *circuit;
+       struct isis_area *area;
+       const char *af = argv[idx_afi]->arg;
+       const char *area_tag = argv[idx_word]->arg;
+
+       /* Prevent more than one area per circuit */
+       circuit = circuit_scan_by_ifp(ifp);
+       if (circuit && circuit->area) {
+               if (strcmp(circuit->area->area_tag, area_tag)) {
+                       vty_out(vty, "ISIS circuit is already defined on %s\n",
+                               circuit->area->area_tag);
+                       return CMD_ERR_NOTHING_TODO;
+               }
+       }
+
+       area = isis_area_lookup(area_tag);
+       if (!area)
+               area = isis_area_create(area_tag);
+
+       if (!circuit || !circuit->area) {
+               circuit = isis_circuit_create(area, ifp);
+
+               if (circuit->state != C_STATE_CONF
+                   && circuit->state != C_STATE_UP) {
+                       vty_out(vty,
+                               "Couldn't bring up interface, please check log.\n");
+                       return CMD_WARNING_CONFIG_FAILED;
+               }
+       }
+
+       bool ip = circuit->ip_router, ipv6 = circuit->ipv6_router;
+       if (af[2] != '\0')
+               ipv6 = true;
+       else
+               ip = true;
+
+       isis_circuit_af_set(circuit, ip, ipv6);
+       return CMD_SUCCESS;
+}
+
+DEFUN (ip6_router_isis,
+       ip6_router_isis_cmd,
+       "ipv6 router " PROTO_NAME " WORD",
+       "Interface Internet Protocol config commands\n"
+       "IP router interface commands\n"
+       PROTO_HELP
+       "Routing process tag\n")
+{
+       return ip_router_isis(self, vty, argc, argv);
+}
+
+DEFUN (no_ip_router_isis,
+       no_ip_router_isis_cmd,
+       "no <ip|ipv6> router " PROTO_NAME " WORD",
+       NO_STR
+       "Interface Internet Protocol config commands\n"
+       "IP router interface commands\n"
+       "IP router interface commands\n"
+       PROTO_HELP
+       "Routing process tag\n")
+{
+       int idx_afi = 1;
+       int idx_word = 4;
+       VTY_DECLVAR_CONTEXT(interface, ifp);
+       struct isis_area *area;
+       struct isis_circuit *circuit;
+       const char *af = argv[idx_afi]->arg;
+       const char *area_tag = argv[idx_word]->arg;
+
+       area = isis_area_lookup(area_tag);
+       if (!area) {
+               vty_out(vty, "Can't find ISIS instance %s\n",
+                       area_tag);
+               return CMD_ERR_NO_MATCH;
+       }
+
+       circuit = circuit_lookup_by_ifp(ifp, area->circuit_list);
+       if (!circuit) {
+               vty_out(vty, "ISIS is not enabled on circuit %s\n", ifp->name);
+               return CMD_ERR_NO_MATCH;
+       }
+
+       bool ip = circuit->ip_router, ipv6 = circuit->ipv6_router;
+       if (af[2] != '\0')
+               ipv6 = false;
+       else
+               ip = false;
+
+       isis_circuit_af_set(circuit, ip, ipv6);
+       return CMD_SUCCESS;
+}
+
 void isis_vty_daemon_init(void)
 {
        install_element(ROUTER_NODE, &fabric_tier_cmd);
@@ -189,4 +293,8 @@ void isis_vty_daemon_init(void)
        install_element(ROUTER_NODE, &no_triggered_csnp_cmd);
 
        install_element(ENABLE_NODE, &show_lsp_flooding_cmd);
+
+       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);
 }
index 0e496193a3210822cb0e11f7eb4153ad92d87482..3721dff3b405164f8fa4168d39135d2c492fbfcb 100644 (file)
@@ -36,6 +36,7 @@
 #include "table.h"
 #include "qobj.h"
 #include "spf_backoff.h"
+#include "lib/northbound_cli.h"
 
 #include "isisd/dict.h"
 #include "isisd/isis_constants.h"
@@ -67,7 +68,6 @@ DEFINE_QOBJ_TYPE(isis_area)
  * Prototypes.
  */
 int isis_area_get(struct vty *, const char *);
-int isis_area_destroy(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);
@@ -207,7 +207,7 @@ int isis_area_get(struct vty *vty, const char *area_tag)
        return CMD_SUCCESS;
 }
 
-int isis_area_destroy(struct vty *vty, const char *area_tag)
+int isis_area_destroy(const char *area_tag)
 {
        struct isis_area *area;
        struct listnode *node, *nnode;
@@ -217,7 +217,8 @@ int isis_area_destroy(struct vty *vty, const char *area_tag)
        area = isis_area_lookup(area_tag);
 
        if (area == NULL) {
-               vty_out(vty, "Can't find ISIS instance \n");
+               zlog_warn("%s: could not find area with area-tag %s",
+                               __func__, area_tag);
                return CMD_ERR_NO_MATCH;
        }
 
@@ -1452,12 +1453,13 @@ DEFUN (show_database,
        return show_isis_database(vty, id, uilevel);
 }
 
+#ifdef FABRICD
 /*
- * 'router isis' command
+ * 'router openfabric' command
  */
-DEFUN_NOSH (router_isis,
-       router_isis_cmd,
-       "router " PROTO_NAME " WORD",
+DEFUN_NOSH (router_openfabric,
+       router_openfabric_cmd,
+       "router openfabric WORD",
        ROUTER_STR
        PROTO_HELP
        "ISO Routing area tag\n")
@@ -1467,20 +1469,20 @@ DEFUN_NOSH (router_isis,
 }
 
 /*
- *'no router isis' command
+ *'no router openfabric' command
  */
-DEFUN (no_router_isis,
-       no_router_isis_cmd,
-       "no router " PROTO_NAME " WORD",
+DEFUN (no_router_openfabric,
+       no_router_openfabric_cmd,
+       "no router openfabric WORD",
        NO_STR
        ROUTER_STR
        PROTO_HELP
        "ISO Routing area tag\n")
 {
        int idx_word = 3;
-       return isis_area_destroy(vty, argv[idx_word]->arg);
+       return isis_area_destroy(argv[idx_word]->arg);
 }
-
+#endif /* ifdef FABRICD */
 /*
  * 'net' command
  */
@@ -2179,11 +2181,12 @@ void isis_init()
        install_element(CONFIG_NODE, &debug_isis_bfd_cmd);
        install_element(CONFIG_NODE, &no_debug_isis_bfd_cmd);
 
-       install_element(CONFIG_NODE, &router_isis_cmd);
-       install_element(CONFIG_NODE, &no_router_isis_cmd);
-
        install_default(ROUTER_NODE);
 
+#ifdef FABRICD
+       install_element(CONFIG_NODE, &router_openfabric_cmd);
+       install_element(CONFIG_NODE, &no_router_openfabric_cmd);
+#endif /* ifdef FABRICD */
        install_element(ROUTER_NODE, &net_cmd);
        install_element(ROUTER_NODE, &no_net_cmd);
 
index 14677ac7a501b2986effef4094c3a10caa7367f0..8447a309b2a89ce58fdd80066acd6702f14c69c7 100644 (file)
@@ -29,6 +29,7 @@
 #include "isisd/isis_common.h"
 #include "isisd/isis_redist.h"
 #include "isisd/isis_pdu_counter.h"
+#include "isisd/isis_circuit.h"
 #include "isis_flags.h"
 #include "dict.h"
 #include "isis_memory.h"
@@ -185,6 +186,7 @@ void isis_new(unsigned long);
 struct isis_area *isis_area_create(const char *);
 struct isis_area *isis_area_lookup(const char *);
 int isis_area_get(struct vty *vty, const char *area_tag);
+int isis_area_destroy(const char *area_tag);
 void print_debug(struct vty *, int, int);
 struct isis_lsp *lsp_for_arg(const char *argv, dict_t *lspdb);