Skip to content

Commit

Permalink
zebra: convert interface ipv6 nd dnssl command to NB
Browse files Browse the repository at this point in the history
Signed-off-by: Igor Ryzhov <[email protected]>
  • Loading branch information
idryzhov committed Jan 23, 2024
1 parent 66a51b6 commit b09bc3d
Show file tree
Hide file tree
Showing 6 changed files with 179 additions and 96 deletions.
26 changes: 26 additions & 0 deletions yang/frr-zebra.yang
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
125 changes: 29 additions & 96 deletions zebra/rtadv.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

/*
Expand All @@ -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;
Expand Down Expand Up @@ -2076,23 +2044,21 @@ 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"
"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 = {};
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;
Expand All @@ -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);
}


Expand Down Expand Up @@ -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)
Expand Down
7 changes: 7 additions & 0 deletions zebra/rtadv.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
14 changes: 14 additions & 0 deletions zebra/zebra_nb.c
Original file line number Diff line number Diff line change
Expand Up @@ -647,6 +647,20 @@ const struct frr_yang_module_info frr_zebra_info = {
.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 = {
Expand Down
8 changes: 8 additions & 0 deletions zebra/zebra_nb.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 *
Expand Down
95 changes: 95 additions & 0 deletions zebra/zebra_nb_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -3086,6 +3086,101 @@ int lib_interface_zebra_ipv6_router_advertisements_rdnss_rdnss_address_lifetime_
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 (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
*/
Expand Down

0 comments on commit b09bc3d

Please sign in to comment.