Move dns settings to global options so that they don't need to be
repeated in every interface block.

OK?

diff --git engine.c engine.c
index db31fb2a15b..93010cace51 100644
--- engine.c
+++ engine.c
@@ -260,6 +260,7 @@ engine_dispatch_main(int fd, short event, void *bula)
 {
        static struct rad_conf          *nconf;
        static struct ra_iface_conf     *ra_iface_conf;
+       static struct ra_options_conf   *ra_options;
        struct imsg                      imsg;
        struct imsgev                   *iev = bula;
        struct imsgbuf                  *ibuf;
@@ -325,6 +326,9 @@ engine_dispatch_main(int fd, short event, void *bula)
                                fatal(NULL);
                        memcpy(nconf, imsg.data, sizeof(struct rad_conf));
                        SIMPLEQ_INIT(&nconf->ra_iface_list);
+                       SIMPLEQ_INIT(&nconf->ra_options.ra_rdnss_list);
+                       SIMPLEQ_INIT(&nconf->ra_options.ra_dnssl_list);
+                       ra_options = &nconf->ra_options;
                        break;
                case IMSG_RECONF_RA_IFACE:
                        if ((ra_iface_conf = malloc(sizeof(struct
@@ -334,10 +338,11 @@ 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_INIT(&ra_iface_conf->ra_options.ra_rdnss_list);
+                       SIMPLEQ_INIT(&ra_iface_conf->ra_options.ra_dnssl_list);
                        SIMPLEQ_INSERT_TAIL(&nconf->ra_iface_list,
                            ra_iface_conf, entry);
+                       ra_options = &ra_iface_conf->ra_options;
                        break;
                case IMSG_RECONF_RA_AUTOPREFIX:
                        if ((ra_iface_conf->autoprefix = malloc(sizeof(struct
@@ -361,7 +366,7 @@ engine_dispatch_main(int fd, short event, void *bula)
                                fatal(NULL);
                        memcpy(ra_rdnss_conf, imsg.data, sizeof(struct
                            ra_rdnss_conf));
-                       SIMPLEQ_INSERT_TAIL(&ra_iface_conf->ra_rdnss_list,
+                       SIMPLEQ_INSERT_TAIL(&ra_options->ra_rdnss_list,
                            ra_rdnss_conf, entry);
                        break;
                case IMSG_RECONF_RA_DNSSL:
@@ -370,7 +375,7 @@ engine_dispatch_main(int fd, short event, void *bula)
                                fatal(NULL);
                        memcpy(ra_dnssl_conf, imsg.data, sizeof(struct
                            ra_dnssl_conf));
-                       SIMPLEQ_INSERT_TAIL(&ra_iface_conf->ra_dnssl_list,
+                       SIMPLEQ_INSERT_TAIL(&ra_options->ra_dnssl_list,
                            ra_dnssl_conf, entry);
                        break;
                case IMSG_RECONF_END:
diff --git frontend.c frontend.c
index e80879c67d5..7b7487f560b 100644
--- frontend.c
+++ frontend.c
@@ -304,6 +304,7 @@ frontend_dispatch_main(int fd, short event, void *bula)
 {
        static struct rad_conf          *nconf;
        static struct ra_iface_conf     *ra_iface_conf;
+       static struct ra_options_conf   *ra_options;
        struct imsg                      imsg;
        struct imsgev                   *iev = bula;
        struct imsgbuf                  *ibuf = &iev->ibuf;
@@ -367,6 +368,9 @@ frontend_dispatch_main(int fd, short event, void *bula)
                                fatal(NULL);
                        memcpy(nconf, imsg.data, sizeof(struct rad_conf));
                        SIMPLEQ_INIT(&nconf->ra_iface_list);
+                       SIMPLEQ_INIT(&nconf->ra_options.ra_rdnss_list);
+                       SIMPLEQ_INIT(&nconf->ra_options.ra_dnssl_list);
+                       ra_options = &nconf->ra_options;
                        break;
                case IMSG_RECONF_RA_IFACE:
                        if ((ra_iface_conf = malloc(sizeof(struct
@@ -376,10 +380,11 @@ 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_INIT(&ra_iface_conf->ra_options.ra_rdnss_list);
+                       SIMPLEQ_INIT(&ra_iface_conf->ra_options.ra_dnssl_list);
                        SIMPLEQ_INSERT_TAIL(&nconf->ra_iface_list,
                            ra_iface_conf, entry);
+                       ra_options = &ra_iface_conf->ra_options;
                        break;
                case IMSG_RECONF_RA_AUTOPREFIX:
                        if ((ra_iface_conf->autoprefix = malloc(sizeof(struct
@@ -403,7 +408,7 @@ frontend_dispatch_main(int fd, short event, void *bula)
                                fatal(NULL);
                        memcpy(ra_rdnss_conf, imsg.data, sizeof(struct
                            ra_rdnss_conf));
-                       SIMPLEQ_INSERT_TAIL(&ra_iface_conf->ra_rdnss_list,
+                       SIMPLEQ_INSERT_TAIL(&ra_options->ra_rdnss_list,
                            ra_rdnss_conf, entry);
                        break;
                case IMSG_RECONF_RA_DNSSL:
@@ -412,7 +417,7 @@ frontend_dispatch_main(int fd, short event, void *bula)
                                fatal(NULL);
                        memcpy(ra_dnssl_conf, imsg.data, sizeof(struct
                            ra_dnssl_conf));
-                       SIMPLEQ_INSERT_TAIL(&ra_iface_conf->ra_dnssl_list,
+                       SIMPLEQ_INSERT_TAIL(&ra_options->ra_dnssl_list,
                            ra_dnssl_conf, entry);
                        break;
                case IMSG_RECONF_END:
@@ -905,14 +910,15 @@ build_packet(struct ra_iface *ra_iface)
        if (ra_options_conf->mtu > 0)
                len += sizeof(*ndopt_mtu);
        len += sizeof(*ndopt_pi) * ra_iface->prefix_count;
-       if (ra_iface_conf->rdnss_count > 0)
-               len += sizeof(*ndopt_rdnss) + ra_iface_conf->rdnss_count *
+       if (ra_iface_conf->ra_options.rdnss_count > 0)
+               len += sizeof(*ndopt_rdnss) +
+                   ra_iface_conf->ra_options.rdnss_count *
                    sizeof(struct in6_addr);
 
-       if (ra_iface_conf->dnssl_len > 0)
+       if (ra_iface_conf->ra_options.dnssl_len > 0)
                /* round up to 8 byte boundary */
-               len += sizeof(*ndopt_dnssl) + ((ra_iface_conf->dnssl_len + 7)
-                   & ~7);
+               len += sizeof(*ndopt_dnssl) +
+                   ((ra_iface_conf->ra_options.dnssl_len + 7) & ~7);
 
        if (len > sizeof(ra_iface->data))
                fatal("%s: packet too big", __func__); /* XXX send multiple */
@@ -969,35 +975,35 @@ build_packet(struct ra_iface *ra_iface)
                p += sizeof(*ndopt_pi);
        }
 
-       if (ra_iface_conf->rdnss_count > 0) {
+       if (ra_iface_conf->ra_options.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;
+                   ra_iface_conf->ra_options.rdnss_count * 2;
                ndopt_rdnss->nd_opt_rdnss_reserved = 0;
                ndopt_rdnss->nd_opt_rdnss_lifetime =
-                   htonl(ra_iface_conf->rdns_lifetime);
+                   htonl(ra_iface_conf->ra_options.rdns_lifetime);
                p += sizeof(struct nd_opt_rdnss);
-               SIMPLEQ_FOREACH(ra_rdnss, &ra_iface_conf->ra_rdnss_list, 
-                   entry) {
+               SIMPLEQ_FOREACH(ra_rdnss,
+                   &ra_iface_conf->ra_options.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) {
+       if (ra_iface_conf->ra_options.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;
+                   ((ra_iface_conf->ra_options.dnssl_len + 7) & ~7) / 8;
                ndopt_dnssl->nd_opt_dnssl_reserved = 0;
                ndopt_dnssl->nd_opt_dnssl_lifetime =
-                   htonl(ra_iface_conf->rdns_lifetime);
+                   htonl(ra_iface_conf->ra_options.rdns_lifetime);
                p += sizeof(struct nd_opt_dnssl);
 
-               SIMPLEQ_FOREACH(ra_dnssl, &ra_iface_conf->ra_dnssl_list,
-                   entry) {
+               SIMPLEQ_FOREACH(ra_dnssl,
+                   &ra_iface_conf->ra_options.ra_dnssl_list, entry) {
                        label_start = ra_dnssl->search;
                        while ((label_end = strchr(label_start, '.')) != NULL) {
                                label_len = label_end - label_start;
diff --git parse.y parse.y
index 8ffa90569de..853d7e905a7 100644
--- parse.y
+++ parse.y
@@ -212,6 +212,7 @@ ra_opt_block        : DEFAULT ROUTER yesno {
                | MTU NUMBER {
                        ra_options->mtu = $2;
                }
+               | DNS dns_block
                ;
 
 optnl          : '\n' optnl            /* zero or more newlines */
@@ -228,6 +229,7 @@ ra_iface    : RA_IFACE STRING {
                        ra_options = &ra_iface_conf->ra_options;
                } ra_iface_block {
                        ra_iface_conf = NULL;
+                       ra_options = &conf->ra_options;
                }
                ;
 
@@ -269,7 +271,6 @@ ra_ifaceoptsl       : NO AUTO PREFIX {
                } ra_prefix_block {
                        ra_prefix_conf = NULL;
                }
-               | DNS dns_block
                | ra_opt_block
                ;
 
@@ -305,7 +306,7 @@ dnsopts_l   : dnsopts_l dnsoptsl nl
                ;
 
 dnsoptsl       : LIFETIME NUMBER {
-                       ra_iface_conf->rdns_lifetime = $2;
+                       ra_options->rdns_lifetime = $2;
                }
                | NAMESERVER nserver_block
                | SEARCH search_block
@@ -336,9 +337,9 @@ nserveroptsl        : STRING {
                            == NULL)
                                err(1, "%s", __func__);
                        memcpy(&ra_rdnss_conf->rdnss, &addr, sizeof(addr));
-                       SIMPLEQ_INSERT_TAIL(&ra_iface_conf->ra_rdnss_list,
+                       SIMPLEQ_INSERT_TAIL(&ra_options->ra_rdnss_list,
                            ra_rdnss_conf, entry);
-                       ra_iface_conf->rdnss_count++;
+                       ra_options->rdnss_count++;
                }
                ;
 search_block   : '{' optnl searchopts_l '}'
@@ -375,9 +376,9 @@ searchoptsl : STRING {
                                        YYERROR;
                                }
                        }
-                       SIMPLEQ_INSERT_TAIL(&ra_iface_conf->ra_dnssl_list,
+                       SIMPLEQ_INSERT_TAIL(&ra_options->ra_dnssl_list,
                            ra_dnssl_conf, entry);
-                       ra_iface_conf->dnssl_len += len + 1;
+                       ra_options->dnssl_len += len + 1;
                }
                ;
 %%
@@ -946,6 +947,8 @@ struct ra_iface_conf *
 conf_get_ra_iface(char *name)
 {
        struct ra_iface_conf    *iface;
+       struct ra_rdnss_conf    *ra_rdnss, *nra_rdnss;
+       struct ra_dnssl_conf    *ra_dnssl, *nra_dnssl;
        size_t                   n;
 
        SIMPLEQ_FOREACH(iface, &conf->ra_iface_list, entry) {
@@ -963,11 +966,24 @@ 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_INIT(&iface->ra_options.ra_rdnss_list);
+       SIMPLEQ_INIT(&iface->ra_options.ra_dnssl_list);
+
+       SIMPLEQ_FOREACH(ra_rdnss, &conf->ra_options.ra_rdnss_list, entry) {
+               if ((nra_rdnss = calloc(1, sizeof(*nra_rdnss))) == NULL)
+                       errx(1, "%s", __func__);
+               memcpy(nra_rdnss, ra_rdnss, sizeof(*nra_rdnss));
+               SIMPLEQ_INSERT_TAIL(&iface->ra_options.ra_rdnss_list, nra_rdnss,
+                   entry);
+       }
+       SIMPLEQ_FOREACH(ra_dnssl, &conf->ra_options.ra_dnssl_list, entry) {
+               if ((nra_dnssl = calloc(1, sizeof(*nra_dnssl))) == NULL)
+                       errx(1, "%s", __func__);
+               memcpy(nra_dnssl, ra_dnssl, sizeof(*nra_dnssl));
+               SIMPLEQ_INSERT_TAIL(&iface->ra_options.ra_dnssl_list, nra_dnssl,
+                   entry);
+       }
 
        SIMPLEQ_INSERT_TAIL(&conf->ra_iface_list, iface, entry);
 
@@ -979,6 +995,8 @@ clear_config(struct rad_conf *xconf)
 {
        struct ra_iface_conf    *iface;
 
+       free_dns_options(&xconf->ra_options);
+
        while((iface = SIMPLEQ_FIRST(&xconf->ra_iface_list)) != NULL) {
                SIMPLEQ_REMOVE_HEAD(&xconf->ra_iface_list, entry);
                free_ra_iface_conf(iface);
diff --git printconf.c printconf.c
index 1f9e1f72b1c..7623a486d93 100644
--- printconf.c
+++ printconf.c
@@ -46,6 +46,10 @@ yesno(int flag)
 void
 print_ra_options(const char *indent, const struct ra_options_conf *ra_options)
 {
+       struct ra_rdnss_conf    *ra_rdnss;
+       struct ra_dnssl_conf    *ra_dnssl;
+       char                     buf[INET6_ADDRSTRLEN];
+
        printf("%sdefault router %s\n", indent, yesno(ra_options->dfr));
        printf("%shop limit %d\n", indent, ra_options->cur_hl);
        printf("%smanaged address configuration %s\n", indent,
@@ -56,6 +60,30 @@ print_ra_options(const char *indent, const struct 
ra_options_conf *ra_options)
        printf("%sretrans timer %u\n", indent, ra_options->retrans_timer);
        if (ra_options->mtu > 0)
                printf("%smtu %u\n", indent, ra_options->mtu);
+
+       if (!SIMPLEQ_EMPTY(&ra_options->ra_rdnss_list) ||
+           !SIMPLEQ_EMPTY(&ra_options->ra_dnssl_list)) {
+               printf("%sdns {\n", indent);
+               printf("%s\tlifetime %u\n", indent, ra_options->rdns_lifetime);
+               if (!SIMPLEQ_EMPTY(&ra_options->ra_rdnss_list)) {
+                       printf("%s\tnameserver {\n", indent);
+                       SIMPLEQ_FOREACH(ra_rdnss,
+                           &ra_options->ra_rdnss_list, entry) {
+                               inet_ntop(AF_INET6, &ra_rdnss->rdnss,
+                                   buf, sizeof(buf));
+                               printf("%s\t\t%s\n", indent, buf);
+                       }
+                       printf("%s\t}\n", indent);
+               }
+               if (!SIMPLEQ_EMPTY(&ra_options->ra_dnssl_list)) {
+                       printf("%s\tsearch {\n", indent);
+                       SIMPLEQ_FOREACH(ra_dnssl,
+                           &ra_options->ra_dnssl_list, entry)
+                               printf("%s\t\t%s\n", indent, ra_dnssl->search);
+                       printf("%s\t}\n", indent);
+               }
+               printf("%s}\n", indent);
+       }
 }
 
 void
@@ -74,8 +102,6 @@ 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);
@@ -101,30 +127,6 @@ 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\tnameserver {\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 rad.c rad.c
index b741dd5120c..67c9f150d56 100644
--- rad.c
+++ rad.c
@@ -604,6 +604,20 @@ main_imsg_send_config(struct rad_conf *xconf)
        if (main_sendboth(IMSG_RECONF_CONF, xconf, sizeof(*xconf)) == -1)
                return (-1);
 
+       /* send global dns options to children */
+       SIMPLEQ_FOREACH(ra_rdnss_conf, &xconf->ra_options.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, &xconf->ra_options.ra_dnssl_list,
+           entry) {
+               if (main_sendboth(IMSG_RECONF_RA_DNSSL, ra_dnssl_conf,
+                   sizeof(*ra_dnssl_conf)) == -1)
+                       return (-1);
+       }
+
        /* Send the interface list to children. */
        SIMPLEQ_FOREACH(ra_iface_conf, &xconf->ra_iface_list, entry) {
                if (main_sendboth(IMSG_RECONF_RA_IFACE, ra_iface_conf,
@@ -621,14 +635,14 @@ main_imsg_send_config(struct rad_conf *xconf)
                            ra_prefix_conf, sizeof(*ra_prefix_conf)) == -1)
                                return (-1);
                }
-               SIMPLEQ_FOREACH(ra_rdnss_conf, &ra_iface_conf->ra_rdnss_list,
-                   entry) {
+               SIMPLEQ_FOREACH(ra_rdnss_conf,
+                   &ra_iface_conf->ra_options.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) {
+               SIMPLEQ_FOREACH(ra_dnssl_conf,
+                   &ra_iface_conf->ra_options.ra_dnssl_list, entry) {
                        if (main_sendboth(IMSG_RECONF_RA_DNSSL, ra_dnssl_conf,
                            sizeof(*ra_dnssl_conf)) == -1)
                                return (-1);
@@ -656,8 +670,6 @@ void
 free_ra_iface_conf(struct ra_iface_conf *ra_iface_conf)
 {
        struct ra_prefix_conf   *prefix;
-       struct ra_rdnss_conf    *ra_rdnss;
-       struct ra_dnssl_conf    *ra_dnssl;
 
        if (!ra_iface_conf)
                return;
@@ -670,33 +682,47 @@ free_ra_iface_conf(struct ra_iface_conf *ra_iface_conf)
                free(prefix);
        }
 
-       while ((ra_rdnss = SIMPLEQ_FIRST(&ra_iface_conf->ra_rdnss_list)) !=
-           NULL) {
-               SIMPLEQ_REMOVE_HEAD(&ra_iface_conf->ra_rdnss_list, entry);
+       free_dns_options(&ra_iface_conf->ra_options);
+
+       free(ra_iface_conf);
+}
+
+void
+free_dns_options(struct ra_options_conf *ra_options)
+{
+       struct ra_rdnss_conf    *ra_rdnss;
+       struct ra_dnssl_conf    *ra_dnssl;
+
+       while ((ra_rdnss = SIMPLEQ_FIRST(&ra_options->ra_rdnss_list)) != NULL) {
+               SIMPLEQ_REMOVE_HEAD(&ra_options->ra_rdnss_list, entry);
                free(ra_rdnss);
        }
+       ra_options->rdnss_count = 0;
 
-       while ((ra_dnssl = SIMPLEQ_FIRST(&ra_iface_conf->ra_dnssl_list)) !=
-           NULL) {
-               SIMPLEQ_REMOVE_HEAD(&ra_iface_conf->ra_dnssl_list, entry);
+       while ((ra_dnssl = SIMPLEQ_FIRST(&ra_options->ra_dnssl_list)) != NULL) {
+               SIMPLEQ_REMOVE_HEAD(&ra_options->ra_dnssl_list, entry);
                free(ra_dnssl);
        }
-
-       free(ra_iface_conf);
+       ra_options->dnssl_len = 0;
 }
 
 void
 merge_config(struct rad_conf *conf, struct rad_conf *xconf)
 {
        struct ra_iface_conf    *ra_iface_conf;
-
-       conf->ra_options = xconf->ra_options;
+       struct ra_rdnss_conf    *ra_rdnss;
+       struct ra_dnssl_conf    *ra_dnssl;
 
        /* Remove & discard existing interfaces. */
        while ((ra_iface_conf = SIMPLEQ_FIRST(&conf->ra_iface_list)) != NULL) {
                SIMPLEQ_REMOVE_HEAD(&conf->ra_iface_list, entry);
                free_ra_iface_conf(ra_iface_conf);
        }
+       free_dns_options(&conf->ra_options);
+
+       conf->ra_options = xconf->ra_options;
+       SIMPLEQ_INIT(&conf->ra_options.ra_rdnss_list);
+       SIMPLEQ_INIT(&conf->ra_options.ra_dnssl_list);
 
        /* Add new interfaces. */
        while ((ra_iface_conf = SIMPLEQ_FIRST(&xconf->ra_iface_list)) != NULL) {
@@ -704,6 +730,19 @@ merge_config(struct rad_conf *conf, struct rad_conf *xconf)
                SIMPLEQ_INSERT_TAIL(&conf->ra_iface_list, ra_iface_conf, entry);
        }
 
+       /* Add dns options */
+       while ((ra_rdnss = SIMPLEQ_FIRST(&xconf->ra_options.ra_rdnss_list))
+           != NULL) {
+               SIMPLEQ_REMOVE_HEAD(&xconf->ra_options.ra_rdnss_list, entry);
+               SIMPLEQ_INSERT_TAIL(&conf->ra_options.ra_rdnss_list, ra_rdnss,
+                   entry);
+       }
+       while ((ra_dnssl = SIMPLEQ_FIRST(&xconf->ra_options.ra_dnssl_list))
+           != NULL) {
+               SIMPLEQ_REMOVE_HEAD(&xconf->ra_options.ra_dnssl_list, entry);
+               SIMPLEQ_INSERT_TAIL(&conf->ra_options.ra_dnssl_list, ra_dnssl,
+                   entry);
+       }
        free(xconf);
 }
 
@@ -726,6 +765,9 @@ config_new_empty(void)
        xconf->ra_options.reachable_time = 0;
        xconf->ra_options.retrans_timer = 0;
        xconf->ra_options.mtu = 0;
+       xconf->ra_options.rdns_lifetime = DEFAULT_RDNS_LIFETIME;
+       SIMPLEQ_INIT(&xconf->ra_options.ra_rdnss_list);
+       SIMPLEQ_INIT(&xconf->ra_options.ra_dnssl_list);
 
        return (xconf);
 }
diff --git rad.conf.5 rad.conf.5
index c07167a2378..eab6972d0d8 100644
--- rad.conf.5
+++ rad.conf.5
@@ -92,6 +92,21 @@ The default is 1800 seconds.
 .\" XXX
 .\" .It Ic retrans timer Ar number
 .\" XXX
+.It Ic dns Brq dns options
+.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 nameserver Pq Ar IP Ns | Ns { nameserver list }
+IPv6 address or list of IPv6 addresses of DNS name servers.
+.It Ic search Pq Ar domain Ns | Ns { domain list }
+Domain or list of domains for the
+.Xr resolv.conf 5
+search list.
+.El
 .El
 .Sh INTERFACES
 A list of interfaces to send advertisments on:
@@ -130,26 +145,6 @@ The valid lifetime (vltime) in seconds for addresses 
generated from this
 prefix.
 The default is 2592000.
 .El
-.Pp
-Name servers 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 nameserver Pq Ar IP Ns | Ns { nameserver list }
-IPv6 address or list of IPv6 addresses of DNS name servers.
-.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 rad.h rad.h
index 3feeb80dca9..ddd7d977321 100644
--- rad.h
+++ rad.h
@@ -75,6 +75,16 @@ enum imsg_type {
        IMSG_SOCKET_IPC
 };
 
+/* 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];
+};
+
 /* RFC 4861 Sections 4.2 and 4.6.4 */
 struct ra_options_conf {
        int             dfr;                    /* is default router? */
@@ -85,6 +95,11 @@ struct ra_options_conf {
        uint32_t        reachable_time;
        uint32_t        retrans_timer;
        uint32_t        mtu;
+       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;
 };
 
 /* RFC 4861 Section 4.6.2 */
@@ -98,27 +113,12 @@ 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_HEAD(ra_prefix_conf_head,
            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];
 };
 
@@ -154,6 +154,7 @@ int imsg_compose_event(struct imsgev *, uint16_t, uint32_t, 
pid_t,
 struct rad_conf        *config_new_empty(void);
 void            config_clear(struct rad_conf *);
 void            free_ra_iface_conf(struct ra_iface_conf *);
+void            free_dns_options(struct ra_options_conf *);
 void            mask_prefix(struct in6_addr*, int len);
 const char     *sin6_to_str(struct sockaddr_in6 *);
 const char     *in6_to_str(struct in6_addr *);


-- 
I'm not entirely sure you are real.

Reply via email to