summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--yang/frr-zebra.yang26
-rw-r--r--zebra/rtadv.c125
-rw-r--r--zebra/rtadv.h7
-rw-r--r--zebra/zebra_nb.c14
-rw-r--r--zebra/zebra_nb.h8
-rw-r--r--zebra/zebra_nb_config.c91
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)