Commit 3511a928 authored by Simon Kelley's avatar Simon Kelley

Fix start-up order for making DHCPv6 DUID

Previously, if the DUID wasn't read from the lease-file or
script, a new one was created _after_ the helper process fork,
so for that first run, the script calls got an empty DUID.

Also, use a DUID_LL format DUID when there's no stable lease
storage, as well as when the RTC is broken. That has a chance of
evaluating to the same value on each startup.
parent 44de649e
...@@ -523,6 +523,8 @@ int config_valid(struct dhcp_config *config, struct dhcp_context *context, struc ...@@ -523,6 +523,8 @@ int config_valid(struct dhcp_config *config, struct dhcp_context *context, struc
void make_duid(time_t now) void make_duid(time_t now)
{ {
(void)now;
if (daemon->duid_config) if (daemon->duid_config)
{ {
unsigned char *p; unsigned char *p;
...@@ -535,8 +537,14 @@ void make_duid(time_t now) ...@@ -535,8 +537,14 @@ void make_duid(time_t now)
} }
else else
{ {
time_t newnow = 0;
/* If we have no persistent lease database, or a non-stable RTC, use DUID_LL (newnow == 0) */
#ifndef HAVE_BROKEN_RTC
/* rebase epoch to 1/1/2000 */ /* rebase epoch to 1/1/2000 */
time_t newnow = now - 946684800; if (!option_bool(OPT_LEASE_RO) || daemon->lease_change_command)
newnow = now - 946684800;
#endif
iface_enumerate(AF_LOCAL, &newnow, make_duid1); iface_enumerate(AF_LOCAL, &newnow, make_duid1);
...@@ -555,22 +563,26 @@ static int make_duid1(int index, unsigned int type, char *mac, size_t maclen, vo ...@@ -555,22 +563,26 @@ static int make_duid1(int index, unsigned int type, char *mac, size_t maclen, vo
unsigned char *p; unsigned char *p;
(void)index; (void)index;
(void)parm; (void)parm;
time_t newnow = *((time_t *)parm);
if (type >= 256) if (type >= 256)
return 1; return 1;
#ifdef HAVE_BROKEN_RTC if (newnow == 0)
{
daemon->duid = p = safe_malloc(maclen + 4); daemon->duid = p = safe_malloc(maclen + 4);
daemon->duid_len = maclen + 4; daemon->duid_len = maclen + 4;
PUTSHORT(3, p); /* DUID_LL */ PUTSHORT(3, p); /* DUID_LL */
PUTSHORT(type, p); /* address type */ PUTSHORT(type, p); /* address type */
#else }
else
{
daemon->duid = p = safe_malloc(maclen + 8); daemon->duid = p = safe_malloc(maclen + 8);
daemon->duid_len = maclen + 8; daemon->duid_len = maclen + 8;
PUTSHORT(1, p); /* DUID_LLT */ PUTSHORT(1, p); /* DUID_LLT */
PUTSHORT(type, p); /* address type */ PUTSHORT(type, p); /* address type */
PUTLONG(*((time_t *)parm), p); /* time */ PUTLONG(*((time_t *)parm), p); /* time */
#endif }
memcpy(p, mac, maclen); memcpy(p, mac, maclen);
......
...@@ -273,6 +273,9 @@ int main (int argc, char **argv) ...@@ -273,6 +273,9 @@ int main (int argc, char **argv)
/* after enumerate_interfaces() */ /* after enumerate_interfaces() */
if (daemon->doing_dhcp6 || daemon->relay6 || daemon->doing_ra) if (daemon->doing_dhcp6 || daemon->relay6 || daemon->doing_ra)
join_multicast(1); join_multicast(1);
/* After netlink_init() and before create_helper() */
lease_make_duid(now);
#endif #endif
if (daemon->port != 0) if (daemon->port != 0)
......
...@@ -1120,6 +1120,7 @@ u64 lease_find_max_addr6(struct dhcp_context *context); ...@@ -1120,6 +1120,7 @@ u64 lease_find_max_addr6(struct dhcp_context *context);
void lease_ping_reply(struct in6_addr *sender, unsigned char *packet, char *interface); void lease_ping_reply(struct in6_addr *sender, unsigned char *packet, char *interface);
void lease_update_slaac(time_t now); void lease_update_slaac(time_t now);
void lease_set_iaid(struct dhcp_lease *lease, int iaid); void lease_set_iaid(struct dhcp_lease *lease, int iaid);
void lease_make_duid(time_t now);
#endif #endif
void lease_set_hwaddr(struct dhcp_lease *lease, unsigned char *hwaddr, void lease_set_hwaddr(struct dhcp_lease *lease, unsigned char *hwaddr,
unsigned char *clid, int hw_len, int hw_type, int clid_len, time_t now, int force); unsigned char *clid, int hw_len, int hw_type, int clid_len, time_t now, int force);
......
...@@ -417,15 +417,21 @@ void lease_find_interfaces(time_t now) ...@@ -417,15 +417,21 @@ void lease_find_interfaces(time_t now)
iface_enumerate(AF_INET, &now, find_interface_v4); iface_enumerate(AF_INET, &now, find_interface_v4);
#ifdef HAVE_DHCP6 #ifdef HAVE_DHCP6
iface_enumerate(AF_INET6, &now, find_interface_v6); iface_enumerate(AF_INET6, &now, find_interface_v6);
#endif
}
#ifdef HAVE_DHCP6
void lease_make_duid(time_t now)
{
/* If we're not doing DHCPv6, and there are not v6 leases, don't add the DUID to the database */ /* If we're not doing DHCPv6, and there are not v6 leases, don't add the DUID to the database */
if (!daemon->duid && daemon->dhcp6) if (!daemon->duid && daemon->doing_dhcp6)
{ {
file_dirty = 1; file_dirty = 1;
make_duid(now); make_duid(now);
} }
#endif
} }
#endif
......
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