diff options
Diffstat (limited to 'isisd/isis_cli.c')
| -rw-r--r-- | isisd/isis_cli.c | 265 |
1 files changed, 265 insertions, 0 deletions
diff --git a/isisd/isis_cli.c b/isisd/isis_cli.c index 9f82d85810..2650c5bcb7 100644 --- a/isisd/isis_cli.c +++ b/isisd/isis_cli.c @@ -43,8 +43,273 @@ #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 */ |
