On 2016/09/02 10:37, Florian Obser wrote:
> Our kernel based rtsol code is like this little child.  We bring up
> the interface, send our first solicitation and get an advertisment
> back with a pltime of a week or so.
> 
> We lean back, quite happy that we can do v6 now, but after 60 seconds
> we wake up, oh shit, better check if that prefix is still valid. and
> so on and on.
> 
> This is particularly annoying if you try to debug ICMPv6 with tcpdump
> in a network with a lot of openbsd machines.
> 
> To stop naddy from pestering me about this at every hackathon (rightly
> so!), let's base the timeout on the prefixes pltime. ;)

There's a problem with this: we lose the exponential backoff for the
quick timer. Say you have v6 at home and enable autoconf on your laptop
then move to a network without v6 - this results in you spamming the
network with a multicast frame every second, which does not make you
a good network citizen especially if that's on a wireless lan.

 310 void
 311 nd6_rs_output_timo(void *ignored_arg)
 312 {
 313         struct ifnet *ifp;
 314         struct in6_ifaddr *ia6;
 315         u_int32_t pltime_expire = ND6_INFINITE_LIFETIME, t;
 316         int timeout = ND6_RS_OUTPUT_INTERVAL;
 318         if (nd6_rs_timeout_count == 0)
 319                 return;
 320                 
 321         if (nd6_rs_output_timeout < ND6_RS_OUTPUT_INTERVAL)
 322                 /* exponential backoff if running quick timeouts */
 323                 timeout = nd6_rs_output_timeout * 2;

I've tried a few things along the lines of these here instead

             if (nd6_rs_output_timeout < ND6_RS_OUTPUT_INTERVAL) {
                        nd6_rs_output_timeout *= 2;
                        timeout = nd6_rs_output_timeout;
             }

but haven't hit on a working combination yet.

I think the current state is quite a lot worse than the previous one
(even though it's better on networks that *do* have v6), so I'm wondering
if it might be better to revert if it's complicated to fix here (there
was a different plan for sending RS in the future anyway wasn't there?)

 324                 
 325         TAILQ_FOREACH(ifp, &ifnet, if_list) {
 326                 if (ISSET(ifp->if_flags, IFF_RUNNING) &&
 327                     ISSET(ifp->if_xflags, IFXF_AUTOCONF6)) {
 328                         t = nd6_rs_next_pltime_timo(ifp);
 329                         if (t == ND6_INFINITE_LIFETIME || t <
 330                             ND6_RS_OUTPUT_INTERVAL) {
 331                                 timeout = ND6_RS_OUTPUT_QUICK_INTERVAL;
 332                                 ia6 = in6ifa_ifpforlinklocal(ifp,
 333                                     IN6_IFF_TENTATIVE);
 334                                 if (ia6 != NULL)
 335                                         nd6_rs_output(ifp, ia6);
 336                         }               
 337                         
 338                         pltime_expire = MIN(pltime_expire, t);
 339                 }       
 340         }       
 341         if (pltime_expire != ND6_INFINITE_LIFETIME)
 342                 timeout = MAX(timeout, pltime_expire / 2);
 343                 
 344         nd6_rs_output_set_timo(timeout);
 345 }  

Reply via email to