diff options
author | Igor Ryzhov <iryzhov@nfware.com> | 2024-01-23 22:00:45 +0100 |
---|---|---|
committer | Igor Ryzhov <iryzhov@nfware.com> | 2024-01-28 22:28:40 +0100 |
commit | 27c21ffd94788744bc0c647430c5096e1c29e9ce (patch) | |
tree | 118220090ed3c32c3513592dd0f429eb6dd3ba27 | |
parent | zebra: convert interface ipv6 nd rdnss command to NB (diff) | |
download | frr-27c21ffd94788744bc0c647430c5096e1c29e9ce.tar.xz frr-27c21ffd94788744bc0c647430c5096e1c29e9ce.zip |
zebra: convert interface ipv6 nd dnssl command to NB
Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
-rw-r--r-- | yang/frr-zebra.yang | 26 | ||||
-rw-r--r-- | zebra/rtadv.c | 125 | ||||
-rw-r--r-- | zebra/rtadv.h | 7 | ||||
-rw-r--r-- | zebra/zebra_nb.c | 14 | ||||
-rw-r--r-- | zebra/zebra_nb.h | 8 | ||||
-rw-r--r-- | zebra/zebra_nb_config.c | 91 |
6 files changed, 175 insertions, 96 deletions
diff --git a/yang/frr-zebra.yang b/yang/frr-zebra.yang index c540e922d..2d3523c48 100644 --- a/yang/frr-zebra.yang +++ b/yang/frr-zebra.yang @@ -2634,6 +2634,32 @@ module frr-zebra { } } } + 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."; + } + } + } } container state { config false; diff --git a/zebra/rtadv.c b/zebra/rtadv.c index 9958a690b..5d3c474ee 100644 --- a/zebra/rtadv.c +++ b/zebra/rtadv.c @@ -1956,54 +1956,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); } /* @@ -2014,7 +1982,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; @@ -2076,9 +2044,10 @@ DEFPY_YANG (ipv6_nd_rdnss, addr_str); } -DEFUN(ipv6_nd_dnssl, +DEFPY_YANG (ipv6_nd_dnssl, ipv6_nd_dnssl_cmd, - "ipv6 nd dnssl SUFFIX [<(0-4294967295)|infinite>]", + "[no] ipv6 nd dnssl SUFFIX [<(0-4294967295)|infinite>]$lifetime", + NO_STR "Interface IPv6 config commands\n" "Neighbor discovery\n" "DNS search list information\n" @@ -2086,13 +2055,10 @@ DEFUN(ipv6_nd_dnssl, "Valid lifetime in seconds\n" "Infinite valid lifetime\n") { - VTY_DECLVAR_CONTEXT(interface, ifp); - struct zebra_if *zif = ifp->info; - struct rtadv_dnssl dnssl = {}; + struct rtadv_dnssl dnssl; size_t len; - int ret; - len = strlcpy(dnssl.name, argv[3]->arg, sizeof(dnssl.name)); + len = strlcpy(dnssl.name, suffix, sizeof(dnssl.name)); if (len == 0 || len >= sizeof(dnssl.name)) { vty_out(vty, "Malformed DNS search domain\n"); return CMD_WARNING_CONFIG_FAILED; @@ -2105,57 +2071,25 @@ DEFUN(ipv6_nd_dnssl, 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; + 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 CMD_SUCCESS; + return nb_cli_apply_changes( + vty, + "./frr-zebra:zebra/ipv6-router-advertisements/dnssl/dnssl-domain[domain='%s']", + dnssl.name); } @@ -2526,7 +2460,6 @@ void rtadv_cmd_init(void) install_element(INTERFACE_NODE, &ipv6_nd_mtu_cmd); install_element(INTERFACE_NODE, &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 64f1cb2f8..0983ea578 100644 --- a/zebra/rtadv.h +++ b/zebra/rtadv.h @@ -398,6 +398,13 @@ struct rtadv_rdnss *rtadv_rdnss_set(struct zebra_if *zif, /* 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); diff --git a/zebra/zebra_nb.c b/zebra/zebra_nb.c index bbdf0536f..e4d887140 100644 --- a/zebra/zebra_nb.c +++ b/zebra/zebra_nb.c @@ -648,6 +648,20 @@ const struct frr_yang_module_info frr_zebra_info = { } }, { + .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, diff --git a/zebra/zebra_nb.h b/zebra/zebra_nb.h index d1312b85a..5f29d0d5d 100644 --- a/zebra/zebra_nb.h +++ b/zebra/zebra_nb.h @@ -241,6 +241,14 @@ int lib_interface_zebra_ipv6_router_advertisements_rdnss_rdnss_address_lifetime_ 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); struct yang_data * lib_interface_zebra_state_up_count_get_elem(struct nb_cb_get_elem_args *args); struct yang_data * diff --git a/zebra/zebra_nb_config.c b/zebra/zebra_nb_config.c index 8130a13c2..db93e41ea 100644 --- a/zebra/zebra_nb_config.c +++ b/zebra/zebra_nb_config.c @@ -3087,6 +3087,97 @@ int lib_interface_zebra_ipv6_router_advertisements_rdnss_rdnss_address_lifetime_ } /* + * 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 (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; +} + +/* * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/l3vni-id */ int lib_vrf_zebra_l3vni_id_modify(struct nb_cb_modify_args *args) |