diff --git a/isisd/isis_cli.c b/isisd/isis_cli.c index c93bcaf8fd..7c7a8d2389 100644 --- a/isisd/isis_cli.c +++ b/isisd/isis_cli.c @@ -23,6 +23,7 @@ #include "isisd/isis_misc.h" #include "isisd/isis_circuit.h" #include "isisd/isis_csm.h" +#include "isisd/isis_flex_algo.h" #include "isisd/isis_cli_clippy.c" @@ -1126,6 +1127,7 @@ void cli_show_isis_purge_origin(struct vty *vty, const struct lyd_node *dnode, vty_out(vty, " purge-originator\n"); } + /* * XPath: /frr-isisd:isis/instance/admin-group-send-zero */ @@ -2720,6 +2722,24 @@ void cli_show_ip_isis_circ_type(struct vty *vty, const struct lyd_node *dnode, } } +static int ag_change(struct vty *vty, int argc, struct cmd_token **argv, + const char *xpath, bool no, int start_idx) +{ + for (int i = start_idx; i < argc; i++) + nb_cli_enqueue_change(vty, xpath, + no ? NB_OP_DESTROY : NB_OP_CREATE, + argv[i]->arg); + return nb_cli_apply_changes(vty, NULL); +} + +static int ag_iter_cb(const struct lyd_node *dnode, void *arg) +{ + struct vty *vty = (struct vty *)arg; + + vty_out(vty, " %s", yang_dnode_get_string(dnode, ".")); + return YANG_ITER_CONTINUE; +} + /* * XPath: /frr-interface:lib/interface/frr-isisd:isis/network-type */ @@ -3348,7 +3368,21 @@ DEFPY_YANG_NOSH(flex_algo, flex_algo_cmd, "flex-algo (128-255)$algorithm", "Flexible Algorithm\n" "Flexible Algorithm Number\n") { - return CMD_SUCCESS; + int ret; + char xpath[XPATH_MAXLEN + 37]; + + snprintf(xpath, sizeof(xpath), + "%s/flex-algos/flex-algo[flex-algo='%ld']", VTY_CURR_XPATH, + algorithm); + + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + + ret = nb_cli_apply_changes( + vty, "./flex-algos/flex-algo[flex-algo='%ld']", algorithm); + if (ret == CMD_SUCCESS) + VTY_PUSH_XPATH(ISIS_FLEX_ALGO_NODE, xpath); + + return ret; } DEFPY_YANG(no_flex_algo, no_flex_algo_cmd, "no flex-algo (128-255)$algorithm", @@ -3356,14 +3390,30 @@ DEFPY_YANG(no_flex_algo, no_flex_algo_cmd, "no flex-algo (128-255)$algorithm", "Flexible Algorithm\n" "Flexible Algorithm Number\n") { - return CMD_SUCCESS; + char xpath[XPATH_MAXLEN + 37]; + + snprintf(xpath, sizeof(xpath), + "%s/flex-algos/flex-algo[flex-algo='%ld']", VTY_CURR_XPATH, + algorithm); + + if (!yang_dnode_exists(vty->candidate_config->dnode, xpath)) { + vty_out(vty, "ISIS flex-algo %ld isn't exist.\n", algorithm); + return CMD_ERR_NO_MATCH; + } + + nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); + return nb_cli_apply_changes_clear_pending( + vty, "./flex-algos/flex-algo[flex-algo='%ld']", algorithm); } DEFPY_YANG(advertise_definition, advertise_definition_cmd, "[no] advertise-definition", NO_STR "Advertise Local Flexible Algorithm\n") { - return CMD_SUCCESS; + nb_cli_enqueue_change(vty, "./advertise-definition", + no ? NB_OP_DESTROY : NB_OP_CREATE, + no ? NULL : "true"); + return nb_cli_apply_changes(vty, NULL); } DEFPY_YANG(affinity_include_any, affinity_include_any_cmd, @@ -3373,7 +3423,9 @@ DEFPY_YANG(affinity_include_any, affinity_include_any_cmd, "Any Include with\n" "Include NAME list\n") { - return CMD_SUCCESS; + const char *xpath = "./affinity-include-anies/affinity-include-any"; + + return ag_change(vty, argc, argv, xpath, no, no ? 3 : 2); } DEFPY_YANG(affinity_include_all, affinity_include_all_cmd, @@ -3383,7 +3435,9 @@ DEFPY_YANG(affinity_include_all, affinity_include_all_cmd, "All Include with\n" "Include NAME list\n") { - return CMD_SUCCESS; + const char *xpath = "./affinity-include-alls/affinity-include-all"; + + return ag_change(vty, argc, argv, xpath, no, no ? 3 : 2); } DEFPY_YANG(affinity_exclude_any, affinity_exclude_any_cmd, @@ -3393,13 +3447,48 @@ DEFPY_YANG(affinity_exclude_any, affinity_exclude_any_cmd, "Any Exclude with\n" "Exclude NAME list\n") { - return CMD_SUCCESS; + const char *xpath = "./affinity-exclude-anies/affinity-exclude-any"; + + return ag_change(vty, argc, argv, xpath, no, no ? 3 : 2); } DEFPY_YANG(prefix_metric, prefix_metric_cmd, "[no] prefix-metric", NO_STR "Use Flex-Algo Prefix Metric\n") { - return CMD_SUCCESS; + nb_cli_enqueue_change(vty, "./prefix-metric", + no ? NB_OP_DESTROY : NB_OP_CREATE, NULL); + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG(dplane_sr_mpls, dplane_sr_mpls_cmd, "[no] dataplane sr-mpls", + NO_STR + "Advertise and participate in the specified Data-Planes\n" + "Advertise and participate in SR-MPLS data-plane\n") +{ + nb_cli_enqueue_change(vty, "./dplane-sr-mpls", + no ? NB_OP_DESTROY : NB_OP_CREATE, NULL); + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_HIDDEN(dplane_srv6, dplane_srv6_cmd, "[no] dataplane srv6", + NO_STR + "Advertise and participate in the specified Data-Planes\n" + "Advertise and participate in SRv6 data-plane\n") +{ + + nb_cli_enqueue_change(vty, "./dplane-srv6", + no ? NB_OP_DESTROY : NB_OP_CREATE, NULL); + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_HIDDEN(dplane_ip, dplane_ip_cmd, "[no] dataplane ip", + NO_STR + "Advertise and participate in the specified Data-Planes\n" + "Advertise and participate in IP data-plane\n") +{ + nb_cli_enqueue_change(vty, "./dplane-ip", + no ? NB_OP_DESTROY : NB_OP_CREATE, NULL); + return nb_cli_apply_changes(vty, NULL); } DEFPY_YANG(metric_type, metric_type_cmd, @@ -3410,7 +3499,29 @@ DEFPY_YANG(metric_type, metric_type_cmd, "Use Delay as metric\n" "Use Traffic Engineering metric\n") { - return CMD_SUCCESS; + const char *type = NULL; + + if (igp) { + type = "igp"; + } else if (te) { + type = "te-default"; + } else if (delay) { + type = "min-uni-link-delay"; + } else { + vty_out(vty, "Error: unknown metric type\n"); + return CMD_SUCCESS; + } + + if (!igp) + vty_out(vty, + "Warning: this version can advertise a Flex-Algorithm Definition (FAD) with the %s metric.\n" + "However, participation in a Flex-Algorithm with such a metric is not yet supported.\n", + type); + + nb_cli_enqueue_change(vty, "./metric-type", + no ? NB_OP_DESTROY : NB_OP_MODIFY, + no ? NULL : type); + return nb_cli_apply_changes(vty, NULL); } DEFPY_YANG(priority, priority_cmd, "[no] priority (0-255)$priority", @@ -3418,18 +3529,85 @@ DEFPY_YANG(priority, priority_cmd, "[no] priority (0-255)$priority", "Flex-Algo definition priority\n" "Priority value\n") { - return CMD_SUCCESS; + nb_cli_enqueue_change(vty, "./priority", + no ? NB_OP_DESTROY : NB_OP_MODIFY, + no ? NULL : priority_str); + return nb_cli_apply_changes(vty, NULL); } void cli_show_isis_flex_algo(struct vty *vty, const struct lyd_node *dnode, bool show_defaults) { + uint32_t algorithm; + enum flex_algo_metric_type metric_type; + uint32_t priority; + char type_str[10]; + + algorithm = yang_dnode_get_uint32(dnode, "./flex-algo"); + vty_out(vty, " flex-algo %u\n", algorithm); + + if (yang_dnode_exists(dnode, "./advertise-definition")) + vty_out(vty, " advertise-definition\n"); + + if (yang_dnode_exists(dnode, "./dplane-sr-mpls")) + vty_out(vty, " dataplane sr-mpls\n"); + if (yang_dnode_exists(dnode, "./dplane-srv6")) + vty_out(vty, " dataplane srv6\n"); + if (yang_dnode_exists(dnode, "./dplane-ip")) + vty_out(vty, " dataplane ip\n"); + + if (yang_dnode_exists(dnode, "./prefix-metric")) + vty_out(vty, " prefix-metric\n"); + + if (yang_dnode_exists(dnode, "./metric-type")) { + metric_type = yang_dnode_get_enum(dnode, "./metric-type"); + if (metric_type != MT_IGP) { + flex_algo_metric_type_print(type_str, sizeof(type_str), + metric_type); + vty_out(vty, " metric-type %s\n", type_str); + } + } + + if (yang_dnode_exists(dnode, "./priority")) { + priority = yang_dnode_get_uint32(dnode, "./priority"); + if (priority != FLEX_ALGO_PRIO_DEFAULT) + vty_out(vty, " priority %u\n", priority); + } + + if (yang_dnode_exists(dnode, + "./affinity-include-alls/affinity-include-all")) { + vty_out(vty, " affinity include-all"); + yang_dnode_iterate( + ag_iter_cb, vty, dnode, + "./affinity-include-alls/affinity-include-all"); + vty_out(vty, "\n"); + } + + if (yang_dnode_exists( + dnode, "./affinity-include-anies/affinity-include-any")) { + vty_out(vty, " affinity include-any"); + yang_dnode_iterate( + ag_iter_cb, vty, dnode, + "./affinity-include-anies/affinity-include-any"); + vty_out(vty, "\n"); + } + + if (yang_dnode_exists( + dnode, "./affinity-exclude-anies/affinity-exclude-any")) { + vty_out(vty, " affinity exclude-any"); + yang_dnode_iterate( + ag_iter_cb, vty, dnode, + "./affinity-exclude-anies/affinity-exclude-any"); + vty_out(vty, "\n"); + } } void cli_show_isis_flex_algo_end(struct vty *vty, const struct lyd_node *dnode) { + vty_out(vty, " !\n"); } + void isis_cli_init(void) { install_element(CONFIG_NODE, &router_isis_cmd); @@ -3581,6 +3759,9 @@ void isis_cli_init(void) install_element(ISIS_FLEX_ALGO_NODE, &affinity_include_any_cmd); install_element(ISIS_FLEX_ALGO_NODE, &affinity_include_all_cmd); install_element(ISIS_FLEX_ALGO_NODE, &affinity_exclude_any_cmd); + install_element(ISIS_FLEX_ALGO_NODE, &dplane_sr_mpls_cmd); + install_element(ISIS_FLEX_ALGO_NODE, &dplane_srv6_cmd); + install_element(ISIS_FLEX_ALGO_NODE, &dplane_ip_cmd); install_element(ISIS_FLEX_ALGO_NODE, &prefix_metric_cmd); install_element(ISIS_FLEX_ALGO_NODE, &metric_type_cmd); install_element(ISIS_FLEX_ALGO_NODE, &priority_cmd);