Don't send RAs to the wrong place when DAD in progress.
diff --git a/src/radv.c b/src/radv.c
index 90678a4..25bcb54 100644
--- a/src/radv.c
+++ b/src/radv.c
@@ -457,6 +457,7 @@
char interface[IF_NAMESIZE+1];
param.now = now;
+ param.iface = 0;
while (1)
{
@@ -482,7 +483,8 @@
ever be able to send ra's and satistfy it. */
if (iface_enumerate(AF_INET6, ¶m, iface_search))
context->ra_time = 0;
- else if (indextoname(daemon->icmp6fd, param.iface, interface) &&
+ else if (param.iface != 0 &&
+ indextoname(daemon->icmp6fd, param.iface, interface) &&
iface_check(AF_LOCAL, NULL, interface))
{
struct iname *tmp;
@@ -512,9 +514,11 @@
if (context->ra_time != 0 && difftime(context->ra_time, param->now) <= 0.0)
{
/* found an interface that's overdue for RA determine new
- timeout value and zap other contexts on the same interface
- so they don't timeout independently .*/
- param->iface = if_index;
+ timeout value and arrange for RA to be sent unless interface is
+ still doing DAD.*/
+
+ if (!dad)
+ param->iface = if_index;
if (difftime(param->now, ra_short_period_start) < 60.0)
/* range 5 - 20 */
@@ -523,6 +527,14 @@
/* range 450 - 600 */
context->ra_time = param->now + 450 + (rand16()/440);
+ /* zero timers for other contexts on the same subnet, so they don't timeout
+ independently */
+ for (context = context->next; context; context = context->next)
+ if (prefix == context->prefix &&
+ is_same_net6(local, &context->start6, prefix) &&
+ is_same_net6(local, &context->end6, prefix))
+ context->ra_time = 0;
+
return 0; /* found, abort */
}