"deprecated" lease-time keyword for IPv6

This commit is contained in:
Simon Kelley
2012-03-28 21:15:41 +01:00
parent 2240704863
commit c8257540bc
8 changed files with 124 additions and 107 deletions

View File

@@ -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_RA_STATELESS))
if (c->flags & (CONTEXT_DEPRECATE | CONTEXT_STATIC | CONTEXT_RA_STATELESS))
continue;
else if (!match_netid(c->filter, netids, pass))
continue;
@@ -282,9 +282,9 @@ struct dhcp_context *address6_available(struct dhcp_context *context,
start = addr6part(&tmp->start6);
end = addr6part(&tmp->end6);
if (!(tmp->flags & (CONTEXT_STATIC | CONTEXT_PROXY)) &&
is_same_net6(&context->start6, taddr, context->prefix) &&
is_same_net6(&context->end6, taddr, context->prefix) &&
if (!(tmp->flags & (CONTEXT_STATIC | CONTEXT_RA_STATELESS)) &&
is_same_net6(&tmp->start6, taddr, tmp->prefix) &&
is_same_net6(&tmp->end6, taddr, tmp->prefix) &&
addr >= start &&
addr <= end &&
match_netid(tmp->filter, netids, 1))

View File

@@ -530,7 +530,7 @@ int main (int argc, char **argv)
my_syslog(MS_DHCP | LOG_INFO, _("IPv6 router advertisement enabled"));
#ifdef HAVE_DHCP
if (daemon->dhcp || daemon->dhcp6)
if (daemon->dhcp || daemon->dhcp6 || daemon->ra_contexts)
{
struct dhcp_context *dhcp_tmp;
int family = AF_INET;
@@ -543,7 +543,7 @@ int main (int argc, char **argv)
{
void *start = &dhcp_tmp->start;
void *end = &dhcp_tmp->end;
#ifdef HAVE_DHCP6
if (family == AF_INET6)
{
@@ -551,31 +551,48 @@ int main (int argc, char **argv)
end = &dhcp_tmp->end6;
struct in6_addr subnet = dhcp_tmp->start6;
setaddr6part(&subnet, 0);
inet_ntop(AF_INET6, &subnet, daemon->dhcp_buff2, 256);
inet_ntop(AF_INET6, &subnet, daemon->addrbuff, 256);
}
#endif
prettyprint_time(daemon->namebuff, dhcp_tmp->lease_time);
inet_ntop(family, start, daemon->dhcp_buff, 256);
inet_ntop(family, end, daemon->dhcp_buff3, 256);
if (family != AF_INET && (dhcp_tmp->flags & CONTEXT_DEPRECATE))
strcpy(daemon->namebuff, _("prefix deprecated"));
else
{
char *p = daemon->namebuff;
p += sprintf(p, _("lease time "));
prettyprint_time(p, dhcp_tmp->lease_time);
}
if (daemon->dhcp_buff)
inet_ntop(family, start, daemon->dhcp_buff, 256);
if (daemon->dhcp_buff3)
inet_ntop(family, end, daemon->dhcp_buff3, 256);
if ((dhcp_tmp->flags & CONTEXT_DHCP) || family == AF_INET)
my_syslog(MS_DHCP | LOG_INFO,
#ifdef HAVE_DHCP6
(dhcp_tmp->flags & CONTEXT_RA_STATELESS) ?
_("SLAAC and stateless DHCPv6 on %.0s%s%.0s") :
#endif
_("stateless DHCPv6 on %s%.0s%.0s") :
(dhcp_tmp->flags & CONTEXT_STATIC) ?
_("DHCP, static leases only on %.0s%s, lease time %s") :
_("DHCP, static leases only on %.0s%s, %s") :
(dhcp_tmp->flags & CONTEXT_PROXY) ?
_("DHCP, proxy on subnet %.0s%s%.0s") :
_("DHCP, IP range %s -- %s, lease time %s"),
_("DHCP, IP range %s -- %s, %s"),
daemon->dhcp_buff, daemon->dhcp_buff3, daemon->namebuff);
#ifdef HAVE_DHCP6
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);
#endif
my_syslog(MS_DHCP | LOG_INFO, _("DHCPv4-derived IPv6 names on %s"),
daemon->addrbuff);
if (dhcp_tmp->flags & (CONTEXT_RA_ONLY | CONTEXT_RA_NAME | CONTEXT_RA_STATELESS))
{
if (!(dhcp_tmp->flags & CONTEXT_DEPRECATE))
{
char *p = daemon->namebuff;
p += sprintf(p, _("prefix valid "));
prettyprint_time(p, dhcp_tmp->lease_time > 7200 ? dhcp_tmp->lease_time : 7200);
}
my_syslog(MS_DHCP | LOG_INFO, _("SLAAC on %s %s"),
daemon->addrbuff, daemon->namebuff);
}
}
#ifdef HAVE_DHCP6

View File

@@ -655,6 +655,7 @@ struct dhcp_context {
#define CONTEXT_RA_NAME 64
#define CONTEXT_RA_STATELESS 128
#define CONTEXT_DHCP 256
#define CONTEXT_DEPRECATE 512
struct ping_result {
struct in_addr addr;

View File

@@ -2118,6 +2118,8 @@ static char *one_opt(int option, char *arg, char *gen_prob, int command_line)
{
if (strcmp(a[leasepos], "infinite") == 0)
new->lease_time = 0xffffffff;
else if (strcmp(a[leasepos], "deprecated") == 0)
new->flags |= CONTEXT_DEPRECATE;
else
{
int fac = 1;
@@ -2150,16 +2152,6 @@ static char *one_opt(int option, char *arg, char *gen_prob, int command_line)
}
}
}
#ifdef HAVE_DHCP6
/* lifetimes must be min 2 hrs, by RFC 2462.
This gets enforced in radv.c for DHCP ranges
which are legitimately less. */
if ((new->flags & CONTEXT_RA_ONLY) &&
new->lease_time < 7200)
new->lease_time = 7200;
#endif
break;
}

View File

@@ -276,9 +276,8 @@ static void send_ra(int iface, char *iface_name, struct in6_addr *dest)
static int add_prefixes(struct in6_addr *local, int prefix,
int scope, int if_index, int dad, void *vparam)
{
struct dhcp_context *context, *tmp;
struct dhcp_context *context;
struct ra_param *param = vparam;
struct prefix_opt *opt;
(void)scope; /* warning */
(void)dad;
@@ -291,13 +290,17 @@ static int add_prefixes(struct in6_addr *local, int prefix,
!IN6_IS_ADDR_LINKLOCAL(local) &&
!IN6_IS_ADDR_MULTICAST(local))
{
int do_slaac = 0;
int deprecate = 0;
unsigned int time = 0xffffffff;
struct in6_addr *addr = NULL;
struct prefix_opt *opt;
for (context = daemon->ra_contexts; context; context = context->next)
if (prefix == context->prefix &&
is_same_net6(local, &context->start6, prefix) &&
is_same_net6(local, &context->end6, prefix))
{
int do_slaac = 0;
if ((context->flags &
(CONTEXT_RA_ONLY | CONTEXT_RA_NAME | CONTEXT_RA_STATELESS)))
{
@@ -314,68 +317,51 @@ static int add_prefixes(struct in6_addr *local, int prefix,
param->other = 1;
}
if (context->flags & CONTEXT_RA_DONE)
continue;
/* find floor time */
if (time > context->lease_time)
time = context->lease_time;
/* subsequent prefixes on the same interface don't need timers */
if (context->flags & CONTEXT_DEPRECATE)
deprecate = 1;
/* subsequent prefixes on the same interface
and subsequent instances of this prefix don't need timers */
if (!param->first)
context->ra_time = 0;
param->first = 0;
param->found_context = 1;
context->flags |= CONTEXT_RA_DONE;
/* mark this subnet and duplicates: as done. */
for (tmp = context->next; tmp; tmp = tmp->next)
if (tmp->prefix == prefix &&
is_same_net6(local, &tmp->start6, prefix) &&
is_same_net6(local, &tmp->end6, prefix))
{
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);
u64 mask = (prefix == 64) ? (u64)-1LL : (1LLU << (128 - prefix)) - 1LLU;
unsigned int time = context->lease_time;
/* lifetimes must be min 2 hrs, by RFC 2462 */
if (time < 7200)
time = 7200;
opt->type = ICMP6_OPT_PREFIX;
opt->len = 4;
opt->prefix_len = prefix;
/* autonomous only is we're not doing dhcp */
opt->flags = do_slaac ? 0x40 : 0x00;
opt->valid_lifetime = opt->preferred_lifetime = htonl(time);
opt->reserved = 0;
opt->prefix = context->start6;
setaddr6part(&opt->prefix, addrpart & ~mask);
inet_ntop(AF_INET6, &opt->prefix, daemon->addrbuff, ADDRSTRLEN);
my_syslog(MS_DHCP | LOG_INFO, "RTR-ADVERT(%s) %s", param->if_name, daemon->addrbuff);
}
if (context->flags & CONTEXT_RA_DONE)
continue;
context->flags |= CONTEXT_RA_DONE;
addr = &context->start6;
}
if (addr && (opt = expand(sizeof(struct prefix_opt))))
{
u64 addrpart = addr6part(addr);
u64 mask = (prefix == 64) ? (u64)-1LL : (1LLU << (128 - prefix)) - 1LLU;
/* lifetimes must be min 2 hrs, by RFC 2462 */
if (time < 7200)
time = 7200;
opt->type = ICMP6_OPT_PREFIX;
opt->len = 4;
opt->prefix_len = prefix;
/* autonomous only is we're not doing dhcp */
opt->flags = do_slaac ? 0x40 : 0x00;
opt->valid_lifetime = htonl(time);
opt->preferred_lifetime = htonl(deprecate ? 0 : time);
opt->reserved = 0;
opt->prefix = *addr;
setaddr6part(&opt->prefix, addrpart & ~mask);
inet_ntop(AF_INET6, &opt->prefix, daemon->addrbuff, ADDRSTRLEN);
my_syslog(MS_DHCP | LOG_INFO, "RTR-ADVERT(%s) %s", param->if_name, daemon->addrbuff);
}
}
}
return 1;

View File

@@ -513,13 +513,13 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
while (1)
{
struct in6_addr alloced_addr, *addrp = NULL;
u32 preferred_time = 0;
u32 requested_time = 0;
struct dhcp_lease *lease = NULL;
if (ia_option)
{
struct in6_addr *req_addr = opt6_ptr(ia_option, 0);
preferred_time = opt6_uint(ia_option, 16, 4);
requested_time = opt6_uint(ia_option, 16, 4);
if (!address6_available(context, req_addr, tags) &&
(!have_config(config, CONFIG_ADDR6) || memcmp(&config->addr6, req_addr, IN6ADDRSZ) != 0))
@@ -621,10 +621,10 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
if (ia_option)
{
if (preferred_time < 120u )
preferred_time = 120u; /* sanity */
if (lease_time == 0xffffffff || (preferred_time != 0xffffffff && preferred_time < lease_time))
lease_time = preferred_time;
if (requested_time < 120u )
requested_time = 120u; /* sanity */
if (lease_time == 0xffffffff || (requested_time != 0xffffffff && requested_time < lease_time))
lease_time = requested_time;
}
if (lease_time < min_time)
@@ -730,8 +730,9 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
{
o1 = new_opt6(OPTION6_IAADDR);
put_opt6(addrp, sizeof(*addrp));
put_opt6_long(lease_time);
put_opt6_long(lease_time);
/* preferred lifetime */
put_opt6_long(this_context && (this_context->flags & CONTEXT_DEPRECATE) ? 0 : lease_time);
put_opt6_long(lease_time); /* valid lifetime */
end_opt6(o1);
log6_packet( make_lease ? "DHCPREPLY" : "DHCPADVERTISE",
@@ -842,7 +843,7 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
{
struct dhcp_lease *lease = NULL;
struct in6_addr *req_addr = opt6_ptr(ia_option, 0);
u32 preferred_time = opt6_uint(ia_option, 16, 4);
u32 requested_time = opt6_uint(ia_option, 16, 4);
unsigned int lease_time;
struct dhcp_context *this_context;
struct dhcp_config *valid_config = config;
@@ -873,7 +874,10 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
if (!address6_available(context, req_addr, tagif) ||
!(this_context = narrow_context6(context, req_addr, tagif)))
lease_time = 0;
{
lease_time = 0;
this_context = NULL;
}
else
{
/* get tags from context if we've not used it before */
@@ -895,10 +899,10 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
lease_time = have_config(valid_config, CONFIG_TIME) ? valid_config->lease_time : this_context->lease_time;
if (preferred_time < 120u )
preferred_time = 120u; /* sanity */
if (lease_time == 0xffffffff || (preferred_time != 0xffffffff && preferred_time < lease_time))
lease_time = preferred_time;
if (requested_time < 120u )
requested_time = 120u; /* sanity */
if (lease_time == 0xffffffff || (requested_time != 0xffffffff && requested_time < lease_time))
lease_time = requested_time;
lease_set_expires(lease, lease_time, now);
if (ia_type == OPTION6_IA_NA && hostname)
@@ -917,8 +921,9 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
o1 = new_opt6(OPTION6_IAADDR);
put_opt6(req_addr, sizeof(*req_addr));
put_opt6_long(lease_time);
put_opt6_long(lease_time);
/* preferred lifetime */
put_opt6_long(this_context && (this_context->flags & CONTEXT_DEPRECATE) ? 0 : lease_time);
put_opt6_long(lease_time); /* valid lifetime */
end_opt6(o1);
}