Commit 8e9ffba6 authored by Simon Kelley's avatar Simon Kelley

Merge branch 'mobile-ra'

Conflicts:
	CHANGELOG
parents 15a97ad6 7ea3d3fd
version 2.72
Add ra-advrouter mode, for RFC-3775 mobile IPv6 support.
version 2.71 version 2.71
Subtle change to error handling to help DNSSEC validation Subtle change to error handling to help DNSSEC validation
when servers fail to provide NODATA answers for when servers fail to provide NODATA answers for
......
...@@ -794,7 +794,7 @@ and ...@@ -794,7 +794,7 @@ and
for details.) for details.)
For IPv6, the mode may be some combination of For IPv6, the mode may be some combination of
.B ra-only, slaac, ra-names, ra-stateless. .B ra-only, slaac, ra-names, ra-stateless, ra-advrouter.
.B ra-only .B ra-only
tells dnsmasq to offer Router Advertisement only on this subnet, tells dnsmasq to offer Router Advertisement only on this subnet,
...@@ -829,6 +829,11 @@ can be combined with ...@@ -829,6 +829,11 @@ can be combined with
and and
.B slaac. .B slaac.
.B ra-advrouter
enables a mode where router address(es) rather than prefix(es) are included in the advertisements.
This is described in RFC-3775 section 7.2 and is used in mobile IPv6. In this mode the interval option
is also included, as described in RFC-3775 section 7.3.
.TP .TP
.B \-G, --dhcp-host=[<hwaddr>][,id:<client_id>|*][,set:<tag>][,<ipaddr>][,<hostname>][,<lease_time>][,ignore] .B \-G, --dhcp-host=[<hwaddr>][,id:<client_id>|*][,set:<tag>][,<ipaddr>][,<hostname>][,<lease_time>][,ignore]
Specify per host parameters for the DHCP server. This allows a machine Specify per host parameters for the DHCP server. This allows a machine
......
...@@ -727,8 +727,7 @@ void dhcp_construct_contexts(time_t now) ...@@ -727,8 +727,7 @@ void dhcp_construct_contexts(time_t now)
if (context->flags & CONTEXT_GC && !(context->flags & CONTEXT_OLD)) if (context->flags & CONTEXT_GC && !(context->flags & CONTEXT_OLD))
{ {
if ((context->flags & (CONTEXT_RA_ONLY | CONTEXT_RA_NAME | CONTEXT_RA_STATELESS)) || if ((context->flags & CONTEXT_RA) || option_bool(OPT_RA))
option_bool(OPT_RA))
{ {
/* previously constructed context has gone. advertise it's demise */ /* previously constructed context has gone. advertise it's demise */
context->flags |= CONTEXT_OLD; context->flags |= CONTEXT_OLD;
......
...@@ -823,7 +823,7 @@ struct dhcp_context { ...@@ -823,7 +823,7 @@ struct dhcp_context {
#define CONTEXT_NETMASK (1u<<1) #define CONTEXT_NETMASK (1u<<1)
#define CONTEXT_BRDCAST (1u<<2) #define CONTEXT_BRDCAST (1u<<2)
#define CONTEXT_PROXY (1u<<3) #define CONTEXT_PROXY (1u<<3)
#define CONTEXT_RA_ONLY (1u<<4) #define CONTEXT_RA_ROUTER (1u<<4)
#define CONTEXT_RA_DONE (1u<<5) #define CONTEXT_RA_DONE (1u<<5)
#define CONTEXT_RA_NAME (1u<<6) #define CONTEXT_RA_NAME (1u<<6)
#define CONTEXT_RA_STATELESS (1u<<7) #define CONTEXT_RA_STATELESS (1u<<7)
...@@ -838,7 +838,6 @@ struct dhcp_context { ...@@ -838,7 +838,6 @@ struct dhcp_context {
#define CONTEXT_OLD (1u<<16) #define CONTEXT_OLD (1u<<16)
#define CONTEXT_V6 (1u<<17) #define CONTEXT_V6 (1u<<17)
struct ping_result { struct ping_result {
struct in_addr addr; struct in_addr addr;
time_t time; time_t time;
......
...@@ -2583,9 +2583,11 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma ...@@ -2583,9 +2583,11 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
if (strcmp(a[leasepos], "static") == 0) if (strcmp(a[leasepos], "static") == 0)
new->flags |= CONTEXT_STATIC | CONTEXT_DHCP; new->flags |= CONTEXT_STATIC | CONTEXT_DHCP;
else if (strcmp(a[leasepos], "ra-only") == 0 || strcmp(a[leasepos], "slaac") == 0 ) else if (strcmp(a[leasepos], "ra-only") == 0 || strcmp(a[leasepos], "slaac") == 0 )
new->flags |= CONTEXT_RA_ONLY | CONTEXT_RA; new->flags |= CONTEXT_RA;
else if (strcmp(a[leasepos], "ra-names") == 0) else if (strcmp(a[leasepos], "ra-names") == 0)
new->flags |= CONTEXT_RA_NAME | CONTEXT_RA; new->flags |= CONTEXT_RA_NAME | CONTEXT_RA;
else if (strcmp(a[leasepos], "ra-advrouter") == 0)
new->flags |= CONTEXT_RA_ROUTER | CONTEXT_RA;
else if (strcmp(a[leasepos], "ra-stateless") == 0) else if (strcmp(a[leasepos], "ra-stateless") == 0)
new->flags |= CONTEXT_RA_STATELESS | CONTEXT_DHCP | CONTEXT_RA; new->flags |= CONTEXT_RA_STATELESS | CONTEXT_DHCP | CONTEXT_RA;
else if (leasepos == 1 && inet_pton(AF_INET6, a[leasepos], &new->end6)) else if (leasepos == 1 && inet_pton(AF_INET6, a[leasepos], &new->end6))
...@@ -2615,7 +2617,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma ...@@ -2615,7 +2617,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
if (new->prefix != 64) if (new->prefix != 64)
{ {
if ((new->flags & (CONTEXT_RA_ONLY | CONTEXT_RA_NAME | CONTEXT_RA_STATELESS))) if (new->flags & CONTEXT_RA)
ret_err(_("prefix length must be exactly 64 for RA subnets")); ret_err(_("prefix length must be exactly 64 for RA subnets"));
else if (new->flags & CONTEXT_TEMPLATE) else if (new->flags & CONTEXT_TEMPLATE)
ret_err(_("prefix length must be exactly 64 for subnet constructors")); ret_err(_("prefix length must be exactly 64 for subnet constructors"));
......
...@@ -49,6 +49,7 @@ struct prefix_opt { ...@@ -49,6 +49,7 @@ struct prefix_opt {
#define ICMP6_OPT_SOURCE_MAC 1 #define ICMP6_OPT_SOURCE_MAC 1
#define ICMP6_OPT_PREFIX 3 #define ICMP6_OPT_PREFIX 3
#define ICMP6_OPT_MTU 5 #define ICMP6_OPT_MTU 5
#define ICMP6_OPT_ADV_INTERVAL 7
#define ICMP6_OPT_RDNSS 25 #define ICMP6_OPT_RDNSS 25
#define ICMP6_OPT_DNSSL 31 #define ICMP6_OPT_DNSSL 31
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
struct ra_param { struct ra_param {
time_t now; time_t now;
int ind, managed, other, found_context, first; int ind, managed, other, found_context, first, adv_router;
char *if_name; char *if_name;
struct dhcp_netid *tags; struct dhcp_netid *tags;
struct in6_addr link_local, link_global, ula; struct in6_addr link_local, link_global, ula;
...@@ -226,6 +226,7 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de ...@@ -226,6 +226,7 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
parm.managed = 0; parm.managed = 0;
parm.other = 0; parm.other = 0;
parm.found_context = 0; parm.found_context = 0;
parm.adv_router = 0;
parm.if_name = iface_name; parm.if_name = iface_name;
parm.first = 1; parm.first = 1;
parm.now = now; parm.now = now;
...@@ -286,8 +287,7 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de ...@@ -286,8 +287,7 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
setaddr6part(&local, addr6part(&local) & ~((context->prefix == 64) ? (u64)-1LL : (1LLU << (128 - context->prefix)) - 1LLU)); setaddr6part(&local, addr6part(&local) & ~((context->prefix == 64) ? (u64)-1LL : (1LLU << (128 - context->prefix)) - 1LLU));
if ((context->flags & if (context->flags & CONTEXT_RA)
(CONTEXT_RA_ONLY | CONTEXT_RA_NAME | CONTEXT_RA_STATELESS)))
{ {
do_slaac = 1; do_slaac = 1;
if (context->flags & CONTEXT_DHCP) if (context->flags & CONTEXT_DHCP)
...@@ -339,6 +339,17 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de ...@@ -339,6 +339,17 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
if (!old_prefix && !parm.found_context) if (!old_prefix && !parm.found_context)
return; return;
/* If we're sending router address instead of prefix in at least on prefix,
include the advertisement interval option. */
if (parm.adv_router)
{
put_opt6_char(ICMP6_OPT_ADV_INTERVAL);
put_opt6_char(1);
put_opt6_short(0);
/* interval value is in milliseconds */
put_opt6_long(1000 * calc_interval(find_iface_param(iface_name)));
}
#ifdef HAVE_LINUX_NETWORK #ifdef HAVE_LINUX_NETWORK
/* Note that IPv6 MTU is not necessarilly the same as the IPv4 MTU /* Note that IPv6 MTU is not necessarilly the same as the IPv4 MTU
available from SIOCGIFMTU */ available from SIOCGIFMTU */
...@@ -500,6 +511,7 @@ static int add_prefixes(struct in6_addr *local, int prefix, ...@@ -500,6 +511,7 @@ static int add_prefixes(struct in6_addr *local, int prefix,
int do_slaac = 0; int do_slaac = 0;
int deprecate = 0; int deprecate = 0;
int constructed = 0; int constructed = 0;
int adv_router = 0;
unsigned int time = 0xffffffff; unsigned int time = 0xffffffff;
struct dhcp_context *context; struct dhcp_context *context;
...@@ -511,8 +523,7 @@ static int add_prefixes(struct in6_addr *local, int prefix, ...@@ -511,8 +523,7 @@ static int add_prefixes(struct in6_addr *local, int prefix,
{ {
context->saved_valid = valid; context->saved_valid = valid;
if ((context->flags & if (context->flags & CONTEXT_RA)
(CONTEXT_RA_ONLY | CONTEXT_RA_NAME | CONTEXT_RA_STATELESS)))
{ {
do_slaac = 1; do_slaac = 1;
if (context->flags & CONTEXT_DHCP) if (context->flags & CONTEXT_DHCP)
...@@ -530,7 +541,17 @@ static int add_prefixes(struct in6_addr *local, int prefix, ...@@ -530,7 +541,17 @@ static int add_prefixes(struct in6_addr *local, int prefix,
param->managed = 1; param->managed = 1;
param->other = 1; param->other = 1;
} }
/* Configured to advertise router address, not prefix. See RFC 3775 7.2
In this case we do all addresses associated with a context,
hence the real_prefix setting here. */
if (context->flags & CONTEXT_RA_ROUTER)
{
adv_router = 1;
param->adv_router = 1;
real_prefix = context->prefix;
}
/* find floor time, don't reduce below 3 * RA interval. */ /* find floor time, don't reduce below 3 * RA interval. */
if (time > context->lease_time) if (time > context->lease_time)
{ {
...@@ -556,7 +577,7 @@ static int add_prefixes(struct in6_addr *local, int prefix, ...@@ -556,7 +577,7 @@ static int add_prefixes(struct in6_addr *local, int prefix,
/* subsequent prefixes on the same interface /* subsequent prefixes on the same interface
and subsequent instances of this prefix don't need timers. and subsequent instances of this prefix don't need timers.
Be careful not to find the same prefix twice with different Be careful not to find the same prefix twice with different
addresses. */ addresses unless we're advertising the actual addresses. */
if (!(context->flags & CONTEXT_RA_DONE)) if (!(context->flags & CONTEXT_RA_DONE))
{ {
if (!param->first) if (!param->first)
...@@ -607,13 +628,18 @@ static int add_prefixes(struct in6_addr *local, int prefix, ...@@ -607,13 +628,18 @@ static int add_prefixes(struct in6_addr *local, int prefix,
if ((opt = expand(sizeof(struct prefix_opt)))) if ((opt = expand(sizeof(struct prefix_opt))))
{ {
/* zero net part of address */ /* zero net part of address */
setaddr6part(local, addr6part(local) & ~((real_prefix == 64) ? (u64)-1LL : (1LLU << (128 - real_prefix)) - 1LLU)); if (!adv_router)
setaddr6part(local, addr6part(local) & ~((real_prefix == 64) ? (u64)-1LL : (1LLU << (128 - real_prefix)) - 1LLU));
opt->type = ICMP6_OPT_PREFIX; opt->type = ICMP6_OPT_PREFIX;
opt->len = 4; opt->len = 4;
opt->prefix_len = real_prefix; opt->prefix_len = real_prefix;
/* autonomous only if we're not doing dhcp, always set "on-link" */ /* autonomous only if we're not doing dhcp, always set "on-link" */
opt->flags = do_slaac ? 0xC0 : 0x80; opt->flags = 0x80;
if (do_slaac)
opt->flags |= 0x40;
if (adv_router)
opt->flags |= 0x20;
opt->valid_lifetime = htonl(valid); opt->valid_lifetime = htonl(valid);
opt->preferred_lifetime = htonl(preferred); opt->preferred_lifetime = htonl(preferred);
opt->reserved = 0; opt->reserved = 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment