diff options
Diffstat (limited to 'isisd/isis_cli.c')
-rw-r--r-- | isisd/isis_cli.c | 4116 |
1 files changed, 4116 insertions, 0 deletions
diff --git a/isisd/isis_cli.c b/isisd/isis_cli.c new file mode 100644 index 0000000..9718a45 --- /dev/null +++ b/isisd/isis_cli.c @@ -0,0 +1,4116 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2001,2002 Sampo Saaristo + * Tampere University of Technology + * Institute of Communications Engineering + * Copyright (C) 2018 Volta Networks + * Emanuele Di Pascale + */ + +#include <zebra.h> + +#include "if.h" +#include "vrf.h" +#include "log.h" +#include "prefix.h" +#include "command.h" +#include "northbound_cli.h" +#include "libfrr.h" +#include "yang.h" +#include "lib/linklist.h" +#include "isisd/isisd.h" +#include "isisd/isis_nb.h" +#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" + +#ifndef FABRICD + +/* + * XPath: /frr-isisd:isis/instance + */ +DEFPY_YANG_NOSH(router_isis, router_isis_cmd, + "router isis WORD$tag [vrf NAME$vrf_name]", + ROUTER_STR + "ISO IS-IS\n" + "ISO Routing area tag\n" VRF_CMD_HELP_STR) +{ + int ret; + char base_xpath[XPATH_MAXLEN]; + + if (!vrf_name) + vrf_name = VRF_DEFAULT_NAME; + + snprintf(base_xpath, XPATH_MAXLEN, + "/frr-isisd:isis/instance[area-tag='%s'][vrf='%s']", tag, + vrf_name); + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + + ret = nb_cli_apply_changes(vty, "%s", base_xpath); + if (ret == CMD_SUCCESS) + VTY_PUSH_XPATH(ISIS_NODE, base_xpath); + + return ret; +} + +DEFPY_YANG(no_router_isis, no_router_isis_cmd, + "no router isis WORD$tag [vrf NAME$vrf_name]", + NO_STR ROUTER_STR + "ISO IS-IS\n" + "ISO Routing area tag\n" VRF_CMD_HELP_STR) +{ + if (!vrf_name) + vrf_name = VRF_DEFAULT_NAME; + + if (!yang_dnode_existsf( + vty->candidate_config->dnode, + "/frr-isisd:isis/instance[area-tag='%s'][vrf='%s']", tag, + vrf_name)) { + vty_out(vty, "ISIS area %s not found.\n", tag); + return CMD_ERR_NOTHING_TODO; + } + + nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes_clear_pending( + vty, "/frr-isisd:isis/instance[area-tag='%s'][vrf='%s']", tag, + vrf_name); +} + +void cli_show_router_isis(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults) +{ + const char *vrf = NULL; + + vrf = yang_dnode_get_string(dnode, "./vrf"); + + vty_out(vty, "!\n"); + vty_out(vty, "router isis %s", + yang_dnode_get_string(dnode, "./area-tag")); + if (!strmatch(vrf, VRF_DEFAULT_NAME)) + vty_out(vty, " vrf %s", yang_dnode_get_string(dnode, "./vrf")); + vty_out(vty, "\n"); +} + +void cli_show_router_isis_end(struct vty *vty, const struct lyd_node *dnode) +{ + vty_out(vty, "exit\n"); +} + +/* + * 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_YANG(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") +{ + 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_MODIFY, "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +ALIAS_HIDDEN(ip_router_isis, ip_router_isis_vrf_cmd, + "ip router isis WORD$tag vrf NAME$vrf_name", + "Interface Internet Protocol config commands\n" + "IP router interface commands\n" + "IS-IS routing protocol\n" + "Routing process tag\n" VRF_CMD_HELP_STR) + +DEFPY_YANG(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") +{ + 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_MODIFY, "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +ALIAS_HIDDEN(ip6_router_isis, ip6_router_isis_vrf_cmd, + "ipv6 router isis WORD$tag vrf NAME$vrf_name", + "Interface Internet Protocol config commands\n" + "IP router interface commands\n" + "IS-IS routing protocol\n" + "Routing process tag\n" VRF_CMD_HELP_STR) + +DEFPY_YANG(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; + + dnode = yang_dnode_getf(vty->candidate_config->dnode, + "%s/frr-isisd:isis", VTY_CURR_XPATH); + if (!dnode) + return CMD_SUCCESS; + + /* + * If both ipv4 and ipv6 are off delete the interface isis container. + */ + if (strmatch(ip, "ipv6")) { + if (!yang_dnode_get_bool(dnode, "./ipv4-routing")) + nb_cli_enqueue_change(vty, "./frr-isisd:isis", + NB_OP_DESTROY, NULL); + else + nb_cli_enqueue_change(vty, + "./frr-isisd:isis/ipv6-routing", + NB_OP_MODIFY, "false"); + } else { + if (!yang_dnode_get_bool(dnode, "./ipv6-routing")) + nb_cli_enqueue_change(vty, "./frr-isisd:isis", + NB_OP_DESTROY, NULL); + else + nb_cli_enqueue_change(vty, + "./frr-isisd:isis/ipv4-routing", + NB_OP_MODIFY, "false"); + } + + return nb_cli_apply_changes(vty, NULL); +} + +ALIAS_HIDDEN(no_ip_router_isis, no_ip_router_isis_vrf_cmd, + "no <ip|ipv6>$ip router isis WORD$tag vrf NAME$vrf_name", + 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" + VRF_CMD_HELP_STR) + +void cli_show_ip_isis_ipv4(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + vty_out(vty, " ip router isis %s\n", + yang_dnode_get_string(dnode, "../area-tag")); +} + +void cli_show_ip_isis_ipv6(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + vty_out(vty, " ipv6 router isis %s\n", + yang_dnode_get_string(dnode, "../area-tag")); +} + +/* + * XPath: /frr-interface:lib/interface/frr-isisd:isis/bfd-monitoring + */ +DEFPY_YANG(isis_bfd, + isis_bfd_cmd, + "[no] isis bfd", + NO_STR PROTO_HELP + "Enable BFD support\n") +{ + const struct lyd_node *dnode; + + dnode = yang_dnode_getf(vty->candidate_config->dnode, + "%s/frr-isisd:isis", VTY_CURR_XPATH); + if (dnode == NULL) { + vty_out(vty, "ISIS is not enabled on this circuit\n"); + return CMD_SUCCESS; + } + + nb_cli_enqueue_change(vty, "./frr-isisd:isis/bfd-monitoring/enabled", + NB_OP_MODIFY, no ? "false" : "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +/* + * XPath: /frr-interface:lib/interface/frr-isisd:isis/bfd-monitoring/profile + */ +DEFPY_YANG(isis_bfd_profile, + isis_bfd_profile_cmd, + "[no] isis bfd profile BFDPROF$profile", + NO_STR PROTO_HELP + "Enable BFD support\n" + "Use a pre-configured profile\n" + "Profile name\n") +{ + const struct lyd_node *dnode; + + dnode = yang_dnode_getf(vty->candidate_config->dnode, + "%s/frr-isisd:isis", VTY_CURR_XPATH); + if (dnode == NULL) { + vty_out(vty, "ISIS is not enabled on this circuit\n"); + return CMD_SUCCESS; + } + + if (no) + nb_cli_enqueue_change(vty, + "./frr-isisd:isis/bfd-monitoring/profile", + NB_OP_DESTROY, NULL); + else + nb_cli_enqueue_change(vty, + "./frr-isisd:isis/bfd-monitoring/profile", + NB_OP_MODIFY, profile); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_ip_isis_bfd_monitoring(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, "./enabled")) { + if (show_defaults) + vty_out(vty, " no isis bfd\n"); + } else { + vty_out(vty, " isis bfd\n"); + } + + if (yang_dnode_exists(dnode, "./profile")) + vty_out(vty, " isis bfd profile %s\n", + yang_dnode_get_string(dnode, "./profile")); +} + +/* + * XPath: /frr-isisd:isis/instance/area-address + */ +DEFPY_YANG(net, net_cmd, "[no] net WORD", + "Remove an existing Network Entity Title for this process\n" + "A Network Entity Title for this process (OSI only)\n" + "XX.XXXX. ... .XXX.XX Network entity title (NET)\n") +{ + nb_cli_enqueue_change(vty, "./area-address", + no ? NB_OP_DESTROY : NB_OP_CREATE, net); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_area_address(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " net %s\n", yang_dnode_get_string(dnode, NULL)); +} + +/* + * XPath: /frr-isisd:isis/instance/is-type + */ +DEFPY_YANG(is_type, is_type_cmd, "is-type <level-1|level-1-2|level-2-only>$level", + "IS Level for this routing process (OSI only)\n" + "Act as a station router only\n" + "Act as both a station router and an area router\n" + "Act as an area router only\n") +{ + nb_cli_enqueue_change(vty, "./is-type", NB_OP_MODIFY, + strmatch(level, "level-2-only") ? "level-2" + : level); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG(no_is_type, no_is_type_cmd, + "no is-type [<level-1|level-1-2|level-2-only>]", + NO_STR + "IS Level for this routing process (OSI only)\n" + "Act as a station router only\n" + "Act as both a station router and an area router\n" + "Act as an area router only\n") +{ + nb_cli_enqueue_change(vty, "./is-type", NB_OP_MODIFY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_is_type(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults) +{ + int is_type = yang_dnode_get_enum(dnode, NULL); + + switch (is_type) { + case IS_LEVEL_1: + vty_out(vty, " is-type level-1\n"); + break; + case IS_LEVEL_2: + vty_out(vty, " is-type level-2-only\n"); + break; + case IS_LEVEL_1_AND_2: + vty_out(vty, " is-type level-1-2\n"); + break; + } +} + +/* + * XPath: /frr-isisd:isis/instance/dynamic-hostname + */ +DEFPY_YANG(dynamic_hostname, dynamic_hostname_cmd, "[no] hostname dynamic", + NO_STR + "Dynamic hostname for IS-IS\n" + "Dynamic hostname\n") +{ + nb_cli_enqueue_change(vty, "./dynamic-hostname", NB_OP_MODIFY, + no ? "false" : "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_dynamic_hostname(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + + vty_out(vty, " hostname dynamic\n"); +} + +/* + * XPath: /frr-isisd:isis/instance/overload + */ +DEFPY_YANG(set_overload_bit, set_overload_bit_cmd, "[no] set-overload-bit", + "Reset overload bit to accept transit traffic\n" + "Set overload bit to avoid any transit traffic\n") +{ + nb_cli_enqueue_change(vty, "./overload/enabled", NB_OP_MODIFY, + no ? "false" : "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_overload(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + vty_out(vty, " set-overload-bit\n"); +} + +/* + * XPath: /frr-isisd:isis/instance/overload/on-startup + */ +DEFPY_YANG(set_overload_bit_on_startup, set_overload_bit_on_startup_cmd, + "set-overload-bit on-startup (0-86400)$val", + "Set overload bit to avoid any transit traffic\n" + "Set overload bit on startup\n" + "Set overload time in seconds\n") +{ + nb_cli_enqueue_change(vty, "./overload/on-startup", NB_OP_MODIFY, + val_str); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG(no_set_overload_bit_on_startup, no_set_overload_bit_on_startup_cmd, + "no set-overload-bit on-startup [(0-86400)$val]", + NO_STR + "Reset overload bit to accept transit traffic\n" + "Set overload bit on startup\n" + "Set overload time in seconds\n") +{ + nb_cli_enqueue_change(vty, "./overload/on-startup", NB_OP_DESTROY, + NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_overload_on_startup(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " set-overload-bit on-startup %s\n", + yang_dnode_get_string(dnode, NULL)); +} + +/* + * XPath: /frr-isisd:isis/instance/advertise-high-metrics + */ +DEFPY_YANG(advertise_high_metrics, advertise_high_metrics_cmd, + "[no] advertise-high-metrics", + NO_STR "Advertise high metric value on all interfaces\n") +{ + nb_cli_enqueue_change(vty, "./advertise-high-metrics", NB_OP_MODIFY, + no ? "false" : "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_advertise_high_metrics(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + if (yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " advertise-high-metrics\n"); + else if (show_defaults) + vty_out(vty, " no advertise-high-metrics\n"); +} + +/* + * XPath: /frr-isisd:isis/instance/attach-send + */ +DEFPY_YANG(attached_bit_send, attached_bit_send_cmd, "[no] attached-bit send", + "Reset attached bit\n" + "Set attached bit for inter-area traffic\n" + "Set attached bit in LSP sent to L1 router\n") +{ + nb_cli_enqueue_change(vty, "./attach-send", NB_OP_MODIFY, + no ? "false" : "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_attached_send(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + vty_out(vty, " attached-bit send\n"); +} + +/* + * XPath: /frr-isisd:isis/instance/attach-receive-ignore + */ +DEFPY_YANG( + attached_bit_receive_ignore, attached_bit_receive_ignore_cmd, + "[no] attached-bit receive ignore", + "Reset attached bit\n" + "Set attach bit for inter-area traffic\n" + "If LSP received with attached bit set, create default route to neighbor\n" + "Do not process attached bit\n") +{ + nb_cli_enqueue_change(vty, "./attach-receive-ignore", NB_OP_MODIFY, + no ? "false" : "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_attached_receive(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + vty_out(vty, " attached-bit receive ignore\n"); +} + +/* + * XPath: /frr-isisd:isis/instance/metric-style + */ +DEFPY_YANG(metric_style, metric_style_cmd, + "metric-style <narrow|transition|wide>$style", + "Use old-style (ISO 10589) or new-style packet formats\n" + "Use old style of TLVs with narrow metric\n" + "Send and accept both styles of TLVs during transition\n" + "Use new style of TLVs to carry wider metric\n") +{ + nb_cli_enqueue_change(vty, "./metric-style", NB_OP_MODIFY, style); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG(no_metric_style, no_metric_style_cmd, + "no metric-style [narrow|transition|wide]", + NO_STR + "Use old-style (ISO 10589) or new-style packet formats\n" + "Use old style of TLVs with narrow metric\n" + "Send and accept both styles of TLVs during transition\n" + "Use new style of TLVs to carry wider metric\n") +{ + nb_cli_enqueue_change(vty, "./metric-style", NB_OP_MODIFY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_metric_style(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults) +{ + int metric = yang_dnode_get_enum(dnode, NULL); + + switch (metric) { + case ISIS_NARROW_METRIC: + vty_out(vty, " metric-style narrow\n"); + break; + case ISIS_WIDE_METRIC: + vty_out(vty, " metric-style wide\n"); + break; + case ISIS_TRANSITION_METRIC: + vty_out(vty, " metric-style transition\n"); + break; + } +} + +/* + * XPath: /frr-isisd:isis/instance/area-password + */ +DEFPY_YANG(area_passwd, area_passwd_cmd, + "area-password <clear|md5>$pwd_type WORD$pwd [authenticate snp <send-only|validate>$snp]", + "Configure the authentication password for an area\n" + "Clear-text authentication type\n" + "MD5 authentication type\n" + "Level-wide password\n" + "Authentication\n" + "SNP PDUs\n" + "Send but do not check PDUs on receiving\n" + "Send and check PDUs on receiving\n") +{ + nb_cli_enqueue_change(vty, "./area-password", NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, "./area-password/password", NB_OP_MODIFY, + pwd); + nb_cli_enqueue_change(vty, "./area-password/password-type", + NB_OP_MODIFY, pwd_type); + nb_cli_enqueue_change(vty, "./area-password/authenticate-snp", + NB_OP_MODIFY, snp ? snp : "none"); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_area_pwd(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults) +{ + const char *snp; + + vty_out(vty, " area-password %s %s", + yang_dnode_get_string(dnode, "./password-type"), + yang_dnode_get_string(dnode, "./password")); + snp = yang_dnode_get_string(dnode, "./authenticate-snp"); + if (!strmatch("none", snp)) + vty_out(vty, " authenticate snp %s", snp); + vty_out(vty, "\n"); +} + +/* + * XPath: /frr-isisd:isis/instance/domain-password + */ +DEFPY_YANG(domain_passwd, domain_passwd_cmd, + "domain-password <clear|md5>$pwd_type WORD$pwd [authenticate snp <send-only|validate>$snp]", + "Set the authentication password for a routing domain\n" + "Clear-text authentication type\n" + "MD5 authentication type\n" + "Level-wide password\n" + "Authentication\n" + "SNP PDUs\n" + "Send but do not check PDUs on receiving\n" + "Send and check PDUs on receiving\n") +{ + nb_cli_enqueue_change(vty, "./domain-password", NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, "./domain-password/password", NB_OP_MODIFY, + pwd); + nb_cli_enqueue_change(vty, "./domain-password/password-type", + NB_OP_MODIFY, pwd_type); + nb_cli_enqueue_change(vty, "./domain-password/authenticate-snp", + NB_OP_MODIFY, snp ? snp : "none"); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG(no_area_passwd, no_area_passwd_cmd, + "no <area-password|domain-password>$cmd", + NO_STR + "Configure the authentication password for an area\n" + "Set the authentication password for a routing domain\n") +{ + nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, "./%s", cmd); +} + +void cli_show_isis_domain_pwd(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults) +{ + const char *snp; + + vty_out(vty, " domain-password %s %s", + yang_dnode_get_string(dnode, "./password-type"), + yang_dnode_get_string(dnode, "./password")); + snp = yang_dnode_get_string(dnode, "./authenticate-snp"); + if (!strmatch("none", snp)) + vty_out(vty, " authenticate snp %s", snp); + vty_out(vty, "\n"); +} + +/* + * XPath: /frr-isisd:isis/instance/lsp/timers/level-1/generation-interval + * XPath: /frr-isisd:isis/instance/lsp/timers/level-2/generation-interval + */ +DEFPY_YANG(lsp_gen_interval, lsp_gen_interval_cmd, + "lsp-gen-interval [level-1|level-2]$level (1-120)$val", + "Minimum interval between regenerating same LSP\n" + "Set interval for level 1 only\n" + "Set interval for level 2 only\n" + "Minimum interval in seconds\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change( + vty, "./lsp/timers/level-1/generation-interval", + NB_OP_MODIFY, val_str); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change( + vty, "./lsp/timers/level-2/generation-interval", + NB_OP_MODIFY, val_str); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG(no_lsp_gen_interval, no_lsp_gen_interval_cmd, + "no lsp-gen-interval [level-1|level-2]$level [(1-120)]", + NO_STR + "Minimum interval between regenerating same LSP\n" + "Set interval for level 1 only\n" + "Set interval for level 2 only\n" + "Minimum interval in seconds\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change( + vty, "./lsp/timers/level-1/generation-interval", + NB_OP_MODIFY, NULL); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change( + vty, "./lsp/timers/level-2/generation-interval", + NB_OP_MODIFY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +/* + * XPath: /frr-isisd:isis/instance/lsp/timers/level-1/refresh-interval + * XPath: /frr-isisd:isis/instance/lsp/timers/level-2/refresh-interval + */ +DEFPY_YANG(lsp_refresh_interval, lsp_refresh_interval_cmd, + "lsp-refresh-interval [level-1|level-2]$level (1-65235)$val", + "LSP refresh interval\n" + "LSP refresh interval for Level 1 only\n" + "LSP refresh interval for Level 2 only\n" + "LSP refresh interval in seconds\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change(vty, + "./lsp/timers/level-1/refresh-interval", + NB_OP_MODIFY, val_str); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change(vty, + "./lsp/timers/level-2/refresh-interval", + NB_OP_MODIFY, val_str); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG(no_lsp_refresh_interval, no_lsp_refresh_interval_cmd, + "no lsp-refresh-interval [level-1|level-2]$level [(1-65235)]", + NO_STR + "LSP refresh interval\n" + "LSP refresh interval for Level 1 only\n" + "LSP refresh interval for Level 2 only\n" + "LSP refresh interval in seconds\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change(vty, + "./lsp/timers/level-1/refresh-interval", + NB_OP_MODIFY, NULL); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change(vty, + "./lsp/timers/level-2/refresh-interval", + NB_OP_MODIFY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +/* + * XPath: /frr-isisd:isis/instance/lsp/timers/level-1/maximum-lifetime + * XPath: /frr-isisd:isis/instance/lsp/timers/level-1/maximum-lifetime + */ + +DEFPY_YANG(max_lsp_lifetime, max_lsp_lifetime_cmd, + "max-lsp-lifetime [level-1|level-2]$level (350-65535)$val", + "Maximum LSP lifetime\n" + "Maximum LSP lifetime for Level 1 only\n" + "Maximum LSP lifetime for Level 2 only\n" + "LSP lifetime in seconds\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change(vty, + "./lsp/timers/level-1/maximum-lifetime", + NB_OP_MODIFY, val_str); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change(vty, + "./lsp/timers/level-2/maximum-lifetime", + NB_OP_MODIFY, val_str); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG(no_max_lsp_lifetime, no_max_lsp_lifetime_cmd, + "no max-lsp-lifetime [level-1|level-2]$level [(350-65535)]", + NO_STR + "Maximum LSP lifetime\n" + "Maximum LSP lifetime for Level 1 only\n" + "Maximum LSP lifetime for Level 2 only\n" + "LSP lifetime in seconds\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change(vty, + "./lsp/timers/level-1/maximum-lifetime", + NB_OP_MODIFY, NULL); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change(vty, + "./lsp/timers/level-2/maximum-lifetime", + NB_OP_MODIFY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +/* unified LSP timers command + * XPath: /frr-isisd:isis/instance/lsp/timers + */ + +DEFPY_YANG(lsp_timers, lsp_timers_cmd, + "lsp-timers [level-1|level-2]$level gen-interval (1-120)$gen refresh-interval (1-65235)$refresh max-lifetime (350-65535)$lifetime", + "LSP-related timers\n" + "LSP-related timers for Level 1 only\n" + "LSP-related timers for Level 2 only\n" + "Minimum interval between regenerating same LSP\n" + "Generation interval in seconds\n" + "LSP refresh interval\n" + "LSP refresh interval in seconds\n" + "Maximum LSP lifetime\n" + "Maximum LSP lifetime in seconds\n") +{ + if (!level || strmatch(level, "level-1")) { + nb_cli_enqueue_change( + vty, "./lsp/timers/level-1/generation-interval", + NB_OP_MODIFY, gen_str); + nb_cli_enqueue_change(vty, + "./lsp/timers/level-1/refresh-interval", + NB_OP_MODIFY, refresh_str); + nb_cli_enqueue_change(vty, + "./lsp/timers/level-1/maximum-lifetime", + NB_OP_MODIFY, lifetime_str); + } + if (!level || strmatch(level, "level-2")) { + nb_cli_enqueue_change( + vty, "./lsp/timers/level-2/generation-interval", + NB_OP_MODIFY, gen_str); + nb_cli_enqueue_change(vty, + "./lsp/timers/level-2/refresh-interval", + NB_OP_MODIFY, refresh_str); + nb_cli_enqueue_change(vty, + "./lsp/timers/level-2/maximum-lifetime", + NB_OP_MODIFY, lifetime_str); + } + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG(no_lsp_timers, no_lsp_timers_cmd, + "no lsp-timers [level-1|level-2]$level [gen-interval (1-120) refresh-interval (1-65235) max-lifetime (350-65535)]", + NO_STR + "LSP-related timers\n" + "LSP-related timers for Level 1 only\n" + "LSP-related timers for Level 2 only\n" + "Minimum interval between regenerating same LSP\n" + "Generation interval in seconds\n" + "LSP refresh interval\n" + "LSP refresh interval in seconds\n" + "Maximum LSP lifetime\n" + "Maximum LSP lifetime in seconds\n") +{ + if (!level || strmatch(level, "level-1")) { + nb_cli_enqueue_change( + vty, "./lsp/timers/level-1/generation-interval", + NB_OP_MODIFY, NULL); + nb_cli_enqueue_change(vty, + "./lsp/timers/level-1/refresh-interval", + NB_OP_MODIFY, NULL); + nb_cli_enqueue_change(vty, + "./lsp/timers/level-1/maximum-lifetime", + NB_OP_MODIFY, NULL); + } + if (!level || strmatch(level, "level-2")) { + nb_cli_enqueue_change( + vty, "./lsp/timers/level-2/generation-interval", + NB_OP_MODIFY, NULL); + nb_cli_enqueue_change(vty, + "./lsp/timers/level-2/refresh-interval", + NB_OP_MODIFY, NULL); + nb_cli_enqueue_change(vty, + "./lsp/timers/level-2/maximum-lifetime", + NB_OP_MODIFY, NULL); + } + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_lsp_timers(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults) +{ + const char *l1_refresh = + yang_dnode_get_string(dnode, "./level-1/refresh-interval"); + const char *l2_refresh = + yang_dnode_get_string(dnode, "./level-2/refresh-interval"); + const char *l1_lifetime = + yang_dnode_get_string(dnode, "./level-1/maximum-lifetime"); + const char *l2_lifetime = + yang_dnode_get_string(dnode, "./level-2/maximum-lifetime"); + const char *l1_gen = + yang_dnode_get_string(dnode, "./level-1/generation-interval"); + const char *l2_gen = + yang_dnode_get_string(dnode, "./level-2/generation-interval"); + if (strmatch(l1_refresh, l2_refresh) + && strmatch(l1_lifetime, l2_lifetime) && strmatch(l1_gen, l2_gen)) + vty_out(vty, + " lsp-timers gen-interval %s refresh-interval %s max-lifetime %s\n", + l1_gen, l1_refresh, l1_lifetime); + else { + vty_out(vty, + " lsp-timers level-1 gen-interval %s refresh-interval %s max-lifetime %s\n", + l1_gen, l1_refresh, l1_lifetime); + vty_out(vty, + " lsp-timers level-2 gen-interval %s refresh-interval %s max-lifetime %s\n", + l2_gen, l2_refresh, l2_lifetime); + } +} + +/* + * XPath: /frr-isisd:isis/instance/lsp/mtu + */ +DEFPY_YANG(area_lsp_mtu, area_lsp_mtu_cmd, "lsp-mtu (128-4352)$val", + "Configure the maximum size of generated LSPs\n" + "Maximum size of generated LSPs\n") +{ + nb_cli_enqueue_change(vty, "./lsp/mtu", NB_OP_MODIFY, val_str); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG(no_area_lsp_mtu, no_area_lsp_mtu_cmd, "no lsp-mtu [(128-4352)]", + NO_STR + "Configure the maximum size of generated LSPs\n" + "Maximum size of generated LSPs\n") +{ + nb_cli_enqueue_change(vty, "./lsp/mtu", NB_OP_MODIFY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_lsp_mtu(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " lsp-mtu %s\n", yang_dnode_get_string(dnode, NULL)); +} + +/* + * XPath: /frr-isisd:isis/instance/advertise-passive-only + */ +DEFPY_YANG(advertise_passive_only, advertise_passive_only_cmd, + "[no] advertise-passive-only", + NO_STR "Advertise prefixes of passive interfaces only\n") +{ + nb_cli_enqueue_change(vty, "./advertise-passive-only", NB_OP_MODIFY, + no ? "false" : "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_advertise_passive_only(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + + vty_out(vty, " advertise-passive-only\n"); +} + +/* + * XPath: /frr-isisd:isis/instance/spf/minimum-interval + */ +DEFPY_YANG(spf_interval, spf_interval_cmd, + "spf-interval [level-1|level-2]$level (1-120)$val", + "Minimum interval between SPF calculations\n" + "Set interval for level 1 only\n" + "Set interval for level 2 only\n" + "Minimum interval between consecutive SPFs in seconds\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change(vty, "./spf/minimum-interval/level-1", + NB_OP_MODIFY, val_str); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change(vty, "./spf/minimum-interval/level-2", + NB_OP_MODIFY, val_str); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG(no_spf_interval, no_spf_interval_cmd, + "no spf-interval [level-1|level-2]$level [(1-120)]", + NO_STR + "Minimum interval between SPF calculations\n" + "Set interval for level 1 only\n" + "Set interval for level 2 only\n" + "Minimum interval between consecutive SPFs in seconds\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change(vty, "./spf/minimum-interval/level-1", + NB_OP_MODIFY, NULL); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change(vty, "./spf/minimum-interval/level-2", + NB_OP_MODIFY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_spf_min_interval(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + const char *l1 = yang_dnode_get_string(dnode, "./level-1"); + const char *l2 = yang_dnode_get_string(dnode, "./level-2"); + + if (strmatch(l1, l2)) + vty_out(vty, " spf-interval %s\n", l1); + else { + vty_out(vty, " spf-interval level-1 %s\n", l1); + vty_out(vty, " spf-interval level-2 %s\n", l2); + } +} + +/* + * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay + */ +DEFPY_YANG(spf_delay_ietf, spf_delay_ietf_cmd, + "spf-delay-ietf init-delay (0-60000) short-delay (0-60000) long-delay (0-60000) holddown (0-60000) time-to-learn (0-60000)", + "IETF SPF delay algorithm\n" + "Delay used while in QUIET state\n" + "Delay used while in QUIET state in milliseconds\n" + "Delay used while in SHORT_WAIT state\n" + "Delay used while in SHORT_WAIT state in milliseconds\n" + "Delay used while in LONG_WAIT\n" + "Delay used while in LONG_WAIT state in milliseconds\n" + "Time with no received IGP events before considering IGP stable\n" + "Time with no received IGP events before considering IGP stable (in milliseconds)\n" + "Maximum duration needed to learn all the events related to a single failure\n" + "Maximum duration needed to learn all the events related to a single failure (in milliseconds)\n") +{ + nb_cli_enqueue_change(vty, "./spf/ietf-backoff-delay", NB_OP_CREATE, + NULL); + nb_cli_enqueue_change(vty, "./spf/ietf-backoff-delay/init-delay", + NB_OP_MODIFY, init_delay_str); + nb_cli_enqueue_change(vty, "./spf/ietf-backoff-delay/short-delay", + NB_OP_MODIFY, short_delay_str); + nb_cli_enqueue_change(vty, "./spf/ietf-backoff-delay/long-delay", + NB_OP_MODIFY, long_delay_str); + nb_cli_enqueue_change(vty, "./spf/ietf-backoff-delay/hold-down", + NB_OP_MODIFY, holddown_str); + nb_cli_enqueue_change(vty, "./spf/ietf-backoff-delay/time-to-learn", + NB_OP_MODIFY, time_to_learn_str); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG(no_spf_delay_ietf, no_spf_delay_ietf_cmd, + "no spf-delay-ietf [init-delay (0-60000) short-delay (0-60000) long-delay (0-60000) holddown (0-60000) time-to-learn (0-60000)]", + NO_STR + "IETF SPF delay algorithm\n" + "Delay used while in QUIET state\n" + "Delay used while in QUIET state in milliseconds\n" + "Delay used while in SHORT_WAIT state\n" + "Delay used while in SHORT_WAIT state in milliseconds\n" + "Delay used while in LONG_WAIT\n" + "Delay used while in LONG_WAIT state in milliseconds\n" + "Time with no received IGP events before considering IGP stable\n" + "Time with no received IGP events before considering IGP stable (in milliseconds)\n" + "Maximum duration needed to learn all the events related to a single failure\n" + "Maximum duration needed to learn all the events related to a single failure (in milliseconds)\n") +{ + nb_cli_enqueue_change(vty, "./spf/ietf-backoff-delay", NB_OP_DESTROY, + NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_spf_ietf_backoff(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, + " spf-delay-ietf init-delay %s short-delay %s long-delay %s holddown %s time-to-learn %s\n", + yang_dnode_get_string(dnode, "./init-delay"), + yang_dnode_get_string(dnode, "./short-delay"), + yang_dnode_get_string(dnode, "./long-delay"), + yang_dnode_get_string(dnode, "./hold-down"), + yang_dnode_get_string(dnode, "./time-to-learn")); +} + +/* + * XPath: /frr-isisd:isis/instance/spf/prefix-priorities/medium/access-list-name + */ +DEFPY_YANG(spf_prefix_priority, spf_prefix_priority_cmd, + "spf prefix-priority <critical|high|medium>$priority ACCESSLIST_NAME$acl_name", + "SPF configuration\n" + "Configure a prefix priority list\n" + "Specify critical priority prefixes\n" + "Specify high priority prefixes\n" + "Specify medium priority prefixes\n" + "Access-list name\n") +{ + char xpath[XPATH_MAXLEN]; + + snprintf(xpath, XPATH_MAXLEN, + "./spf/prefix-priorities/%s/access-list-name", priority); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, acl_name); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG(no_spf_prefix_priority, no_spf_prefix_priority_cmd, + "no spf prefix-priority <critical|high|medium>$priority [ACCESSLIST_NAME]", + NO_STR + "SPF configuration\n" + "Configure a prefix priority list\n" + "Specify critical priority prefixes\n" + "Specify high priority prefixes\n" + "Specify medium priority prefixes\n" + "Access-list name\n") +{ + char xpath[XPATH_MAXLEN]; + + snprintf(xpath, XPATH_MAXLEN, + "./spf/prefix-priorities/%s/access-list-name", priority); + nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_spf_prefix_priority(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " spf prefix-priority %s %s\n", + dnode->parent->schema->name, + yang_dnode_get_string(dnode, NULL)); +} + +/* + * XPath: /frr-isisd:isis/instance/purge-originator + */ +DEFPY_YANG(area_purge_originator, area_purge_originator_cmd, "[no] purge-originator", + NO_STR "Use the RFC 6232 purge-originator\n") +{ + nb_cli_enqueue_change(vty, "./purge-originator", NB_OP_MODIFY, + no ? "false" : "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_purge_origin(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + vty_out(vty, " purge-originator\n"); +} + + +/* + * XPath: /frr-isisd:isis/instance/admin-group-send-zero + */ +DEFPY_YANG(isis_admin_group_send_zero, isis_admin_group_send_zero_cmd, + "[no] admin-group-send-zero", + NO_STR + "Allow sending the default admin-group value of 0x00000000.\n") +{ + nb_cli_enqueue_change(vty, "./admin-group-send-zero", NB_OP_MODIFY, + no ? "false" : "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_admin_group_send_zero(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + vty_out(vty, " admin-group-send-zero\n"); +} + + +/* + * XPath: /frr-isisd:isis/instance/asla-legacy-flag + */ +DEFPY_HIDDEN(isis_asla_legacy_flag, isis_asla_legacy_flag_cmd, + "[no] asla-legacy-flag", + NO_STR "Set the legacy flag (aka. L-FLAG) in the ASLA Sub-TLV.\n") +{ + nb_cli_enqueue_change(vty, "./asla-legacy-flag", NB_OP_MODIFY, + no ? "false" : "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_asla_legacy_flag(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + vty_out(vty, " asla-legacy-flag\n"); +} + +/* + * XPath: /frr-isisd:isis/instance/mpls-te + */ +DEFPY_YANG(isis_mpls_te_on, isis_mpls_te_on_cmd, "mpls-te on", + MPLS_TE_STR "Enable the MPLS-TE functionality\n") +{ + nb_cli_enqueue_change(vty, "./mpls-te", NB_OP_CREATE, + NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG(no_isis_mpls_te_on, no_isis_mpls_te_on_cmd, "no mpls-te [on]", + NO_STR + "Disable the MPLS-TE functionality\n" + "Disable the MPLS-TE functionality\n") +{ + nb_cli_enqueue_change(vty, "./mpls-te", NB_OP_DESTROY, + NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_mpls_te(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " mpls-te on\n"); +} + +/* + * XPath: /frr-isisd:isis/instance/mpls-te/router-address + */ +DEFPY_YANG(isis_mpls_te_router_addr, isis_mpls_te_router_addr_cmd, + "mpls-te router-address A.B.C.D", + MPLS_TE_STR + "Stable IP address of the advertising router\n" + "MPLS-TE router address in IPv4 address format\n") +{ + nb_cli_enqueue_change(vty, "./mpls-te/router-address", + NB_OP_MODIFY, router_address_str); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG(no_isis_mpls_te_router_addr, no_isis_mpls_te_router_addr_cmd, + "no mpls-te router-address [A.B.C.D]", + NO_STR MPLS_TE_STR + "Delete IP address of the advertising router\n" + "MPLS-TE router address in IPv4 address format\n") +{ + nb_cli_enqueue_change(vty, "./mpls-te/router-address", + NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_mpls_te_router_addr(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " mpls-te router-address %s\n", + yang_dnode_get_string(dnode, NULL)); +} + +/* + * XPath: /frr-isisd:isis/instance/mpls-te/router-address-v6 + */ +DEFPY_YANG(isis_mpls_te_router_addr_v6, isis_mpls_te_router_addr_v6_cmd, + "mpls-te router-address ipv6 X:X::X:X", + MPLS_TE_STR + "Stable IP address of the advertising router\n" + "IPv6 address\n" + "MPLS-TE router address in IPv6 address format\n") +{ + nb_cli_enqueue_change(vty, "./mpls-te/router-address-v6", NB_OP_MODIFY, + ipv6_str); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG(no_isis_mpls_te_router_addr_v6, no_isis_mpls_te_router_addr_v6_cmd, + "no mpls-te router-address ipv6 [X:X::X:X]", + NO_STR MPLS_TE_STR + "Delete IP address of the advertising router\n" + "IPv6 address\n" + "MPLS-TE router address in IPv6 address format\n") +{ + nb_cli_enqueue_change(vty, "./mpls-te/router-address-v6", NB_OP_DESTROY, + NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_mpls_te_router_addr_ipv6(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " mpls-te router-address ipv6 %s\n", + yang_dnode_get_string(dnode, NULL)); +} + +DEFPY_YANG(isis_mpls_te_inter_as, isis_mpls_te_inter_as_cmd, + "[no] mpls-te inter-as [level-1|level-1-2|level-2-only]", + NO_STR MPLS_TE_STR + "Configure MPLS-TE Inter-AS support\n" + "AREA native mode self originate INTER-AS LSP with L1 only flooding scope\n" + "AREA native mode self originate INTER-AS LSP with L1 and L2 flooding scope\n" + "AS native mode self originate INTER-AS LSP with L2 only flooding scope\n") +{ + vty_out(vty, "MPLS-TE Inter-AS is not yet supported\n"); + return CMD_SUCCESS; +} + +/* + * XPath: /frr-isisd:isis/instance/mpls-te/export + */ +DEFPY_YANG(isis_mpls_te_export, isis_mpls_te_export_cmd, "mpls-te export", + MPLS_TE_STR "Enable export of MPLS-TE Link State information\n") +{ + nb_cli_enqueue_change(vty, "./mpls-te/export", NB_OP_MODIFY, "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG(no_isis_mpls_te_export, no_isis_mpls_te_export_cmd, + "no mpls-te export", + NO_STR MPLS_TE_STR + "Disable export of MPLS-TE Link State information\n") +{ + nb_cli_enqueue_change(vty, "./mpls-te/export", NB_OP_MODIFY, "false"); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_mpls_te_export(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + + vty_out(vty, " mpls-te export\n"); +} + +/* + * XPath: /frr-isisd:isis/instance/default-information-originate + */ +DEFPY_YANG(isis_default_originate, isis_default_originate_cmd, + "[no] default-information originate <ipv4|ipv6>$ip <level-1|level-2>$level [always]$always [{metric (0-16777215)$metric|route-map RMAP_NAME$rmap}]", + NO_STR + "Control distribution of default information\n" + "Distribute a default route\n" + "Distribute default route for IPv4\n" + "Distribute default route for IPv6\n" + "Distribute default route into level-1\n" + "Distribute default route into level-2\n" + "Always advertise default route\n" + "Metric for default route\n" + "IS-IS default metric\n" + "Route map reference\n" + "Pointer to route-map entries\n") +{ + if (no) + nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); + else { + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, "./always", NB_OP_MODIFY, + always ? "true" : "false"); + nb_cli_enqueue_change(vty, "./route-map", + rmap ? NB_OP_MODIFY : NB_OP_DESTROY, + rmap ? rmap : NULL); + nb_cli_enqueue_change(vty, "./metric", NB_OP_MODIFY, + metric_str ? metric_str : NULL); + if (strmatch(ip, "ipv6") && !always) { + vty_out(vty, + "Zebra doesn't implement default-originate for IPv6 yet\n"); + vty_out(vty, + "so use with care or use default-originate always.\n"); + } + } + + return nb_cli_apply_changes( + vty, "./default-information-originate/%s[level='%s']", ip, + level); +} + +static void vty_print_def_origin(struct vty *vty, const struct lyd_node *dnode, + const char *family, const char *level, + bool show_defaults) +{ + vty_out(vty, " default-information originate %s %s", family, level); + if (yang_dnode_get_bool(dnode, "./always")) + vty_out(vty, " always"); + + if (yang_dnode_exists(dnode, "./route-map")) + vty_out(vty, " route-map %s", + yang_dnode_get_string(dnode, "./route-map")); + if (show_defaults || !yang_dnode_is_default(dnode, "./metric")) + vty_out(vty, " metric %s", + yang_dnode_get_string(dnode, "./metric")); + + vty_out(vty, "\n"); +} + +void cli_show_isis_def_origin_ipv4(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + const char *level = yang_dnode_get_string(dnode, "./level"); + + vty_print_def_origin(vty, dnode, "ipv4", level, show_defaults); +} + +void cli_show_isis_def_origin_ipv6(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + const char *level = yang_dnode_get_string(dnode, "./level"); + + vty_print_def_origin(vty, dnode, "ipv6", level, show_defaults); +} + +/* + * XPath: /frr-isisd:isis/instance/redistribute + */ +DEFPY_YANG(isis_redistribute, isis_redistribute_cmd, + "[no] redistribute <ipv4$ip " PROTO_IP_REDIST_STR "$proto|ipv6$ip " + PROTO_IP6_REDIST_STR "$proto> <level-1|level-2>$level" + "[{metric (0-16777215)|route-map RMAP_NAME$route_map}]", + NO_STR REDIST_STR + "Redistribute IPv4 routes\n" + PROTO_IP_REDIST_HELP + "Redistribute IPv6 routes\n" + PROTO_IP6_REDIST_HELP + "Redistribute into level-1\n" + "Redistribute into level-2\n" + "Metric for redistributed routes\n" + "IS-IS default metric\n" + "Route map reference\n" + "Pointer to route-map entries\n") +{ + if (no) + nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); + else { + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, "./route-map", + route_map ? NB_OP_MODIFY : NB_OP_DESTROY, + route_map ? route_map : NULL); + nb_cli_enqueue_change(vty, "./metric", NB_OP_MODIFY, + metric_str ? metric_str : NULL); + } + + return nb_cli_apply_changes( + vty, "./redistribute/%s[protocol='%s'][level='%s']", ip, proto, + level); +} + +/* + * XPath: /frr-isisd:isis/instance/redistribute/table + */ +DEFPY_YANG(isis_redistribute_table, isis_redistribute_table_cmd, + "[no] redistribute <ipv4|ipv6>$ip table (1-65535)$table" + "<level-1|level-2>$level [{metric (0-16777215)|route-map WORD}]", + NO_STR REDIST_STR "Redistribute IPv4 routes\n" + "Redistribute IPv6 routes\n" + "Non-main Kernel Routing Table\n" + "Table Id\n" + "Redistribute into level-1\n" + "Redistribute into level-2\n" + "Metric for redistributed routes\n" + "IS-IS default metric\n" + "Route map reference\n" + "Pointer to route-map entries\n") +{ + struct isis_redist_table_present_args rtda = {}; + char xpath[XPATH_MAXLEN]; + char xpath_entry[XPATH_MAXLEN + 128]; + int rv; + + rtda.rtda_table = table_str; + rtda.rtda_ip = ip; + rtda.rtda_level = level; + + if (no) { + if (!isis_redist_table_is_present(vty, &rtda)) + return CMD_WARNING_CONFIG_FAILED; + + snprintf(xpath, sizeof(xpath), "./table[table='%s']", table_str); + nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); + rv = nb_cli_apply_changes(vty, + "./redistribute/%s[protocol='table'][level='%s']", + ip, level); + if (rv == CMD_SUCCESS) { + if (isis_redist_table_get_first(vty, &rtda) > 0) + return CMD_SUCCESS; + nb_cli_enqueue_change(vty, "./table", NB_OP_DESTROY, + NULL); + nb_cli_apply_changes(vty, + "./redistribute/%s[protocol='table'][level='%s']", + ip, level); + } + return CMD_SUCCESS; + } + if (isis_redist_table_is_present(vty, &rtda)) + return CMD_SUCCESS; + + snprintf(xpath, sizeof(xpath), "./table[table='%s']", table_str); + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + snprintf(xpath_entry, sizeof(xpath_entry), "%s/route-map", xpath); + nb_cli_enqueue_change(vty, xpath_entry, + route_map ? NB_OP_MODIFY : NB_OP_DESTROY, + route_map ? route_map : NULL); + snprintf(xpath_entry, sizeof(xpath_entry), "%s/metric", xpath); + nb_cli_enqueue_change(vty, xpath_entry, NB_OP_MODIFY, + metric_str ? metric_str : NULL); + return nb_cli_apply_changes(vty, + "./redistribute/%s[protocol='table'][level='%s']", + ip, level); +} + +static void vty_print_redistribute(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults, const char *family, + bool table) +{ + const char *level; + const char *protocol = NULL; + const char *routemap = NULL; + uint16_t tableid; + + if (table) { + level = yang_dnode_get_string(dnode, "../level"); + tableid = yang_dnode_get_uint16(dnode, "./table"); + vty_out(vty, " redistribute %s table %d ", family, tableid); + } else { + protocol = yang_dnode_get_string(dnode, "./protocol"); + if (!table && strmatch(protocol, "table")) + return; + level = yang_dnode_get_string(dnode, "./level"); + vty_out(vty, " redistribute %s %s ", family, protocol); + } + vty_out(vty, "%s", level); + if (show_defaults || !yang_dnode_is_default(dnode, "./metric")) + vty_out(vty, " metric %s", + yang_dnode_get_string(dnode, "%s", "./metric")); + + if (yang_dnode_exists(dnode, "./route-map")) + routemap = yang_dnode_get_string(dnode, "./route-map"); + if (routemap) + vty_out(vty, " route-map %s", routemap); + vty_out(vty, "\n"); +} + +void cli_show_isis_redistribute_ipv4(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + vty_print_redistribute(vty, dnode, show_defaults, "ipv4", false); +} + +void cli_show_isis_redistribute_ipv6(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + vty_print_redistribute(vty, dnode, show_defaults, "ipv6", false); +} + +void cli_show_isis_redistribute_ipv4_table(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + vty_print_redistribute(vty, dnode, show_defaults, "ipv4", true); +} + +void cli_show_isis_redistribute_ipv6_table(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + vty_print_redistribute(vty, dnode, show_defaults, "ipv6", true); +} + +int cli_cmp_isis_redistribute_table(const struct lyd_node *dnode1, + const struct lyd_node *dnode2) +{ + uint16_t table1 = yang_dnode_get_uint16(dnode1, "./table"); + uint16_t table2 = yang_dnode_get_uint16(dnode2, "./table"); + + return table1 - table2; +} + +/* + * XPath: /frr-isisd:isis/instance/multi-topology + */ +DEFPY_YANG( + isis_topology, isis_topology_cmd, + "[no] topology <standard|ipv4-unicast|ipv4-mgmt|ipv6-unicast|ipv4-multicast|ipv6-multicast|ipv6-mgmt|ipv6-dstsrc>$topology [overload]$overload", + NO_STR + "Configure IS-IS topologies\n" + "standard topology\n" + "IPv4 unicast topology\n" + "IPv4 management topology\n" + "IPv6 unicast topology\n" + "IPv4 multicast topology\n" + "IPv6 multicast topology\n" + "IPv6 management topology\n" + "IPv6 dst-src topology\n" + "Set overload bit for topology\n") +{ + char base_xpath[XPATH_MAXLEN]; + + /* Since standard is not configurable it is not present in the + * YANG model, so we need to validate it here + */ + if (strmatch(topology, "standard") || + strmatch(topology, "ipv4-unicast")) { + vty_out(vty, + "Cannot configure IPv4 unicast (Standard) topology\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (strmatch(topology, "ipv4-mgmt")) + snprintf(base_xpath, XPATH_MAXLEN, + "./multi-topology/ipv4-management"); + else if (strmatch(topology, "ipv6-mgmt")) + snprintf(base_xpath, XPATH_MAXLEN, + "./multi-topology/ipv6-management"); + else + snprintf(base_xpath, XPATH_MAXLEN, "./multi-topology/%s", + topology); + + if (no) + nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); + else { + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, "./overload", NB_OP_MODIFY, + overload ? "true" : "false"); + } + + return nb_cli_apply_changes(vty, "%s", base_xpath); +} + +void cli_show_isis_mt_ipv4_multicast(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " topology ipv4-multicast"); + if (yang_dnode_get_bool(dnode, "./overload")) + vty_out(vty, " overload"); + vty_out(vty, "\n"); +} + +void cli_show_isis_mt_ipv4_mgmt(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " topology ipv4-mgmt"); + if (yang_dnode_get_bool(dnode, "./overload")) + vty_out(vty, " overload"); + vty_out(vty, "\n"); +} + +void cli_show_isis_mt_ipv6_unicast(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " topology ipv6-unicast"); + if (yang_dnode_get_bool(dnode, "./overload")) + vty_out(vty, " overload"); + vty_out(vty, "\n"); +} + +void cli_show_isis_mt_ipv6_multicast(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " topology ipv6-multicast"); + if (yang_dnode_get_bool(dnode, "./overload")) + vty_out(vty, " overload"); + vty_out(vty, "\n"); +} + +void cli_show_isis_mt_ipv6_mgmt(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " topology ipv6-mgmt"); + if (yang_dnode_get_bool(dnode, "./overload")) + vty_out(vty, " overload"); + vty_out(vty, "\n"); +} + +void cli_show_isis_mt_ipv6_dstsrc(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " topology ipv6-dstsrc"); + if (yang_dnode_get_bool(dnode, "./overload")) + vty_out(vty, " overload"); + vty_out(vty, "\n"); +} + +/* + * XPath: /frr-isisd:isis/instance/segment-routing/enabled + */ +DEFPY_YANG (isis_sr_enable, + isis_sr_enable_cmd, + "segment-routing on", + SR_STR + "Enable Segment Routing\n") +{ + nb_cli_enqueue_change(vty, "./segment-routing/enabled", NB_OP_MODIFY, + "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG (no_isis_sr_enable, + no_isis_sr_enable_cmd, + "no segment-routing [on]", + NO_STR + SR_STR + "Disable Segment Routing\n") +{ + nb_cli_enqueue_change(vty, "./segment-routing/enabled", NB_OP_MODIFY, + "false"); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_sr_enabled(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + + vty_out(vty, " segment-routing on\n"); +} + +/* + * XPath: /frr-isisd:isis/instance/segment-routing/label-block + */ + +DEFPY_YANG( + isis_sr_global_block_label_range, isis_sr_global_block_label_range_cmd, + "segment-routing global-block (16-1048575)$gb_lower_bound (16-1048575)$gb_upper_bound [local-block (16-1048575)$lb_lower_bound (16-1048575)$lb_upper_bound]", + SR_STR + "Segment Routing Global Block label range\n" + "The lower bound of the global block\n" + "The upper bound of the global block (block size may not exceed 65535)\n" + "Segment Routing Local Block label range\n" + "The lower bound of the local block\n" + "The upper bound of the local block (block size may not exceed 65535)\n") +{ + nb_cli_enqueue_change(vty, + "./segment-routing/label-blocks/srgb/lower-bound", + NB_OP_MODIFY, gb_lower_bound_str); + nb_cli_enqueue_change(vty, + "./segment-routing/label-blocks/srgb/upper-bound", + NB_OP_MODIFY, gb_upper_bound_str); + + nb_cli_enqueue_change( + vty, "./segment-routing/label-blocks/srlb/lower-bound", + NB_OP_MODIFY, lb_lower_bound ? lb_lower_bound_str : NULL); + nb_cli_enqueue_change( + vty, "./segment-routing/label-blocks/srlb/upper-bound", + NB_OP_MODIFY, lb_upper_bound ? lb_upper_bound_str : NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG(no_isis_sr_global_block_label_range, + no_isis_sr_global_block_label_range_cmd, + "no segment-routing global-block [(16-1048575) (16-1048575) local-block (16-1048575) (16-1048575)]", + NO_STR SR_STR + "Segment Routing Global Block label range\n" + "The lower bound of the global block\n" + "The upper bound of the global block (block size may not exceed 65535)\n" + "Segment Routing Local Block label range\n" + "The lower bound of the local block\n" + "The upper bound of the local block (block size may not exceed 65535)\n") +{ + nb_cli_enqueue_change(vty, + "./segment-routing/label-blocks/srgb/lower-bound", + NB_OP_MODIFY, NULL); + nb_cli_enqueue_change(vty, + "./segment-routing/label-blocks/srgb/upper-bound", + NB_OP_MODIFY, NULL); + nb_cli_enqueue_change(vty, + "./segment-routing/label-blocks/srlb/lower-bound", + NB_OP_MODIFY, NULL); + nb_cli_enqueue_change(vty, + "./segment-routing/label-blocks/srlb/upper-bound", + NB_OP_MODIFY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_label_blocks(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " segment-routing global-block %s %s", + yang_dnode_get_string(dnode, "./srgb/lower-bound"), + yang_dnode_get_string(dnode, "./srgb/upper-bound")); + if (!yang_dnode_is_default(dnode, "./srlb/lower-bound") + || !yang_dnode_is_default(dnode, "./srlb/upper-bound")) + vty_out(vty, " local-block %s %s", + yang_dnode_get_string(dnode, "./srlb/lower-bound"), + yang_dnode_get_string(dnode, "./srlb/upper-bound")); + vty_out(vty, "\n"); +} + +/* + * XPath: /frr-isisd:isis/instance/segment-routing/msd/node-msd + */ +DEFPY_YANG (isis_sr_node_msd, + isis_sr_node_msd_cmd, + "segment-routing node-msd (1-16)$msd", + SR_STR + "Maximum Stack Depth for this router\n" + "Maximum number of label that can be stack (1-16)\n") +{ + nb_cli_enqueue_change(vty, "./segment-routing/msd/node-msd", + NB_OP_MODIFY, msd_str); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG (no_isis_sr_node_msd, + no_isis_sr_node_msd_cmd, + "no segment-routing node-msd [(1-16)]", + NO_STR + SR_STR + "Maximum Stack Depth for this router\n" + "Maximum number of label that can be stack (1-16)\n") +{ + nb_cli_enqueue_change(vty, "./segment-routing/msd/node-msd", + NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_node_msd(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " segment-routing node-msd %s\n", + yang_dnode_get_string(dnode, NULL)); +} + +/* + * XPath: /frr-isisd:isis/instance/segment-routing/prefix-sid-map/prefix-sid + */ +DEFPY_YANG (isis_sr_prefix_sid, + isis_sr_prefix_sid_cmd, + "segment-routing prefix\ + <A.B.C.D/M|X:X::X:X/M>$prefix\ + <absolute$sid_type (16-1048575)$sid_value|index$sid_type (0-65535)$sid_value>\ + [<no-php-flag|explicit-null>$lh_behavior] [n-flag-clear$n_flag_clear]", + SR_STR + "Prefix SID\n" + "IPv4 Prefix\n" + "IPv6 Prefix\n" + "Specify the absolute value of Prefix Segment ID\n" + "The Prefix Segment ID value\n" + "Specify the index of Prefix Segment ID\n" + "The Prefix Segment ID index\n" + "Don't request Penultimate Hop Popping (PHP)\n" + "Upstream neighbor must replace prefix-sid with explicit null label\n" + "Not a node SID\n") +{ + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, "./sid-value-type", NB_OP_MODIFY, sid_type); + nb_cli_enqueue_change(vty, "./sid-value", NB_OP_MODIFY, sid_value_str); + if (lh_behavior) { + const char *value; + + if (strmatch(lh_behavior, "no-php-flag")) + value = "no-php"; + else if (strmatch(lh_behavior, "explicit-null")) + value = "explicit-null"; + else + value = "php"; + + nb_cli_enqueue_change(vty, "./last-hop-behavior", NB_OP_MODIFY, + value); + } else + nb_cli_enqueue_change(vty, "./last-hop-behavior", NB_OP_MODIFY, + NULL); + nb_cli_enqueue_change(vty, "./n-flag-clear", NB_OP_MODIFY, + n_flag_clear ? "true" : "false"); + + return nb_cli_apply_changes( + vty, "./segment-routing/prefix-sid-map/prefix-sid[prefix='%s']", + prefix_str); +} + +DEFPY_YANG (no_isis_sr_prefix_sid, + no_isis_sr_prefix_sid_cmd, + "no segment-routing prefix <A.B.C.D/M|X:X::X:X/M>$prefix\ + [<absolute$sid_type (16-1048575)|index (0-65535)> [<no-php-flag|explicit-null>]]\ + [n-flag-clear]", + NO_STR + SR_STR + "Prefix SID\n" + "IPv4 Prefix\n" + "IPv6 Prefix\n" + "Specify the absolute value of Prefix Segment ID\n" + "The Prefix Segment ID value\n" + "Specify the index of Prefix Segment ID\n" + "The Prefix Segment ID index\n" + "Don't request Penultimate Hop Popping (PHP)\n" + "Upstream neighbor must replace prefix-sid with explicit null label\n" + "Not a node SID\n") +{ + nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes( + vty, "./segment-routing/prefix-sid-map/prefix-sid[prefix='%s']", + prefix_str); +} + +void cli_show_isis_prefix_sid(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults) +{ + const char *prefix; + const char *lh_behavior; + const char *sid_value_type; + const char *sid_value; + bool n_flag_clear; + + prefix = yang_dnode_get_string(dnode, "./prefix"); + lh_behavior = yang_dnode_get_string(dnode, "./last-hop-behavior"); + sid_value_type = yang_dnode_get_string(dnode, "./sid-value-type"); + sid_value = yang_dnode_get_string(dnode, "./sid-value"); + n_flag_clear = yang_dnode_get_bool(dnode, "./n-flag-clear"); + + vty_out(vty, " segment-routing prefix %s", prefix); + if (strmatch(sid_value_type, "absolute")) + vty_out(vty, " absolute"); + else + vty_out(vty, " index"); + vty_out(vty, " %s", sid_value); + if (strmatch(lh_behavior, "no-php")) + vty_out(vty, " no-php-flag"); + else if (strmatch(lh_behavior, "explicit-null")) + vty_out(vty, " explicit-null"); + if (n_flag_clear) + vty_out(vty, " n-flag-clear"); + vty_out(vty, "\n"); +} + +#ifndef FABRICD +/* + * XPath: + * /frr-isisd:isis/instance/segment-routing/algorithm-prefix-sids/algorithm-prefix-sid + */ +DEFPY_YANG( + isis_sr_prefix_sid_algorithm, isis_sr_prefix_sid_algorithm_cmd, + "segment-routing prefix <A.B.C.D/M|X:X::X:X/M>$prefix\ + algorithm (128-255)$algorithm\ + <absolute$sid_type (16-1048575)$sid_value|index$sid_type (0-65535)$sid_value>\ + [<no-php-flag|explicit-null>$lh_behavior] [n-flag-clear$n_flag_clear]", + SR_STR + "Prefix SID\n" + "IPv4 Prefix\n" + "IPv6 Prefix\n" + "Algorithm Specific Prefix SID Configuration\n" + "Algorithm number\n" + "Specify the absolute value of Prefix Segment ID\n" + "The Prefix Segment ID value\n" + "Specify the index of Prefix Segment ID\n" + "The Prefix Segment ID index\n" + "Don't request Penultimate Hop Popping (PHP)\n" + "Upstream neighbor must replace prefix-sid with explicit null label\n" + "Not a node SID\n") +{ + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, "./sid-value-type", NB_OP_MODIFY, sid_type); + nb_cli_enqueue_change(vty, "./sid-value", NB_OP_MODIFY, sid_value_str); + if (lh_behavior) { + const char *value; + + if (strmatch(lh_behavior, "no-php-flag")) + value = "no-php"; + else if (strmatch(lh_behavior, "explicit-null")) + value = "explicit-null"; + else + value = "php"; + + nb_cli_enqueue_change(vty, "./last-hop-behavior", NB_OP_MODIFY, + value); + } else + nb_cli_enqueue_change(vty, "./last-hop-behavior", NB_OP_MODIFY, + NULL); + nb_cli_enqueue_change(vty, "./n-flag-clear", NB_OP_MODIFY, + n_flag_clear ? "true" : "false"); + + return nb_cli_apply_changes( + vty, + "./segment-routing/algorithm-prefix-sids/algorithm-prefix-sid[prefix='%s'][algo='%s']", + prefix_str, algorithm_str); +} + +DEFPY_YANG( + no_isis_sr_prefix_algorithm_sid, no_isis_sr_prefix_sid_algorithm_cmd, + "no segment-routing prefix <A.B.C.D/M|X:X::X:X/M>$prefix\ + algorithm (128-255)$algorithm\ + [<absolute$sid_type (16-1048575)|index (0-65535)> [<no-php-flag|explicit-null>]]\ + [n-flag-clear]", + NO_STR SR_STR + "Prefix SID\n" + "IPv4 Prefix\n" + "IPv6 Prefix\n" + "Algorithm Specific Prefix SID Configuration\n" + "Algorithm number\n" + "Specify the absolute value of Prefix Segment ID\n" + "The Prefix Segment ID value\n" + "Specify the index of Prefix Segment ID\n" + "The Prefix Segment ID index\n" + "Don't request Penultimate Hop Popping (PHP)\n" + "Upstream neighbor must replace prefix-sid with explicit null label\n" + "Not a node SID\n") +{ + nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes( + vty, + "./segment-routing/algorithm-prefix-sids/algorithm-prefix-sid[prefix='%s'][algo='%s']", + prefix_str, algorithm_str); + return CMD_SUCCESS; +} +#endif /* ifndef FABRICD */ + +void cli_show_isis_prefix_sid_algorithm(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + const char *prefix; + const char *lh_behavior; + const char *sid_value_type; + const char *sid_value; + bool n_flag_clear; + uint32_t algorithm; + + prefix = yang_dnode_get_string(dnode, "./prefix"); + sid_value_type = yang_dnode_get_string(dnode, "./sid-value-type"); + sid_value = yang_dnode_get_string(dnode, "./sid-value"); + algorithm = yang_dnode_get_uint32(dnode, "./algo"); + lh_behavior = yang_dnode_get_string(dnode, "./last-hop-behavior"); + n_flag_clear = yang_dnode_get_bool(dnode, "./n-flag-clear"); + + vty_out(vty, " segment-routing prefix %s", prefix); + vty_out(vty, " algorithm %u", algorithm); + if (strmatch(sid_value_type, "absolute")) + vty_out(vty, " absolute"); + else + vty_out(vty, " index"); + vty_out(vty, " %s", sid_value); + + if (strmatch(lh_behavior, "no-php")) + vty_out(vty, " no-php-flag"); + else if (strmatch(lh_behavior, "explicit-null")) + vty_out(vty, " explicit-null"); + if (n_flag_clear) + vty_out(vty, " n-flag-clear"); + vty_out(vty, "\n"); +} + +/* + * XPath: /frr-isisd:isis/instance/segment-routing-srv6/locator + */ +DEFPY (isis_srv6_locator, + isis_srv6_locator_cmd, + "[no] locator NAME$loc_name", + NO_STR + "Specify SRv6 locator\n" + "Specify SRv6 locator\n") +{ + if (no) + nb_cli_enqueue_change(vty, "./locator", NB_OP_DESTROY, loc_name); + else + nb_cli_enqueue_change(vty, "./locator", NB_OP_MODIFY, loc_name); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_srv6_locator(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " locator %s\n", yang_dnode_get_string(dnode, NULL)); +} + +/* + * XPath: /frr-isisd:isis/instance/segment-routing-srv6/enabled + */ +DEFPY_YANG_NOSH (isis_srv6_enable, + isis_srv6_enable_cmd, + "segment-routing srv6", + SR_STR + "Enable Segment Routing over IPv6 (SRv6)\n") +{ + int ret; + char xpath[XPATH_MAXLEN + 37]; + + snprintf(xpath, sizeof(xpath), "%s/segment-routing-srv6", + VTY_CURR_XPATH); + + nb_cli_enqueue_change(vty, "./segment-routing-srv6/enabled", + NB_OP_MODIFY, "true"); + + ret = nb_cli_apply_changes(vty, NULL); + if (ret == CMD_SUCCESS) + VTY_PUSH_XPATH(ISIS_SRV6_NODE, xpath); + + return ret; +} + +DEFPY_YANG (no_isis_srv6_enable, + no_isis_srv6_enable_cmd, + "no segment-routing srv6", + NO_STR + SR_STR + "Disable Segment Routing over IPv6 (SRv6)\n") +{ + nb_cli_enqueue_change(vty, "./segment-routing-srv6", NB_OP_DESTROY, + NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_srv6_enabled(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + + vty_out(vty, " segment-routing srv6\n"); +} + +/* + * XPath: /frr-isisd:isis/instance/segment-routing-srv6/msd/node-msd + */ +DEFPY_YANG_NOSH (isis_srv6_node_msd, + isis_srv6_node_msd_cmd, + "[no] node-msd", + NO_STR + "Segment Routing over IPv6 (SRv6) Maximum SRv6 SID Depths\n") +{ + int ret = CMD_SUCCESS; + char xpath[XPATH_MAXLEN + 37]; + + snprintf(xpath, sizeof(xpath), "%s/msd/node-msd", VTY_CURR_XPATH); + + if (no) { + nb_cli_enqueue_change(vty, "./msd/node_msd/max-segs-left", + NB_OP_DESTROY, NULL); + nb_cli_enqueue_change(vty, "./msd/node_msd/end-pop", + NB_OP_DESTROY, NULL); + nb_cli_enqueue_change(vty, "./msd/node_msd/h-encaps", + NB_OP_DESTROY, NULL); + nb_cli_enqueue_change(vty, "./msd/node_msd/end-d", + NB_OP_DESTROY, NULL); + ret = nb_cli_apply_changes(vty, NULL); + } else + VTY_PUSH_XPATH(ISIS_SRV6_NODE_MSD_NODE, xpath); + + return ret; +} + +/* + * XPath: /frr-isisd:isis/instance/segment-routing-srv6/msd/node-msd/max-segs-left + */ +DEFPY (isis_srv6_node_msd_max_segs_left, + isis_srv6_node_msd_max_segs_left_cmd, + "[no] max-segs-left (0-255)$max_segs_left", + NO_STR + "Specify Maximum Segments Left MSD\n" + "Specify Maximum Segments Left MSD\n") +{ + if (no) + nb_cli_enqueue_change(vty, "./max-segs-left", NB_OP_DESTROY, + NULL); + else + nb_cli_enqueue_change(vty, "./max-segs-left", NB_OP_MODIFY, + max_segs_left_str); + + return nb_cli_apply_changes(vty, NULL); +} + +/* + * XPath: /frr-isisd:isis/instance/segment-routing-srv6/msd/node-msd/max-end-pop + */ +DEFPY (isis_srv6_node_msd_max_end_pop, + isis_srv6_node_msd_max_end_pop_cmd, + "[no] max-end-pop (0-255)$max_end_pop", + NO_STR + "Specify Maximum End Pop MSD\n" + "Specify Maximum End Pop MSD\n") +{ + if (no) + nb_cli_enqueue_change(vty, "./max-end-pop", NB_OP_DESTROY, NULL); + else + nb_cli_enqueue_change(vty, "./max-end-pop", NB_OP_MODIFY, + max_end_pop_str); + + return nb_cli_apply_changes(vty, NULL); +} + +/* + * XPath: /frr-isisd:isis/instance/segment-routing-srv6/msd/node-msd/max-h-encaps + */ +DEFPY (isis_srv6_node_msd_max_h_encaps, + isis_srv6_node_msd_max_h_encaps_cmd, + "[no] max-h-encaps (0-255)$max_h_encaps", + NO_STR + "Specify Maximum H.Encaps MSD\n" + "Specify Maximum H.Encaps MSD\n") +{ + if (no) + nb_cli_enqueue_change(vty, "./max-h-encaps", NB_OP_DESTROY, + NULL); + else + nb_cli_enqueue_change(vty, "./max-h-encaps", NB_OP_MODIFY, + max_h_encaps_str); + + return nb_cli_apply_changes(vty, NULL); +} + +/* + * XPath: /frr-isisd:isis/instance/segment-routing-srv6/msd/node-msd/max-end-d + */ +DEFPY (isis_srv6_node_msd_max_end_d, + isis_srv6_node_msd_max_end_d_cmd, + "[no] max-end-d (0-255)$max_end_d", + NO_STR + "Specify Maximum End D MSD\n" + "Specify Maximum End D MSD\n") +{ + if (no) + nb_cli_enqueue_change(vty, "./max-end-d", NB_OP_DESTROY, NULL); + else + nb_cli_enqueue_change(vty, "./max-end-d", NB_OP_MODIFY, + max_end_d_str); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_srv6_node_msd(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " node-msd\n"); + if (yang_dnode_get_uint8(dnode, "./max-segs-left") != + yang_get_default_uint8("%s/msd/node-msd/max-segs-left", ISIS_SRV6)) + vty_out(vty, " max-segs-left %u\n", + yang_dnode_get_uint8(dnode, "./max-segs-left")); + if (yang_dnode_get_uint8(dnode, "./max-end-pop") != + yang_get_default_uint8("%s/msd/node-msd/max-end-pop", ISIS_SRV6)) + vty_out(vty, " max-end-pop %u\n", + yang_dnode_get_uint8(dnode, "./max-end-pop")); + if (yang_dnode_get_uint8(dnode, "./max-h-encaps") != + yang_get_default_uint8("%s/msd/node-msd/max-h-encaps", ISIS_SRV6)) + vty_out(vty, " max-h-encaps %u\n", + yang_dnode_get_uint8(dnode, "./max-h-encaps")); + if (yang_dnode_get_uint8(dnode, "./max-end-d") != + yang_get_default_uint8("%s/msd/node-msd/max-end-d", ISIS_SRV6)) + vty_out(vty, " max-end-d %u\n", + yang_dnode_get_uint8(dnode, "./max-end-d")); +} + +/* + * XPath: /frr-isisd:isis/instance/segment-routing-srv6/interface + */ +DEFPY (isis_srv6_interface, + isis_srv6_interface_cmd, + "[no] interface WORD$interface", + NO_STR + "Interface for Segment Routing over IPv6 (SRv6)\n" + "Interface for Segment Routing over IPv6 (SRv6)\n") +{ + if (no) { + nb_cli_enqueue_change(vty, "./interface", + NB_OP_MODIFY, NULL); + } else { + nb_cli_enqueue_change(vty, "./interface", + NB_OP_MODIFY, interface); + } + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_srv6_interface(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " interface %s\n", yang_dnode_get_string(dnode, NULL)); +} + +/* + * XPath: /frr-isisd:isis/instance/fast-reroute/level-{1,2}/lfa/priority-limit + */ +DEFPY_YANG (isis_frr_lfa_priority_limit, + isis_frr_lfa_priority_limit_cmd, + "[no] fast-reroute priority-limit <critical|high|medium>$priority [<level-1|level-2>$level]", + NO_STR + "Configure Fast ReRoute\n" + "Limit backup computation up to the prefix priority\n" + "Compute for critical priority prefixes only\n" + "Compute for critical & high priority prefixes\n" + "Compute for critical, high & medium priority prefixes\n" + "Set priority-limit for level-1 only\n" + "Set priority-limit for level-2 only\n") +{ + if (!level || strmatch(level, "level-1")) { + if (no) { + nb_cli_enqueue_change( + vty, + "./fast-reroute/level-1/lfa/priority-limit", + NB_OP_DESTROY, NULL); + } else { + nb_cli_enqueue_change( + vty, + "./fast-reroute/level-1/lfa/priority-limit", + NB_OP_CREATE, priority); + } + } + if (!level || strmatch(level, "level-2")) { + if (no) { + nb_cli_enqueue_change( + vty, + "./fast-reroute/level-2/lfa/priority-limit", + NB_OP_DESTROY, NULL); + } else { + nb_cli_enqueue_change( + vty, + "./fast-reroute/level-2/lfa/priority-limit", + NB_OP_CREATE, priority); + } + } + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_frr_lfa_priority_limit(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " fast-reroute priority-limit %s %s\n", + yang_dnode_get_string(dnode, NULL), + dnode->parent->parent->schema->name); +} + +/* + * XPath: /frr-isisd:isis/instance/fast-reroute/level-{1,2}/lfa/tiebreaker + */ +DEFPY_YANG (isis_frr_lfa_tiebreaker, + isis_frr_lfa_tiebreaker_cmd, + "[no] fast-reroute lfa\ + tiebreaker <downstream|lowest-backup-metric|node-protecting>$type\ + index (1-255)$index\ + [<level-1|level-2>$level]", + NO_STR + "Configure Fast ReRoute\n" + "LFA configuration\n" + "Configure tiebreaker for multiple backups\n" + "Prefer backup path via downstream node\n" + "Prefer backup path with lowest total metric\n" + "Prefer node protecting backup path\n" + "Set preference order among tiebreakers\n" + "Index\n" + "Configure tiebreaker for level-1 only\n" + "Configure tiebreaker for level-2 only\n") +{ + char xpath[XPATH_MAXLEN]; + + if (!level || strmatch(level, "level-1")) { + if (no) { + snprintf( + xpath, XPATH_MAXLEN, + "./fast-reroute/level-1/lfa/tiebreaker[index='%s']", + index_str); + nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); + } else { + snprintf( + xpath, XPATH_MAXLEN, + "./fast-reroute/level-1/lfa/tiebreaker[index='%s']/type", + index_str); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, type); + } + } + if (!level || strmatch(level, "level-2")) { + if (no) { + snprintf( + xpath, XPATH_MAXLEN, + "./fast-reroute/level-2/lfa/tiebreaker[index='%s']", + index_str); + nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); + } else { + snprintf( + xpath, XPATH_MAXLEN, + "./fast-reroute/level-2/lfa/tiebreaker[index='%s']/type", + index_str); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, type); + } + } + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_frr_lfa_tiebreaker(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " fast-reroute lfa tiebreaker %s index %s %s\n", + yang_dnode_get_string(dnode, "./type"), + yang_dnode_get_string(dnode, "./index"), + dnode->parent->parent->schema->name); +} + +/* + * XPath: /frr-isisd:isis/instance/fast-reroute/level-{1,2}/lfa/load-sharing + */ +DEFPY_YANG (isis_frr_lfa_load_sharing, + isis_frr_lfa_load_sharing_cmd, + "[no] fast-reroute load-sharing disable [<level-1|level-2>$level]", + NO_STR + "Configure Fast ReRoute\n" + "Load share prefixes across multiple backups\n" + "Disable load sharing\n" + "Disable load sharing for level-1 only\n" + "Disable load sharing for level-2 only\n") +{ + if (!level || strmatch(level, "level-1")) { + if (no) { + nb_cli_enqueue_change( + vty, "./fast-reroute/level-1/lfa/load-sharing", + NB_OP_MODIFY, "true"); + } else { + nb_cli_enqueue_change( + vty, "./fast-reroute/level-1/lfa/load-sharing", + NB_OP_MODIFY, "false"); + } + } + if (!level || strmatch(level, "level-2")) { + if (no) { + nb_cli_enqueue_change( + vty, "./fast-reroute/level-2/lfa/load-sharing", + NB_OP_MODIFY, "true"); + } else { + nb_cli_enqueue_change( + vty, "./fast-reroute/level-2/lfa/load-sharing", + NB_OP_MODIFY, "false"); + } + } + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_frr_lfa_load_sharing(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + if (yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + + vty_out(vty, " fast-reroute load-sharing disable %s\n", + dnode->parent->parent->schema->name); +} + +/* + * XPath: /frr-isisd:isis/instance/fast-reroute/level-{1,2}/remote-lfa/prefix-list + */ +DEFPY_YANG (isis_frr_remote_lfa_plist, + isis_frr_remote_lfa_plist_cmd, + "fast-reroute remote-lfa prefix-list WORD$plist [<level-1|level-2>$level]", + "Configure Fast ReRoute\n" + "Enable remote LFA related configuration\n" + "Filter PQ node router ID based on prefix list\n" + "Prefix-list name\n" + "Enable router ID filtering for level-1 only\n" + "Enable router ID filtering for level-2 only\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change( + vty, "./fast-reroute/level-1/remote-lfa/prefix-list", + NB_OP_MODIFY, plist); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change( + vty, "./fast-reroute/level-2/remote-lfa/prefix-list", + NB_OP_MODIFY, plist); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG (no_isis_frr_remote_lfa_plist, + no_isis_frr_remote_lfa_plist_cmd, + "no fast-reroute remote-lfa prefix-list [WORD] [<level-1|level-2>$level]", + NO_STR + "Configure Fast ReRoute\n" + "Enable remote LFA related configuration\n" + "Filter PQ node router ID based on prefix list\n" + "Prefix-list name\n" + "Enable router ID filtering for level-1 only\n" + "Enable router ID filtering for level-2 only\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change( + vty, "./fast-reroute/level-1/remote-lfa/prefix-list", + NB_OP_DESTROY, NULL); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change( + vty, "./fast-reroute/level-2/remote-lfa/prefix-list", + NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_frr_remote_lfa_plist(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " fast-reroute remote-lfa prefix-list %s %s\n", + yang_dnode_get_string(dnode, NULL), + dnode->parent->parent->schema->name); +} + +/* + * XPath: /frr-interface:lib/interface/frr-isisd:isis/passive + */ +DEFPY_YANG(isis_passive, isis_passive_cmd, "[no] isis passive", + NO_STR + "IS-IS routing protocol\n" + "Configure the passive mode for interface\n") +{ + nb_cli_enqueue_change(vty, "./frr-isisd:isis/passive", NB_OP_MODIFY, + no ? "false" : "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_ip_isis_passive(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + vty_out(vty, " isis passive\n"); +} + +/* + * XPath: /frr-interface:lib/interface/frr-isisd:isis/password + */ + +DEFPY_YANG(isis_passwd, isis_passwd_cmd, "isis password <md5|clear>$type WORD$pwd", + "IS-IS routing protocol\n" + "Configure the authentication password for a circuit\n" + "HMAC-MD5 authentication\n" + "Cleartext password\n" + "Circuit password\n") +{ + nb_cli_enqueue_change(vty, "./frr-isisd:isis/password", NB_OP_CREATE, + NULL); + nb_cli_enqueue_change(vty, "./frr-isisd:isis/password/password", + NB_OP_MODIFY, pwd); + nb_cli_enqueue_change(vty, "./frr-isisd:isis/password/password-type", + NB_OP_MODIFY, type); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG(no_isis_passwd, no_isis_passwd_cmd, "no isis password [<md5|clear> WORD]", + NO_STR + "IS-IS routing protocol\n" + "Configure the authentication password for a circuit\n" + "HMAC-MD5 authentication\n" + "Cleartext password\n" + "Circuit password\n") +{ + nb_cli_enqueue_change(vty, "./frr-isisd:isis/password", NB_OP_DESTROY, + NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_ip_isis_password(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " isis password %s %s\n", + yang_dnode_get_string(dnode, "./password-type"), + yang_dnode_get_string(dnode, "./password")); +} + +/* + * XPath: /frr-interface:lib/interface/frr-isisd:isis/metric + */ +DEFPY_YANG(isis_metric, isis_metric_cmd, + "isis metric [level-1|level-2]$level (0-16777215)$met", + "IS-IS routing protocol\n" + "Set default metric for circuit\n" + "Specify metric for level-1 routing\n" + "Specify metric for level-2 routing\n" + "Default metric value\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change(vty, "./frr-isisd:isis/metric/level-1", + NB_OP_MODIFY, met_str); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change(vty, "./frr-isisd:isis/metric/level-2", + NB_OP_MODIFY, met_str); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG(no_isis_metric, no_isis_metric_cmd, + "no isis metric [level-1|level-2]$level [(0-16777215)]", + NO_STR + "IS-IS routing protocol\n" + "Set default metric for circuit\n" + "Specify metric for level-1 routing\n" + "Specify metric for level-2 routing\n" + "Default metric value\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change(vty, "./frr-isisd:isis/metric/level-1", + NB_OP_MODIFY, NULL); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change(vty, "./frr-isisd:isis/metric/level-2", + NB_OP_MODIFY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_ip_isis_metric(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults) +{ + const char *l1 = yang_dnode_get_string(dnode, "./level-1"); + const char *l2 = yang_dnode_get_string(dnode, "./level-2"); + + if (strmatch(l1, l2)) + vty_out(vty, " isis metric %s\n", l1); + else { + vty_out(vty, " isis metric level-1 %s\n", l1); + vty_out(vty, " isis metric level-2 %s\n", l2); + } +} + +/* + * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/interval + */ +DEFPY_YANG(isis_hello_interval, isis_hello_interval_cmd, + "isis hello-interval [level-1|level-2]$level (1-600)$intv", + "IS-IS routing protocol\n" + "Set Hello interval\n" + "Specify hello-interval for level-1 IIHs\n" + "Specify hello-interval for level-2 IIHs\n" + "Holdtime 1 seconds, interval depends on multiplier\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change(vty, + "./frr-isisd:isis/hello/interval/level-1", + NB_OP_MODIFY, intv_str); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change(vty, + "./frr-isisd:isis/hello/interval/level-2", + NB_OP_MODIFY, intv_str); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG(no_isis_hello_interval, no_isis_hello_interval_cmd, + "no isis hello-interval [level-1|level-2]$level [(1-600)]", + NO_STR + "IS-IS routing protocol\n" + "Set Hello interval\n" + "Specify hello-interval for level-1 IIHs\n" + "Specify hello-interval for level-2 IIHs\n" + "Holdtime 1 second, interval depends on multiplier\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change(vty, + "./frr-isisd:isis/hello/interval/level-1", + NB_OP_MODIFY, NULL); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change(vty, + "./frr-isisd:isis/hello/interval/level-2", + NB_OP_MODIFY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_ip_isis_hello_interval(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + const char *l1 = yang_dnode_get_string(dnode, "./level-1"); + const char *l2 = yang_dnode_get_string(dnode, "./level-2"); + + if (strmatch(l1, l2)) + vty_out(vty, " isis hello-interval %s\n", l1); + else { + vty_out(vty, " isis hello-interval level-1 %s\n", l1); + vty_out(vty, " isis hello-interval level-2 %s\n", l2); + } +} + +/* + * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/multiplier + */ +DEFPY_YANG(isis_hello_multiplier, isis_hello_multiplier_cmd, + "isis hello-multiplier [level-1|level-2]$level (2-100)$mult", + "IS-IS routing protocol\n" + "Set multiplier for Hello holding time\n" + "Specify hello multiplier for level-1 IIHs\n" + "Specify hello multiplier for level-2 IIHs\n" + "Hello multiplier value\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change( + vty, "./frr-isisd:isis/hello/multiplier/level-1", + NB_OP_MODIFY, mult_str); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change( + vty, "./frr-isisd:isis/hello/multiplier/level-2", + NB_OP_MODIFY, mult_str); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG(no_isis_hello_multiplier, no_isis_hello_multiplier_cmd, + "no isis hello-multiplier [level-1|level-2]$level [(2-100)]", + NO_STR + "IS-IS routing protocol\n" + "Set multiplier for Hello holding time\n" + "Specify hello multiplier for level-1 IIHs\n" + "Specify hello multiplier for level-2 IIHs\n" + "Hello multiplier value\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change( + vty, "./frr-isisd:isis/hello/multiplier/level-1", + NB_OP_MODIFY, NULL); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change( + vty, "./frr-isisd:isis/hello/multiplier/level-2", + NB_OP_MODIFY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_ip_isis_hello_multi(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults) +{ + const char *l1 = yang_dnode_get_string(dnode, "./level-1"); + const char *l2 = yang_dnode_get_string(dnode, "./level-2"); + + if (strmatch(l1, l2)) + vty_out(vty, " isis hello-multiplier %s\n", l1); + else { + vty_out(vty, " isis hello-multiplier level-1 %s\n", l1); + vty_out(vty, " isis hello-multiplier level-2 %s\n", l2); + } +} + +/* + * XPath: + * /frr-interface:lib/interface/frr-isisd:isis/disable-three-way-handshake + */ +DEFPY_YANG(isis_threeway_adj, isis_threeway_adj_cmd, "[no] isis three-way-handshake", + NO_STR + "IS-IS commands\n" + "Enable/Disable three-way handshake\n") +{ + nb_cli_enqueue_change(vty, + "./frr-isisd:isis/disable-three-way-handshake", + NB_OP_MODIFY, no ? "true" : "false"); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_ip_isis_threeway_shake(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + if (yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + vty_out(vty, " isis three-way-handshake\n"); +} + +/* + * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/padding + */ +DEFPY_YANG(isis_hello_padding, isis_hello_padding_cmd, + "[no] isis hello padding [during-adjacency-formation]$padding_type", + NO_STR + "IS-IS routing protocol\n" + "Type of padding for IS-IS hello packets\n" + "Pad hello packets\n" + "Add padding to hello packets during adjacency formation only.\n") +{ + if (no) { + nb_cli_enqueue_change(vty, "./frr-isisd:isis/hello/padding", + NB_OP_MODIFY, "disabled"); + } else { + nb_cli_enqueue_change(vty, "./frr-isisd:isis/hello/padding", + NB_OP_MODIFY, + padding_type ? padding_type : "always"); + } + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_ip_isis_hello_padding(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + int hello_padding_type = yang_dnode_get_enum(dnode, NULL); + if (hello_padding_type == ISIS_HELLO_PADDING_DISABLED) + vty_out(vty, " no"); + vty_out(vty, " isis hello padding"); + if (hello_padding_type == ISIS_HELLO_PADDING_DURING_ADJACENCY_FORMATION) + vty_out(vty, " during-adjacency-formation"); + vty_out(vty, "\n"); +} + +/* + * XPath: /frr-interface:lib/interface/frr-isisd:isis/csnp-interval + */ +DEFPY_YANG(csnp_interval, csnp_interval_cmd, + "isis csnp-interval (1-600)$intv [level-1|level-2]$level", + "IS-IS routing protocol\n" + "Set CSNP interval in seconds\n" + "CSNP interval value\n" + "Specify interval for level-1 CSNPs\n" + "Specify interval for level-2 CSNPs\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change(vty, + "./frr-isisd:isis/csnp-interval/level-1", + NB_OP_MODIFY, intv_str); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change(vty, + "./frr-isisd:isis/csnp-interval/level-2", + NB_OP_MODIFY, intv_str); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG(no_csnp_interval, no_csnp_interval_cmd, + "no isis csnp-interval [(1-600)] [level-1|level-2]$level", + NO_STR + "IS-IS routing protocol\n" + "Set CSNP interval in seconds\n" + "CSNP interval value\n" + "Specify interval for level-1 CSNPs\n" + "Specify interval for level-2 CSNPs\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change(vty, + "./frr-isisd:isis/csnp-interval/level-1", + NB_OP_MODIFY, NULL); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change(vty, + "./frr-isisd:isis/csnp-interval/level-2", + NB_OP_MODIFY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_ip_isis_csnp_interval(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + const char *l1 = yang_dnode_get_string(dnode, "./level-1"); + const char *l2 = yang_dnode_get_string(dnode, "./level-2"); + + if (strmatch(l1, l2)) + vty_out(vty, " isis csnp-interval %s\n", l1); + else { + vty_out(vty, " isis csnp-interval %s level-1\n", l1); + vty_out(vty, " isis csnp-interval %s level-2\n", l2); + } +} + +/* + * XPath: /frr-interface:lib/interface/frr-isisd:isis/psnp-interval + */ +DEFPY_YANG(psnp_interval, psnp_interval_cmd, + "isis psnp-interval (1-120)$intv [level-1|level-2]$level", + "IS-IS routing protocol\n" + "Set PSNP interval in seconds\n" + "PSNP interval value\n" + "Specify interval for level-1 PSNPs\n" + "Specify interval for level-2 PSNPs\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change(vty, + "./frr-isisd:isis/psnp-interval/level-1", + NB_OP_MODIFY, intv_str); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change(vty, + "./frr-isisd:isis/psnp-interval/level-2", + NB_OP_MODIFY, intv_str); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG(no_psnp_interval, no_psnp_interval_cmd, + "no isis psnp-interval [(1-120)] [level-1|level-2]$level", + NO_STR + "IS-IS routing protocol\n" + "Set PSNP interval in seconds\n" + "PSNP interval value\n" + "Specify interval for level-1 PSNPs\n" + "Specify interval for level-2 PSNPs\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change(vty, + "./frr-isisd:isis/psnp-interval/level-1", + NB_OP_MODIFY, NULL); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change(vty, + "./frr-isisd:isis/psnp-interval/level-2", + NB_OP_MODIFY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_ip_isis_psnp_interval(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + const char *l1 = yang_dnode_get_string(dnode, "./level-1"); + const char *l2 = yang_dnode_get_string(dnode, "./level-2"); + + if (strmatch(l1, l2)) + vty_out(vty, " isis psnp-interval %s\n", l1); + else { + vty_out(vty, " isis psnp-interval %s level-1\n", l1); + vty_out(vty, " isis psnp-interval %s level-2\n", l2); + } +} + +/* + * XPath: /frr-interface:lib/interface/frr-isisd:isis/multi-topology + */ +DEFPY_YANG(circuit_topology, circuit_topology_cmd, + "[no] isis topology<standard|ipv4-unicast|ipv4-mgmt|ipv6-unicast|ipv4-multicast|ipv6-multicast|ipv6-mgmt|ipv6-dstsrc>$topology", + NO_STR + "IS-IS routing protocol\n" + "Configure interface IS-IS topologies\n" + "Standard topology\n" + "IPv4 unicast topology\n" + "IPv4 management topology\n" + "IPv6 unicast topology\n" + "IPv4 multicast topology\n" + "IPv6 multicast topology\n" + "IPv6 management topology\n" + "IPv6 dst-src topology\n") +{ + nb_cli_enqueue_change(vty, ".", NB_OP_MODIFY, no ? "false" : "true"); + + if (strmatch(topology, "ipv4-mgmt")) + return nb_cli_apply_changes( + vty, "./frr-isisd:isis/multi-topology/ipv4-management"); + else if (strmatch(topology, "ipv6-mgmt")) + return nb_cli_apply_changes( + vty, "./frr-isisd:isis/multi-topology/ipv6-management"); + if (strmatch(topology, "ipv4-unicast")) + return nb_cli_apply_changes( + vty, "./frr-isisd:isis/multi-topology/standard"); + else + return nb_cli_apply_changes( + vty, "./frr-isisd:isis/multi-topology/%s", topology); +} + +void cli_show_ip_isis_mt_standard(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + vty_out(vty, " isis topology standard\n"); +} + +void cli_show_ip_isis_mt_ipv4_multicast(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + vty_out(vty, " isis topology ipv4-multicast\n"); +} + +void cli_show_ip_isis_mt_ipv4_mgmt(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + vty_out(vty, " isis topology ipv4-mgmt\n"); +} + +void cli_show_ip_isis_mt_ipv6_unicast(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + vty_out(vty, " isis topology ipv6-unicast\n"); +} + +void cli_show_ip_isis_mt_ipv6_multicast(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + vty_out(vty, " isis topology ipv6-multicast\n"); +} + +void cli_show_ip_isis_mt_ipv6_mgmt(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + vty_out(vty, " isis topology ipv6-mgmt\n"); +} + +void cli_show_ip_isis_mt_ipv6_dstsrc(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + vty_out(vty, " isis topology ipv6-dstsrc\n"); +} + +/* + * XPath: /frr-interface:lib/interface/frr-isisd:isis/circuit-type + */ +DEFPY_YANG(isis_circuit_type, isis_circuit_type_cmd, + "isis circuit-type <level-1|level-1-2|level-2-only>$type", + "IS-IS routing protocol\n" + "Configure circuit type for interface\n" + "Level-1 only adjacencies are formed\n" + "Level-1-2 adjacencies are formed\n" + "Level-2 only adjacencies are formed\n") +{ + nb_cli_enqueue_change( + vty, "./frr-isisd:isis/circuit-type", NB_OP_MODIFY, + strmatch(type, "level-2-only") ? "level-2" : type); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG(no_isis_circuit_type, no_isis_circuit_type_cmd, + "no isis circuit-type [level-1|level-1-2|level-2-only]", + NO_STR + "IS-IS routing protocol\n" + "Configure circuit type for interface\n" + "Level-1 only adjacencies are formed\n" + "Level-1-2 adjacencies are formed\n" + "Level-2 only adjacencies are formed\n") +{ + nb_cli_enqueue_change(vty, "./frr-isisd:isis/circuit-type", + NB_OP_MODIFY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_ip_isis_circ_type(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults) +{ + int level = yang_dnode_get_enum(dnode, NULL); + + switch (level) { + case IS_LEVEL_1: + vty_out(vty, " isis circuit-type level-1\n"); + break; + case IS_LEVEL_2: + vty_out(vty, " isis circuit-type level-2-only\n"); + break; + case IS_LEVEL_1_AND_2: + vty_out(vty, " isis circuit-type level-1-2\n"); + break; + } +} + +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 + */ +DEFPY_YANG(isis_network, isis_network_cmd, "[no] isis network point-to-point", + NO_STR + "IS-IS routing protocol\n" + "Set network type\n" + "point-to-point network type\n") +{ + nb_cli_enqueue_change(vty, "./frr-isisd:isis/network-type", + NB_OP_MODIFY, + no ? "broadcast" : "point-to-point"); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_ip_isis_network_type(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + if (yang_dnode_get_enum(dnode, NULL) != CIRCUIT_T_P2P) + vty_out(vty, " no"); + + vty_out(vty, " isis network point-to-point\n"); +} + +/* + * XPath: /frr-interface:lib/interface/frr-isisd:isis/priority + */ +DEFPY_YANG(isis_priority, isis_priority_cmd, + "isis priority (0-127)$prio [level-1|level-2]$level", + "IS-IS routing protocol\n" + "Set priority for Designated Router election\n" + "Priority value\n" + "Specify priority for level-1 routing\n" + "Specify priority for level-2 routing\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change(vty, "./frr-isisd:isis/priority/level-1", + NB_OP_MODIFY, prio_str); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change(vty, "./frr-isisd:isis/priority/level-2", + NB_OP_MODIFY, prio_str); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG(no_isis_priority, no_isis_priority_cmd, + "no isis priority [(0-127)] [level-1|level-2]$level", + NO_STR + "IS-IS routing protocol\n" + "Set priority for Designated Router election\n" + "Priority value\n" + "Specify priority for level-1 routing\n" + "Specify priority for level-2 routing\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change(vty, "./frr-isisd:isis/priority/level-1", + NB_OP_MODIFY, NULL); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change(vty, "./frr-isisd:isis/priority/level-2", + NB_OP_MODIFY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_ip_isis_priority(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults) +{ + const char *l1 = yang_dnode_get_string(dnode, "./level-1"); + const char *l2 = yang_dnode_get_string(dnode, "./level-2"); + + if (strmatch(l1, l2)) + vty_out(vty, " isis priority %s\n", l1); + else { + vty_out(vty, " isis priority %s level-1\n", l1); + vty_out(vty, " isis priority %s level-2\n", l2); + } +} + +/* + * XPath: /frr-interface:lib/interface/frr-isisd:isis/fast-reroute + */ +void cli_show_ip_isis_frr(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults) +{ + bool l1_enabled, l2_enabled; + bool l1_node_protection, l2_node_protection; + bool l1_link_fallback, l2_link_fallback; + + /* Classic LFA */ + l1_enabled = yang_dnode_get_bool(dnode, "./level-1/lfa/enable"); + l2_enabled = yang_dnode_get_bool(dnode, "./level-2/lfa/enable"); + + if (l1_enabled || l2_enabled) { + if (l1_enabled == l2_enabled) { + vty_out(vty, " isis fast-reroute lfa\n"); + vty_out(vty, "\n"); + } else { + if (l1_enabled) + vty_out(vty, + " isis fast-reroute lfa level-1\n"); + if (l2_enabled) + vty_out(vty, + " isis fast-reroute lfa level-2\n"); + } + } + + /* Remote LFA */ + l1_enabled = yang_dnode_get_bool(dnode, "./level-1/remote-lfa/enable"); + l2_enabled = yang_dnode_get_bool(dnode, "./level-2/remote-lfa/enable"); + + if (l1_enabled || l2_enabled) { + if (l1_enabled == l2_enabled) { + vty_out(vty, + " isis fast-reroute remote-lfa tunnel mpls-ldp\n"); + vty_out(vty, "\n"); + } else { + if (l1_enabled) + vty_out(vty, + " isis fast-reroute remote-lfa tunnel mpls-ldp level-1\n"); + if (l2_enabled) + vty_out(vty, + " isis fast-reroute remote-lfa tunnel mpls-ldp level-2\n"); + } + } + + /* TI-LFA */ + l1_enabled = yang_dnode_get_bool(dnode, "./level-1/ti-lfa/enable"); + l2_enabled = yang_dnode_get_bool(dnode, "./level-2/ti-lfa/enable"); + l1_node_protection = + yang_dnode_get_bool(dnode, "./level-1/ti-lfa/node-protection"); + l2_node_protection = + yang_dnode_get_bool(dnode, "./level-2/ti-lfa/node-protection"); + l1_link_fallback = + yang_dnode_get_bool(dnode, "./level-1/ti-lfa/link-fallback"); + l2_link_fallback = + yang_dnode_get_bool(dnode, "./level-2/ti-lfa/link-fallback"); + + + if (l1_enabled || l2_enabled) { + if (l1_enabled == l2_enabled + && l1_node_protection == l2_node_protection + && l1_link_fallback == l2_link_fallback) { + vty_out(vty, " isis fast-reroute ti-lfa"); + if (l1_node_protection) + vty_out(vty, " node-protection"); + if (l1_link_fallback) + vty_out(vty, " link-fallback"); + vty_out(vty, "\n"); + } else { + if (l1_enabled) { + vty_out(vty, + " isis fast-reroute ti-lfa level-1"); + if (l1_node_protection) + vty_out(vty, " node-protection"); + if (l1_link_fallback) + vty_out(vty, " link-fallback"); + vty_out(vty, "\n"); + } + if (l2_enabled) { + vty_out(vty, + " isis fast-reroute ti-lfa level-2"); + if (l2_node_protection) + vty_out(vty, " node-protection"); + if (l2_link_fallback) + vty_out(vty, " link-fallback"); + vty_out(vty, "\n"); + } + } + } +} + +/* + * XPath: /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-{1,2}/lfa/enable + */ +DEFPY(isis_lfa, isis_lfa_cmd, + "[no] isis fast-reroute lfa [level-1|level-2]$level", + NO_STR + "IS-IS routing protocol\n" + "Interface IP Fast-reroute configuration\n" + "Enable LFA computation\n" + "Enable LFA computation for Level 1 only\n" + "Enable LFA computation for Level 2 only\n") +{ + if (!level || strmatch(level, "level-1")) { + if (no) { + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-1/lfa/enable", + NB_OP_MODIFY, "false"); + } else { + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-1/lfa/enable", + NB_OP_MODIFY, "true"); + } + } + if (!level || strmatch(level, "level-2")) { + if (no) { + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-2/lfa/enable", + NB_OP_MODIFY, "false"); + } else { + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-2/lfa/enable", + NB_OP_MODIFY, "true"); + } + } + + return nb_cli_apply_changes(vty, NULL); +} + +/* + * XPath: + * /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-{1,2}/lfa/exclude-interface + */ +DEFPY(isis_lfa_exclude_interface, isis_lfa_exclude_interface_cmd, + "[no] isis fast-reroute lfa [level-1|level-2]$level exclude interface IFNAME$ifname", + NO_STR + "IS-IS routing protocol\n" + "Interface IP Fast-reroute configuration\n" + "Enable LFA computation\n" + "Enable LFA computation for Level 1 only\n" + "Enable LFA computation for Level 2 only\n" + "FRR exclusion information\n" + "Exclude an interface from computation\n" + "Interface name\n") +{ + if (!level || strmatch(level, "level-1")) { + if (no) { + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-1/lfa/exclude-interface", + NB_OP_DESTROY, ifname); + } else { + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-1/lfa/exclude-interface", + NB_OP_CREATE, ifname); + } + } + if (!level || strmatch(level, "level-2")) { + if (no) { + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-2/lfa/exclude-interface", + NB_OP_DESTROY, ifname); + } else { + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-2/lfa/exclude-interface", + NB_OP_CREATE, ifname); + } + } + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_frr_lfa_exclude_interface(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " isis fast-reroute lfa %s exclude interface %s\n", + dnode->parent->parent->schema->name, + yang_dnode_get_string(dnode, NULL)); +} + +/* + * XPath: + * /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-{1,2}/remote-lfa/enable + */ +DEFPY(isis_remote_lfa, isis_remote_lfa_cmd, + "[no] isis fast-reroute remote-lfa tunnel mpls-ldp [level-1|level-2]$level", + NO_STR + "IS-IS routing protocol\n" + "Interface IP Fast-reroute configuration\n" + "Enable remote LFA computation\n" + "Enable remote LFA computation using tunnels\n" + "Use MPLS LDP tunnel to reach the remote LFA node\n" + "Enable LFA computation for Level 1 only\n" + "Enable LFA computation for Level 2 only\n") +{ + if (!level || strmatch(level, "level-1")) { + if (no) { + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-1/remote-lfa/enable", + NB_OP_MODIFY, "false"); + } else { + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-1/remote-lfa/enable", + NB_OP_MODIFY, "true"); + } + } + if (!level || strmatch(level, "level-2")) { + if (no) { + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-2/remote-lfa/enable", + NB_OP_MODIFY, "false"); + } else { + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-2/remote-lfa/enable", + NB_OP_MODIFY, "true"); + } + } + + return nb_cli_apply_changes(vty, NULL); +} + +/* + * XPath: + * /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-{1,2}/remote-lfa/maximum-metric + */ +DEFPY(isis_remote_lfa_max_metric, isis_remote_lfa_max_metric_cmd, + "[no] isis fast-reroute remote-lfa maximum-metric (1-16777215)$metric [level-1|level-2]$level", + NO_STR + "IS-IS routing protocol\n" + "Interface IP Fast-reroute configuration\n" + "Enable remote LFA computation\n" + "Limit remote LFA node selection within the metric\n" + "Value of the metric\n" + "Enable LFA computation for Level 1 only\n" + "Enable LFA computation for Level 2 only\n") +{ + if (!level || strmatch(level, "level-1")) { + if (no) { + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-1/remote-lfa/maximum-metric", + NB_OP_DESTROY, NULL); + } else { + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-1/remote-lfa/maximum-metric", + NB_OP_MODIFY, metric_str); + } + } + if (!level || strmatch(level, "level-2")) { + if (no) { + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-2/remote-lfa/maximum-metric", + NB_OP_DESTROY, NULL); + } else { + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-2/remote-lfa/maximum-metric", + NB_OP_MODIFY, metric_str); + } + } + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_frr_remote_lfa_max_metric(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " isis fast-reroute remote-lfa maximum-metric %s %s\n", + yang_dnode_get_string(dnode, NULL), + dnode->parent->parent->schema->name); +} + +/* + * XPath: /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-{1,2}/ti-lfa/enable + */ +DEFPY(isis_ti_lfa, isis_ti_lfa_cmd, + "[no] isis fast-reroute ti-lfa [level-1|level-2]$level [node-protection$node_protection [link-fallback$link_fallback]]", + NO_STR + "IS-IS routing protocol\n" + "Interface IP Fast-reroute configuration\n" + "Enable TI-LFA computation\n" + "Enable TI-LFA computation for Level 1 only\n" + "Enable TI-LFA computation for Level 2 only\n" + "Protect against node failures\n" + "Enable link-protection fallback\n") +{ + if (!level || strmatch(level, "level-1")) { + if (no) { + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-1/ti-lfa/enable", + NB_OP_MODIFY, "false"); + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-1/ti-lfa/node-protection", + NB_OP_MODIFY, "false"); + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-1/ti-lfa/link-fallback", + NB_OP_MODIFY, "false"); + } else { + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-1/ti-lfa/enable", + NB_OP_MODIFY, "true"); + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-1/ti-lfa/node-protection", + NB_OP_MODIFY, + node_protection ? "true" : "false"); + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-1/ti-lfa/link-fallback", + NB_OP_MODIFY, link_fallback ? "true" : "false"); + } + } + if (!level || strmatch(level, "level-2")) { + if (no) { + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-2/ti-lfa/enable", + NB_OP_MODIFY, "false"); + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-2/ti-lfa/node-protection", + NB_OP_MODIFY, "false"); + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-2/ti-lfa/link-fallback", + NB_OP_MODIFY, "false"); + } else { + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-2/ti-lfa/enable", + NB_OP_MODIFY, "true"); + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-2/ti-lfa/node-protection", + NB_OP_MODIFY, + node_protection ? "true" : "false"); + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-2/ti-lfa/link-fallback", + NB_OP_MODIFY, link_fallback ? "true" : "false"); + } + } + + return nb_cli_apply_changes(vty, NULL); +} + +/* + * XPath: /frr-isisd:isis/instance/log-adjacency-changes + */ +DEFPY_YANG(log_adj_changes, log_adj_changes_cmd, "[no] log-adjacency-changes", + NO_STR "Log changes in adjacency state\n") +{ + nb_cli_enqueue_change(vty, "./log-adjacency-changes", NB_OP_MODIFY, + no ? "false" : "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_log_adjacency(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + vty_out(vty, " log-adjacency-changes\n"); +} + +/* + * XPath: /frr-isisd:isis/instance/log-pdu-drops + */ +DEFPY_YANG(log_pdu_drops, log_pdu_drops_cmd, "[no] log-pdu-drops", + NO_STR "Log any dropped PDUs\n") +{ + nb_cli_enqueue_change(vty, "./log-pdu-drops", NB_OP_MODIFY, + no ? "false" : "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_log_pdu_drops(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + vty_out(vty, " log-pdu-drops\n"); +} + +/* + * XPath: /frr-isisd:isis/instance/mpls/ldp-sync + */ +DEFPY(isis_mpls_ldp_sync, isis_mpls_ldp_sync_cmd, "mpls ldp-sync", + MPLS_STR MPLS_LDP_SYNC_STR) +{ + nb_cli_enqueue_change(vty, "./mpls/ldp-sync", NB_OP_CREATE, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY(no_isis_mpls_ldp_sync, no_isis_mpls_ldp_sync_cmd, "no mpls ldp-sync", + NO_STR MPLS_STR NO_MPLS_LDP_SYNC_STR) +{ + nb_cli_enqueue_change(vty, "./mpls/ldp-sync", NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_mpls_ldp_sync(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " mpls ldp-sync\n"); +} + +DEFPY(isis_mpls_ldp_sync_holddown, isis_mpls_ldp_sync_holddown_cmd, + "mpls ldp-sync holddown (0-10000)", + MPLS_STR MPLS_LDP_SYNC_STR + "Time to wait for LDP-SYNC to occur before restoring interface metric\n" + "Time in seconds\n") +{ + nb_cli_enqueue_change(vty, "./mpls/ldp-sync/holddown", NB_OP_MODIFY, + holddown_str); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY(no_isis_mpls_ldp_sync_holddown, no_isis_mpls_ldp_sync_holddown_cmd, + "no mpls ldp-sync holddown [<(1-10000)>]", + NO_STR MPLS_STR MPLS_LDP_SYNC_STR NO_MPLS_LDP_SYNC_HOLDDOWN_STR "Time in seconds\n") +{ + nb_cli_enqueue_change(vty, "./mpls/ldp-sync/holddown", NB_OP_DESTROY, + NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_mpls_ldp_sync_holddown(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " mpls ldp-sync holddown %s\n", + yang_dnode_get_string(dnode, NULL)); +} + +/* + * XPath: /frr-interface:lib/interface/frr-isisd:isis/mpls/ldp-sync + */ +DEFPY(isis_mpls_if_ldp_sync, isis_mpls_if_ldp_sync_cmd, + "[no] isis mpls ldp-sync", + NO_STR "IS-IS routing protocol\n" MPLS_STR MPLS_LDP_SYNC_STR) +{ + const struct lyd_node *dnode; + + dnode = yang_dnode_getf(vty->candidate_config->dnode, + "%s/frr-isisd:isis", VTY_CURR_XPATH); + if (dnode == NULL) { + vty_out(vty, "ISIS is not enabled on this circuit\n"); + return CMD_SUCCESS; + } + + nb_cli_enqueue_change(vty, "./frr-isisd:isis/mpls/ldp-sync", + NB_OP_MODIFY, no ? "false" : "true"); + + return nb_cli_apply_changes(vty, NULL); +} + + +void cli_show_isis_mpls_if_ldp_sync(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + + vty_out(vty, " isis mpls ldp-sync\n"); +} + +DEFPY(isis_mpls_if_ldp_sync_holddown, isis_mpls_if_ldp_sync_holddown_cmd, + "isis mpls ldp-sync holddown (0-10000)", + "IS-IS routing protocol\n" MPLS_STR MPLS_LDP_SYNC_STR + "Time to wait for LDP-SYNC to occur before restoring interface metric\n" + "Time in seconds\n") +{ + const struct lyd_node *dnode; + + dnode = yang_dnode_getf(vty->candidate_config->dnode, + "%s/frr-isisd:isis", VTY_CURR_XPATH); + if (dnode == NULL) { + vty_out(vty, "ISIS is not enabled on this circuit\n"); + return CMD_SUCCESS; + } + + nb_cli_enqueue_change(vty, "./frr-isisd:isis/mpls/holddown", + NB_OP_MODIFY, holddown_str); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY(no_isis_mpls_if_ldp_sync_holddown, no_isis_mpls_if_ldp_sync_holddown_cmd, + "no isis mpls ldp-sync holddown [<(1-10000)>]", + NO_STR "IS-IS routing protocol\n" MPLS_STR NO_MPLS_LDP_SYNC_STR + NO_MPLS_LDP_SYNC_HOLDDOWN_STR "Time in seconds\n") +{ + const struct lyd_node *dnode; + + dnode = yang_dnode_getf(vty->candidate_config->dnode, + "%s/frr-isisd:isis", VTY_CURR_XPATH); + if (dnode == NULL) { + vty_out(vty, "ISIS is not enabled on this circuit\n"); + return CMD_SUCCESS; + } + + nb_cli_enqueue_change(vty, "./frr-isisd:isis/mpls/holddown", + NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_mpls_if_ldp_sync_holddown(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " isis mpls ldp-sync holddown %s\n", + yang_dnode_get_string(dnode, NULL)); +} + +DEFPY_YANG_NOSH(flex_algo, flex_algo_cmd, "flex-algo (128-255)$algorithm", + "Flexible Algorithm\n" + "Flexible Algorithm Number\n") +{ + 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", + NO_STR + "Flexible Algorithm\n" + "Flexible Algorithm Number\n") +{ + 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") +{ + 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, + "[no] affinity include-any NAME...", + NO_STR + "Affinity configuration\n" + "Any Include with\n" + "Include NAME list\n") +{ + 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, + "[no] affinity include-all NAME...", + NO_STR + "Affinity configuration\n" + "All Include with\n" + "Include NAME list\n") +{ + 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, + "[no] affinity exclude-any NAME...", + NO_STR + "Affinity configuration\n" + "Any Exclude with\n" + "Exclude NAME list\n") +{ + 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") +{ + 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, + "[no] metric-type [igp$igp|te$te|delay$delay]", + NO_STR + "Metric-type used by flex-algo calculation\n" + "Use IGP metric (default)\n" + "Use Delay as metric\n" + "Use Traffic Engineering metric\n") +{ + 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", + NO_STR + "Flex-Algo definition priority\n" + "Priority value\n") +{ + 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); + install_element(CONFIG_NODE, &no_router_isis_cmd); + + install_element(INTERFACE_NODE, &ip_router_isis_cmd); + install_element(INTERFACE_NODE, &ip_router_isis_vrf_cmd); + install_element(INTERFACE_NODE, &ip6_router_isis_cmd); + install_element(INTERFACE_NODE, &ip6_router_isis_vrf_cmd); + install_element(INTERFACE_NODE, &no_ip_router_isis_cmd); + install_element(INTERFACE_NODE, &no_ip_router_isis_vrf_cmd); + install_element(INTERFACE_NODE, &isis_bfd_cmd); + install_element(INTERFACE_NODE, &isis_bfd_profile_cmd); + + install_element(ISIS_NODE, &net_cmd); + + install_element(ISIS_NODE, &is_type_cmd); + install_element(ISIS_NODE, &no_is_type_cmd); + + install_element(ISIS_NODE, &dynamic_hostname_cmd); + + install_element(ISIS_NODE, &set_overload_bit_cmd); + install_element(ISIS_NODE, &set_overload_bit_on_startup_cmd); + install_element(ISIS_NODE, &no_set_overload_bit_on_startup_cmd); + + install_element(ISIS_NODE, &attached_bit_send_cmd); + install_element(ISIS_NODE, &attached_bit_receive_ignore_cmd); + + install_element(ISIS_NODE, &metric_style_cmd); + install_element(ISIS_NODE, &no_metric_style_cmd); + + install_element(ISIS_NODE, &advertise_high_metrics_cmd); + + install_element(ISIS_NODE, &area_passwd_cmd); + install_element(ISIS_NODE, &domain_passwd_cmd); + install_element(ISIS_NODE, &no_area_passwd_cmd); + + install_element(ISIS_NODE, &lsp_gen_interval_cmd); + install_element(ISIS_NODE, &no_lsp_gen_interval_cmd); + install_element(ISIS_NODE, &lsp_refresh_interval_cmd); + install_element(ISIS_NODE, &no_lsp_refresh_interval_cmd); + install_element(ISIS_NODE, &max_lsp_lifetime_cmd); + install_element(ISIS_NODE, &no_max_lsp_lifetime_cmd); + install_element(ISIS_NODE, &lsp_timers_cmd); + install_element(ISIS_NODE, &no_lsp_timers_cmd); + install_element(ISIS_NODE, &area_lsp_mtu_cmd); + install_element(ISIS_NODE, &no_area_lsp_mtu_cmd); + install_element(ISIS_NODE, &advertise_passive_only_cmd); + + install_element(ISIS_NODE, &spf_interval_cmd); + install_element(ISIS_NODE, &no_spf_interval_cmd); + install_element(ISIS_NODE, &spf_prefix_priority_cmd); + install_element(ISIS_NODE, &no_spf_prefix_priority_cmd); + install_element(ISIS_NODE, &spf_delay_ietf_cmd); + install_element(ISIS_NODE, &no_spf_delay_ietf_cmd); + + install_element(ISIS_NODE, &area_purge_originator_cmd); + + install_element(ISIS_NODE, &isis_admin_group_send_zero_cmd); + install_element(ISIS_NODE, &isis_asla_legacy_flag_cmd); + + install_element(ISIS_NODE, &isis_mpls_te_on_cmd); + install_element(ISIS_NODE, &no_isis_mpls_te_on_cmd); + install_element(ISIS_NODE, &isis_mpls_te_router_addr_cmd); + install_element(ISIS_NODE, &no_isis_mpls_te_router_addr_cmd); + install_element(ISIS_NODE, &isis_mpls_te_router_addr_v6_cmd); + install_element(ISIS_NODE, &no_isis_mpls_te_router_addr_v6_cmd); + install_element(ISIS_NODE, &isis_mpls_te_inter_as_cmd); + install_element(ISIS_NODE, &isis_mpls_te_export_cmd); + install_element(ISIS_NODE, &no_isis_mpls_te_export_cmd); + + install_element(ISIS_NODE, &isis_default_originate_cmd); + install_element(ISIS_NODE, &isis_redistribute_cmd); + install_element(ISIS_NODE, &isis_redistribute_table_cmd); + + install_element(ISIS_NODE, &isis_topology_cmd); + + install_element(ISIS_NODE, &isis_sr_enable_cmd); + install_element(ISIS_NODE, &no_isis_sr_enable_cmd); + install_element(ISIS_NODE, &isis_sr_global_block_label_range_cmd); + install_element(ISIS_NODE, &no_isis_sr_global_block_label_range_cmd); + install_element(ISIS_NODE, &isis_sr_node_msd_cmd); + install_element(ISIS_NODE, &no_isis_sr_node_msd_cmd); + install_element(ISIS_NODE, &isis_sr_prefix_sid_cmd); + install_element(ISIS_NODE, &no_isis_sr_prefix_sid_cmd); +#ifndef FABRICD + install_element(ISIS_NODE, &isis_sr_prefix_sid_algorithm_cmd); + install_element(ISIS_NODE, &no_isis_sr_prefix_sid_algorithm_cmd); +#endif /* ifndef FABRICD */ + install_element(ISIS_NODE, &isis_frr_lfa_priority_limit_cmd); + install_element(ISIS_NODE, &isis_frr_lfa_tiebreaker_cmd); + install_element(ISIS_NODE, &isis_frr_lfa_load_sharing_cmd); + install_element(ISIS_NODE, &isis_frr_remote_lfa_plist_cmd); + install_element(ISIS_NODE, &no_isis_frr_remote_lfa_plist_cmd); + + install_element(ISIS_NODE, &isis_srv6_enable_cmd); + install_element(ISIS_NODE, &no_isis_srv6_enable_cmd); + install_element(ISIS_SRV6_NODE, &isis_srv6_locator_cmd); + install_element(ISIS_SRV6_NODE, &isis_srv6_node_msd_cmd); + install_element(ISIS_SRV6_NODE, &isis_srv6_interface_cmd); + install_element(ISIS_SRV6_NODE_MSD_NODE, + &isis_srv6_node_msd_max_segs_left_cmd); + install_element(ISIS_SRV6_NODE_MSD_NODE, + &isis_srv6_node_msd_max_end_pop_cmd); + install_element(ISIS_SRV6_NODE_MSD_NODE, + &isis_srv6_node_msd_max_h_encaps_cmd); + install_element(ISIS_SRV6_NODE_MSD_NODE, + &isis_srv6_node_msd_max_end_d_cmd); + + install_element(INTERFACE_NODE, &isis_passive_cmd); + + 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, &isis_threeway_adj_cmd); + + install_element(INTERFACE_NODE, &isis_hello_padding_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, &isis_circuit_type_cmd); + install_element(INTERFACE_NODE, &no_isis_circuit_type_cmd); + + install_element(INTERFACE_NODE, &isis_network_cmd); + + install_element(INTERFACE_NODE, &isis_priority_cmd); + install_element(INTERFACE_NODE, &no_isis_priority_cmd); + + install_element(INTERFACE_NODE, &isis_lfa_cmd); + install_element(INTERFACE_NODE, &isis_lfa_exclude_interface_cmd); + install_element(INTERFACE_NODE, &isis_remote_lfa_cmd); + install_element(INTERFACE_NODE, &isis_remote_lfa_max_metric_cmd); + install_element(INTERFACE_NODE, &isis_ti_lfa_cmd); + + install_element(ISIS_NODE, &log_adj_changes_cmd); + install_element(ISIS_NODE, &log_pdu_drops_cmd); + + install_element(ISIS_NODE, &isis_mpls_ldp_sync_cmd); + install_element(ISIS_NODE, &no_isis_mpls_ldp_sync_cmd); + install_element(ISIS_NODE, &isis_mpls_ldp_sync_holddown_cmd); + install_element(ISIS_NODE, &no_isis_mpls_ldp_sync_holddown_cmd); + install_element(INTERFACE_NODE, &isis_mpls_if_ldp_sync_cmd); + install_element(INTERFACE_NODE, &isis_mpls_if_ldp_sync_holddown_cmd); + install_element(INTERFACE_NODE, &no_isis_mpls_if_ldp_sync_holddown_cmd); + + install_element(ISIS_NODE, &flex_algo_cmd); + install_element(ISIS_NODE, &no_flex_algo_cmd); + install_element(ISIS_FLEX_ALGO_NODE, &advertise_definition_cmd); + 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); +} + +#endif /* ifndef FABRICD */ |