summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dhcp6.c2
-rw-r--r--src/dnsmasq.c31
-rw-r--r--src/dnsmasq.h16
-rw-r--r--src/option.c74
-rw-r--r--src/radv.c42
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;
diff --git a/src/radv.c b/src/radv.c
index 353ca87..e184d00 100644
--- a/src/radv.c
+++ b/src/radv.c
@@ -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);