zebra: convert interface ipv6 nd rdnss command to NB

Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
This commit is contained in:
Igor Ryzhov 2024-01-23 22:14:53 +02:00
parent 36131494c2
commit 61c7ba7557
6 changed files with 159 additions and 87 deletions

View File

@ -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;

View File

@ -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)
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)
@ -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 (!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);
}
if (rtadv_rdnss_reset(zif, &rdnss) != 1) {
vty_out(vty, "Non-existant RDNSS address\n");
return CMD_WARNING_CONFIG_FAILED;
}
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);
}

View File

@ -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);

View File

@ -677,6 +677,20 @@ const struct frr_yang_module_info frr_zebra_info = {
.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,
}
},
{
.xpath = "/frr-interface:lib/interface/frr-zebra:zebra/state/up-count",
.cbs = {

View File

@ -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 *

View File

@ -3007,6 +3007,85 @@ int lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_router_add
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-vrf:lib/vrf/frr-zebra:zebra/l3vni-id
*/