diff options
-rw-r--r-- | src/dhcp6.c | 2 | ||||
-rw-r--r-- | src/dnsmasq.c | 31 | ||||
-rw-r--r-- | src/dnsmasq.h | 16 | ||||
-rw-r--r-- | src/option.c | 74 | ||||
-rw-r--r-- | src/radv.c | 42 |
5 files changed, 96 insertions, 69 deletions
diff --git a/src/dhcp6.c b/src/dhcp6.c index e8502fb..305fec7 100644 --- a/src/dhcp6.c +++ b/src/dhcp6.c @@ -229,7 +229,7 @@ int address6_allocate(struct dhcp_context *context, unsigned char *clid, int cl for (pass = 0; pass <= 1; pass++) for (c = context; c; c = c->current) - if (c->flags & (CONTEXT_STATIC | CONTEXT_PROXY)) + if (c->flags & (CONTEXT_STATIC | CONTEXT_RA_STATELESS)) continue; else if (!match_netid(c->filter, netids, pass)) continue; diff --git a/src/dnsmasq.c b/src/dnsmasq.c index 92084a8..579e27e 100644 --- a/src/dnsmasq.c +++ b/src/dnsmasq.c @@ -549,23 +549,30 @@ int main (int argc, char **argv) { start = &dhcp_tmp->start6; end = &dhcp_tmp->end6; + struct in6_addr subnet = dhcp_tmp->start6; + setaddr6part(&subnet, 0); + inet_ntop(AF_INET6, &subnet, daemon->dhcp_buff2, 256); } #endif - prettyprint_time(daemon->dhcp_buff2, dhcp_tmp->lease_time); + prettyprint_time(daemon->namebuff, dhcp_tmp->lease_time); inet_ntop(family, start, daemon->dhcp_buff, 256); inet_ntop(family, end, daemon->dhcp_buff3, 256); - my_syslog(MS_DHCP | LOG_INFO, - (dhcp_tmp->flags & CONTEXT_STATIC) ? - _("DHCP, static leases only on %.0s%s, lease time %s") : - (dhcp_tmp->flags & CONTEXT_RA_NAME) ? - _("router advertisement with DHCPv4-derived names on %.0s%s, lifetime %s") : - (dhcp_tmp->flags & CONTEXT_RA_ONLY) ? - _("router advertisement only on %.0s%s, lifetime %s") : - (dhcp_tmp->flags & CONTEXT_PROXY) ? - _("DHCP, proxy on subnet %.0s%s%.0s") : - _("DHCP, IP range %s -- %s, lease time %s"), - daemon->dhcp_buff, daemon->dhcp_buff3, daemon->dhcp_buff2); + if ((dhcp_tmp->flags & CONTEXT_DHCP) || family == AF_INET) + my_syslog(MS_DHCP | LOG_INFO, + (dhcp_tmp->flags & CONTEXT_STATIC) ? + _("DHCP, static leases only on %.0s%s, lease time %s") : + (dhcp_tmp->flags & CONTEXT_RA_STATELESS) ? + _("SLAAC and stateless DHCPv6 on %.0s%s%.0s") : + (dhcp_tmp->flags & CONTEXT_PROXY) ? + _("DHCP, proxy on subnet %.0s%s%.0s") : + _("DHCP, IP range %s -- %s, lease time %s"), + daemon->dhcp_buff, daemon->dhcp_buff3, daemon->namebuff); + if (dhcp_tmp->flags & CONTEXT_RA_NAME) + my_syslog(MS_DHCP | LOG_INFO, _("SLAAC and DHCPv4-derived names on %s"), daemon->dhcp_buff2); + if (dhcp_tmp->flags & CONTEXT_RA_ONLY) + my_syslog(MS_DHCP | LOG_INFO, _("SLAAC on %s"), daemon->dhcp_buff2); + } #ifdef HAVE_DHCP6 diff --git a/src/dnsmasq.h b/src/dnsmasq.h index baa8430..3df7940 100644 --- a/src/dnsmasq.h +++ b/src/dnsmasq.h @@ -646,13 +646,15 @@ struct dhcp_context { struct dhcp_context *next, *current; }; -#define CONTEXT_STATIC 1 -#define CONTEXT_NETMASK 2 -#define CONTEXT_BRDCAST 4 -#define CONTEXT_PROXY 8 -#define CONTEXT_RA_ONLY 16 -#define CONTEXT_RA_DONE 32 -#define CONTEXT_RA_NAME 64 +#define CONTEXT_STATIC 1 +#define CONTEXT_NETMASK 2 +#define CONTEXT_BRDCAST 4 +#define CONTEXT_PROXY 8 +#define CONTEXT_RA_ONLY 16 +#define CONTEXT_RA_DONE 32 +#define CONTEXT_RA_NAME 64 +#define CONTEXT_RA_STATELESS 128 +#define CONTEXT_DHCP 256 struct ping_result { struct in_addr addr; diff --git a/src/option.c b/src/option.c index 08554d8..9be5001 100644 --- a/src/option.c +++ b/src/option.c @@ -1959,7 +1959,7 @@ static char *one_opt(int option, char *arg, char *gen_prob, int command_line) case 'F': /* --dhcp-range */ { int k, leasepos = 2; - char *cp, *a[5] = { NULL, NULL, NULL, NULL, NULL }; + char *cp, *a[7] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; struct dhcp_context *new = opt_malloc(sizeof(struct dhcp_context)); memset (new, 0, sizeof(*new)); @@ -2010,7 +2010,7 @@ static char *one_opt(int option, char *arg, char *gen_prob, int command_line) } } - for (k = 1; k < 5; k++) + for (k = 1; k < 7; k++) if (!(a[k] = split(a[k-1]))) break; @@ -2020,17 +2020,12 @@ static char *one_opt(int option, char *arg, char *gen_prob, int command_line) { new->next = daemon->dhcp; daemon->dhcp = new; + new->end = new->start; if (strcmp(a[1], "static") == 0) - { - new->end = new->start; - new->flags |= CONTEXT_STATIC; - } + new->flags |= CONTEXT_STATIC; else if (strcmp(a[1], "proxy") == 0) - { - new->end = new->start; - new->flags |= CONTEXT_PROXY; - } - else if ((new->end.s_addr = inet_addr(a[1])) == (in_addr_t)-1) + new->flags |= CONTEXT_PROXY; + else if (!inet_pton(AF_INET, a[1], &new->end)) option = '?'; if (ntohl(new->start.s_addr) > ntohl(new->end.s_addr)) @@ -2060,53 +2055,54 @@ static char *one_opt(int option, char *arg, char *gen_prob, int command_line) else if (inet_pton(AF_INET6, a[0], &new->start6)) { new->prefix = 64; /* default */ - - if (strcmp(a[1], "static") == 0) - { - memcpy(&new->end6, &new->start6, IN6ADDRSZ); - new->flags |= CONTEXT_STATIC; - } - else if (strcmp(a[1], "ra-only") == 0) - { - memcpy(&new->end6, &new->start6, IN6ADDRSZ); - new->flags |= CONTEXT_RA_ONLY; - } - else if (strcmp(a[1], "ra-names") == 0) + new->end6 = new->start6; + + for (leasepos = 1; leasepos < k; leasepos++) { - memcpy(&new->end6, &new->start6, IN6ADDRSZ); - new->flags |= CONTEXT_RA_NAME | CONTEXT_RA_ONLY; + if (strcmp(a[leasepos], "static") == 0) + new->flags |= CONTEXT_STATIC | CONTEXT_DHCP; + else if (strcmp(a[leasepos], "ra-only") == 0 || strcmp(a[leasepos], "slaac") == 0 ) + new->flags |= CONTEXT_RA_ONLY; + else if (strcmp(a[leasepos], "ra-names") == 0) + new->flags |= CONTEXT_RA_NAME; + else if (strcmp(a[leasepos], "ra-stateless") == 0) + new->flags |= CONTEXT_RA_STATELESS | CONTEXT_DHCP; + else if (leasepos == 1 && inet_pton(AF_INET6, a[leasepos], &new->end6)) + new->flags |= CONTEXT_DHCP; + else + break; } - else if (!inet_pton(AF_INET6, a[1], &new->end6)) - option = '?'; - if (new->flags & CONTEXT_RA_ONLY) + if (new->flags & CONTEXT_DHCP) { - new->next = daemon->ra_contexts; - daemon->ra_contexts = new; + new->next = daemon->dhcp6; + daemon->dhcp6 = new; } else { - new->next = daemon->dhcp6; - daemon->dhcp6 = new; + new->next = daemon->ra_contexts; + daemon->ra_contexts = new; } - + /* bare integer < 128 is prefix value */ - if (option != '?' && k >= 3) + if (option != '?' && leasepos < k) { int pref; - for (cp = a[2]; *cp; cp++) + for (cp = a[leasepos]; *cp; cp++) if (!(*cp >= '0' && *cp <= '9')) break; - if (!*cp && (pref = atoi(a[2])) <= 128) + if (!*cp && (pref = atoi(a[leasepos])) <= 128) { new->prefix = pref; - leasepos = 3; - if ((new->flags & CONTEXT_RA_ONLY) && new->prefix != 64) + leasepos++; + if ((new->flags & (CONTEXT_RA_ONLY | CONTEXT_RA_NAME | CONTEXT_RA_STATELESS)) && + new->prefix != 64) problem = _("prefix must be exactly 64 for RA subnets"); else if (new->prefix < 64) problem = _("prefix must be at least 64"); } } + if (!problem && !is_same_net6(&new->start6, &new->end6, new->prefix)) problem = _("inconsistent DHCPv6 range"); else if (addr6part(&new->start6) > addr6part(&new->end6)) @@ -2118,7 +2114,7 @@ static char *one_opt(int option, char *arg, char *gen_prob, int command_line) } #endif - if (k >= leasepos+1) + if (leasepos < k) { if (strcmp(a[leasepos], "infinite") == 0) new->lease_time = 0xffffffff; @@ -27,7 +27,7 @@ #include <netinet/icmp6.h> struct ra_param { - int ind, managed, found_context, first; + int ind, managed, other, found_context, first; char *if_name; struct in6_addr link_local; }; @@ -213,6 +213,7 @@ static void send_ra(int iface, char *iface_name, struct in6_addr *dest) parm.ind = iface; parm.managed = 0; + parm.other = 0; parm.found_context = 0; parm.if_name = iface_name; parm.first = 1; @@ -246,8 +247,10 @@ static void send_ra(int iface, char *iface_name, struct in6_addr *dest) /* set managed bits unless we're providing only RA on this link */ if (parm.managed) - ra->flags = 0xc0; /* M flag, managed, O flag, other */ - + ra->flags |= 0x80; /* M flag, managed, */ + if (parm.other) + ra->flags |= 0x40; /* O flag, other */ + /* decide where we're sending */ memset(&addr, 0, sizeof(addr)); #ifdef HAVE_SOCKADDR_SA_LEN @@ -295,14 +298,20 @@ static int add_prefixes(struct in6_addr *local, int prefix, { int do_slaac = 0; - if (context->flags & CONTEXT_RA_ONLY) - do_slaac = 1; + if ((context->flags & + (CONTEXT_RA_ONLY | CONTEXT_RA_NAME | CONTEXT_RA_STATELESS))) + { + do_slaac = 1; + if (context->flags & CONTEXT_RA_STATELESS) + param->other = 1; + } else { /* don't do RA for non-ra-only unless --enable-ra is set */ if (!option_bool(OPT_RA)) continue; param->managed = 1; + param->other = 1; } if (context->flags & CONTEXT_RA_DONE) @@ -321,14 +330,27 @@ static int add_prefixes(struct in6_addr *local, int prefix, is_same_net6(local, &tmp->start6, prefix) && is_same_net6(local, &tmp->end6, prefix)) { - /* if any dhcp-range with ra-only on this subnet - set the "do_slaac" bit */ - if (tmp->flags & CONTEXT_RA_ONLY) - do_slaac = 1; tmp->flags |= CONTEXT_RA_DONE; context->ra_time = 0; + /* if any dhcp-range with ra-only on this subnet + set the "do_slaac" bit */ + if (tmp->flags & + (CONTEXT_RA_ONLY | CONTEXT_RA_NAME | CONTEXT_RA_STATELESS)) + { + do_slaac = 1; + if (context->flags & CONTEXT_RA_STATELESS) + param->other = 1; + } + else + { + /* don't do RA for non-ra-only unless --enable-ra is set */ + if (!option_bool(OPT_RA)) + continue; + param->managed = 1; + param->other = 1; + } } - + if ((opt = expand(sizeof(struct prefix_opt)))) { u64 addrpart = addr6part(&context->start6); |