- // Rearm timer
- int msecs;
- odhcpd_urandom(&msecs, sizeof(msecs));
- msecs = (labs(msecs) % (1000 * (MaxRtrAdvInterval
- - MinRtrAdvInterval))) + (MinRtrAdvInterval * 1000);
- uloop_timeout_set(&iface->timer_rs, msecs);
+ // Rearm timer if not shut down
+ if (event->cb) {
+ uint32_t maxinterval = MaxRtrAdvInterval * 1000;
+ uint32_t mininterval = MinRtrAdvInterval * 1000;
+
+ if (maxpreferred > 0 && maxinterval > maxpreferred / 2) {
+ maxinterval = maxpreferred / 2;
+ if (maxinterval < 4000)
+ maxinterval = 4000;
+
+ if (maxinterval >= 9000)
+ mininterval = maxinterval / 3;
+ else
+ mininterval = (maxinterval * 3) / 4;
+ }
+
+ int msecs;
+ odhcpd_urandom(&msecs, sizeof(msecs));
+ msecs = (labs(msecs) % (maxinterval - mininterval)) + mininterval;
+ uloop_timeout_set(&iface->timer_rs, msecs);
+ }