summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorflorian <florian@openbsd.org>2018-07-15 09:28:21 +0000
committerflorian <florian@openbsd.org>2018-07-15 09:28:21 +0000
commit4c40b7e8ed0a313f15b06f9a298049cf3842ca3b (patch)
treefc09616e382c96412e85d8d9bd7db726f6dd0aa3
parentmark up managed / other configuration (diff)
downloadwireguard-openbsd-4c40b7e8ed0a313f15b06f9a298049cf3842ca3b.tar.xz
wireguard-openbsd-4c40b7e8ed0a313f15b06f9a298049cf3842ca3b.zip
Implement RFC 8106: IPv6 Router Advertisement Options for DNS
Configuration.
-rw-r--r--usr.sbin/rad/engine.c30
-rw-r--r--usr.sbin/rad/frontend.c86
-rw-r--r--usr.sbin/rad/parse.y96
-rw-r--r--usr.sbin/rad/printconf.c28
-rw-r--r--usr.sbin/rad/rad.c20
-rw-r--r--usr.sbin/rad/rad.conf.522
-rw-r--r--usr.sbin/rad/rad.h35
7 files changed, 300 insertions, 17 deletions
diff --git a/usr.sbin/rad/engine.c b/usr.sbin/rad/engine.c
index 9ecb93da44b..5d186439dd8 100644
--- a/usr.sbin/rad/engine.c
+++ b/usr.sbin/rad/engine.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: engine.c,v 1.6 2018/07/11 19:05:25 florian Exp $ */
+/* $OpenBSD: engine.c,v 1.7 2018/07/15 09:28:21 florian Exp $ */
/*
* Copyright (c) 2018 Florian Obser <florian@openbsd.org>
@@ -43,9 +43,6 @@
#include "rad.h"
#include "engine.h"
-#define MAX_RTR_ADV_INTERVAL 600
-#define MIN_RTR_ADV_INTERVAL 200
-
struct engine_iface {
TAILQ_ENTRY(engine_iface) entry;
struct event timer;
@@ -267,6 +264,8 @@ engine_dispatch_main(int fd, short event, void *bula)
struct imsgev *iev = bula;
struct imsgbuf *ibuf;
struct ra_prefix_conf *ra_prefix_conf;
+ struct ra_rdnss_conf *ra_rdnss_conf;
+ struct ra_dnssl_conf *ra_dnssl_conf;
ssize_t n;
int shut = 0;
@@ -335,6 +334,8 @@ engine_dispatch_main(int fd, short event, void *bula)
sizeof(struct ra_iface_conf));
ra_iface_conf->autoprefix = NULL;
SIMPLEQ_INIT(&ra_iface_conf->ra_prefix_list);
+ SIMPLEQ_INIT(&ra_iface_conf->ra_rdnss_list);
+ SIMPLEQ_INIT(&ra_iface_conf->ra_dnssl_list);
SIMPLEQ_INSERT_TAIL(&nconf->ra_iface_list,
ra_iface_conf, entry);
break;
@@ -354,6 +355,27 @@ engine_dispatch_main(int fd, short event, void *bula)
SIMPLEQ_INSERT_TAIL(&ra_iface_conf->ra_prefix_list,
ra_prefix_conf, entry);
break;
+ case IMSG_RECONF_RA_RDNS_LIFETIME:
+ ra_iface_conf->rdns_lifetime = *((uint32_t *)imsg.data);
+ break;
+ case IMSG_RECONF_RA_RDNSS:
+ if ((ra_rdnss_conf = malloc(sizeof(struct
+ ra_rdnss_conf))) == NULL)
+ fatal(NULL);
+ memcpy(ra_rdnss_conf, imsg.data, sizeof(struct
+ ra_rdnss_conf));
+ SIMPLEQ_INSERT_TAIL(&ra_iface_conf->ra_rdnss_list,
+ ra_rdnss_conf, entry);
+ break;
+ case IMSG_RECONF_RA_DNSSL:
+ if ((ra_dnssl_conf = malloc(sizeof(struct
+ ra_dnssl_conf))) == NULL)
+ fatal(NULL);
+ memcpy(ra_dnssl_conf, imsg.data, sizeof(struct
+ ra_dnssl_conf));
+ SIMPLEQ_INSERT_TAIL(&ra_iface_conf->ra_dnssl_list,
+ ra_dnssl_conf, entry);
+ break;
case IMSG_RECONF_END:
merge_config(engine_conf, nconf);
nconf = NULL;
diff --git a/usr.sbin/rad/frontend.c b/usr.sbin/rad/frontend.c
index 2fa5d7c34dd..c9d2c8e3ddb 100644
--- a/usr.sbin/rad/frontend.c
+++ b/usr.sbin/rad/frontend.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: frontend.c,v 1.9 2018/07/15 09:26:26 florian Exp $ */
+/* $OpenBSD: frontend.c,v 1.10 2018/07/15 09:28:21 florian Exp $ */
/*
* Copyright (c) 2018 Florian Obser <florian@openbsd.org>
@@ -308,6 +308,8 @@ frontend_dispatch_main(int fd, short event, void *bula)
struct imsgev *iev = bula;
struct imsgbuf *ibuf = &iev->ibuf;
struct ra_prefix_conf *ra_prefix_conf;
+ struct ra_rdnss_conf *ra_rdnss_conf;
+ struct ra_dnssl_conf *ra_dnssl_conf;
int n, shut = 0;
if (event & EV_READ) {
@@ -374,6 +376,8 @@ frontend_dispatch_main(int fd, short event, void *bula)
ra_iface_conf));
ra_iface_conf->autoprefix = NULL;
SIMPLEQ_INIT(&ra_iface_conf->ra_prefix_list);
+ SIMPLEQ_INIT(&ra_iface_conf->ra_rdnss_list);
+ SIMPLEQ_INIT(&ra_iface_conf->ra_dnssl_list);
SIMPLEQ_INSERT_TAIL(&nconf->ra_iface_list,
ra_iface_conf, entry);
break;
@@ -393,6 +397,27 @@ frontend_dispatch_main(int fd, short event, void *bula)
SIMPLEQ_INSERT_TAIL(&ra_iface_conf->ra_prefix_list,
ra_prefix_conf, entry);
break;
+ case IMSG_RECONF_RA_RDNS_LIFETIME:
+ ra_iface_conf->rdns_lifetime = *((uint32_t *)imsg.data);
+ break;
+ case IMSG_RECONF_RA_RDNSS:
+ if ((ra_rdnss_conf = malloc(sizeof(struct
+ ra_rdnss_conf))) == NULL)
+ fatal(NULL);
+ memcpy(ra_rdnss_conf, imsg.data, sizeof(struct
+ ra_rdnss_conf));
+ SIMPLEQ_INSERT_TAIL(&ra_iface_conf->ra_rdnss_list,
+ ra_rdnss_conf, entry);
+ break;
+ case IMSG_RECONF_RA_DNSSL:
+ if ((ra_dnssl_conf = malloc(sizeof(struct
+ ra_dnssl_conf))) == NULL)
+ fatal(NULL);
+ memcpy(ra_dnssl_conf, imsg.data, sizeof(struct
+ ra_dnssl_conf));
+ SIMPLEQ_INSERT_TAIL(&ra_iface_conf->ra_dnssl_list,
+ ra_dnssl_conf, entry);
+ break;
case IMSG_RECONF_END:
merge_config(frontend_conf, nconf);
merge_ra_interfaces();
@@ -866,8 +891,13 @@ build_packet(struct ra_iface *ra_iface)
struct ra_iface_conf *ra_iface_conf;
struct ra_options_conf *ra_options_conf;
struct ra_prefix_conf *ra_prefix_conf;
- size_t len;
+ struct nd_opt_rdnss *ndopt_rdnss;
+ struct nd_opt_dnssl *ndopt_dnssl;
+ struct ra_rdnss_conf *ra_rdnss;
+ struct ra_dnssl_conf *ra_dnssl;
+ size_t len, label_len;
uint8_t *p, buf[RA_MAX_SIZE];
+ char *label_start, *label_end;
ra_iface_conf = find_ra_iface_conf(&frontend_conf->ra_iface_list,
ra_iface->name);
@@ -875,6 +905,14 @@ build_packet(struct ra_iface *ra_iface)
len = sizeof(*ra);
len += sizeof(*ndopt_pi) * ra_iface->prefix_count;
+ if (ra_iface_conf->rdnss_count > 0)
+ len += sizeof(*ndopt_rdnss) + ra_iface_conf->rdnss_count *
+ sizeof(struct in6_addr);
+
+ if (ra_iface_conf->dnssl_len > 0)
+ /* round up to 8 byte boundary */
+ len += sizeof(*ndopt_dnssl) + ((ra_iface_conf->dnssl_len + 7)
+ & ~7);
if (len > sizeof(ra_iface->data))
fatal("%s: packet too big", __func__); /* XXX send multiple */
@@ -922,6 +960,50 @@ build_packet(struct ra_iface *ra_iface)
p += sizeof(*ndopt_pi);
}
+ if (ra_iface_conf->rdnss_count > 0) {
+ ndopt_rdnss = (struct nd_opt_rdnss *)p;
+ ndopt_rdnss->nd_opt_rdnss_type = ND_OPT_RDNSS;
+ ndopt_rdnss->nd_opt_rdnss_len = 1 +
+ ra_iface_conf->rdnss_count * 2;
+ ndopt_rdnss->nd_opt_rdnss_reserved = 0;
+ ndopt_rdnss->nd_opt_rdnss_lifetime =
+ htonl(ra_iface_conf->rdns_lifetime);
+ p += sizeof(struct nd_opt_rdnss);
+ SIMPLEQ_FOREACH(ra_rdnss, &ra_iface_conf->ra_rdnss_list,
+ entry) {
+ memcpy(p, &ra_rdnss->rdnss, sizeof(ra_rdnss->rdnss));
+ p += sizeof(ra_rdnss->rdnss);
+ }
+ }
+
+ if (ra_iface_conf->dnssl_len > 0) {
+ ndopt_dnssl = (struct nd_opt_dnssl *)p;
+ ndopt_dnssl->nd_opt_dnssl_type = ND_OPT_DNSSL;
+ /* round up to 8 byte boundary */
+ ndopt_dnssl->nd_opt_dnssl_len = 1 +
+ ((ra_iface_conf->dnssl_len + 7) & ~7) / 8;
+ ndopt_dnssl->nd_opt_dnssl_reserved = 0;
+ ndopt_dnssl->nd_opt_dnssl_lifetime =
+ htonl(ra_iface_conf->rdns_lifetime);
+ p += sizeof(struct nd_opt_dnssl);
+
+ SIMPLEQ_FOREACH(ra_dnssl, &ra_iface_conf->ra_dnssl_list,
+ entry) {
+ label_start = ra_dnssl->search;
+ while ((label_end = strchr(label_start, '.')) != NULL) {
+ label_len = label_end - label_start;
+ *p++ = label_len;
+ memcpy(p, label_start, label_len);
+ p += label_len;
+ label_start = label_end + 1;
+ }
+ *p++ = '\0'; /* last dot */
+ }
+ /* zero pad */
+ while (((uintptr_t)p) % 8 != 0)
+ *p++ = '\0';
+ }
+
if (len != ra_iface->datalen || memcmp(buf, ra_iface->data, len)
!= 0) {
memcpy(ra_iface->data, buf, len);
diff --git a/usr.sbin/rad/parse.y b/usr.sbin/rad/parse.y
index bb2ce2ba4e9..582d165c7d6 100644
--- a/usr.sbin/rad/parse.y
+++ b/usr.sbin/rad/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.2 2018/07/11 08:47:03 florian Exp $ */
+/* $OpenBSD: parse.y,v 1.3 2018/07/15 09:28:21 florian Exp $ */
/*
* Copyright (c) 2018 Florian Obser <florian@openbsd.org>
@@ -115,7 +115,7 @@ typedef struct {
%token DEFAULT ROUTER HOP LIMIT MANAGED ADDRESS
%token CONFIGURATION OTHER LIFETIME REACHABLE TIME RETRANS TIMER
%token AUTO PREFIX VALID PREFERRED LIFETIME ONLINK AUTONOMOUS
-%token ADDRESS_CONFIGURATION
+%token ADDRESS_CONFIGURATION DNS RESOLVER SEARCH
%token <v.string> STRING
%token <v.number> NUMBER
@@ -265,6 +265,7 @@ ra_ifaceoptsl : NO AUTO PREFIX {
} ra_prefix_block {
ra_prefix_conf = NULL;
}
+ | DNS dns_block
| ra_opt_block
;
@@ -290,7 +291,91 @@ ra_prefixoptsl : VALID LIFETIME NUMBER {
ra_prefix_conf->aflag = $3;
}
;
+dns_block : '{' optnl dnsopts_l '}'
+ | '{' optnl '}'
+ | /* empty */
+ ;
+
+dnsopts_l : dnsopts_l dnsoptsl nl
+ | dnsoptsl optnl
+ ;
+dnsoptsl : LIFETIME NUMBER {
+ ra_iface_conf->rdns_lifetime = $2;
+ }
+ | RESOLVER resolver_block
+ | SEARCH search_block
+ ;
+resolver_block : '{' optnl resolveropts_l '}'
+ | '{' optnl '}'
+ | resolveroptsl
+ | /* empty */
+ ;
+
+resolveropts_l : resolveropts_l resolveroptsl optnl
+ | resolveroptsl optnl
+ ;
+
+resolveroptsl : STRING {
+ struct ra_rdnss_conf *ra_rdnss_conf;
+ struct in6_addr addr;
+
+ memset(&addr, 0, sizeof(addr));
+ if (inet_pton(AF_INET6, $1, &addr)
+ != 1) {
+ yyerror("error parsing resolver address %s",
+ $1);
+ free($1);
+ YYERROR;
+ }
+ if ((ra_rdnss_conf = calloc(1, sizeof(*ra_rdnss_conf)))
+ == NULL)
+ err(1, "%s", __func__);
+ memcpy(&ra_rdnss_conf->rdnss, &addr, sizeof(addr));
+ SIMPLEQ_INSERT_TAIL(&ra_iface_conf->ra_rdnss_list,
+ ra_rdnss_conf, entry);
+ ra_iface_conf->rdnss_count++;
+ }
+ ;
+search_block : '{' optnl searchopts_l '}'
+ | '{' optnl '}'
+ | searchoptsl
+ | /* empty */
+ ;
+
+searchopts_l : searchopts_l searchoptsl optnl
+ | searchoptsl optnl
+ ;
+
+searchoptsl : STRING {
+ struct ra_dnssl_conf *ra_dnssl_conf;
+ size_t len;
+
+ if ((ra_dnssl_conf = calloc(1,
+ sizeof(*ra_dnssl_conf))) == NULL)
+ err(1, "%s", __func__);
+
+ if ((len = strlcpy(ra_dnssl_conf->search, $1,
+ sizeof(ra_dnssl_conf->search))) >
+ sizeof(ra_dnssl_conf->search)) {
+ yyerror("search string too long");
+ free($1);
+ YYERROR;
+ }
+ if (ra_dnssl_conf->search[len] != '.') {
+ if ((len = strlcat(ra_dnssl_conf->search, ".",
+ sizeof(ra_dnssl_conf->search))) >
+ sizeof(ra_dnssl_conf->search)) {
+ yyerror("search string too long");
+ free($1);
+ YYERROR;
+ }
+ }
+ SIMPLEQ_INSERT_TAIL(&ra_iface_conf->ra_dnssl_list,
+ ra_dnssl_conf, entry);
+ ra_iface_conf->dnssl_len += len + 1;
+ }
+ ;
%%
struct keywords {
@@ -331,6 +416,7 @@ lookup(char *s)
{"autonomous", AUTONOMOUS},
{"configuration", CONFIGURATION},
{"default", DEFAULT},
+ {"dns", DNS},
{"hop", HOP},
{"include", INCLUDE},
{"interface", RA_IFACE},
@@ -343,8 +429,10 @@ lookup(char *s)
{"preferred", PREFERRED},
{"prefix", PREFIX},
{"reachable", REACHABLE},
+ {"resolver", RESOLVER},
{"retrans", RETRANS},
{"router", ROUTER},
+ {"search", SEARCH},
{"time", TIME},
{"timer", TIMER},
{"valid", VALID},
@@ -870,7 +958,11 @@ conf_get_ra_iface(char *name)
/* Inherit attributes set in global section. */
iface->ra_options = conf->ra_options;
+ iface->rdns_lifetime = DEFAULT_RDNS_LIFETIME;
+
SIMPLEQ_INIT(&iface->ra_prefix_list);
+ SIMPLEQ_INIT(&iface->ra_rdnss_list);
+ SIMPLEQ_INIT(&iface->ra_dnssl_list);
SIMPLEQ_INSERT_TAIL(&conf->ra_iface_list, iface, entry);
diff --git a/usr.sbin/rad/printconf.c b/usr.sbin/rad/printconf.c
index 57ccb2ccaf5..1fc8cd4ca3f 100644
--- a/usr.sbin/rad/printconf.c
+++ b/usr.sbin/rad/printconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: printconf.c,v 1.1 2018/07/10 16:39:54 florian Exp $ */
+/* $OpenBSD: printconf.c,v 1.2 2018/07/15 09:28:21 florian Exp $ */
/*
* Copyright (c) 2018 Florian Obser <florian@openbsd.org>
@@ -72,6 +72,8 @@ print_config(struct rad_conf *conf)
{
struct ra_iface_conf *iface;
struct ra_prefix_conf *prefix;
+ struct ra_rdnss_conf *ra_rdnss;
+ struct ra_dnssl_conf *ra_dnssl;
char buf[INET6_ADDRSTRLEN], *bufp;
print_ra_options("", &conf->ra_options);
@@ -97,6 +99,30 @@ print_config(struct rad_conf *conf)
printf("\t}\n");
}
+ if (!SIMPLEQ_EMPTY(&iface->ra_rdnss_list) ||
+ !SIMPLEQ_EMPTY(&iface->ra_dnssl_list)) {
+ printf("\tdns {\n");
+ printf("\t\tlifetime %u\n", iface->rdns_lifetime);
+ if (!SIMPLEQ_EMPTY(&iface->ra_rdnss_list)) {
+ printf("\t\tresolver {\n");
+ SIMPLEQ_FOREACH(ra_rdnss,
+ &iface->ra_rdnss_list, entry) {
+ inet_ntop(AF_INET6, &ra_rdnss->rdnss,
+ buf, sizeof(buf));
+ printf("\t\t\t%s\n", buf);
+ }
+ printf("\t\t}\n");
+ }
+ if (!SIMPLEQ_EMPTY(&iface->ra_dnssl_list)) {
+ printf("\t\tsearch {\n");
+ SIMPLEQ_FOREACH(ra_dnssl,
+ &iface->ra_dnssl_list, entry)
+ printf("\t\t\t%s\n", ra_dnssl->search);
+ printf("\t\t}\n");
+ }
+ printf("\t}\n");
+ }
+
printf("}\n");
}
}
diff --git a/usr.sbin/rad/rad.c b/usr.sbin/rad/rad.c
index c184c8c2efe..36b68f2e318 100644
--- a/usr.sbin/rad/rad.c
+++ b/usr.sbin/rad/rad.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rad.c,v 1.7 2018/07/13 09:16:15 florian Exp $ */
+/* $OpenBSD: rad.c,v 1.8 2018/07/15 09:28:21 florian Exp $ */
/*
* Copyright (c) 2018 Florian Obser <florian@openbsd.org>
@@ -594,6 +594,8 @@ main_imsg_send_config(struct rad_conf *xconf)
{
struct ra_iface_conf *ra_iface_conf;
struct ra_prefix_conf *ra_prefix_conf;
+ struct ra_rdnss_conf *ra_rdnss_conf;
+ struct ra_dnssl_conf *ra_dnssl_conf;
/* Send fixed part of config to children. */
if (main_sendboth(IMSG_RECONF_CONF, xconf, sizeof(*xconf)) == -1)
@@ -616,6 +618,22 @@ main_imsg_send_config(struct rad_conf *xconf)
ra_prefix_conf, sizeof(*ra_prefix_conf)) == -1)
return (-1);
}
+ if (main_sendboth(IMSG_RECONF_RA_RDNS_LIFETIME,
+ &ra_iface_conf->rdns_lifetime,
+ sizeof(ra_iface_conf->rdns_lifetime)) == -1)
+ return (-1);
+ SIMPLEQ_FOREACH(ra_rdnss_conf, &ra_iface_conf->ra_rdnss_list,
+ entry) {
+ if (main_sendboth(IMSG_RECONF_RA_RDNSS, ra_rdnss_conf,
+ sizeof(*ra_rdnss_conf)) == -1)
+ return (-1);
+ }
+ SIMPLEQ_FOREACH(ra_dnssl_conf, &ra_iface_conf->ra_dnssl_list,
+ entry) {
+ if (main_sendboth(IMSG_RECONF_RA_DNSSL, ra_dnssl_conf,
+ sizeof(*ra_dnssl_conf)) == -1)
+ return (-1);
+ }
}
/* Tell children the revised config is now complete. */
diff --git a/usr.sbin/rad/rad.conf.5 b/usr.sbin/rad/rad.conf.5
index b0c10e44cc8..286d174784b 100644
--- a/usr.sbin/rad/rad.conf.5
+++ b/usr.sbin/rad/rad.conf.5
@@ -1,4 +1,4 @@
-.\" $OpenBSD: rad.conf.5,v 1.4 2018/07/15 09:27:02 florian Exp $
+.\" $OpenBSD: rad.conf.5,v 1.5 2018/07/15 09:28:21 florian Exp $
.\"
.\" Copyright (c) 2018 Florian Obser <florian@openbsd.org>
.\" Copyright (c) 2005 Esben Norby <norby@openbsd.org>
@@ -125,6 +125,26 @@ The valid lifetime (vltime) in seconds for addresses generated from this
prefix.
The default is 2592000.
.El
+.Pp
+Recursive resolvers are configured inside an interface block:
+.Bd -unfilled -offset indent
+.Ic dns Brq dns options
+.Ed
+.Pp
+.Ic dns
+options are as follows:
+.Bl -tag -width Ds
+.It Ic lifetime Ar seconds
+The number of seconds the dns options are valid after receiving a router
+advertisement message.
+The default is 900 seconds.
+.It Ic resolver Pq Ar IP Ns | Ns { resolver list }
+IPv6 address or list of IPv6 addresses of recursive dns resolvers.
+.It Ic search Pq Ar domain Ns | Ns { domain list }
+Domain or list of domains for the
+.Xr resolv.conf 5
+search list.
+.El
.Sh FILES
.Bl -tag -width "/etc/rad.conf" -compact
.It Pa /etc/rad.conf
diff --git a/usr.sbin/rad/rad.h b/usr.sbin/rad/rad.h
index 22f296ae63a..db80d7c772d 100644
--- a/usr.sbin/rad/rad.h
+++ b/usr.sbin/rad/rad.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: rad.h,v 1.10 2018/07/15 09:25:41 florian Exp $ */
+/* $OpenBSD: rad.h,v 1.11 2018/07/15 09:28:21 florian Exp $ */
/*
* Copyright (c) 2018 Florian Obser <florian@openbsd.org>
@@ -27,6 +27,11 @@
#define OPT_NOACTION 0x00000004
+#define MAX_RTR_ADV_INTERVAL 600
+#define MIN_RTR_ADV_INTERVAL 200
+#define MAX_SEARCH 1025 /* same as MAXDNAME in arpa/nameser.h */
+#define DEFAULT_RDNS_LIFETIME 600 * 1.5
+
enum {
PROC_MAIN,
PROC_ENGINE,
@@ -54,6 +59,9 @@ enum imsg_type {
IMSG_RECONF_RA_IFACE,
IMSG_RECONF_RA_AUTOPREFIX,
IMSG_RECONF_RA_PREFIX,
+ IMSG_RECONF_RA_RDNS_LIFETIME,
+ IMSG_RECONF_RA_RDNSS,
+ IMSG_RECONF_RA_DNSSL,
IMSG_RECONF_END,
IMSG_ICMP6SOCK,
IMSG_ROUTESOCK,
@@ -90,13 +98,28 @@ struct ra_prefix_conf {
int aflag; /* autonom. addr flag */
};
+/* RFC 8106 */
+struct ra_rdnss_conf {
+ SIMPLEQ_ENTRY(ra_rdnss_conf) entry;
+ struct in6_addr rdnss;
+};
+struct ra_dnssl_conf {
+ SIMPLEQ_ENTRY(ra_dnssl_conf) entry;
+ char search[MAX_SEARCH];
+};
+
struct ra_iface_conf {
- SIMPLEQ_ENTRY(ra_iface_conf) entry;
- struct ra_options_conf ra_options;
- struct ra_prefix_conf *autoprefix;
+ SIMPLEQ_ENTRY(ra_iface_conf) entry;
+ struct ra_options_conf ra_options;
+ struct ra_prefix_conf *autoprefix;
SIMPLEQ_HEAD(ra_prefix_conf_head,
- ra_prefix_conf) ra_prefix_list;
- char name[IF_NAMESIZE];
+ ra_prefix_conf) ra_prefix_list;
+ uint32_t rdns_lifetime;
+ SIMPLEQ_HEAD(, ra_rdnss_conf) ra_rdnss_list;
+ int rdnss_count;
+ SIMPLEQ_HEAD(, ra_dnssl_conf) ra_dnssl_list;
+ int dnssl_len;
+ char name[IF_NAMESIZE];
};
struct rad_conf {