From: florian Date: Fri, 3 Aug 2018 13:14:46 +0000 (+0000) Subject: Move dns settings to global options so that they don't need to be X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=8815eebd53b4dcb993e9c941b0ba526f15c56793;p=openbsd Move dns settings to global options so that they don't need to be repeated in every interface block - they can still be overwritten on a per interface basis. Pointed out by, tweaks & OK sthen --- diff --git a/usr.sbin/rad/engine.c b/usr.sbin/rad/engine.c index db31fb2a15b..02f1a68ce0c 100644 --- a/usr.sbin/rad/engine.c +++ b/usr.sbin/rad/engine.c @@ -1,4 +1,4 @@ -/* $OpenBSD: engine.c,v 1.8 2018/07/20 20:35:00 florian Exp $ */ +/* $OpenBSD: engine.c,v 1.9 2018/08/03 13:14:46 florian Exp $ */ /* * Copyright (c) 2018 Florian Obser @@ -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 a/usr.sbin/rad/frontend.c b/usr.sbin/rad/frontend.c index e80879c67d5..0a5a982ba9e 100644 --- a/usr.sbin/rad/frontend.c +++ b/usr.sbin/rad/frontend.c @@ -1,4 +1,4 @@ -/* $OpenBSD: frontend.c,v 1.14 2018/07/20 20:35:00 florian Exp $ */ +/* $OpenBSD: frontend.c,v 1.15 2018/08/03 13:14:46 florian Exp $ */ /* * Copyright (c) 2018 Florian Obser @@ -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 a/usr.sbin/rad/parse.y b/usr.sbin/rad/parse.y index 8ffa90569de..45947eed6f8 100644 --- a/usr.sbin/rad/parse.y +++ b/usr.sbin/rad/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.7 2018/07/20 20:34:18 florian Exp $ */ +/* $OpenBSD: parse.y,v 1.8 2018/08/03 13:14:46 florian Exp $ */ /* * Copyright (c) 2018 Florian Obser @@ -100,6 +100,8 @@ static struct ra_prefix_conf *ra_prefix_conf; struct ra_prefix_conf *conf_get_ra_prefix(struct in6_addr*, int); struct ra_iface_conf *conf_get_ra_iface(char *); +void copy_dns_options(const struct ra_options_conf *, + struct ra_options_conf *); typedef struct { union { @@ -212,6 +214,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 +231,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 +273,6 @@ ra_ifaceoptsl : NO AUTO PREFIX { } ra_prefix_block { ra_prefix_conf = NULL; } - | DNS dns_block | ra_opt_block ; @@ -305,7 +308,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 +339,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 +378,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; } ; %% @@ -793,7 +796,8 @@ popfile(void) struct rad_conf * parse_config(char *filename) { - struct sym *sym, *next; + struct sym *sym, *next; + struct ra_iface_conf *iface; conf = config_new_empty(); ra_options = NULL; @@ -827,9 +831,44 @@ parse_config(char *filename) return (NULL); } + if (!SIMPLEQ_EMPTY(&conf->ra_options.ra_rdnss_list) || + !SIMPLEQ_EMPTY(&conf->ra_options.ra_dnssl_list)) { + SIMPLEQ_FOREACH(iface, &conf->ra_iface_list, entry) + copy_dns_options(&conf->ra_options, + &iface->ra_options); + } + return (conf); } +void +copy_dns_options(const struct ra_options_conf *src, struct ra_options_conf *dst) +{ + struct ra_rdnss_conf *ra_rdnss, *nra_rdnss; + struct ra_dnssl_conf *ra_dnssl, *nra_dnssl; + + if (SIMPLEQ_EMPTY(&dst->ra_rdnss_list)) { + SIMPLEQ_FOREACH(ra_rdnss, &src->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(&dst->ra_rdnss_list, nra_rdnss, + entry); + } + dst->rdnss_count = src->rdnss_count; + } + if (SIMPLEQ_EMPTY(&dst->ra_dnssl_list)) { + SIMPLEQ_FOREACH(ra_dnssl, &src->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(&dst->ra_dnssl_list, nra_dnssl, + entry); + } + dst->dnssl_len = src->dnssl_len; + } +} + int symset(const char *nam, const char *val, int persist) { @@ -963,11 +1002,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_INIT(&iface->ra_options.ra_rdnss_list); + iface->ra_options.rdnss_count = 0; + SIMPLEQ_INIT(&iface->ra_options.ra_dnssl_list); + iface->ra_options.dnssl_len = 0; SIMPLEQ_INSERT_TAIL(&conf->ra_iface_list, iface, entry); @@ -979,6 +1018,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 a/usr.sbin/rad/printconf.c b/usr.sbin/rad/printconf.c index 1f9e1f72b1c..d42890da518 100644 --- a/usr.sbin/rad/printconf.c +++ b/usr.sbin/rad/printconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: printconf.c,v 1.4 2018/07/20 17:55:09 bket Exp $ */ +/* $OpenBSD: printconf.c,v 1.5 2018/08/03 13:14:46 florian Exp $ */ /* * Copyright (c) 2018 Florian Obser @@ -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 a/usr.sbin/rad/rad.c b/usr.sbin/rad/rad.c index b741dd5120c..4c82b429e2f 100644 --- a/usr.sbin/rad/rad.c +++ b/usr.sbin/rad/rad.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rad.c,v 1.12 2018/07/20 20:35:00 florian Exp $ */ +/* $OpenBSD: rad.c,v 1.13 2018/08/03 13:14:46 florian Exp $ */ /* * Copyright (c) 2018 Florian Obser @@ -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 a/usr.sbin/rad/rad.conf.5 b/usr.sbin/rad/rad.conf.5 index c07167a2378..9ca4c40dbc4 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.9 2018/07/21 09:35:50 jmc Exp $ +.\" $OpenBSD: rad.conf.5,v 1.10 2018/08/03 13:14:46 florian Exp $ .\" .\" Copyright (c) 2018 Florian Obser .\" Copyright (c) 2005 Esben Norby @@ -18,7 +18,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: July 21 2018 $ +.Dd $Mdocdate: August 3 2018 $ .Dt RAD.CONF 5 .Os .Sh NAME @@ -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 a/usr.sbin/rad/rad.h b/usr.sbin/rad/rad.h index 3feeb80dca9..cd16a0a36db 100644 --- a/usr.sbin/rad/rad.h +++ b/usr.sbin/rad/rad.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rad.h,v 1.14 2018/07/20 20:35:00 florian Exp $ */ +/* $OpenBSD: rad.h,v 1.15 2018/08/03 13:14:46 florian Exp $ */ /* * Copyright (c) 2018 Florian Obser @@ -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 *);