mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-20 02:38:32 +00:00
Make RA without DHCPv6 possible.
This commit is contained in:
@@ -157,6 +157,13 @@
|
|||||||
# an explicit netmask instead.
|
# an explicit netmask instead.
|
||||||
#dhcp-range=192.168.0.0,static
|
#dhcp-range=192.168.0.0,static
|
||||||
|
|
||||||
|
# Enable DHCPv6. Note that the prefix-length does not need to be specified
|
||||||
|
# and defaults to 64 if missing/
|
||||||
|
#dhcp-range=1234::2, 1234::500, 64, 12h
|
||||||
|
|
||||||
|
# Not Router Advertisements, BUT NOT DHCP for this subnet.
|
||||||
|
#dhcp-range=1234::, ra-only
|
||||||
|
|
||||||
# Supply parameters for specified hosts using DHCP. There are lots
|
# Supply parameters for specified hosts using DHCP. There are lots
|
||||||
# of valid alternatives, so we will give examples of each. Note that
|
# of valid alternatives, so we will give examples of each. Note that
|
||||||
# IP addresses DO NOT have to be in the range given above, they just
|
# IP addresses DO NOT have to be in the range given above, they just
|
||||||
@@ -219,6 +226,12 @@
|
|||||||
# any machine with Ethernet address starting 11:22:33:
|
# any machine with Ethernet address starting 11:22:33:
|
||||||
#dhcp-host=11:22:33:*:*:*,set:red
|
#dhcp-host=11:22:33:*:*:*,set:red
|
||||||
|
|
||||||
|
# Give a fixed IPv6 address and name to client with
|
||||||
|
# DUID 00:01:00:01:16:d2:83:fc:92:d4:19:e2:d8:b2
|
||||||
|
# Note the MAC addresses CANNOT be used to identify DHCPv6 clients.
|
||||||
|
# Note also the they [] around the IPv6 address are obilgatory.
|
||||||
|
#dhcp-host=id:00:01:00:01:16:d2:83:fc:92:d4:19:e2:d8:b2, fred, [1234::5]
|
||||||
|
|
||||||
# Ignore any clients which are not specified in dhcp-host lines
|
# Ignore any clients which are not specified in dhcp-host lines
|
||||||
# or /etc/ethers. Equivalent to ISC "deny unknown-clients".
|
# or /etc/ethers. Equivalent to ISC "deny unknown-clients".
|
||||||
# This relies on the special "known" tag which is set when
|
# This relies on the special "known" tag which is set when
|
||||||
@@ -270,6 +283,9 @@
|
|||||||
# Set the NTP time server addresses to 192.168.0.4 and 10.10.0.5
|
# Set the NTP time server addresses to 192.168.0.4 and 10.10.0.5
|
||||||
#dhcp-option=option:ntp-server,192.168.0.4,10.10.0.5
|
#dhcp-option=option:ntp-server,192.168.0.4,10.10.0.5
|
||||||
|
|
||||||
|
# Send DHCPv6 option. Note [] around IPv6 addresses.
|
||||||
|
dhcp-option=option6:dns-server,[1234::77],[1234::88]
|
||||||
|
|
||||||
# Set the NTP time server address to be the same machine as
|
# Set the NTP time server address to be the same machine as
|
||||||
# is running dnsmasq
|
# is running dnsmasq
|
||||||
#dhcp-option=42,0.0.0.0
|
#dhcp-option=42,0.0.0.0
|
||||||
|
|||||||
@@ -358,4 +358,90 @@ void dhcp_update_configs(struct dhcp_config *configs)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_DHCP6
|
||||||
|
static int join_multicast_worker(struct in6_addr *local, int prefix,
|
||||||
|
int scope, int if_index, int dad, void *vparam)
|
||||||
|
{
|
||||||
|
char ifrn_name[IFNAMSIZ];
|
||||||
|
struct ipv6_mreq mreq;
|
||||||
|
int fd, i, max = *((int *)vparam);
|
||||||
|
struct dhcp_context *context;
|
||||||
|
struct iname *tmp;
|
||||||
|
|
||||||
|
(void)prefix;
|
||||||
|
(void)scope;
|
||||||
|
(void)dad;
|
||||||
|
|
||||||
|
/* record which interfaces we join on, so that we do it at most one per
|
||||||
|
interface, even when they have multiple addresses. Use outpacket
|
||||||
|
as an array of int, since it's always allocated here and easy
|
||||||
|
to expand for theoretical vast numbers of interfaces. */
|
||||||
|
for (i = 0; i < max; i++)
|
||||||
|
if (if_index == ((int *)daemon->outpacket.iov_base)[i])
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if ((fd = socket(PF_INET6, SOCK_DGRAM, 0)) == -1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!indextoname(fd, if_index, ifrn_name))
|
||||||
|
{
|
||||||
|
close(fd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
/* Are we doing DHCP on this interface? */
|
||||||
|
if (!iface_check(AF_INET6, (struct all_addr *)local, ifrn_name))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
|
||||||
|
if (tmp->name && (strcmp(tmp->name, ifrn_name) == 0))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* weird libvirt-inspired access control */
|
||||||
|
for (context = daemon->dhcp6; context; context = context->next)
|
||||||
|
if (!context->interface || strcmp(context->interface, ifrn_name) == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!context)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
mreq.ipv6mr_interface = if_index;
|
||||||
|
|
||||||
|
inet_pton(AF_INET6, ALL_RELAY_AGENTS_AND_SERVERS, &mreq.ipv6mr_multiaddr);
|
||||||
|
|
||||||
|
if (daemon->dhcp6 &&
|
||||||
|
setsockopt(daemon->dhcp6fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) == -1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
inet_pton(AF_INET6, ALL_SERVERS, &mreq.ipv6mr_multiaddr);
|
||||||
|
|
||||||
|
if (daemon->dhcp6 &&
|
||||||
|
setsockopt(daemon->dhcp6fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) == -1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
inet_pton(AF_INET6, ALL_ROUTERS, &mreq.ipv6mr_multiaddr);
|
||||||
|
|
||||||
|
if (daemon->ra_contexts &&
|
||||||
|
setsockopt(daemon->icmp6fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) == -1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
expand_buf(&daemon->outpacket, (max+1) * sizeof(int));
|
||||||
|
((int *)daemon->outpacket.iov_base)[max++] = if_index;
|
||||||
|
|
||||||
|
*((int *)vparam) = max;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void join_multicast(void)
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
if (!iface_enumerate(AF_INET6, &count, join_multicast_worker))
|
||||||
|
die(_("failed to join DHCPv6 multicast group: %s"), NULL, EC_BADNET);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
88
src/dhcp6.c
88
src/dhcp6.c
@@ -24,14 +24,6 @@ struct iface_param {
|
|||||||
int ind;
|
int ind;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct listen_param {
|
|
||||||
int fd_or_iface;
|
|
||||||
struct listen_param *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int join_multicast(struct in6_addr *local, int prefix,
|
|
||||||
int scope, int if_index, int dad, void *vparam);
|
|
||||||
|
|
||||||
static int complete_context6(struct in6_addr *local, int prefix,
|
static int complete_context6(struct in6_addr *local, int prefix,
|
||||||
int scope, int if_index, int dad, void *vparam);
|
int scope, int if_index, int dad, void *vparam);
|
||||||
|
|
||||||
@@ -41,7 +33,6 @@ void dhcp6_init(void)
|
|||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
struct sockaddr_in6 saddr;
|
struct sockaddr_in6 saddr;
|
||||||
struct listen_param *listenp, listen;
|
|
||||||
#if defined(IP_TOS) && defined(IPTOS_CLASS_CS6)
|
#if defined(IP_TOS) && defined(IPTOS_CLASS_CS6)
|
||||||
int class = IPTOS_CLASS_CS6;
|
int class = IPTOS_CLASS_CS6;
|
||||||
#endif
|
#endif
|
||||||
@@ -65,88 +56,9 @@ void dhcp6_init(void)
|
|||||||
if (bind(fd, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in6)))
|
if (bind(fd, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in6)))
|
||||||
die(_("failed to bind DHCPv6 server socket: %s"), NULL, EC_BADNET);
|
die(_("failed to bind DHCPv6 server socket: %s"), NULL, EC_BADNET);
|
||||||
|
|
||||||
/* join multicast groups on each interface we're interested in */
|
|
||||||
listen.fd_or_iface = fd;
|
|
||||||
listen.next = NULL;
|
|
||||||
if (!iface_enumerate(AF_INET6, &listen, join_multicast))
|
|
||||||
die(_("failed to join DHCPv6 multicast group: %s"), NULL, EC_BADNET);
|
|
||||||
for (listenp = listen.next; listenp; )
|
|
||||||
{
|
|
||||||
struct listen_param *tmp = listenp->next;
|
|
||||||
free(listenp);
|
|
||||||
listenp = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
daemon->dhcp6fd = fd;
|
daemon->dhcp6fd = fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int join_multicast(struct in6_addr *local, int prefix,
|
|
||||||
int scope, int if_index, int dad, void *vparam)
|
|
||||||
{
|
|
||||||
char ifrn_name[IFNAMSIZ];
|
|
||||||
struct ipv6_mreq mreq;
|
|
||||||
struct listen_param *listenp, *param = vparam;
|
|
||||||
int fd = param->fd_or_iface;
|
|
||||||
struct dhcp_context *context;
|
|
||||||
struct iname *tmp;
|
|
||||||
|
|
||||||
(void)prefix;
|
|
||||||
(void)scope;
|
|
||||||
(void)dad;
|
|
||||||
|
|
||||||
/* record which interfaces we join on, so
|
|
||||||
that we do it at most one per interface, even when they
|
|
||||||
have multiple addresses */
|
|
||||||
for (listenp = param->next; listenp; listenp = listenp->next)
|
|
||||||
if (if_index == listenp->fd_or_iface)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if (!indextoname(fd, if_index, ifrn_name))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Are we doing DHCP on this interface? */
|
|
||||||
if (!iface_check(AF_INET6, (struct all_addr *)local, ifrn_name))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
|
|
||||||
if (tmp->name && (strcmp(tmp->name, ifrn_name) == 0))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
/* weird libvirt-inspired access control */
|
|
||||||
for (context = daemon->dhcp6; context; context = context->next)
|
|
||||||
if (!context->interface || strcmp(context->interface, ifrn_name) == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (!context)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
mreq.ipv6mr_interface = if_index;
|
|
||||||
|
|
||||||
inet_pton(AF_INET6, ALL_RELAY_AGENTS_AND_SERVERS, &mreq.ipv6mr_multiaddr);
|
|
||||||
|
|
||||||
if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) == -1)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
inet_pton(AF_INET6, ALL_SERVERS, &mreq.ipv6mr_multiaddr);
|
|
||||||
|
|
||||||
if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) == -1)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
inet_pton(AF_INET6, ALL_ROUTERS, &mreq.ipv6mr_multiaddr);
|
|
||||||
|
|
||||||
if (daemon->icmp6fd != -1 &&
|
|
||||||
setsockopt(daemon->icmp6fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) == -1)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
listenp = whine_malloc(sizeof(struct listen_param));
|
|
||||||
listenp->fd_or_iface = if_index;
|
|
||||||
listenp->next = param->next;
|
|
||||||
param->next = listenp;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void dhcp6_packet(time_t now)
|
void dhcp6_packet(time_t now)
|
||||||
{
|
{
|
||||||
struct dhcp_context *context;
|
struct dhcp_context *context;
|
||||||
|
|||||||
@@ -154,24 +154,41 @@ int main (int argc, char **argv)
|
|||||||
before lease_init to allocate buffers it uses.*/
|
before lease_init to allocate buffers it uses.*/
|
||||||
dhcp_common_init();
|
dhcp_common_init();
|
||||||
lease_init(now);
|
lease_init(now);
|
||||||
|
|
||||||
if (daemon->dhcp)
|
if (daemon->dhcp)
|
||||||
dhcp_init();
|
dhcp_init();
|
||||||
#ifdef HAVE_DHCP6
|
|
||||||
daemon->icmp6fd = -1;
|
|
||||||
if (daemon->dhcp6)
|
|
||||||
{
|
|
||||||
/* ra_init before dhcp6_init, so dhcp6_init can setup multicast listening */
|
|
||||||
if (option_bool(OPT_RA))
|
|
||||||
ra_init(now);
|
|
||||||
dhcp6_init();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ifdef HAVE_DHCP6
|
||||||
|
/* Start RA subsystem if --enable-ra OR dhcp-range=<subnet>, ra-only */
|
||||||
|
if (daemon->ra_contexts || option_bool(OPT_RA))
|
||||||
|
{
|
||||||
|
/* link the DHCP6 contexts to the ra-only ones so we can traverse them all
|
||||||
|
from ->ra_contexts, but only the non-ra-onlies from ->dhcp6 */
|
||||||
|
struct dhcp_context *context;
|
||||||
|
|
||||||
|
if (!daemon->ra_contexts)
|
||||||
|
daemon->ra_contexts = daemon->dhcp6;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (context = daemon->ra_contexts; context->next; context = context->next);
|
||||||
|
context->next = daemon->dhcp6;
|
||||||
|
}
|
||||||
|
ra_init(now);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (daemon->dhcp6)
|
||||||
|
dhcp6_init();
|
||||||
|
|
||||||
|
if (daemon->ra_contexts || daemon->dhcp6)
|
||||||
|
join_multicast();
|
||||||
|
# endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!enumerate_interfaces())
|
if (!enumerate_interfaces())
|
||||||
die(_("failed to find list of interfaces: %s"), NULL, EC_MISC);
|
die(_("failed to find list of interfaces: %s"), NULL, EC_MISC);
|
||||||
|
|
||||||
if (option_bool(OPT_NOWILD))
|
if (option_bool(OPT_NOWILD))
|
||||||
{
|
{
|
||||||
create_bound_listeners(1);
|
create_bound_listeners(1);
|
||||||
@@ -211,7 +228,8 @@ int main (int argc, char **argv)
|
|||||||
|
|
||||||
#if defined(HAVE_SCRIPT)
|
#if defined(HAVE_SCRIPT)
|
||||||
/* Note getpwnam returns static storage */
|
/* Note getpwnam returns static storage */
|
||||||
if ((daemon->dhcp || daemon->dhcp6) && daemon->scriptuser &&
|
if ((daemon->dhcp || daemon->dhcp6) &&
|
||||||
|
daemon->scriptuser &&
|
||||||
(daemon->lease_change_command || daemon->luascript))
|
(daemon->lease_change_command || daemon->luascript))
|
||||||
{
|
{
|
||||||
if ((ent_pw = getpwnam(daemon->scriptuser)))
|
if ((ent_pw = getpwnam(daemon->scriptuser)))
|
||||||
@@ -502,7 +520,7 @@ int main (int argc, char **argv)
|
|||||||
if (daemon->max_logs != 0)
|
if (daemon->max_logs != 0)
|
||||||
my_syslog(LOG_INFO, _("asynchronous logging enabled, queue limit is %d messages"), daemon->max_logs);
|
my_syslog(LOG_INFO, _("asynchronous logging enabled, queue limit is %d messages"), daemon->max_logs);
|
||||||
|
|
||||||
if (option_bool(OPT_RA))
|
if (daemon->ra_contexts)
|
||||||
my_syslog(MS_DHCP | LOG_INFO, _("IPv6 router advertisement enabled"));
|
my_syslog(MS_DHCP | LOG_INFO, _("IPv6 router advertisement enabled"));
|
||||||
|
|
||||||
#ifdef HAVE_DHCP
|
#ifdef HAVE_DHCP
|
||||||
@@ -668,7 +686,7 @@ int main (int argc, char **argv)
|
|||||||
FD_SET(daemon->dhcp6fd, &rset);
|
FD_SET(daemon->dhcp6fd, &rset);
|
||||||
bump_maxfd(daemon->dhcp6fd, &maxfd);
|
bump_maxfd(daemon->dhcp6fd, &maxfd);
|
||||||
|
|
||||||
if (daemon->icmp6fd != -1)
|
if (daemon->ra_contexts)
|
||||||
{
|
{
|
||||||
FD_SET(daemon->icmp6fd, &rset);
|
FD_SET(daemon->icmp6fd, &rset);
|
||||||
bump_maxfd(daemon->icmp6fd, &maxfd);
|
bump_maxfd(daemon->icmp6fd, &maxfd);
|
||||||
@@ -777,7 +795,7 @@ int main (int argc, char **argv)
|
|||||||
if (FD_ISSET(daemon->dhcp6fd, &rset))
|
if (FD_ISSET(daemon->dhcp6fd, &rset))
|
||||||
dhcp6_packet(now);
|
dhcp6_packet(now);
|
||||||
|
|
||||||
if (daemon->icmp6fd != -1 && FD_ISSET(daemon->icmp6fd, &rset))
|
if (daemon->ra_contexts && FD_ISSET(daemon->icmp6fd, &rset))
|
||||||
icmp6_packet();
|
icmp6_packet();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -953,6 +971,16 @@ static void async_event(int pipe, time_t now)
|
|||||||
lease_prune(NULL, now);
|
lease_prune(NULL, now);
|
||||||
lease_update_file(now);
|
lease_update_file(now);
|
||||||
}
|
}
|
||||||
|
#ifdef HAVE_DHCP6
|
||||||
|
else if (daemon->ra_contexts)
|
||||||
|
{
|
||||||
|
/* Not doing DHCP, so no lease system, manage
|
||||||
|
alarms for ra only */
|
||||||
|
time_t next_event = periodic_ra(now);
|
||||||
|
if (next_event != 0)
|
||||||
|
alarm((unsigned)difftime(next_event, now));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1117,6 +1145,16 @@ void clear_cache_and_reload(time_t now)
|
|||||||
lease_update_file(now);
|
lease_update_file(now);
|
||||||
lease_update_dns();
|
lease_update_dns();
|
||||||
}
|
}
|
||||||
|
#ifdef HAVE_DHCP6
|
||||||
|
else if (daemon->ra_contexts)
|
||||||
|
{
|
||||||
|
/* Not doing DHCP, so no lease system, manage
|
||||||
|
alarms for ra only */
|
||||||
|
time_t next_event = periodic_ra(now);
|
||||||
|
if (next_event != 0)
|
||||||
|
alarm((unsigned)difftime(next_event, now));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1402,7 +1440,7 @@ int icmp_ping(struct in_addr addr)
|
|||||||
set_log_writer(&wset, &maxfd);
|
set_log_writer(&wset, &maxfd);
|
||||||
|
|
||||||
#ifdef HAVE_DHCP6
|
#ifdef HAVE_DHCP6
|
||||||
if (daemon->icmp6fd != -1)
|
if (daemon->ra_contexts)
|
||||||
{
|
{
|
||||||
FD_SET(daemon->icmp6fd, &rset);
|
FD_SET(daemon->icmp6fd, &rset);
|
||||||
bump_maxfd(daemon->icmp6fd, &maxfd);
|
bump_maxfd(daemon->icmp6fd, &maxfd);
|
||||||
@@ -1421,7 +1459,7 @@ int icmp_ping(struct in_addr addr)
|
|||||||
check_dns_listeners(&rset, now);
|
check_dns_listeners(&rset, now);
|
||||||
|
|
||||||
#ifdef HAVE_DHCP6
|
#ifdef HAVE_DHCP6
|
||||||
if (daemon->icmp6fd != -1 && FD_ISSET(daemon->icmp6fd, &rset))
|
if (daemon->ra_contexts && FD_ISSET(daemon->icmp6fd, &rset))
|
||||||
icmp6_packet();
|
icmp6_packet();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -1059,6 +1059,9 @@ void log_tags(struct dhcp_netid *netid, u32 xid);
|
|||||||
int match_bytes(struct dhcp_opt *o, unsigned char *p, int len);
|
int match_bytes(struct dhcp_opt *o, unsigned char *p, int len);
|
||||||
void dhcp_update_configs(struct dhcp_config *configs);
|
void dhcp_update_configs(struct dhcp_config *configs);
|
||||||
void check_dhcp_hosts(int fatal);
|
void check_dhcp_hosts(int fatal);
|
||||||
|
# ifdef HAVE_DHCP6
|
||||||
|
void join_multicast(void);
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* outpacket.c */
|
/* outpacket.c */
|
||||||
|
|||||||
@@ -317,7 +317,7 @@ void lease_update_file(time_t now)
|
|||||||
|
|
||||||
#ifdef HAVE_DHCP6
|
#ifdef HAVE_DHCP6
|
||||||
/* do timed RAs and determine when the next is */
|
/* do timed RAs and determine when the next is */
|
||||||
if (option_bool(OPT_RA))
|
if (daemon->ra_contexts)
|
||||||
next_event = periodic_ra(now);
|
next_event = periodic_ra(now);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -343,7 +343,7 @@ static void nl_routechange(struct nlmsghdr *h)
|
|||||||
|
|
||||||
#ifdef HAVE_DHCP6
|
#ifdef HAVE_DHCP6
|
||||||
/* force RAs to sync new network and pick up new interfaces. */
|
/* force RAs to sync new network and pick up new interfaces. */
|
||||||
if (option_bool(OPT_RA))
|
if (daemon->ra_contexts)
|
||||||
{
|
{
|
||||||
ra_start_unsolicted(dnsmasq_time());
|
ra_start_unsolicted(dnsmasq_time());
|
||||||
/* cause lease_update_file to run after we return, in case we were called from
|
/* cause lease_update_file to run after we return, in case we were called from
|
||||||
|
|||||||
22
src/radv.c
22
src/radv.c
@@ -15,9 +15,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* NB. This code may be called during a DHCPv4 transaction which is in ping-wait
|
/* NB. This code may be called during a DHCPv4 or transaction which is in ping-wait
|
||||||
It therefore cannot use any DHCP buffer resources except outpacket, which is
|
It therefore cannot use any DHCP buffer resources except outpacket, which is
|
||||||
not used by DHCPv4 code. */
|
not used by DHCPv4 code. This code may also be called when DHCP 4 or 6 isn't
|
||||||
|
active, so we ensure that outpacket is allocated here too */
|
||||||
|
|
||||||
#include "dnsmasq.h"
|
#include "dnsmasq.h"
|
||||||
|
|
||||||
@@ -47,7 +48,6 @@ static time_t ra_short_period_start;
|
|||||||
|
|
||||||
void ra_init(time_t now)
|
void ra_init(time_t now)
|
||||||
{
|
{
|
||||||
struct dhcp_context *context;
|
|
||||||
struct icmp6_filter filter;
|
struct icmp6_filter filter;
|
||||||
int fd;
|
int fd;
|
||||||
#if defined(IP_TOS) && defined(IPTOS_CLASS_CS6)
|
#if defined(IP_TOS) && defined(IPTOS_CLASS_CS6)
|
||||||
@@ -56,6 +56,9 @@ void ra_init(time_t now)
|
|||||||
int val = 255; /* radvd uses this value */
|
int val = 255; /* radvd uses this value */
|
||||||
size_t len = sizeof(int);
|
size_t len = sizeof(int);
|
||||||
|
|
||||||
|
/* ensure this is around even if we're not doing DHCPv6 */
|
||||||
|
expand_buf(&daemon->outpacket, sizeof(struct dhcp_packet));
|
||||||
|
|
||||||
ICMP6_FILTER_SETBLOCKALL(&filter);
|
ICMP6_FILTER_SETBLOCKALL(&filter);
|
||||||
ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT, &filter);
|
ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT, &filter);
|
||||||
ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter);
|
ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter);
|
||||||
@@ -74,19 +77,6 @@ void ra_init(time_t now)
|
|||||||
|
|
||||||
daemon->icmp6fd = fd;
|
daemon->icmp6fd = fd;
|
||||||
|
|
||||||
/* link the DHCP6 contexts to the ra-only ones so we can traverse them all
|
|
||||||
from ->ra_contexts, but only the non-ra-onlies from ->dhcp6 */
|
|
||||||
if (!daemon->ra_contexts)
|
|
||||||
daemon->ra_contexts = daemon->dhcp6;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (context = daemon->ra_contexts; context->next; context = context->next);
|
|
||||||
context->next = daemon->dhcp6;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!daemon->dhcp6)
|
|
||||||
die(_("cannot do router advertisement unless DHCPv6 is enabled"), NULL, EC_BADCONF);
|
|
||||||
|
|
||||||
ra_start_unsolicted(now);
|
ra_start_unsolicted(now);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user