#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 */
#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_ */
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
.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",
.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",
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",
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);
#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,
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);
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);
}
#include "table.h"
#include "qobj.h"
#include "spf_backoff.h"
+#include "lib/northbound_cli.h"
#include "isisd/dict.h"
#include "isisd/isis_constants.h"
* 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);
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;
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;
}
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")
}
/*
- *'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
*/
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);
#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"
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);