diff options
60 files changed, 7323 insertions, 5071 deletions
diff --git a/doc/user/zebra.rst b/doc/user/zebra.rst index 8f4c9e1d45..9199404f3e 100644 --- a/doc/user/zebra.rst +++ b/doc/user/zebra.rst @@ -178,7 +178,7 @@ Standard Commands work on non-linux systems at all. 'enable' and 'disable' will respectively turn on and off mpls on the given interface. -.. clicmd:: multicast +.. clicmd:: multicast <enable|disable> Enable or disable multicast flag for the interface. @@ -214,20 +214,14 @@ Link Parameters Commands .. clicmd:: link-params + Enter into the link parameters sub node. This command activates the link + parameters and allows to configure routing information that could be used + as part of Traffic Engineering on this interface. MPLS-TE must be enabled at + the OSPF (:ref:`ospf-traffic-engineering`) or ISIS + (:ref:`isis-traffic-engineering`) router level in complement to this. To + disable link parameters, use the ``no`` version of this command. - Enter into the link parameters sub node. At least 'enable' must be - set to activate the link parameters, and consequently routing - information that could be used as part of Traffic Engineering on - this interface. MPLS-TE must be enable at the OSPF - (:ref:`ospf-traffic-engineering`) or ISIS - (:ref:`isis-traffic-engineering`) router level in complement to - this. - - Under link parameter statement, the following commands set the different TE values: - -.. clicmd:: enable - - Enable link parameters for this interface. +Under link parameter statement, the following commands set the different TE values: .. clicmd:: metric (0-4294967295) diff --git a/lib/affinitymap.h b/lib/affinitymap.h index f5924ca3ef..ebe2659bf7 100644 --- a/lib/affinitymap.h +++ b/lib/affinitymap.h @@ -58,6 +58,7 @@ struct affinity_maps { DECLARE_QOBJ_TYPE(affinity_maps); extern const struct frr_yang_module_info frr_affinity_map_info; +extern const struct frr_yang_module_info frr_affinity_map_cli_info; void affinity_map_set(const char *name, int pos); void affinity_map_unset(const char *name); @@ -69,9 +70,6 @@ void affinity_map_set_update_hook(void (*func)(const char *affmap_name, uint16_t old_pos, uint16_t new_pos)); -void cli_show_affinity_map(struct vty *vty, const struct lyd_node *dnode, - bool show_defaults); - void affinity_map_init(void); diff --git a/lib/affinitymap_cli.c b/lib/affinitymap_cli.c index d417ae1951..73b91e775b 100644 --- a/lib/affinitymap_cli.c +++ b/lib/affinitymap_cli.c @@ -30,15 +30,6 @@ #include "lib/affinitymap.h" #include "lib/affinitymap_cli_clippy.c" -/* Route map node structure. */ -static int affinity_map_config_write(struct vty *vty); -static struct cmd_node affinitymap_node = { - .name = "affinity-map", - .node = AFFMAP_NODE, - .prompt = "", - .config_write = affinity_map_config_write, -}; - /* max value is EXT_ADMIN_GROUP_MAX_POSITIONS - 1 */ DEFPY_YANG_NOSH(affinity_map, affinity_map_cmd, "affinity-map NAME$name bit-position (0-1023)$position", @@ -75,21 +66,7 @@ DEFPY_YANG_NOSH(no_affinity_map, no_affinity_map_cmd, return nb_cli_apply_changes(vty, NULL); } -static int affinity_map_config_write(struct vty *vty) -{ - const struct lyd_node *dnode; - int written = 0; - - dnode = yang_dnode_get(running_config->dnode, "/frr-affinity-map:lib"); - if (dnode) { - nb_cli_show_dnode_cmds(vty, dnode, false); - written = 1; - } - - return written; -} - -void cli_show_affinity_map(struct vty *vty, const struct lyd_node *dnode, +static void cli_show_affinity_map(struct vty *vty, const struct lyd_node *dnode, bool show_defaults __attribute__((__unused__))) { vty_out(vty, "affinity-map %s bit-position %u\n", @@ -97,11 +74,24 @@ void cli_show_affinity_map(struct vty *vty, const struct lyd_node *dnode, yang_dnode_get_uint16(dnode, "value")); } +const struct frr_yang_module_info frr_affinity_map_cli_info = { + .name = "frr-affinity-map", + .ignore_cfg_cbs = true, + .nodes = { + { + .xpath = "/frr-affinity-map:lib/affinity-maps/affinity-map", + .cbs.cli_show = cli_show_affinity_map, + }, + { + .xpath = NULL, + }, + } +}; + /* Initialization of affinity map vector. */ void affinity_map_init(void) { /* CLI commands. */ - install_node(&affinitymap_node); install_element(CONFIG_NODE, &affinity_map_cmd); install_element(CONFIG_NODE, &no_affinity_map_cmd); } diff --git a/lib/affinitymap_northbound.c b/lib/affinitymap_northbound.c index 9daccc2800..8e84d36f2f 100644 --- a/lib/affinitymap_northbound.c +++ b/lib/affinitymap_northbound.c @@ -94,7 +94,6 @@ const struct frr_yang_module_info frr_affinity_map_info = { .cbs = { .create = lib_affinity_map_create, .destroy = lib_affinity_map_destroy, - .cli_show = cli_show_affinity_map, } }, { diff --git a/lib/command.h b/lib/command.h index 4886b4bc47..04c66adb26 100644 --- a/lib/command.h +++ b/lib/command.h @@ -291,6 +291,10 @@ struct cmd_node { #define DEFPY_YANG(funcname, cmdname, cmdstr, helpstr) \ DEFPY_ATTR(funcname, cmdname, cmdstr, helpstr, CMD_ATTR_YANG) +#define DEFPY_YANG_HIDDEN(funcname, cmdname, cmdstr, helpstr) \ + DEFPY_ATTR(funcname, cmdname, cmdstr, helpstr, \ + CMD_ATTR_YANG | CMD_ATTR_HIDDEN) + #define DEFPY_YANG_NOSH(funcname, cmdname, cmdstr, helpstr) \ DEFPY_ATTR(funcname, cmdname, cmdstr, helpstr, \ CMD_ATTR_YANG | CMD_ATTR_NOSH) @@ -315,6 +319,10 @@ struct cmd_node { #define DEFUN_NOSH(funcname, cmdname, cmdstr, helpstr) \ DEFUN_ATTR(funcname, cmdname, cmdstr, helpstr, CMD_ATTR_NOSH) +#define DEFUN_YANG_HIDDEN(funcname, cmdname, cmdstr, helpstr) \ + DEFUN_ATTR(funcname, cmdname, cmdstr, helpstr, \ + CMD_ATTR_YANG | CMD_ATTR_HIDDEN) + #define DEFUN_YANG_NOSH(funcname, cmdname, cmdstr, helpstr) \ DEFUN_ATTR(funcname, cmdname, cmdstr, helpstr, \ CMD_ATTR_YANG | CMD_ATTR_NOSH) diff --git a/lib/defun_lex.l b/lib/defun_lex.l index 124f864166..3104e48063 100644 --- a/lib/defun_lex.l +++ b/lib/defun_lex.l @@ -140,6 +140,7 @@ SPECIAL [(),] "DEFPY_ATTR" value = strdup(yytext); return DEFUNNY; "DEFPY_HIDDEN" value = strdup(yytext); return DEFUNNY; "DEFPY_YANG" value = strdup(yytext); return DEFUNNY; +"DEFPY_YANG_HIDDEN" value = strdup(yytext); return DEFUNNY; "DEFPY_YANG_NOSH" value = strdup(yytext); return DEFUNNY; "ALIAS" value = strdup(yytext); return DEFUNNY; "ALIAS_HIDDEN" value = strdup(yytext); return DEFUNNY; @@ -1135,7 +1135,7 @@ struct if_link_params *if_link_params_enable(struct interface *ifp) iflp->unrsv_bw[i] = iflp->default_bw; /* Update Link parameters status */ - iflp->lp_status = LP_MAX_BW | LP_MAX_RSV_BW | LP_UNRSV_BW | LP_EXTEND_ADM_GRP; + iflp->lp_status = LP_MAX_BW | LP_MAX_RSV_BW | LP_UNRSV_BW; /* Set TE metric equal to standard metric only if it is set */ if (ifp->metric != 0) { @@ -195,7 +195,7 @@ struct if_link_params { uint32_t min_delay; /* Link Min Delay */ uint32_t max_delay; /* Link Max Delay */ uint32_t delay_var; /* Link Delay Variation */ - float pkt_loss; /* Link Packet Loss */ + uint32_t pkt_loss; /* Link Packet Loss */ float res_bw; /* Residual Bandwidth */ float ava_bw; /* Available Bandwidth */ float use_bw; /* Utilized Bandwidth */ diff --git a/lib/mgmt_be_client.c b/lib/mgmt_be_client.c index 458623844a..463aefdf25 100644 --- a/lib/mgmt_be_client.c +++ b/lib/mgmt_be_client.c @@ -19,6 +19,7 @@ #include "northbound.h" #include "stream.h" #include "sockopt.h" +#include "northbound_cli.h" #include "lib/mgmt_be_client_clippy.c" @@ -1068,7 +1069,7 @@ struct mgmt_be_client *mgmt_be_client_create(const char *client_name, client->name = XSTRDUP(MTYPE_MGMTD_BE_CLIENT_NAME, client_name); client->running_config = running_config; - client->candidate_config = nb_config_new(NULL); + client->candidate_config = vty_shared_candidate_config; if (cbs) client->cbs = *cbs; mgmt_be_txns_init(&client->txn_head); @@ -1107,7 +1108,6 @@ void mgmt_be_client_destroy(struct mgmt_be_client *client) msg_client_cleanup(&client->client); mgmt_be_cleanup_all_txns(client); mgmt_be_txns_fini(&client->txn_head); - nb_config_free(client->candidate_config); XFREE(MTYPE_MGMTD_BE_CLIENT_NAME, client->name); XFREE(MTYPE_MGMTD_BE_CLIENT, client); diff --git a/lib/northbound.c b/lib/northbound.c index 949218332a..b1da3315d0 100644 --- a/lib/northbound.c +++ b/lib/northbound.c @@ -2384,7 +2384,8 @@ void nb_init(struct event_loop *tm, for (size_t i = 0; i < nmodules; i++) { DEBUGD(&nb_dbg_events, "northbound: loading %s.yang", modules[i]->name); - *loadedp++ = yang_module_load(modules[i]->name); + *loadedp++ = yang_module_load(modules[i]->name, + modules[i]->features); } if (explicit_compile) diff --git a/lib/northbound.h b/lib/northbound.h index 493e5ce703..2d9643e7b4 100644 --- a/lib/northbound.h +++ b/lib/northbound.h @@ -628,6 +628,14 @@ struct frr_yang_module_info { */ bool ignore_cfg_cbs; + /* + * The NULL-terminated list of supported features. + * Features are defined with "feature" statements in the YANG model. + * Use ["*", NULL] to enable all features. + * Use NULL to disable all features. + */ + const char **features; + /* Northbound callbacks. */ const struct { /* Data path of this YANG node. */ @@ -956,6 +956,25 @@ static int lib_vrf_destroy(struct nb_cb_destroy_args *args) return NB_OK; } +static void lib_vrf_cli_write(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults) +{ + const char *name = yang_dnode_get_string(dnode, "name"); + + if (strcmp(name, VRF_DEFAULT_NAME)) { + vty_out(vty, "!\n"); + vty_out(vty, "vrf %s\n", name); + } +} + +static void lib_vrf_cli_write_end(struct vty *vty, const struct lyd_node *dnode) +{ + const char *name = yang_dnode_get_string(dnode, "name"); + + if (strcmp(name, VRF_DEFAULT_NAME)) + vty_out(vty, "exit-vrf\n"); +} + static const void *lib_vrf_get_next(struct nb_cb_get_next_args *args) { struct vrf *vrfp = (struct vrf *)args->list_entry; @@ -1035,6 +1054,8 @@ const struct frr_yang_module_info frr_vrf_info = { .cbs = { .create = lib_vrf_create, .destroy = lib_vrf_destroy, + .cli_show = lib_vrf_cli_write, + .cli_show_end = lib_vrf_cli_write_end, .get_next = lib_vrf_get_next, .get_keys = lib_vrf_get_keys, .lookup_entry = lib_vrf_lookup_entry, @@ -126,6 +126,7 @@ bool vty_log_commands; static bool vty_log_commands_perm; char const *const mgmt_daemons[] = { + "zebra", #ifdef HAVE_RIPD "ripd", #endif @@ -2264,19 +2265,6 @@ bool mgmt_vty_read_configs(void) snprintf(path, sizeof(path), "%s/mgmtd.conf", frr_sysconfdir); confp = vty_open_config(path, config_default); - if (!confp) { - char *orig; - - snprintf(path, sizeof(path), "%s/zebra.conf", frr_sysconfdir); - orig = XSTRDUP(MTYPE_TMP, host_config_get()); - - zlog_info("mgmtd: trying backup config file: %s", path); - confp = vty_open_config(path, config_default); - - host_config_set(path); - XFREE(MTYPE_TMP, orig); - } - if (confp) { zlog_info("mgmtd: reading config file: %s", path); diff --git a/lib/yang.c b/lib/yang.c index b6884619d9..3dd2513a4b 100644 --- a/lib/yang.c +++ b/lib/yang.c @@ -100,13 +100,14 @@ RB_GENERATE(yang_modules, yang_module, entry, yang_module_compare) struct yang_modules yang_modules = RB_INITIALIZER(&yang_modules); -struct yang_module *yang_module_load(const char *module_name) +struct yang_module *yang_module_load(const char *module_name, + const char **features) { struct yang_module *module; const struct lys_module *module_info; - module_info = - ly_ctx_load_module(ly_native_ctx, module_name, NULL, NULL); + module_info = ly_ctx_load_module(ly_native_ctx, module_name, NULL, + features); if (!module_info) { flog_err(EC_LIB_YANG_MODULE_LOAD, "%s: failed to load data model: %s", __func__, @@ -130,8 +131,10 @@ struct yang_module *yang_module_load(const char *module_name) void yang_module_load_all(void) { + static const char * const all_features[] = { "*", NULL }; + for (size_t i = 0; i < array_size(frr_native_modules); i++) - yang_module_load(frr_native_modules[i]); + yang_module_load(frr_native_modules[i], (const char **)all_features); } struct yang_module *yang_module_find(const char *module_name) @@ -625,7 +628,8 @@ struct lyd_node *yang_dnode_dup(const struct lyd_node *dnode) { struct lyd_node *dup = NULL; LY_ERR err; - err = lyd_dup_siblings(dnode, NULL, LYD_DUP_RECURSIVE, &dup); + err = lyd_dup_siblings(dnode, NULL, + LYD_DUP_RECURSIVE | LYD_DUP_WITH_FLAGS, &dup); assert(!err); return dup; } diff --git a/lib/yang.h b/lib/yang.h index 1235125f26..431b2eee48 100644 --- a/lib/yang.h +++ b/lib/yang.h @@ -112,10 +112,16 @@ extern struct yang_modules yang_modules; * module_name * Name of the YANG module. * + * features + * NULL-terminated array of feature names to enable. + * If NULL, all features are disabled. + * To enable all features, use ["*", NULL]. + * * Returns: * Pointer to newly created YANG module. */ -extern struct yang_module *yang_module_load(const char *module_name); +extern struct yang_module *yang_module_load(const char *module_name, + const char **features); /* * Load all FRR native YANG models. diff --git a/lib/yang_wrappers.c b/lib/yang_wrappers.c index dc049a374a..a0133954c3 100644 --- a/lib/yang_wrappers.c +++ b/lib/yang_wrappers.c @@ -168,10 +168,9 @@ struct yang_data *yang_data_new_dec64(const char *xpath, double value) double yang_dnode_get_dec64(const struct lyd_node *dnode, const char *xpath_fmt, ...) { - const double denom[19] = {1e0, 1e-1, 1e-2, 1e-3, 1e-4, - 1e-5, 1e-6, 1e-7, 1e-8, 1e-9, - 1e-10, 1e-11, 1e-12, 1e-13, 1e-14, - 1e-15, 1e-16, 1e-17, 1e-18}; + const double denom[19] = { 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, + 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, + 1e14, 1e15, 1e16, 1e17, 1e18 }; const struct lysc_type_dec *dectype; const struct lyd_value *dvalue; @@ -179,7 +178,7 @@ double yang_dnode_get_dec64(const struct lyd_node *dnode, const char *xpath_fmt, dectype = (const struct lysc_type_dec *)dvalue->realtype; assert(dectype->basetype == LY_TYPE_DEC64); assert(dectype->fraction_digits < sizeof(denom) / sizeof(*denom)); - return (double)dvalue->dec64 * denom[dectype->fraction_digits]; + return (double)dvalue->dec64 / denom[dectype->fraction_digits]; } double yang_get_default_dec64(const char *xpath_fmt, ...) @@ -1020,6 +1019,13 @@ void yang_str2mac(const char *value, struct ethaddr *mac) (void)prefix_str2mac(value, mac); } +void yang_dnode_get_mac(struct ethaddr *mac, const struct lyd_node *dnode, + const char *xpath_fmt, ...) +{ + const char *canon = YANG_DNODE_XPATH_GET_CANON(dnode, xpath_fmt); + (void)prefix_str2mac(canon, mac); +} + struct yang_data *yang_data_new_date_and_time(const char *xpath, time_t time) { struct tm tm; @@ -1046,6 +1052,17 @@ struct yang_data *yang_data_new_date_and_time(const char *xpath, time_t time) return yang_data_new(xpath, timebuf); } +float yang_dnode_get_bandwidth_ieee_float32(const struct lyd_node *dnode, + const char *xpath_fmt, ...) +{ + const char *canon = YANG_DNODE_XPATH_GET_CANON(dnode, xpath_fmt); + float value; + + assert(sscanf(canon, "%a", &value) == 1); + + return value; +} + const char *yang_nexthop_type2str(uint32_t ntype) { switch (ntype) { diff --git a/lib/yang_wrappers.h b/lib/yang_wrappers.h index 06e05872e3..59b5b13acd 100644 --- a/lib/yang_wrappers.h +++ b/lib/yang_wrappers.h @@ -195,11 +195,18 @@ extern void yang_get_default_ip(struct ipaddr *var, const char *xpath_fmt, ...) extern struct yang_data *yang_data_new_mac(const char *xpath, const struct ethaddr *mac); extern void yang_str2mac(const char *value, struct ethaddr *mac); +extern void yang_dnode_get_mac(struct ethaddr *mac, const struct lyd_node *dnode, + const char *xpath_fmt, ...) PRINTFRR(3, 4); /*data-and-time */ extern struct yang_data *yang_data_new_date_and_time(const char *xpath, time_t time); +/* rt-types:bandwidth-ieee-float32 */ +extern float yang_dnode_get_bandwidth_ieee_float32(const struct lyd_node *dnode, + const char *xpath_fmt, ...) + PRINTFRR(2, 3); + /* nexthop enum2str */ extern const char *yang_nexthop_type2str(uint32_t ntype); diff --git a/mgmtd/mgmt_be_adapter.c b/mgmtd/mgmt_be_adapter.c index 6754657500..8d7ae88555 100644 --- a/mgmtd/mgmt_be_adapter.c +++ b/mgmtd/mgmt_be_adapter.c @@ -65,6 +65,23 @@ struct mgmt_be_xpath_map { * above map as well. */ +static const char *const zebra_config_xpaths[] = { + "/frr-affinity-map:lib", + "/frr-filter:lib", + "/frr-route-map:lib", + "/frr-zebra:zebra", + "/frr-interface:lib", + "/frr-vrf:lib", + NULL, +}; + +static const char *const zebra_oper_xpaths[] = { + "/frr-interface:lib/interface", + "/frr-vrf:lib/vrf/frr-zebra:zebra", + "/frr-zebra:zebra", + NULL, +}; + #if HAVE_RIPD static const char *const ripd_config_xpaths[] = { "/frr-filter:lib", @@ -105,6 +122,7 @@ static const char *const staticd_config_xpaths[] = { #endif static const char *const *be_client_config_xpaths[MGMTD_BE_CLIENT_ID_MAX] = { + [MGMTD_BE_CLIENT_ID_ZEBRA] = zebra_config_xpaths, #ifdef HAVE_RIPD [MGMTD_BE_CLIENT_ID_RIPD] = ripd_config_xpaths, #endif @@ -116,13 +134,6 @@ static const char *const *be_client_config_xpaths[MGMTD_BE_CLIENT_ID_MAX] = { #endif }; -static const char *const zebra_oper_xpaths[] = { - "/frr-interface:lib/interface", - "/frr-vrf:lib/vrf/frr-zebra:zebra", - "/frr-zebra:zebra", - NULL, -}; - static const char *const *be_client_oper_xpaths[MGMTD_BE_CLIENT_ID_MAX] = { #ifdef HAVE_RIPD [MGMTD_BE_CLIENT_ID_RIPD] = ripd_oper_xpaths, diff --git a/mgmtd/mgmt_main.c b/mgmtd/mgmt_main.c index 100f574b34..6dbd1f2e52 100644 --- a/mgmtd/mgmt_main.c +++ b/mgmtd/mgmt_main.c @@ -17,7 +17,8 @@ #include "ripd/rip_nb.h" #include "ripngd/ripng_nb.h" #include "routing_nb.h" - +#include "affinitymap.h" +#include "zebra/zebra_cli.h" /* mgmt options, we use GNU getopt library. */ static const struct option longopts[] = { @@ -143,24 +144,11 @@ static struct frr_signal_t mgmt_signals[] = { extern const struct frr_yang_module_info frr_staticd_cli_info; #endif - /* * These are stub info structs that are used to load the modules used by backend * clients into mgmtd. The modules are used by libyang in order to support * parsing binary data returns from the backend. */ -const struct frr_yang_module_info zebra_info = { - .name = "frr-zebra", - .ignore_cfg_cbs = true, - .nodes = { { .xpath = NULL } }, -}; - -const struct frr_yang_module_info affinity_map_info = { - .name = "frr-affinity-map", - .ignore_cfg_cbs = true, - .nodes = { { .xpath = NULL } }, -}; - const struct frr_yang_module_info zebra_route_map_info = { .name = "frr-zebra-route-map", .ignore_cfg_cbs = true, @@ -177,13 +165,13 @@ static const struct frr_yang_module_info *const mgmt_yang_modules[] = { &frr_route_map_cli_info, &frr_routing_info, &frr_vrf_info, + &frr_affinity_map_cli_info, /* * YANG module info used by backend clients get added here. */ - &zebra_info, - &affinity_map_info, + &frr_zebra_cli_info, &zebra_route_map_info, #ifdef HAVE_RIPD diff --git a/mgmtd/mgmt_vty.c b/mgmtd/mgmt_vty.c index 194af13f1e..7135bc5547 100644 --- a/mgmtd/mgmt_vty.c +++ b/mgmtd/mgmt_vty.c @@ -8,6 +8,7 @@ #include <zebra.h> +#include "affinitymap.h" #include "command.h" #include "filter.h" #include "json.h" @@ -25,6 +26,7 @@ #include "ripd/rip_nb.h" #include "ripngd/ripng_nb.h" #include "staticd/static_vty.h" +#include "zebra/zebra_cli.h" extern struct frr_daemon_info *mgmt_daemon_info; @@ -570,6 +572,7 @@ void mgmt_vty_init(void) */ filter_cli_init(); route_map_cli_init(); + affinity_map_init(); /* * Initialize command handling from VTYSH connection. @@ -577,6 +580,7 @@ void mgmt_vty_init(void) * backend components that are moved to new MGMTD infra * here one by one. */ + zebra_cli_init(); #if HAVE_RIPD rip_cli_init(); #endif diff --git a/mgmtd/subdir.am b/mgmtd/subdir.am index 3d1dafabd4..a3955925ed 100644 --- a/mgmtd/subdir.am +++ b/mgmtd/subdir.am @@ -16,8 +16,10 @@ clippy_scan += \ lib_LTLIBRARIES += mgmtd/libmgmt_be_nb.la mgmtd_libmgmt_be_nb_la_SOURCES = \ + zebra/zebra_cli.c \ # end nodist_mgmtd_libmgmt_be_nb_la_SOURCES = \ + lib/affinitymap_cli.c \ # end mgmtd_libmgmt_be_nb_la_CFLAGS = $(AM_CFLAGS) -DINCLUDE_MGMTD_CMDDEFS_ONLY mgmtd_libmgmt_be_nb_la_CPPFLAGS = $(AM_CPPFLAGS) -DINCLUDE_MGMTD_CMDDEFS_ONLY @@ -43,6 +45,7 @@ noinst_HEADERS += \ mgmtd/mgmt_history.h \ mgmtd/mgmt_memory.h \ mgmtd/mgmt_txn.h \ + zebra/zebra_cli.h \ # end sbin_PROGRAMS += mgmtd/mgmtd @@ -51,6 +54,7 @@ mgmtd_mgmtd_SOURCES = \ mgmtd/mgmt_main.c \ # end nodist_mgmtd_mgmtd_SOURCES = \ + yang/frr-zebra.yang.c \ # nothing mgmtd_mgmtd_CFLAGS = $(AM_CFLAGS) -I ./ mgmtd_mgmtd_LDADD = mgmtd/libmgmtd.a lib/libfrr.la $(LIBCAP) $(LIBM) $(LIBYANG_LIBS) $(UST_LIBS) diff --git a/python/xref2vtysh.py b/python/xref2vtysh.py index 1760588ca8..91ccba64f0 100644 --- a/python/xref2vtysh.py +++ b/python/xref2vtysh.py @@ -324,17 +324,7 @@ class CommandEntry: def load(cls, xref): nodes = NodeDict() - mgmtname = "mgmtd/libmgmt_be_nb.la" for cmd_name, origins in xref.get("cli", {}).items(): - # If mgmtd has a yang version of a CLI command, make it the only daemon - # to handle it. For now, daemons can still be compiling their cmds into the - # binaries to allow for running standalone with CLI config files. When they - # do this they will also be present in the xref file, but we want to ignore - # those in vtysh. - if "yang" in origins.get(mgmtname, {}).get("attrs", []): - CommandEntry.process(nodes, cmd_name, mgmtname, origins[mgmtname]) - continue - for origin, spec in origins.items(): CommandEntry.process(nodes, cmd_name, origin, spec) return nodes diff --git a/staticd/static_vty.c b/staticd/static_vty.c index 95f79564af..05f23f54d1 100644 --- a/staticd/static_vty.c +++ b/staticd/static_vty.c @@ -1696,8 +1696,7 @@ void static_vty_init(void) install_element(CONFIG_NODE, &debug_staticd_cmd); install_element(ENABLE_NODE, &show_debugging_static_cmd); install_element(ENABLE_NODE, &staticd_show_bfd_routes_cmd); -#endif /* ifndef INCLUDE_MGMTD_CMDDEFS_ONLY */ - +#else /* else INCLUDE_MGMTD_CMDDEFS_ONLY */ install_element(CONFIG_NODE, &ip_mroute_dist_cmd); install_element(CONFIG_NODE, &ip_route_blackhole_cmd); @@ -1713,6 +1712,7 @@ void static_vty_init(void) install_element(VRF_NODE, &ipv6_route_address_interface_vrf_cmd); install_element(CONFIG_NODE, &ipv6_route_cmd); install_element(VRF_NODE, &ipv6_route_vrf_cmd); +#endif /* ifndef INCLUDE_MGMTD_CMDDEFS_ONLY */ #ifndef INCLUDE_MGMTD_CMDDEFS_ONLY mgmt_be_client_lib_vty_init(); diff --git a/tests/isisd/test_isis_spf.c b/tests/isisd/test_isis_spf.c index 95f045c90d..4ea28cda2f 100644 --- a/tests/isisd/test_isis_spf.c +++ b/tests/isisd/test_isis_spf.c @@ -540,7 +540,7 @@ int main(int argc, char **argv) zlog_aux_init("NONE: ", ZLOG_DISABLED); /* IS-IS inits. */ - yang_module_load("frr-isisd"); + yang_module_load("frr-isisd", NULL); SET_FLAG(im->options, F_ISIS_UNIT_TEST); debug_spf_events |= DEBUG_SPF_EVENTS; debug_lfa |= DEBUG_LFA; diff --git a/tests/topotests/bgp_recursive_route_ebgp_multi_hop/test_bgp_recursive_route_ebgp_multi_hop.py b/tests/topotests/bgp_recursive_route_ebgp_multi_hop/test_bgp_recursive_route_ebgp_multi_hop.py index 35459f6f68..88251fae60 100644 --- a/tests/topotests/bgp_recursive_route_ebgp_multi_hop/test_bgp_recursive_route_ebgp_multi_hop.py +++ b/tests/topotests/bgp_recursive_route_ebgp_multi_hop/test_bgp_recursive_route_ebgp_multi_hop.py @@ -257,10 +257,10 @@ def test_recursive_routes_iBGP_peer_p1(request): ) dut = "r2" create_interface_in_kernel( - tgen, dut, "lo", "40.40.40.50", netmask="255.255.255.0", create=True + tgen, dut, "lo10", "40.40.40.50", netmask="255.255.255.0", create=True ) create_interface_in_kernel( - tgen, dut, "lo", "40:40::40:50", netmask="120", create=True + tgen, dut, "lo10", "40:40::40:50", netmask="120", create=True ) for addr_type in ADDR_TYPES: input_dict_3 = { diff --git a/tests/topotests/mgmt_oper/simple-results/result-intf-eth0-only-config.json b/tests/topotests/mgmt_oper/simple-results/result-intf-eth0-only-config.json index adcf99053f..9289759274 100644 --- a/tests/topotests/mgmt_oper/simple-results/result-intf-eth0-only-config.json +++ b/tests/topotests/mgmt_oper/simple-results/result-intf-eth0-only-config.json @@ -3,7 +3,15 @@ "interface": [ { "name": "r1-eth0", - "description": "r1-eth0-desc" + "description": "r1-eth0-desc", + "frr-zebra:zebra": { + "ipv4-addrs": [ + { + "ip": "1.1.1.1", + "prefix-length": 24 + } + ] + } } ] } diff --git a/tests/topotests/mgmt_oper/simple-results/result-intf-eth0-with-config.json b/tests/topotests/mgmt_oper/simple-results/result-intf-eth0-with-config.json index 47c9686252..ef9e005619 100644 --- a/tests/topotests/mgmt_oper/simple-results/result-intf-eth0-with-config.json +++ b/tests/topotests/mgmt_oper/simple-results/result-intf-eth0-with-config.json @@ -14,6 +14,12 @@ "phy-address": "rubout" }, "frr-zebra:zebra": { + "ipv4-addrs": [ + { + "ip": "1.1.1.1", + "prefix-length": 24 + } + ], "state": { "up-count": 0, "down-count": 0 diff --git a/tools/gen_northbound_callbacks.c b/tools/gen_northbound_callbacks.c index 550058bfec..6188559010 100644 --- a/tools/gen_northbound_callbacks.c +++ b/tools/gen_northbound_callbacks.c @@ -350,7 +350,7 @@ int main(int argc, char *argv[]) module = yang_module_find(argv[0]); if (!module) /* Non-native FRR module (e.g. modules from unit tests). */ - module = yang_module_load(argv[0]); + module = yang_module_load(argv[0], NULL); yang_init_loading_complete(); diff --git a/tools/gen_yang_deviations.c b/tools/gen_yang_deviations.c index fc9f55bcbc..251643c69e 100644 --- a/tools/gen_yang_deviations.c +++ b/tools/gen_yang_deviations.c @@ -55,7 +55,7 @@ int main(int argc, char *argv[]) yang_init(false, false); /* Load YANG module. */ - module = yang_module_load(argv[0]); + module = yang_module_load(argv[0], NULL); /* Generate deviations. */ yang_snodes_iterate(module->info, generate_yang_deviation, 0, NULL); diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index b1a53965cd..940b63b0e1 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -1615,7 +1615,6 @@ struct cmd_node link_params_node = { .node = LINK_PARAMS_NODE, .parent_node = INTERFACE_NODE, .prompt = "%s(config-link-params)# ", - .no_xpath = true, }; #ifdef HAVE_BGPD @@ -3008,14 +3007,22 @@ DEFUN (vtysh_show_work_queues_daemon, return show_one_daemon(vty, argv, argc - 1, argv[argc - 1]->text); } -DEFUNSH(VTYSH_ZEBRA, vtysh_link_params, vtysh_link_params_cmd, "link-params", +DEFUNSH(VTYSH_MGMTD, vtysh_link_params, vtysh_link_params_cmd, "link-params", LINK_PARAMS_STR) { vty->node = LINK_PARAMS_NODE; return CMD_SUCCESS; } -DEFUNSH(VTYSH_ZEBRA, exit_link_params, exit_link_params_cmd, "exit-link-params", +DEFUNSH_HIDDEN(VTYSH_MGMTD, no_link_params_enable, no_link_params_enable_cmd, + "no enable", NO_STR "Disable link parameters on this interface\n") +{ + if (vty->node == LINK_PARAMS_NODE) + vty->node = INTERFACE_NODE; + return CMD_SUCCESS; +} + +DEFUNSH(VTYSH_MGMTD, exit_link_params, exit_link_params_cmd, "exit-link-params", "Exit from Link Params configuration node\n") { if (vty->node == LINK_PARAMS_NODE) @@ -3023,7 +3030,7 @@ DEFUNSH(VTYSH_ZEBRA, exit_link_params, exit_link_params_cmd, "exit-link-params", return CMD_SUCCESS; } -DEFUNSH(VTYSH_ZEBRA, vtysh_exit_link_params, vtysh_exit_link_params_cmd, "exit", +DEFUNSH(VTYSH_MGMTD, vtysh_exit_link_params, vtysh_exit_link_params_cmd, "exit", "Exit current mode and down to previous mode\n") { if (vty->node == LINK_PARAMS_NODE) @@ -3031,7 +3038,7 @@ DEFUNSH(VTYSH_ZEBRA, vtysh_exit_link_params, vtysh_exit_link_params_cmd, "exit", return CMD_SUCCESS; } -DEFUNSH(VTYSH_ZEBRA, vtysh_quit_link_params, vtysh_quit_link_params_cmd, "quit", +DEFUNSH(VTYSH_MGMTD, vtysh_quit_link_params, vtysh_quit_link_params_cmd, "quit", "Exit current mode and down to previous mode\n") { return vtysh_exit_link_params(self, vty, argc, argv); @@ -5064,6 +5071,7 @@ void vtysh_init_vty(void) install_node(&link_params_node); install_element(INTERFACE_NODE, &vtysh_link_params_cmd); + install_element(LINK_PARAMS_NODE, &no_link_params_enable_cmd); install_element(LINK_PARAMS_NODE, &exit_link_params_cmd); install_element(LINK_PARAMS_NODE, &vtysh_end_all_cmd); install_element(LINK_PARAMS_NODE, &vtysh_exit_link_params_cmd); diff --git a/vtysh/vtysh.h b/vtysh/vtysh.h index b1e914ebf7..7758ceaea5 100644 --- a/vtysh/vtysh.h +++ b/vtysh/vtysh.h @@ -53,23 +53,23 @@ extern struct event_loop *master; VTYSH_BFDD | VTYSH_BABELD | VTYSH_BGPD | VTYSH_EIGRPD | VTYSH_ISISD | \ VTYSH_FABRICD | VTYSH_LDPD | VTYSH_NHRPD | VTYSH_OSPF6D | \ VTYSH_OSPFD | VTYSH_PBRD | VTYSH_PIMD | VTYSH_PIM6D | \ - VTYSH_VRRPD | VTYSH_ZEBRA | VTYSH_MGMTD + VTYSH_VRRPD | VTYSH_MGMTD #define VTYSH_ACL_SHOW \ VTYSH_BFDD | VTYSH_BABELD | VTYSH_BGPD | VTYSH_EIGRPD | VTYSH_ISISD | \ VTYSH_FABRICD | VTYSH_LDPD | VTYSH_NHRPD | VTYSH_OSPF6D | \ VTYSH_OSPFD | VTYSH_PBRD | VTYSH_PIMD | VTYSH_PIM6D | \ VTYSH_RIPD | VTYSH_RIPNGD | VTYSH_VRRPD | VTYSH_ZEBRA -#define VTYSH_AFFMAP VTYSH_ZEBRA | VTYSH_ISISD +#define VTYSH_AFFMAP VTYSH_ISISD | VTYSH_MGMTD #define VTYSH_RMAP_CONFIG \ - VTYSH_ZEBRA | VTYSH_OSPFD | VTYSH_OSPF6D | VTYSH_BGPD | VTYSH_ISISD | \ + VTYSH_OSPFD | VTYSH_OSPF6D | VTYSH_BGPD | VTYSH_ISISD | \ VTYSH_PIMD | VTYSH_EIGRPD | VTYSH_FABRICD | VTYSH_MGMTD #define VTYSH_RMAP_SHOW \ VTYSH_ZEBRA | VTYSH_RIPD | VTYSH_RIPNGD | VTYSH_OSPFD | VTYSH_OSPF6D | \ VTYSH_BGPD | VTYSH_ISISD | VTYSH_PIMD | VTYSH_EIGRPD | \ VTYSH_FABRICD #define VTYSH_INTERFACE_SUBSET \ - VTYSH_ZEBRA | VTYSH_OSPFD | VTYSH_OSPF6D | \ + VTYSH_OSPFD | VTYSH_OSPF6D | \ VTYSH_ISISD | VTYSH_PIMD | VTYSH_PIM6D | VTYSH_NHRPD | \ VTYSH_EIGRPD | VTYSH_BABELD | VTYSH_PBRD | VTYSH_FABRICD | \ VTYSH_VRRPD | VTYSH_MGMTD diff --git a/yang/frr-zebra.yang b/yang/frr-zebra.yang index 1168f05f40..564617103b 100644 --- a/yang/frr-zebra.yang +++ b/yang/frr-zebra.yang @@ -81,6 +81,16 @@ module frr-zebra { "Initial revision."; } + feature ipv6-router-advertisements { + description + "Support for IPv6 Router Advertisements."; + } + + feature ptm-bfd { + description + "Using an external PTM daemon that implements BFD."; + } + typedef unix-timestamp { type uint32; units "seconds"; @@ -1935,19 +1945,23 @@ module frr-zebra { description "Extends interface model with Zebra-related parameters."; container zebra { - list ip-addrs { - key "address-family ip-prefix"; + list ipv4-addrs { + key "ip prefix-length"; description - "IP prefixes for an interface."; - uses frr-rt:address-family { + "The list of configured IPv4 addresses on the interface."; + + leaf ip { + type inet:ipv4-address-no-zone; description - "Address family of the RIB."; + "The IPv4 address on the interface."; } - leaf ip-prefix { - type inet:ip-prefix; + leaf prefix-length { + type uint8 { + range "0..32"; + } description - "IP address prefix."; + "The length of the subnet prefix."; } leaf label { @@ -1955,12 +1969,57 @@ module frr-zebra { description "Optional string label for the address."; } + } + + list ipv4-p2p-addrs { + key "ip peer-ip peer-prefix-length"; + description + "The list of configured peer-to-peer IPv4 addresses on the interface."; + + leaf ip { + type inet:ipv4-address-no-zone; + description + "The IPv4 address on the interface."; + } + + leaf peer-ip { + type inet:ipv4-address-no-zone; + description + "Peer address."; + } + + leaf peer-prefix-length { + type uint8 { + range "0..32"; + } + description + "The length of the peer subnet prefix."; + } - leaf ip4-peer { - when "derived-from-or-self(../address-family, 'frr-rt:ipv4')"; - type inet:ipv4-prefix; + leaf label { + type string; description - "Peer prefix, for peer-to-peer interfaces."; + "Optional string label for the address."; + } + } + + list ipv6-addrs { + key "ip prefix-length"; + description + "The list of configured IPv6 addresses on the interface."; + + leaf ip { + type inet:ipv6-address-no-zone; + description + "The IPv6 address on the interface."; + } + + leaf prefix-length { + type uint8 { + range "0..128"; + } + description + "The length of the subnet prefix."; } } @@ -1972,11 +2031,12 @@ module frr-zebra { leaf link-detect { type boolean; + default "true"; description "Link-detection for the interface."; } - leaf shutdown { + leaf enabled { type boolean; description "Interface admin status."; @@ -1992,12 +2052,67 @@ module frr-zebra { type uint32 { range "1..100000"; } + units "megabits/sec"; description "Link bandwidth informational parameter, in megabits."; } container link-params { + presence "Activates link parameters on this interface."; description "link-params for Traffic-Engineering (TE) use in IGP extensions."; + leaf metric { + type uint32; + description + "Link metric for MPLS-TE purpose."; + } + leaf max-bandwidth { + type rt-types:bandwidth-ieee-float32; + description + "Maximum bandwidth."; + } + leaf max-reservable-bandwidth { + type rt-types:bandwidth-ieee-float32; + description + "Maximum reservable bandwidth."; + } + container unreserved-bandwidths { + description + "All unreserved bandwidths."; + list unreserved-bandwidth { + key "priority"; + leaf priority { + type uint8 { + range "0 .. 7"; + } + description + "Priority from 0 to 7."; + } + leaf unreserved-bandwidth { + type rt-types:bandwidth-ieee-float32; + mandatory true; + description + "Unreserved bandwidth."; + } + description + "List of unreserved bandwidths for different + priorities."; + } + } + leaf residual-bandwidth { + type rt-types:bandwidth-ieee-float32; + description + "Unidirectional residual bandwidth."; + } + leaf available-bandwidth { + type rt-types:bandwidth-ieee-float32; + description + "Unidirectional available bandwidth."; + } + leaf utilized-bandwidth { + type rt-types:bandwidth-ieee-float32; + description + "Unidirectional utilized bandwidth."; + } choice admin-group-mode { description "Admin-group mode"; case legacy { @@ -2044,9 +2159,526 @@ module frr-zebra { } } } + container neighbor { + description "Remote ASBR information (RFC 5316 & RFC 5392)"; + presence "Activates neighbor information on this interface."; + leaf remote-as { + type inet:as-number; + mandatory true; + description + "Remote AS Number (RFC 5316 & RFC 5392)"; + } + leaf ipv4-remote-id { + type inet:ipv4-address; + mandatory true; + description + "IPv4 Remote ASBR ID (RFC 5316 & RFC 5392)"; + } + } + leaf delay { + type uint32 { + range "0..16777215"; + } + description + "Average Unidirectional Link Delay"; + } + container min-max-delay { + description + "Min/Max Unidirectional Link Delay"; + presence "Activates min/max delay."; + leaf delay-min { + type uint32 { + range "0..16777215"; + } + must '. <= ../../delay' { + error-message "Min delay must be less than or equal to delay"; + } + mandatory true; + description + "Min Delay"; + } + leaf delay-max { + type uint32 { + range "0..16777215"; + } + must '. >= ../../delay' { + error-message "Max delay must be greater than or equal to delay"; + } + mandatory true; + description + "Max Delay"; + } + } + leaf delay-variation { + type uint32 { + range "0..16777215"; + } + description + "Unidirectional Delay Variation"; + } + leaf packet-loss { + type decimal64 { + fraction-digits 6; + range "0..50.331642"; + } + description + "Unidirectional Link Packet Loss"; + } // TODO -- other link-params options // for (experimental/partial TE use in IGP extensions) } + container evpn-mh { + description "EVPN multihoming configuration"; + choice esi-choice { + description "ESI type"; + container type-0 { + leaf esi { + type yang:hex-string { + length "29"; + } + description + "10-octet ESI."; + } + } + container type-3 { + leaf system-mac { + type yang:mac-address; + description + "System MAC address."; + } + leaf local-discriminator { + type uint32 { + range "1..16777215"; + } + description + "Local discriminator."; + } + } + } + leaf df-preference { + type uint16; + default "32767"; + description + "Preference value used for DF election."; + } + leaf bypass { + type boolean; + default "false"; + description + "Bypass mode."; + } + leaf uplink { + type boolean; + default "false"; + description + "Uplink to the VxLAN core."; + } + } + container ipv6-router-advertisements { + if-feature "ipv6-router-advertisements"; + description + "Support for IPv6 Router Advertisements."; + leaf send-advertisements { + type boolean; + default "false"; + description + "A flag indicating whether or not the router sends + periodic Router Advertisements and responds to + Router Solicitations."; + reference + "RFC 4861: Neighbor Discovery for IP version 6 (IPv6) + - AdvSendAdvertisements"; + } + leaf max-rtr-adv-interval { + type uint32 { + range "70..1800000"; + } + units "milliseconds"; + default "600000"; + description + "The maximum time allowed between sending unsolicited + multicast Router Advertisements from the interface."; + reference + "RFC 4861: Neighbor Discovery for IP version 6 (IPv6) + - MaxRtrAdvInterval + RFC 6275: Mobility Support in IPv6"; + } + // Setting this value is not yet supported by the actual code. + /* + leaf min-rtr-adv-interval { + type uint32 { + range "30..1350000"; + } + units "milliseconds"; + must ". <= 0.75 * ../max-rtr-adv-interval" { + description + "The value MUST NOT be greater than 75% of + 'max-rtr-adv-interval'."; + } + description + "The minimum time allowed between sending unsolicited + multicast Router Advertisements from the interface. + + The default value to be used operationally if this + leaf is not configured is determined as follows: + + - if max-rtr-adv-interval >= 9 seconds, the default + value is 0.33 * max-rtr-adv-interval; + + - otherwise, it is 0.75 * max-rtr-adv-interval."; + reference + "RFC 4861: Neighbor Discovery for IP version 6 (IPv6) + - MaxRtrAdvInterval + RFC 6275: Mobility Support in IPv6"; + } + */ + leaf managed-flag { + type boolean; + default "false"; + description + "The value to be placed in the 'Managed address + configuration' flag field in the Router + Advertisement."; + reference + "RFC 4861: Neighbor Discovery for IP version 6 (IPv6) + - AdvManagedFlag"; + } + leaf other-config-flag { + type boolean; + default "false"; + description + "The value to be placed in the 'Other configuration' + flag field in the Router Advertisement."; + reference + "RFC 4861: Neighbor Discovery for IP version 6 (IPv6) + - AdvOtherConfigFlag"; + } + leaf home-agent-flag { + type boolean; + default "false"; + description + "The value to be placed in the 'Home Agent' + flag field in the Router Advertisement."; + reference + "RFC 6275: Mobility Support in IPv6"; + } + leaf link-mtu { + type uint32; + default "0"; + description + "The value to be placed in MTU options sent by the + router. A value of zero indicates that no MTU options + are sent."; + reference + "RFC 4861: Neighbor Discovery for IP version 6 (IPv6) + - AdvLinkMTU"; + } + leaf reachable-time { + type uint32 { + range "0..3600000"; + } + units "milliseconds"; + default "0"; + description + "The value to be placed in the Reachable Time field in + the Router Advertisement messages sent by the router. + A value of zero means unspecified (by this router)."; + reference + "RFC 4861: Neighbor Discovery for IP version 6 (IPv6) + - AdvReachableTime"; + } + leaf retrans-timer { + type uint32; + units "milliseconds"; + default "0"; + description + "The value to be placed in the Retrans Timer field in + the Router Advertisement messages sent by the router. + A value of zero means unspecified (by this router)."; + reference + "RFC 4861: Neighbor Discovery for IP version 6 (IPv6) + - AdvRetransTimer"; + } + leaf cur-hop-limit { + type uint8; + description + "The value to be placed in the Cur Hop Limit field in + the Router Advertisement messages sent by the router. + A value of zero means unspecified (by this router). + + If this parameter is not configured, the device SHOULD + use the IANA-specified value for the default IPv4 + Time to Live (TTL) parameter that was in effect at the + time of implementation."; + reference + "RFC 3232: Assigned Numbers: RFC 1700 is Replaced by + an On-line Database + RFC 4861: Neighbor Discovery for IP version 6 (IPv6) + - AdvCurHopLimit + IANA: IP Parameters + (https://www.iana.org/assignments/ip-parameters)"; + } + leaf default-lifetime { + type uint16 { + range "0..9000"; + } + units "seconds"; + must ". = 0 or . * 1000 >= ../max-rtr-adv-interval" { + description + "The value MUST NOT be less than max-rtr-adv-interval."; + } + description + "The value to be placed in the Router Lifetime field of + Router Advertisements sent from the interface, in + seconds. It MUST be either zero or between + max-rtr-adv-interval and 9000 seconds. A value of zero + indicates that the router is not to be used as a + default router. These limits may be overridden by + specific documents that describe how IPv6 operates over + different link layers. + + If this parameter is not configured, the device SHOULD + use a value of 3 * max-rtr-adv-interval."; + reference + "RFC 4861: Neighbor Discovery for IP version 6 (IPv6) + - AdvDefaultLifetime"; + } + leaf fast-retransmit { + type boolean; + default "true"; + description + "Allow sending unsolicited multicast Router Advertisements + more frequently than once every 3 seconds as required by + RFC 4861."; + } + leaf advertisement-interval-option { + type boolean; + default "false"; + description + "Enable sending the Advertisement Interval Option in + Router Advertisements."; + reference + "RFC 6275: Mobility Support in IPv6"; + } + leaf home-agent-preference { + type uint16; + description + "The value to be placed in the Home Agent Preference + field in the Router Advertisement messages sent by the + router."; + reference + "RFC 6275: Mobility Support in IPv6"; + } + leaf home-agent-lifetime { + type uint16; + description + "The value to be placed in the Home Agent Lifetime + field in the Router Advertisement messages sent by the + router."; + reference + "RFC 6275: Mobility Support in IPv6"; + } + leaf default-router-preference { + type enumeration { + enum high { + value 1; /* 01 */ + description + "High preference."; + } + enum medium { + value 0; /* 00 */ + description + "Medium preference."; + } + enum low { + value 3; /* 11 */ + description + "Low preference."; + } + } + default "medium"; + description + "The value to be placed in the Default Router + Preference field in the Router Advertisement messages + sent by the router."; + reference + "RFC 4191: Default Router Preferences and More-Specific + Routes"; + } + container prefix-list { + description + "Support for prefixes to be placed in Prefix + Information options in Router Advertisement messages + sent from the interface. + + Prefixes that are advertised by default but do not + have their entries in the child 'prefix' list are + advertised with the default values of all parameters. + + The link-local prefix SHOULD NOT be included in the + list of advertised prefixes."; + reference + "RFC 4861: Neighbor Discovery for IP version 6 (IPv6) + - AdvPrefixList"; + list prefix { + key "prefix-spec"; + description + "Support for an advertised prefix entry."; + leaf prefix-spec { + type inet:ipv6-prefix; + description + "IPv6 address prefix."; + } + // FRR doesn't support 'no-advertise'. Keeping the code + // here for future reference. + /* + choice control-adv-prefixes { + default "advertise"; + description + "Either (1) the prefix is explicitly removed from the + set of advertised prefixes or (2) the parameters with + which the prefix is advertised are specified (default + case)."; + leaf no-advertise { + type empty; + description + "The prefix will not be advertised. + + This can be used for removing the prefix from + the default set of advertised prefixes."; + } + case advertise { + */ + leaf valid-lifetime { + type uint32; + units "seconds"; + default "2592000"; + description + "The value to be placed in the Valid Lifetime + in the Prefix Information option. The + designated value of all 1's (0xffffffff) + represents infinity."; + reference + "RFC 4861: Neighbor Discovery for IP version 6 + (IPv6) - AdvValidLifetime"; + } + leaf on-link-flag { + type boolean; + default "true"; + description + "The value to be placed in the on-link flag + ('L-bit') field in the Prefix Information + option."; + reference + "RFC 4861: Neighbor Discovery for IP version 6 + (IPv6) - AdvOnLinkFlag"; + } + leaf preferred-lifetime { + type uint32; + units "seconds"; + must ". <= ../valid-lifetime" { + description + "This value MUST NOT be greater than + valid-lifetime."; + } + default "604800"; + description + "The value to be placed in the Preferred + Lifetime in the Prefix Information option. + The designated value of all 1's (0xffffffff) + represents infinity."; + reference + "RFC 4861: Neighbor Discovery for IP version 6 + (IPv6) - AdvPreferredLifetime"; + } + leaf autonomous-flag { + type boolean; + default "true"; + description + "The value to be placed in the Autonomous Flag + field in the Prefix Information option."; + reference + "RFC 4861: Neighbor Discovery for IP version 6 + (IPv6) - AdvAutonomousFlag"; + } + leaf router-address-flag { + type boolean; + default "false"; + description + "The value to be placed in the Router Address + flag field in the Prefix Information option."; + reference + "RFC 6275: Mobility Support in IPv6"; + } + /* + } + } + */ + // This is closing brackets for `case advertise` and + // `choice control-adv-prefixes`. + } + } + container rdnss { + description + "A list of recursive DNS server addresses that are placed + in Recursive DNS Server (RDNSS) options in Router + Advertisement messages sent from the interface."; + reference + "RFC 8106: IPv6 Router Advertisement Options for DNS + Configuration"; + list rdnss-address { + key "address"; + description + "Recursive DNS server address."; + leaf address { + type inet:ipv6-address; + description + "IPv6 address of a recursive DNS server."; + } + leaf lifetime { + type uint32; + units "seconds"; + description + "The value that is placed in the Lifetime field in the + RDNSS option. The designated value of all 1's + (0xffffffff) represents infinity."; + } + } + } + container dnssl { + description + "A list of domain names that are placed in DNS Search List (DNSSL) + options in Router Advertisement messages sent from the interface."; + reference + "RFC 8106: IPv6 Router Advertisement Options for DNS + Configuration"; + list dnssl-domain { + key "domain"; + description + "Domain name for the search list."; + leaf domain { + type inet:domain-name; + description + "Domain name for the search list."; + } + leaf lifetime { + type uint32; + units "seconds"; + description + "The value that is placed in the Lifetime field in the + DNSSL option. The designated value of all 1's + (0xffffffff) represents infinity."; + } + } + } + } + leaf ptm-enable { + if-feature ptm-bfd; + type boolean; + default "true"; + description + "Enable PTM on the interface."; + } container state { config false; description @@ -2111,6 +2743,112 @@ module frr-zebra { container zebra { description "Zebra's vrf specific configuration and operational model."; + + leaf router-id { + type yang:dotted-quad; + description + "A 32-bit number in the form of a dotted quad that is used by + some routing protocols identifying a router."; + } + + leaf ipv6-router-id { + type inet:ipv6-address-no-zone; + description + "A 128-bit number in the form of an IPv6 address that is used by + some routing protocols identifying a router."; + } + + list filter-protocol { + key "afi-safi protocol"; + description + "Filter routing info exchanged between zebra and protocol."; + leaf afi-safi { + type identityref { + base frr-rt:afi-safi-type; + } + description + "AFI-SAFI type."; + } + leaf protocol { + // This should be identityref to frr-rt:control-plane-protocol someday + type string; + description + "The protocol to filter."; + } + leaf route-map { + type frr-route-map:route-map-ref; + mandatory true; + description + "A route-map to filter routes."; + } + } + + list filter-nht { + key "afi-safi protocol"; + description + "Filter next hop tracking route resolution."; + leaf afi-safi { + type identityref { + base frr-rt:afi-safi-type; + } + description + "AFI-SAFI type."; + } + leaf protocol { + // This should be identityref to frr-rt:control-plane-protocol someday + type string; + description + "The protocol to filter."; + } + leaf route-map { + type frr-route-map:route-map-ref; + mandatory true; + description + "A route-map to filter nexthops."; + } + } + + leaf resolve-via-default { + type boolean; + description + "Resolve IPv4 nexthops via the default route. This is true by default + for traditional profile and false by default for datacenter profile. + Removing the leaf sets it back to the default value for the profile."; + } + + leaf ipv6-resolve-via-default { + type boolean; + description + "Resolve IPv4 nexthops via the default route. This is true by default + for traditional profile and false by default for datacenter profile. + Removing the leaf sets it back to the default value for the profile."; + } + + container netns { + description + "Configuration for netns VRF backend."; + container table-range { + presence "Activates table-range configuration."; + description + "The range of tables to use for this netns."; + leaf start { + type uint32; + mandatory true; + description + "The first table to use."; + } + leaf end { + type uint32; + mandatory true; + must ". >= ../start" { + error-message "End table must be greater than or equal to start table"; + } + description + "The last table to use."; + } + } + } + uses ribs; uses vrf-vni-mapping; @@ -2216,6 +2954,22 @@ module frr-zebra { description "Limit on the number of updates queued to the dataplane subsystem."; } + leaf ptm-enable { + if-feature ptm-bfd; + type boolean; + default "false"; + description + "Enable PTM globally."; + } + leaf route-map-delay { + type uint32 { + range "0..600"; + } + units "seconds"; + default "5"; + description + "Time to wait before route-map updates are processed."; + } /* * Debug options */ diff --git a/zebra/interface.c b/zebra/interface.c index f864b91822..6e33d7ec7d 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -18,7 +18,6 @@ #include "log.h" #include "zclient.h" #include "vrf.h" -#include "lib/northbound_cli.h" #include "zebra/rtadv.h" #include "zebra_ns.h" @@ -44,8 +43,6 @@ DEFINE_MTYPE_STATIC(ZEBRA, ZINFO, "Zebra Interface Information"); DEFINE_HOOK(zebra_if_extra_info, (struct vty * vty, struct interface *ifp), (vty, ifp)); -DEFINE_HOOK(zebra_if_config_wr, (struct vty * vty, struct interface *ifp), - (vty, ifp)); DEFINE_MTYPE(ZEBRA, ZIF_DESC, "Intf desc"); @@ -136,7 +133,7 @@ static int if_zebra_new_hook(struct interface *ifp) zebra_if->multicast = IF_ZEBRA_DATA_UNSPEC; zebra_if->mpls_config = IF_ZEBRA_DATA_UNSPEC; - zebra_if->shutdown = IF_ZEBRA_DATA_OFF; + zebra_if->shutdown = IF_ZEBRA_DATA_UNSPEC; zebra_if->link_nsid = NS_UNKNOWN; @@ -148,6 +145,8 @@ static int if_zebra_new_hook(struct interface *ifp) rtadv_if_init(zebra_if); + zebra_evpn_mh_if_init(zebra_if); + memset(&zebra_if->neigh_mac[0], 0, 6); /* Initialize installed address chains tree. */ @@ -2877,8 +2876,8 @@ static void if_dump_vty(struct vty *vty, struct interface *ifp) " Link Delay Variation %u (micro-sec.)\n", iflp->delay_var); if (IS_PARAM_SET(iflp, LP_PKT_LOSS)) - vty_out(vty, " Link Packet Loss %g (in %%)\n", - iflp->pkt_loss); + vty_out(vty, " Link Packet Loss %f (in %%)\n", + (double)iflp->pkt_loss * LOSS_PRECISION); if (IS_PARAM_SET(iflp, LP_AVA_BW)) vty_out(vty, " Available Bandwidth %g (Byte/s)\n", iflp->ava_bw); @@ -3278,7 +3277,8 @@ static void if_dump_vty_json(struct vty *vty, struct interface *ifp, iflp->delay_var); if (IS_PARAM_SET(iflp, LP_PKT_LOSS)) json_object_double_add(json_te, "linkPacketLoss", - iflp->pkt_loss); + (double)iflp->pkt_loss * + LOSS_PRECISION); if (IS_PARAM_SET(iflp, LP_AVA_BW)) json_object_double_add(json_te, "availableBandwidth", iflp->ava_bw); @@ -3701,47 +3701,6 @@ int if_multicast_set(struct interface *ifp) return 0; } -DEFUN (multicast, - multicast_cmd, - "multicast", - "Set multicast flag to interface\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - int ret; - struct zebra_if *if_data; - - if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) { - ret = if_set_flags(ifp, IFF_MULTICAST); - if (ret < 0) { - vty_out(vty, "Can't set multicast flag\n"); - return CMD_WARNING_CONFIG_FAILED; - } - if_refresh(ifp); - } - if_data = ifp->info; - if_data->multicast = IF_ZEBRA_DATA_ON; - - return CMD_SUCCESS; -} - -DEFPY (mpls, - mpls_cmd, - "[no] mpls <enable$on|disable$off>", - NO_STR - MPLS_STR - "Set mpls to be on for the interface\n" - "Set mpls to be off for the interface\n") -{ - if (!no) - nb_cli_enqueue_change(vty, "./frr-zebra:zebra/mpls", - NB_OP_CREATE, on ? "true" : "false"); - else - nb_cli_enqueue_change(vty, "./frr-zebra:zebra/mpls", - NB_OP_DESTROY, NULL); - - return nb_cli_apply_changes(vty, NULL); -} - int if_multicast_unset(struct interface *ifp) { struct zebra_if *if_data; @@ -3760,30 +3719,6 @@ int if_multicast_unset(struct interface *ifp) return 0; } -DEFUN (no_multicast, - no_multicast_cmd, - "no multicast", - NO_STR - "Unset multicast flag to interface\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - int ret; - struct zebra_if *if_data; - - if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) { - ret = if_unset_flags(ifp, IFF_MULTICAST); - if (ret < 0) { - vty_out(vty, "Can't unset multicast flag\n"); - return CMD_WARNING_CONFIG_FAILED; - } - if_refresh(ifp); - } - if_data = ifp->info; - if_data->multicast = IF_ZEBRA_DATA_OFF; - - return CMD_SUCCESS; -} - int if_linkdetect(struct interface *ifp, bool detect) { int if_was_operative; @@ -3807,30 +3742,6 @@ int if_linkdetect(struct interface *ifp, bool detect) return 0; } -DEFUN(linkdetect, linkdetect_cmd, "link-detect", - "Enable link detection on interface\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - - if_linkdetect(ifp, true); - - return CMD_SUCCESS; -} - - -DEFUN (no_linkdetect, - no_linkdetect_cmd, - "no link-detect", - NO_STR - "Disable link detection on interface\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - - if_linkdetect(ifp, false); - - return CMD_SUCCESS; -} - int if_shutdown(struct interface *ifp) { struct zebra_if *if_data; @@ -3850,31 +3761,6 @@ int if_shutdown(struct interface *ifp) return 0; } -DEFUN (shutdown_if, - shutdown_if_cmd, - "shutdown", - "Shutdown the selected interface\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - int ret; - struct zebra_if *if_data; - - if (ifp->ifindex != IFINDEX_INTERNAL) { - /* send RA lifetime of 0 before stopping. rfc4861/6.2.5 */ - rtadv_stop_ra(ifp); - ret = if_unset_flags(ifp, IFF_UP); - if (ret < 0) { - vty_out(vty, "Can't shutdown interface\n"); - return CMD_WARNING_CONFIG_FAILED; - } - if_refresh(ifp); - } - if_data = ifp->info; - if_data->shutdown = IF_ZEBRA_DATA_ON; - - return CMD_SUCCESS; -} - int if_no_shutdown(struct interface *ifp) { struct zebra_if *if_data; @@ -3899,961 +3785,56 @@ int if_no_shutdown(struct interface *ifp) return 0; } -DEFUN (no_shutdown_if, - no_shutdown_if_cmd, - "no shutdown", - NO_STR - "Shutdown the selected interface\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - int ret; - struct zebra_if *if_data; - - if (ifp->ifindex != IFINDEX_INTERNAL) { - ret = if_set_flags(ifp, IFF_UP | IFF_RUNNING); - if (ret < 0) { - vty_out(vty, "Can't up interface\n"); - return CMD_WARNING_CONFIG_FAILED; - } - if_refresh(ifp); - - /* Some addresses (in particular, IPv6 addresses on Linux) get - * removed when the interface goes down. They need to be - * readded. - */ - if_addr_wakeup(ifp); - } - - if_data = ifp->info; - if_data->shutdown = IF_ZEBRA_DATA_OFF; - - return CMD_SUCCESS; -} - -DEFUN (bandwidth_if, - bandwidth_if_cmd, - "bandwidth (1-100000)", - "Set bandwidth informational parameter\n" - "Bandwidth in megabits\n") -{ - int idx_number = 1; - VTY_DECLVAR_CONTEXT(interface, ifp); - unsigned int bandwidth; - - bandwidth = strtol(argv[idx_number]->arg, NULL, 10); - - /* bandwidth range is <1-100000> */ - if (bandwidth < 1 || bandwidth > 100000) { - vty_out(vty, "Bandwidth is invalid\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - ifp->bandwidth = bandwidth; - - /* force protocols to recalculate routes due to cost change */ - if (if_is_operative(ifp)) - zebra_interface_up_update(ifp); - - return CMD_SUCCESS; -} - -DEFUN (no_bandwidth_if, - no_bandwidth_if_cmd, - "no bandwidth [(1-100000)]", - NO_STR - "Set bandwidth informational parameter\n" - "Bandwidth in megabits\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - - ifp->bandwidth = 0; - - /* force protocols to recalculate routes due to cost change */ - if (if_is_operative(ifp)) - zebra_interface_up_update(ifp); - - return CMD_SUCCESS; -} - - -struct cmd_node link_params_node = { - .name = "link-params", - .node = LINK_PARAMS_NODE, - .parent_node = INTERFACE_NODE, - .prompt = "%s(config-link-params)# ", - .no_xpath = true, -}; - -static void link_param_cmd_set_uint32(struct interface *ifp, uint32_t *field, - uint32_t type, uint32_t value) +void link_param_cmd_set_uint32(struct interface *ifp, uint32_t *field, + uint32_t type, uint32_t value) { /* Update field as needed */ if (IS_PARAM_UNSET(ifp->link_params, type) || *field != value) { *field = value; SET_PARAM(ifp->link_params, type); - - /* force protocols to update LINK STATE due to parameters change - */ - if (if_is_operative(ifp)) - zebra_interface_parameters_update(ifp); } } -static void link_param_cmd_set_float(struct interface *ifp, float *field, - uint32_t type, float value) -{ +void link_param_cmd_set_float(struct interface *ifp, float *field, + uint32_t type, float value) +{ /* Update field as needed */ if (IS_PARAM_UNSET(ifp->link_params, type) || *field != value) { *field = value; SET_PARAM(ifp->link_params, type); - - /* force protocols to update LINK STATE due to parameters change - */ - if (if_is_operative(ifp)) - zebra_interface_parameters_update(ifp); } } -static void link_param_cmd_unset(struct interface *ifp, uint32_t type) +void link_param_cmd_unset(struct interface *ifp, uint32_t type) { if (ifp->link_params == NULL) return; /* Unset field */ UNSET_PARAM(ifp->link_params, type); - - /* force protocols to update LINK STATE due to parameters change */ - if (if_is_operative(ifp)) - zebra_interface_parameters_update(ifp); -} - -DEFUN_NOSH (link_params, - link_params_cmd, - "link-params", - LINK_PARAMS_STR) -{ - /* vty->qobj_index stays the same @ interface pointer */ - vty->node = LINK_PARAMS_NODE; - - return CMD_SUCCESS; } -DEFUN_NOSH (exit_link_params, - exit_link_params_cmd, - "exit-link-params", - "Exit from Link Params configuration mode\n") -{ - if (vty->node == LINK_PARAMS_NODE) - vty->node = INTERFACE_NODE; - return CMD_SUCCESS; -} - -/* Specific Traffic Engineering parameters commands */ -DEFUN (link_params_enable, - link_params_enable_cmd, - "enable", - "Activate link parameters on this interface\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - - /* This command could be issue at startup, when activate MPLS TE */ - /* on a new interface or after a ON / OFF / ON toggle */ - /* In all case, TE parameters are reset to their default factory */ - if (IS_ZEBRA_DEBUG_EVENT || IS_ZEBRA_DEBUG_MPLS) - zlog_debug( - "Link-params: enable TE link parameters on interface %s", - ifp->name); - - if (!if_link_params_get(ifp)) - if_link_params_enable(ifp); - - /* force protocols to update LINK STATE due to parameters change */ - if (if_is_operative(ifp)) - zebra_interface_parameters_update(ifp); - - return CMD_SUCCESS; -} - -DEFUN (no_link_params_enable, - no_link_params_enable_cmd, - "no enable", - NO_STR - "Disable link parameters on this interface\n") -{ - char xpath[XPATH_MAXLEN]; - int ret; - VTY_DECLVAR_CONTEXT(interface, ifp); - - if (IS_ZEBRA_DEBUG_EVENT || IS_ZEBRA_DEBUG_MPLS) - zlog_debug("MPLS-TE: disable TE link parameters on interface %s", - ifp->name); - - if_link_params_free(ifp); - - snprintf( - xpath, sizeof(xpath), - "/frr-interface:lib/interface[name='%s']/frr-zebra:zebra/link-params/affinities", - ifp->name); - if (yang_dnode_exists(running_config->dnode, xpath)) - nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); - - ret = nb_cli_apply_changes(vty, NULL); - - if (ret != CMD_SUCCESS) - return ret; - - /* force protocols to update LINK STATE due to parameters change */ - if (if_is_operative(ifp)) - zebra_interface_parameters_update(ifp); - - return CMD_SUCCESS; -} - -/* STANDARD TE metrics */ -DEFUN (link_params_metric, - link_params_metric_cmd, - "metric (0-4294967295)", - "Link metric for MPLS-TE purpose\n" - "Metric value in decimal\n") -{ - int idx_number = 1; - VTY_DECLVAR_CONTEXT(interface, ifp); - struct if_link_params *iflp = if_link_params_get(ifp); - uint32_t metric; - - metric = strtoul(argv[idx_number]->arg, NULL, 10); - - if (!iflp) - iflp = if_link_params_enable(ifp); - - /* Update TE metric if needed */ - link_param_cmd_set_uint32(ifp, &iflp->te_metric, LP_TE_METRIC, metric); - - return CMD_SUCCESS; -} - -DEFUN (no_link_params_metric, - no_link_params_metric_cmd, - "no metric", - NO_STR - "Disable Link Metric on this interface\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - - /* Unset TE Metric */ - link_param_cmd_unset(ifp, LP_TE_METRIC); - - return CMD_SUCCESS; -} - -DEFUN (link_params_maxbw, - link_params_maxbw_cmd, - "max-bw BANDWIDTH", - "Maximum bandwidth that can be used\n" - "Bytes/second (IEEE floating point format)\n") -{ - int idx_bandwidth = 1; - VTY_DECLVAR_CONTEXT(interface, ifp); - struct if_link_params *iflp = if_link_params_get(ifp); - - float bw; - - if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) { - vty_out(vty, "link_params_maxbw: fscanf: %s\n", - safe_strerror(errno)); - return CMD_WARNING_CONFIG_FAILED; - } - - /* Check that Maximum bandwidth is not lower than other bandwidth - * parameters */ - if (iflp && ((bw <= iflp->max_rsv_bw) || (bw <= iflp->unrsv_bw[0]) || - (bw <= iflp->unrsv_bw[1]) || (bw <= iflp->unrsv_bw[2]) || - (bw <= iflp->unrsv_bw[3]) || (bw <= iflp->unrsv_bw[4]) || - (bw <= iflp->unrsv_bw[5]) || (bw <= iflp->unrsv_bw[6]) || - (bw <= iflp->unrsv_bw[7]) || (bw <= iflp->ava_bw) || - (bw <= iflp->res_bw) || (bw <= iflp->use_bw))) { - vty_out(vty, - "Maximum Bandwidth could not be lower than others bandwidth\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (!iflp) - iflp = if_link_params_enable(ifp); - - /* Update Maximum Bandwidth if needed */ - link_param_cmd_set_float(ifp, &iflp->max_bw, LP_MAX_BW, bw); - - return CMD_SUCCESS; -} - -DEFUN (link_params_max_rsv_bw, - link_params_max_rsv_bw_cmd, - "max-rsv-bw BANDWIDTH", - "Maximum bandwidth that may be reserved\n" - "Bytes/second (IEEE floating point format)\n") -{ - int idx_bandwidth = 1; - VTY_DECLVAR_CONTEXT(interface, ifp); - struct if_link_params *iflp = if_link_params_get(ifp); - float bw; - - if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) { - vty_out(vty, "link_params_max_rsv_bw: fscanf: %s\n", - safe_strerror(errno)); - return CMD_WARNING_CONFIG_FAILED; - } - - /* Check that bandwidth is not greater than maximum bandwidth parameter - */ - if (iflp && bw > iflp->max_bw) { - vty_out(vty, - "Maximum Reservable Bandwidth could not be greater than Maximum Bandwidth (%g)\n", - iflp->max_bw); - return CMD_WARNING_CONFIG_FAILED; - } - - if (!iflp) - iflp = if_link_params_enable(ifp); - - /* Update Maximum Reservable Bandwidth if needed */ - link_param_cmd_set_float(ifp, &iflp->max_rsv_bw, LP_MAX_RSV_BW, bw); - - return CMD_SUCCESS; -} - -DEFUN (link_params_unrsv_bw, - link_params_unrsv_bw_cmd, - "unrsv-bw (0-7) BANDWIDTH", - "Unreserved bandwidth at each priority level\n" - "Priority\n" - "Bytes/second (IEEE floating point format)\n") -{ - int idx_number = 1; - int idx_bandwidth = 2; - VTY_DECLVAR_CONTEXT(interface, ifp); - struct if_link_params *iflp = if_link_params_get(ifp); - int priority; - float bw; - - /* We don't have to consider about range check here. */ - if (sscanf(argv[idx_number]->arg, "%d", &priority) != 1) { - vty_out(vty, "link_params_unrsv_bw: fscanf: %s\n", - safe_strerror(errno)); - return CMD_WARNING_CONFIG_FAILED; - } - - if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) { - vty_out(vty, "link_params_unrsv_bw: fscanf: %s\n", - safe_strerror(errno)); - return CMD_WARNING_CONFIG_FAILED; - } - - /* Check that bandwidth is not greater than maximum bandwidth parameter - */ - if (iflp && bw > iflp->max_bw) { - vty_out(vty, - "UnReserved Bandwidth could not be greater than Maximum Bandwidth (%g)\n", - iflp->max_bw); - return CMD_WARNING_CONFIG_FAILED; - } - - if (!iflp) - iflp = if_link_params_enable(ifp); - - /* Update Unreserved Bandwidth if needed */ - link_param_cmd_set_float(ifp, &iflp->unrsv_bw[priority], LP_UNRSV_BW, - bw); - - return CMD_SUCCESS; -} - -DEFPY_YANG(link_params_admin_grp, link_params_admin_grp_cmd, - "admin-grp BITPATTERN", - "Administrative group membership\n" - "32-bit Hexadecimal value (e.g. 0xa1)\n") -{ - int idx_bitpattern = 1; - unsigned long value; - char value_str[11]; - - if (sscanf(argv[idx_bitpattern]->arg, "0x%lx", &value) != 1) { - vty_out(vty, "link_params_admin_grp: fscanf: %s\n", - safe_strerror(errno)); - return CMD_WARNING_CONFIG_FAILED; - } - - if (value > 0xFFFFFFFF) { - vty_out(vty, "value must be not be superior to 0xFFFFFFFF\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - snprintf(value_str, sizeof(value_str), "%ld", value); - - nb_cli_enqueue_change( - vty, "./frr-zebra:zebra/link-params/legacy-admin-group", - NB_OP_MODIFY, value_str); - - return nb_cli_apply_changes(vty, NULL); -} - -DEFPY_YANG(no_link_params_admin_grp, no_link_params_admin_grp_cmd, - "no admin-grp", - NO_STR "Disable Administrative group membership on this interface\n") -{ - nb_cli_enqueue_change( - vty, "./frr-zebra:zebra/link-params/legacy-admin-group", - NB_OP_DESTROY, NULL); - - return nb_cli_apply_changes(vty, NULL); -} - -/* RFC5392 & RFC5316: INTER-AS */ -DEFUN (link_params_inter_as, - link_params_inter_as_cmd, - "neighbor A.B.C.D as (1-4294967295)", - "Configure remote ASBR information (Neighbor IP address and AS number)\n" - "Remote IP address in dot decimal A.B.C.D\n" - "Remote AS number\n" - "AS number in the range <1-4294967295>\n") -{ - int idx_ipv4 = 1; - int idx_number = 3; - - VTY_DECLVAR_CONTEXT(interface, ifp); - struct if_link_params *iflp = if_link_params_get(ifp); - struct in_addr addr; - uint32_t as; - - if (!inet_aton(argv[idx_ipv4]->arg, &addr)) { - vty_out(vty, "Please specify Router-Addr by A.B.C.D\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (!iflp) - iflp = if_link_params_enable(ifp); - - as = strtoul(argv[idx_number]->arg, NULL, 10); - - /* Update Remote IP and Remote AS fields if needed */ - if (IS_PARAM_UNSET(iflp, LP_RMT_AS) || iflp->rmt_as != as - || iflp->rmt_ip.s_addr != addr.s_addr) { - - iflp->rmt_as = as; - iflp->rmt_ip.s_addr = addr.s_addr; - SET_PARAM(iflp, LP_RMT_AS); - - /* force protocols to update LINK STATE due to parameters change - */ - if (if_is_operative(ifp)) - zebra_interface_parameters_update(ifp); - } - return CMD_SUCCESS; -} - -DEFUN (no_link_params_inter_as, - no_link_params_inter_as_cmd, - "no neighbor", - NO_STR - "Remove Neighbor IP address and AS number for Inter-AS TE\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - struct if_link_params *iflp = if_link_params_get(ifp); - - if (!iflp) - return CMD_SUCCESS; - - /* Reset Remote IP and AS neighbor */ - iflp->rmt_as = 0; - iflp->rmt_ip.s_addr = 0; - UNSET_PARAM(iflp, LP_RMT_AS); - - /* force protocols to update LINK STATE due to parameters change */ - if (if_is_operative(ifp)) - zebra_interface_parameters_update(ifp); - - return CMD_SUCCESS; -} - -/* RFC7471: OSPF Traffic Engineering (TE) Metric extensions & - * draft-ietf-isis-metric-extensions-07.txt */ -DEFUN (link_params_delay, - link_params_delay_cmd, - "delay (0-16777215) [min (0-16777215) max (0-16777215)]", - "Unidirectional Average Link Delay\n" - "Average delay in micro-second as decimal (0...16777215)\n" - "Minimum delay\n" - "Minimum delay in micro-second as decimal (0...16777215)\n" - "Maximum delay\n" - "Maximum delay in micro-second as decimal (0...16777215)\n") -{ - /* Get and Check new delay values */ - uint32_t delay = 0, low = 0, high = 0; - delay = strtoul(argv[1]->arg, NULL, 10); - if (argc == 6) { - low = strtoul(argv[3]->arg, NULL, 10); - high = strtoul(argv[5]->arg, NULL, 10); - } - - VTY_DECLVAR_CONTEXT(interface, ifp); - struct if_link_params *iflp = if_link_params_get(ifp); - uint8_t update = 0; - - if (argc == 2) { - /* - * Check new delay value against old Min and Max delays if set - * - * RFC 7471 Section 4.2.7: - * It is possible for min delay and max delay to be - * the same value. - * - * Therefore, it is also allowed that the average - * delay be equal to the min delay or max delay. - */ - if (iflp && IS_PARAM_SET(iflp, LP_MM_DELAY) && - (delay < iflp->min_delay || delay > iflp->max_delay)) { - vty_out(vty, - "Average delay should be in range Min (%d) - Max (%d) delay\n", - iflp->min_delay, iflp->max_delay); - return CMD_WARNING_CONFIG_FAILED; - } - - if (!iflp) - iflp = if_link_params_enable(ifp); - - /* Update delay if value is not set or change */ - if (IS_PARAM_UNSET(iflp, LP_DELAY) || iflp->av_delay != delay) { - iflp->av_delay = delay; - SET_PARAM(iflp, LP_DELAY); - update = 1; - } - /* Unset Min and Max delays if already set */ - if (IS_PARAM_SET(iflp, LP_MM_DELAY)) { - iflp->min_delay = 0; - iflp->max_delay = 0; - UNSET_PARAM(iflp, LP_MM_DELAY); - update = 1; - } - } else { - /* - * Check new delays value coherency. See above note - * regarding average delay equal to min/max allowed - */ - if (delay < low || delay > high) { - vty_out(vty, - "Average delay should be in range Min (%d) - Max (%d) delay\n", - low, high); - return CMD_WARNING_CONFIG_FAILED; - } - - if (!iflp) - iflp = if_link_params_enable(ifp); - - /* Update Delays if needed */ - if (IS_PARAM_UNSET(iflp, LP_DELAY) - || IS_PARAM_UNSET(iflp, LP_MM_DELAY) - || iflp->av_delay != delay || iflp->min_delay != low - || iflp->max_delay != high) { - iflp->av_delay = delay; - SET_PARAM(iflp, LP_DELAY); - iflp->min_delay = low; - iflp->max_delay = high; - SET_PARAM(iflp, LP_MM_DELAY); - update = 1; - } - } - - /* force protocols to update LINK STATE due to parameters change */ - if (update == 1 && if_is_operative(ifp)) - zebra_interface_parameters_update(ifp); - - return CMD_SUCCESS; -} - -DEFUN (no_link_params_delay, - no_link_params_delay_cmd, - "no delay", - NO_STR - "Disable Unidirectional Average, Min & Max Link Delay on this interface\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - struct if_link_params *iflp = if_link_params_get(ifp); - - if (!iflp) - return CMD_SUCCESS; - - /* Unset Delays */ - iflp->av_delay = 0; - UNSET_PARAM(iflp, LP_DELAY); - iflp->min_delay = 0; - iflp->max_delay = 0; - UNSET_PARAM(iflp, LP_MM_DELAY); - - /* force protocols to update LINK STATE due to parameters change */ - if (if_is_operative(ifp)) - zebra_interface_parameters_update(ifp); - - return CMD_SUCCESS; -} - -DEFUN (link_params_delay_var, - link_params_delay_var_cmd, - "delay-variation (0-16777215)", - "Unidirectional Link Delay Variation\n" - "delay variation in micro-second as decimal (0...16777215)\n") -{ - int idx_number = 1; - VTY_DECLVAR_CONTEXT(interface, ifp); - struct if_link_params *iflp = if_link_params_get(ifp); - uint32_t value; - - value = strtoul(argv[idx_number]->arg, NULL, 10); - - if (!iflp) - iflp = if_link_params_enable(ifp); - - /* Update Delay Variation if needed */ - link_param_cmd_set_uint32(ifp, &iflp->delay_var, LP_DELAY_VAR, value); - - return CMD_SUCCESS; -} - -DEFUN (no_link_params_delay_var, - no_link_params_delay_var_cmd, - "no delay-variation", - NO_STR - "Disable Unidirectional Delay Variation on this interface\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - - /* Unset Delay Variation */ - link_param_cmd_unset(ifp, LP_DELAY_VAR); - - return CMD_SUCCESS; -} - -DEFUN (link_params_pkt_loss, - link_params_pkt_loss_cmd, - "packet-loss PERCENTAGE", - "Unidirectional Link Packet Loss\n" - "percentage of total traffic by 0.000003% step and less than 50.331642%\n") -{ - int idx_percentage = 1; - VTY_DECLVAR_CONTEXT(interface, ifp); - struct if_link_params *iflp = if_link_params_get(ifp); - float fval; - - if (sscanf(argv[idx_percentage]->arg, "%g", &fval) != 1) { - vty_out(vty, "link_params_pkt_loss: fscanf: %s\n", - safe_strerror(errno)); - return CMD_WARNING_CONFIG_FAILED; - } - - if (fval > MAX_PKT_LOSS) - fval = MAX_PKT_LOSS; - - if (!iflp) - iflp = if_link_params_enable(ifp); - - /* Update Packet Loss if needed */ - link_param_cmd_set_float(ifp, &iflp->pkt_loss, LP_PKT_LOSS, fval); - - return CMD_SUCCESS; -} - -DEFUN (no_link_params_pkt_loss, - no_link_params_pkt_loss_cmd, - "no packet-loss", - NO_STR - "Disable Unidirectional Link Packet Loss on this interface\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - - /* Unset Packet Loss */ - link_param_cmd_unset(ifp, LP_PKT_LOSS); - - return CMD_SUCCESS; -} - -DEFUN (link_params_res_bw, - link_params_res_bw_cmd, - "res-bw BANDWIDTH", - "Unidirectional Residual Bandwidth\n" - "Bytes/second (IEEE floating point format)\n") -{ - int idx_bandwidth = 1; - VTY_DECLVAR_CONTEXT(interface, ifp); - struct if_link_params *iflp = if_link_params_get(ifp); - float bw; - - if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) { - vty_out(vty, "link_params_res_bw: fscanf: %s\n", - safe_strerror(errno)); - return CMD_WARNING_CONFIG_FAILED; - } - - /* Check that bandwidth is not greater than maximum bandwidth parameter - */ - if (iflp && bw > iflp->max_bw) { - vty_out(vty, - "Residual Bandwidth could not be greater than Maximum Bandwidth (%g)\n", - iflp->max_bw); - return CMD_WARNING_CONFIG_FAILED; - } - - if (!iflp) - iflp = if_link_params_enable(ifp); - - /* Update Residual Bandwidth if needed */ - link_param_cmd_set_float(ifp, &iflp->res_bw, LP_RES_BW, bw); - - return CMD_SUCCESS; -} - -DEFUN (no_link_params_res_bw, - no_link_params_res_bw_cmd, - "no res-bw", - NO_STR - "Disable Unidirectional Residual Bandwidth on this interface\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - - /* Unset Residual Bandwidth */ - link_param_cmd_unset(ifp, LP_RES_BW); - - return CMD_SUCCESS; -} - -DEFUN (link_params_ava_bw, - link_params_ava_bw_cmd, - "ava-bw BANDWIDTH", - "Unidirectional Available Bandwidth\n" - "Bytes/second (IEEE floating point format)\n") -{ - int idx_bandwidth = 1; - VTY_DECLVAR_CONTEXT(interface, ifp); - struct if_link_params *iflp = if_link_params_get(ifp); - float bw; - - if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) { - vty_out(vty, "link_params_ava_bw: fscanf: %s\n", - safe_strerror(errno)); - return CMD_WARNING_CONFIG_FAILED; - } - - /* Check that bandwidth is not greater than maximum bandwidth parameter - */ - if (iflp && bw > iflp->max_bw) { - vty_out(vty, - "Available Bandwidth could not be greater than Maximum Bandwidth (%g)\n", - iflp->max_bw); - return CMD_WARNING_CONFIG_FAILED; - } - - if (!iflp) - iflp = if_link_params_enable(ifp); - - /* Update Residual Bandwidth if needed */ - link_param_cmd_set_float(ifp, &iflp->ava_bw, LP_AVA_BW, bw); - - return CMD_SUCCESS; -} - -DEFUN (no_link_params_ava_bw, - no_link_params_ava_bw_cmd, - "no ava-bw", - NO_STR - "Disable Unidirectional Available Bandwidth on this interface\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - - /* Unset Available Bandwidth */ - link_param_cmd_unset(ifp, LP_AVA_BW); - - return CMD_SUCCESS; -} - -DEFUN (link_params_use_bw, - link_params_use_bw_cmd, - "use-bw BANDWIDTH", - "Unidirectional Utilised Bandwidth\n" - "Bytes/second (IEEE floating point format)\n") -{ - int idx_bandwidth = 1; - VTY_DECLVAR_CONTEXT(interface, ifp); - struct if_link_params *iflp = if_link_params_get(ifp); - float bw; - - if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) { - vty_out(vty, "link_params_use_bw: fscanf: %s\n", - safe_strerror(errno)); - return CMD_WARNING_CONFIG_FAILED; - } - - /* Check that bandwidth is not greater than maximum bandwidth parameter - */ - if (iflp && bw > iflp->max_bw) { - vty_out(vty, - "Utilised Bandwidth could not be greater than Maximum Bandwidth (%g)\n", - iflp->max_bw); - return CMD_WARNING_CONFIG_FAILED; - } - - if (!iflp) - iflp = if_link_params_enable(ifp); - - /* Update Utilized Bandwidth if needed */ - link_param_cmd_set_float(ifp, &iflp->use_bw, LP_USE_BW, bw); - - return CMD_SUCCESS; -} - -DEFUN (no_link_params_use_bw, - no_link_params_use_bw_cmd, - "no use-bw", - NO_STR - "Disable Unidirectional Utilised Bandwidth on this interface\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - - /* Unset Utilised Bandwidth */ - link_param_cmd_unset(ifp, LP_USE_BW); - - return CMD_SUCCESS; -} - -static int ag_change(struct vty *vty, int argc, struct cmd_token **argv, - const char *xpath_base, bool no, int start_idx) -{ - char xpath[XPATH_MAXLEN]; - - for (int i = start_idx; i < argc; i++) { - snprintf(xpath, XPATH_MAXLEN, "%s[.='%s']", xpath_base, - argv[i]->arg); - nb_cli_enqueue_change(vty, xpath, - no ? NB_OP_DESTROY : NB_OP_CREATE, NULL); - } - return nb_cli_apply_changes(vty, NULL); -} - -/* - * XPath: - * /frr-interface:lib/interface/frr-zebra:zebra/link-params/affinities/affinity - */ -DEFPY_YANG(link_params_affinity, link_params_affinity_cmd, - "[no] affinity NAME...", - NO_STR - "Interface affinities\n" - "Affinity names\n") -{ - return ag_change(vty, argc, argv, - "./frr-zebra:zebra/link-params/affinities/affinity", - no, no ? 2 : 1); -} - - -/* - * XPath: - * /frr-interface:lib/interface/frr-zebra:zebra/link-params/affinities/affinity-mode - */ -DEFPY_YANG(link_params_affinity_mode, link_params_affinity_mode_cmd, - "affinity-mode <standard|extended|both>$affmode", - "Interface affinity mode\n" - "Standard Admin-Group only RFC3630,5305,5329\n" - "Extended Admin-Group only RFC7308 (default)\n" - "Standard and extended Admin-Group format\n") -{ - const char *xpath = "./frr-zebra:zebra/link-params/affinity-mode"; - - nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, affmode); - - return nb_cli_apply_changes(vty, NULL); -} - -DEFPY_YANG(no_link_params_affinity_mode, no_link_params_affinity_mode_cmd, - "no affinity-mode [<standard|extended|both>]", - NO_STR - "Interface affinity mode\n" - "Standard Admin-Group only RFC3630,5305,5329\n" - "Extended Admin-Group only RFC7308 (default)\n" - "Standard and extended Admin-Group format\n") -{ - const char *xpath = "./frr-zebra:zebra/link-params/affinity-mode"; - - nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, "extended"); - - 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; -} - -void cli_show_legacy_admin_group(struct vty *vty, const struct lyd_node *dnode, - bool show_defaults) -{ - vty_out(vty, " admin-grp 0x%x\n", - yang_dnode_get_uint32(dnode, NULL)); -} - -void cli_show_affinity_mode(struct vty *vty, const struct lyd_node *dnode, - bool show_defaults) -{ - enum affinity_mode affinity_mode = yang_dnode_get_enum(dnode, "."); - - if (affinity_mode == AFFINITY_MODE_STANDARD) - vty_out(vty, " affinity-mode standard\n"); - else if (affinity_mode == AFFINITY_MODE_BOTH) - vty_out(vty, " affinity-mode both\n"); - else if (affinity_mode == AFFINITY_MODE_EXTENDED && show_defaults) - vty_out(vty, " affinity-mode extended\n"); -} - -void cli_show_affinity(struct vty *vty, const struct lyd_node *dnode, - bool show_defaults) -{ - if (!yang_dnode_exists(dnode, "affinity")) - return; - - vty_out(vty, " affinity"); - yang_dnode_iterate(ag_iter_cb, vty, dnode, "affinity"); - vty_out(vty, "\n"); -} - -int if_ip_address_install(struct interface *ifp, struct prefix *prefix, - const char *label, struct prefix *pp) +void if_ip_address_install(struct interface *ifp, struct prefix *prefix, + const char *label, struct prefix *pp) { struct zebra_if *if_data; - struct prefix_ipv4 lp; - struct prefix_ipv4 *p; struct connected *ifc; - enum zebra_dplane_result dplane_res; if_data = ifp->info; - lp.family = prefix->family; - lp.prefix = prefix->u.prefix4; - lp.prefixlen = prefix->prefixlen; - apply_mask_ipv4(&lp); - - ifc = connected_check_ptp(ifp, &lp, pp ? pp : NULL); + ifc = connected_check_ptp(ifp, prefix, pp); if (!ifc) { ifc = connected_new(); ifc->ifp = ifp; /* Address. */ - p = prefix_ipv4_new(); - *p = lp; - ifc->address = (struct prefix *)p; + ifc->address = prefix_new(); + prefix_copy(ifc->address, prefix); if (pp) { SET_FLAG(ifc->flags, ZEBRA_IFA_PEER); - p = prefix_ipv4_new(); - *p = *(struct prefix_ipv4 *)pp; - ifc->destination = (struct prefix *)p; + ifc->destination = prefix_new(); + prefix_copy(ifc->destination, pp); } /* Label. */ @@ -4878,13 +3859,7 @@ int if_ip_address_install(struct interface *ifp, struct prefix *prefix, if_refresh(ifp); } - dplane_res = dplane_intf_addr_set(ifp, ifc); - if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) { - zlog_debug( - "dplane can't set interface IP address: %s.", - dplane_res2str(dplane_res)); - return NB_ERR; - } + dplane_intf_addr_set(ifp, ifc); SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED); /* The address will be advertised to zebra clients when the @@ -4892,127 +3867,16 @@ int if_ip_address_install(struct interface *ifp, struct prefix *prefix, * from the kernel has been received. * It will also be added to the subnet chain list, then. */ } - - return 0; } -static int ip_address_install(struct vty *vty, struct interface *ifp, - const char *addr_str, const char *peer_str, - const char *label) +void if_ip_address_uninstall(struct interface *ifp, struct prefix *prefix, + struct prefix *pp) { - struct zebra_if *if_data; - struct prefix_ipv4 lp, pp; struct connected *ifc; - struct prefix_ipv4 *p; - int ret; - enum zebra_dplane_result dplane_res; - - if_data = ifp->info; - - ret = str2prefix_ipv4(addr_str, &lp); - if (ret <= 0) { - vty_out(vty, "%% Malformed address \n"); - return CMD_WARNING_CONFIG_FAILED; - } - if (ipv4_martian(&lp.prefix)) { - vty_out(vty, "%% Invalid address\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (peer_str) { - if (lp.prefixlen != IPV4_MAX_BITLEN) { - vty_out(vty, - "%% Local prefix length for P-t-P address must be /32\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - ret = str2prefix_ipv4(peer_str, &pp); - if (ret <= 0) { - vty_out(vty, "%% Malformed peer address\n"); - return CMD_WARNING_CONFIG_FAILED; - } - } - - ifc = connected_check_ptp(ifp, &lp, peer_str ? &pp : NULL); - if (!ifc) { - ifc = connected_new(); - ifc->ifp = ifp; - - /* Address. */ - p = prefix_ipv4_new(); - *p = lp; - ifc->address = (struct prefix *)p; - - if (peer_str) { - SET_FLAG(ifc->flags, ZEBRA_IFA_PEER); - p = prefix_ipv4_new(); - *p = pp; - ifc->destination = (struct prefix *)p; - } - - /* Label. */ - if (label) - ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label); - - /* Add to linked list. */ - if_connected_add_tail(ifp->connected, ifc); - } - - /* This address is configured from zebra. */ - if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED)) - SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED); - - /* In case of this route need to install kernel. */ - if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED) && - CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE) && - !(if_data && if_data->shutdown == IF_ZEBRA_DATA_ON)) { - /* Some system need to up the interface to set IP address. */ - if (!if_is_up(ifp)) { - if_set_flags(ifp, IFF_UP | IFF_RUNNING); - if_refresh(ifp); - } - - dplane_res = dplane_intf_addr_set(ifp, ifc); - if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) { - vty_out(vty, "%% Can't set interface IP address: %s.\n", - dplane_res2str(dplane_res)); - return CMD_WARNING_CONFIG_FAILED; - } + ifc = connected_check_ptp(ifp, prefix, pp); + assert(ifc); - SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED); - /* The address will be advertised to zebra clients when the - * notification - * from the kernel has been received. - * It will also be added to the subnet chain list, then. */ - } - - return CMD_SUCCESS; -} - -int if_ip_address_uinstall(struct interface *ifp, struct prefix *prefix) -{ - struct connected *ifc = NULL; - enum zebra_dplane_result dplane_res; - - if (prefix->family == AF_INET) { - /* Check current interface address. */ - ifc = connected_check_ptp(ifp, prefix, NULL); - if (!ifc) { - zlog_debug("interface %s Can't find address", - ifp->name); - return -1; - } - - } else if (prefix->family == AF_INET6) { - /* Check current interface address. */ - ifc = connected_check(ifp, prefix); - } - - if (!ifc) { - zlog_debug("interface %s Can't find address", ifp->name); - return -1; - } UNSET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED); /* This is not real address or interface is not active. */ @@ -5020,276 +3884,30 @@ int if_ip_address_uinstall(struct interface *ifp, struct prefix *prefix) || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) { if_connected_del(ifp->connected, ifc); connected_free(&ifc); - return CMD_WARNING_CONFIG_FAILED; + return; } /* This is real route. */ - dplane_res = dplane_intf_addr_unset(ifp, ifc); - if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) { - zlog_debug("Can't unset interface IP address: %s.", - dplane_res2str(dplane_res)); - return -1; - } - UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED); - - return 0; -} - -static int ip_address_uninstall(struct vty *vty, struct interface *ifp, - const char *addr_str, const char *peer_str, - const char *label) -{ - struct prefix_ipv4 lp, pp; - struct connected *ifc; - int ret; - enum zebra_dplane_result dplane_res; - - /* Convert to prefix structure. */ - ret = str2prefix_ipv4(addr_str, &lp); - if (ret <= 0) { - vty_out(vty, "%% Malformed address \n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (peer_str) { - if (lp.prefixlen != IPV4_MAX_BITLEN) { - vty_out(vty, - "%% Local prefix length for P-t-P address must be /32\n"); - return CMD_WARNING_CONFIG_FAILED; - } + dplane_intf_addr_unset(ifp, ifc); - ret = str2prefix_ipv4(peer_str, &pp); - if (ret <= 0) { - vty_out(vty, "%% Malformed peer address\n"); - return CMD_WARNING_CONFIG_FAILED; - } - } - - /* Check current interface address. */ - ifc = connected_check_ptp(ifp, &lp, peer_str ? &pp : NULL); - if (!ifc) { - vty_out(vty, "%% Can't find address\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - /* This is not configured address. */ - if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED)) - return CMD_WARNING_CONFIG_FAILED; - - UNSET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED); - - /* This is not real address or interface is not active. */ - if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED) - || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) { - if_connected_del(ifp->connected, ifc); - connected_free(&ifc); - return CMD_WARNING_CONFIG_FAILED; - } - - /* This is real route. */ - dplane_res = dplane_intf_addr_unset(ifp, ifc); - if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) { - vty_out(vty, "%% Can't unset interface IP address: %s.\n", - dplane_res2str(dplane_res)); - return CMD_WARNING_CONFIG_FAILED; - } UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED); - /* we will receive a kernel notification about this route being removed. - * this will trigger its removal from the connected list. */ - return CMD_SUCCESS; -} - -DEFUN (ip_address, - ip_address_cmd, - "ip address A.B.C.D/M", - "Interface Internet Protocol config commands\n" - "Set the IP address of an interface\n" - "IP address (e.g. 10.0.0.1/8)\n") -{ - int idx_ipv4_prefixlen = 2; - VTY_DECLVAR_CONTEXT(interface, ifp); - return ip_address_install(vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL, - NULL); -} - -DEFUN (no_ip_address, - no_ip_address_cmd, - "no ip address A.B.C.D/M", - NO_STR - "Interface Internet Protocol config commands\n" - "Set the IP address of an interface\n" - "IP Address (e.g. 10.0.0.1/8)\n") -{ - int idx_ipv4_prefixlen = 3; - VTY_DECLVAR_CONTEXT(interface, ifp); - return ip_address_uninstall(vty, ifp, argv[idx_ipv4_prefixlen]->arg, - NULL, NULL); -} - -DEFUN(ip_address_peer, - ip_address_peer_cmd, - "ip address A.B.C.D peer A.B.C.D/M", - "Interface Internet Protocol config commands\n" - "Set the IP address of an interface\n" - "Local IP (e.g. 10.0.0.1) for P-t-P address\n" - "Specify P-t-P address\n" - "Peer IP address (e.g. 10.0.0.1/8)\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - return ip_address_install(vty, ifp, argv[2]->arg, argv[4]->arg, NULL); -} - -DEFUN(no_ip_address_peer, - no_ip_address_peer_cmd, - "no ip address A.B.C.D peer A.B.C.D/M", - NO_STR - "Interface Internet Protocol config commands\n" - "Set the IP address of an interface\n" - "Local IP (e.g. 10.0.0.1) for P-t-P address\n" - "Specify P-t-P address\n" - "Peer IP address (e.g. 10.0.0.1/8)\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - return ip_address_uninstall(vty, ifp, argv[3]->arg, argv[5]->arg, NULL); -} - -#ifdef HAVE_NETLINK -DEFUN (ip_address_label, - ip_address_label_cmd, - "ip address A.B.C.D/M label LINE", - "Interface Internet Protocol config commands\n" - "Set the IP address of an interface\n" - "IP address (e.g. 10.0.0.1/8)\n" - "Label of this address\n" - "Label\n") -{ - int idx_ipv4_prefixlen = 2; - int idx_line = 4; - VTY_DECLVAR_CONTEXT(interface, ifp); - return ip_address_install(vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL, - argv[idx_line]->arg); -} - -DEFUN (no_ip_address_label, - no_ip_address_label_cmd, - "no ip address A.B.C.D/M label LINE", - NO_STR - "Interface Internet Protocol config commands\n" - "Set the IP address of an interface\n" - "IP address (e.g. 10.0.0.1/8)\n" - "Label of this address\n" - "Label\n") -{ - int idx_ipv4_prefixlen = 3; - int idx_line = 5; - VTY_DECLVAR_CONTEXT(interface, ifp); - return ip_address_uninstall(vty, ifp, argv[idx_ipv4_prefixlen]->arg, - NULL, argv[idx_line]->arg); -} -#endif /* HAVE_NETLINK */ - -int if_ipv6_address_install(struct interface *ifp, struct prefix *prefix, - const char *label) -{ - struct zebra_if *if_data; - struct prefix_ipv6 cp; - struct connected *ifc; - struct prefix_ipv6 *p; - enum zebra_dplane_result dplane_res; - - if_data = ifp->info; - - cp.family = prefix->family; - cp.prefixlen = prefix->prefixlen; - cp.prefix = prefix->u.prefix6; - apply_mask_ipv6(&cp); - - ifc = connected_check(ifp, (struct prefix *)&cp); - if (!ifc) { - ifc = connected_new(); - ifc->ifp = ifp; - - /* Address. */ - p = prefix_ipv6_new(); - *p = cp; - ifc->address = (struct prefix *)p; - - /* Label. */ - if (label) - ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label); - - /* Add to linked list. */ - if_connected_add_tail(ifp->connected, ifc); - } - - /* This address is configured from zebra. */ - if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED)) - SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED); - - /* In case of this route need to install kernel. */ - if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED) && - CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE) && - !(if_data && if_data->shutdown == IF_ZEBRA_DATA_ON)) { - /* Some system need to up the interface to set IP address. */ - if (!if_is_up(ifp)) { - if_set_flags(ifp, IFF_UP | IFF_RUNNING); - if_refresh(ifp); - } - - dplane_res = dplane_intf_addr_set(ifp, ifc); - if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) { - zlog_debug( - "dplane can't set interface IP address: %s.", - dplane_res2str(dplane_res)); - return NB_ERR; - } - - SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED); - /* The address will be advertised to zebra clients when the - * notification - * from the kernel has been received. */ - } - - return 0; } -static int ipv6_address_install(struct vty *vty, struct interface *ifp, - const char *addr_str, const char *peer_str, - const char *label) +void if_ipv6_address_install(struct interface *ifp, struct prefix *prefix) { struct zebra_if *if_data; - struct prefix_ipv6 cp; struct connected *ifc; - struct prefix_ipv6 *p; - int ret; - enum zebra_dplane_result dplane_res; if_data = ifp->info; - ret = str2prefix_ipv6(addr_str, &cp); - if (ret <= 0) { - vty_out(vty, "%% Malformed address \n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (ipv6_martian(&cp.prefix)) { - vty_out(vty, "%% Invalid address\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - ifc = connected_check(ifp, (struct prefix *)&cp); + ifc = connected_check(ifp, prefix); if (!ifc) { ifc = connected_new(); ifc->ifp = ifp; /* Address. */ - p = prefix_ipv6_new(); - *p = cp; - ifc->address = (struct prefix *)p; - - /* Label. */ - if (label) - ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label); + ifc->address = prefix_new(); + prefix_copy(ifc->address, prefix); /* Add to linked list. */ if_connected_add_tail(ifp->connected, ifc); @@ -5309,48 +3927,21 @@ static int ipv6_address_install(struct vty *vty, struct interface *ifp, if_refresh(ifp); } - dplane_res = dplane_intf_addr_set(ifp, ifc); - if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) { - vty_out(vty, "%% Can't set interface IP address: %s.\n", - dplane_res2str(dplane_res)); - return CMD_WARNING_CONFIG_FAILED; - } + dplane_intf_addr_set(ifp, ifc); SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED); /* The address will be advertised to zebra clients when the * notification * from the kernel has been received. */ } - - return CMD_SUCCESS; } -static int ipv6_address_uninstall(struct vty *vty, struct interface *ifp, - const char *addr_str, const char *peer_str, - const char *label) +void if_ipv6_address_uninstall(struct interface *ifp, struct prefix *prefix) { - struct prefix_ipv6 cp; struct connected *ifc; - int ret; - enum zebra_dplane_result dplane_res; - - /* Convert to prefix structure. */ - ret = str2prefix_ipv6(addr_str, &cp); - if (ret <= 0) { - vty_out(vty, "%% Malformed address \n"); - return CMD_WARNING_CONFIG_FAILED; - } - /* Check current interface address. */ - ifc = connected_check(ifp, (struct prefix *)&cp); - if (!ifc) { - vty_out(vty, "%% Can't find address\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - /* This is not configured address. */ - if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED)) - return CMD_WARNING_CONFIG_FAILED; + ifc = connected_check(ifp, prefix); + assert(ifc); UNSET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED); @@ -5359,199 +3950,13 @@ static int ipv6_address_uninstall(struct vty *vty, struct interface *ifp, || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) { if_connected_del(ifp->connected, ifc); connected_free(&ifc); - return CMD_WARNING_CONFIG_FAILED; + return; } /* This is real route. */ - dplane_res = dplane_intf_addr_unset(ifp, ifc); - if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) { - vty_out(vty, "%% Can't unset interface IP address: %s.\n", - dplane_res2str(dplane_res)); - return CMD_WARNING_CONFIG_FAILED; - } + dplane_intf_addr_unset(ifp, ifc); UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED); - /* This information will be propagated to the zclients when the - * kernel notification is received. */ - return CMD_SUCCESS; -} - -DEFUN (ipv6_address, - ipv6_address_cmd, - "ipv6 address X:X::X:X/M", - "Interface IPv6 config commands\n" - "Set the IP address of an interface\n" - "IPv6 address (e.g. 3ffe:506::1/48)\n") -{ - int idx_ipv6_prefixlen = 2; - VTY_DECLVAR_CONTEXT(interface, ifp); - return ipv6_address_install(vty, ifp, argv[idx_ipv6_prefixlen]->arg, - NULL, NULL); -} - -DEFUN (no_ipv6_address, - no_ipv6_address_cmd, - "no ipv6 address X:X::X:X/M", - NO_STR - "Interface IPv6 config commands\n" - "Set the IP address of an interface\n" - "IPv6 address (e.g. 3ffe:506::1/48)\n") -{ - int idx_ipv6_prefixlen = 3; - VTY_DECLVAR_CONTEXT(interface, ifp); - return ipv6_address_uninstall(vty, ifp, argv[idx_ipv6_prefixlen]->arg, - NULL, NULL); -} - -static int link_params_config_write(struct vty *vty, struct interface *ifp) -{ - const struct lyd_node *dnode; - char xpath[XPATH_MAXLEN]; - int i; - - if ((ifp == NULL) || !HAS_LINK_PARAMS(ifp)) - return -1; - - struct if_link_params *iflp = ifp->link_params; - - vty_out(vty, " link-params\n"); - vty_out(vty, " enable\n"); - if (IS_PARAM_SET(iflp, LP_TE_METRIC) && iflp->te_metric != ifp->metric) - vty_out(vty, " metric %u\n", iflp->te_metric); - if (IS_PARAM_SET(iflp, LP_MAX_BW) && iflp->max_bw != iflp->default_bw) - vty_out(vty, " max-bw %g\n", iflp->max_bw); - if (IS_PARAM_SET(iflp, LP_MAX_RSV_BW) - && iflp->max_rsv_bw != iflp->default_bw) - vty_out(vty, " max-rsv-bw %g\n", iflp->max_rsv_bw); - if (IS_PARAM_SET(iflp, LP_UNRSV_BW)) { - for (i = 0; i < 8; i++) - if (iflp->unrsv_bw[i] != iflp->default_bw) - vty_out(vty, " unrsv-bw %d %g\n", i, - iflp->unrsv_bw[i]); - } - - snprintf( - xpath, sizeof(xpath), - "/frr-interface:lib/interface[name='%s']/frr-zebra:zebra/link-params", - ifp->name); - dnode = yang_dnode_get(running_config->dnode, xpath); - if (dnode) - nb_cli_show_dnode_cmds(vty, dnode, false); - - if (IS_PARAM_SET(iflp, LP_DELAY)) { - vty_out(vty, " delay %u", iflp->av_delay); - if (IS_PARAM_SET(iflp, LP_MM_DELAY)) { - vty_out(vty, " min %u", iflp->min_delay); - vty_out(vty, " max %u", iflp->max_delay); - } - vty_out(vty, "\n"); - } - if (IS_PARAM_SET(iflp, LP_DELAY_VAR)) - vty_out(vty, " delay-variation %u\n", iflp->delay_var); - if (IS_PARAM_SET(iflp, LP_PKT_LOSS)) - vty_out(vty, " packet-loss %g\n", iflp->pkt_loss); - if (IS_PARAM_SET(iflp, LP_AVA_BW)) - vty_out(vty, " ava-bw %g\n", iflp->ava_bw); - if (IS_PARAM_SET(iflp, LP_RES_BW)) - vty_out(vty, " res-bw %g\n", iflp->res_bw); - if (IS_PARAM_SET(iflp, LP_USE_BW)) - vty_out(vty, " use-bw %g\n", iflp->use_bw); - if (IS_PARAM_SET(iflp, LP_RMT_AS)) - vty_out(vty, " neighbor %pI4 as %u\n", &iflp->rmt_ip, - iflp->rmt_as); - - vty_out(vty, " exit-link-params\n"); - return 0; -} - -static int if_config_write(struct vty *vty) -{ - struct vrf *vrf; - struct interface *ifp; - - zebra_ptm_write(vty); - - RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) - FOR_ALL_INTERFACES (vrf, ifp) { - struct zebra_if *if_data; - struct connected *ifc; - struct prefix *p; - - if_data = ifp->info; - - if_vty_config_start(vty, ifp); - - if (if_data) { - if (if_data->shutdown == IF_ZEBRA_DATA_ON) - vty_out(vty, " shutdown\n"); - - zebra_ptm_if_write(vty, if_data); - } - - if (ifp->desc) - vty_out(vty, " description %s\n", ifp->desc); - - /* Assign bandwidth here to avoid unnecessary interface - flap - while processing config script */ - if (ifp->bandwidth != 0) - vty_out(vty, " bandwidth %u\n", ifp->bandwidth); - - if (!CHECK_FLAG(ifp->status, - ZEBRA_INTERFACE_LINKDETECTION)) - vty_out(vty, " no link-detect\n"); - - frr_each (if_connected, ifp->connected, ifc) { - if (CHECK_FLAG(ifc->conf, - ZEBRA_IFC_CONFIGURED)) { - char buf[INET6_ADDRSTRLEN]; - p = ifc->address; - vty_out(vty, " ip%s address %s", - p->family == AF_INET ? "" - : "v6", - inet_ntop(p->family, - &p->u.prefix, buf, - sizeof(buf))); - if (CONNECTED_PEER(ifc)) { - p = ifc->destination; - vty_out(vty, " peer %s", - inet_ntop(p->family, - &p->u.prefix, - buf, - sizeof(buf))); - } - vty_out(vty, "/%d", p->prefixlen); - - if (ifc->label) - vty_out(vty, " label %s", - ifc->label); - - vty_out(vty, "\n"); - } - } - - if (if_data) { - if (if_data->multicast != IF_ZEBRA_DATA_UNSPEC) - vty_out(vty, " %smulticast\n", - if_data->multicast == - IF_ZEBRA_DATA_ON - ? "" - : "no "); - - if (if_data->mpls_config == IF_ZEBRA_DATA_ON) - vty_out(vty, " mpls enable\n"); - else if (if_data->mpls_config == - IF_ZEBRA_DATA_OFF) - vty_out(vty, " mpls disable\n"); - } - - hook_call(zebra_if_config_wr, vty, ifp); - zebra_evpn_mh_if_write(vty, ifp); - link_params_config_write(vty, ifp); - - if_vty_config_end(vty); - } - return 0; } /* Allocate and initialize interface vector. */ @@ -5561,10 +3966,6 @@ void zebra_if_init(void) hook_register_prio(if_add, 0, if_zebra_new_hook); hook_register_prio(if_del, 0, if_zebra_delete_hook); - /* Install configuration write function. */ - if_cmd_init(if_config_write); - install_node(&link_params_node); - install_element(VIEW_NODE, &show_interface_cmd); install_element(VIEW_NODE, &show_interface_vrf_all_cmd); install_element(VIEW_NODE, &show_interface_name_vrf_cmd); @@ -5572,55 +3973,4 @@ void zebra_if_init(void) install_element(ENABLE_NODE, &show_interface_desc_cmd); install_element(ENABLE_NODE, &show_interface_desc_vrf_all_cmd); - install_element(INTERFACE_NODE, &multicast_cmd); - install_element(INTERFACE_NODE, &no_multicast_cmd); - install_element(INTERFACE_NODE, &mpls_cmd); - install_element(INTERFACE_NODE, &linkdetect_cmd); - install_element(INTERFACE_NODE, &no_linkdetect_cmd); - install_element(INTERFACE_NODE, &shutdown_if_cmd); - install_element(INTERFACE_NODE, &no_shutdown_if_cmd); - install_element(INTERFACE_NODE, &bandwidth_if_cmd); - install_element(INTERFACE_NODE, &no_bandwidth_if_cmd); - install_element(INTERFACE_NODE, &ip_address_cmd); - install_element(INTERFACE_NODE, &no_ip_address_cmd); - install_element(INTERFACE_NODE, &ip_address_peer_cmd); - install_element(INTERFACE_NODE, &no_ip_address_peer_cmd); - install_element(INTERFACE_NODE, &ipv6_address_cmd); - install_element(INTERFACE_NODE, &no_ipv6_address_cmd); -#ifdef HAVE_NETLINK - install_element(INTERFACE_NODE, &ip_address_label_cmd); - install_element(INTERFACE_NODE, &no_ip_address_label_cmd); -#endif /* HAVE_NETLINK */ - install_element(INTERFACE_NODE, &link_params_cmd); - install_default(LINK_PARAMS_NODE); - install_element(LINK_PARAMS_NODE, &link_params_enable_cmd); - install_element(LINK_PARAMS_NODE, &no_link_params_enable_cmd); - install_element(LINK_PARAMS_NODE, &link_params_metric_cmd); - install_element(LINK_PARAMS_NODE, &no_link_params_metric_cmd); - install_element(LINK_PARAMS_NODE, &link_params_maxbw_cmd); - install_element(LINK_PARAMS_NODE, &link_params_max_rsv_bw_cmd); - install_element(LINK_PARAMS_NODE, &link_params_unrsv_bw_cmd); - install_element(LINK_PARAMS_NODE, &link_params_admin_grp_cmd); - install_element(LINK_PARAMS_NODE, &no_link_params_admin_grp_cmd); - install_element(LINK_PARAMS_NODE, &link_params_inter_as_cmd); - install_element(LINK_PARAMS_NODE, &no_link_params_inter_as_cmd); - install_element(LINK_PARAMS_NODE, &link_params_delay_cmd); - install_element(LINK_PARAMS_NODE, &no_link_params_delay_cmd); - install_element(LINK_PARAMS_NODE, &link_params_delay_var_cmd); - install_element(LINK_PARAMS_NODE, &no_link_params_delay_var_cmd); - install_element(LINK_PARAMS_NODE, &link_params_pkt_loss_cmd); - install_element(LINK_PARAMS_NODE, &no_link_params_pkt_loss_cmd); - install_element(LINK_PARAMS_NODE, &link_params_ava_bw_cmd); - install_element(LINK_PARAMS_NODE, &no_link_params_ava_bw_cmd); - install_element(LINK_PARAMS_NODE, &link_params_res_bw_cmd); - install_element(LINK_PARAMS_NODE, &no_link_params_res_bw_cmd); - install_element(LINK_PARAMS_NODE, &link_params_use_bw_cmd); - install_element(LINK_PARAMS_NODE, &no_link_params_use_bw_cmd); - install_element(LINK_PARAMS_NODE, &link_params_affinity_cmd); - install_element(LINK_PARAMS_NODE, &link_params_affinity_mode_cmd); - install_element(LINK_PARAMS_NODE, &no_link_params_affinity_mode_cmd); - install_element(LINK_PARAMS_NODE, &exit_link_params_cmd); - - /* setup EVPN MH elements */ - zebra_evpn_interface_init(); } diff --git a/zebra/interface.h b/zebra/interface.h index a96f2ec718..fc6850e80e 100644 --- a/zebra/interface.h +++ b/zebra/interface.h @@ -218,8 +218,6 @@ struct zebra_if { DECLARE_HOOK(zebra_if_extra_info, (struct vty * vty, struct interface *ifp), (vty, ifp)); -DECLARE_HOOK(zebra_if_config_wr, (struct vty * vty, struct interface *ifp), - (vty, ifp)); #define IS_ZEBRA_IF_VRF(ifp) \ (((struct zebra_if *)(ifp->info))->zif_type == ZEBRA_IF_VRF) @@ -307,11 +305,14 @@ extern void cli_show_affinity(struct vty *vty, const struct lyd_node *dnode, */ extern int zebra_if_set_protodown(struct interface *ifp, bool down, enum protodown_reasons new_reason); -extern int if_ip_address_install(struct interface *ifp, struct prefix *prefix, - const char *label, struct prefix *pp); -extern int if_ipv6_address_install(struct interface *ifp, struct prefix *prefix, - const char *label); -extern int if_ip_address_uinstall(struct interface *ifp, struct prefix *prefix); +extern void if_ip_address_install(struct interface *ifp, struct prefix *prefix, + const char *label, struct prefix *pp); +extern void if_ip_address_uninstall(struct interface *ifp, + struct prefix *prefix, struct prefix *pp); +extern void if_ipv6_address_install(struct interface *ifp, + struct prefix *prefix); +extern void if_ipv6_address_uninstall(struct interface *ifp, + struct prefix *prefix); extern int if_shutdown(struct interface *ifp); extern int if_no_shutdown(struct interface *ifp); extern void if_arp(struct interface *ifp, bool enable); @@ -320,6 +321,12 @@ extern int if_multicast_unset(struct interface *ifp); extern int if_linkdetect(struct interface *ifp, bool detect); extern void if_addr_wakeup(struct interface *ifp); +void link_param_cmd_set_uint32(struct interface *ifp, uint32_t *field, + uint32_t type, uint32_t value); +void link_param_cmd_set_float(struct interface *ifp, float *field, + uint32_t type, float value); +void link_param_cmd_unset(struct interface *ifp, uint32_t type); + /* Nexthop group connected functions */ extern void if_nhg_dependents_add(struct interface *ifp, struct nhg_hash_entry *nhe); diff --git a/zebra/irdp_interface.c b/zebra/irdp_interface.c index 591236d680..70f3f57ae0 100644 --- a/zebra/irdp_interface.c +++ b/zebra/irdp_interface.c @@ -694,7 +694,6 @@ DEFUN (ip_irdp_debug_disable, void irdp_if_init(void) { - hook_register(zebra_if_config_wr, irdp_config_write); hook_register(if_del, irdp_if_delete); install_element(INTERFACE_NODE, &ip_irdp_broadcast_cmd); diff --git a/zebra/main.c b/zebra/main.c index 47aef46cac..606ecc7279 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -442,7 +442,7 @@ int main(int argc, char **argv) zebra_vty_init(); mgmt_be_client = mgmt_be_client_create("zebra", NULL, 0, zrouter.master); - access_list_init(); + access_list_init_new(true); prefix_list_init(); rtadv_init(); diff --git a/zebra/router-id.c b/zebra/router-id.c index ef87d924fe..2f251a79e5 100644 --- a/zebra/router-id.c +++ b/zebra/router-id.c @@ -109,7 +109,7 @@ int router_id_get(afi_t afi, struct prefix *p, struct zebra_vrf *zvrf) assert(!"Reached end of function we should never hit"); } -static int router_id_set(afi_t afi, struct prefix *p, struct zebra_vrf *zvrf) +int router_id_set(afi_t afi, struct prefix *p, struct zebra_vrf *zvrf) { struct prefix after, before; struct listnode *node; @@ -241,256 +241,6 @@ void router_id_del_address(struct connected *ifc) zsend_router_id_update(client, afi, &after, zvrf_id(zvrf)); } -void router_id_write(struct vty *vty, struct zebra_vrf *zvrf) -{ - char space[2]; - - memset(space, 0, sizeof(space)); - - if (zvrf_id(zvrf) != VRF_DEFAULT) - snprintf(space, sizeof(space), "%s", " "); - - if (zvrf->rid_user_assigned.u.prefix4.s_addr != INADDR_ANY) { - vty_out(vty, "%sip router-id %pI4\n", space, - &zvrf->rid_user_assigned.u.prefix4); - } - if (!router_id_v6_is_any(&zvrf->rid6_user_assigned)) { - vty_out(vty, "%sipv6 router-id %pI6\n", space, - &zvrf->rid_user_assigned.u.prefix6); - } -} - -DEFUN (ip_router_id, - ip_router_id_cmd, - "ip router-id A.B.C.D vrf NAME", - IP_STR - "Manually set the router-id\n" - "IP address to use for router-id\n" - VRF_CMD_HELP_STR) -{ - int idx = 0; - struct prefix rid; - vrf_id_t vrf_id; - struct zebra_vrf *zvrf; - - argv_find(argv, argc, "A.B.C.D", &idx); - - if (!inet_pton(AF_INET, argv[idx]->arg, &rid.u.prefix4)) - return CMD_WARNING_CONFIG_FAILED; - - rid.prefixlen = IPV4_MAX_BITLEN; - rid.family = AF_INET; - - argv_find(argv, argc, "NAME", &idx); - VRF_GET_ID(vrf_id, argv[idx]->arg, false); - - zvrf = zebra_vrf_lookup_by_id(vrf_id); - router_id_set(AFI_IP, &rid, zvrf); - - return CMD_SUCCESS; -} - -ALIAS (ip_router_id, - router_id_cmd, - "router-id A.B.C.D vrf NAME", - "Manually set the router-id\n" - "IP address to use for router-id\n" - VRF_CMD_HELP_STR); - -DEFUN (ipv6_router_id, - ipv6_router_id_cmd, - "ipv6 router-id X:X::X:X vrf NAME", - IPV6_STR - "Manually set the router-id\n" - "IPv6 address to use for router-id\n" - VRF_CMD_HELP_STR) -{ - int idx = 0; - struct prefix rid; - vrf_id_t vrf_id; - struct zebra_vrf *zvrf; - - argv_find(argv, argc, "X:X::X:X", &idx); - - if (!inet_pton(AF_INET6, argv[idx]->arg, &rid.u.prefix6)) - return CMD_WARNING_CONFIG_FAILED; - - rid.prefixlen = IPV6_MAX_BITLEN; - rid.family = AF_INET6; - - argv_find(argv, argc, "NAME", &idx); - VRF_GET_ID(vrf_id, argv[idx]->arg, false); - - zvrf = zebra_vrf_lookup_by_id(vrf_id); - router_id_set(AFI_IP6, &rid, zvrf); - - return CMD_SUCCESS; -} - - -DEFUN (ip_router_id_in_vrf, - ip_router_id_in_vrf_cmd, - "ip router-id A.B.C.D", - IP_STR - "Manually set the router-id\n" - "IP address to use for router-id\n") -{ - ZEBRA_DECLVAR_CONTEXT_VRF(vrf, zvrf); - int idx = 0; - struct prefix rid; - - argv_find(argv, argc, "A.B.C.D", &idx); - - if (!inet_pton(AF_INET, argv[idx]->arg, &rid.u.prefix4)) - return CMD_WARNING_CONFIG_FAILED; - - rid.prefixlen = IPV4_MAX_BITLEN; - rid.family = AF_INET; - - router_id_set(AFI_IP, &rid, zvrf); - - return CMD_SUCCESS; -} - -ALIAS (ip_router_id_in_vrf, - router_id_in_vrf_cmd, - "router-id A.B.C.D", - "Manually set the router-id\n" - "IP address to use for router-id\n"); - -DEFUN (ipv6_router_id_in_vrf, - ipv6_router_id_in_vrf_cmd, - "ipv6 router-id X:X::X:X", - IP6_STR - "Manually set the IPv6 router-id\n" - "IPV6 address to use for router-id\n") -{ - ZEBRA_DECLVAR_CONTEXT_VRF(vrf, zvrf); - int idx = 0; - struct prefix rid; - - argv_find(argv, argc, "X:X::X:X", &idx); - - if (!inet_pton(AF_INET6, argv[idx]->arg, &rid.u.prefix6)) - return CMD_WARNING_CONFIG_FAILED; - - rid.prefixlen = IPV6_MAX_BITLEN; - rid.family = AF_INET6; - - router_id_set(AFI_IP6, &rid, zvrf); - - return CMD_SUCCESS; -} - -DEFUN (no_ip_router_id, - no_ip_router_id_cmd, - "no ip router-id [A.B.C.D vrf NAME]", - NO_STR - IP_STR - "Remove the manually configured router-id\n" - "IP address to use for router-id\n" - VRF_CMD_HELP_STR) -{ - int idx = 0; - struct prefix rid; - vrf_id_t vrf_id = VRF_DEFAULT; - struct zebra_vrf *zvrf; - - rid.u.prefix4.s_addr = 0; - rid.prefixlen = 0; - rid.family = AF_INET; - - if (argv_find(argv, argc, "NAME", &idx)) - VRF_GET_ID(vrf_id, argv[idx]->arg, false); - - zvrf = zebra_vrf_lookup_by_id(vrf_id); - router_id_set(AFI_IP, &rid, zvrf); - - return CMD_SUCCESS; -} - -ALIAS (no_ip_router_id, - no_router_id_cmd, - "no router-id [A.B.C.D vrf NAME]", - NO_STR - "Remove the manually configured router-id\n" - "IP address to use for router-id\n" - VRF_CMD_HELP_STR); - -DEFUN (no_ipv6_router_id, - no_ipv6_router_id_cmd, - "no ipv6 router-id [X:X::X:X vrf NAME]", - NO_STR - IPV6_STR - "Remove the manually configured IPv6 router-id\n" - "IPv6 address to use for router-id\n" - VRF_CMD_HELP_STR) -{ - int idx = 0; - struct prefix rid; - vrf_id_t vrf_id = VRF_DEFAULT; - struct zebra_vrf *zvrf; - - memset(&rid, 0, sizeof(rid)); - rid.family = AF_INET; - - if (argv_find(argv, argc, "NAME", &idx)) - VRF_GET_ID(vrf_id, argv[idx]->arg, false); - - zvrf = zebra_vrf_lookup_by_id(vrf_id); - router_id_set(AFI_IP6, &rid, zvrf); - - return CMD_SUCCESS; -} - -DEFUN (no_ip_router_id_in_vrf, - no_ip_router_id_in_vrf_cmd, - "no ip router-id [A.B.C.D]", - NO_STR - IP_STR - "Remove the manually configured router-id\n" - "IP address to use for router-id\n") -{ - ZEBRA_DECLVAR_CONTEXT_VRF(vrf, zvrf); - - struct prefix rid; - - rid.u.prefix4.s_addr = 0; - rid.prefixlen = 0; - rid.family = AF_INET; - - router_id_set(AFI_IP, &rid, zvrf); - - return CMD_SUCCESS; -} - -ALIAS (no_ip_router_id_in_vrf, - no_router_id_in_vrf_cmd, - "no router-id [A.B.C.D]", - NO_STR - "Remove the manually configured router-id\n" - "IP address to use for router-id\n"); - -DEFUN (no_ipv6_router_id_in_vrf, - no_ipv6_router_id_in_vrf_cmd, - "no ipv6 router-id [X:X::X:X]", - NO_STR - IP6_STR - "Remove the manually configured IPv6 router-id\n" - "IPv6 address to use for router-id\n") -{ - ZEBRA_DECLVAR_CONTEXT_VRF(vrf, zvrf); - - struct prefix rid; - - memset(&rid, 0, sizeof(rid)); - rid.family = AF_INET; - - router_id_set(AFI_IP6, &rid, zvrf); - - return CMD_SUCCESS; -} - DEFUN (show_ip_router_id, show_ip_router_id_cmd, "show [ip|ipv6] router-id [vrf NAME]", @@ -557,24 +307,6 @@ static int router_id_v6_cmp(void *a, void *b) void router_id_cmd_init(void) { - install_element(CONFIG_NODE, &ip_router_id_cmd); - install_element(CONFIG_NODE, &router_id_cmd); - install_element(CONFIG_NODE, &ipv6_router_id_cmd); - install_element(CONFIG_NODE, &no_ip_router_id_cmd); - install_element(CONFIG_NODE, &no_router_id_cmd); - install_element(CONFIG_NODE, &ip_router_id_in_vrf_cmd); - install_element(VRF_NODE, &ip_router_id_in_vrf_cmd); - install_element(CONFIG_NODE, &router_id_in_vrf_cmd); - install_element(VRF_NODE, &router_id_in_vrf_cmd); - install_element(CONFIG_NODE, &ipv6_router_id_in_vrf_cmd); - install_element(VRF_NODE, &ipv6_router_id_in_vrf_cmd); - install_element(CONFIG_NODE, &no_ipv6_router_id_cmd); - install_element(CONFIG_NODE, &no_ip_router_id_in_vrf_cmd); - install_element(VRF_NODE, &no_ip_router_id_in_vrf_cmd); - install_element(CONFIG_NODE, &no_router_id_in_vrf_cmd); - install_element(VRF_NODE, &no_router_id_in_vrf_cmd); - install_element(CONFIG_NODE, &no_ipv6_router_id_in_vrf_cmd); - install_element(VRF_NODE, &no_ipv6_router_id_in_vrf_cmd); install_element(VIEW_NODE, &show_ip_router_id_cmd); } diff --git a/zebra/router-id.h b/zebra/router-id.h index 45860d8b7b..09ad4ec65e 100644 --- a/zebra/router-id.h +++ b/zebra/router-id.h @@ -25,8 +25,8 @@ extern void router_id_add_address(struct connected *c); extern void router_id_del_address(struct connected *c); extern void router_id_init(struct zebra_vrf *zvrf); extern void router_id_cmd_init(void); -extern void router_id_write(struct vty *vty, struct zebra_vrf *zvrf); extern int router_id_get(afi_t afi, struct prefix *p, struct zebra_vrf *zvrf); +extern int router_id_set(afi_t afi, struct prefix *p, struct zebra_vrf *zvrf); #ifdef __cplusplus } diff --git a/zebra/rtadv.c b/zebra/rtadv.c index 00f018d192..6aca643bd8 100644 --- a/zebra/rtadv.c +++ b/zebra/rtadv.c @@ -1134,7 +1134,8 @@ static void rtadv_prefix_set_defaults(struct rtadv_prefix *rp) rp->AdvValidLifetime = RTADV_VALID_LIFETIME; } -static void rtadv_prefix_set(struct zebra_if *zif, struct rtadv_prefix *rp) +static struct rtadv_prefix *rtadv_prefix_set(struct zebra_if *zif, + struct rtadv_prefix *rp) { struct rtadv_prefix *rprefix; @@ -1167,13 +1168,16 @@ static void rtadv_prefix_set(struct zebra_if *zif, struct rtadv_prefix *rp) rtadv_prefix_set_defaults(rprefix); } } + + return rprefix; } -static int rtadv_prefix_reset(struct zebra_if *zif, struct rtadv_prefix *rp) +static void rtadv_prefix_reset(struct zebra_if *zif, struct rtadv_prefix *rp, + struct rtadv_prefix *rprefix) { - struct rtadv_prefix *rprefix; + if (!rprefix) + rprefix = rtadv_prefixes_find(zif->rtadv.prefixes, rp); - rprefix = rtadv_prefixes_find(zif->rtadv.prefixes, rp); if (rprefix != NULL) { /* @@ -1187,20 +1191,35 @@ static int rtadv_prefix_reset(struct zebra_if *zif, struct rtadv_prefix *rp) if (rprefix->AdvPrefixCreate == PREFIX_SRC_BOTH) { rprefix->AdvPrefixCreate = PREFIX_SRC_AUTO; rtadv_prefix_set_defaults(rprefix); - return 1; + return; } } else if (rp->AdvPrefixCreate == PREFIX_SRC_AUTO) { if (rprefix->AdvPrefixCreate == PREFIX_SRC_BOTH) { rprefix->AdvPrefixCreate = PREFIX_SRC_MANUAL; - return 1; + return; } } rtadv_prefixes_del(zif->rtadv.prefixes, rprefix); rtadv_prefix_free(rprefix); - return 1; - } else - return 0; + } +} + +struct rtadv_prefix *rtadv_add_prefix_manual(struct zebra_if *zif, + struct rtadv_prefix *rp) +{ + rp->AdvPrefixCreate = PREFIX_SRC_MANUAL; + return rtadv_prefix_set(zif, rp); +} + +void rtadv_delete_prefix_manual(struct zebra_if *zif, + struct rtadv_prefix *rprefix) +{ + struct rtadv_prefix rp; + + rp.AdvPrefixCreate = PREFIX_SRC_MANUAL; + + rtadv_prefix_reset(zif, &rp, rprefix); } /* Add IPv6 prefixes learned from the kernel to the RA prefix list */ @@ -1222,7 +1241,7 @@ void rtadv_delete_prefix(struct zebra_if *zif, const struct prefix *p) rp.prefix = *((struct prefix_ipv6 *)p); apply_mask_ipv6(&rp.prefix); rp.AdvPrefixCreate = PREFIX_SRC_AUTO; - rtadv_prefix_reset(zif, &rp); + rtadv_prefix_reset(zif, &rp, NULL); } static void rtadv_start_interface_events(struct zebra_vrf *zvrf, @@ -1248,8 +1267,8 @@ static void rtadv_start_interface_events(struct zebra_vrf *zvrf, rtadv_event(zvrf, RTADV_START, 0); } -static void ipv6_nd_suppress_ra_set(struct interface *ifp, - enum ipv6_nd_suppress_ra_status status) +void ipv6_nd_suppress_ra_set(struct interface *ifp, + enum ipv6_nd_suppress_ra_status status) { struct zebra_if *zif; struct zebra_vrf *zvrf; @@ -1297,6 +1316,36 @@ static void ipv6_nd_suppress_ra_set(struct interface *ifp, } } +void ipv6_nd_interval_set(struct interface *ifp, uint32_t interval) +{ + struct zebra_if *zif = ifp->info; + struct zebra_vrf *zvrf = rtadv_interface_get_zvrf(ifp); + struct adv_if *adv_if; + + if (zif->rtadv.MaxRtrAdvInterval % 1000) { + adv_if = adv_msec_if_del(zvrf, ifp->name); + if (adv_if != NULL) + adv_if_free(adv_if); + } + + if (interval % 1000) + (void)adv_msec_if_add(zvrf, ifp->name); + + zif->rtadv.MaxRtrAdvInterval = interval; + zif->rtadv.MinRtrAdvInterval = 0.33 * interval; + + if (interval != RTADV_MAX_RTR_ADV_INTERVAL) { + SET_FLAG(zif->rtadv.ra_configured, VTY_RA_INTERVAL_CONFIGURED); + zif->rtadv.AdvIntervalTimer = 0; + } else { + if (CHECK_FLAG(zif->rtadv.ra_configured, BGP_RA_CONFIGURED)) + zif->rtadv.MaxRtrAdvInterval = 10000; + + UNSET_FLAG(zif->rtadv.ra_configured, VTY_RA_INTERVAL_CONFIGURED); + zif->rtadv.AdvIntervalTimer = zif->rtadv.MaxRtrAdvInterval; + } +} + /* * Handle client (BGP) message to enable or disable IPv6 RA on an interface. * Note that while the client could request RA on an interface on which the @@ -1414,7 +1463,7 @@ void rtadv_stop_ra_all(void) frr_each_safe (rtadv_prefixes, zif->rtadv.prefixes, rprefix) - rtadv_prefix_reset(zif, rprefix); + rtadv_prefix_reset(zif, rprefix, rprefix); rtadv_stop_ra(ifp); } @@ -1499,777 +1548,6 @@ DEFPY(show_ipv6_nd_ra_if, show_ipv6_nd_ra_if_cmd, return CMD_SUCCESS; } -DEFUN (ipv6_nd_ra_fast_retrans, - ipv6_nd_ra_fast_retrans_cmd, - "ipv6 nd ra-fast-retrans", - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Fast retransmit of RA packets\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - struct zebra_if *zif = ifp->info; - - if (if_is_loopback(ifp)) { - vty_out(vty, - "Cannot configure IPv6 Router Advertisements on this interface\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - zif->rtadv.UseFastRexmit = true; - - return CMD_SUCCESS; -} - -DEFUN (no_ipv6_nd_ra_fast_retrans, - no_ipv6_nd_ra_fast_retrans_cmd, - "no ipv6 nd ra-fast-retrans", - NO_STR - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Fast retransmit of RA packets\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - struct zebra_if *zif = ifp->info; - - if (if_is_loopback(ifp)) { - vty_out(vty, - "Cannot configure IPv6 Router Advertisements on this interface\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - zif->rtadv.UseFastRexmit = false; - - return CMD_SUCCESS; -} - -DEFPY (ipv6_nd_ra_hop_limit, - ipv6_nd_ra_hop_limit_cmd, - "ipv6 nd ra-hop-limit (0-255)$hopcount", - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Advertisement Hop Limit\n" - "Advertisement Hop Limit in hops (default:64)\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - struct zebra_if *zif = ifp->info; - - if (if_is_loopback(ifp)) { - vty_out(vty, - "Cannot configure IPv6 Router Advertisements on this interface\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - zif->rtadv.AdvCurHopLimit = hopcount; - - return CMD_SUCCESS; -} - -DEFPY (no_ipv6_nd_ra_hop_limit, - no_ipv6_nd_ra_hop_limit_cmd, - "no ipv6 nd ra-hop-limit [(0-255)]", - NO_STR - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Advertisement Hop Limit\n" - "Advertisement Hop Limit in hops\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - struct zebra_if *zif = ifp->info; - - if (if_is_loopback(ifp)) { - vty_out(vty, - "Cannot configure IPv6 Router Advertisements on this interface\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - zif->rtadv.AdvCurHopLimit = RTADV_DEFAULT_HOPLIMIT; - - return CMD_SUCCESS; -} - -DEFPY (ipv6_nd_ra_retrans_interval, - ipv6_nd_ra_retrans_interval_cmd, - "ipv6 nd ra-retrans-interval (0-4294967295)$interval", - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Advertisement Retransmit Interval\n" - "Advertisement Retransmit Interval in msec\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - struct zebra_if *zif = ifp->info; - - if (if_is_loopback(ifp)) { - vty_out(vty, - "Cannot configure IPv6 Router Advertisements on loopback interface\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - zif->rtadv.AdvRetransTimer = interval; - - return CMD_SUCCESS; -} - -DEFPY (no_ipv6_nd_ra_retrans_interval, - no_ipv6_nd_ra_retrans_interval_cmd, - "no ipv6 nd ra-retrans-interval [(0-4294967295)]", - NO_STR - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Advertisement Retransmit Interval\n" - "Advertisement Retransmit Interval in msec\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - struct zebra_if *zif = ifp->info; - - if (if_is_loopback(ifp)) { - vty_out(vty, - "Cannot remove IPv6 Router Advertisements on loopback interface\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - zif->rtadv.AdvRetransTimer = 0; - - return CMD_SUCCESS; -} - -DEFUN (ipv6_nd_suppress_ra, - ipv6_nd_suppress_ra_cmd, - "ipv6 nd suppress-ra", - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Suppress Router Advertisement\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - struct zebra_if *zif = ifp->info; - - if (if_is_loopback(ifp)) { - vty_out(vty, - "Cannot configure IPv6 Router Advertisements on this interface\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (!CHECK_FLAG(zif->rtadv.ra_configured, BGP_RA_CONFIGURED)) - ipv6_nd_suppress_ra_set(ifp, RA_SUPPRESS); - - UNSET_FLAG(zif->rtadv.ra_configured, VTY_RA_CONFIGURED); - return CMD_SUCCESS; -} - -DEFUN (no_ipv6_nd_suppress_ra, - no_ipv6_nd_suppress_ra_cmd, - "no ipv6 nd suppress-ra", - NO_STR - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Suppress Router Advertisement\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - struct zebra_if *zif = ifp->info; - - if (if_is_loopback(ifp)) { - vty_out(vty, - "Cannot configure IPv6 Router Advertisements on this interface\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - ipv6_nd_suppress_ra_set(ifp, RA_ENABLE); - SET_FLAG(zif->rtadv.ra_configured, VTY_RA_CONFIGURED); - return CMD_SUCCESS; -} - -DEFUN (ipv6_nd_ra_interval_msec, - ipv6_nd_ra_interval_msec_cmd, - "ipv6 nd ra-interval msec (70-1800000)", - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Router Advertisement interval\n" - "Router Advertisement interval in milliseconds\n" - "Router Advertisement interval in milliseconds\n") -{ - int idx_number = 4; - VTY_DECLVAR_CONTEXT(interface, ifp); - unsigned interval; - struct zebra_if *zif = ifp->info; - struct zebra_vrf *zvrf; - struct adv_if *adv_if; - - zvrf = rtadv_interface_get_zvrf(ifp); - - interval = strtoul(argv[idx_number]->arg, NULL, 10); - if ((zif->rtadv.AdvDefaultLifetime != -1 - && interval > (unsigned)zif->rtadv.AdvDefaultLifetime * 1000)) { - vty_out(vty, - "This ra-interval would conflict with configured ra-lifetime!\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (zif->rtadv.MaxRtrAdvInterval % 1000) { - adv_if = adv_msec_if_del(zvrf, ifp->name); - if (adv_if != NULL) - adv_if_free(adv_if); - } - - if (interval % 1000) - (void)adv_msec_if_add(zvrf, ifp->name); - - SET_FLAG(zif->rtadv.ra_configured, VTY_RA_INTERVAL_CONFIGURED); - zif->rtadv.MaxRtrAdvInterval = interval; - zif->rtadv.MinRtrAdvInterval = 0.33 * interval; - zif->rtadv.AdvIntervalTimer = 0; - - return CMD_SUCCESS; -} - -DEFUN (ipv6_nd_ra_interval, - ipv6_nd_ra_interval_cmd, - "ipv6 nd ra-interval (1-1800)", - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Router Advertisement interval\n" - "Router Advertisement interval in seconds\n") -{ - int idx_number = 3; - VTY_DECLVAR_CONTEXT(interface, ifp); - unsigned interval; - struct zebra_if *zif = ifp->info; - struct zebra_vrf *zvrf; - struct adv_if *adv_if; - - zvrf = rtadv_interface_get_zvrf(ifp); - - interval = strtoul(argv[idx_number]->arg, NULL, 10); - if ((zif->rtadv.AdvDefaultLifetime != -1 - && interval > (unsigned)zif->rtadv.AdvDefaultLifetime)) { - vty_out(vty, - "This ra-interval would conflict with configured ra-lifetime!\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (zif->rtadv.MaxRtrAdvInterval % 1000) { - adv_if = adv_msec_if_del(zvrf, ifp->name); - if (adv_if != NULL) - adv_if_free(adv_if); - } - - /* convert to milliseconds */ - interval = interval * 1000; - - SET_FLAG(zif->rtadv.ra_configured, VTY_RA_INTERVAL_CONFIGURED); - zif->rtadv.MaxRtrAdvInterval = interval; - zif->rtadv.MinRtrAdvInterval = 0.33 * interval; - zif->rtadv.AdvIntervalTimer = 0; - - return CMD_SUCCESS; -} - -DEFUN (no_ipv6_nd_ra_interval, - no_ipv6_nd_ra_interval_cmd, - "no ipv6 nd ra-interval [<(1-1800)|msec (1-1800000)>]", - NO_STR - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Router Advertisement interval\n" - "Router Advertisement interval in seconds\n" - "Specify millisecond router advertisement interval\n" - "Router Advertisement interval in milliseconds\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - struct zebra_if *zif = ifp->info; - struct zebra_vrf *zvrf = NULL; - struct adv_if *adv_if; - - zvrf = rtadv_interface_get_zvrf(ifp); - - if (zif->rtadv.MaxRtrAdvInterval % 1000) { - adv_if = adv_msec_if_del(zvrf, ifp->name); - if (adv_if != NULL) - adv_if_free(adv_if); - } - - UNSET_FLAG(zif->rtadv.ra_configured, VTY_RA_INTERVAL_CONFIGURED); - - if (CHECK_FLAG(zif->rtadv.ra_configured, BGP_RA_CONFIGURED)) - zif->rtadv.MaxRtrAdvInterval = 10000; - else - zif->rtadv.MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL; - - zif->rtadv.AdvIntervalTimer = zif->rtadv.MaxRtrAdvInterval; - zif->rtadv.MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL; - - return CMD_SUCCESS; -} - -DEFUN (ipv6_nd_ra_lifetime, - ipv6_nd_ra_lifetime_cmd, - "ipv6 nd ra-lifetime (0-9000)", - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Router lifetime\n" - "Router lifetime in seconds (0 stands for a non-default gw)\n") -{ - int idx_number = 3; - VTY_DECLVAR_CONTEXT(interface, ifp); - struct zebra_if *zif = ifp->info; - int lifetime; - - lifetime = strtoul(argv[idx_number]->arg, NULL, 10); - - /* The value to be placed in the Router Lifetime field - * of Router Advertisements sent from the interface, - * in seconds. MUST be either zero or between - * MaxRtrAdvInterval and 9000 seconds. -- RFC4861, 6.2.1 */ - if ((lifetime != 0 && lifetime * 1000 < zif->rtadv.MaxRtrAdvInterval)) { - vty_out(vty, - "This ra-lifetime would conflict with configured ra-interval\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - zif->rtadv.AdvDefaultLifetime = lifetime; - - return CMD_SUCCESS; -} - -DEFUN (no_ipv6_nd_ra_lifetime, - no_ipv6_nd_ra_lifetime_cmd, - "no ipv6 nd ra-lifetime [(0-9000)]", - NO_STR - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Router lifetime\n" - "Router lifetime in seconds (0 stands for a non-default gw)\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - struct zebra_if *zif = ifp->info; - - zif->rtadv.AdvDefaultLifetime = -1; - - return CMD_SUCCESS; -} - -DEFUN (ipv6_nd_reachable_time, - ipv6_nd_reachable_time_cmd, - "ipv6 nd reachable-time (1-3600000)", - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Reachable time\n" - "Reachable time in milliseconds\n") -{ - int idx_number = 3; - VTY_DECLVAR_CONTEXT(interface, ifp); - struct zebra_if *zif = ifp->info; - zif->rtadv.AdvReachableTime = strtoul(argv[idx_number]->arg, NULL, 10); - return CMD_SUCCESS; -} - -DEFUN (no_ipv6_nd_reachable_time, - no_ipv6_nd_reachable_time_cmd, - "no ipv6 nd reachable-time [(1-3600000)]", - NO_STR - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Reachable time\n" - "Reachable time in milliseconds\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - struct zebra_if *zif = ifp->info; - - zif->rtadv.AdvReachableTime = 0; - - return CMD_SUCCESS; -} - -DEFUN (ipv6_nd_homeagent_preference, - ipv6_nd_homeagent_preference_cmd, - "ipv6 nd home-agent-preference (0-65535)", - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Home Agent preference\n" - "preference value (default is 0, least preferred)\n") -{ - int idx_number = 3; - VTY_DECLVAR_CONTEXT(interface, ifp); - struct zebra_if *zif = ifp->info; - zif->rtadv.HomeAgentPreference = - strtoul(argv[idx_number]->arg, NULL, 10); - return CMD_SUCCESS; -} - -DEFUN (no_ipv6_nd_homeagent_preference, - no_ipv6_nd_homeagent_preference_cmd, - "no ipv6 nd home-agent-preference [(0-65535)]", - NO_STR - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Home Agent preference\n" - "preference value (default is 0, least preferred)\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - struct zebra_if *zif = ifp->info; - - zif->rtadv.HomeAgentPreference = 0; - - return CMD_SUCCESS; -} - -DEFUN (ipv6_nd_homeagent_lifetime, - ipv6_nd_homeagent_lifetime_cmd, - "ipv6 nd home-agent-lifetime (0-65520)", - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Home Agent lifetime\n" - "Home Agent lifetime in seconds (0 to track ra-lifetime)\n") -{ - int idx_number = 3; - VTY_DECLVAR_CONTEXT(interface, ifp); - struct zebra_if *zif = ifp->info; - zif->rtadv.HomeAgentLifetime = strtoul(argv[idx_number]->arg, NULL, 10); - return CMD_SUCCESS; -} - -DEFUN (no_ipv6_nd_homeagent_lifetime, - no_ipv6_nd_homeagent_lifetime_cmd, - "no ipv6 nd home-agent-lifetime [(0-65520)]", - NO_STR - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Home Agent lifetime\n" - "Home Agent lifetime in seconds (0 to track ra-lifetime)\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - struct zebra_if *zif = ifp->info; - - zif->rtadv.HomeAgentLifetime = -1; - - return CMD_SUCCESS; -} - -DEFUN (ipv6_nd_managed_config_flag, - ipv6_nd_managed_config_flag_cmd, - "ipv6 nd managed-config-flag", - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Managed address configuration flag\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - struct zebra_if *zif = ifp->info; - - zif->rtadv.AdvManagedFlag = 1; - - return CMD_SUCCESS; -} - -DEFUN (no_ipv6_nd_managed_config_flag, - no_ipv6_nd_managed_config_flag_cmd, - "no ipv6 nd managed-config-flag", - NO_STR - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Managed address configuration flag\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - struct zebra_if *zif = ifp->info; - - zif->rtadv.AdvManagedFlag = 0; - - return CMD_SUCCESS; -} - -DEFUN (ipv6_nd_homeagent_config_flag, - ipv6_nd_homeagent_config_flag_cmd, - "ipv6 nd home-agent-config-flag", - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Home Agent configuration flag\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - struct zebra_if *zif = ifp->info; - - zif->rtadv.AdvHomeAgentFlag = 1; - - return CMD_SUCCESS; -} - -DEFUN (no_ipv6_nd_homeagent_config_flag, - no_ipv6_nd_homeagent_config_flag_cmd, - "no ipv6 nd home-agent-config-flag", - NO_STR - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Home Agent configuration flag\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - struct zebra_if *zif = ifp->info; - - zif->rtadv.AdvHomeAgentFlag = 0; - - return CMD_SUCCESS; -} - -DEFUN (ipv6_nd_adv_interval_config_option, - ipv6_nd_adv_interval_config_option_cmd, - "ipv6 nd adv-interval-option", - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Advertisement Interval Option\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - struct zebra_if *zif = ifp->info; - - zif->rtadv.AdvIntervalOption = 1; - - return CMD_SUCCESS; -} - -DEFUN (no_ipv6_nd_adv_interval_config_option, - no_ipv6_nd_adv_interval_config_option_cmd, - "no ipv6 nd adv-interval-option", - NO_STR - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Advertisement Interval Option\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - struct zebra_if *zif = ifp->info; - - zif->rtadv.AdvIntervalOption = 0; - - return CMD_SUCCESS; -} - -DEFUN (ipv6_nd_other_config_flag, - ipv6_nd_other_config_flag_cmd, - "ipv6 nd other-config-flag", - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Other statefull configuration flag\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - struct zebra_if *zif = ifp->info; - - zif->rtadv.AdvOtherConfigFlag = 1; - - return CMD_SUCCESS; -} - -DEFUN (no_ipv6_nd_other_config_flag, - no_ipv6_nd_other_config_flag_cmd, - "no ipv6 nd other-config-flag", - NO_STR - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Other statefull configuration flag\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - struct zebra_if *zif = ifp->info; - - zif->rtadv.AdvOtherConfigFlag = 0; - - return CMD_SUCCESS; -} - -DEFUN (ipv6_nd_prefix, - ipv6_nd_prefix_cmd, - "ipv6 nd prefix X:X::X:X/M [<(0-4294967295)|infinite> <(0-4294967295)|infinite>] [<router-address|off-link [no-autoconfig]|no-autoconfig [off-link]>]", - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Prefix information\n" - "IPv6 prefix\n" - "Valid lifetime in seconds\n" - "Infinite valid lifetime\n" - "Preferred lifetime in seconds\n" - "Infinite preferred lifetime\n" - "Set Router Address flag\n" - "Do not use prefix for onlink determination\n" - "Do not use prefix for autoconfiguration\n" - "Do not use prefix for autoconfiguration\n" - "Do not use prefix for onlink determination\n") -{ - /* prelude */ - char *prefix = argv[3]->arg; - int lifetimes = (argc > 4) && (argv[4]->type == RANGE_TKN - || strmatch(argv[4]->text, "infinite")); - int routeropts = lifetimes ? argc > 6 : argc > 4; - - int idx_routeropts = routeropts ? (lifetimes ? 6 : 4) : 0; - - char *lifetime = NULL, *preflifetime = NULL; - int routeraddr = 0, offlink = 0, noautoconf = 0; - if (lifetimes) { - lifetime = argv[4]->type == RANGE_TKN ? argv[4]->arg - : argv[4]->text; - preflifetime = argv[5]->type == RANGE_TKN ? argv[5]->arg - : argv[5]->text; - } - if (routeropts) { - routeraddr = - strmatch(argv[idx_routeropts]->text, "router-address"); - if (!routeraddr) { - offlink = (argc > idx_routeropts + 1 - || strmatch(argv[idx_routeropts]->text, - "off-link")); - noautoconf = (argc > idx_routeropts + 1 - || strmatch(argv[idx_routeropts]->text, - "no-autoconfig")); - } - } - - /* business */ - VTY_DECLVAR_CONTEXT(interface, ifp); - struct zebra_if *zebra_if = ifp->info; - int ret; - struct rtadv_prefix rp; - - ret = str2prefix_ipv6(prefix, &rp.prefix); - if (!ret) { - vty_out(vty, "Malformed IPv6 prefix\n"); - return CMD_WARNING_CONFIG_FAILED; - } - apply_mask_ipv6(&rp.prefix); /* RFC4861 4.6.2 */ - rp.AdvOnLinkFlag = !offlink; - rp.AdvAutonomousFlag = !noautoconf; - rp.AdvRouterAddressFlag = routeraddr; - rp.AdvValidLifetime = RTADV_VALID_LIFETIME; - rp.AdvPreferredLifetime = RTADV_PREFERRED_LIFETIME; - rp.AdvPrefixCreate = PREFIX_SRC_MANUAL; - - if (lifetimes) { - rp.AdvValidLifetime = strmatch(lifetime, "infinite") - ? UINT32_MAX - : strtoll(lifetime, NULL, 10); - rp.AdvPreferredLifetime = - strmatch(preflifetime, "infinite") - ? UINT32_MAX - : strtoll(preflifetime, NULL, 10); - if (rp.AdvPreferredLifetime > rp.AdvValidLifetime) { - vty_out(vty, "Invalid preferred lifetime\n"); - return CMD_WARNING_CONFIG_FAILED; - } - } - - rtadv_prefix_set(zebra_if, &rp); - - return CMD_SUCCESS; -} - -DEFUN (no_ipv6_nd_prefix, - no_ipv6_nd_prefix_cmd, - "no ipv6 nd prefix X:X::X:X/M [<(0-4294967295)|infinite> <(0-4294967295)|infinite>] [<router-address|off-link [no-autoconfig]|no-autoconfig [off-link]>]", - NO_STR - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Prefix information\n" - "IPv6 prefix\n" - "Valid lifetime in seconds\n" - "Infinite valid lifetime\n" - "Preferred lifetime in seconds\n" - "Infinite preferred lifetime\n" - "Set Router Address flag\n" - "Do not use prefix for onlink determination\n" - "Do not use prefix for autoconfiguration\n" - "Do not use prefix for autoconfiguration\n" - "Do not use prefix for onlink determination\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - struct zebra_if *zebra_if = ifp->info; - int ret; - struct rtadv_prefix rp; - char *prefix = argv[4]->arg; - - ret = str2prefix_ipv6(prefix, &rp.prefix); - if (!ret) { - vty_out(vty, "Malformed IPv6 prefix\n"); - return CMD_WARNING_CONFIG_FAILED; - } - apply_mask_ipv6(&rp.prefix); /* RFC4861 4.6.2 */ - rp.AdvPrefixCreate = PREFIX_SRC_MANUAL; - - ret = rtadv_prefix_reset(zebra_if, &rp); - if (!ret) { - vty_out(vty, "Non-existant IPv6 prefix\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - return CMD_SUCCESS; -} - -DEFUN (ipv6_nd_router_preference, - ipv6_nd_router_preference_cmd, - "ipv6 nd router-preference <high|medium|low>", - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Default router preference\n" - "High default router preference\n" - "Medium default router preference (default)\n" - "Low default router preference\n") -{ - int idx_high_medium_low = 3; - VTY_DECLVAR_CONTEXT(interface, ifp); - struct zebra_if *zif = ifp->info; - int i = 0; - - while (0 != rtadv_pref_strs[i]) { - if (strncmp(argv[idx_high_medium_low]->arg, rtadv_pref_strs[i], - 1) - == 0) { - zif->rtadv.DefaultPreference = i; - return CMD_SUCCESS; - } - i++; - } - - return CMD_ERR_NO_MATCH; -} - -DEFUN (no_ipv6_nd_router_preference, - no_ipv6_nd_router_preference_cmd, - "no ipv6 nd router-preference [<high|medium|low>]", - NO_STR - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Default router preference\n" - "High default router preference\n" - "Medium default router preference (default)\n" - "Low default router preference\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - struct zebra_if *zif = ifp->info; - - zif->rtadv.DefaultPreference = - RTADV_PREF_MEDIUM; /* Default per RFC4191. */ - - return CMD_SUCCESS; -} - -DEFUN (ipv6_nd_mtu, - ipv6_nd_mtu_cmd, - "ipv6 nd mtu (1-65535)", - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Advertised MTU\n" - "MTU in bytes\n") -{ - int idx_number = 3; - VTY_DECLVAR_CONTEXT(interface, ifp); - struct zebra_if *zif = ifp->info; - zif->rtadv.AdvLinkMTU = strtoul(argv[idx_number]->arg, NULL, 10); - return CMD_SUCCESS; -} - -DEFUN (no_ipv6_nd_mtu, - no_ipv6_nd_mtu_cmd, - "no ipv6 nd mtu [(1-65535)]", - NO_STR - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Advertised MTU\n" - "MTU in bytes\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - struct zebra_if *zif = ifp->info; - zif->rtadv.AdvLinkMTU = 0; - return CMD_SUCCESS; -} - static struct rtadv_rdnss *rtadv_rdnss_new(void) { return XCALLOC(MTYPE_RTADV_RDNSS, sizeof(struct rtadv_rdnss)); @@ -2280,55 +1558,22 @@ static void rtadv_rdnss_free(struct rtadv_rdnss *rdnss) XFREE(MTYPE_RTADV_RDNSS, rdnss); } -static struct rtadv_rdnss *rtadv_rdnss_lookup(struct list *list, - struct rtadv_rdnss *rdnss) -{ - struct listnode *node; - struct rtadv_rdnss *p; - - for (ALL_LIST_ELEMENTS_RO(list, node, p)) - if (IPV6_ADDR_SAME(&p->addr, &rdnss->addr)) - return p; - return NULL; -} - -static struct rtadv_rdnss *rtadv_rdnss_get(struct list *list, - struct rtadv_rdnss *rdnss) +struct rtadv_rdnss *rtadv_rdnss_set(struct zebra_if *zif, + struct rtadv_rdnss *rdnss) { struct rtadv_rdnss *p; - p = rtadv_rdnss_lookup(list, rdnss); - if (p) - return p; - p = rtadv_rdnss_new(); memcpy(p, rdnss, sizeof(struct rtadv_rdnss)); - listnode_add(list, p); + listnode_add(zif->rtadv.AdvRDNSSList, p); return p; } -static void rtadv_rdnss_set(struct zebra_if *zif, struct rtadv_rdnss *rdnss) +void rtadv_rdnss_reset(struct zebra_if *zif, struct rtadv_rdnss *p) { - struct rtadv_rdnss *p; - - p = rtadv_rdnss_get(zif->rtadv.AdvRDNSSList, rdnss); - p->lifetime = rdnss->lifetime; - p->lifetime_set = rdnss->lifetime_set; -} - -static int rtadv_rdnss_reset(struct zebra_if *zif, struct rtadv_rdnss *rdnss) -{ - struct rtadv_rdnss *p; - - p = rtadv_rdnss_lookup(zif->rtadv.AdvRDNSSList, rdnss); - if (p) { - listnode_delete(zif->rtadv.AdvRDNSSList, p); - rtadv_rdnss_free(p); - return 1; - } - - return 0; + listnode_delete(zif->rtadv.AdvRDNSSList, p); + rtadv_rdnss_free(p); } static struct rtadv_dnssl *rtadv_dnssl_new(void) @@ -2341,54 +1586,22 @@ static void rtadv_dnssl_free(struct rtadv_dnssl *dnssl) XFREE(MTYPE_RTADV_DNSSL, dnssl); } -static struct rtadv_dnssl *rtadv_dnssl_lookup(struct list *list, - struct rtadv_dnssl *dnssl) +struct rtadv_dnssl *rtadv_dnssl_set(struct zebra_if *zif, + struct rtadv_dnssl *dnssl) { - struct listnode *node; struct rtadv_dnssl *p; - for (ALL_LIST_ELEMENTS_RO(list, node, p)) - if (!strcasecmp(p->name, dnssl->name)) - return p; - return NULL; -} - -static struct rtadv_dnssl *rtadv_dnssl_get(struct list *list, - struct rtadv_dnssl *dnssl) -{ - struct rtadv_dnssl *p; - - p = rtadv_dnssl_lookup(list, dnssl); - if (p) - return p; - p = rtadv_dnssl_new(); memcpy(p, dnssl, sizeof(struct rtadv_dnssl)); - listnode_add(list, p); + listnode_add(zif->rtadv.AdvDNSSLList, p); return p; } -static void rtadv_dnssl_set(struct zebra_if *zif, struct rtadv_dnssl *dnssl) +void rtadv_dnssl_reset(struct zebra_if *zif, struct rtadv_dnssl *p) { - struct rtadv_dnssl *p; - - p = rtadv_dnssl_get(zif->rtadv.AdvDNSSLList, dnssl); - memcpy(p, dnssl, sizeof(struct rtadv_dnssl)); -} - -static int rtadv_dnssl_reset(struct zebra_if *zif, struct rtadv_dnssl *dnssl) -{ - struct rtadv_dnssl *p; - - p = rtadv_dnssl_lookup(zif->rtadv.AdvDNSSLList, dnssl); - if (p) { - listnode_delete(zif->rtadv.AdvDNSSLList, p); - rtadv_dnssl_free(p); - return 1; - } - - return 0; + listnode_delete(zif->rtadv.AdvDNSSLList, p); + rtadv_dnssl_free(p); } /* @@ -2399,7 +1612,7 @@ static int rtadv_dnssl_reset(struct zebra_if *zif, struct rtadv_dnssl *dnssl) * Returns the number of octets written to out or -1 if in does not constitute * a valid domain name. */ -static int rtadv_dnssl_encode(uint8_t *out, const char *in) +int rtadv_dnssl_encode(uint8_t *out, const char *in) { const char *label_start, *label_end; size_t outp; @@ -2430,148 +1643,6 @@ static int rtadv_dnssl_encode(uint8_t *out, const char *in) return outp; } -DEFUN(ipv6_nd_rdnss, - ipv6_nd_rdnss_cmd, - "ipv6 nd rdnss X:X::X:X [<(0-4294967295)|infinite>]", - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Recursive DNS server information\n" - "IPv6 address\n" - "Valid lifetime in seconds\n" - "Infinite valid lifetime\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - struct zebra_if *zif = ifp->info; - struct rtadv_rdnss rdnss = {}; - - if (inet_pton(AF_INET6, argv[3]->arg, &rdnss.addr) != 1) { - vty_out(vty, "Malformed IPv6 address\n"); - return CMD_WARNING_CONFIG_FAILED; - } - if (argc > 4) { - char *lifetime = argv[4]->type == RANGE_TKN ? argv[4]->arg - : argv[4]->text; - rdnss.lifetime = strmatch(lifetime, "infinite") - ? UINT32_MAX - : strtoll(lifetime, NULL, 10); - rdnss.lifetime_set = 1; - } - - rtadv_rdnss_set(zif, &rdnss); - - return CMD_SUCCESS; -} - -DEFUN(no_ipv6_nd_rdnss, - no_ipv6_nd_rdnss_cmd, - "no ipv6 nd rdnss X:X::X:X [<(0-4294967295)|infinite>]", - NO_STR - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Recursive DNS server information\n" - "IPv6 address\n" - "Valid lifetime in seconds\n" - "Infinite valid lifetime\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - struct zebra_if *zif = ifp->info; - struct rtadv_rdnss rdnss = {}; - - if (inet_pton(AF_INET6, argv[4]->arg, &rdnss.addr) != 1) { - vty_out(vty, "Malformed IPv6 address\n"); - return CMD_WARNING_CONFIG_FAILED; - } - if (rtadv_rdnss_reset(zif, &rdnss) != 1) { - vty_out(vty, "Non-existant RDNSS address\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - return CMD_SUCCESS; -} - -DEFUN(ipv6_nd_dnssl, - ipv6_nd_dnssl_cmd, - "ipv6 nd dnssl SUFFIX [<(0-4294967295)|infinite>]", - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "DNS search list information\n" - "Domain name suffix\n" - "Valid lifetime in seconds\n" - "Infinite valid lifetime\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - struct zebra_if *zif = ifp->info; - struct rtadv_dnssl dnssl = {}; - size_t len; - int ret; - - len = strlcpy(dnssl.name, argv[3]->arg, sizeof(dnssl.name)); - if (len == 0 || len >= sizeof(dnssl.name)) { - vty_out(vty, "Malformed DNS search domain\n"); - return CMD_WARNING_CONFIG_FAILED; - } - if (dnssl.name[len - 1] == '.') { - /* - * Allow, but don't require, a trailing dot signifying the root - * zone. Canonicalize by cutting it off if present. - */ - dnssl.name[len - 1] = '\0'; - len--; - } - if (argc > 4) { - char *lifetime = argv[4]->type == RANGE_TKN ? argv[4]->arg - : argv[4]->text; - dnssl.lifetime = strmatch(lifetime, "infinite") - ? UINT32_MAX - : strtoll(lifetime, NULL, 10); - dnssl.lifetime_set = 1; - } - - ret = rtadv_dnssl_encode(dnssl.encoded_name, dnssl.name); - if (ret < 0) { - vty_out(vty, "Malformed DNS search domain\n"); - return CMD_WARNING_CONFIG_FAILED; - } - dnssl.encoded_len = ret; - rtadv_dnssl_set(zif, &dnssl); - - return CMD_SUCCESS; -} - -DEFUN(no_ipv6_nd_dnssl, - no_ipv6_nd_dnssl_cmd, - "no ipv6 nd dnssl SUFFIX [<(0-4294967295)|infinite>]", - NO_STR - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "DNS search list information\n" - "Domain name suffix\n" - "Valid lifetime in seconds\n" - "Infinite valid lifetime\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - struct zebra_if *zif = ifp->info; - struct rtadv_dnssl dnssl = {}; - size_t len; - - len = strlcpy(dnssl.name, argv[4]->arg, sizeof(dnssl.name)); - if (len == 0 || len >= sizeof(dnssl.name)) { - vty_out(vty, "Malformed DNS search domain\n"); - return CMD_WARNING_CONFIG_FAILED; - } - if (dnssl.name[len - 1] == '.') { - dnssl.name[len - 1] = '\0'; - len--; - } - if (rtadv_dnssl_reset(zif, &dnssl) != 1) { - vty_out(vty, "Non-existant DNS search domain\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - return CMD_SUCCESS; -} - - /* Dump interface ND information to vty. */ static int nd_dump_vty(struct vty *vty, struct interface *ifp) { @@ -2642,136 +1713,6 @@ static int nd_dump_vty(struct vty *vty, struct interface *ifp) return 0; } - -/* Write configuration about router advertisement. */ -static int rtadv_config_write(struct vty *vty, struct interface *ifp) -{ - struct zebra_if *zif; - struct listnode *node; - struct rtadv_prefix *rprefix; - struct rtadv_rdnss *rdnss; - struct rtadv_dnssl *dnssl; - int interval; - - zif = ifp->info; - - if (!if_is_loopback(ifp)) { - if (zif->rtadv.AdvSendAdvertisements - && CHECK_FLAG(zif->rtadv.ra_configured, VTY_RA_CONFIGURED)) - vty_out(vty, " no ipv6 nd suppress-ra\n"); - } - - interval = zif->rtadv.MaxRtrAdvInterval; - if (CHECK_FLAG(zif->rtadv.ra_configured, VTY_RA_INTERVAL_CONFIGURED)) { - if (interval % 1000) - vty_out(vty, " ipv6 nd ra-interval msec %d\n", - interval); - else if (interval != RTADV_MAX_RTR_ADV_INTERVAL) - vty_out(vty, " ipv6 nd ra-interval %d\n", - interval / 1000); - } - - if (zif->rtadv.AdvIntervalOption) - vty_out(vty, " ipv6 nd adv-interval-option\n"); - - if (!zif->rtadv.UseFastRexmit) - vty_out(vty, " no ipv6 nd ra-fast-retrans\n"); - - if (zif->rtadv.AdvRetransTimer != 0) - vty_out(vty, " ipv6 nd ra-retrans-interval %u\n", - zif->rtadv.AdvRetransTimer); - - if (zif->rtadv.AdvCurHopLimit != RTADV_DEFAULT_HOPLIMIT) - vty_out(vty, " ipv6 nd ra-hop-limit %d\n", - zif->rtadv.AdvCurHopLimit); - - if (zif->rtadv.AdvDefaultLifetime != -1) - vty_out(vty, " ipv6 nd ra-lifetime %d\n", - zif->rtadv.AdvDefaultLifetime); - - if (zif->rtadv.HomeAgentPreference) - vty_out(vty, " ipv6 nd home-agent-preference %u\n", - zif->rtadv.HomeAgentPreference); - - if (zif->rtadv.HomeAgentLifetime != -1) - vty_out(vty, " ipv6 nd home-agent-lifetime %u\n", - zif->rtadv.HomeAgentLifetime); - - if (zif->rtadv.AdvHomeAgentFlag) - vty_out(vty, " ipv6 nd home-agent-config-flag\n"); - - if (zif->rtadv.AdvReachableTime) - vty_out(vty, " ipv6 nd reachable-time %d\n", - zif->rtadv.AdvReachableTime); - - if (zif->rtadv.AdvManagedFlag) - vty_out(vty, " ipv6 nd managed-config-flag\n"); - - if (zif->rtadv.AdvOtherConfigFlag) - vty_out(vty, " ipv6 nd other-config-flag\n"); - - if (zif->rtadv.DefaultPreference != RTADV_PREF_MEDIUM) - vty_out(vty, " ipv6 nd router-preference %s\n", - rtadv_pref_strs[zif->rtadv.DefaultPreference]); - - if (zif->rtadv.AdvLinkMTU) - vty_out(vty, " ipv6 nd mtu %d\n", zif->rtadv.AdvLinkMTU); - - frr_each (rtadv_prefixes, zif->rtadv.prefixes, rprefix) { - if ((rprefix->AdvPrefixCreate == PREFIX_SRC_MANUAL) - || (rprefix->AdvPrefixCreate == PREFIX_SRC_BOTH)) { - vty_out(vty, " ipv6 nd prefix %pFX", &rprefix->prefix); - if ((rprefix->AdvValidLifetime != RTADV_VALID_LIFETIME) - || (rprefix->AdvPreferredLifetime - != RTADV_PREFERRED_LIFETIME)) { - if (rprefix->AdvValidLifetime == UINT32_MAX) - vty_out(vty, " infinite"); - else - vty_out(vty, " %u", - rprefix->AdvValidLifetime); - if (rprefix->AdvPreferredLifetime == UINT32_MAX) - vty_out(vty, " infinite"); - else - vty_out(vty, " %u", - rprefix->AdvPreferredLifetime); - } - if (!rprefix->AdvOnLinkFlag) - vty_out(vty, " off-link"); - if (!rprefix->AdvAutonomousFlag) - vty_out(vty, " no-autoconfig"); - if (rprefix->AdvRouterAddressFlag) - vty_out(vty, " router-address"); - vty_out(vty, "\n"); - } - } - - for (ALL_LIST_ELEMENTS_RO(zif->rtadv.AdvRDNSSList, node, rdnss)) { - char buf[INET6_ADDRSTRLEN]; - - vty_out(vty, " ipv6 nd rdnss %s", - inet_ntop(AF_INET6, &rdnss->addr, buf, sizeof(buf))); - if (rdnss->lifetime_set) { - if (rdnss->lifetime == UINT32_MAX) - vty_out(vty, " infinite"); - else - vty_out(vty, " %u", rdnss->lifetime); - } - vty_out(vty, "\n"); - } - for (ALL_LIST_ELEMENTS_RO(zif->rtadv.AdvDNSSLList, node, dnssl)) { - vty_out(vty, " ipv6 nd dnssl %s", dnssl->name); - if (dnssl->lifetime_set) { - if (dnssl->lifetime == UINT32_MAX) - vty_out(vty, " infinite"); - else - vty_out(vty, " %u", dnssl->lifetime); - } - vty_out(vty, "\n"); - } - return 0; -} - - static void rtadv_event(struct zebra_vrf *zvrf, enum rtadv_event event, int val) { struct rtadv *rtadv; @@ -2917,49 +1858,8 @@ void rtadv_cmd_init(void) interfaces_configured_for_ra_from_bgp = 0; hook_register(zebra_if_extra_info, nd_dump_vty); - hook_register(zebra_if_config_wr, rtadv_config_write); install_element(VIEW_NODE, &show_ipv6_nd_ra_if_cmd); - - install_element(INTERFACE_NODE, &ipv6_nd_ra_fast_retrans_cmd); - install_element(INTERFACE_NODE, &no_ipv6_nd_ra_fast_retrans_cmd); - install_element(INTERFACE_NODE, &ipv6_nd_ra_retrans_interval_cmd); - install_element(INTERFACE_NODE, &no_ipv6_nd_ra_retrans_interval_cmd); - install_element(INTERFACE_NODE, &ipv6_nd_ra_hop_limit_cmd); - install_element(INTERFACE_NODE, &no_ipv6_nd_ra_hop_limit_cmd); - install_element(INTERFACE_NODE, &ipv6_nd_suppress_ra_cmd); - install_element(INTERFACE_NODE, &no_ipv6_nd_suppress_ra_cmd); - install_element(INTERFACE_NODE, &ipv6_nd_ra_interval_cmd); - install_element(INTERFACE_NODE, &ipv6_nd_ra_interval_msec_cmd); - install_element(INTERFACE_NODE, &no_ipv6_nd_ra_interval_cmd); - install_element(INTERFACE_NODE, &ipv6_nd_ra_lifetime_cmd); - install_element(INTERFACE_NODE, &no_ipv6_nd_ra_lifetime_cmd); - install_element(INTERFACE_NODE, &ipv6_nd_reachable_time_cmd); - install_element(INTERFACE_NODE, &no_ipv6_nd_reachable_time_cmd); - install_element(INTERFACE_NODE, &ipv6_nd_managed_config_flag_cmd); - install_element(INTERFACE_NODE, &no_ipv6_nd_managed_config_flag_cmd); - install_element(INTERFACE_NODE, &ipv6_nd_other_config_flag_cmd); - install_element(INTERFACE_NODE, &no_ipv6_nd_other_config_flag_cmd); - install_element(INTERFACE_NODE, &ipv6_nd_homeagent_config_flag_cmd); - install_element(INTERFACE_NODE, &no_ipv6_nd_homeagent_config_flag_cmd); - install_element(INTERFACE_NODE, &ipv6_nd_homeagent_preference_cmd); - install_element(INTERFACE_NODE, &no_ipv6_nd_homeagent_preference_cmd); - install_element(INTERFACE_NODE, &ipv6_nd_homeagent_lifetime_cmd); - install_element(INTERFACE_NODE, &no_ipv6_nd_homeagent_lifetime_cmd); - install_element(INTERFACE_NODE, - &ipv6_nd_adv_interval_config_option_cmd); - install_element(INTERFACE_NODE, - &no_ipv6_nd_adv_interval_config_option_cmd); - install_element(INTERFACE_NODE, &ipv6_nd_prefix_cmd); - install_element(INTERFACE_NODE, &no_ipv6_nd_prefix_cmd); - install_element(INTERFACE_NODE, &ipv6_nd_router_preference_cmd); - install_element(INTERFACE_NODE, &no_ipv6_nd_router_preference_cmd); - install_element(INTERFACE_NODE, &ipv6_nd_mtu_cmd); - install_element(INTERFACE_NODE, &no_ipv6_nd_mtu_cmd); - install_element(INTERFACE_NODE, &ipv6_nd_rdnss_cmd); - install_element(INTERFACE_NODE, &no_ipv6_nd_rdnss_cmd); - install_element(INTERFACE_NODE, &ipv6_nd_dnssl_cmd); - install_element(INTERFACE_NODE, &no_ipv6_nd_dnssl_cmd); } static int if_join_all_router(int sock, struct interface *ifp) diff --git a/zebra/rtadv.h b/zebra/rtadv.h index 9d358d4b0d..0983ea578f 100644 --- a/zebra/rtadv.h +++ b/zebra/rtadv.h @@ -385,6 +385,30 @@ extern void rtadv_if_fini(struct zebra_if *zif); extern void rtadv_add_prefix(struct zebra_if *zif, const struct prefix_ipv6 *p); extern void rtadv_delete_prefix(struct zebra_if *zif, const struct prefix *p); +/* returns created prefix */ +struct rtadv_prefix *rtadv_add_prefix_manual(struct zebra_if *zif, + struct rtadv_prefix *rp); +/* rprefix must be the one returned by rtadv_add_prefix_manual */ +void rtadv_delete_prefix_manual(struct zebra_if *zif, + struct rtadv_prefix *rprefix); + +/* returns created address */ +struct rtadv_rdnss *rtadv_rdnss_set(struct zebra_if *zif, + struct rtadv_rdnss *rdnss); +/* p must be the one returned by rtadv_rdnss_set */ +void rtadv_rdnss_reset(struct zebra_if *zif, struct rtadv_rdnss *p); + +/* returns created domain */ +struct rtadv_dnssl *rtadv_dnssl_set(struct zebra_if *zif, + struct rtadv_dnssl *dnssl); +/* p must be the one returned by rtadv_dnssl_set */ +void rtadv_dnssl_reset(struct zebra_if *zif, struct rtadv_dnssl *p); +int rtadv_dnssl_encode(uint8_t *out, const char *in); + +void ipv6_nd_suppress_ra_set(struct interface *ifp, + enum ipv6_nd_suppress_ra_status status); +void ipv6_nd_interval_set(struct interface *ifp, uint32_t interval); + #else /* !HAVE_RTADV */ struct rtadv { /* empty structs aren't valid ISO C */ diff --git a/zebra/subdir.am b/zebra/subdir.am index a59515d3a8..d9c8d9045e 100644 --- a/zebra/subdir.am +++ b/zebra/subdir.am @@ -28,7 +28,7 @@ man8 += $(MANBUILD)/frr-zebra.8 ## endif ZEBRA endif -zebra_zebra_LDADD = lib/libfrr.la $(LIBCAP) $(UST_LIBS) +zebra_zebra_LDADD = lib/libfrr.la $(LIBCAP) $(LIBYANG_LIBS) $(UST_LIBS) if HAVE_PROTOBUF3 zebra_zebra_LDADD += mlag/libmlag_pb.la $(PROTOBUF_C_LIBS) zebra/zebra_mlag.$(OBJEXT): mlag/mlag.pb-c.h @@ -118,7 +118,6 @@ clippy_scan += \ zebra/debug.c \ zebra/interface.c \ zebra/rtadv.c \ - zebra/zebra_evpn_mh.c \ zebra/zebra_mlag_vty.c \ zebra/zebra_routemap.c \ zebra/zebra_vty.c \ @@ -126,6 +125,7 @@ clippy_scan += \ zebra/zebra_vrf.c \ zebra/dpdk/zebra_dplane_dpdk_vty.c \ zebra/label_manager.c \ + zebra/zebra_cli.c \ # end noinst_HEADERS += \ diff --git a/zebra/table_manager.c b/zebra/table_manager.c index 512508b79f..8417a22114 100644 --- a/zebra/table_manager.c +++ b/zebra/table_manager.c @@ -24,21 +24,6 @@ #include "zebra/table_manager.h" #include "zebra/zebra_errors.h" -/* routing table identifiers - * - */ -#if !defined(GNU_LINUX) -/* BSD systems - */ -#else -/* Linux Systems - */ -#define RT_TABLE_ID_LOCAL 255 -#define RT_TABLE_ID_MAIN 254 -#define RT_TABLE_ID_DEFAULT 253 -#define RT_TABLE_ID_COMPAT 252 -#define RT_TABLE_ID_UNSPEC 0 -#endif /* !def(GNU_LINUX) */ #define RT_TABLE_ID_UNRESERVED_MIN 1 #define RT_TABLE_ID_UNRESERVED_MAX 0xffffffff @@ -279,52 +264,11 @@ void table_manager_disable(struct zebra_vrf *zvrf) zvrf->tbl_mgr = NULL; } -int table_manager_range(struct vty *vty, bool add, struct zebra_vrf *zvrf, - const char *start_table_str, const char *end_table_str) +void table_manager_range(bool add, struct zebra_vrf *zvrf, uint32_t start, + uint32_t end) { - uint32_t start; - uint32_t end; - - if (add) { - if (!start_table_str || !end_table_str) { - vty_out(vty, "%% Labels not specified\n"); - return CMD_WARNING_CONFIG_FAILED; - } - start = atoi(start_table_str); - end = atoi(end_table_str); - if (end < start) { - vty_out(vty, "%% End table is less than Start table\n"); - return CMD_WARNING_CONFIG_FAILED; - } - -#if !defined(GNU_LINUX) -/* BSD systems - */ -#else - /* Linux Systems - */ - if ((start >= RT_TABLE_ID_COMPAT && start <= RT_TABLE_ID_LOCAL) - || (end >= RT_TABLE_ID_COMPAT - && end <= RT_TABLE_ID_LOCAL)) { - vty_out(vty, "%% Values forbidden in range [%u;%u]\n", - RT_TABLE_ID_COMPAT, RT_TABLE_ID_LOCAL); - return CMD_WARNING_CONFIG_FAILED; - } - if (start < RT_TABLE_ID_COMPAT && end > RT_TABLE_ID_LOCAL) { - vty_out(vty, - "%% Range overlaps range [%u;%u] forbidden\n", - RT_TABLE_ID_COMPAT, RT_TABLE_ID_LOCAL); - return CMD_WARNING_CONFIG_FAILED; - } -#endif - if (zvrf->tbl_mgr - && ((zvrf->tbl_mgr->start && zvrf->tbl_mgr->start != start) - || (zvrf->tbl_mgr->end && zvrf->tbl_mgr->end != end))) { - vty_out(vty, - "%% New range will be taken into account at restart\n"); - } + if (add) table_range_add(zvrf, start, end); - } else + else table_range_add(zvrf, 0, 0); - return CMD_SUCCESS; } diff --git a/zebra/table_manager.h b/zebra/table_manager.h index f8e99a357d..21691994cb 100644 --- a/zebra/table_manager.h +++ b/zebra/table_manager.h @@ -18,6 +18,22 @@ extern "C" { #endif +/* routing table identifiers + * + */ +#if !defined(GNU_LINUX) +/* BSD systems + */ +#else +/* Linux Systems + */ +#define RT_TABLE_ID_LOCAL 255 +#define RT_TABLE_ID_MAIN 254 +#define RT_TABLE_ID_DEFAULT 253 +#define RT_TABLE_ID_COMPAT 252 +#define RT_TABLE_ID_UNSPEC 0 +#endif /* !def(GNU_LINUX) */ + /* * Table chunk struct * Client daemon which the chunk belongs to can be identified by either @@ -56,8 +72,8 @@ int release_table_chunk(uint8_t proto, uint16_t instance, uint32_t start, uint32_t end, struct zebra_vrf *zvrf); int release_daemon_table_chunks(struct zserv *client); void table_manager_disable(struct zebra_vrf *zvrf); -int table_manager_range(struct vty *vty, bool add, struct zebra_vrf *zvrf, - const char *min, const char *max); +void table_manager_range(bool add, struct zebra_vrf *zvrf, uint32_t start, + uint32_t end); #ifdef __cplusplus } diff --git a/zebra/zebra_cli.c b/zebra/zebra_cli.c new file mode 100644 index 0000000000..76b2df157e --- /dev/null +++ b/zebra/zebra_cli.c @@ -0,0 +1,2969 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "command.h" +#include "defaults.h" +#include "northbound_cli.h" +#include "vrf.h" + +#include "zebra_cli.h" +#include "zebra/zebra_cli_clippy.c" + +#define EVPN_MH_VTY_STR "Multihoming\n" + +FRR_CFG_DEFAULT_BOOL(ZEBRA_IP_NHT_RESOLVE_VIA_DEFAULT, + { .val_bool = true, .match_profile = "traditional", }, + { .val_bool = false }, +); + +#if HAVE_BFDD == 0 +DEFPY_YANG (zebra_ptm_enable, + zebra_ptm_enable_cmd, + "[no] ptm-enable", + NO_STR + "Enable neighbor check with specified topology\n") +{ + nb_cli_enqueue_change(vty, "/frr-zebra:zebra/ptm-enable", NB_OP_MODIFY, + no ? "false" : "true"); + return nb_cli_apply_changes(vty, NULL); +} + +static void zebra_ptm_enable_cli_write(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + bool enable = yang_dnode_get_bool(dnode, NULL); + + if (enable) + vty_out(vty, "ptm-enable\n"); + else if (show_defaults) + vty_out(vty, "no ptm-enable\n"); +} +#endif + +DEFPY_YANG (zebra_route_map_timer, + zebra_route_map_timer_cmd, + "[no] zebra route-map delay-timer ![(0-600)$delay]", + NO_STR + ZEBRA_STR + "Set route-map parameters\n" + "Time to wait before route-map updates are processed\n" + "0 means route-map changes are run immediately instead of delaying\n") +{ + if (!no) + nb_cli_enqueue_change(vty, "/frr-zebra:zebra/route-map-delay", + NB_OP_MODIFY, delay_str); + else + nb_cli_enqueue_change(vty, "/frr-zebra:zebra/route-map-delay", + NB_OP_DESTROY, NULL); + return nb_cli_apply_changes(vty, NULL); +} + +static void zebra_route_map_delay_cli_write(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + uint32_t delay = yang_dnode_get_uint32(dnode, NULL); + + vty_out(vty, "zebra route-map delay-timer %u\n", delay); +} + +DEFPY_YANG (multicast_new, + multicast_new_cmd, + "[no] multicast <enable$on|disable$off>", + NO_STR + "Control multicast flag on interface\n" + "Set multicast flag on interface\n" + "Unset multicast flag on interface\n") +{ + if (!no) + nb_cli_enqueue_change(vty, "./frr-zebra:zebra/multicast", + NB_OP_CREATE, on ? "true" : "false"); + else + nb_cli_enqueue_change(vty, "./frr-zebra:zebra/multicast", + NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +static void lib_interface_zebra_multicast_cli_write(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + bool multicast = yang_dnode_get_bool(dnode, NULL); + + if (multicast) + vty_out(vty, " multicast enable\n"); + else + vty_out(vty, " multicast disable\n"); +} + +/* Deprecated multicast commands */ + +DEFPY_YANG_HIDDEN (multicast, + multicast_cmd, + "[no] multicast", + NO_STR + "Set multicast flag to interface\n") +{ + nb_cli_enqueue_change(vty, "./frr-zebra:zebra/multicast", + NB_OP_CREATE, no ? "false" : "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG (mpls, + mpls_cmd, + "[no] mpls <enable$on|disable$off>", + NO_STR + MPLS_STR + "Set mpls to be on for the interface\n" + "Set mpls to be off for the interface\n") +{ + if (!no) + nb_cli_enqueue_change(vty, "./frr-zebra:zebra/mpls", + NB_OP_CREATE, on ? "true" : "false"); + else + nb_cli_enqueue_change(vty, "./frr-zebra:zebra/mpls", + NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +static void lib_interface_zebra_mpls_cli_write(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + bool mpls = yang_dnode_get_bool(dnode, NULL); + + if (mpls) + vty_out(vty, " mpls enable\n"); + else + vty_out(vty, " mpls disable\n"); +} + +DEFPY_YANG (linkdetect, + linkdetect_cmd, + "[no] link-detect", + NO_STR + "Enable link detection on interface\n") +{ + nb_cli_enqueue_change(vty, "./frr-zebra:zebra/link-detect", + NB_OP_CREATE, no ? "false" : "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +static void lib_interface_zebra_link_detect_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + bool link_detect = yang_dnode_get_bool(dnode, NULL); + + if (!link_detect) + vty_out(vty, " no link-detect\n"); + else if (show_defaults) + vty_out(vty, " link-detect\n"); +} + +DEFPY_YANG (shutdown_if, + shutdown_if_cmd, + "[no] shutdown", + NO_STR + "Shutdown the selected interface\n") +{ + nb_cli_enqueue_change(vty, "./frr-zebra:zebra/enabled", NB_OP_CREATE, + no ? "true" : "false"); + + return nb_cli_apply_changes(vty, NULL); +} + +static void lib_interface_zebra_enabled_cli_write(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + bool enabled = yang_dnode_get_bool(dnode, NULL); + + if (!enabled) + vty_out(vty, " shutdown\n"); + else if (show_defaults) + vty_out(vty, " no shutdown\n"); +} + +DEFPY_YANG (bandwidth_if, + bandwidth_if_cmd, + "[no] bandwidth ![(1-100000)]$bw", + NO_STR + "Set bandwidth informational parameter\n" + "Bandwidth in megabits\n") +{ + if (!no) + nb_cli_enqueue_change(vty, "./frr-zebra:zebra/bandwidth", + NB_OP_CREATE, bw_str); + else + nb_cli_enqueue_change(vty, "./frr-zebra:zebra/bandwidth", + NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +static void lib_interface_zebra_bandwidth_cli_write(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + uint32_t bandwidth = yang_dnode_get_uint32(dnode, NULL); + + vty_out(vty, " bandwidth %u\n", bandwidth); +} + +DEFUN_YANG_NOSH (link_params, + link_params_cmd, + "link-params", + LINK_PARAMS_STR) +{ + int ret; + + nb_cli_enqueue_change(vty, "./frr-zebra:zebra/link-params", + NB_OP_CREATE, NULL); + + ret = nb_cli_apply_changes(vty, NULL); + if (ret == CMD_SUCCESS) { + char *xpath; + + xpath = asprintfrr(MTYPE_TMP, "%s/frr-zebra:zebra/link-params", + VTY_CURR_XPATH); + VTY_PUSH_XPATH(LINK_PARAMS_NODE, xpath); + XFREE(MTYPE_TMP, xpath); + } + + return ret; +} + +DEFUN_NOSH (exit_link_params, + exit_link_params_cmd, + "exit-link-params", + "Exit from Link Params configuration mode\n") +{ + cmd_exit(vty); + return CMD_SUCCESS; +} + +static void lib_interface_zebra_link_params_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + vty_out(vty, " link-params\n"); +} + +static void +lib_interface_zebra_link_params_cli_write_end(struct vty *vty, + const struct lyd_node *dnode) +{ + vty_out(vty, " exit-link-params\n"); +} + +DEFUN_YANG (no_link_params, + no_link_params_cmd, + "no link-params", + NO_STR + LINK_PARAMS_STR) +{ + nb_cli_enqueue_change(vty, "./frr-zebra:zebra/link-params", NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +/* [no] enable is deprecated, link-params is enabled when entering the node. */ + +DEFUN_YANG_HIDDEN (link_params_enable, + link_params_enable_cmd, + "enable", + "Activate link parameters on this interface\n") +{ + vty_out(vty, "This command is deprecated. Link parameters are activated when \"link-params\" node is entered.\n"); + + return CMD_SUCCESS; +} + +DEFUN_YANG_NOSH (no_link_params_enable, + no_link_params_enable_cmd, + "no enable", + NO_STR + "Disable link parameters on this interface\n") +{ + int ret; + + vty_out(vty, "This command is deprecated. To disable link parameters use \"no link-params\" in the interface node.\n"); + + nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); + + ret = nb_cli_apply_changes(vty, NULL); + if (ret == CMD_SUCCESS) + cmd_exit(vty); + + return ret; +} + +DEFPY_YANG (link_params_metric, + link_params_metric_cmd, + "[no] metric ![(0-4294967295)]$metric", + NO_STR + "Link metric for MPLS-TE purpose\n" + "Metric value in decimal\n") +{ + if (!no) + nb_cli_enqueue_change(vty, "./metric", NB_OP_MODIFY, metric_str); + else + nb_cli_enqueue_change(vty, "./metric", NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +static void lib_interface_zebra_link_params_metric_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + uint32_t metric = yang_dnode_get_uint32(dnode, NULL); + + vty_out(vty, " metric %u\n", metric); +} + +DEFPY_YANG (link_params_maxbw, + link_params_maxbw_cmd, + "max-bw BANDWIDTH", + "Maximum bandwidth that can be used\n" + "Bytes/second (IEEE floating point format)\n") +{ + char value[YANG_VALUE_MAXLEN]; + float bw; + + if (sscanf(bandwidth, "%g", &bw) != 1) { + vty_out(vty, "Invalid bandwidth value\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + snprintf(value, sizeof(value), "%a", bw); + + nb_cli_enqueue_change(vty, "./max-bandwidth", NB_OP_MODIFY, value); + + return nb_cli_apply_changes(vty, NULL); +} + +static void lib_interface_zebra_link_params_max_bandwidth_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + float max_bandwidth = yang_dnode_get_bandwidth_ieee_float32(dnode, NULL); + + vty_out(vty, " max-bw %g\n", max_bandwidth); +} + +DEFPY_YANG (link_params_max_rsv_bw, + link_params_max_rsv_bw_cmd, + "max-rsv-bw BANDWIDTH", + "Maximum bandwidth that may be reserved\n" + "Bytes/second (IEEE floating point format)\n") +{ + char value[YANG_VALUE_MAXLEN]; + float bw; + + if (sscanf(bandwidth, "%g", &bw) != 1) { + vty_out(vty, "Invalid bandwidth value\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + snprintf(value, sizeof(value), "%a", bw); + + nb_cli_enqueue_change(vty, "./max-reservable-bandwidth", NB_OP_MODIFY, + value); + + return nb_cli_apply_changes(vty, NULL); +} + +static void lib_interface_zebra_link_params_max_reservable_bandwidth_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + float max_reservable_bandwidth = + yang_dnode_get_bandwidth_ieee_float32(dnode, NULL); + + vty_out(vty, " max-rsv-bw %g\n", max_reservable_bandwidth); +} + +DEFPY_YANG (link_params_unrsv_bw, + link_params_unrsv_bw_cmd, + "unrsv-bw (0-7)$priority BANDWIDTH", + "Unreserved bandwidth at each priority level\n" + "Priority\n" + "Bytes/second (IEEE floating point format)\n") +{ + char xpath[XPATH_MAXLEN]; + char value[YANG_VALUE_MAXLEN]; + float bw; + + if (sscanf(bandwidth, "%g", &bw) != 1) { + vty_out(vty, "Invalid bandwidth value\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + snprintf(xpath, sizeof(xpath), + "./unreserved-bandwidths/unreserved-bandwidth[priority='%s']/unreserved-bandwidth", + priority_str); + snprintf(value, sizeof(value), "%a", bw); + + nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, value); + + return nb_cli_apply_changes(vty, NULL); +} + +static void +lib_interface_zebra_link_params_unreserved_bandwidths_unreserved_bandwidth_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + uint8_t priority = yang_dnode_get_uint8(dnode, "priority"); + float unreserved_bandwidth = + yang_dnode_get_bandwidth_ieee_float32(dnode, + "unreserved-bandwidth"); + + vty_out(vty, " unrsv-bw %u %g\n", priority, unreserved_bandwidth); +} + +DEFPY_YANG (link_params_admin_grp, + link_params_admin_grp_cmd, + "[no] admin-grp ![BITPATTERN]", + NO_STR + "Administrative group membership\n" + "32-bit Hexadecimal value (e.g. 0xa1)\n") +{ + uint32_t value; + char value_str[YANG_VALUE_MAXLEN]; + + if (!no) { + if (bitpattern[0] != '0' || bitpattern[1] != 'x' || + strlen(bitpattern) > 10) { + vty_out(vty, "Invalid bitpattern value\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + sscanf(bitpattern, "%x", &value); + snprintf(value_str, sizeof(value_str), "%u", value); + + nb_cli_enqueue_change(vty, "./legacy-admin-group", NB_OP_MODIFY, + value_str); + } else { + nb_cli_enqueue_change(vty, "./legacy-admin-group", + NB_OP_DESTROY, NULL); + } + + return nb_cli_apply_changes(vty, NULL); +} + +static void lib_interface_zebra_link_params_legacy_admin_group_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + vty_out(vty, " admin-grp %#x\n", yang_dnode_get_uint32(dnode, NULL)); +} + +/* RFC5392 & RFC5316: INTER-AS */ +DEFPY_YANG (link_params_inter_as, + link_params_inter_as_cmd, + "[no] neighbor ![A.B.C.D$ip as (1-4294967295)$as]", + NO_STR + "Configure remote ASBR information (Neighbor IP address and AS number)\n" + "Remote IP address in dot decimal A.B.C.D\n" + "Remote AS number\n" + "AS number in the range <1-4294967295>\n") +{ + if (!no) { + nb_cli_enqueue_change(vty, "./neighbor", NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, "./neighbor/remote-as", NB_OP_MODIFY, + as_str); + nb_cli_enqueue_change(vty, "./neighbor/ipv4-remote-id", + NB_OP_MODIFY, ip_str); + } else { + nb_cli_enqueue_change(vty, "./neighbor", NB_OP_DESTROY, NULL); + } + + return nb_cli_apply_changes(vty, NULL); +} + +static void lib_interface_zebra_link_params_neighbor_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + uint32_t remote_as = yang_dnode_get_uint32(dnode, "remote-as"); + const char *ipv4_remote_id = yang_dnode_get_string(dnode, + "ipv4-remote-id"); + + vty_out(vty, " neighbor %s as %u\n", ipv4_remote_id, remote_as); +} + +/* RFC7471 & RFC8570 */ +DEFPY_YANG (link_params_delay, + link_params_delay_cmd, + "[no] delay ![(0-16777215)$delay [min (0-16777215)$min max (0-16777215)$max]]", + NO_STR + "Unidirectional Average Link Delay\n" + "Average delay in micro-second as decimal (0...16777215)\n" + "Minimum delay\n" + "Minimum delay in micro-second as decimal (0...16777215)\n" + "Maximum delay\n" + "Maximum delay in micro-second as decimal (0...16777215)\n") +{ + if (!no) { + nb_cli_enqueue_change(vty, "./delay", NB_OP_MODIFY, delay_str); + if (min_str && max_str) { + nb_cli_enqueue_change(vty, "./min-max-delay", + NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, "./min-max-delay/delay-min", + NB_OP_MODIFY, min_str); + nb_cli_enqueue_change(vty, "./min-max-delay/delay-max", + NB_OP_MODIFY, max_str); + } else { + nb_cli_enqueue_change(vty, "./min-max-delay", + NB_OP_DESTROY, NULL); + } + } else { + nb_cli_enqueue_change(vty, "./delay", NB_OP_DESTROY, NULL); + nb_cli_enqueue_change(vty, "./min-max-delay", NB_OP_DESTROY, + NULL); + } + + return nb_cli_apply_changes(vty, NULL); +} + +static void lib_interface_zebra_link_params_delay_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + uint32_t delay = yang_dnode_get_uint32(dnode, NULL); + + vty_out(vty, " delay %u", delay); + + if (yang_dnode_exists(dnode, "../min-max-delay")) { + uint32_t delay_min = + yang_dnode_get_uint32(dnode, + "../min-max-delay/delay-min"); + uint32_t delay_max = + yang_dnode_get_uint32(dnode, + "../min-max-delay/delay-max"); + + vty_out(vty, " min %u max %u", delay_min, delay_max); + } + + vty_out(vty, "\n"); +} + +DEFPY_YANG (link_params_delay_var, + link_params_delay_var_cmd, + "[no] delay-variation ![(0-16777215)$delay_var]", + NO_STR + "Unidirectional Link Delay Variation\n" + "delay variation in micro-second as decimal (0...16777215)\n") +{ + if (!no) + nb_cli_enqueue_change(vty, "./delay-variation", NB_OP_MODIFY, + delay_var_str); + else + nb_cli_enqueue_change(vty, "./delay-variation", NB_OP_DESTROY, + NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +static void lib_interface_zebra_link_params_delay_variation_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + uint32_t delay_variation = yang_dnode_get_uint32(dnode, NULL); + + vty_out(vty, " delay-variation %u\n", delay_variation); +} + +DEFPY_YANG( + link_params_pkt_loss, link_params_pkt_loss_cmd, + "[no] packet-loss ![PERCENTAGE]", + NO_STR + "Unidirectional Link Packet Loss\n" + "percentage of total traffic by 0.000003% step and less than 50.331642%\n") +{ + if (!no) + nb_cli_enqueue_change(vty, "./packet-loss", NB_OP_MODIFY, + percentage); + else + nb_cli_enqueue_change(vty, "./packet-loss", NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +static void lib_interface_zebra_link_params_packet_loss_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + double packet_loss = yang_dnode_get_dec64(dnode, NULL); + + vty_out(vty, " packet-loss %lf\n", packet_loss); +} + +DEFPY_YANG (link_params_res_bw, + link_params_res_bw_cmd, + "[no] res-bw ![BANDWIDTH]", + NO_STR + "Unidirectional Residual Bandwidth\n" + "Bytes/second (IEEE floating point format)\n") +{ + char value[YANG_VALUE_MAXLEN]; + float bw; + + if (!no) { + if (sscanf(bandwidth, "%g", &bw) != 1) { + vty_out(vty, "Invalid bandwidth value\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + snprintf(value, sizeof(value), "%a", bw); + + nb_cli_enqueue_change(vty, "./residual-bandwidth", NB_OP_MODIFY, + value); + } else { + nb_cli_enqueue_change(vty, "./residual-bandwidth", + NB_OP_DESTROY, NULL); + } + + return nb_cli_apply_changes(vty, NULL); +} + +static void lib_interface_zebra_link_params_residual_bandwidth_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + float residual_bandwidth = yang_dnode_get_bandwidth_ieee_float32(dnode, + NULL); + + vty_out(vty, " res-bw %g\n", residual_bandwidth); +} + +DEFPY_YANG (link_params_ava_bw, + link_params_ava_bw_cmd, + "[no] ava-bw ![BANDWIDTH]", + NO_STR + "Unidirectional Available Bandwidth\n" + "Bytes/second (IEEE floating point format)\n") +{ + char value[YANG_VALUE_MAXLEN]; + float bw; + + if (!no) { + if (sscanf(bandwidth, "%g", &bw) != 1) { + vty_out(vty, "Invalid bandwidth value\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + snprintf(value, sizeof(value), "%a", bw); + + nb_cli_enqueue_change(vty, "./available-bandwidth", + NB_OP_MODIFY, value); + } else { + nb_cli_enqueue_change(vty, "./available-bandwidth", + NB_OP_DESTROY, NULL); + } + + return nb_cli_apply_changes(vty, NULL); +} + +static void lib_interface_zebra_link_params_available_bandwidth_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + float available_bandwidth = yang_dnode_get_bandwidth_ieee_float32(dnode, + NULL); + + vty_out(vty, " ava-bw %g\n", available_bandwidth); +} + +DEFPY_YANG (link_params_use_bw, + link_params_use_bw_cmd, + "[no] use-bw ![BANDWIDTH]", + NO_STR + "Unidirectional Utilised Bandwidth\n" + "Bytes/second (IEEE floating point format)\n") +{ + char value[YANG_VALUE_MAXLEN]; + float bw; + + if (!no) { + if (sscanf(bandwidth, "%g", &bw) != 1) { + vty_out(vty, "Invalid bandwidth value\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + snprintf(value, sizeof(value), "%a", bw); + + nb_cli_enqueue_change(vty, "./utilized-bandwidth", NB_OP_MODIFY, + value); + } else { + nb_cli_enqueue_change(vty, "./utilized-bandwidth", + NB_OP_DESTROY, NULL); + } + + return nb_cli_apply_changes(vty, NULL); +} + +static void lib_interface_zebra_link_params_utilized_bandwidth_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + float utilized_bandwidth = yang_dnode_get_bandwidth_ieee_float32(dnode, + NULL); + + vty_out(vty, " use-bw %g\n", utilized_bandwidth); +} + +DEFPY_YANG (link_params_affinity, + link_params_affinity_cmd, + "[no] affinity NAME...", + NO_STR + "Interface affinities\n" + "Affinity names\n") +{ + char xpath[XPATH_MAXLEN]; + int i; + + for (i = no ? 2 : 1; i < argc; i++) { + snprintf(xpath, XPATH_MAXLEN, "./affinities/affinity[.='%s']", + argv[i]->arg); + nb_cli_enqueue_change(vty, xpath, + no ? NB_OP_DESTROY : NB_OP_CREATE, NULL); + } + + return nb_cli_apply_changes(vty, NULL); +} + +static int ag_iter_cb(const struct lyd_node *dnode, void *arg) +{ + struct vty *vty = arg; + + vty_out(vty, " %s", yang_dnode_get_string(dnode, NULL)); + return YANG_ITER_CONTINUE; +} + +static void lib_interface_zebra_link_params_affinities_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + vty_out(vty, " affinity"); + yang_dnode_iterate(ag_iter_cb, vty, dnode, "affinity"); + vty_out(vty, "\n"); +} + +DEFPY_YANG (link_params_affinity_mode, + link_params_affinity_mode_cmd, + "[no] affinity-mode ![<standard|extended|both>$mode]", + NO_STR + "Interface affinity mode\n" + "Standard Admin-Group only RFC3630,5305,5329\n" + "Extended Admin-Group only RFC7308 (default)\n" + "Standard and extended Admin-Group format\n") +{ + if (!no) + nb_cli_enqueue_change(vty, "./affinity-mode", NB_OP_MODIFY, + mode); + else + nb_cli_enqueue_change(vty, "./affinity-mode", NB_OP_DESTROY, + NULL); + return nb_cli_apply_changes(vty, NULL); +} + +static void lib_interface_zebra_link_params_affinity_mode_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + enum affinity_mode affinity_mode = yang_dnode_get_enum(dnode, NULL); + + if (affinity_mode == AFFINITY_MODE_STANDARD) + vty_out(vty, " affinity-mode standard\n"); + else if (affinity_mode == AFFINITY_MODE_BOTH) + vty_out(vty, " affinity-mode both\n"); + else if (affinity_mode == AFFINITY_MODE_EXTENDED && show_defaults) + vty_out(vty, " affinity-mode extended\n"); +} + +#ifdef HAVE_NETLINK +DEFPY_YANG (ip_address, + ip_address_cmd, + "[no] ip address A.B.C.D/M [label LINE$label]", + NO_STR + "Interface Internet Protocol config commands\n" + "Set the IP address of an interface\n" + "IP address (e.g. 10.0.0.1/8)\n" + "Label of this address\n" + "Label\n") +#else +DEFPY_YANG (ip_address, + ip_address_cmd, + "[no] ip address A.B.C.D/M", + NO_STR + "Interface Internet Protocol config commands\n" + "Set the IP address of an interface\n" + "IP address (e.g. 10.0.0.1/8)\n") +#endif +{ + char ip[INET_ADDRSTRLEN + 3]; + char *mask; + + if (no) { + nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); + } else { + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); +#ifdef HAVE_NETLINK + if (label) + nb_cli_enqueue_change(vty, "./label", NB_OP_MODIFY, + label); + else + nb_cli_enqueue_change(vty, "./label", NB_OP_DESTROY, + NULL); +#endif + } + + strlcpy(ip, address_str, sizeof(ip)); + + mask = strchr(ip, '/'); + *mask = 0; + mask++; + + return nb_cli_apply_changes(vty, + "./frr-zebra:zebra/ipv4-addrs[ip='%s'][prefix-length='%s']", + ip, mask); +} + +static void lib_interface_zebra_ipv4_addrs_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + const char *ip = yang_dnode_get_string(dnode, "ip"); + uint8_t prefix_length = yang_dnode_get_uint8(dnode, "prefix-length"); + + vty_out(vty, " ip address %s/%u", ip, prefix_length); + + if (yang_dnode_exists(dnode, "label")) { + const char *label = yang_dnode_get_string(dnode, "label"); + + vty_out(vty, " label %s", label); + } + + vty_out(vty, "\n"); +} + +#ifdef HAVE_NETLINK +DEFPY_YANG (ip_address_peer, + ip_address_peer_cmd, + "[no] ip address A.B.C.D peer A.B.C.D/M [label LINE$label]", + NO_STR + "Interface Internet Protocol config commands\n" + "Set the IP address of an interface\n" + "Local IP (e.g. 10.0.0.1) for P-t-P address\n" + "Specify P-t-P address\n" + "Peer IP address (e.g. 10.0.0.1/8)\n" + "Label of this address\n" + "Label\n") +#else +DEFPY_YANG (ip_address_peer, + ip_address_peer_cmd, + "[no] ip address A.B.C.D peer A.B.C.D/M", + NO_STR + "Interface Internet Protocol config commands\n" + "Set the IP address of an interface\n" + "Local IP (e.g. 10.0.0.1) for P-t-P address\n" + "Specify P-t-P address\n" + "Peer IP address (e.g. 10.0.0.1/8)\n") +#endif +{ + char peer_ip[INET_ADDRSTRLEN + 3]; + char *peer_mask; + + if (no) { + nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); + } else { + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); +#ifdef HAVE_NETLINK + if (label) + nb_cli_enqueue_change(vty, "./label", NB_OP_MODIFY, + label); + else + nb_cli_enqueue_change(vty, "./label", NB_OP_DESTROY, + NULL); +#endif + } + + strlcpy(peer_ip, peer_str, sizeof(peer_ip)); + + peer_mask = strchr(peer_ip, '/'); + *peer_mask = 0; + peer_mask++; + + return nb_cli_apply_changes( + vty, + "./frr-zebra:zebra/ipv4-p2p-addrs[ip='%s'][peer-ip='%s'][peer-prefix-length='%s']", + address_str, peer_ip, peer_mask); +} + +static void lib_interface_zebra_ipv4_p2p_addrs_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + const char *ip = yang_dnode_get_string(dnode, "ip"); + const char *peer_ip = yang_dnode_get_string(dnode, "peer-ip"); + uint8_t peer_prefix_length = yang_dnode_get_uint8(dnode, + "peer-prefix-length"); + + vty_out(vty, " ip address %s peer %s/%u", ip, peer_ip, + peer_prefix_length); + + if (yang_dnode_exists(dnode, "label")) { + const char *label = yang_dnode_get_string(dnode, "label"); + + vty_out(vty, " label %s", label); + } + + vty_out(vty, "\n"); +} + +DEFPY_YANG (ipv6_address, + ipv6_address_cmd, + "[no] ipv6 address X:X::X:X/M", + NO_STR + "Interface IPv6 config commands\n" + "Set the IP address of an interface\n" + "IPv6 address (e.g. 3ffe:506::1/48)\n") +{ + char ip[INET6_ADDRSTRLEN + 4]; + char *mask; + + if (no) + nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); + else + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + + strlcpy(ip, address_str, sizeof(ip)); + + mask = strchr(ip, '/'); + *mask = 0; + mask++; + + return nb_cli_apply_changes(vty, + "./frr-zebra:zebra/ipv6-addrs[ip='%s'][prefix-length='%s']", + ip, mask); +} + +static void lib_interface_zebra_ipv6_addrs_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + const char *ip = yang_dnode_get_string(dnode, "ip"); + uint8_t prefix_length = yang_dnode_get_uint8(dnode, "prefix-length"); + + vty_out(vty, " ipv6 address %s/%u\n", ip, prefix_length); +} + +/* CLI for setting an ES in bypass mode */ +DEFPY_YANG_HIDDEN (zebra_evpn_es_bypass, + zebra_evpn_es_bypass_cmd, + "[no] evpn mh bypass", + NO_STR + "EVPN\n" + EVPN_MH_VTY_STR + "Set bypass mode\n") +{ + if (!no) + nb_cli_enqueue_change(vty, "./frr-zebra:zebra/evpn-mh/bypass", + NB_OP_MODIFY, "true"); + else + nb_cli_enqueue_change(vty, "./frr-zebra:zebra/evpn-mh/bypass", + NB_OP_DESTROY, NULL); + return nb_cli_apply_changes(vty, NULL); +} + +static void lib_interface_zebra_evpn_mh_bypass_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + bool bypass = yang_dnode_get_bool(dnode, NULL); + + if (bypass) + vty_out(vty, " evpn mh bypass\n"); + else if (show_defaults) + vty_out(vty, " no evpn mh bypass\n"); +} + +/* CLI for configuring DF preference part for an ES */ +DEFPY_YANG (zebra_evpn_es_pref, + zebra_evpn_es_pref_cmd, + "[no$no] evpn mh es-df-pref ![(1-65535)$df_pref]", + NO_STR + "EVPN\n" + EVPN_MH_VTY_STR + "Preference value used for DF election\n" + "Preference\n") +{ + if (!no) + nb_cli_enqueue_change(vty, + "./frr-zebra:zebra/evpn-mh/df-preference", + NB_OP_MODIFY, df_pref_str); + else + nb_cli_enqueue_change(vty, + "./frr-zebra:zebra/evpn-mh/df-preference", + NB_OP_DESTROY, NULL); + return nb_cli_apply_changes(vty, NULL); +} + +static void lib_interface_zebra_evpn_mh_df_preference_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + uint16_t df_pref = yang_dnode_get_uint16(dnode, NULL); + + vty_out(vty, " evpn mh es-df-pref %u\n", df_pref); +} + +/* CLI for setting up sysmac part of ESI on an access port */ +DEFPY_YANG (zebra_evpn_es_sys_mac, + zebra_evpn_es_sys_mac_cmd, + "[no$no] evpn mh es-sys-mac ![X:X:X:X:X:X$mac]", + NO_STR + "EVPN\n" + EVPN_MH_VTY_STR + "Ethernet segment system MAC\n" + MAC_STR) +{ + if (!no) + nb_cli_enqueue_change(vty, + "./frr-zebra:zebra/evpn-mh/type-3/system-mac", + NB_OP_MODIFY, mac_str); + else + nb_cli_enqueue_change(vty, + "./frr-zebra:zebra/evpn-mh/type-3/system-mac", + NB_OP_DESTROY, NULL); + return nb_cli_apply_changes(vty, NULL); +} + +static void lib_interface_zebra_evpn_mh_type_3_system_mac_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + char buf[ETHER_ADDR_STRLEN]; + struct ethaddr mac; + + yang_dnode_get_mac(&mac, dnode, NULL); + + vty_out(vty, " evpn mh es-sys-mac %s\n", + prefix_mac2str(&mac, buf, sizeof(buf))); +} + +/* CLI for setting up local-ID part of ESI on an access port */ +DEFPY_YANG (zebra_evpn_es_id, + zebra_evpn_es_id_cmd, + "[no$no] evpn mh es-id ![(1-16777215)$es_lid | NAME$esi_str]", + NO_STR + "EVPN\n" + EVPN_MH_VTY_STR + "Ethernet segment identifier\n" + "local discriminator\n" + "10-byte ID - 00:AA:BB:CC:DD:EE:FF:GG:HH:II\n") +{ + if (no) { + /* We don't know which one is configured, so detroy both types. */ + nb_cli_enqueue_change(vty, + "./frr-zebra:zebra/evpn-mh/type-0/esi", + NB_OP_DESTROY, NULL); + nb_cli_enqueue_change(vty, + "./frr-zebra:zebra/evpn-mh/type-3/local-discriminator", + NB_OP_DESTROY, NULL); + } else { + if (esi_str) + nb_cli_enqueue_change(vty, + "./frr-zebra:zebra/evpn-mh/type-0/esi", + NB_OP_MODIFY, esi_str); + else + nb_cli_enqueue_change(vty, + "./frr-zebra:zebra/evpn-mh/type-3/local-discriminator", + NB_OP_MODIFY, es_lid_str); + } + return nb_cli_apply_changes(vty, NULL); +} + +static void lib_interface_zebra_evpn_mh_type_0_esi_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + const char *esi_str = yang_dnode_get_string(dnode, NULL); + + vty_out(vty, " evpn mh es-id %s\n", esi_str); +} + +static void lib_interface_zebra_evpn_mh_type_3_local_discriminator_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + uint32_t es_lid = yang_dnode_get_uint32(dnode, NULL); + + vty_out(vty, " evpn mh es-id %u\n", es_lid); +} + +/* CLI for tagging an interface as an uplink */ +DEFPY_YANG (zebra_evpn_mh_uplink, + zebra_evpn_mh_uplink_cmd, + "[no] evpn mh uplink", + NO_STR + "EVPN\n" + EVPN_MH_VTY_STR + "Uplink to the VxLAN core\n") +{ + if (!no) + nb_cli_enqueue_change(vty, "./frr-zebra:zebra/evpn-mh/uplink", + NB_OP_MODIFY, "true"); + else + nb_cli_enqueue_change(vty, "./frr-zebra:zebra/evpn-mh/uplink", + NB_OP_DESTROY, NULL); + return nb_cli_apply_changes(vty, NULL); +} + +static void lib_interface_zebra_evpn_mh_uplink_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + bool uplink = yang_dnode_get_bool(dnode, NULL); + + if (uplink) + vty_out(vty, " evpn mh uplink\n"); + else if (show_defaults) + vty_out(vty, " no evpn mh uplink\n"); +} + +#if defined(HAVE_RTADV) +DEFPY_YANG (ipv6_nd_ra_fast_retrans, + ipv6_nd_ra_fast_retrans_cmd, + "[no] ipv6 nd ra-fast-retrans", + NO_STR + "Interface IPv6 config commands\n" + "Neighbor discovery\n" + "Fast retransmit of RA packets\n") +{ + if (no) + nb_cli_enqueue_change(vty, + "./frr-zebra:zebra/ipv6-router-advertisements/fast-retransmit", + NB_OP_MODIFY, "false"); + else + nb_cli_enqueue_change(vty, + "./frr-zebra:zebra/ipv6-router-advertisements/fast-retransmit", + NB_OP_DESTROY, NULL); + return nb_cli_apply_changes(vty, NULL); +} + +static void +lib_interface_zebra_ipv6_router_advertisements_fast_retransmit_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + bool fast_retransmit = yang_dnode_get_bool(dnode, NULL); + + if (!fast_retransmit) + vty_out(vty, " no ipv6 nd ra-fast-retrans\n"); + else if (show_defaults) + vty_out(vty, " ipv6 nd ra-fast-retrans\n"); +} + +DEFPY_YANG (ipv6_nd_ra_hop_limit, + ipv6_nd_ra_hop_limit_cmd, + "[no] ipv6 nd ra-hop-limit ![(0-255)$hopcount]", + NO_STR + "Interface IPv6 config commands\n" + "Neighbor discovery\n" + "Advertisement Hop Limit\n" + "Advertisement Hop Limit in hops (default:64)\n") +{ + if (!no) + nb_cli_enqueue_change(vty, + "./frr-zebra:zebra/ipv6-router-advertisements/cur-hop-limit", + NB_OP_MODIFY, hopcount_str); + else + nb_cli_enqueue_change(vty, + "./frr-zebra:zebra/ipv6-router-advertisements/cur-hop-limit", + NB_OP_DESTROY, NULL); + return nb_cli_apply_changes(vty, NULL); +} + +static void +lib_interface_zebra_ipv6_router_advertisements_cur_hop_limit_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + uint8_t hop_limit = yang_dnode_get_uint8(dnode, NULL); + + vty_out(vty, " ipv6 nd ra-hop-limit %u\n", hop_limit); +} + +DEFPY_YANG (ipv6_nd_ra_retrans_interval, + ipv6_nd_ra_retrans_interval_cmd, + "[no] ipv6 nd ra-retrans-interval ![(0-4294967295)$interval]", + NO_STR + "Interface IPv6 config commands\n" + "Neighbor discovery\n" + "Advertisement Retransmit Interval\n" + "Advertisement Retransmit Interval in msec\n") +{ + if (!no) + nb_cli_enqueue_change(vty, + "./frr-zebra:zebra/ipv6-router-advertisements/retrans-timer", + NB_OP_MODIFY, interval_str); + else + nb_cli_enqueue_change(vty, + "./frr-zebra:zebra/ipv6-router-advertisements/retrans-timer", + NB_OP_DESTROY, NULL); + return nb_cli_apply_changes(vty, NULL); +} + +static void +lib_interface_zebra_ipv6_router_advertisements_retrans_timer_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + uint32_t retrans_timer = yang_dnode_get_uint32(dnode, NULL); + + vty_out(vty, " ipv6 nd ra-retrans-interval %u\n", retrans_timer); +} + +DEFPY_YANG (ipv6_nd_suppress_ra, + ipv6_nd_suppress_ra_cmd, + "[no] ipv6 nd suppress-ra", + NO_STR + "Interface IPv6 config commands\n" + "Neighbor discovery\n" + "Suppress Router Advertisement\n") +{ + if (no) + nb_cli_enqueue_change(vty, + "./frr-zebra:zebra/ipv6-router-advertisements/send-advertisements", + NB_OP_MODIFY, "true"); + else + nb_cli_enqueue_change(vty, + "./frr-zebra:zebra/ipv6-router-advertisements/send-advertisements", + NB_OP_DESTROY, NULL); + return nb_cli_apply_changes(vty, NULL); +} + +static void +lib_interface_zebra_ipv6_router_advertisements_send_advertisements_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + bool send_advertisements = yang_dnode_get_bool(dnode, NULL); + + if (send_advertisements) + vty_out(vty, " no ipv6 nd suppress-ra\n"); + else if (show_defaults) + vty_out(vty, " ipv6 nd suppress-ra\n"); +} + +DEFPY_YANG (ipv6_nd_ra_interval, + ipv6_nd_ra_interval_cmd, + "[no] ipv6 nd ra-interval ![<(1-1800)$sec|msec (70-1800000)$msec>]", + NO_STR + "Interface IPv6 config commands\n" + "Neighbor discovery\n" + "Router Advertisement interval\n" + "Router Advertisement interval in seconds\n" + "Router Advertisement interval in milliseconds\n" + "Router Advertisement interval in milliseconds\n") +{ + char value[YANG_VALUE_MAXLEN]; + + if (!no) { + if (sec) + snprintf(value, sizeof(value), "%lu", sec * 1000); + else + snprintf(value, sizeof(value), "%lu", msec); + + nb_cli_enqueue_change(vty, + "./frr-zebra:zebra/ipv6-router-advertisements/max-rtr-adv-interval", + NB_OP_MODIFY, value); + } else { + nb_cli_enqueue_change(vty, + "./frr-zebra:zebra/ipv6-router-advertisements/max-rtr-adv-interval", + NB_OP_DESTROY, NULL); + } + return nb_cli_apply_changes(vty, NULL); +} + +static void +lib_interface_zebra_ipv6_router_advertisements_max_rtr_adv_interval_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + uint32_t max_rtr_adv_interval = yang_dnode_get_uint32(dnode, NULL); + + if (max_rtr_adv_interval % 1000) + vty_out(vty, " ipv6 nd ra-interval msec %u\n", + max_rtr_adv_interval); + else + vty_out(vty, " ipv6 nd ra-interval %u\n", + max_rtr_adv_interval / 1000); +} + +DEFPY_YANG (ipv6_nd_ra_lifetime, + ipv6_nd_ra_lifetime_cmd, + "[no] ipv6 nd ra-lifetime ![(0-9000)$lifetime]", + NO_STR + "Interface IPv6 config commands\n" + "Neighbor discovery\n" + "Router lifetime\n" + "Router lifetime in seconds (0 stands for a non-default gw)\n") +{ + if (!no) + nb_cli_enqueue_change(vty, + "./frr-zebra:zebra/ipv6-router-advertisements/default-lifetime", + NB_OP_MODIFY, lifetime_str); + else + nb_cli_enqueue_change(vty, + "./frr-zebra:zebra/ipv6-router-advertisements/default-lifetime", + NB_OP_DESTROY, NULL); + return nb_cli_apply_changes(vty, NULL); +} + +static void +lib_interface_zebra_ipv6_router_advertisements_default_lifetime_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + uint16_t default_lifetime = yang_dnode_get_uint16(dnode, NULL); + + vty_out(vty, " ipv6 nd ra-lifetime %u\n", default_lifetime); +} + +DEFPY_YANG (ipv6_nd_reachable_time, + ipv6_nd_reachable_time_cmd, + "[no] ipv6 nd reachable-time ![(1-3600000)$msec]", + NO_STR + "Interface IPv6 config commands\n" + "Neighbor discovery\n" + "Reachable time\n" + "Reachable time in milliseconds\n") +{ + if (!no) + nb_cli_enqueue_change(vty, + "./frr-zebra:zebra/ipv6-router-advertisements/reachable-time", + NB_OP_MODIFY, msec_str); + else + nb_cli_enqueue_change(vty, + "./frr-zebra:zebra/ipv6-router-advertisements/reachable-time", + NB_OP_DESTROY, NULL); + return nb_cli_apply_changes(vty, NULL); +} + +static void +lib_interface_zebra_ipv6_router_advertisements_reachable_time_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + uint32_t reachable_time = yang_dnode_get_uint32(dnode, NULL); + + vty_out(vty, " ipv6 nd reachable-time %u\n", reachable_time); +} + +DEFPY_YANG (ipv6_nd_homeagent_preference, + ipv6_nd_homeagent_preference_cmd, + "[no] ipv6 nd home-agent-preference ![(0-65535)$pref]", + NO_STR + "Interface IPv6 config commands\n" + "Neighbor discovery\n" + "Home Agent preference\n" + "preference value (default is 0, least preferred)\n") +{ + if (!no) + nb_cli_enqueue_change(vty, + "./frr-zebra:zebra/ipv6-router-advertisements/home-agent-preference", + NB_OP_MODIFY, pref_str); + else + nb_cli_enqueue_change(vty, + "./frr-zebra:zebra/ipv6-router-advertisements/home-agent-preference", + NB_OP_DESTROY, NULL); + return nb_cli_apply_changes(vty, NULL); +} + +static void +lib_interface_zebra_ipv6_router_advertisements_home_agent_preference_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + uint16_t home_agent_preference = yang_dnode_get_uint16(dnode, NULL); + + vty_out(vty, " ipv6 nd home-agent-preference %u\n", + home_agent_preference); +} + +DEFPY_YANG (ipv6_nd_homeagent_lifetime, + ipv6_nd_homeagent_lifetime_cmd, + "[no] ipv6 nd home-agent-lifetime ![(1-65520)$lifetime]", + NO_STR + "Interface IPv6 config commands\n" + "Neighbor discovery\n" + "Home Agent lifetime\n" + "Home Agent lifetime in seconds\n") +{ + if (!no) + nb_cli_enqueue_change(vty, + "./frr-zebra:zebra/ipv6-router-advertisements/home-agent-lifetime", + NB_OP_MODIFY, lifetime_str); + else + nb_cli_enqueue_change(vty, + "./frr-zebra:zebra/ipv6-router-advertisements/home-agent-lifetime", + NB_OP_DESTROY, NULL); + return nb_cli_apply_changes(vty, NULL); +} + +static void +lib_interface_zebra_ipv6_router_advertisements_home_agent_lifetime_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + uint16_t home_agent_lifetime = yang_dnode_get_uint16(dnode, NULL); + + vty_out(vty, " ipv6 nd home-agent-lifetime %u\n", home_agent_lifetime); +} + +DEFPY_YANG (ipv6_nd_managed_config_flag, + ipv6_nd_managed_config_flag_cmd, + "[no] ipv6 nd managed-config-flag", + NO_STR + "Interface IPv6 config commands\n" + "Neighbor discovery\n" + "Managed address configuration flag\n") +{ + if (!no) + nb_cli_enqueue_change(vty, + "./frr-zebra:zebra/ipv6-router-advertisements/managed-flag", + NB_OP_MODIFY, "true"); + else + nb_cli_enqueue_change(vty, + "./frr-zebra:zebra/ipv6-router-advertisements/managed-flag", + NB_OP_DESTROY, NULL); + return nb_cli_apply_changes(vty, NULL); +} + +static void lib_interface_zebra_ipv6_router_advertisements_managed_flag_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + bool managed_flag = yang_dnode_get_bool(dnode, NULL); + + if (managed_flag) + vty_out(vty, " ipv6 nd managed-config-flag\n"); + else if (show_defaults) + vty_out(vty, " no ipv6 nd managed-config-flag\n"); +} + +DEFPY_YANG (ipv6_nd_homeagent_config_flag, + ipv6_nd_homeagent_config_flag_cmd, + "[no] ipv6 nd home-agent-config-flag", + NO_STR + "Interface IPv6 config commands\n" + "Neighbor discovery\n" + "Home Agent configuration flag\n") +{ + if (!no) + nb_cli_enqueue_change(vty, + "./frr-zebra:zebra/ipv6-router-advertisements/home-agent-flag", + NB_OP_MODIFY, "true"); + else + nb_cli_enqueue_change(vty, + "./frr-zebra:zebra/ipv6-router-advertisements/home-agent-flag", + NB_OP_DESTROY, NULL); + return nb_cli_apply_changes(vty, NULL); +} + +static void +lib_interface_zebra_ipv6_router_advertisements_home_agent_flag_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + bool home_agent_flag = yang_dnode_get_bool(dnode, NULL); + + if (home_agent_flag) + vty_out(vty, " ipv6 nd home-agent-config-flag\n"); + else if (show_defaults) + vty_out(vty, " no ipv6 nd home-agent-config-flag\n"); +} + +DEFPY_YANG (ipv6_nd_adv_interval_config_option, + ipv6_nd_adv_interval_config_option_cmd, + "[no] ipv6 nd adv-interval-option", + NO_STR + "Interface IPv6 config commands\n" + "Neighbor discovery\n" + "Advertisement Interval Option\n") +{ + if (!no) + nb_cli_enqueue_change(vty, + "./frr-zebra:zebra/ipv6-router-advertisements/advertisement-interval-option", + NB_OP_MODIFY, "true"); + else + nb_cli_enqueue_change(vty, + "./frr-zebra:zebra/ipv6-router-advertisements/advertisement-interval-option", + NB_OP_DESTROY, NULL); + return nb_cli_apply_changes(vty, NULL); +} + +static void +lib_interface_zebra_ipv6_router_advertisements_advertisement_interval_option_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + bool advertisement_interval_option = yang_dnode_get_bool(dnode, NULL); + + if (advertisement_interval_option) + vty_out(vty, " ipv6 nd adv-interval-option\n"); + else if (show_defaults) + vty_out(vty, " no ipv6 nd adv-interval-option\n"); +} + +DEFPY_YANG (ipv6_nd_other_config_flag, + ipv6_nd_other_config_flag_cmd, + "[no] ipv6 nd other-config-flag", + NO_STR + "Interface IPv6 config commands\n" + "Neighbor discovery\n" + "Other statefull configuration flag\n") +{ + if (!no) + nb_cli_enqueue_change(vty, + "./frr-zebra:zebra/ipv6-router-advertisements/other-config-flag", + NB_OP_MODIFY, "true"); + else + nb_cli_enqueue_change(vty, + "./frr-zebra:zebra/ipv6-router-advertisements/other-config-flag", + NB_OP_DESTROY, NULL); + return nb_cli_apply_changes(vty, NULL); +} + +static void +lib_interface_zebra_ipv6_router_advertisements_other_config_flag_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + bool other_config_flag = yang_dnode_get_bool(dnode, NULL); + + if (other_config_flag) + vty_out(vty, " ipv6 nd other-config-flag\n"); + else if (show_defaults) + vty_out(vty, " no ipv6 nd other-config-flag\n"); +} + +DEFPY_YANG (ipv6_nd_prefix, + ipv6_nd_prefix_cmd, + "[no] ipv6 nd prefix X:X::X:X/M$prefix [<(0-4294967295)|infinite>$valid <(0-4294967295)|infinite>$preferred] [{router-address$routeraddr|off-link$offlink|no-autoconfig$noautoconf}]", + NO_STR + "Interface IPv6 config commands\n" + "Neighbor discovery\n" + "Prefix information\n" + "IPv6 prefix\n" + "Valid lifetime in seconds\n" + "Infinite valid lifetime\n" + "Preferred lifetime in seconds\n" + "Infinite preferred lifetime\n" + "Set Router Address flag\n" + "Do not use prefix for onlink determination\n" + "Do not use prefix for autoconfiguration\n") +{ + if (!no) { + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + if (valid) { + if (strmatch(valid, "infinite")) + valid = "4294967295"; + nb_cli_enqueue_change(vty, "./valid-lifetime", + NB_OP_MODIFY, valid); + } else { + nb_cli_enqueue_change(vty, "./valid-lifetime", + NB_OP_DESTROY, NULL); + } + if (preferred) { + if (strmatch(preferred, "infinite")) + preferred = "4294967295"; + nb_cli_enqueue_change(vty, "./preferred-lifetime", + NB_OP_MODIFY, preferred); + } else { + nb_cli_enqueue_change(vty, "./preferred-lifetime", + NB_OP_DESTROY, NULL); + } + if (routeraddr) + nb_cli_enqueue_change(vty, "./router-address-flag", + NB_OP_MODIFY, "true"); + else + nb_cli_enqueue_change(vty, "./router-address-flag", + NB_OP_DESTROY, NULL); + if (offlink) + nb_cli_enqueue_change(vty, "./on-link-flag", + NB_OP_MODIFY, "false"); + else + nb_cli_enqueue_change(vty, "./on-link-flag", + NB_OP_DESTROY, NULL); + if (noautoconf) + nb_cli_enqueue_change(vty, "./autonomous-flag", + NB_OP_MODIFY, "false"); + else + nb_cli_enqueue_change(vty, "./autonomous-flag", + NB_OP_DESTROY, NULL); + } else { + nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); + } + return nb_cli_apply_changes( + vty, + "./frr-zebra:zebra/ipv6-router-advertisements/prefix-list/prefix[prefix-spec='%s']", + prefix_str); +} + +static void +lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + const char *prefix = yang_dnode_get_string(dnode, "prefix-spec"); + struct lyd_node *valid = yang_dnode_get(dnode, "valid-lifetime"); + struct lyd_node *preferred = yang_dnode_get(dnode, "preferred-lifetime"); + bool router_address_flag = yang_dnode_get_bool(dnode, + "router-address-flag"); + bool on_link_flag = yang_dnode_get_bool(dnode, "on-link-flag"); + bool autonomous_flag = yang_dnode_get_bool(dnode, "autonomous-flag"); + + vty_out(vty, " ipv6 nd prefix %s", prefix); + + if (!yang_dnode_is_default(valid, NULL) || + !yang_dnode_is_default(preferred, NULL) || show_defaults) { + uint32_t valid_lifetime = yang_dnode_get_uint32(valid, NULL); + uint32_t preferred_lifetime = yang_dnode_get_uint32(preferred, + NULL); + + if (valid_lifetime == UINT32_MAX) + vty_out(vty, " infinite"); + else + vty_out(vty, " %u", valid_lifetime); + if (preferred_lifetime == UINT32_MAX) + vty_out(vty, " infinite"); + else + vty_out(vty, " %u", preferred_lifetime); + } + + if (!on_link_flag) + vty_out(vty, " off-link"); + + if (!autonomous_flag) + vty_out(vty, " no-autoconfig"); + + if (router_address_flag) + vty_out(vty, " router-address"); + + vty_out(vty, "\n"); +} + +DEFPY_YANG (ipv6_nd_router_preference, + ipv6_nd_router_preference_cmd, + "[no] ipv6 nd router-preference ![<high|medium|low>$pref]", + NO_STR + "Interface IPv6 config commands\n" + "Neighbor discovery\n" + "Default router preference\n" + "High default router preference\n" + "Medium default router preference (default)\n" + "Low default router preference\n") +{ + if (!no) + nb_cli_enqueue_change(vty, + "./frr-zebra:zebra/ipv6-router-advertisements/default-router-preference", + NB_OP_MODIFY, pref); + else + nb_cli_enqueue_change(vty, + "./frr-zebra:zebra/ipv6-router-advertisements/default-router-preference", + NB_OP_DESTROY, NULL); + return nb_cli_apply_changes(vty, NULL); +} + +static void +lib_interface_zebra_ipv6_router_advertisements_default_router_preference_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + const char *default_router_preference = yang_dnode_get_string(dnode, + NULL); + + vty_out(vty, " ipv6 nd router-preference %s\n", + default_router_preference); +} + +DEFPY_YANG (ipv6_nd_mtu, + ipv6_nd_mtu_cmd, + "[no] ipv6 nd mtu ![(1-65535)]", + NO_STR + "Interface IPv6 config commands\n" + "Neighbor discovery\n" + "Advertised MTU\n" + "MTU in bytes\n") +{ + if (!no) + nb_cli_enqueue_change(vty, + "./frr-zebra:zebra/ipv6-router-advertisements/link-mtu", + NB_OP_MODIFY, mtu_str); + else + nb_cli_enqueue_change(vty, + "./frr-zebra:zebra/ipv6-router-advertisements/link-mtu", + NB_OP_DESTROY, NULL); + return nb_cli_apply_changes(vty, NULL); +} + +static void lib_interface_zebra_ipv6_router_advertisements_link_mtu_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + uint16_t link_mtu = yang_dnode_get_uint32(dnode, NULL); + + vty_out(vty, " ipv6 nd mtu %u\n", link_mtu); +} + +DEFPY_YANG (ipv6_nd_rdnss, + ipv6_nd_rdnss_cmd, + "[no] ipv6 nd rdnss X:X::X:X$addr [<(0-4294967295)|infinite>]$lifetime", + NO_STR + "Interface IPv6 config commands\n" + "Neighbor discovery\n" + "Recursive DNS server information\n" + "IPv6 address\n" + "Valid lifetime in seconds\n" + "Infinite valid lifetime\n") +{ + if (!no) { + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + if (lifetime) { + if (strmatch(lifetime, "infinite")) + lifetime = "4294967295"; + nb_cli_enqueue_change(vty, "./lifetime", NB_OP_MODIFY, + lifetime); + } else { + nb_cli_enqueue_change(vty, "./lifetime", NB_OP_DESTROY, + NULL); + } + } else { + nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); + } + return nb_cli_apply_changes( + vty, + "./frr-zebra:zebra/ipv6-router-advertisements/rdnss/rdnss-address[address='%s']", + addr_str); +} + +static void +lib_interface_zebra_ipv6_router_advertisements_rdnss_rdnss_address_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + const char *address = yang_dnode_get_string(dnode, "address"); + + vty_out(vty, " ipv6 nd rdnss %s", address); + + if (yang_dnode_exists(dnode, "lifetime")) { + uint32_t lifetime = yang_dnode_get_uint32(dnode, "lifetime"); + + if (lifetime == UINT32_MAX) + vty_out(vty, " infinite"); + else + vty_out(vty, " %u", lifetime); + } + + vty_out(vty, "\n"); +} + +DEFPY_YANG (ipv6_nd_dnssl, + ipv6_nd_dnssl_cmd, + "[no] ipv6 nd dnssl SUFFIX [<(0-4294967295)|infinite>]$lifetime", + NO_STR + "Interface IPv6 config commands\n" + "Neighbor discovery\n" + "DNS search list information\n" + "Domain name suffix\n" + "Valid lifetime in seconds\n" + "Infinite valid lifetime\n") +{ + char domain[254]; + size_t len; + + len = strlcpy(domain, suffix, sizeof(domain)); + if (len == 0 || len >= sizeof(domain)) { + vty_out(vty, "Malformed DNS search domain\n"); + return CMD_WARNING_CONFIG_FAILED; + } + if (domain[len - 1] == '.') { + /* + * Allow, but don't require, a trailing dot signifying the root + * zone. Canonicalize by cutting it off if present. + */ + domain[len - 1] = '\0'; + len--; + } + + if (!no) { + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + if (lifetime) { + if (strmatch(lifetime, "infinite")) + lifetime = "4294967295"; + nb_cli_enqueue_change(vty, "./lifetime", NB_OP_MODIFY, + lifetime); + } else { + nb_cli_enqueue_change(vty, "./lifetime", NB_OP_DESTROY, + NULL); + } + } else { + nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); + } + return nb_cli_apply_changes( + vty, + "./frr-zebra:zebra/ipv6-router-advertisements/dnssl/dnssl-domain[domain='%s']", + domain); +} + +static void +lib_interface_zebra_ipv6_router_advertisements_dnssl_dnssl_domain_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + const char *domain = yang_dnode_get_string(dnode, "domain"); + + vty_out(vty, " ipv6 nd dnssl %s", domain); + + if (yang_dnode_exists(dnode, "lifetime")) { + uint32_t lifetime = yang_dnode_get_uint32(dnode, "lifetime"); + + if (lifetime == UINT32_MAX) + vty_out(vty, " infinite"); + else + vty_out(vty, " %u", lifetime); + } + + vty_out(vty, "\n"); +} +#endif /* HAVE_RTADV */ + +#if HAVE_BFDD == 0 +DEFPY_YANG (zebra_ptm_enable_if, + zebra_ptm_enable_if_cmd, + "[no] ptm-enable", + NO_STR + "Enable neighbor check with specified topology\n") +{ + if (no) + nb_cli_enqueue_change(vty, "./frr-zebra:zebra/ptm-enable", + NB_OP_MODIFY, "false"); + else + nb_cli_enqueue_change(vty, "./frr-zebra:zebra/ptm-enable", + NB_OP_DESTROY, NULL); + return nb_cli_apply_changes(vty, NULL); +} + +static void lib_interface_zebra_ptm_enable_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + bool enable = yang_dnode_get_bool(dnode, NULL); + + if (!enable) + vty_out(vty, " no ptm-enable\n"); + else if (show_defaults) + vty_out(vty, " ptm-enable\n"); +} +#endif /* HAVE_BFDD == 0 */ + +/* + * VRF commands + */ + +static void zebra_vrf_indent_cli_write(struct vty *vty, + const struct lyd_node *dnode) +{ + const struct lyd_node *vrf = yang_dnode_get_parent(dnode, "vrf"); + + if (vrf && strcmp(yang_dnode_get_string(vrf, "name"), VRF_DEFAULT_NAME)) + vty_out(vty, " "); +} + +DEFPY_YANG (ip_router_id, + ip_router_id_cmd, + "[no] ip router-id A.B.C.D$id vrf NAME", + NO_STR + IP_STR + "Manually set the router-id\n" + "IP address to use for router-id\n" + VRF_CMD_HELP_STR) +{ + if (!no) + nb_cli_enqueue_change(vty, "./frr-zebra:zebra/router-id", NB_OP_MODIFY, + id_str); + else + nb_cli_enqueue_change(vty, "./frr-zebra:zebra/router-id", NB_OP_DESTROY, + NULL); + return nb_cli_apply_changes(vty, "/frr-vrf:lib/vrf[name='%s']", vrf); +} + +ALIAS_YANG (ip_router_id, + router_id_cmd, + "[no] router-id A.B.C.D$id vrf NAME", + NO_STR + "Manually set the router-id\n" + "IP address to use for router-id\n" + VRF_CMD_HELP_STR); + +DEFPY_YANG (ipv6_router_id, + ipv6_router_id_cmd, + "[no] ipv6 router-id X:X::X:X$id vrf NAME", + NO_STR + IPV6_STR + "Manually set the router-id\n" + "IPv6 address to use for router-id\n" + VRF_CMD_HELP_STR) +{ + if (!no) + nb_cli_enqueue_change(vty, "./frr-zebra:zebra/ipv6-router-id", + NB_OP_MODIFY, id_str); + else + nb_cli_enqueue_change(vty, "./frr-zebra:zebra/ipv6-router-id", + NB_OP_DESTROY, NULL); + return nb_cli_apply_changes(vty, "/frr-vrf:lib/vrf[name='%s']", vrf); +} + +DEFPY_YANG (ip_router_id_in_vrf, + ip_router_id_in_vrf_cmd, + "[no] ip router-id ![A.B.C.D$id]", + NO_STR + IP_STR + "Manually set the router-id\n" + "IP address to use for router-id\n") +{ + if (!no) + nb_cli_enqueue_change(vty, "./frr-zebra:zebra/router-id", NB_OP_MODIFY, + id_str); + else + nb_cli_enqueue_change(vty, "./frr-zebra:zebra/router-id", NB_OP_DESTROY, + NULL); + + if (vty->node == CONFIG_NODE) + return nb_cli_apply_changes(vty, "/frr-vrf:lib/vrf[name='%s']", + VRF_DEFAULT_NAME); + + return nb_cli_apply_changes(vty, NULL); +} + +ALIAS_YANG (ip_router_id_in_vrf, + router_id_in_vrf_cmd, + "[no] router-id ![A.B.C.D$id]", + NO_STR + "Manually set the router-id\n" + "IP address to use for router-id\n"); + +DEFPY_YANG (ipv6_router_id_in_vrf, + ipv6_router_id_in_vrf_cmd, + "[no] ipv6 router-id ![X:X::X:X$id]", + NO_STR + IP6_STR + "Manually set the IPv6 router-id\n" + "IPV6 address to use for router-id\n") +{ + if (!no) + nb_cli_enqueue_change(vty, "./frr-zebra:zebra/ipv6-router-id", + NB_OP_MODIFY, id_str); + else + nb_cli_enqueue_change(vty, "./frr-zebra:zebra/ipv6-router-id", + NB_OP_DESTROY, NULL); + + if (vty->node == CONFIG_NODE) + return nb_cli_apply_changes(vty, "/frr-vrf:lib/vrf[name='%s']", + VRF_DEFAULT_NAME); + + return nb_cli_apply_changes(vty, NULL); +} + +static void lib_vrf_zebra_router_id_cli_write(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + const char *id = yang_dnode_get_string(dnode, NULL); + + zebra_vrf_indent_cli_write(vty, dnode); + + vty_out(vty, "ip router-id %s\n", id); +} + +static void lib_vrf_zebra_ipv6_router_id_cli_write(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + const char *id = yang_dnode_get_string(dnode, NULL); + + zebra_vrf_indent_cli_write(vty, dnode); + + vty_out(vty, "ipv6 router-id %s\n", id); +} + +DEFPY_YANG (ip_protocol, + ip_protocol_cmd, + "[no] ip protocol " FRR_IP_PROTOCOL_MAP_STR_ZEBRA + " $proto ![route-map ROUTE-MAP$rmap]", + NO_STR + IP_STR + "Filter routing info exchanged between zebra and protocol\n" + FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA + "Specify route-map\n" + "Route map name\n") +{ + if (!no) { + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, "./route-map", NB_OP_MODIFY, rmap); + } else { + nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); + } + + if (vty->node == CONFIG_NODE) + return nb_cli_apply_changes( + vty, + "/frr-vrf:lib/vrf[name='%s']/frr-zebra:zebra/filter-protocol[afi-safi='%s'][protocol='%s']", + VRF_DEFAULT_NAME, + yang_afi_safi_value2identity(AFI_IP, SAFI_UNICAST), + proto); + + return nb_cli_apply_changes( + vty, + "./frr-zebra:zebra/filter-protocol[afi-safi='%s'][protocol='%s']", + yang_afi_safi_value2identity(AFI_IP, SAFI_UNICAST), proto); +} + +DEFPY_YANG (ipv6_protocol, + ipv6_protocol_cmd, + "[no] ipv6 protocol " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA + " $proto ![route-map ROUTE-MAP$rmap]", + NO_STR + IP6_STR + "Filter IPv6 routing info exchanged between zebra and protocol\n" + FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA + "Specify route-map\n" + "Route map name\n") +{ + if (!no) { + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, "./route-map", NB_OP_MODIFY, rmap); + } else { + nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); + } + + if (vty->node == CONFIG_NODE) + return nb_cli_apply_changes( + vty, + "/frr-vrf:lib/vrf[name='%s']/frr-zebra:zebra/filter-protocol[afi-safi='%s'][protocol='%s']", + VRF_DEFAULT_NAME, + yang_afi_safi_value2identity(AFI_IP6, SAFI_UNICAST), + proto); + + return nb_cli_apply_changes( + vty, + "./frr-zebra:zebra/filter-protocol[afi-safi='%s'][protocol='%s']", + yang_afi_safi_value2identity(AFI_IP6, SAFI_UNICAST), proto); +} + +static void lib_vrf_zebra_filter_protocol_cli_write(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + const char *afi_safi = yang_dnode_get_string(dnode, "afi-safi"); + const char *proto = yang_dnode_get_string(dnode, "protocol"); + const char *rmap = yang_dnode_get_string(dnode, "route-map"); + afi_t afi; + safi_t safi; + + yang_afi_safi_identity2value(afi_safi, &afi, &safi); + + if (safi != SAFI_UNICAST) + return; + + zebra_vrf_indent_cli_write(vty, dnode); + + if (afi == AFI_IP) + vty_out(vty, "ip protocol %s route-map %s\n", proto, rmap); + else + vty_out(vty, "ipv6 protocol %s route-map %s\n", proto, rmap); +} + +DEFPY_YANG (ip_protocol_nht_rmap, + ip_protocol_nht_rmap_cmd, + "[no] ip nht " FRR_IP_PROTOCOL_MAP_STR_ZEBRA + " $proto ![route-map ROUTE-MAP$rmap]", + NO_STR + IP_STR + "Filter Next Hop tracking route resolution\n" + FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA + "Specify route map\n" + "Route map name\n") +{ + if (!no) { + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, "./route-map", NB_OP_MODIFY, rmap); + } else { + nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); + } + + if (vty->node == CONFIG_NODE) + return nb_cli_apply_changes( + vty, + "/frr-vrf:lib/vrf[name='%s']/frr-zebra:zebra/filter-nht[afi-safi='%s'][protocol='%s']", + VRF_DEFAULT_NAME, + yang_afi_safi_value2identity(AFI_IP, SAFI_UNICAST), + proto); + + return nb_cli_apply_changes( + vty, + "./frr-zebra:zebra/filter-nht[afi-safi='%s'][protocol='%s']", + yang_afi_safi_value2identity(AFI_IP, SAFI_UNICAST), proto); +} + +DEFPY_YANG (ipv6_protocol_nht_rmap, + ipv6_protocol_nht_rmap_cmd, + "[no] ipv6 nht " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA + " $proto ![route-map ROUTE-MAP$rmap]", + NO_STR + IP6_STR + "Filter Next Hop tracking route resolution\n" + FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA + "Specify route map\n" + "Route map name\n") +{ + if (!no) { + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, "./route-map", NB_OP_MODIFY, rmap); + } else { + nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); + } + + if (vty->node == CONFIG_NODE) + return nb_cli_apply_changes( + vty, + "/frr-vrf:lib/vrf[name='%s']/frr-zebra:zebra/filter-nht[afi-safi='%s'][protocol='%s']", + VRF_DEFAULT_NAME, + yang_afi_safi_value2identity(AFI_IP6, SAFI_UNICAST), + proto); + + return nb_cli_apply_changes( + vty, + "./frr-zebra:zebra/filter-nht[afi-safi='%s'][protocol='%s']", + yang_afi_safi_value2identity(AFI_IP6, SAFI_UNICAST), proto); +} + +static void lib_vrf_zebra_filter_nht_cli_write(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + const char *afi_safi = yang_dnode_get_string(dnode, "afi-safi"); + const char *proto = yang_dnode_get_string(dnode, "protocol"); + const char *rmap = yang_dnode_get_string(dnode, "route-map"); + afi_t afi; + safi_t safi; + + yang_afi_safi_identity2value(afi_safi, &afi, &safi); + + if (safi != SAFI_UNICAST) + return; + + zebra_vrf_indent_cli_write(vty, dnode); + + if (afi == AFI_IP) + vty_out(vty, "ip nht %s route-map %s\n", proto, rmap); + else + vty_out(vty, "ipv6 nht %s route-map %s\n", proto, rmap); +} + +DEFPY_YANG (ip_nht_default_route, + ip_nht_default_route_cmd, + "[no] ip nht resolve-via-default", + NO_STR + IP_STR + "Filter Next Hop tracking route resolution\n" + "Resolve via default route\n") +{ + nb_cli_enqueue_change(vty, "./frr-zebra:zebra/resolve-via-default", + NB_OP_MODIFY, no ? "false" : "true"); + + if (vty->node == CONFIG_NODE) + return nb_cli_apply_changes(vty, "/frr-vrf:lib/vrf[name='%s']", + VRF_DEFAULT_NAME); + + return nb_cli_apply_changes(vty, NULL); +} + +static void lib_vrf_zebra_resolve_via_default_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + bool resolve_via_default = yang_dnode_get_bool(dnode, NULL); + + if (resolve_via_default != SAVE_ZEBRA_IP_NHT_RESOLVE_VIA_DEFAULT || + show_defaults) { + zebra_vrf_indent_cli_write(vty, dnode); + + vty_out(vty, "%sip nht resolve-via-default\n", + resolve_via_default ? "" : "no "); + } +} + +DEFPY_YANG (ipv6_nht_default_route, + ipv6_nht_default_route_cmd, + "[no] ipv6 nht resolve-via-default", + NO_STR + IP6_STR + "Filter Next Hop tracking route resolution\n" + "Resolve via default route\n") +{ + nb_cli_enqueue_change(vty, "./frr-zebra:zebra/ipv6-resolve-via-default", + NB_OP_MODIFY, no ? "false" : "true"); + + if (vty->node == CONFIG_NODE) + return nb_cli_apply_changes(vty, "/frr-vrf:lib/vrf[name='%s']", + VRF_DEFAULT_NAME); + + return nb_cli_apply_changes(vty, NULL); +} + +static void lib_vrf_zebra_ipv6_resolve_via_default_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + bool resolve_via_default = yang_dnode_get_bool(dnode, NULL); + + if (resolve_via_default != SAVE_ZEBRA_IP_NHT_RESOLVE_VIA_DEFAULT || + show_defaults) { + zebra_vrf_indent_cli_write(vty, dnode); + + vty_out(vty, "%sipv6 nht resolve-via-default\n", + resolve_via_default ? "" : "no "); + } +} + +DEFPY_YANG (vrf_netns, + vrf_netns_cmd, + "[no] netns ![NAME$netns_name]", + NO_STR + "Attach VRF to a Namespace\n" + "The file name in " NS_RUN_DIR ", or a full pathname\n") +{ + vty_out(vty, "%% This command doesn't do anything.\n"); + vty_out(vty, + "%% VRF is linked to a netns automatically based on its name.\n"); + return CMD_WARNING; +} + +DEFPY_YANG (ip_table_range, ip_table_range_cmd, + "[no] ip table range ![(1-4294967295)$start (1-4294967295)$end]", + NO_STR IP_STR + "table configuration\n" + "Configure table range\n" + "Start Routing Table\n" + "End Routing Table\n") +{ + if (!no) { + const struct lyd_node *start_node; + const struct lyd_node *end_node; + + if (vty->node == CONFIG_NODE) { + start_node = + yang_dnode_getf(vty->candidate_config->dnode, + "/frr-vrf:lib/vrf[name='%s']/frr-zebra:zebra/netns/table-range/start", + VRF_DEFAULT_NAME); + end_node = + yang_dnode_getf(vty->candidate_config->dnode, + "/frr-vrf:lib/vrf[name='%s']/frr-zebra:zebra/netns/table-range/end", + VRF_DEFAULT_NAME); + } else { + start_node = + yang_dnode_getf(vty->candidate_config->dnode, + "%s/frr-zebra:zebra/netns/table-range/start", + VTY_CURR_XPATH); + end_node = + yang_dnode_getf(vty->candidate_config->dnode, + "%s/frr-zebra:zebra/netns/table-range/end", + VTY_CURR_XPATH); + } + + if (start_node && end_node) { + if (yang_dnode_get_uint32(start_node, NULL) != + (uint32_t)start || + yang_dnode_get_uint32(end_node, NULL) != + (uint32_t)end) { + vty_out(vty, + "%% New range will be taken into account at restart.\n"); + vty_out(vty, + "%% Don't forget to save your configuration.\n"); + } + } + + nb_cli_enqueue_change(vty, "./frr-zebra:zebra/netns/table-range", + NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, + "./frr-zebra:zebra/netns/table-range/start", + NB_OP_MODIFY, start_str); + nb_cli_enqueue_change(vty, + "./frr-zebra:zebra/netns/table-range/end", + NB_OP_MODIFY, end_str); + } else { + nb_cli_enqueue_change(vty, "./frr-zebra:zebra/netns/table-range", + NB_OP_DESTROY, NULL); + } + + if (vty->node == CONFIG_NODE) + return nb_cli_apply_changes(vty, "/frr-vrf:lib/vrf[name='%s']", + VRF_DEFAULT_NAME); + + return nb_cli_apply_changes(vty, NULL); +} + +static void lib_vrf_zebra_netns_table_range_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +{ + uint32_t start = yang_dnode_get_uint32(dnode, "start"); + uint32_t end = yang_dnode_get_uint32(dnode, "end"); + + zebra_vrf_indent_cli_write(vty, dnode); + + vty_out(vty, "ip table range %u %u\n", start, end); +} + +DEFPY_YANG (vni_mapping, + vni_mapping_cmd, + "[no] vni ![" CMD_VNI_RANGE "[prefix-routes-only$filter]]", + NO_STR + "VNI corresponding to tenant VRF\n" + "VNI-ID\n" + "prefix-routes-only\n") +{ + if (!no) + nb_cli_enqueue_change(vty, "./frr-zebra:zebra/l3vni-id", NB_OP_MODIFY, + vni_str); + else + nb_cli_enqueue_change(vty, "./frr-zebra:zebra/l3vni-id", NB_OP_DESTROY, + NULL); + + if (filter) + nb_cli_enqueue_change(vty, "./frr-zebra:zebra/prefix-only", + NB_OP_MODIFY, "true"); + else + nb_cli_enqueue_change(vty, "./frr-zebra:zebra/prefix-only", + NB_OP_DESTROY, NULL); + + if (vty->node == CONFIG_NODE) + return nb_cli_apply_changes(vty, "/frr-vrf:lib/vrf[name='%s']", + VRF_DEFAULT_NAME); + + return nb_cli_apply_changes(vty, NULL); +} + +static void lib_vrf_zebra_l3vni_id_cli_write(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + vni_t vni = yang_dnode_get_uint32(dnode, NULL); + bool prefix_only = yang_dnode_get_bool(dnode, "../prefix-only"); + + zebra_vrf_indent_cli_write(vty, dnode); + + vty_out(vty, "vni %u", vni); + + if (prefix_only) + vty_out(vty, " prefix-routes-only"); + + vty_out(vty, "\n"); +} + +DEFPY_YANG( + match_ip_address_prefix_len, match_ip_address_prefix_len_cmd, + "match ip address prefix-len (0-32)$length", + MATCH_STR + IP_STR + "Match prefix length of IP address\n" + "Match prefix length of IP address\n" + "Prefix length\n") +{ + const char *xpath = + "./match-condition[condition='frr-zebra-route-map:ipv4-prefix-length']"; + char xpath_value[XPATH_MAXLEN]; + + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + snprintf( + xpath_value, sizeof(xpath_value), + "%s/rmap-match-condition/frr-zebra-route-map:ipv4-prefix-length", + xpath); + nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, length_str); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG( + no_match_ip_address_prefix_len, no_match_ip_address_prefix_len_cmd, + "no match ip address prefix-len [(0-32)]", + NO_STR + MATCH_STR + IP_STR + "Match prefix length of IP address\n" + "Match prefix length of IP address\n" + "Prefix length\n") +{ + const char *xpath = + "./match-condition[condition='frr-zebra-route-map:ipv4-prefix-length']"; + + nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG( + match_ipv6_address_prefix_len, match_ipv6_address_prefix_len_cmd, + "match ipv6 address prefix-len (0-128)$length", + MATCH_STR + IPV6_STR + "Match prefix length of IPv6 address\n" + "Match prefix length of IPv6 address\n" + "Prefix length\n") +{ + const char *xpath = + "./match-condition[condition='frr-zebra-route-map:ipv6-prefix-length']"; + char xpath_value[XPATH_MAXLEN]; + + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + snprintf( + xpath_value, sizeof(xpath_value), + "%s/rmap-match-condition/frr-zebra-route-map:ipv6-prefix-length", + xpath); + nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, length_str); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG( + no_match_ipv6_address_prefix_len, no_match_ipv6_address_prefix_len_cmd, + "no match ipv6 address prefix-len [(0-128)]", + NO_STR + MATCH_STR + IPV6_STR + "Match prefix length of IPv6 address\n" + "Match prefix length of IPv6 address\n" + "Prefix length\n") +{ + const char *xpath = + "./match-condition[condition='frr-zebra-route-map:ipv6-prefix-length']"; + + nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG( + match_ip_nexthop_prefix_len, match_ip_nexthop_prefix_len_cmd, + "match ip next-hop prefix-len (0-32)$length", + MATCH_STR + IP_STR + "Match prefixlen of nexthop IP address\n" + "Match prefixlen of given nexthop\n" + "Prefix length\n") +{ + const char *xpath = + "./match-condition[condition='frr-zebra-route-map:ipv4-next-hop-prefix-length']"; + char xpath_value[XPATH_MAXLEN]; + + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + snprintf( + xpath_value, sizeof(xpath_value), + "%s/rmap-match-condition/frr-zebra-route-map:ipv4-prefix-length", + xpath); + nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, length_str); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG( + no_match_ip_nexthop_prefix_len, no_match_ip_nexthop_prefix_len_cmd, + "no match ip next-hop prefix-len [(0-32)]", + NO_STR + MATCH_STR + IP_STR + "Match prefixlen of nexthop IP address\n" + "Match prefix length of nexthop\n" + "Prefix length\n") +{ + const char *xpath = + "./match-condition[condition='frr-zebra-route-map:ipv4-next-hop-prefix-length']"; + + nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG( + match_source_protocol, match_source_protocol_cmd, + "match source-protocol " FRR_REDIST_STR_ZEBRA "$proto", + MATCH_STR + "Match protocol via which the route was learnt\n" + FRR_REDIST_HELP_STR_ZEBRA) +{ + const char *xpath = + "./match-condition[condition='frr-zebra-route-map:source-protocol']"; + char xpath_value[XPATH_MAXLEN]; + + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + snprintf(xpath_value, sizeof(xpath_value), + "%s/rmap-match-condition/frr-zebra-route-map:source-protocol", + xpath); + nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, proto); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG( + no_match_source_protocol, no_match_source_protocol_cmd, + "no match source-protocol [" FRR_REDIST_STR_ZEBRA "]", + NO_STR + MATCH_STR + "Match protocol via which the route was learnt\n" + FRR_REDIST_HELP_STR_ZEBRA) +{ + const char *xpath = + "./match-condition[condition='frr-zebra-route-map:source-protocol']"; + + nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG( + match_source_instance, match_source_instance_cmd, + "match source-instance (0-255)$instance", + MATCH_STR + "Match the protocol's instance number\n" + "The instance number\n") +{ + const char *xpath = + "./match-condition[condition='frr-zebra-route-map:source-instance']"; + char xpath_value[XPATH_MAXLEN]; + + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + snprintf(xpath_value, sizeof(xpath_value), + "%s/rmap-match-condition/frr-zebra-route-map:source-instance", + xpath); + nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, instance_str); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG( + no_match_source_instance, no_match_source_instance_cmd, + "no match source-instance [(0-255)]", + NO_STR MATCH_STR + "Match the protocol's instance number\n" + "The instance number\n") +{ + const char *xpath = + "./match-condition[condition='frr-zebra-route-map:source-instance']"; + + nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +/* set functions */ + +DEFPY_YANG( + set_src, set_src_cmd, + "set src <A.B.C.D$addrv4|X:X::X:X$addrv6>", + SET_STR + "src address for route\n" + "IPv4 src address\n" + "IPv6 src address\n") +{ + const char *xpath = + "./set-action[action='frr-zebra-route-map:src-address']"; + char xpath_value[XPATH_MAXLEN]; + + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (addrv4_str) { + snprintf( + xpath_value, sizeof(xpath_value), + "%s/rmap-set-action/frr-zebra-route-map:ipv4-src-address", + xpath); + nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, + addrv4_str); + } else { + snprintf( + xpath_value, sizeof(xpath_value), + "%s/rmap-set-action/frr-zebra-route-map:ipv6-src-address", + xpath); + nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, + addrv6_str); + } + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG( + no_set_src, no_set_src_cmd, + "no set src [<A.B.C.D|X:X::X:X>]", + NO_STR + SET_STR + "Source address for route\n" + "IPv4 address\n" + "IPv6 address\n") +{ + const char *xpath = + "./set-action[action='frr-zebra-route-map:src-address']"; + + nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +const char *features[] = { +#if HAVE_BFDD == 0 + "ptm-bfd", +#endif +#if defined(HAVE_RTADV) + "ipv6-router-advertisements", +#endif + NULL +}; + +/* clang-format off */ +const struct frr_yang_module_info frr_zebra_cli_info = { + .name = "frr-zebra", + .ignore_cfg_cbs = true, + .features = features, + .nodes = { +#if HAVE_BFDD == 0 + { + .xpath = "/frr-zebra:zebra/ptm-enable", + .cbs.cli_show = zebra_ptm_enable_cli_write, + }, +#endif + { + .xpath = "/frr-zebra:zebra/route-map-delay", + .cbs.cli_show = zebra_route_map_delay_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv4-addrs", + .cbs.cli_show = lib_interface_zebra_ipv4_addrs_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv4-p2p-addrs", + .cbs.cli_show = lib_interface_zebra_ipv4_p2p_addrs_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-addrs", + .cbs.cli_show = lib_interface_zebra_ipv6_addrs_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/multicast", + .cbs.cli_show = lib_interface_zebra_multicast_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/link-detect", + .cbs.cli_show = lib_interface_zebra_link_detect_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/enabled", + .cbs.cli_show = lib_interface_zebra_enabled_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/bandwidth", + .cbs.cli_show = lib_interface_zebra_bandwidth_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/mpls", + .cbs.cli_show = lib_interface_zebra_mpls_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/link-params", + .cbs.cli_show = lib_interface_zebra_link_params_cli_write, + .cbs.cli_show_end = lib_interface_zebra_link_params_cli_write_end, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/link-params/metric", + .cbs.cli_show = lib_interface_zebra_link_params_metric_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/link-params/max-bandwidth", + .cbs.cli_show = lib_interface_zebra_link_params_max_bandwidth_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/link-params/max-reservable-bandwidth", + .cbs.cli_show = lib_interface_zebra_link_params_max_reservable_bandwidth_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/link-params/unreserved-bandwidths/unreserved-bandwidth", + .cbs.cli_show = lib_interface_zebra_link_params_unreserved_bandwidths_unreserved_bandwidth_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/link-params/residual-bandwidth", + .cbs.cli_show = lib_interface_zebra_link_params_residual_bandwidth_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/link-params/available-bandwidth", + .cbs.cli_show = lib_interface_zebra_link_params_available_bandwidth_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/link-params/utilized-bandwidth", + .cbs.cli_show = lib_interface_zebra_link_params_utilized_bandwidth_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/link-params/legacy-admin-group", + .cbs.cli_show = lib_interface_zebra_link_params_legacy_admin_group_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/link-params/affinities", + .cbs.cli_show = lib_interface_zebra_link_params_affinities_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/link-params/affinity-mode", + .cbs.cli_show = lib_interface_zebra_link_params_affinity_mode_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/link-params/neighbor", + .cbs.cli_show = lib_interface_zebra_link_params_neighbor_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/link-params/delay", + .cbs.cli_show = lib_interface_zebra_link_params_delay_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/link-params/delay-variation", + .cbs.cli_show = lib_interface_zebra_link_params_delay_variation_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/link-params/packet-loss", + .cbs.cli_show = lib_interface_zebra_link_params_packet_loss_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/evpn-mh/type-0/esi", + .cbs.cli_show = lib_interface_zebra_evpn_mh_type_0_esi_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/evpn-mh/type-3/system-mac", + .cbs.cli_show = lib_interface_zebra_evpn_mh_type_3_system_mac_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/evpn-mh/type-3/local-discriminator", + .cbs.cli_show = lib_interface_zebra_evpn_mh_type_3_local_discriminator_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/evpn-mh/df-preference", + .cbs.cli_show = lib_interface_zebra_evpn_mh_df_preference_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/evpn-mh/bypass", + .cbs.cli_show = lib_interface_zebra_evpn_mh_bypass_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/evpn-mh/uplink", + .cbs.cli_show = lib_interface_zebra_evpn_mh_uplink_cli_write, + }, +#if defined(HAVE_RTADV) + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/send-advertisements", + .cbs.cli_show = lib_interface_zebra_ipv6_router_advertisements_send_advertisements_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/max-rtr-adv-interval", + .cbs.cli_show = lib_interface_zebra_ipv6_router_advertisements_max_rtr_adv_interval_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/managed-flag", + .cbs.cli_show = lib_interface_zebra_ipv6_router_advertisements_managed_flag_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/other-config-flag", + .cbs.cli_show = lib_interface_zebra_ipv6_router_advertisements_other_config_flag_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/home-agent-flag", + .cbs.cli_show = lib_interface_zebra_ipv6_router_advertisements_home_agent_flag_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/link-mtu", + .cbs.cli_show = lib_interface_zebra_ipv6_router_advertisements_link_mtu_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/reachable-time", + .cbs.cli_show = lib_interface_zebra_ipv6_router_advertisements_reachable_time_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/retrans-timer", + .cbs.cli_show = lib_interface_zebra_ipv6_router_advertisements_retrans_timer_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/cur-hop-limit", + .cbs.cli_show = lib_interface_zebra_ipv6_router_advertisements_cur_hop_limit_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/default-lifetime", + .cbs.cli_show = lib_interface_zebra_ipv6_router_advertisements_default_lifetime_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/fast-retransmit", + .cbs.cli_show = lib_interface_zebra_ipv6_router_advertisements_fast_retransmit_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/advertisement-interval-option", + .cbs.cli_show = lib_interface_zebra_ipv6_router_advertisements_advertisement_interval_option_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/home-agent-preference", + .cbs.cli_show = lib_interface_zebra_ipv6_router_advertisements_home_agent_preference_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/home-agent-lifetime", + .cbs.cli_show = lib_interface_zebra_ipv6_router_advertisements_home_agent_lifetime_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/default-router-preference", + .cbs.cli_show = lib_interface_zebra_ipv6_router_advertisements_default_router_preference_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/prefix-list/prefix", + .cbs.cli_show = lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/dnssl/dnssl-domain", + .cbs.cli_show = lib_interface_zebra_ipv6_router_advertisements_dnssl_dnssl_domain_cli_write, + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/rdnss/rdnss-address", + .cbs.cli_show = lib_interface_zebra_ipv6_router_advertisements_rdnss_rdnss_address_cli_write, + }, +#endif /* defined(HAVE_RTADV) */ +#if HAVE_BFDD == 0 + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ptm-enable", + .cbs.cli_show = lib_interface_zebra_ptm_enable_cli_write, + }, +#endif + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:zebra/router-id", + .cbs.cli_show = lib_vrf_zebra_router_id_cli_write, + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:zebra/ipv6-router-id", + .cbs.cli_show = lib_vrf_zebra_ipv6_router_id_cli_write, + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:zebra/filter-protocol", + .cbs.cli_show = lib_vrf_zebra_filter_protocol_cli_write, + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:zebra/filter-nht", + .cbs.cli_show = lib_vrf_zebra_filter_nht_cli_write, + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:zebra/resolve-via-default", + .cbs.cli_show = lib_vrf_zebra_resolve_via_default_cli_write, + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:zebra/ipv6-resolve-via-default", + .cbs.cli_show = lib_vrf_zebra_ipv6_resolve_via_default_cli_write, + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:zebra/netns/table-range", + .cbs.cli_show = lib_vrf_zebra_netns_table_range_cli_write, + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:zebra/l3vni-id", + .cbs.cli_show = lib_vrf_zebra_l3vni_id_cli_write, + }, + { + .xpath = NULL, + }, + } +}; + +struct cmd_node link_params_node = { + .name = "link-params", + .node = LINK_PARAMS_NODE, + .parent_node = INTERFACE_NODE, + .prompt = "%s(config-link-params)# ", +}; + +void zebra_cli_init(void) +{ + install_node(&link_params_node); + + install_element(INTERFACE_NODE, &multicast_new_cmd); + install_element(INTERFACE_NODE, &multicast_cmd); + install_element(INTERFACE_NODE, &mpls_cmd); + install_element(INTERFACE_NODE, &linkdetect_cmd); + install_element(INTERFACE_NODE, &shutdown_if_cmd); + install_element(INTERFACE_NODE, &bandwidth_if_cmd); + install_element(INTERFACE_NODE, &ip_address_cmd); + install_element(INTERFACE_NODE, &ip_address_peer_cmd); + install_element(INTERFACE_NODE, &ipv6_address_cmd); + install_element(INTERFACE_NODE, &link_params_cmd); + install_element(INTERFACE_NODE, &no_link_params_cmd); + install_default(LINK_PARAMS_NODE); + install_element(LINK_PARAMS_NODE, &link_params_enable_cmd); + install_element(LINK_PARAMS_NODE, &no_link_params_enable_cmd); + install_element(LINK_PARAMS_NODE, &link_params_metric_cmd); + install_element(LINK_PARAMS_NODE, &link_params_maxbw_cmd); + install_element(LINK_PARAMS_NODE, &link_params_max_rsv_bw_cmd); + install_element(LINK_PARAMS_NODE, &link_params_unrsv_bw_cmd); + install_element(LINK_PARAMS_NODE, &link_params_admin_grp_cmd); + install_element(LINK_PARAMS_NODE, &link_params_inter_as_cmd); + install_element(LINK_PARAMS_NODE, &link_params_delay_cmd); + install_element(LINK_PARAMS_NODE, &link_params_delay_var_cmd); + install_element(LINK_PARAMS_NODE, &link_params_pkt_loss_cmd); + install_element(LINK_PARAMS_NODE, &link_params_ava_bw_cmd); + install_element(LINK_PARAMS_NODE, &link_params_res_bw_cmd); + install_element(LINK_PARAMS_NODE, &link_params_use_bw_cmd); + install_element(LINK_PARAMS_NODE, &link_params_affinity_cmd); + install_element(LINK_PARAMS_NODE, &link_params_affinity_mode_cmd); + install_element(LINK_PARAMS_NODE, &exit_link_params_cmd); + + install_element(INTERFACE_NODE, &zebra_evpn_es_id_cmd); + install_element(INTERFACE_NODE, &zebra_evpn_es_sys_mac_cmd); + install_element(INTERFACE_NODE, &zebra_evpn_es_pref_cmd); + install_element(INTERFACE_NODE, &zebra_evpn_es_bypass_cmd); + install_element(INTERFACE_NODE, &zebra_evpn_mh_uplink_cmd); + +#if defined(HAVE_RTADV) + install_element(INTERFACE_NODE, &ipv6_nd_ra_fast_retrans_cmd); + install_element(INTERFACE_NODE, &ipv6_nd_ra_retrans_interval_cmd); + install_element(INTERFACE_NODE, &ipv6_nd_ra_hop_limit_cmd); + install_element(INTERFACE_NODE, &ipv6_nd_suppress_ra_cmd); + install_element(INTERFACE_NODE, &ipv6_nd_ra_interval_cmd); + install_element(INTERFACE_NODE, &ipv6_nd_ra_lifetime_cmd); + install_element(INTERFACE_NODE, &ipv6_nd_reachable_time_cmd); + install_element(INTERFACE_NODE, &ipv6_nd_managed_config_flag_cmd); + install_element(INTERFACE_NODE, &ipv6_nd_other_config_flag_cmd); + install_element(INTERFACE_NODE, &ipv6_nd_homeagent_config_flag_cmd); + install_element(INTERFACE_NODE, &ipv6_nd_homeagent_preference_cmd); + install_element(INTERFACE_NODE, &ipv6_nd_homeagent_lifetime_cmd); + install_element(INTERFACE_NODE, &ipv6_nd_adv_interval_config_option_cmd); + install_element(INTERFACE_NODE, &ipv6_nd_prefix_cmd); + install_element(INTERFACE_NODE, &ipv6_nd_router_preference_cmd); + install_element(INTERFACE_NODE, &ipv6_nd_mtu_cmd); + install_element(INTERFACE_NODE, &ipv6_nd_rdnss_cmd); + install_element(INTERFACE_NODE, &ipv6_nd_dnssl_cmd); +#endif +#if HAVE_BFDD == 0 + install_element(INTERFACE_NODE, &zebra_ptm_enable_if_cmd); +#endif + + install_element(CONFIG_NODE, &ip_router_id_cmd); + install_element(CONFIG_NODE, &router_id_cmd); + install_element(CONFIG_NODE, &ipv6_router_id_cmd); + install_element(CONFIG_NODE, &ip_router_id_in_vrf_cmd); + install_element(CONFIG_NODE, &router_id_in_vrf_cmd); + install_element(CONFIG_NODE, &ipv6_router_id_in_vrf_cmd); + install_element(VRF_NODE, &ip_router_id_in_vrf_cmd); + install_element(VRF_NODE, &router_id_in_vrf_cmd); + install_element(VRF_NODE, &ipv6_router_id_in_vrf_cmd); + + install_element(CONFIG_NODE, &ip_protocol_cmd); + install_element(VRF_NODE, &ip_protocol_cmd); + install_element(CONFIG_NODE, &ipv6_protocol_cmd); + install_element(VRF_NODE, &ipv6_protocol_cmd); + install_element(CONFIG_NODE, &ip_protocol_nht_rmap_cmd); + install_element(VRF_NODE, &ip_protocol_nht_rmap_cmd); + install_element(CONFIG_NODE, &ipv6_protocol_nht_rmap_cmd); + install_element(VRF_NODE, &ipv6_protocol_nht_rmap_cmd); + install_element(CONFIG_NODE, &zebra_route_map_timer_cmd); + + install_element(CONFIG_NODE, &ip_nht_default_route_cmd); + install_element(CONFIG_NODE, &ipv6_nht_default_route_cmd); + install_element(VRF_NODE, &ip_nht_default_route_cmd); + install_element(VRF_NODE, &ipv6_nht_default_route_cmd); + + install_element(CONFIG_NODE, &vni_mapping_cmd); + install_element(VRF_NODE, &vni_mapping_cmd); + + if (vrf_is_backend_netns()) + install_element(VRF_NODE, &vrf_netns_cmd); + + install_element(CONFIG_NODE, &ip_table_range_cmd); + install_element(VRF_NODE, &ip_table_range_cmd); +#if HAVE_BFDD == 0 + install_element(CONFIG_NODE, &zebra_ptm_enable_cmd); +#endif + install_element(RMAP_NODE, &match_ip_nexthop_prefix_len_cmd); + install_element(RMAP_NODE, &no_match_ip_nexthop_prefix_len_cmd); + install_element(RMAP_NODE, &match_ip_address_prefix_len_cmd); + install_element(RMAP_NODE, &match_ipv6_address_prefix_len_cmd); + install_element(RMAP_NODE, &no_match_ipv6_address_prefix_len_cmd); + install_element(RMAP_NODE, &no_match_ip_address_prefix_len_cmd); + install_element(RMAP_NODE, &match_source_protocol_cmd); + install_element(RMAP_NODE, &no_match_source_protocol_cmd); + install_element(RMAP_NODE, &match_source_instance_cmd); + install_element(RMAP_NODE, &no_match_source_instance_cmd); + + install_element(RMAP_NODE, &set_src_cmd); + install_element(RMAP_NODE, &no_set_src_cmd); +} diff --git a/zebra/zebra_cli.h b/zebra/zebra_cli.h new file mode 100644 index 0000000000..01931a47ab --- /dev/null +++ b/zebra/zebra_cli.h @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#ifndef _ZEBRA_CLI_H +#define _ZEBRA_CLI_H 1 + +extern const struct frr_yang_module_info frr_zebra_cli_info; + +void zebra_cli_init(void); + +#endif diff --git a/zebra/zebra_evpn_mh.c b/zebra/zebra_evpn_mh.c index a5092c629a..35d5027fb8 100644 --- a/zebra/zebra_evpn_mh.c +++ b/zebra/zebra_evpn_mh.c @@ -52,10 +52,9 @@ static void zebra_evpn_es_get_one_base_evpn(void); static int zebra_evpn_es_evi_send_to_client(struct zebra_evpn_es *es, struct zebra_evpn *zevpn, bool add); static void zebra_evpn_local_es_del(struct zebra_evpn_es **esp); -static int zebra_evpn_local_es_update(struct zebra_if *zif, esi_t *esi); +static void zebra_evpn_local_es_update(struct zebra_if *zif); static bool zebra_evpn_es_br_port_dplane_update(struct zebra_evpn_es *es, const char *caller); -static void zebra_evpn_mh_uplink_cfg_update(struct zebra_if *zif, bool set); static void zebra_evpn_mh_update_protodown_es(struct zebra_evpn_es *es, bool resync_dplane); static void zebra_evpn_mh_clear_protodown_es(struct zebra_evpn_es *es); @@ -1139,7 +1138,7 @@ void zebra_evpn_if_init(struct zebra_if *zif) /* if an es_id and sysmac are already present against the interface * activate it */ - zebra_evpn_local_es_update(zif, &zif->es_info.esi); + zebra_evpn_local_es_update(zif); } /* handle deletion of an access port by removing it from all associated @@ -2250,8 +2249,7 @@ static void zebra_evpn_es_local_info_set(struct zebra_evpn_es *es, /* attach es to interface */ zif->es_info.es = es; - es->df_pref = zif->es_info.df_pref ? zif->es_info.df_pref - : EVPN_MH_DF_PREF_DEFAULT; + es->df_pref = zif->es_info.df_pref; /* attach interface to es */ es->zif = zif; @@ -2402,73 +2400,63 @@ static void zebra_evpn_es_remote_info_re_eval(struct zebra_evpn_es **esp) } } +void zebra_build_type3_esi(uint32_t lid, struct ethaddr *mac, esi_t *esi) +{ + int offset = 0; + int field_bytes = 0; + + /* build 10-byte type-3-ESI - + * Type(1-byte), MAC(6-bytes), ES-LID (3-bytes) + */ + field_bytes = 1; + esi->val[offset] = ESI_TYPE_MAC; + offset += field_bytes; + + field_bytes = ETH_ALEN; + memcpy(&esi->val[offset], (uint8_t *)mac, field_bytes); + offset += field_bytes; + + esi->val[offset++] = (uint8_t)(lid >> 16); + esi->val[offset++] = (uint8_t)(lid >> 8); + esi->val[offset++] = (uint8_t)lid; +} + /* A new local es is created when a local-es-id and sysmac is configured * against an interface. */ -static int zebra_evpn_local_es_update(struct zebra_if *zif, esi_t *esi) +static void zebra_evpn_local_es_update(struct zebra_if *zif) { struct zebra_evpn_es *old_es = zif->es_info.es; struct zebra_evpn_es *es; + esi_t _esi, *esi; + + if (!zebra_evpn_is_if_es_capable(zif)) + return; + + if (memcmp(&zif->es_info.esi, zero_esi, sizeof(*zero_esi))) { + esi = &zif->es_info.esi; + } else if (zif->es_info.lid && !is_zero_mac(&zif->es_info.sysmac)) { + zebra_build_type3_esi(zif->es_info.lid, &zif->es_info.sysmac, + &_esi); + esi = &_esi; + } else { + esi = zero_esi; + } if (old_es && !memcmp(&old_es->esi, esi, sizeof(*esi))) /* dup - nothing to be done */ - return 0; + return; /* release the old_es against the zif */ if (old_es) zebra_evpn_local_es_del(&old_es); es = zebra_evpn_es_find(esi); - if (es) { - /* if it exists against another interface flag an error */ - if (es->zif && es->zif != zif) - return -1; - } else { - /* create new es */ + if (!es) es = zebra_evpn_es_new(esi); - } - memcpy(&zif->es_info.esi, esi, sizeof(*esi)); if (es) zebra_evpn_es_local_info_set(es, zif); - - return 0; -} - -static int zebra_evpn_type3_esi_update(struct zebra_if *zif, uint32_t lid, - struct ethaddr *sysmac) -{ - struct zebra_evpn_es *old_es = zif->es_info.es; - esi_t esi; - int offset = 0; - int field_bytes = 0; - - /* Complete config of the ES-ID bootstraps the ES */ - if (!lid || is_zero_mac(sysmac)) { - /* clear old esi */ - memset(&zif->es_info.esi, 0, sizeof(zif->es_info.esi)); - /* if in ES is attached to zif delete it */ - if (old_es) - zebra_evpn_local_es_del(&old_es); - return 0; - } - - /* build 10-byte type-3-ESI - - * Type(1-byte), MAC(6-bytes), ES-LID (3-bytes) - */ - field_bytes = 1; - esi.val[offset] = ESI_TYPE_MAC; - offset += field_bytes; - - field_bytes = ETH_ALEN; - memcpy(&esi.val[offset], (uint8_t *)sysmac, field_bytes); - offset += field_bytes; - - esi.val[offset++] = (uint8_t)(lid >> 16); - esi.val[offset++] = (uint8_t)(lid >> 8); - esi.val[offset++] = (uint8_t)lid; - - return zebra_evpn_local_es_update(zif, &esi); } int zebra_evpn_remote_es_del(const esi_t *esi, struct in_addr vtep_ip) @@ -2673,44 +2661,33 @@ static int zebra_evpn_es_evi_send_to_client(struct zebra_evpn_es *es, } /* sysmac part of a local ESI has changed */ -static int zebra_evpn_es_sys_mac_update(struct zebra_if *zif, - struct ethaddr *sysmac) +void zebra_evpn_es_sys_mac_update(struct zebra_if *zif, struct ethaddr *sysmac) { - int rv; - - rv = zebra_evpn_type3_esi_update(zif, zif->es_info.lid, sysmac); - if (!rv) + if (sysmac) memcpy(&zif->es_info.sysmac, sysmac, sizeof(struct ethaddr)); + else + memset(&zif->es_info.sysmac, 0, sizeof(struct ethaddr)); - return rv; + zebra_evpn_local_es_update(zif); } /* local-ID part of ESI has changed */ -static int zebra_evpn_es_lid_update(struct zebra_if *zif, uint32_t lid) +void zebra_evpn_es_lid_update(struct zebra_if *zif, uint32_t lid) { - int rv; - - rv = zebra_evpn_type3_esi_update(zif, lid, &zif->es_info.sysmac); - if (!rv) - zif->es_info.lid = lid; + zif->es_info.lid = lid; - return rv; + zebra_evpn_local_es_update(zif); } /* type-0 esi has changed */ -static int zebra_evpn_es_type0_esi_update(struct zebra_if *zif, esi_t *esi) +void zebra_evpn_es_type0_esi_update(struct zebra_if *zif, esi_t *esi) { - int rv; - - rv = zebra_evpn_local_es_update(zif, esi); - - /* clear the old es_lid, es_sysmac - type-0 is being set so old - * type-3 params need to be flushed - */ - memset(&zif->es_info.sysmac, 0, sizeof(struct ethaddr)); - zif->es_info.lid = 0; + if (esi) + memcpy(&zif->es_info.esi, esi, sizeof(*esi)); + else + memset(&zif->es_info.esi, 0, sizeof(*esi)); - return rv; + zebra_evpn_local_es_update(zif); } void zebra_evpn_es_cleanup(void) @@ -2726,10 +2703,9 @@ void zebra_evpn_es_cleanup(void) } } -static void zebra_evpn_es_df_pref_update(struct zebra_if *zif, uint16_t df_pref) +void zebra_evpn_es_df_pref_update(struct zebra_if *zif, uint16_t df_pref) { struct zebra_evpn_es *es; - uint16_t tmp_pref; if (zif->es_info.df_pref == df_pref) return; @@ -2740,13 +2716,10 @@ static void zebra_evpn_es_df_pref_update(struct zebra_if *zif, uint16_t df_pref) if (!es) return; - tmp_pref = zif->es_info.df_pref ? zif->es_info.df_pref - : EVPN_MH_DF_PREF_DEFAULT; - - if (es->df_pref == tmp_pref) + if (es->df_pref == zif->es_info.df_pref) return; - es->df_pref = tmp_pref; + es->df_pref = zif->es_info.df_pref; /* run df election */ zebra_evpn_es_run_df_election(es, __func__); /* notify bgp */ @@ -2833,7 +2806,7 @@ void zebra_evpn_es_bypass_update(struct zebra_evpn_es *es, zebra_evpn_es_br_port_dplane_update(es, __func__); } -static void zebra_evpn_es_bypass_cfg_update(struct zebra_if *zif, bool bypass) +void zebra_evpn_es_bypass_cfg_update(struct zebra_if *zif, bool bypass) { bool old_bypass = !!(zif->es_info.flags & ZIF_CFG_ES_FLAG_BYPASS); @@ -3326,208 +3299,9 @@ void zebra_evpn_es_show_esi(struct vty *vty, bool uj, esi_t *esi) vty_json(vty, json); } -int zebra_evpn_mh_if_write(struct vty *vty, struct interface *ifp) +void zebra_evpn_mh_if_init(struct zebra_if *zif) { - struct zebra_if *zif = ifp->info; - char buf[ETHER_ADDR_STRLEN]; - bool type_3_esi = false; - char esi_buf[ESI_STR_LEN]; - - if (zif->es_info.lid) { - vty_out(vty, " evpn mh es-id %u\n", zif->es_info.lid); - type_3_esi = true; - } - - if (!is_zero_mac(&zif->es_info.sysmac)) { - vty_out(vty, " evpn mh es-sys-mac %s\n", - prefix_mac2str(&zif->es_info.sysmac, - buf, sizeof(buf))); - type_3_esi = true; - } - - if (!type_3_esi - && memcmp(&zif->es_info.esi, zero_esi, sizeof(*zero_esi))) - vty_out(vty, " evpn mh es-id %s\n", - esi_to_str(&zif->es_info.esi, esi_buf, sizeof(esi_buf))); - - if (zif->es_info.df_pref) - vty_out(vty, " evpn mh es-df-pref %u\n", zif->es_info.df_pref); - - if (zif->flags & ZIF_FLAG_EVPN_MH_UPLINK) - vty_out(vty, " evpn mh uplink\n"); - - return 0; -} - -#include "zebra/zebra_evpn_mh_clippy.c" -/* CLI for setting an ES in bypass mode */ -DEFPY_HIDDEN(zebra_evpn_es_bypass, zebra_evpn_es_bypass_cmd, - "[no] evpn mh bypass", - NO_STR "EVPN\n" EVPN_MH_VTY_STR "set bypass mode\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - struct zebra_if *zif; - - zif = ifp->info; - - if (no) { - zebra_evpn_es_bypass_cfg_update(zif, false); - } else { - if (!zebra_evpn_is_if_es_capable(zif)) { - vty_out(vty, - "%% DF bypass cannot be associated with this interface type\n"); - return CMD_WARNING; - } - zebra_evpn_es_bypass_cfg_update(zif, true); - } - return CMD_SUCCESS; -} - -/* CLI for configuring DF preference part for an ES */ -DEFPY(zebra_evpn_es_pref, zebra_evpn_es_pref_cmd, - "[no$no] evpn mh es-df-pref [(1-65535)$df_pref]", - NO_STR "EVPN\n" EVPN_MH_VTY_STR - "preference value used for DF election\n" - "pref\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - struct zebra_if *zif; - - zif = ifp->info; - - if (no) { - zebra_evpn_es_df_pref_update(zif, 0); - } else { - if (!zebra_evpn_is_if_es_capable(zif)) { - vty_out(vty, - "%% DF preference cannot be associated with this interface type\n"); - return CMD_WARNING; - } - zebra_evpn_es_df_pref_update(zif, df_pref); - } - return CMD_SUCCESS; -} - -/* CLI for setting up sysmac part of ESI on an access port */ -DEFPY(zebra_evpn_es_sys_mac, - zebra_evpn_es_sys_mac_cmd, - "[no$no] evpn mh es-sys-mac [X:X:X:X:X:X$mac]", - NO_STR - "EVPN\n" - EVPN_MH_VTY_STR - "Ethernet segment system MAC\n" - MAC_STR -) -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - struct zebra_if *zif; - int ret = 0; - - zif = ifp->info; - - if (no) { - static struct ethaddr zero_mac; - - ret = zebra_evpn_es_sys_mac_update(zif, &zero_mac); - if (ret == -1) { - vty_out(vty, "%% Failed to clear ES sysmac\n"); - return CMD_WARNING; - } - } else { - - if (!zebra_evpn_is_if_es_capable(zif)) { - vty_out(vty, - "%% ESI cannot be associated with this interface type\n"); - return CMD_WARNING; - } - - if (!mac || is_zero_mac(&mac->eth_addr)) { - vty_out(vty, "%% ES sysmac value is invalid\n"); - return CMD_WARNING; - } - - ret = zebra_evpn_es_sys_mac_update(zif, &mac->eth_addr); - if (ret == -1) { - vty_out(vty, - "%% ESI already exists on a different interface\n"); - return CMD_WARNING; - } - } - return CMD_SUCCESS; -} - -/* CLI for setting up local-ID part of ESI on an access port */ -DEFPY(zebra_evpn_es_id, - zebra_evpn_es_id_cmd, - "[no$no] evpn mh es-id [(1-16777215)$es_lid | NAME$esi_str]", - NO_STR - "EVPN\n" - EVPN_MH_VTY_STR - "Ethernet segment identifier\n" - "local discriminator\n" - "10-byte ID - 00:AA:BB:CC:DD:EE:FF:GG:HH:II\n" -) -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - struct zebra_if *zif; - int ret = 0; - esi_t esi; - - zif = ifp->info; - - if (no) { - if (zif->es_info.lid) - ret = zebra_evpn_es_lid_update(zif, 0); - else if (memcmp(&zif->es_info.esi, zero_esi, sizeof(*zero_esi))) - ret = zebra_evpn_es_type0_esi_update(zif, zero_esi); - - if (ret == -1) { - vty_out(vty, - "%% Failed to clear ES local id or ESI name\n"); - return CMD_WARNING; - } - } else { - if (!zebra_evpn_is_if_es_capable(zif)) { - vty_out(vty, - "%% ESI cannot be associated with this interface type\n"); - return CMD_WARNING; - } - - if (esi_str) { - if (!str_to_esi(esi_str, &esi)) { - vty_out(vty, "%% Malformed ESI name\n"); - return CMD_WARNING; - } - ret = zebra_evpn_es_type0_esi_update(zif, &esi); - } else { - if (!es_lid) { - vty_out(vty, - "%% Specify ES local id or ESI name\n"); - return CMD_WARNING; - } - ret = zebra_evpn_es_lid_update(zif, es_lid); - } - - if (ret == -1) { - vty_out(vty, - "%% ESI already exists on a different interface\n"); - return CMD_WARNING; - } - } - return CMD_SUCCESS; -} - -/* CLI for tagging an interface as an uplink */ -DEFPY(zebra_evpn_mh_uplink, zebra_evpn_mh_uplink_cmd, "[no] evpn mh uplink", - NO_STR "EVPN\n" EVPN_MH_VTY_STR "uplink to the VxLAN core\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - struct zebra_if *zif; - - zif = ifp->info; - zebra_evpn_mh_uplink_cfg_update(zif, no ? false : true); - - return CMD_SUCCESS; + zif->es_info.df_pref = EVPN_MH_DF_PREF_DEFAULT; } void zebra_evpn_mh_json(json_object *json) @@ -3864,7 +3638,7 @@ static void zebra_evpn_mh_uplink_oper_flags_update(struct zebra_if *zif, } } -static void zebra_evpn_mh_uplink_cfg_update(struct zebra_if *zif, bool set) +void zebra_evpn_mh_uplink_cfg_update(struct zebra_if *zif, bool set) { bool old_protodown = zebra_evpn_mh_is_all_uplinks_down(); bool new_protodown; @@ -4087,15 +3861,6 @@ int zebra_evpn_mh_redirect_off(struct vty *vty, bool redirect_off) return 0; } -void zebra_evpn_interface_init(void) -{ - install_element(INTERFACE_NODE, &zebra_evpn_es_id_cmd); - install_element(INTERFACE_NODE, &zebra_evpn_es_sys_mac_cmd); - install_element(INTERFACE_NODE, &zebra_evpn_es_pref_cmd); - install_element(INTERFACE_NODE, &zebra_evpn_es_bypass_cmd); - install_element(INTERFACE_NODE, &zebra_evpn_mh_uplink_cmd); -} - void zebra_evpn_mh_init(void) { zrouter.mh_info = XCALLOC(MTYPE_ZMH_INFO, sizeof(*zrouter.mh_info)); diff --git a/zebra/zebra_evpn_mh.h b/zebra/zebra_evpn_mh.h index 59a41d0606..6080048976 100644 --- a/zebra/zebra_evpn_mh.h +++ b/zebra/zebra_evpn_mh.h @@ -17,8 +17,7 @@ #include "zebra_vxlan.h" #include "zebra_vxlan_private.h" #include "zebra_nhg.h" - -#define EVPN_MH_VTY_STR "Multihoming\n" +#include "zebra_nb.h" /* Ethernet Segment entry - * - Local and remote ESs are maintained in a global RB tree, @@ -336,8 +335,6 @@ extern bool zebra_evpn_es_mac_ref_entry(struct zebra_mac *mac, struct zebra_evpn_es *es); extern bool zebra_evpn_es_mac_ref(struct zebra_mac *mac, const esi_t *esi); extern struct zebra_evpn_es *zebra_evpn_es_find(const esi_t *esi); -extern void zebra_evpn_interface_init(void); -extern int zebra_evpn_mh_if_write(struct vty *vty, struct interface *ifp); extern void zebra_evpn_acc_vl_show(struct vty *vty, bool uj); extern void zebra_evpn_acc_vl_show_detail(struct vty *vty, bool uj); extern void zebra_evpn_if_es_print(struct vty *vty, json_object *json, @@ -382,4 +379,16 @@ extern void zebra_evpn_proc_remote_nh(ZAPI_HANDLER_ARGS); extern struct zebra_evpn_es_evi * zebra_evpn_es_evi_find(struct zebra_evpn_es *es, struct zebra_evpn *zevpn); +void zebra_build_type3_esi(uint32_t lid, struct ethaddr *mac, esi_t *esi); + +void zebra_evpn_es_sys_mac_update(struct zebra_if *zif, struct ethaddr *sysmac); +void zebra_evpn_es_lid_update(struct zebra_if *zif, uint32_t lid); +void zebra_evpn_es_type0_esi_update(struct zebra_if *zif, esi_t *esi); + +void zebra_evpn_es_df_pref_update(struct zebra_if *zif, uint16_t df_pref); +void zebra_evpn_es_bypass_cfg_update(struct zebra_if *zif, bool bypass); +void zebra_evpn_mh_uplink_cfg_update(struct zebra_if *zif, bool set); + +void zebra_evpn_mh_if_init(struct zebra_if *zif); + #endif /* _ZEBRA_EVPN_MH_H */ diff --git a/zebra/zebra_nb.c b/zebra/zebra_nb.c index 7cdcaedd7e..7e1c43c204 100644 --- a/zebra/zebra_nb.c +++ b/zebra/zebra_nb.c @@ -10,9 +10,20 @@ #include "libfrr.h" #include "zebra_nb.h" +const char *features[] = { +#if HAVE_BFDD == 0 + "ptm-bfd", +#endif +#if defined(HAVE_RTADV) + "ipv6-router-advertisements", +#endif + NULL +}; + /* clang-format off */ const struct frr_yang_module_info frr_zebra_info = { .name = "frr-zebra", + .features = features, .nodes = { { .xpath = "/frr-zebra:zebra/mcast-rpf-lookup", @@ -79,6 +90,20 @@ const struct frr_yang_module_info frr_zebra_info = { .modify = zebra_dplane_queue_limit_modify, } }, +#if HAVE_BFDD == 0 + { + .xpath = "/frr-zebra:zebra/ptm-enable", + .cbs = { + .modify = zebra_ptm_enable_modify, + } + }, +#endif + { + .xpath = "/frr-zebra:zebra/route-map-delay", + .cbs = { + .modify = zebra_route_map_delay_modify, + } + }, { .xpath = "/frr-zebra:zebra/debugs/debug-events", .cbs = { @@ -290,24 +315,38 @@ const struct frr_yang_module_info frr_zebra_info = { } }, { - .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ip-addrs", + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv4-addrs", + .cbs = { + .create = lib_interface_zebra_ipv4_addrs_create, + .destroy = lib_interface_zebra_ipv4_addrs_destroy, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv4-addrs/label", .cbs = { - .create = lib_interface_zebra_ip_addrs_create, - .destroy = lib_interface_zebra_ip_addrs_destroy, + .modify = lib_interface_zebra_ipv4_addrs_label_modify, + .destroy = lib_interface_zebra_ipv4_addrs_label_destroy, } }, { - .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ip-addrs/label", + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv4-p2p-addrs", .cbs = { - .modify = lib_interface_zebra_ip_addrs_label_modify, - .destroy = lib_interface_zebra_ip_addrs_label_destroy, + .create = lib_interface_zebra_ipv4_p2p_addrs_create, + .destroy = lib_interface_zebra_ipv4_p2p_addrs_destroy, } }, { - .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ip-addrs/ip4-peer", + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv4-p2p-addrs/label", .cbs = { - .modify = lib_interface_zebra_ip_addrs_ip4_peer_modify, - .destroy = lib_interface_zebra_ip_addrs_ip4_peer_destroy, + .modify = lib_interface_zebra_ipv4_p2p_addrs_label_modify, + .destroy = lib_interface_zebra_ipv4_p2p_addrs_label_destroy, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-addrs", + .cbs = { + .create = lib_interface_zebra_ipv6_addrs_create, + .destroy = lib_interface_zebra_ipv6_addrs_destroy, } }, { @@ -321,14 +360,13 @@ const struct frr_yang_module_info frr_zebra_info = { .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/link-detect", .cbs = { .modify = lib_interface_zebra_link_detect_modify, - .destroy = lib_interface_zebra_link_detect_destroy, } }, { - .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/shutdown", + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/enabled", .cbs = { - .modify = lib_interface_zebra_shutdown_modify, - .destroy = lib_interface_zebra_shutdown_destroy, + .modify = lib_interface_zebra_enabled_modify, + .destroy = lib_interface_zebra_enabled_destroy, } }, { @@ -346,10 +384,66 @@ const struct frr_yang_module_info frr_zebra_info = { } }, { - .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/bandwidth", + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/link-params", .cbs = { - .modify = lib_interface_zebra_bandwidth_modify, - .destroy = lib_interface_zebra_bandwidth_destroy, + .create = lib_interface_zebra_link_params_create, + .destroy = lib_interface_zebra_link_params_destroy, + .apply_finish = lib_interface_zebra_link_params_apply_finish, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/link-params/metric", + .cbs = { + .modify = lib_interface_zebra_link_params_metric_modify, + .destroy = lib_interface_zebra_link_params_metric_destroy, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/link-params/max-bandwidth", + .cbs = { + .modify = lib_interface_zebra_link_params_max_bandwidth_modify, + .destroy = lib_interface_zebra_link_params_max_bandwidth_destroy, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/link-params/max-reservable-bandwidth", + .cbs = { + .modify = lib_interface_zebra_link_params_max_reservable_bandwidth_modify, + .destroy = lib_interface_zebra_link_params_max_reservable_bandwidth_destroy, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/link-params/unreserved-bandwidths/unreserved-bandwidth", + .cbs = { + .create = lib_interface_zebra_link_params_unreserved_bandwidths_unreserved_bandwidth_create, + .destroy = lib_interface_zebra_link_params_unreserved_bandwidths_unreserved_bandwidth_destroy, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/link-params/unreserved-bandwidths/unreserved-bandwidth/unreserved-bandwidth", + .cbs = { + .modify = lib_interface_zebra_link_params_unreserved_bandwidths_unreserved_bandwidth_unreserved_bandwidth_modify, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/link-params/residual-bandwidth", + .cbs = { + .modify = lib_interface_zebra_link_params_residual_bandwidth_modify, + .destroy = lib_interface_zebra_link_params_residual_bandwidth_destroy, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/link-params/available-bandwidth", + .cbs = { + .modify = lib_interface_zebra_link_params_available_bandwidth_modify, + .destroy = lib_interface_zebra_link_params_available_bandwidth_destroy, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/link-params/utilized-bandwidth", + .cbs = { + .modify = lib_interface_zebra_link_params_utilized_bandwidth_modify, + .destroy = lib_interface_zebra_link_params_utilized_bandwidth_destroy, } }, { @@ -357,13 +451,11 @@ const struct frr_yang_module_info frr_zebra_info = { .cbs = { .modify = lib_interface_zebra_legacy_admin_group_modify, .destroy = lib_interface_zebra_legacy_admin_group_destroy, - .cli_show = cli_show_legacy_admin_group, }, }, { .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/link-params/affinities", .cbs = { - .cli_show = cli_show_affinity, }, }, { @@ -377,10 +469,276 @@ const struct frr_yang_module_info frr_zebra_info = { .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/link-params/affinity-mode", .cbs = { .modify = lib_interface_zebra_affinity_mode_modify, - .cli_show = cli_show_affinity_mode, }, }, { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/link-params/neighbor", + .cbs = { + .create = lib_interface_zebra_link_params_neighbor_create, + .destroy = lib_interface_zebra_link_params_neighbor_destroy, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/link-params/neighbor/remote-as", + .cbs = { + .modify = lib_interface_zebra_link_params_neighbor_remote_as_modify, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/link-params/neighbor/ipv4-remote-id", + .cbs = { + .modify = lib_interface_zebra_link_params_neighbor_ipv4_remote_id_modify, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/link-params/delay", + .cbs = { + .modify = lib_interface_zebra_link_params_delay_modify, + .destroy = lib_interface_zebra_link_params_delay_destroy, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/link-params/min-max-delay", + .cbs = { + .create = lib_interface_zebra_link_params_min_max_delay_create, + .destroy = lib_interface_zebra_link_params_min_max_delay_destroy, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/link-params/min-max-delay/delay-min", + .cbs = { + .modify = lib_interface_zebra_link_params_min_max_delay_delay_min_modify, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/link-params/min-max-delay/delay-max", + .cbs = { + .modify = lib_interface_zebra_link_params_min_max_delay_delay_max_modify, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/link-params/delay-variation", + .cbs = { + .modify = lib_interface_zebra_link_params_delay_variation_modify, + .destroy = lib_interface_zebra_link_params_delay_variation_destroy, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/link-params/packet-loss", + .cbs = { + .modify = lib_interface_zebra_link_params_packet_loss_modify, + .destroy = lib_interface_zebra_link_params_packet_loss_destroy, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/evpn-mh/type-0/esi", + .cbs = { + .modify = lib_interface_zebra_evpn_mh_type_0_esi_modify, + .destroy = lib_interface_zebra_evpn_mh_type_0_esi_destroy, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/evpn-mh/type-3/system-mac", + .cbs = { + .modify = lib_interface_zebra_evpn_mh_type_3_system_mac_modify, + .destroy = lib_interface_zebra_evpn_mh_type_3_system_mac_destroy, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/evpn-mh/type-3/local-discriminator", + .cbs = { + .modify = lib_interface_zebra_evpn_mh_type_3_local_discriminator_modify, + .destroy = lib_interface_zebra_evpn_mh_type_3_local_discriminator_destroy, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/evpn-mh/df-preference", + .cbs = { + .modify = lib_interface_zebra_evpn_mh_df_preference_modify, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/evpn-mh/bypass", + .cbs = { + .modify = lib_interface_zebra_evpn_mh_bypass_modify, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/evpn-mh/uplink", + .cbs = { + .modify = lib_interface_zebra_evpn_mh_uplink_modify, + } + }, +#if defined(HAVE_RTADV) + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/send-advertisements", + .cbs = { + .modify = lib_interface_zebra_ipv6_router_advertisements_send_advertisements_modify, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/max-rtr-adv-interval", + .cbs = { + .modify = lib_interface_zebra_ipv6_router_advertisements_max_rtr_adv_interval_modify, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/managed-flag", + .cbs = { + .modify = lib_interface_zebra_ipv6_router_advertisements_managed_flag_modify, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/other-config-flag", + .cbs = { + .modify = lib_interface_zebra_ipv6_router_advertisements_other_config_flag_modify, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/home-agent-flag", + .cbs = { + .modify = lib_interface_zebra_ipv6_router_advertisements_home_agent_flag_modify, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/link-mtu", + .cbs = { + .modify = lib_interface_zebra_ipv6_router_advertisements_link_mtu_modify, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/reachable-time", + .cbs = { + .modify = lib_interface_zebra_ipv6_router_advertisements_reachable_time_modify, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/retrans-timer", + .cbs = { + .modify = lib_interface_zebra_ipv6_router_advertisements_retrans_timer_modify, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/cur-hop-limit", + .cbs = { + .modify = lib_interface_zebra_ipv6_router_advertisements_cur_hop_limit_modify, + .destroy = lib_interface_zebra_ipv6_router_advertisements_cur_hop_limit_destroy, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/default-lifetime", + .cbs = { + .modify = lib_interface_zebra_ipv6_router_advertisements_default_lifetime_modify, + .destroy = lib_interface_zebra_ipv6_router_advertisements_default_lifetime_destroy, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/fast-retransmit", + .cbs = { + .modify = lib_interface_zebra_ipv6_router_advertisements_fast_retransmit_modify, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/advertisement-interval-option", + .cbs = { + .modify = lib_interface_zebra_ipv6_router_advertisements_advertisement_interval_option_modify, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/home-agent-preference", + .cbs = { + .modify = lib_interface_zebra_ipv6_router_advertisements_home_agent_preference_modify, + .destroy = lib_interface_zebra_ipv6_router_advertisements_home_agent_preference_destroy, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/home-agent-lifetime", + .cbs = { + .modify = lib_interface_zebra_ipv6_router_advertisements_home_agent_lifetime_modify, + .destroy = lib_interface_zebra_ipv6_router_advertisements_home_agent_lifetime_destroy, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/default-router-preference", + .cbs = { + .modify = lib_interface_zebra_ipv6_router_advertisements_default_router_preference_modify, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/prefix-list/prefix", + .cbs = { + .create = lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_create, + .destroy = lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_destroy, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/dnssl/dnssl-domain", + .cbs = { + .create = lib_interface_zebra_ipv6_router_advertisements_dnssl_dnssl_domain_create, + .destroy = lib_interface_zebra_ipv6_router_advertisements_dnssl_dnssl_domain_destroy, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/dnssl/dnssl-domain/lifetime", + .cbs = { + .modify = lib_interface_zebra_ipv6_router_advertisements_dnssl_dnssl_domain_lifetime_modify, + .destroy = lib_interface_zebra_ipv6_router_advertisements_dnssl_dnssl_domain_lifetime_destroy, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/prefix-list/prefix/valid-lifetime", + .cbs = { + .modify = lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_valid_lifetime_modify, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/prefix-list/prefix/on-link-flag", + .cbs = { + .modify = lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_on_link_flag_modify, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/prefix-list/prefix/preferred-lifetime", + .cbs = { + .modify = lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_preferred_lifetime_modify, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/prefix-list/prefix/autonomous-flag", + .cbs = { + .modify = lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_autonomous_flag_modify, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/prefix-list/prefix/router-address-flag", + .cbs = { + .modify = lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_router_address_flag_modify, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/rdnss/rdnss-address", + .cbs = { + .create = lib_interface_zebra_ipv6_router_advertisements_rdnss_rdnss_address_create, + .destroy = lib_interface_zebra_ipv6_router_advertisements_rdnss_rdnss_address_destroy, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/rdnss/rdnss-address/lifetime", + .cbs = { + .modify = lib_interface_zebra_ipv6_router_advertisements_rdnss_rdnss_address_lifetime_modify, + .destroy = lib_interface_zebra_ipv6_router_advertisements_rdnss_rdnss_address_lifetime_destroy, + } + }, +#endif /* defined(HAVE_RTADV) */ +#if HAVE_BFDD == 0 + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ptm-enable", + .cbs = { + .modify = lib_interface_zebra_ptm_enable_modify, + } + }, +#endif + { .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/state/up-count", .cbs = { .get_elem = lib_interface_zebra_state_up_count_get_elem, @@ -429,6 +787,81 @@ const struct frr_yang_module_info frr_zebra_info = { } }, { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:zebra/router-id", + .cbs = { + .modify = lib_vrf_zebra_router_id_modify, + .destroy = lib_vrf_zebra_router_id_destroy, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:zebra/ipv6-router-id", + .cbs = { + .modify = lib_vrf_zebra_ipv6_router_id_modify, + .destroy = lib_vrf_zebra_ipv6_router_id_destroy, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:zebra/filter-protocol", + .cbs = { + .create = lib_vrf_zebra_filter_protocol_create, + .destroy = lib_vrf_zebra_filter_protocol_destroy, + .apply_finish = lib_vrf_zebra_filter_protocol_apply_finish, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:zebra/filter-protocol/route-map", + .cbs = { + .modify = lib_vrf_zebra_filter_protocol_route_map_modify, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:zebra/filter-nht", + .cbs = { + .create = lib_vrf_zebra_filter_nht_create, + .destroy = lib_vrf_zebra_filter_nht_destroy, + .apply_finish = lib_vrf_zebra_filter_nht_apply_finish, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:zebra/filter-nht/route-map", + .cbs = { + .modify = lib_vrf_zebra_filter_nht_route_map_modify, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:zebra/resolve-via-default", + .cbs = { + .modify = lib_vrf_zebra_resolve_via_default_modify, + .destroy = lib_vrf_zebra_resolve_via_default_destroy, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:zebra/ipv6-resolve-via-default", + .cbs = { + .modify = lib_vrf_zebra_ipv6_resolve_via_default_modify, + .destroy = lib_vrf_zebra_ipv6_resolve_via_default_destroy, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:zebra/netns/table-range", + .cbs = { + .create = lib_vrf_zebra_netns_table_range_create, + .destroy = lib_vrf_zebra_netns_table_range_destroy, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:zebra/netns/table-range/start", + .cbs = { + .modify = lib_vrf_zebra_netns_table_range_start_modify, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:zebra/netns/table-range/end", + .cbs = { + .modify = lib_vrf_zebra_netns_table_range_end_modify, + } + }, + { .xpath = "/frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib", .cbs = { .get_next = lib_vrf_zebra_ribs_rib_get_next, diff --git a/zebra/zebra_nb.h b/zebra/zebra_nb.h index 6762ebd314..97979ef962 100644 --- a/zebra/zebra_nb.h +++ b/zebra/zebra_nb.h @@ -44,6 +44,10 @@ int zebra_import_kernel_table_route_map_destroy( int zebra_allow_external_route_update_create(struct nb_cb_create_args *args); int zebra_allow_external_route_update_destroy(struct nb_cb_destroy_args *args); int zebra_dplane_queue_limit_modify(struct nb_cb_modify_args *args); +#if HAVE_BFDD == 0 +int zebra_ptm_enable_modify(struct nb_cb_modify_args *args); +#endif +int zebra_route_map_delay_modify(struct nb_cb_modify_args *args); int zebra_debugs_debug_events_modify(struct nb_cb_modify_args *args); int zebra_debugs_debug_events_destroy(struct nb_cb_destroy_args *args); int zebra_debugs_debug_zapi_send_modify(struct nb_cb_modify_args *args); @@ -80,31 +84,185 @@ int zebra_debugs_debug_dplane_detail_modify(struct nb_cb_modify_args *args); int zebra_debugs_debug_dplane_detail_destroy(struct nb_cb_destroy_args *args); int zebra_debugs_debug_mlag_modify(struct nb_cb_modify_args *args); int zebra_debugs_debug_mlag_destroy(struct nb_cb_destroy_args *args); -int lib_interface_zebra_ip_addrs_create(struct nb_cb_create_args *args); -int lib_interface_zebra_ip_addrs_destroy(struct nb_cb_destroy_args *args); -int lib_interface_zebra_ip_addrs_label_modify(struct nb_cb_modify_args *args); -int lib_interface_zebra_ip_addrs_label_destroy(struct nb_cb_destroy_args *args); -int lib_interface_zebra_ip_addrs_ip4_peer_modify( +int lib_interface_zebra_ipv4_addrs_create(struct nb_cb_create_args *args); +int lib_interface_zebra_ipv4_addrs_destroy(struct nb_cb_destroy_args *args); +int lib_interface_zebra_ipv4_addrs_label_modify(struct nb_cb_modify_args *args); +int lib_interface_zebra_ipv4_addrs_label_destroy(struct nb_cb_destroy_args *args); +int lib_interface_zebra_ipv4_p2p_addrs_create(struct nb_cb_create_args *args); +int lib_interface_zebra_ipv4_p2p_addrs_destroy(struct nb_cb_destroy_args *args); +int lib_interface_zebra_ipv4_p2p_addrs_label_modify( struct nb_cb_modify_args *args); -int lib_interface_zebra_ip_addrs_ip4_peer_destroy( +int lib_interface_zebra_ipv4_p2p_addrs_label_destroy( struct nb_cb_destroy_args *args); +int lib_interface_zebra_ipv6_addrs_create(struct nb_cb_create_args *args); +int lib_interface_zebra_ipv6_addrs_destroy(struct nb_cb_destroy_args *args); int lib_interface_zebra_multicast_modify(struct nb_cb_modify_args *args); int lib_interface_zebra_multicast_destroy(struct nb_cb_destroy_args *args); int lib_interface_zebra_link_detect_modify(struct nb_cb_modify_args *args); -int lib_interface_zebra_link_detect_destroy(struct nb_cb_destroy_args *args); -int lib_interface_zebra_shutdown_modify(struct nb_cb_modify_args *args); -int lib_interface_zebra_shutdown_destroy(struct nb_cb_destroy_args *args); +int lib_interface_zebra_enabled_modify(struct nb_cb_modify_args *args); +int lib_interface_zebra_enabled_destroy(struct nb_cb_destroy_args *args); int lib_interface_zebra_bandwidth_modify(struct nb_cb_modify_args *args); int lib_interface_zebra_bandwidth_destroy(struct nb_cb_destroy_args *args); int lib_interface_zebra_mpls_modify(struct nb_cb_modify_args *args); int lib_interface_zebra_mpls_destroy(struct nb_cb_destroy_args *args); -int lib_interface_zebra_legacy_admin_group_modify( +int lib_interface_zebra_link_params_create(struct nb_cb_create_args *args); +int lib_interface_zebra_link_params_destroy(struct nb_cb_destroy_args *args); +void lib_interface_zebra_link_params_apply_finish( + struct nb_cb_apply_finish_args *args); +int lib_interface_zebra_link_params_metric_modify(struct nb_cb_modify_args *args); +int lib_interface_zebra_link_params_metric_destroy( + struct nb_cb_destroy_args *args); +int lib_interface_zebra_link_params_max_bandwidth_modify( + struct nb_cb_modify_args *args); +int lib_interface_zebra_link_params_max_bandwidth_destroy( + struct nb_cb_destroy_args *args); +int lib_interface_zebra_link_params_max_reservable_bandwidth_modify( + struct nb_cb_modify_args *args); +int lib_interface_zebra_link_params_max_reservable_bandwidth_destroy( + struct nb_cb_destroy_args *args); +int lib_interface_zebra_link_params_unreserved_bandwidths_unreserved_bandwidth_create( + struct nb_cb_create_args *args); +void lib_interface_zebra_link_params_unreserved_bandwidths_unreserved_bandwidth_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults); +int lib_interface_zebra_link_params_unreserved_bandwidths_unreserved_bandwidth_destroy( + struct nb_cb_destroy_args *args); +int lib_interface_zebra_link_params_unreserved_bandwidths_unreserved_bandwidth_unreserved_bandwidth_modify( + struct nb_cb_modify_args *args); +void lib_interface_zebra_link_params_unreserved_bandwidths_unreserved_bandwidth_unreserved_bandwidth_cli_write( + struct vty *vty, const struct lyd_node *dnode, bool show_defaults); +int lib_interface_zebra_link_params_residual_bandwidth_modify( struct nb_cb_modify_args *args); +int lib_interface_zebra_link_params_residual_bandwidth_destroy( + struct nb_cb_destroy_args *args); +int lib_interface_zebra_link_params_available_bandwidth_modify( + struct nb_cb_modify_args *args); +int lib_interface_zebra_link_params_available_bandwidth_destroy( + struct nb_cb_destroy_args *args); +int lib_interface_zebra_link_params_utilized_bandwidth_modify( + struct nb_cb_modify_args *args); +int lib_interface_zebra_link_params_utilized_bandwidth_destroy( + struct nb_cb_destroy_args *args); +int lib_interface_zebra_legacy_admin_group_modify(struct nb_cb_modify_args *args); int lib_interface_zebra_legacy_admin_group_destroy( struct nb_cb_destroy_args *args); int lib_interface_zebra_affinity_create(struct nb_cb_create_args *args); int lib_interface_zebra_affinity_destroy(struct nb_cb_destroy_args *args); int lib_interface_zebra_affinity_mode_modify(struct nb_cb_modify_args *args); +int lib_interface_zebra_link_params_neighbor_create( + struct nb_cb_create_args *args); +int lib_interface_zebra_link_params_neighbor_destroy( + struct nb_cb_destroy_args *args); +int lib_interface_zebra_link_params_neighbor_remote_as_modify( + struct nb_cb_modify_args *args); +int lib_interface_zebra_link_params_neighbor_ipv4_remote_id_modify( + struct nb_cb_modify_args *args); +int lib_interface_zebra_link_params_delay_modify(struct nb_cb_modify_args *args); +int lib_interface_zebra_link_params_delay_destroy( + struct nb_cb_destroy_args *args); +int lib_interface_zebra_link_params_min_max_delay_create( + struct nb_cb_create_args *args); +int lib_interface_zebra_link_params_min_max_delay_destroy( + struct nb_cb_destroy_args *args); +int lib_interface_zebra_link_params_min_max_delay_delay_min_modify( + struct nb_cb_modify_args *args); +int lib_interface_zebra_link_params_min_max_delay_delay_max_modify( + struct nb_cb_modify_args *args); +int lib_interface_zebra_link_params_delay_variation_modify( + struct nb_cb_modify_args *args); +int lib_interface_zebra_link_params_delay_variation_destroy( + struct nb_cb_destroy_args *args); +int lib_interface_zebra_link_params_packet_loss_modify( + struct nb_cb_modify_args *args); +int lib_interface_zebra_link_params_packet_loss_destroy( + struct nb_cb_destroy_args *args); +int lib_interface_zebra_evpn_mh_type_0_esi_modify(struct nb_cb_modify_args *args); +int lib_interface_zebra_evpn_mh_type_0_esi_destroy( + struct nb_cb_destroy_args *args); +int lib_interface_zebra_evpn_mh_type_3_system_mac_modify( + struct nb_cb_modify_args *args); +int lib_interface_zebra_evpn_mh_type_3_system_mac_destroy( + struct nb_cb_destroy_args *args); +int lib_interface_zebra_evpn_mh_type_3_local_discriminator_modify( + struct nb_cb_modify_args *args); +int lib_interface_zebra_evpn_mh_type_3_local_discriminator_destroy( + struct nb_cb_destroy_args *args); +int lib_interface_zebra_evpn_mh_df_preference_modify( + struct nb_cb_modify_args *args); +int lib_interface_zebra_evpn_mh_bypass_modify(struct nb_cb_modify_args *args); +int lib_interface_zebra_evpn_mh_uplink_modify(struct nb_cb_modify_args *args); +#if defined(HAVE_RTADV) +int lib_interface_zebra_ipv6_router_advertisements_send_advertisements_modify( + struct nb_cb_modify_args *args); +int lib_interface_zebra_ipv6_router_advertisements_max_rtr_adv_interval_modify( + struct nb_cb_modify_args *args); +int lib_interface_zebra_ipv6_router_advertisements_managed_flag_modify( + struct nb_cb_modify_args *args); +int lib_interface_zebra_ipv6_router_advertisements_other_config_flag_modify( + struct nb_cb_modify_args *args); +int lib_interface_zebra_ipv6_router_advertisements_home_agent_flag_modify( + struct nb_cb_modify_args *args); +int lib_interface_zebra_ipv6_router_advertisements_link_mtu_modify( + struct nb_cb_modify_args *args); +int lib_interface_zebra_ipv6_router_advertisements_reachable_time_modify( + struct nb_cb_modify_args *args); +int lib_interface_zebra_ipv6_router_advertisements_retrans_timer_modify( + struct nb_cb_modify_args *args); +int lib_interface_zebra_ipv6_router_advertisements_cur_hop_limit_modify( + struct nb_cb_modify_args *args); +int lib_interface_zebra_ipv6_router_advertisements_cur_hop_limit_destroy( + struct nb_cb_destroy_args *args); +int lib_interface_zebra_ipv6_router_advertisements_default_lifetime_modify( + struct nb_cb_modify_args *args); +int lib_interface_zebra_ipv6_router_advertisements_default_lifetime_destroy( + struct nb_cb_destroy_args *args); +int lib_interface_zebra_ipv6_router_advertisements_fast_retransmit_modify( + struct nb_cb_modify_args *args); +int lib_interface_zebra_ipv6_router_advertisements_advertisement_interval_option_modify( + struct nb_cb_modify_args *args); +int lib_interface_zebra_ipv6_router_advertisements_home_agent_preference_modify( + struct nb_cb_modify_args *args); +int lib_interface_zebra_ipv6_router_advertisements_home_agent_preference_destroy( + struct nb_cb_destroy_args *args); +int lib_interface_zebra_ipv6_router_advertisements_home_agent_lifetime_modify( + struct nb_cb_modify_args *args); +int lib_interface_zebra_ipv6_router_advertisements_home_agent_lifetime_destroy( + struct nb_cb_destroy_args *args); +int lib_interface_zebra_ipv6_router_advertisements_default_router_preference_modify( + struct nb_cb_modify_args *args); +int lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_create( + struct nb_cb_create_args *args); +int lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_destroy( + struct nb_cb_destroy_args *args); +int lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_valid_lifetime_modify( + struct nb_cb_modify_args *args); +int lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_on_link_flag_modify( + struct nb_cb_modify_args *args); +int lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_preferred_lifetime_modify( + struct nb_cb_modify_args *args); +int lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_autonomous_flag_modify( + struct nb_cb_modify_args *args); +int lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_router_address_flag_modify( + struct nb_cb_modify_args *args); +int lib_interface_zebra_ipv6_router_advertisements_rdnss_rdnss_address_create( + struct nb_cb_create_args *args); +int lib_interface_zebra_ipv6_router_advertisements_rdnss_rdnss_address_destroy( + struct nb_cb_destroy_args *args); +int lib_interface_zebra_ipv6_router_advertisements_rdnss_rdnss_address_lifetime_modify( + struct nb_cb_modify_args *args); +int lib_interface_zebra_ipv6_router_advertisements_rdnss_rdnss_address_lifetime_destroy( + struct nb_cb_destroy_args *args); +int lib_interface_zebra_ipv6_router_advertisements_dnssl_dnssl_domain_create( + struct nb_cb_create_args *args); +int lib_interface_zebra_ipv6_router_advertisements_dnssl_dnssl_domain_destroy( + struct nb_cb_destroy_args *args); +int lib_interface_zebra_ipv6_router_advertisements_dnssl_dnssl_domain_lifetime_modify( + struct nb_cb_modify_args *args); +int lib_interface_zebra_ipv6_router_advertisements_dnssl_dnssl_domain_lifetime_destroy( + struct nb_cb_destroy_args *args); +#endif /* defined(HAVE_RTADV) */ +#if HAVE_BFDD == 0 +int lib_interface_zebra_ptm_enable_modify(struct nb_cb_modify_args *args); +#endif struct yang_data * lib_interface_zebra_state_up_count_get_elem(struct nb_cb_get_elem_args *args); struct yang_data * @@ -121,6 +279,29 @@ struct yang_data *lib_interface_zebra_state_remote_vtep_get_elem( struct nb_cb_get_elem_args *args); struct yang_data *lib_interface_zebra_state_mcast_group_get_elem( struct nb_cb_get_elem_args *args); +int lib_vrf_zebra_router_id_modify(struct nb_cb_modify_args *args); +int lib_vrf_zebra_router_id_destroy(struct nb_cb_destroy_args *args); +int lib_vrf_zebra_ipv6_router_id_modify(struct nb_cb_modify_args *args); +int lib_vrf_zebra_ipv6_router_id_destroy(struct nb_cb_destroy_args *args); +int lib_vrf_zebra_filter_protocol_create(struct nb_cb_create_args *args); +int lib_vrf_zebra_filter_protocol_destroy(struct nb_cb_destroy_args *args); +void lib_vrf_zebra_filter_protocol_apply_finish( + struct nb_cb_apply_finish_args *args); +int lib_vrf_zebra_filter_protocol_route_map_modify( + struct nb_cb_modify_args *args); +int lib_vrf_zebra_filter_nht_create(struct nb_cb_create_args *args); +int lib_vrf_zebra_filter_nht_destroy(struct nb_cb_destroy_args *args); +void lib_vrf_zebra_filter_nht_apply_finish(struct nb_cb_apply_finish_args *args); +int lib_vrf_zebra_filter_nht_route_map_modify(struct nb_cb_modify_args *args); +int lib_vrf_zebra_resolve_via_default_modify(struct nb_cb_modify_args *args); +int lib_vrf_zebra_resolve_via_default_destroy(struct nb_cb_destroy_args *args); +int lib_vrf_zebra_ipv6_resolve_via_default_modify(struct nb_cb_modify_args *args); +int lib_vrf_zebra_ipv6_resolve_via_default_destroy( + struct nb_cb_destroy_args *args); +int lib_vrf_zebra_netns_table_range_create(struct nb_cb_create_args *args); +int lib_vrf_zebra_netns_table_range_destroy(struct nb_cb_destroy_args *args); +int lib_vrf_zebra_netns_table_range_start_modify(struct nb_cb_modify_args *args); +int lib_vrf_zebra_netns_table_range_end_modify(struct nb_cb_modify_args *args); const void *lib_vrf_zebra_ribs_rib_get_next(struct nb_cb_get_next_args *args); int lib_vrf_zebra_ribs_rib_get_keys(struct nb_cb_get_keys_args *args); const void * diff --git a/zebra/zebra_nb_config.c b/zebra/zebra_nb_config.c index 98c241b2a1..f24af16a2e 100644 --- a/zebra/zebra_nb_config.c +++ b/zebra/zebra_nb_config.c @@ -23,6 +23,12 @@ #include "zebra/debug.h" #include "zebra/zebra_vxlan_private.h" #include "zebra/zebra_vxlan.h" +#include "zebra/zebra_evpn_mh.h" +#include "zebra/zebra_ptm.h" +#include "zebra/router-id.h" +#include "zebra/zebra_routemap.h" +#include "zebra/zebra_rnh.h" +#include "zebra/table_manager.h" /* * XPath: /frr-zebra:zebra/mcast-rpf-lookup @@ -264,6 +270,43 @@ int zebra_dplane_queue_limit_modify(struct nb_cb_modify_args *args) return NB_OK; } +#if HAVE_BFDD == 0 +/* + * XPath: /frr-zebra:zebra/ptm-enable + */ +int zebra_ptm_enable_modify(struct nb_cb_modify_args *args) +{ + bool ptm; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + ptm = yang_dnode_get_bool(args->dnode, NULL); + + if (ptm) + zebra_global_ptm_enable(); + else + zebra_global_ptm_disable(); + + return NB_OK; +} +#endif + +/* + * XPath: /frr-zebra:zebra/route-map-delay + */ +int zebra_route_map_delay_modify(struct nb_cb_modify_args *args) +{ + uint32_t delay = yang_dnode_get_uint32(args->dnode, NULL); + + if (args->event != NB_EV_APPLY) + return NB_OK; + + zebra_route_map_set_delay_timer(delay); + + return NB_OK; +} + /* * XPath: /frr-zebra:zebra/debugs/debug-events */ @@ -823,28 +866,26 @@ int zebra_debugs_debug_mlag_destroy(struct nb_cb_destroy_args *args) } /* - * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ip-addrs + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv4-addrs */ -int lib_interface_zebra_ip_addrs_create(struct nb_cb_create_args *args) +int lib_interface_zebra_ipv4_addrs_create(struct nb_cb_create_args *args) { struct interface *ifp; - struct prefix prefix; + struct prefix p; + const char *label = NULL; - // addr_family = yang_dnode_get_enum(dnode, "address-family"); - yang_dnode_get_prefix(&prefix, args->dnode, "ip-prefix"); - apply_mask(&prefix); + p.family = AF_INET; + yang_dnode_get_ipv4(&p.u.prefix4, args->dnode, "ip"); + p.prefixlen = yang_dnode_get_uint8(args->dnode, "prefix-length"); + + if (yang_dnode_exists(args->dnode, "label")) + label = yang_dnode_get_string(args->dnode, "label"); switch (args->event) { case NB_EV_VALIDATE: - if (prefix.family == AF_INET - && ipv4_martian(&prefix.u.prefix4)) { - snprintfrr(args->errmsg, args->errmsg_len, - "invalid address %pFX", &prefix); - return NB_ERR_VALIDATION; - } else if (prefix.family == AF_INET6 - && ipv6_martian(&prefix.u.prefix6)) { + if (ipv4_martian(&p.u.prefix4)) { snprintfrr(args->errmsg, args->errmsg_len, - "invalid address %pFX", &prefix); + "invalid address %pFX", &p); return NB_ERR_VALIDATION; } break; @@ -853,65 +894,105 @@ int lib_interface_zebra_ip_addrs_create(struct nb_cb_create_args *args) break; case NB_EV_APPLY: ifp = nb_running_get_entry(args->dnode, NULL, true); - if (prefix.family == AF_INET) - if_ip_address_install(ifp, &prefix, NULL, NULL); - else if (prefix.family == AF_INET6) - if_ipv6_address_install(ifp, &prefix, NULL); + if_ip_address_install(ifp, &p, label, NULL); + /* set something for checking on label modify */ + nb_running_set_entry(args->dnode, (void *)0x1); break; } return NB_OK; } -int lib_interface_zebra_ip_addrs_destroy(struct nb_cb_destroy_args *args) +int lib_interface_zebra_ipv4_addrs_destroy(struct nb_cb_destroy_args *args) { struct interface *ifp; - struct prefix prefix; - struct connected *ifc; + struct prefix p; - yang_dnode_get_prefix(&prefix, args->dnode, "ip-prefix"); - apply_mask(&prefix); + p.family = AF_INET; + yang_dnode_get_ipv4(&p.u.prefix4, args->dnode, "ip"); + p.prefixlen = yang_dnode_get_uint8(args->dnode, "prefix-length"); switch (args->event) { case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + nb_running_unset_entry(args->dnode); + ifp = nb_running_get_entry(args->dnode, NULL, false); - if (!ifp) - return NB_OK; - - if (prefix.family == AF_INET) { - /* Check current interface address. */ - ifc = connected_check_ptp(ifp, &prefix, NULL); - if (!ifc) { - snprintf(args->errmsg, args->errmsg_len, - "interface %s Can't find address\n", - ifp->name); - return NB_ERR_VALIDATION; - } - } else if (prefix.family == AF_INET6) { - /* Check current interface address. */ - ifc = connected_check(ifp, &prefix); - if (!ifc) { - snprintf(args->errmsg, args->errmsg_len, - "interface can't find address %s", - ifp->name); - return NB_ERR_VALIDATION; - } - } else - return NB_ERR_VALIDATION; + if_ip_address_uninstall(ifp, &p, NULL); + break; + } + + return NB_OK; +} - /* This is not configured address. */ - if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED)) { +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv4-addrs/label + */ +int lib_interface_zebra_ipv4_addrs_label_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + if (nb_running_get_entry_non_rec(lyd_parent(args->dnode), NULL, + false)) { snprintf(args->errmsg, args->errmsg_len, - "interface %s not configured", ifp->name); + "Changing label is not allowed"); return NB_ERR_VALIDATION; } + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + break; + } - /* This is not real address or interface is not active. */ - if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED) - || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) { - if_connected_del(ifp->connected, ifc); - connected_free(&ifc); + return NB_OK; +} + +int lib_interface_zebra_ipv4_addrs_label_destroy(struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + snprintf(args->errmsg, args->errmsg_len, + "Removing label is not allowed"); + return NB_ERR_VALIDATION; + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + break; + } + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv4-p2p-addrs + */ +int lib_interface_zebra_ipv4_p2p_addrs_create(struct nb_cb_create_args *args) +{ + struct interface *ifp; + struct prefix p, pp; + const char *label = NULL; + + p.family = AF_INET; + yang_dnode_get_ipv4(&p.u.prefix4, args->dnode, "ip"); + p.prefixlen = 32; + + pp.family = AF_INET; + yang_dnode_get_ipv4(&pp.u.prefix4, args->dnode, "peer-ip"); + pp.prefixlen = yang_dnode_get_uint8(args->dnode, "peer-prefix-length"); + + if (yang_dnode_exists(args->dnode, "label")) + label = yang_dnode_get_string(args->dnode, "label"); + + switch (args->event) { + case NB_EV_VALIDATE: + if (ipv4_martian(&p.u.prefix4)) { + snprintfrr(args->errmsg, args->errmsg_len, + "invalid address %pFX", &p); return NB_ERR_VALIDATION; } break; @@ -920,7 +1001,39 @@ int lib_interface_zebra_ip_addrs_destroy(struct nb_cb_destroy_args *args) break; case NB_EV_APPLY: ifp = nb_running_get_entry(args->dnode, NULL, true); - if_ip_address_uinstall(ifp, &prefix); + if_ip_address_install(ifp, &p, label, &pp); + + /* set something for checking on label modify */ + nb_running_set_entry(args->dnode, (void *)0x1); + break; + } + + return NB_OK; +} + +int lib_interface_zebra_ipv4_p2p_addrs_destroy(struct nb_cb_destroy_args *args) +{ + struct interface *ifp; + struct prefix p, pp; + + p.family = AF_INET; + yang_dnode_get_ipv4(&p.u.prefix4, args->dnode, "ip"); + p.prefixlen = 32; + + pp.family = AF_INET; + yang_dnode_get_ipv4(&pp.u.prefix4, args->dnode, "peer-ip"); + pp.prefixlen = yang_dnode_get_uint8(args->dnode, "peer-prefix-length"); + + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + nb_running_unset_entry(args->dnode); + + ifp = nb_running_get_entry(args->dnode, NULL, false); + if_ip_address_uninstall(ifp, &p, &pp); break; } @@ -928,30 +1041,39 @@ int lib_interface_zebra_ip_addrs_destroy(struct nb_cb_destroy_args *args) } /* - * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ip-addrs/label + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv4-p2p-addrs/label */ -int lib_interface_zebra_ip_addrs_label_modify(struct nb_cb_modify_args *args) +int lib_interface_zebra_ipv4_p2p_addrs_label_modify(struct nb_cb_modify_args *args) { switch (args->event) { case NB_EV_VALIDATE: + if (nb_running_get_entry_non_rec(lyd_parent(args->dnode), NULL, + false)) { + snprintf(args->errmsg, args->errmsg_len, + "Changing label is not allowed"); + return NB_ERR_VALIDATION; + } + break; case NB_EV_PREPARE: case NB_EV_ABORT: case NB_EV_APPLY: - /* TODO: implement me. */ break; } return NB_OK; } -int lib_interface_zebra_ip_addrs_label_destroy(struct nb_cb_destroy_args *args) +int lib_interface_zebra_ipv4_p2p_addrs_label_destroy( + struct nb_cb_destroy_args *args) { switch (args->event) { case NB_EV_VALIDATE: + snprintf(args->errmsg, args->errmsg_len, + "Removing label is not allowed"); + return NB_ERR_VALIDATION; case NB_EV_PREPARE: case NB_EV_ABORT: case NB_EV_APPLY: - /* TODO: implement me. */ break; } @@ -959,31 +1081,54 @@ int lib_interface_zebra_ip_addrs_label_destroy(struct nb_cb_destroy_args *args) } /* - * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ip-addrs/ip4-peer + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-addrs */ -int lib_interface_zebra_ip_addrs_ip4_peer_modify(struct nb_cb_modify_args *args) +int lib_interface_zebra_ipv6_addrs_create(struct nb_cb_create_args *args) { + struct interface *ifp; + struct prefix p; + + p.family = AF_INET6; + yang_dnode_get_ipv6(&p.u.prefix6, args->dnode, "ip"); + p.prefixlen = yang_dnode_get_uint8(args->dnode, "prefix-length"); + switch (args->event) { case NB_EV_VALIDATE: + if (ipv6_martian(&p.u.prefix6)) { + snprintfrr(args->errmsg, args->errmsg_len, + "invalid address %pFX", &p); + return NB_ERR_VALIDATION; + } + break; case NB_EV_PREPARE: case NB_EV_ABORT: + break; case NB_EV_APPLY: - /* TODO: implement me. */ + ifp = nb_running_get_entry(args->dnode, NULL, true); + if_ipv6_address_install(ifp, &p); break; } return NB_OK; } -int lib_interface_zebra_ip_addrs_ip4_peer_destroy( - struct nb_cb_destroy_args *args) +int lib_interface_zebra_ipv6_addrs_destroy(struct nb_cb_destroy_args *args) { + struct interface *ifp; + struct prefix p; + + p.family = AF_INET6; + yang_dnode_get_ipv6(&p.u.prefix6, args->dnode, "ip"); + p.prefixlen = yang_dnode_get_uint8(args->dnode, "prefix-length"); + switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: + break; case NB_EV_APPLY: - /* TODO: implement me. */ + ifp = nb_running_get_entry(args->dnode, NULL, false); + if_ipv6_address_uninstall(ifp, &p); break; } @@ -999,10 +1144,14 @@ int lib_interface_zebra_multicast_modify(struct nb_cb_modify_args *args) return NB_OK; struct interface *ifp; + bool multicast = yang_dnode_get_bool(args->dnode, NULL); ifp = nb_running_get_entry(args->dnode, NULL, true); - if_multicast_set(ifp); + if (multicast) + if_multicast_set(ifp); + else + if_multicast_unset(ifp); return NB_OK; } @@ -1013,10 +1162,12 @@ int lib_interface_zebra_multicast_destroy(struct nb_cb_destroy_args *args) return NB_OK; struct interface *ifp; + struct zebra_if *zif; ifp = nb_running_get_entry(args->dnode, NULL, true); + zif = ifp->info; - if_multicast_unset(ifp); + zif->multicast = IF_ZEBRA_DATA_UNSPEC; return NB_OK; } @@ -1033,23 +1184,7 @@ int lib_interface_zebra_link_detect_modify(struct nb_cb_modify_args *args) bool link_detect; ifp = nb_running_get_entry(args->dnode, NULL, true); - link_detect = yang_dnode_get_bool(args->dnode, "link-detect"); - - if_linkdetect(ifp, link_detect); - - return NB_OK; -} - -int lib_interface_zebra_link_detect_destroy(struct nb_cb_destroy_args *args) -{ - if (args->event != NB_EV_APPLY) - return NB_OK; - - struct interface *ifp; - bool link_detect; - - ifp = nb_running_get_entry(args->dnode, NULL, true); - link_detect = yang_dnode_get_bool(args->dnode, "link-detect"); + link_detect = yang_dnode_get_bool(args->dnode, NULL); if_linkdetect(ifp, link_detect); @@ -1057,32 +1192,39 @@ int lib_interface_zebra_link_detect_destroy(struct nb_cb_destroy_args *args) } /* - * XPath: /frr-interface:lib/interface/frr-zebra:zebra/shutdown + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/enabled */ -int lib_interface_zebra_shutdown_modify(struct nb_cb_modify_args *args) +int lib_interface_zebra_enabled_modify(struct nb_cb_modify_args *args) { if (args->event != NB_EV_APPLY) return NB_OK; struct interface *ifp; + bool enabled; ifp = nb_running_get_entry(args->dnode, NULL, true); + enabled = yang_dnode_get_bool(args->dnode, NULL); - if_shutdown(ifp); + if (enabled) + if_no_shutdown(ifp); + else + if_shutdown(ifp); return NB_OK; } -int lib_interface_zebra_shutdown_destroy(struct nb_cb_destroy_args *args) +int lib_interface_zebra_enabled_destroy(struct nb_cb_destroy_args *args) { if (args->event != NB_EV_APPLY) return NB_OK; struct interface *ifp; + struct zebra_if *zif; ifp = nb_running_get_entry(args->dnode, NULL, true); + zif = ifp->info; - if_no_shutdown(ifp); + zif->shutdown = IF_ZEBRA_DATA_UNSPEC; return NB_OK; } @@ -1143,7 +1285,7 @@ int lib_interface_zebra_bandwidth_modify(struct nb_cb_modify_args *args) uint32_t bandwidth; ifp = nb_running_get_entry(args->dnode, NULL, true); - bandwidth = yang_dnode_get_uint32(args->dnode, "bandwidth"); + bandwidth = yang_dnode_get_uint32(args->dnode, NULL); ifp->bandwidth = bandwidth; @@ -1173,6 +1315,414 @@ int lib_interface_zebra_bandwidth_destroy(struct nb_cb_destroy_args *args) } /* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-params + */ +int lib_interface_zebra_link_params_create(struct nb_cb_create_args *args) +{ + struct interface *ifp; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + if_link_params_enable(ifp); + + /* + * The interface is updated in the apply_finish callback after all + * parameters are set in the corresponding callbacks. + */ + + return NB_OK; +} + +int lib_interface_zebra_link_params_destroy(struct nb_cb_destroy_args *args) +{ + struct interface *ifp; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + if_link_params_free(ifp); + if (if_is_operative(ifp)) + zebra_interface_parameters_update(ifp); + + return NB_OK; +} + +void lib_interface_zebra_link_params_apply_finish( + struct nb_cb_apply_finish_args *args) +{ + struct interface *ifp; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + if (if_is_operative(ifp)) + zebra_interface_parameters_update(ifp); +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-params/metric + */ +int lib_interface_zebra_link_params_metric_modify(struct nb_cb_modify_args *args) +{ + struct interface *ifp; + struct if_link_params *iflp; + uint32_t metric; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + iflp = if_link_params_get(ifp); + metric = yang_dnode_get_uint32(args->dnode, NULL); + + link_param_cmd_set_uint32(ifp, &iflp->te_metric, LP_TE_METRIC, metric); + + return NB_OK; +} + +int lib_interface_zebra_link_params_metric_destroy(struct nb_cb_destroy_args *args) +{ + struct interface *ifp; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + + link_param_cmd_unset(ifp, LP_TE_METRIC); + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-params/max-bandwidth + */ +int lib_interface_zebra_link_params_max_bandwidth_modify( + struct nb_cb_modify_args *args) +{ + struct interface *ifp; + struct if_link_params *iflp; + float max_bw, res_bw, ava_bw, use_bw; + + max_bw = yang_dnode_get_bandwidth_ieee_float32(args->dnode, NULL); + + switch (args->event) { + case NB_EV_VALIDATE: + if (yang_dnode_exists(args->dnode, "../residual-bandwidth")) { + res_bw = yang_dnode_get_bandwidth_ieee_float32( + args->dnode, "../residual-bandwidth"); + if (max_bw < res_bw) { + snprintfrr(args->errmsg, args->errmsg_len, + "max-bandwidth %f is less than residual-bandwidth %f", + max_bw, res_bw); + return NB_ERR_VALIDATION; + } + } + if (yang_dnode_exists(args->dnode, "../available-bandwidth")) { + ava_bw = yang_dnode_get_bandwidth_ieee_float32( + args->dnode, "../available-bandwidth"); + if (max_bw < ava_bw) { + snprintfrr(args->errmsg, args->errmsg_len, + "max-bandwidth %f is less than available-bandwidth %f", + max_bw, ava_bw); + return NB_ERR_VALIDATION; + } + } + if (yang_dnode_exists(args->dnode, "../utilized-bandwidth")) { + use_bw = yang_dnode_get_bandwidth_ieee_float32( + args->dnode, "../utilized-bandwidth"); + if (max_bw < use_bw) { + snprintfrr(args->errmsg, args->errmsg_len, + "max-bandwidth %f is less than utilized-bandwidth %f", + max_bw, use_bw); + return NB_ERR_VALIDATION; + } + } + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + ifp = nb_running_get_entry(args->dnode, NULL, true); + iflp = if_link_params_get(ifp); + link_param_cmd_set_float(ifp, &iflp->max_bw, LP_MAX_BW, max_bw); + break; + } + + return NB_OK; +} + +int lib_interface_zebra_link_params_max_bandwidth_destroy( + struct nb_cb_destroy_args *args) +{ + if (args->event == NB_EV_VALIDATE) { + snprintfrr(args->errmsg, args->errmsg_len, + "Removing max-bandwidth is not allowed"); + return NB_ERR_VALIDATION; + } + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-params/max-reservable-bandwidth + */ +int lib_interface_zebra_link_params_max_reservable_bandwidth_modify( + struct nb_cb_modify_args *args) +{ + struct interface *ifp; + struct if_link_params *iflp; + float max_rsv_bw; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + max_rsv_bw = yang_dnode_get_bandwidth_ieee_float32(args->dnode, NULL); + + ifp = nb_running_get_entry(args->dnode, NULL, true); + iflp = if_link_params_get(ifp); + link_param_cmd_set_float(ifp, &iflp->max_rsv_bw, LP_MAX_RSV_BW, + max_rsv_bw); + + return NB_OK; +} + +int lib_interface_zebra_link_params_max_reservable_bandwidth_destroy( + struct nb_cb_destroy_args *args) +{ + if (args->event == NB_EV_VALIDATE) { + snprintfrr(args->errmsg, args->errmsg_len, + "Removing max-reservable-bandwidth is not allowed"); + return NB_ERR_VALIDATION; + } + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-params/unreserved-bandwidths/unreserved-bandwidth + */ +int lib_interface_zebra_link_params_unreserved_bandwidths_unreserved_bandwidth_create( + struct nb_cb_create_args *args) +{ + struct interface *ifp; + struct if_link_params *iflp; + uint8_t priority; + float unrsv_bw; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + priority = yang_dnode_get_uint8(args->dnode, "priority"); + unrsv_bw = yang_dnode_get_bandwidth_ieee_float32(args->dnode, + "unreserved-bandwidth"); + + ifp = nb_running_get_entry(args->dnode, NULL, true); + iflp = if_link_params_get(ifp); + link_param_cmd_set_float(ifp, &iflp->unrsv_bw[priority], LP_UNRSV_BW, + unrsv_bw); + + return NB_OK; +} + +int lib_interface_zebra_link_params_unreserved_bandwidths_unreserved_bandwidth_destroy( + struct nb_cb_destroy_args *args) +{ + if (args->event == NB_EV_VALIDATE) { + snprintfrr(args->errmsg, args->errmsg_len, + "Removing unreserved-bandwidth is not allowed"); + return NB_ERR_VALIDATION; + } + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-params/unreserved-bandwidths/unreserved-bandwidth/unreserved-bandwidth + */ +int lib_interface_zebra_link_params_unreserved_bandwidths_unreserved_bandwidth_unreserved_bandwidth_modify( + struct nb_cb_modify_args *args) +{ + struct interface *ifp; + struct if_link_params *iflp; + uint8_t priority; + float unrsv_bw; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + priority = yang_dnode_get_uint8(args->dnode, "../priority"); + unrsv_bw = yang_dnode_get_bandwidth_ieee_float32(args->dnode, NULL); + + ifp = nb_running_get_entry(args->dnode, NULL, true); + iflp = if_link_params_get(ifp); + link_param_cmd_set_float(ifp, &iflp->unrsv_bw[priority], LP_UNRSV_BW, + unrsv_bw); + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-params/residual-bandwidth + */ +int lib_interface_zebra_link_params_residual_bandwidth_modify( + struct nb_cb_modify_args *args) +{ + struct interface *ifp; + struct if_link_params *iflp; + float max_bw, res_bw; + + res_bw = yang_dnode_get_bandwidth_ieee_float32(args->dnode, NULL); + + switch (args->event) { + case NB_EV_VALIDATE: + if (yang_dnode_exists(args->dnode, "../max-bandwidth")) { + max_bw = + yang_dnode_get_bandwidth_ieee_float32(args->dnode, + "../max-bandwidth"); + if (max_bw < res_bw) { + snprintfrr(args->errmsg, args->errmsg_len, + "max-bandwidth %f is less than residual-bandwidth %f", + max_bw, res_bw); + return NB_ERR_VALIDATION; + } + } + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + ifp = nb_running_get_entry(args->dnode, NULL, true); + iflp = if_link_params_get(ifp); + link_param_cmd_set_float(ifp, &iflp->res_bw, LP_RES_BW, res_bw); + break; + } + + return NB_OK; +} + +int lib_interface_zebra_link_params_residual_bandwidth_destroy( + struct nb_cb_destroy_args *args) +{ + struct interface *ifp; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + link_param_cmd_unset(ifp, LP_RES_BW); + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-params/available-bandwidth + */ +int lib_interface_zebra_link_params_available_bandwidth_modify( + struct nb_cb_modify_args *args) +{ + struct interface *ifp; + struct if_link_params *iflp; + float max_bw, ava_bw; + + ava_bw = yang_dnode_get_bandwidth_ieee_float32(args->dnode, NULL); + + switch (args->event) { + case NB_EV_VALIDATE: + if (yang_dnode_exists(args->dnode, "../max-bandwidth")) { + max_bw = + yang_dnode_get_bandwidth_ieee_float32(args->dnode, + "../max-bandwidth"); + if (max_bw < ava_bw) { + snprintfrr(args->errmsg, args->errmsg_len, + "max-bandwidth %f is less than available-bandwidth %f", + max_bw, ava_bw); + return NB_ERR_VALIDATION; + } + } + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + ifp = nb_running_get_entry(args->dnode, NULL, true); + iflp = if_link_params_get(ifp); + link_param_cmd_set_float(ifp, &iflp->ava_bw, LP_AVA_BW, ava_bw); + break; + } + + return NB_OK; +} + +int lib_interface_zebra_link_params_available_bandwidth_destroy( + struct nb_cb_destroy_args *args) +{ + struct interface *ifp; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + link_param_cmd_unset(ifp, LP_AVA_BW); + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-params/utilized-bandwidth + */ +int lib_interface_zebra_link_params_utilized_bandwidth_modify( + struct nb_cb_modify_args *args) +{ + struct interface *ifp; + struct if_link_params *iflp; + float max_bw, use_bw; + + use_bw = yang_dnode_get_bandwidth_ieee_float32(args->dnode, NULL); + + switch (args->event) { + case NB_EV_VALIDATE: + if (yang_dnode_exists(args->dnode, "../max-bandwidth")) { + max_bw = + yang_dnode_get_bandwidth_ieee_float32(args->dnode, + "../max-bandwidth"); + if (max_bw < use_bw) { + snprintfrr(args->errmsg, args->errmsg_len, + "max-bandwidth %f is less than utilized-bandwidth %f", + max_bw, use_bw); + return NB_ERR_VALIDATION; + } + } + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + ifp = nb_running_get_entry(args->dnode, NULL, true); + iflp = if_link_params_get(ifp); + link_param_cmd_set_float(ifp, &iflp->use_bw, LP_USE_BW, use_bw); + break; + } + + return NB_OK; +} + +int lib_interface_zebra_link_params_utilized_bandwidth_destroy( + struct nb_cb_destroy_args *args) +{ + struct interface *ifp; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + link_param_cmd_unset(ifp, LP_USE_BW); + + return NB_OK; +} + +/* * XPath: * /frr-interface:lib/interface/frr-zebra:zebra/link-params/legacy-admin-group */ @@ -1183,31 +1733,22 @@ int lib_interface_zebra_legacy_admin_group_modify( struct if_link_params *iflp; uint32_t admin_group_value; - ifp = nb_running_get_entry(args->dnode, NULL, true); admin_group_value = yang_dnode_get_uint32(args->dnode, "."); - if (!ifp) - return NB_ERR_RESOURCE; - - iflp = if_link_params_get(ifp); - switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: break; case NB_EV_APPLY: - if (!iflp) - iflp = if_link_params_enable(ifp); + ifp = nb_running_get_entry(args->dnode, NULL, true); + iflp = if_link_params_get(ifp); iflp->admin_grp = admin_group_value; SET_PARAM(iflp, LP_ADM_GRP); admin_group_clear(&iflp->ext_admin_grp); UNSET_PARAM(iflp, LP_EXTEND_ADM_GRP); - - if (if_is_operative(ifp)) - zebra_interface_parameters_update(ifp); break; } return NB_OK; @@ -1219,27 +1760,17 @@ int lib_interface_zebra_legacy_admin_group_destroy( struct interface *ifp; struct if_link_params *iflp; - ifp = nb_running_get_entry(args->dnode, NULL, true); - - if (!ifp) - return NB_ERR_RESOURCE; - - iflp = if_link_params_get(ifp); - switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: break; case NB_EV_APPLY: - if (!iflp) - iflp = if_link_params_enable(ifp); + ifp = nb_running_get_entry(args->dnode, NULL, true); + iflp = if_link_params_get(ifp); iflp->admin_grp = 0; UNSET_PARAM(iflp, LP_ADM_GRP); - - if (if_is_operative(ifp)) - zebra_interface_parameters_update(ifp); break; } return NB_OK; @@ -1257,25 +1788,18 @@ int lib_interface_zebra_affinity_create(struct nb_cb_create_args *args) struct affinity_map *affmap; enum affinity_mode affinity_mode; - - ifp = nb_running_get_entry(args->dnode, NULL, true); affname = yang_dnode_get_string(args->dnode, "."); affinity_mode = yang_dnode_get_enum(args->dnode, "../../affinity-mode"); - if (!ifp) - return NB_ERR_RESOURCE; - - affmap = affinity_map_get(affname); - iflp = if_link_params_get(ifp); - switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: break; case NB_EV_APPLY: - if (!iflp) - iflp = if_link_params_enable(ifp); + ifp = nb_running_get_entry(args->dnode, NULL, true); + iflp = if_link_params_get(ifp); + affmap = affinity_map_get(affname); if (affmap->bit_position < 32 && (affinity_mode == AFFINITY_MODE_STANDARD || @@ -1289,9 +1813,6 @@ int lib_interface_zebra_affinity_create(struct nb_cb_create_args *args) affmap->bit_position); SET_PARAM(iflp, LP_EXTEND_ADM_GRP); } - - if (if_is_operative(ifp)) - zebra_interface_parameters_update(ifp); break; } return NB_OK; @@ -1305,24 +1826,19 @@ int lib_interface_zebra_affinity_destroy(struct nb_cb_destroy_args *args) struct affinity_map *affmap; enum affinity_mode affinity_mode; - ifp = nb_running_get_entry(args->dnode, NULL, true); affname = yang_dnode_get_string(args->dnode, "."); affinity_mode = yang_dnode_get_enum(args->dnode, "../../affinity-mode"); - if (!ifp) - return NB_ERR_RESOURCE; - - affmap = affinity_map_get(affname); - iflp = if_link_params_get(ifp); - switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: break; case NB_EV_APPLY: - if (!iflp) - return NB_OK; + ifp = nb_running_get_entry(args->dnode, NULL, true); + iflp = if_link_params_get(ifp); + affmap = affinity_map_get(affname); + if (affmap->bit_position < 32 && (affinity_mode == AFFINITY_MODE_STANDARD || affinity_mode == AFFINITY_MODE_BOTH)) { @@ -1337,9 +1853,6 @@ int lib_interface_zebra_affinity_destroy(struct nb_cb_destroy_args *args) if (admin_group_zero(&iflp->ext_admin_grp)) UNSET_PARAM(iflp, LP_EXTEND_ADM_GRP); } - - if (if_is_operative(ifp)) - zebra_interface_parameters_update(ifp); break; } return NB_OK; @@ -1355,23 +1868,17 @@ int lib_interface_zebra_affinity_mode_modify(struct nb_cb_modify_args *args) struct if_link_params *iflp; enum affinity_mode affinity_mode; - - ifp = nb_running_get_entry(args->dnode, NULL, true); affinity_mode = yang_dnode_get_enum(args->dnode, "."); - if (!ifp) - return NB_ERR_RESOURCE; - - iflp = if_link_params_get(ifp); - switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: break; case NB_EV_APPLY: - if (!iflp) - iflp = if_link_params_enable(ifp); + ifp = nb_running_get_entry(args->dnode, NULL, true); + iflp = if_link_params_get(ifp); + if (affinity_mode == AFFINITY_MODE_STANDARD) { if (!IS_PARAM_SET(iflp, LP_ADM_GRP) && IS_PARAM_SET(iflp, LP_EXTEND_ADM_GRP)) { @@ -1405,84 +1912,1835 @@ int lib_interface_zebra_affinity_mode_modify(struct nb_cb_modify_args *args) SET_PARAM(iflp, LP_ADM_GRP); } } + break; + } + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-params/neighbor + */ +int lib_interface_zebra_link_params_neighbor_create(struct nb_cb_create_args *args) +{ + struct interface *ifp; + struct if_link_params *iflp; + struct in_addr ip; + uint32_t as; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + as = yang_dnode_get_uint32(args->dnode, "remote-as"); + yang_dnode_get_ipv4(&ip, args->dnode, "ipv4-remote-id"); + + ifp = nb_running_get_entry(args->dnode, NULL, true); + iflp = if_link_params_get(ifp); + + iflp->rmt_as = as; + iflp->rmt_ip = ip; + SET_PARAM(iflp, LP_RMT_AS); + + return NB_OK; +} + +int lib_interface_zebra_link_params_neighbor_destroy( + struct nb_cb_destroy_args *args) +{ + struct interface *ifp; + struct if_link_params *iflp; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + iflp = if_link_params_get(ifp); + + iflp->rmt_as = 0; + iflp->rmt_ip.s_addr = 0; + UNSET_PARAM(iflp, LP_RMT_AS); + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-params/neighbor/remote-as + */ +int lib_interface_zebra_link_params_neighbor_remote_as_modify( + struct nb_cb_modify_args *args) +{ + struct interface *ifp; + struct if_link_params *iflp; + uint32_t as; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + as = yang_dnode_get_uint32(args->dnode, NULL); + + ifp = nb_running_get_entry(args->dnode, NULL, true); + iflp = if_link_params_get(ifp); + + iflp->rmt_as = as; + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-params/neighbor/ipv4-remote-id + */ +int lib_interface_zebra_link_params_neighbor_ipv4_remote_id_modify( + struct nb_cb_modify_args *args) +{ + struct interface *ifp; + struct if_link_params *iflp; + struct in_addr ip; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + yang_dnode_get_ipv4(&ip, args->dnode, NULL); + + ifp = nb_running_get_entry(args->dnode, NULL, true); + iflp = if_link_params_get(ifp); + + iflp->rmt_ip = ip; + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-params/delay + */ +int lib_interface_zebra_link_params_delay_modify(struct nb_cb_modify_args *args) +{ + struct interface *ifp; + struct if_link_params *iflp; + uint32_t delay; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + delay = yang_dnode_get_uint32(args->dnode, NULL); + + ifp = nb_running_get_entry(args->dnode, NULL, true); + iflp = if_link_params_get(ifp); + + link_param_cmd_set_uint32(ifp, &iflp->av_delay, LP_DELAY, delay); + + return NB_OK; +} + +int lib_interface_zebra_link_params_delay_destroy(struct nb_cb_destroy_args *args) +{ + struct interface *ifp; + struct if_link_params *iflp; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + iflp = if_link_params_get(ifp); + + iflp->av_delay = 0; + link_param_cmd_unset(ifp, LP_DELAY); + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-params/min-max-delay + */ +int lib_interface_zebra_link_params_min_max_delay_create( + struct nb_cb_create_args *args) +{ + struct interface *ifp; + struct if_link_params *iflp; + uint32_t delay_min, delay_max; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + delay_min = yang_dnode_get_uint32(args->dnode, "delay-min"); + delay_max = yang_dnode_get_uint32(args->dnode, "delay-max"); + + ifp = nb_running_get_entry(args->dnode, NULL, true); + iflp = if_link_params_get(ifp); + + iflp->min_delay = delay_min; + iflp->max_delay = delay_max; + SET_PARAM(iflp, LP_MM_DELAY); + + return NB_OK; +} + +int lib_interface_zebra_link_params_min_max_delay_destroy( + struct nb_cb_destroy_args *args) +{ + struct interface *ifp; + struct if_link_params *iflp; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + iflp = if_link_params_get(ifp); + + iflp->min_delay = 0; + iflp->max_delay = 0; + UNSET_PARAM(iflp, LP_MM_DELAY); + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-params/min-max-delay/delay-min + */ +int lib_interface_zebra_link_params_min_max_delay_delay_min_modify( + struct nb_cb_modify_args *args) +{ + struct interface *ifp; + struct if_link_params *iflp; + uint32_t delay_min; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + delay_min = yang_dnode_get_uint32(args->dnode, NULL); + + ifp = nb_running_get_entry(args->dnode, NULL, true); + iflp = if_link_params_get(ifp); + + iflp->min_delay = delay_min; + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-params/min-max-delay/delay-max + */ +int lib_interface_zebra_link_params_min_max_delay_delay_max_modify( + struct nb_cb_modify_args *args) +{ + struct interface *ifp; + struct if_link_params *iflp; + uint32_t delay_max; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + delay_max = yang_dnode_get_uint32(args->dnode, NULL); + + ifp = nb_running_get_entry(args->dnode, NULL, true); + iflp = if_link_params_get(ifp); + + iflp->max_delay = delay_max; + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-params/delay-variation + */ +int lib_interface_zebra_link_params_delay_variation_modify( + struct nb_cb_modify_args *args) +{ + struct interface *ifp; + struct if_link_params *iflp; + uint32_t delay_var; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + delay_var = yang_dnode_get_uint32(args->dnode, NULL); + + ifp = nb_running_get_entry(args->dnode, NULL, true); + iflp = if_link_params_get(ifp); - if (if_is_operative(ifp)) - zebra_interface_parameters_update(ifp); + link_param_cmd_set_uint32(ifp, &iflp->delay_var, LP_DELAY_VAR, + delay_var); + + return NB_OK; +} + +int lib_interface_zebra_link_params_delay_variation_destroy( + struct nb_cb_destroy_args *args) +{ + struct interface *ifp; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + + link_param_cmd_unset(ifp, LP_DELAY_VAR); + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-params/packet-loss + */ +int lib_interface_zebra_link_params_packet_loss_modify( + struct nb_cb_modify_args *args) +{ + struct interface *ifp; + struct if_link_params *iflp; + double packet_loss; + uint32_t value; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + packet_loss = yang_dnode_get_dec64(args->dnode, NULL); + value = (uint32_t)(packet_loss / LOSS_PRECISION); + + ifp = nb_running_get_entry(args->dnode, NULL, true); + iflp = if_link_params_get(ifp); + + link_param_cmd_set_uint32(ifp, &iflp->pkt_loss, LP_PKT_LOSS, value); + + return NB_OK; +} + +int lib_interface_zebra_link_params_packet_loss_destroy( + struct nb_cb_destroy_args *args) +{ + struct interface *ifp; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + + link_param_cmd_unset(ifp, LP_PKT_LOSS); + + return NB_OK; +} + +static bool evpn_mh_dnode_to_esi(const struct lyd_node *dnode, esi_t *esi) +{ + if (yang_dnode_exists(dnode, "type-0/esi")) { + str_to_esi(yang_dnode_get_string(dnode, "type-0/esi"), esi); + } else if (yang_dnode_exists(dnode, "type-3/system-mac") && + yang_dnode_exists(dnode, "type-3/local-discriminator")) { + struct ethaddr mac; + uint32_t lid; + + yang_dnode_get_mac(&mac, dnode, "type-3/system-mac"); + lid = yang_dnode_get_uint32(dnode, "type-3/local-discriminator"); + + zebra_build_type3_esi(lid, &mac, esi); + } else { + return false; + } + + return true; +} + +struct esi_cmp_iter_arg { + struct lyd_node *dnode; + esi_t esi; + bool exists; +}; + +static int esi_cmp_iter_cb(const struct lyd_node *dnode, void *arg) +{ + struct esi_cmp_iter_arg *iter = arg; + esi_t esi; + + if (dnode == iter->dnode) + return YANG_ITER_CONTINUE; + + if (!evpn_mh_dnode_to_esi(dnode, &esi)) + return YANG_ITER_CONTINUE; + + if (!memcmp(&esi, &iter->esi, ESI_BYTES)) { + iter->exists = true; + return YANG_ITER_STOP; + } + + return YANG_ITER_CONTINUE; +} + +/* evpn-mh should be passed to this function */ +static bool esi_unique(struct lyd_node *dnode) +{ + struct esi_cmp_iter_arg iter; + + iter.dnode = dnode; + evpn_mh_dnode_to_esi(dnode, &iter.esi); + iter.exists = false; + + yang_dnode_iterate(esi_cmp_iter_cb, &iter, dnode, + "/frr-interface:lib/interface/frr-zebra:zebra/evpn-mh"); + + if (iter.exists) + return false; + + return true; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/evpn-mh/type-0/esi + */ +int lib_interface_zebra_evpn_mh_type_0_esi_modify(struct nb_cb_modify_args *args) +{ + struct interface *ifp; + esi_t esi; + + switch (args->event) { + case NB_EV_VALIDATE: + if (!esi_unique(lyd_parent(lyd_parent(args->dnode)))) { + snprintfrr(args->errmsg, args->errmsg_len, + "ESI already exists on a different interface"); + return NB_ERR_VALIDATION; + } + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + ifp = nb_running_get_entry(args->dnode, NULL, true); + str_to_esi(yang_dnode_get_string(args->dnode, NULL), &esi); + zebra_evpn_es_type0_esi_update(ifp->info, &esi); break; } + + return NB_OK; +} + +int lib_interface_zebra_evpn_mh_type_0_esi_destroy(struct nb_cb_destroy_args *args) +{ + struct interface *ifp; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + zebra_evpn_es_type0_esi_update(ifp->info, NULL); + return NB_OK; } /* - * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/l3vni-id + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/evpn-mh/type-3/system-mac */ -int lib_vrf_zebra_l3vni_id_modify(struct nb_cb_modify_args *args) +int lib_interface_zebra_evpn_mh_type_3_system_mac_modify( + struct nb_cb_modify_args *args) { - struct vrf *vrf; - struct zebra_vrf *zvrf; - vni_t vni = 0; - struct zebra_l3vni *zl3vni = NULL; - char err[ERR_STR_SZ]; - bool pfx_only = false; - const struct lyd_node *pn_dnode; - const char *vrfname; + struct interface *ifp; + struct ethaddr mac; + + yang_dnode_get_mac(&mac, args->dnode, NULL); switch (args->event) { + case NB_EV_VALIDATE: + if (is_zero_mac(&mac)) { + snprintfrr(args->errmsg, args->errmsg_len, + "MAC cannot be all-zeroes"); + return NB_ERR_VALIDATION; + } + if (!esi_unique(lyd_parent(lyd_parent(args->dnode)))) { + snprintfrr(args->errmsg, args->errmsg_len, + "ESI already exists on a different interface"); + return NB_ERR_VALIDATION; + } + break; case NB_EV_PREPARE: case NB_EV_ABORT: + break; + case NB_EV_APPLY: + ifp = nb_running_get_entry(args->dnode, NULL, true); + zebra_evpn_es_sys_mac_update(ifp->info, &mac); + break; + } + + return NB_OK; +} + +int lib_interface_zebra_evpn_mh_type_3_system_mac_destroy( + struct nb_cb_destroy_args *args) +{ + struct interface *ifp; + + if (args->event != NB_EV_APPLY) return NB_OK; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + zebra_evpn_es_sys_mac_update(ifp->info, NULL); + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/evpn-mh/type-3/local-discriminator + */ +int lib_interface_zebra_evpn_mh_type_3_local_discriminator_modify( + struct nb_cb_modify_args *args) +{ + struct interface *ifp; + uint32_t lid; + + switch (args->event) { case NB_EV_VALIDATE: - vni = yang_dnode_get_uint32(args->dnode, NULL); - /* Get vrf info from parent node, reject configuration - * if zebra vrf already mapped to different vni id. - */ - pn_dnode = yang_dnode_get_parent(args->dnode, "vrf"); - vrfname = yang_dnode_get_string(pn_dnode, "name"); - zvrf = zebra_vrf_lookup_by_name(vrfname); - if (!zvrf) { - snprintf(args->errmsg, args->errmsg_len, - "zebra vrf info not found for vrf:%s.", - vrfname); + if (!esi_unique(lyd_parent(lyd_parent(args->dnode)))) { + snprintfrr(args->errmsg, args->errmsg_len, + "ESI already exists on a different interface"); + return NB_ERR_VALIDATION; + } + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + ifp = nb_running_get_entry(args->dnode, NULL, true); + lid = yang_dnode_get_uint32(args->dnode, NULL); + zebra_evpn_es_lid_update(ifp->info, lid); + break; + } + + return NB_OK; +} + +int lib_interface_zebra_evpn_mh_type_3_local_discriminator_destroy( + struct nb_cb_destroy_args *args) +{ + struct interface *ifp; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + zebra_evpn_es_lid_update(ifp->info, 0); + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/evpn-mh/df-preference + */ +int lib_interface_zebra_evpn_mh_df_preference_modify( + struct nb_cb_modify_args *args) +{ + struct interface *ifp; + uint16_t df_pref; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + df_pref = yang_dnode_get_uint16(args->dnode, NULL); + zebra_evpn_es_df_pref_update(ifp->info, df_pref); + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/evpn-mh/bypass + */ +int lib_interface_zebra_evpn_mh_bypass_modify(struct nb_cb_modify_args *args) +{ + struct interface *ifp; + bool bypass; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + bypass = yang_dnode_get_bool(args->dnode, NULL); + zebra_evpn_es_bypass_cfg_update(ifp->info, bypass); + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/evpn-mh/uplink + */ +int lib_interface_zebra_evpn_mh_uplink_modify(struct nb_cb_modify_args *args) +{ + struct interface *ifp; + bool uplink; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + uplink = yang_dnode_get_bool(args->dnode, NULL); + zebra_evpn_mh_uplink_cfg_update(ifp->info, uplink); + + return NB_OK; +} + +#if defined(HAVE_RTADV) +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/send-advertisements + */ +int lib_interface_zebra_ipv6_router_advertisements_send_advertisements_modify( + struct nb_cb_modify_args *args) +{ + struct interface *ifp; + struct zebra_if *zif; + bool send_adv; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + zif = ifp->info; + + send_adv = yang_dnode_get_bool(args->dnode, NULL); + + if (send_adv) { + ipv6_nd_suppress_ra_set(ifp, RA_ENABLE); + SET_FLAG(zif->rtadv.ra_configured, VTY_RA_CONFIGURED); + } else { + if (!CHECK_FLAG(zif->rtadv.ra_configured, BGP_RA_CONFIGURED)) + ipv6_nd_suppress_ra_set(ifp, RA_SUPPRESS); + UNSET_FLAG(zif->rtadv.ra_configured, VTY_RA_CONFIGURED); + } + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/max-rtr-adv-interval + */ +int lib_interface_zebra_ipv6_router_advertisements_max_rtr_adv_interval_modify( + struct nb_cb_modify_args *args) +{ + struct interface *ifp; + uint32_t interval; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + interval = yang_dnode_get_uint32(args->dnode, NULL); + + ipv6_nd_interval_set(ifp, interval); + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/managed-flag + */ +int lib_interface_zebra_ipv6_router_advertisements_managed_flag_modify( + struct nb_cb_modify_args *args) +{ + struct interface *ifp; + struct zebra_if *zif; + bool managed_flag; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + zif = ifp->info; + + managed_flag = yang_dnode_get_bool(args->dnode, NULL); + + zif->rtadv.AdvManagedFlag = managed_flag; + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/other-config-flag + */ +int lib_interface_zebra_ipv6_router_advertisements_other_config_flag_modify( + struct nb_cb_modify_args *args) +{ + struct interface *ifp; + struct zebra_if *zif; + bool other_config_flag; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + zif = ifp->info; + + other_config_flag = yang_dnode_get_bool(args->dnode, NULL); + + zif->rtadv.AdvOtherConfigFlag = other_config_flag; + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/home-agent-flag + */ +int lib_interface_zebra_ipv6_router_advertisements_home_agent_flag_modify( + struct nb_cb_modify_args *args) +{ + struct interface *ifp; + struct zebra_if *zif; + bool home_agent_flag; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + zif = ifp->info; + + home_agent_flag = yang_dnode_get_bool(args->dnode, NULL); + + zif->rtadv.AdvHomeAgentFlag = home_agent_flag; + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/link-mtu + */ +int lib_interface_zebra_ipv6_router_advertisements_link_mtu_modify( + struct nb_cb_modify_args *args) +{ + struct interface *ifp; + struct zebra_if *zif; + uint32_t mtu; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + zif = ifp->info; + + mtu = yang_dnode_get_uint32(args->dnode, NULL); + + zif->rtadv.AdvLinkMTU = mtu; + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/reachable-time + */ +int lib_interface_zebra_ipv6_router_advertisements_reachable_time_modify( + struct nb_cb_modify_args *args) +{ + struct interface *ifp; + struct zebra_if *zif; + uint32_t time; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + zif = ifp->info; + time = yang_dnode_get_uint32(args->dnode, NULL); + + zif->rtadv.AdvReachableTime = time; + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/retrans-timer + */ +int lib_interface_zebra_ipv6_router_advertisements_retrans_timer_modify( + struct nb_cb_modify_args *args) +{ + struct interface *ifp; + struct zebra_if *zif; + uint32_t timer; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + zif = ifp->info; + timer = yang_dnode_get_uint32(args->dnode, NULL); + + zif->rtadv.AdvRetransTimer = timer; + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/cur-hop-limit + */ +int lib_interface_zebra_ipv6_router_advertisements_cur_hop_limit_modify( + struct nb_cb_modify_args *args) +{ + struct interface *ifp; + struct zebra_if *zif; + uint8_t limit; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + zif = ifp->info; + limit = yang_dnode_get_uint8(args->dnode, NULL); + + zif->rtadv.AdvCurHopLimit = limit; + + return NB_OK; +} + +int lib_interface_zebra_ipv6_router_advertisements_cur_hop_limit_destroy( + struct nb_cb_destroy_args *args) +{ + struct interface *ifp; + struct zebra_if *zif; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + zif = ifp->info; + + zif->rtadv.AdvCurHopLimit = RTADV_DEFAULT_HOPLIMIT; + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/default-lifetime + */ +int lib_interface_zebra_ipv6_router_advertisements_default_lifetime_modify( + struct nb_cb_modify_args *args) +{ + struct interface *ifp; + struct zebra_if *zif; + uint16_t lifetime; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + zif = ifp->info; + + lifetime = yang_dnode_get_uint16(args->dnode, NULL); + + zif->rtadv.AdvDefaultLifetime = lifetime; + + return NB_OK; +} + +int lib_interface_zebra_ipv6_router_advertisements_default_lifetime_destroy( + struct nb_cb_destroy_args *args) +{ + struct interface *ifp; + struct zebra_if *zif; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + zif = ifp->info; + + zif->rtadv.AdvDefaultLifetime = -1; + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/fast-retransmit + */ +int lib_interface_zebra_ipv6_router_advertisements_fast_retransmit_modify( + struct nb_cb_modify_args *args) +{ + struct interface *ifp; + struct zebra_if *zif; + bool fast_retransmit; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + zif = ifp->info; + + fast_retransmit = yang_dnode_get_bool(args->dnode, NULL); + + zif->rtadv.UseFastRexmit = fast_retransmit; + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/advertisement-interval-option + */ +int lib_interface_zebra_ipv6_router_advertisements_advertisement_interval_option_modify( + struct nb_cb_modify_args *args) +{ + struct interface *ifp; + struct zebra_if *zif; + bool option; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + zif = ifp->info; + + option = yang_dnode_get_bool(args->dnode, NULL); + + zif->rtadv.AdvIntervalOption = option; + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/home-agent-preference + */ +int lib_interface_zebra_ipv6_router_advertisements_home_agent_preference_modify( + struct nb_cb_modify_args *args) +{ + struct interface *ifp; + struct zebra_if *zif; + uint16_t preference; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + zif = ifp->info; + + preference = yang_dnode_get_uint16(args->dnode, NULL); + + zif->rtadv.HomeAgentPreference = preference; + + return NB_OK; +} + +int lib_interface_zebra_ipv6_router_advertisements_home_agent_preference_destroy( + struct nb_cb_destroy_args *args) +{ + struct interface *ifp; + struct zebra_if *zif; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + zif = ifp->info; + + zif->rtadv.HomeAgentPreference = 0; + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/home-agent-lifetime + */ +int lib_interface_zebra_ipv6_router_advertisements_home_agent_lifetime_modify( + struct nb_cb_modify_args *args) +{ + struct interface *ifp; + struct zebra_if *zif; + uint16_t lifetime; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + zif = ifp->info; + + lifetime = yang_dnode_get_uint16(args->dnode, NULL); + + zif->rtadv.HomeAgentLifetime = lifetime; + + return NB_OK; +} + +int lib_interface_zebra_ipv6_router_advertisements_home_agent_lifetime_destroy( + struct nb_cb_destroy_args *args) +{ + struct interface *ifp; + struct zebra_if *zif; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + zif = ifp->info; + + zif->rtadv.HomeAgentLifetime = -1; + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/default-router-preference + */ +int lib_interface_zebra_ipv6_router_advertisements_default_router_preference_modify( + struct nb_cb_modify_args *args) +{ + struct interface *ifp; + struct zebra_if *zif; + int preference; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + zif = ifp->info; + + preference = yang_dnode_get_enum(args->dnode, NULL); + + zif->rtadv.DefaultPreference = preference; + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/prefix-list/prefix + */ +int lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_create( + struct nb_cb_create_args *args) +{ + struct interface *ifp; + struct rtadv_prefix rp, *prefix; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + + yang_dnode_get_ipv6p(&rp.prefix, args->dnode, "prefix-spec"); + rp.AdvOnLinkFlag = yang_dnode_get_bool(args->dnode, "on-link-flag"); + rp.AdvAutonomousFlag = yang_dnode_get_bool(args->dnode, + "autonomous-flag"); + rp.AdvRouterAddressFlag = yang_dnode_get_bool(args->dnode, + "router-address-flag"); + rp.AdvValidLifetime = yang_dnode_get_uint32(args->dnode, + "valid-lifetime"); + rp.AdvPreferredLifetime = yang_dnode_get_uint32(args->dnode, + "preferred-lifetime"); + + prefix = rtadv_add_prefix_manual(ifp->info, &rp); + nb_running_set_entry(args->dnode, prefix); + + return NB_OK; +} + +int lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_destroy( + struct nb_cb_destroy_args *args) +{ + struct interface *ifp; + struct rtadv_prefix *prefix; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + prefix = nb_running_unset_entry(args->dnode); + ifp = nb_running_get_entry(args->dnode, NULL, true); + + rtadv_delete_prefix_manual(ifp->info, prefix); + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/prefix-list/prefix/valid-lifetime + */ +int lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_valid_lifetime_modify( + struct nb_cb_modify_args *args) +{ + struct rtadv_prefix *prefix; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + prefix = nb_running_get_entry(args->dnode, NULL, true); + + prefix->AdvValidLifetime = yang_dnode_get_uint32(args->dnode, NULL); + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/prefix-list/prefix/on-link-flag + */ +int lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_on_link_flag_modify( + struct nb_cb_modify_args *args) +{ + struct rtadv_prefix *prefix; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + prefix = nb_running_get_entry(args->dnode, NULL, true); + + prefix->AdvOnLinkFlag = yang_dnode_get_bool(args->dnode, NULL); + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/prefix-list/prefix/preferred-lifetime + */ +int lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_preferred_lifetime_modify( + struct nb_cb_modify_args *args) +{ + struct rtadv_prefix *prefix; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + prefix = nb_running_get_entry(args->dnode, NULL, true); + + prefix->AdvPreferredLifetime = yang_dnode_get_uint32(args->dnode, NULL); + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/prefix-list/prefix/autonomous-flag + */ +int lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_autonomous_flag_modify( + struct nb_cb_modify_args *args) +{ + struct rtadv_prefix *prefix; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + prefix = nb_running_get_entry(args->dnode, NULL, true); + + prefix->AdvAutonomousFlag = yang_dnode_get_bool(args->dnode, NULL); + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/prefix-list/prefix/router-address-flag + */ +int lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_router_address_flag_modify( + struct nb_cb_modify_args *args) +{ + struct rtadv_prefix *prefix; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + prefix = nb_running_get_entry(args->dnode, NULL, true); + + prefix->AdvRouterAddressFlag = yang_dnode_get_bool(args->dnode, NULL); + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/rdnss/rdnss-address + */ +int lib_interface_zebra_ipv6_router_advertisements_rdnss_rdnss_address_create( + struct nb_cb_create_args *args) +{ + struct interface *ifp; + struct rtadv_rdnss rdnss, *p; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + + yang_dnode_get_ipv6(&rdnss.addr, args->dnode, "address"); + if (yang_dnode_exists(args->dnode, "lifetime")) { + rdnss.lifetime = yang_dnode_get_uint32(args->dnode, "lifetime"); + rdnss.lifetime_set = 1; + } else { + rdnss.lifetime_set = 0; + } + + p = rtadv_rdnss_set(ifp->info, &rdnss); + nb_running_set_entry(args->dnode, p); + + return NB_OK; +} + +int lib_interface_zebra_ipv6_router_advertisements_rdnss_rdnss_address_destroy( + struct nb_cb_destroy_args *args) +{ + struct interface *ifp; + struct rtadv_rdnss *p; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + p = nb_running_unset_entry(args->dnode); + ifp = nb_running_get_entry(args->dnode, NULL, true); + + rtadv_rdnss_reset(ifp->info, p); + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/rdnss/rdnss-address/lifetime + */ +int lib_interface_zebra_ipv6_router_advertisements_rdnss_rdnss_address_lifetime_modify( + struct nb_cb_modify_args *args) +{ + struct rtadv_rdnss *p; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + p = nb_running_get_entry(args->dnode, NULL, true); + + p->lifetime = yang_dnode_get_uint32(args->dnode, NULL); + p->lifetime_set = 1; + + return NB_OK; +} + +int lib_interface_zebra_ipv6_router_advertisements_rdnss_rdnss_address_lifetime_destroy( + struct nb_cb_destroy_args *args) +{ + struct rtadv_rdnss *p; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + p = nb_running_get_entry(args->dnode, NULL, true); + + p->lifetime_set = 0; + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/dnssl/dnssl-domain + */ +int lib_interface_zebra_ipv6_router_advertisements_dnssl_dnssl_domain_create( + struct nb_cb_create_args *args) +{ + struct interface *ifp; + struct rtadv_dnssl dnssl, *p; + int ret; + + strlcpy(dnssl.name, yang_dnode_get_string(args->dnode, "domain"), + sizeof(dnssl.name)); + ret = rtadv_dnssl_encode(dnssl.encoded_name, dnssl.name); + + if (args->event == NB_EV_VALIDATE) { + if (ret < 0) { + snprintfrr(args->errmsg, args->errmsg_len, + "Malformed DNS search domain"); return NB_ERR_VALIDATION; } - if (zvrf->l3vni && zvrf->l3vni != vni) { - snprintf( - args->errmsg, args->errmsg_len, - "vni %u cannot be configured as vni %u is already configured under the vrf", - vni, zvrf->l3vni); + } + + if (args->event != NB_EV_APPLY) + return NB_OK; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + + if (yang_dnode_exists(args->dnode, "lifetime")) { + dnssl.lifetime = yang_dnode_get_uint32(args->dnode, "lifetime"); + dnssl.lifetime_set = 1; + } else { + dnssl.lifetime_set = 0; + } + + p = rtadv_dnssl_set(ifp->info, &dnssl); + nb_running_set_entry(args->dnode, p); + + return NB_OK; +} + +int lib_interface_zebra_ipv6_router_advertisements_dnssl_dnssl_domain_destroy( + struct nb_cb_destroy_args *args) +{ + struct interface *ifp; + struct rtadv_dnssl *p; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + p = nb_running_unset_entry(args->dnode); + ifp = nb_running_get_entry(args->dnode, NULL, true); + + rtadv_dnssl_reset(ifp->info, p); + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/dnssl/dnssl-domain/lifetime + */ +int lib_interface_zebra_ipv6_router_advertisements_dnssl_dnssl_domain_lifetime_modify( + struct nb_cb_modify_args *args) +{ + struct rtadv_dnssl *p; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + p = nb_running_get_entry(args->dnode, NULL, true); + + p->lifetime = yang_dnode_get_uint32(args->dnode, NULL); + p->lifetime_set = 1; + + return NB_OK; +} + +int lib_interface_zebra_ipv6_router_advertisements_dnssl_dnssl_domain_lifetime_destroy( + struct nb_cb_destroy_args *args) +{ + struct rtadv_dnssl *p; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + p = nb_running_get_entry(args->dnode, NULL, true); + + p->lifetime_set = 0; + + return NB_OK; +} +#endif /* defined(HAVE_RTADV) */ + +#if HAVE_BFDD == 0 +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ptm-enable + */ +int lib_interface_zebra_ptm_enable_modify(struct nb_cb_modify_args *args) +{ + struct interface *ifp; + bool ptm; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + + ptm = yang_dnode_get_bool(args->dnode, NULL); + if (ptm) + zebra_if_ptm_enable(ifp); + else + zebra_if_ptm_disable(ifp); + + return NB_OK; +} +#endif + +/* + * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/router-id + */ +int lib_vrf_zebra_router_id_modify(struct nb_cb_modify_args *args) +{ + struct vrf *vrf; + struct prefix p; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + vrf = nb_running_get_entry(args->dnode, NULL, true); + + yang_dnode_get_ipv4p(&p, args->dnode, NULL); + + router_id_set(AFI_IP, &p, vrf->info); + + return NB_OK; +} + +int lib_vrf_zebra_router_id_destroy(struct nb_cb_destroy_args *args) +{ + struct vrf *vrf; + struct prefix p; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + vrf = nb_running_get_entry(args->dnode, NULL, true); + + memset(&p, 0, sizeof(p)); + p.family = AF_INET; + + router_id_set(AFI_IP, &p, vrf->info); + + return NB_OK; +} + +/* + * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ipv6-router-id + */ +int lib_vrf_zebra_ipv6_router_id_modify(struct nb_cb_modify_args *args) +{ + struct vrf *vrf; + struct prefix p; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + vrf = nb_running_get_entry(args->dnode, NULL, true); + + yang_dnode_get_ipv6p(&p, args->dnode, NULL); + + router_id_set(AFI_IP6, &p, vrf->info); + + return NB_OK; +} + +int lib_vrf_zebra_ipv6_router_id_destroy(struct nb_cb_destroy_args *args) +{ + struct vrf *vrf; + struct prefix p; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + vrf = nb_running_get_entry(args->dnode, NULL, true); + + memset(&p, 0, sizeof(p)); + p.family = AF_INET6; + + router_id_set(AFI_IP6, &p, vrf->info); + + return NB_OK; +} + +/* + * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/filter-protocol + */ +int lib_vrf_zebra_filter_protocol_create(struct nb_cb_create_args *args) +{ + const char *proto = yang_dnode_get_string(args->dnode, "protocol"); + int rtype; + + if (strcasecmp(proto, "any") == 0) + rtype = ZEBRA_ROUTE_MAX; + else + rtype = proto_name2num(proto); + + if (args->event == NB_EV_VALIDATE) + if (rtype < 0) { + snprintfrr(args->errmsg, args->errmsg_len, + "invalid protocol name \"%s\"", proto); return NB_ERR_VALIDATION; } - /* Check if this VNI is already present in the system */ - zl3vni = zl3vni_lookup(vni); - if (zl3vni) { - snprintf(args->errmsg, args->errmsg_len, - "VNI %u is already configured as L3-VNI", vni); + /* the creation finishes in the apply_finish callback */ + + return NB_OK; +} + +int lib_vrf_zebra_filter_protocol_destroy(struct nb_cb_destroy_args *args) +{ + struct vrf *vrf; + const char *afi_safi = yang_dnode_get_string(args->dnode, "afi-safi"); + const char *proto = yang_dnode_get_string(args->dnode, "protocol"); + const char *rmap = yang_dnode_get_string(args->dnode, "route-map"); + afi_t afi; + safi_t safi; + int rtype; + + yang_afi_safi_identity2value(afi_safi, &afi, &safi); + + if (strcasecmp(proto, "any") == 0) + rtype = ZEBRA_ROUTE_MAX; + else + rtype = proto_name2num(proto); + + /* deleting an existing entry, it can't be invalid */ + assert(rtype >= 0); + + if (args->event != NB_EV_APPLY) + return NB_OK; + + vrf = nb_running_get_entry(args->dnode, NULL, true); + + ip_protocol_rm_del(vrf->info, rmap, rtype, afi, safi); + + return NB_OK; +} + +void lib_vrf_zebra_filter_protocol_apply_finish( + struct nb_cb_apply_finish_args *args) +{ + struct vrf *vrf; + const char *afi_safi = yang_dnode_get_string(args->dnode, "afi-safi"); + const char *proto = yang_dnode_get_string(args->dnode, "protocol"); + const char *rmap = yang_dnode_get_string(args->dnode, "route-map"); + afi_t afi; + safi_t safi; + int rtype; + + yang_afi_safi_identity2value(afi_safi, &afi, &safi); + + if (strcasecmp(proto, "any") == 0) + rtype = ZEBRA_ROUTE_MAX; + else + rtype = proto_name2num(proto); + + /* finishing apply for a validated entry, it can't be invalid */ + assert(rtype >= 0); + + vrf = nb_running_get_entry(args->dnode, NULL, true); + + ip_protocol_rm_add(vrf->info, rmap, rtype, afi, safi); +} + +/* + * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/filter-protocol/route-map + */ +int lib_vrf_zebra_filter_protocol_route_map_modify(struct nb_cb_modify_args *args) +{ + /* the update is done in the apply_finish callback */ + return NB_OK; +} + +/* + * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/filter-nht + */ +int lib_vrf_zebra_filter_nht_create(struct nb_cb_create_args *args) +{ + const char *afi_safi = yang_dnode_get_string(args->dnode, "afi-safi"); + const char *proto = yang_dnode_get_string(args->dnode, "protocol"); + afi_t afi; + safi_t safi; + int rtype; + + yang_afi_safi_identity2value(afi_safi, &afi, &safi); + + if (strcasecmp(proto, "any") == 0) + rtype = ZEBRA_ROUTE_MAX; + else + rtype = proto_name2num(proto); + + if (args->event == NB_EV_VALIDATE) { + if (rtype < 0) { + snprintfrr(args->errmsg, args->errmsg_len, + "invalid protocol name \"%s\"", proto); + return NB_ERR_VALIDATION; + } + if (safi != SAFI_UNICAST) { + snprintfrr(args->errmsg, args->errmsg_len, + "only SAFI unicast is supported"); + return NB_ERR_VALIDATION; + } + } + + /* the creation finishes in the apply_finish callback */ + + return NB_OK; +} + +int lib_vrf_zebra_filter_nht_destroy(struct nb_cb_destroy_args *args) +{ + struct vrf *vrf; + const char *afi_safi = yang_dnode_get_string(args->dnode, "afi-safi"); + const char *proto = yang_dnode_get_string(args->dnode, "protocol"); + const char *rmap = yang_dnode_get_string(args->dnode, "route-map"); + afi_t afi; + safi_t safi; + int rtype; + + yang_afi_safi_identity2value(afi_safi, &afi, &safi); + + if (strcasecmp(proto, "any") == 0) + rtype = ZEBRA_ROUTE_MAX; + else + rtype = proto_name2num(proto); + + /* deleting an existing entry, it can't be invalid */ + assert(rtype >= 0); + assert(safi == SAFI_UNICAST); + + if (args->event != NB_EV_APPLY) + return NB_OK; + + vrf = nb_running_get_entry(args->dnode, NULL, true); + + ip_nht_rm_del(vrf->info, rmap, rtype, afi); + + return NB_OK; +} + +void lib_vrf_zebra_filter_nht_apply_finish(struct nb_cb_apply_finish_args *args) +{ + struct vrf *vrf; + const char *afi_safi = yang_dnode_get_string(args->dnode, "afi-safi"); + const char *proto = yang_dnode_get_string(args->dnode, "protocol"); + const char *rmap = yang_dnode_get_string(args->dnode, "route-map"); + afi_t afi; + safi_t safi; + int rtype; + + yang_afi_safi_identity2value(afi_safi, &afi, &safi); + + if (strcasecmp(proto, "any") == 0) + rtype = ZEBRA_ROUTE_MAX; + else + rtype = proto_name2num(proto); + + /* finishing apply for an existing entry, it can't be invalid */ + assert(rtype >= 0); + assert(safi == SAFI_UNICAST); + + vrf = nb_running_get_entry(args->dnode, NULL, true); + + ip_nht_rm_add(vrf->info, rmap, rtype, afi); +} + +/* + * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/filter-nht/route-map + */ +int lib_vrf_zebra_filter_nht_route_map_modify(struct nb_cb_modify_args *args) +{ + /* the update is done in the apply_finish callback */ + return NB_OK; +} + +/* + * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/resolve-via-default + */ +int lib_vrf_zebra_resolve_via_default_modify(struct nb_cb_modify_args *args) +{ + struct vrf *vrf; + struct zebra_vrf *zvrf; + bool resolve_via_default; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + vrf = nb_running_get_entry(args->dnode, NULL, true); + zvrf = vrf->info; + + resolve_via_default = yang_dnode_get_bool(args->dnode, NULL); + + if (zvrf->zebra_rnh_ip_default_route == resolve_via_default) + return NB_OK; + + zvrf->zebra_rnh_ip_default_route = resolve_via_default; + + zebra_evaluate_rnh(zvrf, AFI_IP, 0, NULL, SAFI_UNICAST); + + return NB_OK; +} + +int lib_vrf_zebra_resolve_via_default_destroy(struct nb_cb_destroy_args *args) +{ + struct vrf *vrf; + struct zebra_vrf *zvrf; + bool resolve_via_default; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + vrf = nb_running_get_entry(args->dnode, NULL, true); + zvrf = vrf->info; + + resolve_via_default = DFLT_ZEBRA_IP_NHT_RESOLVE_VIA_DEFAULT; + + if (zvrf->zebra_rnh_ip_default_route == resolve_via_default) + return NB_OK; + + zvrf->zebra_rnh_ip_default_route = resolve_via_default; + + zebra_evaluate_rnh(zvrf, AFI_IP, 0, NULL, SAFI_UNICAST); + + return NB_OK; +} + +/* + * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ipv6-resolve-via-default + */ +int lib_vrf_zebra_ipv6_resolve_via_default_modify(struct nb_cb_modify_args *args) +{ + struct vrf *vrf; + struct zebra_vrf *zvrf; + bool resolve_via_default; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + vrf = nb_running_get_entry(args->dnode, NULL, true); + zvrf = vrf->info; + + resolve_via_default = yang_dnode_get_bool(args->dnode, NULL); + + if (zvrf->zebra_rnh_ipv6_default_route == resolve_via_default) + return NB_OK; + + zvrf->zebra_rnh_ipv6_default_route = resolve_via_default; + + zebra_evaluate_rnh(zvrf, AFI_IP6, 0, NULL, SAFI_UNICAST); + + return NB_OK; +} + +int lib_vrf_zebra_ipv6_resolve_via_default_destroy(struct nb_cb_destroy_args *args) +{ + struct vrf *vrf; + struct zebra_vrf *zvrf; + bool resolve_via_default; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + vrf = nb_running_get_entry(args->dnode, NULL, true); + zvrf = vrf->info; + + resolve_via_default = DFLT_ZEBRA_IP_NHT_RESOLVE_VIA_DEFAULT; + + if (zvrf->zebra_rnh_ipv6_default_route == resolve_via_default) + return NB_OK; + + zvrf->zebra_rnh_ipv6_default_route = resolve_via_default; + + zebra_evaluate_rnh(zvrf, AFI_IP6, 0, NULL, SAFI_UNICAST); + + return NB_OK; +} + +/* + * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/netns/table-range + */ +static int table_range_validate(uint32_t start, uint32_t end, char *errmsg, + size_t errmsg_len) +{ +#if defined(GNU_LINUX) + if ((start >= RT_TABLE_ID_COMPAT && start <= RT_TABLE_ID_LOCAL) || + (end >= RT_TABLE_ID_COMPAT && end <= RT_TABLE_ID_LOCAL)) { + snprintfrr(errmsg, errmsg_len, + "Values forbidden in range [%u;%u]", + RT_TABLE_ID_COMPAT, RT_TABLE_ID_LOCAL); + return NB_ERR_VALIDATION; + } + if (start < RT_TABLE_ID_COMPAT && end > RT_TABLE_ID_LOCAL) { + snprintfrr(errmsg, errmsg_len, + "Range overlaps range [%u;%u] forbidden", + RT_TABLE_ID_COMPAT, RT_TABLE_ID_LOCAL); + return NB_ERR_VALIDATION; + } +#endif + return NB_OK; +} + +int lib_vrf_zebra_netns_table_range_create(struct nb_cb_create_args *args) +{ + struct vrf *vrf; + uint32_t start, end; + const char *vrf_name; + + start = yang_dnode_get_uint32(args->dnode, "start"); + end = yang_dnode_get_uint32(args->dnode, "end"); + + if (args->event == NB_EV_VALIDATE) { + vrf_name = yang_dnode_get_string(args->dnode, "../../../name"); + if (!vrf_is_backend_netns() && + strcmp(vrf_name, VRF_DEFAULT_NAME)) { + snprintfrr(args->errmsg, args->errmsg_len, + "Configuration is not available in non-default VRFs when using VRF-lite backend."); return NB_ERR_VALIDATION; } + return table_range_validate(start, end, args->errmsg, + args->errmsg_len); + } + + if (args->event != NB_EV_APPLY) + return NB_OK; + + vrf = nb_running_get_entry(args->dnode, NULL, true); + + table_manager_range(true, vrf->info, start, end); + + return NB_OK; +} + +int lib_vrf_zebra_netns_table_range_destroy(struct nb_cb_destroy_args *args) +{ + struct vrf *vrf; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + vrf = nb_running_get_entry(args->dnode, NULL, true); + + table_manager_range(false, vrf->info, 0, 0); + + return NB_OK; +} + +/* + * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/netns/table-range/start + */ +int lib_vrf_zebra_netns_table_range_start_modify(struct nb_cb_modify_args *args) +{ + struct vrf *vrf; + uint32_t start, end; + + start = yang_dnode_get_uint32(args->dnode, NULL); + end = yang_dnode_get_uint32(args->dnode, "../end"); + if (args->event == NB_EV_VALIDATE) + return table_range_validate(start, end, args->errmsg, + args->errmsg_len); + + if (args->event != NB_EV_APPLY) + return NB_OK; + + vrf = nb_running_get_entry(args->dnode, NULL, true); + + table_manager_range(true, vrf->info, start, end); + + return NB_OK; +} + +/* + * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/netns/table-range/end + */ +int lib_vrf_zebra_netns_table_range_end_modify(struct nb_cb_modify_args *args) +{ + struct vrf *vrf; + uint32_t start, end; + + start = yang_dnode_get_uint32(args->dnode, "../start"); + end = yang_dnode_get_uint32(args->dnode, NULL); + + if (args->event == NB_EV_VALIDATE) + return table_range_validate(start, end, args->errmsg, + args->errmsg_len); + + if (args->event != NB_EV_APPLY) + return NB_OK; + + vrf = nb_running_get_entry(args->dnode, NULL, true); + + table_manager_range(true, vrf->info, start, end); + + return NB_OK; +} + +/* + * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/l3vni-id + */ +int lib_vrf_zebra_l3vni_id_modify(struct nb_cb_modify_args *args) +{ + struct vrf *vrf; + vni_t vni = 0; + bool pfx_only = false; + uint32_t count; + + vni = yang_dnode_get_uint32(args->dnode, NULL); + + switch (args->event) { + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_VALIDATE: + count = yang_dnode_count(args->dnode, + "/frr-vrf:lib/vrf/frr-zebra:zebra[l3vni-id='%u']", + vni); + if (count > 1) { + snprintfrr(args->errmsg, args->errmsg_len, + "vni %u is already mapped to another vrf", + vni); + return NB_ERR_VALIDATION; + } break; case NB_EV_APPLY: - vrf = nb_running_get_entry(args->dnode, NULL, true); - zvrf = zebra_vrf_lookup_by_name(vrf->name); - vni = yang_dnode_get_uint32(args->dnode, NULL); - /* Note: This covers lib_vrf_zebra_prefix_only_modify() config - * along with l3vni config - */ pfx_only = yang_dnode_get_bool(args->dnode, "../prefix-only"); - if (zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ, - pfx_only ? 1 : 0, 1) - != 0) { - if (IS_ZEBRA_DEBUG_VXLAN) - snprintf( - args->errmsg, args->errmsg_len, - "vrf vni %u mapping failed with error: %s", - vni, err); - return NB_ERR; - } - + zebra_vxlan_process_vrf_vni_cmd(vrf->info, vni, + pfx_only ? 1 : 0, 1); break; } @@ -1492,10 +3750,7 @@ int lib_vrf_zebra_l3vni_id_modify(struct nb_cb_modify_args *args) int lib_vrf_zebra_l3vni_id_destroy(struct nb_cb_destroy_args *args) { struct vrf *vrf; - struct zebra_vrf *zvrf; vni_t vni = 0; - char err[ERR_STR_SZ]; - uint8_t filter = 0; switch (args->event) { case NB_EV_PREPARE: @@ -1504,32 +3759,9 @@ int lib_vrf_zebra_l3vni_id_destroy(struct nb_cb_destroy_args *args) return NB_OK; case NB_EV_APPLY: vrf = nb_running_get_entry(args->dnode, NULL, true); - zvrf = zebra_vrf_lookup_by_name(vrf->name); vni = yang_dnode_get_uint32(args->dnode, NULL); - if (!zl3vni_lookup(vni)) - return NB_OK; - - if (zvrf->l3vni != vni) { - snprintf(args->errmsg, args->errmsg_len, - "vrf %s has different vni %u mapped", - vrf->name, zvrf->l3vni); - return NB_ERR; - } - - if (is_l3vni_for_prefix_routes_only(zvrf->l3vni)) - filter = 1; - - if (zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ, - filter, 0) - != 0) { - if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug( - "vrf vni %u unmapping failed with error: %s", - vni, err); - return NB_ERR; - } - + zebra_vxlan_process_vrf_vni_cmd(vrf->info, vni, 0, 0); break; } diff --git a/zebra/zebra_ns.c b/zebra/zebra_ns.c index f74b30a6ce..803d8f0034 100644 --- a/zebra/zebra_ns.c +++ b/zebra/zebra_ns.c @@ -238,10 +238,3 @@ int zebra_ns_init(void) return 0; } - -int zebra_ns_config_write(struct vty *vty, struct ns *ns) -{ - if (ns && ns->name != NULL) - vty_out(vty, " netns %s\n", ns->name); - return 0; -} diff --git a/zebra/zebra_ns.h b/zebra/zebra_ns.h index 55cbb95528..8d988c3f82 100644 --- a/zebra/zebra_ns.h +++ b/zebra/zebra_ns.h @@ -70,7 +70,6 @@ int zebra_ns_early_shutdown(struct ns *ns, int zebra_ns_final_shutdown(struct ns *ns, void *param_in __attribute__((unused)), void **param_out __attribute__((unused))); -int zebra_ns_config_write(struct vty *vty, struct ns *ns); void zebra_ns_startup_continue(struct zebra_dplane_ctx *ctx); diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c index 40630d7890..d7d752f01e 100644 --- a/zebra/zebra_ptm.c +++ b/zebra/zebra_ptm.c @@ -86,7 +86,6 @@ struct zebra_ptm_cb ptm_cb; static int zebra_ptm_socket_init(void); void zebra_ptm_sock_read(struct event *thread); -static void zebra_ptm_install_commands(void); static int zebra_ptm_handle_msg_cb(void *arg, void *in_ctxt); void zebra_bfd_peer_replay_req(void); void zebra_ptm_send_status_req(void); @@ -115,7 +114,6 @@ void zebra_ptm_init(void) } ptm_cb.pid = getpid(); - zebra_ptm_install_commands(); snprintf(buf, sizeof(buf), "%s", FRR_PTM_NAME); ptm_hdl = ptm_lib_register(buf, NULL, zebra_ptm_handle_msg_cb, @@ -240,10 +238,7 @@ void zebra_ptm_connect(struct event *t) } } -DEFUN (zebra_ptm_enable, - zebra_ptm_enable_cmd, - "ptm-enable", - "Enable neighbor check with specified topology\n") +void zebra_global_ptm_enable(void) { struct vrf *vrf; struct interface *ifp; @@ -266,27 +261,16 @@ DEFUN (zebra_ptm_enable, } zebra_ptm_connect(NULL); - - return CMD_SUCCESS; } -DEFUN (no_zebra_ptm_enable, - no_zebra_ptm_enable_cmd, - "no ptm-enable", - NO_STR - "Enable neighbor check with specified topology\n") +void zebra_global_ptm_disable(void) { ptm_cb.ptm_enable = ZEBRA_IF_PTM_ENABLE_OFF; zebra_ptm_reset_status(1); - return CMD_SUCCESS; } -DEFUN (zebra_ptm_enable_if, - zebra_ptm_enable_if_cmd, - "ptm-enable", - "Enable neighbor check with specified topology\n") +void zebra_if_ptm_enable(struct interface *ifp) { - VTY_DECLVAR_CONTEXT(interface, ifp); struct zebra_if *if_data; int old_ptm_enable; int send_linkdown = 0; @@ -295,7 +279,7 @@ DEFUN (zebra_ptm_enable_if, if_data->ptm_enable = ZEBRA_IF_PTM_ENABLE_UNSPEC; if (ifp->ifindex == IFINDEX_INTERNAL) { - return CMD_SUCCESS; + return; } old_ptm_enable = ifp->ptm_enable; @@ -312,19 +296,12 @@ DEFUN (zebra_ptm_enable_if, if_down(ifp); } } - - return CMD_SUCCESS; } -DEFUN (no_zebra_ptm_enable_if, - no_zebra_ptm_enable_if_cmd, - "no ptm-enable", - NO_STR - "Enable neighbor check with specified topology\n") +void zebra_if_ptm_disable(struct interface *ifp) { - VTY_DECLVAR_CONTEXT(interface, ifp); - int send_linkup = 0; struct zebra_if *if_data; + int send_linkup = 0; if ((ifp->ifindex != IFINDEX_INTERNAL) && (ifp->ptm_enable)) { if (!if_is_operative(ifp)) @@ -341,17 +318,6 @@ DEFUN (no_zebra_ptm_enable_if, if_data = ifp->info; if_data->ptm_enable = ZEBRA_IF_PTM_ENABLE_OFF; - - return CMD_SUCCESS; -} - - -void zebra_ptm_write(struct vty *vty) -{ - if (ptm_cb.ptm_enable) - vty_out(vty, "ptm-enable\n"); - - return; } static int zebra_ptm_socket_init(void) @@ -394,14 +360,6 @@ static int zebra_ptm_socket_init(void) return sock; } -static void zebra_ptm_install_commands(void) -{ - install_element(CONFIG_NODE, &zebra_ptm_enable_cmd); - install_element(CONFIG_NODE, &no_zebra_ptm_enable_cmd); - install_element(INTERFACE_NODE, &zebra_ptm_enable_if_cmd); - install_element(INTERFACE_NODE, &no_zebra_ptm_enable_if_cmd); -} - /* BFD session goes down, send message to the protocols. */ static void if_bfd_session_update(struct interface *ifp, struct prefix *dp, struct prefix *sp, int status, @@ -1165,12 +1123,6 @@ void zebra_ptm_if_set_ptm_state(struct interface *ifp, ifp->ptm_enable = zebra_ifp->ptm_enable; } -void zebra_ptm_if_write(struct vty *vty, struct zebra_if *zebra_ifp) -{ - if (zebra_ifp->ptm_enable == ZEBRA_IF_PTM_ENABLE_OFF) - vty_out(vty, " no ptm-enable\n"); -} - #else /* HAVE_BFDD */ /* @@ -1533,16 +1485,6 @@ void zebra_ptm_show_status(struct vty *vty __attribute__((__unused__)), /* NOTHING */ } -void zebra_ptm_write(struct vty *vty __attribute__((__unused__))) -{ - /* NOTHING */ -} - -void zebra_ptm_if_write(struct vty *vty __attribute__((__unused__)), - struct zebra_if *zifp __attribute__((__unused__))) -{ - /* NOTHING */ -} void zebra_ptm_if_set_ptm_state(struct interface *i __attribute__((__unused__)), struct zebra_if *zi __attribute__((__unused__))) { diff --git a/zebra/zebra_ptm.h b/zebra/zebra_ptm.h index 4d09474b7f..20a53e2fea 100644 --- a/zebra/zebra_ptm.h +++ b/zebra/zebra_ptm.h @@ -58,9 +58,15 @@ struct zebra_ptm_cb { void zebra_ptm_init(void); void zebra_ptm_finish(void); void zebra_ptm_connect(struct event *t); -void zebra_ptm_write(struct vty *vty); int zebra_ptm_get_enable_state(void); +#if HAVE_BFDD == 0 +void zebra_global_ptm_enable(void); +void zebra_global_ptm_disable(void); +void zebra_if_ptm_enable(struct interface *ifp); +void zebra_if_ptm_disable(struct interface *ifp); +#endif + /* ZAPI message handlers */ void zebra_ptm_bfd_dst_register(ZAPI_HANDLER_ARGS); void zebra_ptm_bfd_dst_deregister(ZAPI_HANDLER_ARGS); @@ -74,7 +80,6 @@ void zebra_ptm_show_status(struct vty *vty, json_object *json, void zebra_ptm_if_init(struct zebra_if *zebra_ifp); void zebra_ptm_if_set_ptm_state(struct interface *ifp, struct zebra_if *zebra_ifp); -void zebra_ptm_if_write(struct vty *vty, struct zebra_if *zebra_ifp); #ifdef __cplusplus } diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c index 21aaf1d066..95da789108 100644 --- a/zebra/zebra_routemap.c +++ b/zebra/zebra_routemap.c @@ -14,7 +14,6 @@ #include "filter.h" #include "plist.h" #include "nexthop.h" -#include "northbound_cli.h" #include "lib/route_types.h" #include "vrf.h" #include "frrstr.h" @@ -24,6 +23,7 @@ #include "zebra/debug.h" #include "zebra/zebra_rnh.h" #include "zebra/zebra_routemap.h" +#include "zebra/zebra_vrf.h" #include "zebra/zebra_routemap_clippy.c" @@ -36,8 +36,6 @@ struct zebra_rmap_obj { struct route_entry *re; }; -static void zebra_route_map_set_delay_timer(uint32_t value); - /* 'match tag TAG' * Match function return 1 if match is success else return 0 */ @@ -284,8 +282,8 @@ static const struct route_map_rule_cmd route_match_interface_cmd = { route_match_interface_free }; -static int ip_protocol_rm_add(struct zebra_vrf *zvrf, const char *rmap, - int rtype, afi_t afi, safi_t safi) +int ip_protocol_rm_add(struct zebra_vrf *zvrf, const char *rmap, int rtype, + afi_t afi, safi_t safi) { struct route_table *table; @@ -317,8 +315,8 @@ static int ip_protocol_rm_add(struct zebra_vrf *zvrf, const char *rmap, return CMD_SUCCESS; } -static int ip_protocol_rm_del(struct zebra_vrf *zvrf, const char *rmap, - int rtype, afi_t afi, safi_t safi) +int ip_protocol_rm_del(struct zebra_vrf *zvrf, const char *rmap, int rtype, + afi_t afi, safi_t safi) { struct route_table *table; @@ -346,8 +344,7 @@ static int ip_protocol_rm_del(struct zebra_vrf *zvrf, const char *rmap, return CMD_SUCCESS; } -static int ip_nht_rm_add(struct zebra_vrf *zvrf, const char *rmap, int rtype, - int afi) +int ip_nht_rm_add(struct zebra_vrf *zvrf, const char *rmap, int rtype, int afi) { if (NHT_RM_NAME(zvrf, afi, rtype)) { @@ -368,8 +365,7 @@ static int ip_nht_rm_add(struct zebra_vrf *zvrf, const char *rmap, int rtype, return CMD_SUCCESS; } -static int ip_nht_rm_del(struct zebra_vrf *zvrf, const char *rmap, int rtype, - int afi) +int ip_nht_rm_del(struct zebra_vrf *zvrf, const char *rmap, int rtype, int afi) { if (!NHT_RM_NAME(zvrf, afi, rtype)) @@ -391,351 +387,7 @@ static int ip_nht_rm_del(struct zebra_vrf *zvrf, const char *rmap, int rtype, return CMD_SUCCESS; } -DEFPY_YANG( - match_ip_address_prefix_len, match_ip_address_prefix_len_cmd, - "match ip address prefix-len (0-32)$length", - MATCH_STR - IP_STR - "Match prefix length of IP address\n" - "Match prefix length of IP address\n" - "Prefix length\n") -{ - const char *xpath = - "./match-condition[condition='frr-zebra-route-map:ipv4-prefix-length']"; - char xpath_value[XPATH_MAXLEN]; - - nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); - snprintf( - xpath_value, sizeof(xpath_value), - "%s/rmap-match-condition/frr-zebra-route-map:ipv4-prefix-length", - xpath); - nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, length_str); - - return nb_cli_apply_changes(vty, NULL); -} - -DEFPY_YANG( - no_match_ip_address_prefix_len, no_match_ip_address_prefix_len_cmd, - "no match ip address prefix-len [(0-32)]", - NO_STR - MATCH_STR - IP_STR - "Match prefix length of IP address\n" - "Match prefix length of IP address\n" - "Prefix length\n") -{ - const char *xpath = - "./match-condition[condition='frr-zebra-route-map:ipv4-prefix-length']"; - - nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); - - return nb_cli_apply_changes(vty, NULL); -} - -DEFPY_YANG( - match_ipv6_address_prefix_len, match_ipv6_address_prefix_len_cmd, - "match ipv6 address prefix-len (0-128)$length", - MATCH_STR - IPV6_STR - "Match prefix length of IPv6 address\n" - "Match prefix length of IPv6 address\n" - "Prefix length\n") -{ - const char *xpath = - "./match-condition[condition='frr-zebra-route-map:ipv6-prefix-length']"; - char xpath_value[XPATH_MAXLEN]; - - nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); - snprintf( - xpath_value, sizeof(xpath_value), - "%s/rmap-match-condition/frr-zebra-route-map:ipv6-prefix-length", - xpath); - nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, length_str); - - return nb_cli_apply_changes(vty, NULL); -} - -DEFPY_YANG( - no_match_ipv6_address_prefix_len, no_match_ipv6_address_prefix_len_cmd, - "no match ipv6 address prefix-len [(0-128)]", - NO_STR - MATCH_STR - IPV6_STR - "Match prefix length of IPv6 address\n" - "Match prefix length of IPv6 address\n" - "Prefix length\n") -{ - const char *xpath = - "./match-condition[condition='frr-zebra-route-map:ipv6-prefix-length']"; - - nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); - - return nb_cli_apply_changes(vty, NULL); -} - -DEFPY_YANG( - match_ip_nexthop_prefix_len, match_ip_nexthop_prefix_len_cmd, - "match ip next-hop prefix-len (0-32)$length", - MATCH_STR - IP_STR - "Match prefixlen of nexthop IP address\n" - "Match prefixlen of given nexthop\n" - "Prefix length\n") -{ - const char *xpath = - "./match-condition[condition='frr-zebra-route-map:ipv4-next-hop-prefix-length']"; - char xpath_value[XPATH_MAXLEN]; - - nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); - snprintf( - xpath_value, sizeof(xpath_value), - "%s/rmap-match-condition/frr-zebra-route-map:ipv4-prefix-length", - xpath); - nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, length_str); - - return nb_cli_apply_changes(vty, NULL); -} - -DEFPY_YANG( - no_match_ip_nexthop_prefix_len, no_match_ip_nexthop_prefix_len_cmd, - "no match ip next-hop prefix-len [(0-32)]", - NO_STR - MATCH_STR - IP_STR - "Match prefixlen of nexthop IP address\n" - "Match prefix length of nexthop\n" - "Prefix length\n") -{ - const char *xpath = - "./match-condition[condition='frr-zebra-route-map:ipv4-next-hop-prefix-length']"; - - nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); - - return nb_cli_apply_changes(vty, NULL); -} - -DEFPY_YANG( - match_source_protocol, match_source_protocol_cmd, - "match source-protocol " FRR_REDIST_STR_ZEBRA "$proto", - MATCH_STR - "Match protocol via which the route was learnt\n" - FRR_REDIST_HELP_STR_ZEBRA) -{ - const char *xpath = - "./match-condition[condition='frr-zebra-route-map:source-protocol']"; - char xpath_value[XPATH_MAXLEN]; - - nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); - snprintf(xpath_value, sizeof(xpath_value), - "%s/rmap-match-condition/frr-zebra-route-map:source-protocol", - xpath); - nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, proto); - - return nb_cli_apply_changes(vty, NULL); -} - -DEFPY_YANG( - no_match_source_protocol, no_match_source_protocol_cmd, - "no match source-protocol [" FRR_REDIST_STR_ZEBRA "]", - NO_STR - MATCH_STR - "Match protocol via which the route was learnt\n" - FRR_REDIST_HELP_STR_ZEBRA) -{ - const char *xpath = - "./match-condition[condition='frr-zebra-route-map:source-protocol']"; - - nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); - - return nb_cli_apply_changes(vty, NULL); -} - -DEFPY_YANG( - match_source_instance, match_source_instance_cmd, - "match source-instance (0-255)$instance", - MATCH_STR - "Match the protocol's instance number\n" - "The instance number\n") -{ - const char *xpath = - "./match-condition[condition='frr-zebra-route-map:source-instance']"; - char xpath_value[XPATH_MAXLEN]; - - nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); - snprintf(xpath_value, sizeof(xpath_value), - "%s/rmap-match-condition/frr-zebra-route-map:source-instance", - xpath); - nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, instance_str); - - return nb_cli_apply_changes(vty, NULL); -} - -DEFPY_YANG( - no_match_source_instance, no_match_source_instance_cmd, - "no match source-instance [(0-255)]", - NO_STR MATCH_STR - "Match the protocol's instance number\n" - "The instance number\n") -{ - const char *xpath = - "./match-condition[condition='frr-zebra-route-map:source-instance']"; - - nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); - - return nb_cli_apply_changes(vty, NULL); -} - -/* set functions */ - -DEFPY_YANG( - set_src, set_src_cmd, - "set src <A.B.C.D$addrv4|X:X::X:X$addrv6>", - SET_STR - "src address for route\n" - "IPv4 src address\n" - "IPv6 src address\n") -{ - const char *xpath = - "./set-action[action='frr-zebra-route-map:src-address']"; - char xpath_value[XPATH_MAXLEN]; - - nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); - if (addrv4_str) { - snprintf( - xpath_value, sizeof(xpath_value), - "%s/rmap-set-action/frr-zebra-route-map:ipv4-src-address", - xpath); - nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, - addrv4_str); - } else { - snprintf( - xpath_value, sizeof(xpath_value), - "%s/rmap-set-action/frr-zebra-route-map:ipv6-src-address", - xpath); - nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, - addrv6_str); - } - - return nb_cli_apply_changes(vty, NULL); -} - -DEFPY_YANG( - no_set_src, no_set_src_cmd, - "no set src [<A.B.C.D|X:X::X:X>]", - NO_STR - SET_STR - "Source address for route\n" - "IPv4 address\n" - "IPv6 address\n") -{ - const char *xpath = - "./set-action[action='frr-zebra-route-map:src-address']"; - - nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); - - return nb_cli_apply_changes(vty, NULL); -} - -DEFUN_YANG (zebra_route_map_timer, - zebra_route_map_timer_cmd, - "zebra route-map delay-timer (0-600)", - ZEBRA_STR - "Set route-map parameters\n" - "Time to wait before route-map updates are processed\n" - "0 means route-map changes are run immediately instead of delaying\n") -{ - int idx_number = 3; - uint32_t rmap_delay_timer; - - rmap_delay_timer = strtoul(argv[idx_number]->arg, NULL, 10); - zebra_route_map_set_delay_timer(rmap_delay_timer); - - return (CMD_SUCCESS); -} - -DEFUN_YANG (no_zebra_route_map_timer, - no_zebra_route_map_timer_cmd, - "no zebra route-map delay-timer [(0-600)]", - NO_STR - ZEBRA_STR - "Set route-map parameters\n" - "Reset delay-timer to default value, 30 secs\n" - "0 means route-map changes are run immediately instead of delaying\n") -{ - zebra_route_map_set_delay_timer(ZEBRA_RMAP_DEFAULT_UPDATE_TIMER); - - return (CMD_SUCCESS); -} - -DEFPY_YANG (ip_protocol, - ip_protocol_cmd, - "ip protocol " FRR_IP_PROTOCOL_MAP_STR_ZEBRA - " $proto route-map ROUTE-MAP$rmap", - IP_STR - "Filter routing info exchanged between zebra and protocol\n" - FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA - "Specify route-map\n" - "Route map name\n") -{ - int ret, rtype; - - assert(proto); - assert(rmap); - - ZEBRA_DECLVAR_CONTEXT_VRF(vrf, zvrf); - - if (!zvrf) - return CMD_WARNING; - - if (strcasecmp(proto, "any") == 0) - rtype = ZEBRA_ROUTE_MAX; - else - rtype = proto_name2num(proto); - if (rtype < 0) { - vty_out(vty, "invalid protocol name \"%s\"\n", proto); - return CMD_WARNING_CONFIG_FAILED; - } - - ret = ip_protocol_rm_add(zvrf, rmap, rtype, AFI_IP, SAFI_UNICAST); - - return ret; -} - -DEFPY_YANG (no_ip_protocol, - no_ip_protocol_cmd, - "no ip protocol " FRR_IP_PROTOCOL_MAP_STR_ZEBRA - " $proto [route-map ROUTE-MAP$rmap]", - NO_STR - IP_STR - "Stop filtering routing info between zebra and protocol\n" - FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA - "Specify route-map\n" - "Route map name\n") -{ - int ret, rtype; - - assert(proto); - - ZEBRA_DECLVAR_CONTEXT_VRF(vrf, zvrf); - - if (!zvrf) - return CMD_WARNING; - - if (strcasecmp(proto, "any") == 0) - rtype = ZEBRA_ROUTE_MAX; - else - rtype = proto_name2num(proto); - if (rtype < 0) { - vty_out(vty, "invalid protocol name \"%s\"\n", proto); - return CMD_WARNING_CONFIG_FAILED; - } - - ret = ip_protocol_rm_del(zvrf, rmap, rtype, AFI_IP, SAFI_UNICAST); - - return ret; -} - -DEFPY_YANG (show_ip_protocol, +DEFPY (show_ip_protocol, show_ip_protocol_cmd, "show ip protocol [vrf <NAME$vrf_name|all$vrf_all>]", SHOW_STR @@ -748,75 +400,7 @@ DEFPY_YANG (show_ip_protocol, return ret; } -DEFPY_YANG (ipv6_protocol, - ipv6_protocol_cmd, - "ipv6 protocol " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA - " $proto route-map ROUTE-MAP$rmap", - IP6_STR - "Filter IPv6 routing info exchanged between zebra and protocol\n" - FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA - "Specify route-map\n" - "Route map name\n") -{ - int ret, rtype; - - assert(rmap); - assert(proto); - - ZEBRA_DECLVAR_CONTEXT_VRF(vrf, zvrf); - - if (!zvrf) - return CMD_WARNING; - - if (strcasecmp(proto, "any") == 0) - rtype = ZEBRA_ROUTE_MAX; - else - rtype = proto_name2num(proto); - if (rtype < 0) { - vty_out(vty, "invalid protocol name \"%s\"\n", proto); - return CMD_WARNING_CONFIG_FAILED; - } - - ret = ip_protocol_rm_add(zvrf, rmap, rtype, AFI_IP6, SAFI_UNICAST); - - return ret; -} - -DEFPY_YANG (no_ipv6_protocol, - no_ipv6_protocol_cmd, - "no ipv6 protocol " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA - " $proto [route-map ROUTE-MAP$rmap]", - NO_STR - IP6_STR - "Stop filtering IPv6 routing info between zebra and protocol\n" - FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA - "Specify route-map\n" - "Route map name\n") -{ - int ret, rtype; - - assert(proto); - - ZEBRA_DECLVAR_CONTEXT_VRF(vrf, zvrf); - - if (!zvrf) - return CMD_WARNING; - - if (strcasecmp(proto, "any") == 0) - rtype = ZEBRA_ROUTE_MAX; - else - rtype = proto_name2num(proto); - if (rtype < 0) { - vty_out(vty, "invalid protocol name \"%s\"\n", proto); - return CMD_WARNING_CONFIG_FAILED; - } - - ret = ip_protocol_rm_del(zvrf, rmap, rtype, AFI_IP6, SAFI_UNICAST); - - return ret; -} - -DEFPY_YANG (show_ipv6_protocol, +DEFPY (show_ipv6_protocol, show_ipv6_protocol_cmd, "show ipv6 protocol [vrf <NAME$vrf_name|all$vrf_all>]", SHOW_STR @@ -829,76 +413,7 @@ DEFPY_YANG (show_ipv6_protocol, return ret; } -DEFPY_YANG (ip_protocol_nht_rmap, - ip_protocol_nht_rmap_cmd, - "ip nht " FRR_IP_PROTOCOL_MAP_STR_ZEBRA - " $proto route-map ROUTE-MAP$rmap", - IP_STR - "Filter Next Hop tracking route resolution\n" - FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA - "Specify route map\n" - "Route map name\n") -{ - - int ret, rtype; - - assert(proto); - assert(rmap); - - ZEBRA_DECLVAR_CONTEXT_VRF(vrf, zvrf); - - if (!zvrf) - return CMD_WARNING; - - if (strcasecmp(proto, "any") == 0) - rtype = ZEBRA_ROUTE_MAX; - else - rtype = proto_name2num(proto); - if (rtype < 0) { - vty_out(vty, "invalid protocol name \"%s\"\n", proto); - return CMD_WARNING_CONFIG_FAILED; - } - - ret = ip_nht_rm_add(zvrf, rmap, rtype, AFI_IP); - - return ret; -} - -DEFPY_YANG (no_ip_protocol_nht_rmap, - no_ip_protocol_nht_rmap_cmd, - "no ip nht " FRR_IP_PROTOCOL_MAP_STR_ZEBRA - " $proto route-map [ROUTE-MAP$rmap]", - NO_STR - IP_STR - "Filter Next Hop tracking route resolution\n" - FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA - "Specify route map\n" - "Route map name\n") -{ - int ret, rtype; - - assert(proto); - - ZEBRA_DECLVAR_CONTEXT_VRF(vrf, zvrf); - - if (!zvrf) - return CMD_WARNING; - - if (strcasecmp(proto, "any") == 0) - rtype = ZEBRA_ROUTE_MAX; - else - rtype = proto_name2num(proto); - if (rtype < 0) { - vty_out(vty, "invalid protocol name \"%s\"\n", proto); - return CMD_WARNING_CONFIG_FAILED; - } - - ret = ip_nht_rm_del(zvrf, rmap, rtype, AFI_IP); - - return ret; -} - -DEFPY_YANG (show_ip_protocol_nht, +DEFPY (show_ip_protocol_nht, show_ip_protocol_nht_cmd, "show ip nht route-map [vrf <NAME$vrf_name|all$vrf_all>] [json]", SHOW_STR @@ -917,75 +432,7 @@ DEFPY_YANG (show_ip_protocol_nht, return ret; } -DEFPY_YANG (ipv6_protocol_nht_rmap, - ipv6_protocol_nht_rmap_cmd, - "ipv6 nht " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA - " $proto route-map ROUTE-MAP$rmap", - IP6_STR - "Filter Next Hop tracking route resolution\n" - FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA - "Specify route map\n" - "Route map name\n") -{ - int ret, rtype; - - assert(rmap); - assert(proto); - - ZEBRA_DECLVAR_CONTEXT_VRF(vrf, zvrf); - - if (!zvrf) - return CMD_WARNING; - - if (strcasecmp(proto, "any") == 0) - rtype = ZEBRA_ROUTE_MAX; - else - rtype = proto_name2num(proto); - if (rtype < 0) { - vty_out(vty, "invalid protocol name \"%s\"\n", proto); - return CMD_WARNING_CONFIG_FAILED; - } - - ret = ip_nht_rm_add(zvrf, rmap, rtype, AFI_IP6); - - return ret; -} - -DEFPY_YANG (no_ipv6_protocol_nht_rmap, - no_ipv6_protocol_nht_rmap_cmd, - "no ipv6 nht " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA - " $proto [route-map ROUTE-MAP$rmap]", - NO_STR - IP6_STR - "Filter Next Hop tracking route resolution\n" - FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA - "Specify route map\n" - "Route map name\n") -{ - int ret, rtype; - - assert(proto); - - ZEBRA_DECLVAR_CONTEXT_VRF(vrf, zvrf); - - if (!zvrf) - return CMD_WARNING; - - if (strcasecmp(proto, "any") == 0) - rtype = ZEBRA_ROUTE_MAX; - else - rtype = proto_name2num(proto); - if (rtype < 0) { - vty_out(vty, "invalid protocol name \"%s\"\n", proto); - return CMD_WARNING_CONFIG_FAILED; - } - - ret = ip_nht_rm_del(zvrf, rmap, rtype, AFI_IP6); - - return ret; -} - -DEFPY_YANG (show_ipv6_protocol_nht, +DEFPY (show_ipv6_protocol_nht, show_ipv6_protocol_nht_cmd, "show ipv6 nht route-map [vrf <NAME$vrf_name|all$vrf_all>] [json]", SHOW_STR @@ -1736,7 +1183,7 @@ static void zebra_route_map_update_timer(struct event *thread) */ } -static void zebra_route_map_set_delay_timer(uint32_t value) +void zebra_route_map_set_delay_timer(uint32_t value) { zebra_rmap_update_timer = value; if (!value && zebra_t_rmap_update) { @@ -1903,88 +1350,14 @@ void zebra_routemap_vrf_delete(struct zebra_vrf *zvrf) } } -/* ip protocol configuration write function */ -void zebra_routemap_config_write_protocol(struct vty *vty, - struct zebra_vrf *zvrf) -{ - int i; - char space[2]; - - memset(space, 0, sizeof(space)); - - if (zvrf_id(zvrf) != VRF_DEFAULT) - snprintf(space, sizeof(space), "%s", " "); - - for (i = 0; i < ZEBRA_ROUTE_MAX; i++) { - if (PROTO_RM_NAME(zvrf, AFI_IP, i)) - vty_out(vty, "%sip protocol %s route-map %s\n", space, - zebra_route_string(i), - PROTO_RM_NAME(zvrf, AFI_IP, i)); - - if (PROTO_RM_NAME(zvrf, AFI_IP6, i)) - vty_out(vty, "%sipv6 protocol %s route-map %s\n", space, - zebra_route_string(i), - PROTO_RM_NAME(zvrf, AFI_IP6, i)); - - if (NHT_RM_NAME(zvrf, AFI_IP, i)) - vty_out(vty, "%sip nht %s route-map %s\n", space, - zebra_route_string(i), - NHT_RM_NAME(zvrf, AFI_IP, i)); - - if (NHT_RM_NAME(zvrf, AFI_IP6, i)) - vty_out(vty, "%sipv6 nht %s route-map %s\n", space, - zebra_route_string(i), - NHT_RM_NAME(zvrf, AFI_IP6, i)); - } - - if (PROTO_RM_NAME(zvrf, AFI_IP, ZEBRA_ROUTE_MAX)) - vty_out(vty, "%sip protocol %s route-map %s\n", space, "any", - PROTO_RM_NAME(zvrf, AFI_IP, ZEBRA_ROUTE_MAX)); - - if (PROTO_RM_NAME(zvrf, AFI_IP6, ZEBRA_ROUTE_MAX)) - vty_out(vty, "%sipv6 protocol %s route-map %s\n", space, "any", - PROTO_RM_NAME(zvrf, AFI_IP6, ZEBRA_ROUTE_MAX)); - - if (NHT_RM_NAME(zvrf, AFI_IP, ZEBRA_ROUTE_MAX)) - vty_out(vty, "%sip nht %s route-map %s\n", space, "any", - NHT_RM_NAME(zvrf, AFI_IP, ZEBRA_ROUTE_MAX)); - - if (NHT_RM_NAME(zvrf, AFI_IP6, ZEBRA_ROUTE_MAX)) - vty_out(vty, "%sipv6 nht %s route-map %s\n", space, "any", - NHT_RM_NAME(zvrf, AFI_IP6, ZEBRA_ROUTE_MAX)); - - if (zvrf_id(zvrf) == VRF_DEFAULT - && zebra_rmap_update_timer != ZEBRA_RMAP_DEFAULT_UPDATE_TIMER) - vty_out(vty, "zebra route-map delay-timer %d\n", - zebra_rmap_update_timer); -} - void zebra_route_map_init(void) { - install_element(CONFIG_NODE, &ip_protocol_cmd); - install_element(CONFIG_NODE, &no_ip_protocol_cmd); - install_element(VRF_NODE, &ip_protocol_cmd); - install_element(VRF_NODE, &no_ip_protocol_cmd); install_element(VIEW_NODE, &show_ip_protocol_cmd); - install_element(CONFIG_NODE, &ipv6_protocol_cmd); - install_element(CONFIG_NODE, &no_ipv6_protocol_cmd); - install_element(VRF_NODE, &ipv6_protocol_cmd); - install_element(VRF_NODE, &no_ipv6_protocol_cmd); install_element(VIEW_NODE, &show_ipv6_protocol_cmd); - install_element(CONFIG_NODE, &ip_protocol_nht_rmap_cmd); - install_element(CONFIG_NODE, &no_ip_protocol_nht_rmap_cmd); - install_element(VRF_NODE, &ip_protocol_nht_rmap_cmd); - install_element(VRF_NODE, &no_ip_protocol_nht_rmap_cmd); install_element(VIEW_NODE, &show_ip_protocol_nht_cmd); - install_element(CONFIG_NODE, &ipv6_protocol_nht_rmap_cmd); - install_element(CONFIG_NODE, &no_ipv6_protocol_nht_rmap_cmd); - install_element(VRF_NODE, &ipv6_protocol_nht_rmap_cmd); - install_element(VRF_NODE, &no_ipv6_protocol_nht_rmap_cmd); install_element(VIEW_NODE, &show_ipv6_protocol_nht_cmd); - install_element(CONFIG_NODE, &zebra_route_map_timer_cmd); - install_element(CONFIG_NODE, &no_zebra_route_map_timer_cmd); - route_map_init(); + route_map_init_new(true); route_map_add_hook(zebra_route_map_add); route_map_delete_hook(zebra_route_map_delete); @@ -2038,19 +1411,4 @@ void zebra_route_map_init(void) /* */ route_map_install_set(&route_set_src_cmd); - /* */ - install_element(RMAP_NODE, &match_ip_nexthop_prefix_len_cmd); - install_element(RMAP_NODE, &no_match_ip_nexthop_prefix_len_cmd); - install_element(RMAP_NODE, &match_ip_address_prefix_len_cmd); - install_element(RMAP_NODE, &match_ipv6_address_prefix_len_cmd); - install_element(RMAP_NODE, &no_match_ipv6_address_prefix_len_cmd); - install_element(RMAP_NODE, &no_match_ip_address_prefix_len_cmd); - install_element(RMAP_NODE, &match_source_protocol_cmd); - install_element(RMAP_NODE, &no_match_source_protocol_cmd); - install_element(RMAP_NODE, &match_source_instance_cmd); - install_element(RMAP_NODE, &no_match_source_instance_cmd); - - /* */ - install_element(RMAP_NODE, &set_src_cmd); - install_element(RMAP_NODE, &no_set_src_cmd); } diff --git a/zebra/zebra_routemap.h b/zebra/zebra_routemap.h index fceb53c841..2039e80e3a 100644 --- a/zebra/zebra_routemap.h +++ b/zebra/zebra_routemap.h @@ -14,8 +14,6 @@ extern "C" { #endif extern void zebra_route_map_init(void); -extern void zebra_routemap_config_write_protocol(struct vty *vty, - struct zebra_vrf *vrf); extern char *zebra_get_import_table_route_map(afi_t afi, uint32_t table); extern void zebra_add_import_table_route_map(afi_t afi, const char *rmap_name, uint32_t table); @@ -35,6 +33,16 @@ extern route_map_result_t zebra_nht_route_map_check(afi_t afi, int client_proto, struct route_entry *re, struct nexthop *nexthop); +extern void zebra_route_map_set_delay_timer(uint32_t value); +extern int ip_protocol_rm_add(struct zebra_vrf *zvrf, const char *rmap, + int rtype, afi_t afi, safi_t safi); +extern int ip_protocol_rm_del(struct zebra_vrf *zvrf, const char *rmap, + int rtype, afi_t afi, safi_t safi); +extern int ip_nht_rm_add(struct zebra_vrf *zvrf, const char *rmap, int rtype, + int afi); +extern int ip_nht_rm_del(struct zebra_vrf *zvrf, const char *rmap, int rtype, + int afi); + extern void zebra_routemap_vrf_delete(struct zebra_vrf *zvrf); #ifdef __cplusplus diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index 92982f25c8..e464e47b1f 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -450,141 +450,6 @@ struct route_table *zebra_vrf_table(afi_t afi, safi_t safi, vrf_id_t vrf_id) return zvrf->table[afi][safi]; } -static int vrf_config_write(struct vty *vty) -{ - struct vrf *vrf; - struct zebra_vrf *zvrf; - - RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { - zvrf = vrf->info; - - if (!zvrf) - continue; - - if (zvrf_id(zvrf) == VRF_DEFAULT) { - if (zvrf->l3vni) - vty_out(vty, "vni %u%s\n", zvrf->l3vni, - is_l3vni_for_prefix_routes_only( - zvrf->l3vni) - ? " prefix-routes-only" - : ""); - - if (zvrf->zebra_rnh_ip_default_route != - SAVE_ZEBRA_IP_NHT_RESOLVE_VIA_DEFAULT) - vty_out(vty, "%sip nht resolve-via-default\n", - zvrf->zebra_rnh_ip_default_route - ? "" - : "no "); - - if (zvrf->zebra_rnh_ipv6_default_route != - SAVE_ZEBRA_IP_NHT_RESOLVE_VIA_DEFAULT) - vty_out(vty, "%sipv6 nht resolve-via-default\n", - zvrf->zebra_rnh_ipv6_default_route - ? "" - : "no "); - - if (zvrf->tbl_mgr - && (zvrf->tbl_mgr->start || zvrf->tbl_mgr->end)) - vty_out(vty, "ip table range %u %u\n", - zvrf->tbl_mgr->start, - zvrf->tbl_mgr->end); - } else { - vty_frame(vty, "vrf %s\n", zvrf_name(zvrf)); - if (zvrf->l3vni) - vty_out(vty, " vni %u%s\n", zvrf->l3vni, - is_l3vni_for_prefix_routes_only( - zvrf->l3vni) - ? " prefix-routes-only" - : ""); - zebra_ns_config_write(vty, (struct ns *)vrf->ns_ctxt); - if (zvrf->zebra_rnh_ip_default_route != - SAVE_ZEBRA_IP_NHT_RESOLVE_VIA_DEFAULT) - vty_out(vty, " %sip nht resolve-via-default\n", - zvrf->zebra_rnh_ip_default_route - ? "" - : "no "); - - if (zvrf->zebra_rnh_ipv6_default_route != - SAVE_ZEBRA_IP_NHT_RESOLVE_VIA_DEFAULT) - vty_out(vty, " %sipv6 nht resolve-via-default\n", - zvrf->zebra_rnh_ipv6_default_route - ? "" - : "no "); - - if (zvrf->tbl_mgr && vrf_is_backend_netns() - && (zvrf->tbl_mgr->start || zvrf->tbl_mgr->end)) - vty_out(vty, " ip table range %u %u\n", - zvrf->tbl_mgr->start, - zvrf->tbl_mgr->end); - } - - - zebra_routemap_config_write_protocol(vty, zvrf); - router_id_write(vty, zvrf); - - if (zvrf_id(zvrf) != VRF_DEFAULT) - vty_endframe(vty, "exit-vrf\n!\n"); - else - vty_out(vty, "!\n"); - } - return 0; -} - -DEFPY (vrf_netns, - vrf_netns_cmd, - "netns NAME$netns_name", - "Attach VRF to a Namespace\n" - "The file name in " NS_RUN_DIR ", or a full pathname\n") -{ - char *pathname = ns_netns_pathname(vty, netns_name); - int ret; - - VTY_DECLVAR_CONTEXT(vrf, vrf); - - if (!pathname) - return CMD_WARNING_CONFIG_FAILED; - - frr_with_privs(&zserv_privs) { - ret = zebra_vrf_netns_handler_create( - vty, vrf, pathname, NS_UNKNOWN, NS_UNKNOWN, NS_UNKNOWN); - } - - return ret; -} - -DEFUN (no_vrf_netns, - no_vrf_netns_cmd, - "no netns [NAME]", - NO_STR - "Detach VRF from a Namespace\n" - "The file name in " NS_RUN_DIR ", or a full pathname\n") -{ - struct ns *ns = NULL; - - VTY_DECLVAR_CONTEXT(vrf, vrf); - - if (!vrf_is_backend_netns()) { - vty_out(vty, "VRF backend is not Netns. Aborting\n"); - return CMD_WARNING_CONFIG_FAILED; - } - if (!vrf->ns_ctxt) { - vty_out(vty, "VRF %s(%u) is not configured with NetNS\n", - vrf->name, vrf->vrf_id); - return CMD_WARNING_CONFIG_FAILED; - } - - ns = (struct ns *)vrf->ns_ctxt; - - ns->vrf_ctxt = NULL; - vrf_disable(vrf); - /* vrf ID from VRF is necessary for Zebra - * so that propagate to other clients is done - */ - ns_delete(ns); - vrf->ns_ctxt = NULL; - return CMD_SUCCESS; -} - /* if ns_id is different and not VRF_UNKNOWN, * then update vrf identifier, and enable VRF */ @@ -683,12 +548,4 @@ void zebra_vrf_init(void) zebra_vrf_delete); hook_register(zserv_client_close, release_daemon_table_chunks); - - vrf_cmd_init(vrf_config_write); - - if (vrf_is_backend_netns() && ns_have_netns()) { - /* Install NS commands. */ - install_element(VRF_NODE, &vrf_netns_cmd); - install_element(VRF_NODE, &no_vrf_netns_cmd); - } } diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index b778b39508..70b71fe707 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -51,6 +51,7 @@ #include "zebra/zebra_script.h" #include "zebra/rtadv.h" #include "zebra/zebra_neigh.h" +#include "zebra/zebra_ptm.h" /* context to manage dumps in multiple tables or vrfs */ struct route_show_ctx { @@ -1163,27 +1164,6 @@ DEFPY (show_ip_nht, return CMD_SUCCESS; } -DEFUN (ip_nht_default_route, - ip_nht_default_route_cmd, - "ip nht resolve-via-default", - IP_STR - "Filter Next Hop tracking route resolution\n" - "Resolve via default route\n") -{ - ZEBRA_DECLVAR_CONTEXT_VRF(vrf, zvrf); - - if (!zvrf) - return CMD_WARNING; - - if (zvrf->zebra_rnh_ip_default_route) - return CMD_SUCCESS; - - zvrf->zebra_rnh_ip_default_route = true; - - zebra_evaluate_rnh(zvrf, AFI_IP, 0, NULL, SAFI_UNICAST); - return CMD_SUCCESS; -} - static void show_nexthop_group_out(struct vty *vty, struct nhg_hash_entry *nhe, json_object *json_nhe_hdr) { @@ -1682,68 +1662,6 @@ DEFPY_HIDDEN(backup_nexthop_recursive_use_enable, return CMD_SUCCESS; } -DEFUN (no_ip_nht_default_route, - no_ip_nht_default_route_cmd, - "no ip nht resolve-via-default", - NO_STR - IP_STR - "Filter Next Hop tracking route resolution\n" - "Resolve via default route\n") -{ - ZEBRA_DECLVAR_CONTEXT_VRF(vrf, zvrf); - - if (!zvrf) - return CMD_WARNING; - - if (!zvrf->zebra_rnh_ip_default_route) - return CMD_SUCCESS; - - zvrf->zebra_rnh_ip_default_route = false; - zebra_evaluate_rnh(zvrf, AFI_IP, 0, NULL, SAFI_UNICAST); - return CMD_SUCCESS; -} - -DEFUN (ipv6_nht_default_route, - ipv6_nht_default_route_cmd, - "ipv6 nht resolve-via-default", - IP6_STR - "Filter Next Hop tracking route resolution\n" - "Resolve via default route\n") -{ - ZEBRA_DECLVAR_CONTEXT_VRF(vrf, zvrf); - - if (!zvrf) - return CMD_WARNING; - - if (zvrf->zebra_rnh_ipv6_default_route) - return CMD_SUCCESS; - - zvrf->zebra_rnh_ipv6_default_route = true; - zebra_evaluate_rnh(zvrf, AFI_IP6, 0, NULL, SAFI_UNICAST); - return CMD_SUCCESS; -} - -DEFUN (no_ipv6_nht_default_route, - no_ipv6_nht_default_route_cmd, - "no ipv6 nht resolve-via-default", - NO_STR - IP6_STR - "Filter Next Hop tracking route resolution\n" - "Resolve via default route\n") -{ - ZEBRA_DECLVAR_CONTEXT_VRF(vrf, zvrf); - - if (!zvrf) - return CMD_WARNING; - - if (!zvrf->zebra_rnh_ipv6_default_route) - return CMD_SUCCESS; - - zvrf->zebra_rnh_ipv6_default_route = false; - zebra_evaluate_rnh(zvrf, AFI_IP6, 0, NULL, SAFI_UNICAST); - return CMD_SUCCESS; -} - DEFPY_HIDDEN(rnh_hide_backups, rnh_hide_backups_cmd, "[no] ip nht hide-backup-events", NO_STR @@ -2727,146 +2645,6 @@ DEFPY(evpn_mh_redirect_off, evpn_mh_redirect_off_cmd, return zebra_evpn_mh_redirect_off(vty, redirect_off); } -DEFUN (default_vrf_vni_mapping, - default_vrf_vni_mapping_cmd, - "vni " CMD_VNI_RANGE "[prefix-routes-only]", - "VNI corresponding to the DEFAULT VRF\n" - "VNI-ID\n" - "Prefix routes only \n") -{ - char xpath[XPATH_MAXLEN]; - int filter = 0; - - if (argc == 3) - filter = 1; - - snprintf(xpath, sizeof(xpath), FRR_VRF_KEY_XPATH "/frr-zebra:zebra", - VRF_DEFAULT_NAME); - nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); - - snprintf(xpath, sizeof(xpath), - FRR_VRF_KEY_XPATH "/frr-zebra:zebra/l3vni-id", - VRF_DEFAULT_NAME); - nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, argv[1]->arg); - - if (filter) { - snprintf(xpath, sizeof(xpath), - FRR_VRF_KEY_XPATH "/frr-zebra:zebra/prefix-only", - VRF_DEFAULT_NAME); - nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, "true"); - } - - return nb_cli_apply_changes(vty, NULL); -} - -DEFUN (no_default_vrf_vni_mapping, - no_default_vrf_vni_mapping_cmd, - "no vni " CMD_VNI_RANGE "[prefix-routes-only]", - NO_STR - "VNI corresponding to DEFAULT VRF\n" - "VNI-ID\n" - "Prefix routes only \n") -{ - char xpath[XPATH_MAXLEN]; - int filter = 0; - vni_t vni = strtoul(argv[2]->arg, NULL, 10); - struct zebra_vrf *zvrf = NULL; - - zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT); - - if (argc == 4) - filter = 1; - - if (zvrf->l3vni != vni) { - vty_out(vty, "VNI %d doesn't exist in VRF: %s \n", vni, - zvrf->vrf->name); - return CMD_WARNING; - } - - snprintf(xpath, sizeof(xpath), - FRR_VRF_KEY_XPATH "/frr-zebra:zebra/l3vni-id", - VRF_DEFAULT_NAME); - nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, argv[2]->arg); - - if (filter) { - snprintf(xpath, sizeof(xpath), - FRR_VRF_KEY_XPATH "/frr-zebra:zebra/prefix-only", - VRF_DEFAULT_NAME); - nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, "true"); - } - - snprintf(xpath, sizeof(xpath), FRR_VRF_KEY_XPATH "/frr-zebra:zebra", - VRF_DEFAULT_NAME); - nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); - - return nb_cli_apply_changes(vty, NULL); -} - -DEFUN (vrf_vni_mapping, - vrf_vni_mapping_cmd, - "vni " CMD_VNI_RANGE "[prefix-routes-only]", - "VNI corresponding to tenant VRF\n" - "VNI-ID\n" - "prefix-routes-only\n") -{ - int filter = 0; - - ZEBRA_DECLVAR_CONTEXT_VRF(vrf, zvrf); - - assert(vrf); - assert(zvrf); - - if (argc == 3) - filter = 1; - - nb_cli_enqueue_change(vty, "./frr-zebra:zebra", NB_OP_CREATE, NULL); - nb_cli_enqueue_change(vty, "./frr-zebra:zebra/l3vni-id", NB_OP_MODIFY, - argv[1]->arg); - - if (filter) - nb_cli_enqueue_change(vty, "./frr-zebra:zebra/prefix-only", - NB_OP_MODIFY, "true"); - - return nb_cli_apply_changes(vty, NULL); -} - -DEFUN (no_vrf_vni_mapping, - no_vrf_vni_mapping_cmd, - "no vni " CMD_VNI_RANGE "[prefix-routes-only]", - NO_STR - "VNI corresponding to tenant VRF\n" - "VNI-ID\n" - "prefix-routes-only\n") -{ - int filter = 0; - - ZEBRA_DECLVAR_CONTEXT_VRF(vrf, zvrf); - vni_t vni = strtoul(argv[2]->arg, NULL, 10); - - assert(vrf); - assert(zvrf); - - if (argc == 4) - filter = 1; - - if (zvrf->l3vni != vni) { - vty_out(vty, "VNI %d doesn't exist in VRF: %s \n", vni, - zvrf->vrf->name); - return CMD_WARNING; - } - - nb_cli_enqueue_change(vty, "./frr-zebra:zebra/l3vni-id", NB_OP_DESTROY, - argv[2]->arg); - - if (filter) - nb_cli_enqueue_change(vty, "./frr-zebra:zebra/prefix-only", - NB_OP_DESTROY, "true"); - - nb_cli_enqueue_change(vty, "./frr-zebra:zebra", NB_OP_DESTROY, NULL); - - return nb_cli_apply_changes(vty, NULL); -} - /* show vrf */ DEFPY (show_vrf_vni, show_vrf_vni_cmd, @@ -4498,31 +4276,6 @@ DEFPY (no_zebra_protodown_bit, #endif /* HAVE_NETLINK */ -DEFUN(ip_table_range, ip_table_range_cmd, - "[no] ip table range (1-4294967295) (1-4294967295)", - NO_STR IP_STR - "table configuration\n" - "Configure table range\n" - "Start Routing Table\n" - "End Routing Table\n") -{ - ZEBRA_DECLVAR_CONTEXT_VRF(vrf, zvrf); - - if (!zvrf) - return CMD_WARNING; - - if (zvrf_id(zvrf) != VRF_DEFAULT && !vrf_is_backend_netns()) { - vty_out(vty, - "VRF subcommand does not make any sense in l3mdev based vrf's\n"); - return CMD_WARNING; - } - - if (strmatch(argv[0]->text, "no")) - return table_manager_range(vty, false, zvrf, NULL, NULL); - - return table_manager_range(vty, true, zvrf, argv[3]->arg, argv[4]->arg); -} - #ifdef HAVE_SCRIPTING DEFUN(zebra_on_rib_process_script, zebra_on_rib_process_script_cmd, @@ -4634,14 +4387,6 @@ void zebra_vty_init(void) install_element(VIEW_NODE, &show_ip_rpf_addr_cmd); install_element(VIEW_NODE, &show_ipv6_rpf_addr_cmd); - install_element(CONFIG_NODE, &ip_nht_default_route_cmd); - install_element(CONFIG_NODE, &no_ip_nht_default_route_cmd); - install_element(CONFIG_NODE, &ipv6_nht_default_route_cmd); - install_element(CONFIG_NODE, &no_ipv6_nht_default_route_cmd); - install_element(VRF_NODE, &ip_nht_default_route_cmd); - install_element(VRF_NODE, &no_ip_nht_default_route_cmd); - install_element(VRF_NODE, &ipv6_nht_default_route_cmd); - install_element(VRF_NODE, &no_ipv6_nht_default_route_cmd); install_element(CONFIG_NODE, &rnh_hide_backups_cmd); install_element(VIEW_NODE, &show_frr_cmd); @@ -4693,19 +4438,12 @@ void zebra_vty_init(void) install_element(CONFIG_NODE, &evpn_mh_neigh_holdtime_cmd); install_element(CONFIG_NODE, &evpn_mh_startup_delay_cmd); install_element(CONFIG_NODE, &evpn_mh_redirect_off_cmd); - install_element(CONFIG_NODE, &default_vrf_vni_mapping_cmd); - install_element(CONFIG_NODE, &no_default_vrf_vni_mapping_cmd); - install_element(VRF_NODE, &vrf_vni_mapping_cmd); - install_element(VRF_NODE, &no_vrf_vni_mapping_cmd); install_element(VIEW_NODE, &show_dataplane_cmd); install_element(VIEW_NODE, &show_dataplane_providers_cmd); install_element(CONFIG_NODE, &zebra_dplane_queue_limit_cmd); install_element(CONFIG_NODE, &no_zebra_dplane_queue_limit_cmd); - install_element(CONFIG_NODE, &ip_table_range_cmd); - install_element(VRF_NODE, &ip_table_range_cmd); - #ifdef HAVE_NETLINK install_element(CONFIG_NODE, &zebra_kernel_netlink_batch_tx_buf_cmd); install_element(CONFIG_NODE, &no_zebra_kernel_netlink_batch_tx_buf_cmd); diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 7d0c82a437..f0401d02a5 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -5174,9 +5174,8 @@ void zebra_vxlan_macvlan_up(struct interface *ifp) } } -int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf *zvrf, vni_t vni, - char *err, int err_str_sz, int filter, - int add) +void zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf *zvrf, vni_t vni, + int filter, int add) { struct zebra_l3vni *zl3vni = NULL; struct zebra_vrf *zvrf_evpn = NULL; @@ -5188,21 +5187,6 @@ int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf *zvrf, vni_t vni, add ? "ADD" : "DEL"); if (add) { - /* check if the vni is already present under zvrf */ - if (zvrf->l3vni) { - snprintf(err, err_str_sz, - "VNI is already configured under the vrf"); - return -1; - } - - /* check if this VNI is already present in the system */ - zl3vni = zl3vni_lookup(vni); - if (zl3vni) { - snprintf(err, err_str_sz, - "VNI is already configured as L3-VNI"); - return -1; - } - /* Remove L2VNI if present */ zebra_vxlan_handle_vni_transition(zvrf, vni, add); @@ -5248,23 +5232,7 @@ int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf *zvrf, vni_t vni, } else { zl3vni = zl3vni_lookup(vni); - if (!zl3vni) { - snprintf(err, err_str_sz, "VNI doesn't exist"); - return -1; - } - - if (zvrf->l3vni != vni) { - snprintf(err, err_str_sz, - "VNI %d doesn't exist in VRF: %s", - vni, zvrf->vrf->name); - return -1; - } - - if (filter && !CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY)) { - snprintf(err, ERR_STR_SZ, - "prefix-routes-only is not set for the vni"); - return -1; - } + assert(zl3vni); zebra_vxlan_process_l3vni_oper_down(zl3vni); @@ -5282,7 +5250,6 @@ int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf *zvrf, vni_t vni, /* Add L2VNI for this VNI */ zebra_vxlan_handle_vni_transition(zvrf, vni, add); } - return 0; } int zebra_vxlan_vrf_enable(struct zebra_vrf *zvrf) diff --git a/zebra/zebra_vxlan.h b/zebra/zebra_vxlan.h index 5785e0b3c3..eb02de6f7b 100644 --- a/zebra/zebra_vxlan.h +++ b/zebra/zebra_vxlan.h @@ -178,9 +178,8 @@ extern int zebra_vxlan_if_add(struct interface *ifp); extern int zebra_vxlan_if_update(struct interface *ifp, struct zebra_vxlan_if_update_ctx *ctx); extern int zebra_vxlan_if_del(struct interface *ifp); -extern int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf *zvrf, vni_t vni, - char *err, int err_str_sz, - int filter, int add); +extern void zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf *zvrf, vni_t vni, + int filter, int add); extern void zebra_vxlan_init_tables(struct zebra_vrf *zvrf); extern void zebra_vxlan_close_tables(struct zebra_vrf *); extern void zebra_vxlan_cleanup_tables(struct zebra_vrf *); |
