summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--yang/frr-zebra.yang27
-rw-r--r--zebra/rtadv.c112
-rw-r--r--zebra/rtadv.h6
-rw-r--r--zebra/zebra_nb.c14
-rw-r--r--zebra/zebra_nb.h8
-rw-r--r--zebra/zebra_nb_config.c79
6 files changed, 159 insertions, 87 deletions
diff --git a/yang/frr-zebra.yang b/yang/frr-zebra.yang
index 66107d1a19..c540e922dc 100644
--- a/yang/frr-zebra.yang
+++ b/yang/frr-zebra.yang
@@ -2607,6 +2607,33 @@ module frr-zebra {
// `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 state {
config false;
diff --git a/zebra/rtadv.c b/zebra/rtadv.c
index 04ae248f86..9958a690b7 100644
--- a/zebra/rtadv.c
+++ b/zebra/rtadv.c
@@ -1928,55 +1928,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)
-{
- 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)
+void rtadv_rdnss_reset(struct zebra_if *zif, struct rtadv_rdnss *p)
{
- 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)
@@ -2078,41 +2045,9 @@ static int rtadv_dnssl_encode(uint8_t *out, const char *in)
return outp;
}
-DEFUN(ipv6_nd_rdnss,
+DEFPY_YANG (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] ipv6 nd rdnss X:X::X:X$addr [<(0-4294967295)|infinite>]$lifetime",
NO_STR
"Interface IPv6 config commands\n"
"Neighbor discovery\n"
@@ -2121,20 +2056,24 @@ DEFUN(no_ipv6_nd_rdnss,
"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;
+ 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/rdnss/rdnss-address[address='%s']",
+ addr_str);
}
DEFUN(ipv6_nd_dnssl,
@@ -2586,7 +2525,6 @@ void rtadv_cmd_init(void)
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, &no_ipv6_nd_rdnss_cmd);
install_element(INTERFACE_NODE, &ipv6_nd_dnssl_cmd);
install_element(INTERFACE_NODE, &no_ipv6_nd_dnssl_cmd);
}
diff --git a/zebra/rtadv.h b/zebra/rtadv.h
index 8c43465132..64f1cb2f88 100644
--- a/zebra/rtadv.h
+++ b/zebra/rtadv.h
@@ -392,6 +392,12 @@ struct rtadv_prefix *rtadv_add_prefix_manual(struct zebra_if *zif,
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);
+
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 40a4ee4a02..bbdf0536fc 100644
--- a/zebra/zebra_nb.c
+++ b/zebra/zebra_nb.c
@@ -678,6 +678,20 @@ const struct frr_yang_module_info frr_zebra_info = {
}
},
{
+ .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,
+ }
+ },
+ {
.xpath = "/frr-interface:lib/interface/frr-zebra:zebra/state/up-count",
.cbs = {
.get_elem = lib_interface_zebra_state_up_count_get_elem,
diff --git a/zebra/zebra_nb.h b/zebra/zebra_nb.h
index d831a249d1..d1312b85a4 100644
--- a/zebra/zebra_nb.h
+++ b/zebra/zebra_nb.h
@@ -233,6 +233,14 @@ int lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_autonomous
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);
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 2fc42cc0d9..8130a13c26 100644
--- a/zebra/zebra_nb_config.c
+++ b/zebra/zebra_nb_config.c
@@ -3008,6 +3008,85 @@ int lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_router_add
}
/*
+ * 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-vrf:lib/vrf/frr-zebra:zebra/l3vni-id
*/
int lib_vrf_zebra_l3vni_id_modify(struct nb_cb_modify_args *args)