Already heard from.Florian - I'm travelling to fix a router today but
this is what I plan to commit after I'm back and have gained confidence
in it :)

More changes may make sense but this seems a useful initial change.

Index: slaacd.c
===================================================================
RCS file: /cvs/src/sbin/slaacd/slaacd.c,v
retrieving revision 1.23
diff -u -p -r1.23 slaacd.c
--- slaacd.c    18 Jun 2018 16:13:45 -0000      1.23
+++ slaacd.c    6 Jul 2018 11:16:08 -0000
@@ -244,8 +244,9 @@ main(int argc, char *argv[])
        log_procinit(log_procnames[slaacd_process]);
 
        if ((routesock = socket(PF_ROUTE, SOCK_RAW | SOCK_CLOEXEC |
-           SOCK_NONBLOCK, 0)) < 0)
+           SOCK_NONBLOCK, AF_INET6)) < 0)
                fatal("route socket");
+       shutdown(SHUT_RD, routesock);
 
        event_init();
 
@@ -304,8 +305,8 @@ main(int argc, char *argv[])
            sizeof(filt)) == -1)
                fatal("ICMP6_FILTER");
 
-       if ((frontend_routesock = socket(PF_ROUTE, SOCK_RAW | SOCK_CLOEXEC, 0))
-           < 0)
+       if ((frontend_routesock = socket(PF_ROUTE, SOCK_RAW | SOCK_CLOEXEC,
+           AF_INET6)) < 0)
                fatal("route socket");
 
        rtfilter = ROUTE_FILTER(RTM_IFINFO) | ROUTE_FILTER(RTM_NEWADDR) |


On 2018/07/06 13:13, Sebastian Benoit wrote:
> Claudio Jeker([email protected]) on 2018.07.06 07:44:43 +0200:
> > On Thu, Jul 05, 2018 at 10:51:24PM +0100, Stuart Henderson wrote:
> > > I noticed relatively high cpu use from slaacd on a BGP router
> > > that was undergoing some route churn earlier (no interfaces were
> > > actually configured to use slaac).
> > > 
> > > routesock is currently unfiltered so will see a lot of messages,
> > > frontend_routesock is filtered but will still see all RTM_DELETE
> > > which will be noticeable during churn.
> > > 
> > > Seems that we may be able to restrict these to inet6 (kernel comment
> > > is, "If route socket is bound to an address family only send messages
> > > that match the address family. Address family agnostic messages are
> > > always sent.") Does this make sense or am I missing something about
> > > the messages needed by slaacd?
> > > 
> > 
> > In my opinion this is the right thing to do.
> > RTM_IFINFO is always sent, RTM_NEWADDR and RTM_DELADDR will be filtered
> > based on the address family as is RTM_DELETE. Those should be fine.
> > My question mark is about RTM_PROPOSAL. Does slaacd need to see dhclient
> > RTM_PROPOSAL messages? Looking at the code it does not seem like that is
> > the case.
> 
> well, if the ideas around RTM_PROPOSAL, ie networkd ever come to fruition,
> its going to send and receive(?) RTM_PROPOSAL.
> 
> I dont know if it even needs to see all messages of AF_INET6 on the
> routesock. If not, maybe it could also use the prio filter here.
> 
> > Also it seems routesock is never read so it should be
> >     shutdown(routesock, SHUT_RD);
> > 
> > OK claudio@ (which is not much worth when it comes to AF_INET6 :))
> 
> come to the dark side, we have cookies (and more ip addresses).
> 
> ok benno@, but maybe wait until florian can respond.
> 
> > > 
> > > Index: slaacd.c
> > > ===================================================================
> > > RCS file: /cvs/src/sbin/slaacd/slaacd.c,v
> > > retrieving revision 1.23
> > > diff -u -p -u -7 -r1.23 slaacd.c
> > > --- slaacd.c      18 Jun 2018 16:13:45 -0000      1.23
> > > +++ slaacd.c      5 Jul 2018 21:44:38 -0000
> > > @@ -240,15 +240,15 @@ main(int argc, char *argv[])
> > >       pipe_main2frontend[1], debug, verbose);
> > >  
> > >   slaacd_process = PROC_MAIN;
> > >  
> > >   log_procinit(log_procnames[slaacd_process]);
> > >  
> > >   if ((routesock = socket(PF_ROUTE, SOCK_RAW | SOCK_CLOEXEC |
> > > -     SOCK_NONBLOCK, 0)) < 0)
> > > +     SOCK_NONBLOCK, AF_INET6)) < 0)
> > >           fatal("route socket");
> > >  
> > >   event_init();
> > >  
> > >   /* Setup signal handler. */
> > >   signal_set(&ev_sigint, SIGINT, main_sig_handler, NULL);
> > >   signal_set(&ev_sigterm, SIGTERM, main_sig_handler, NULL);
> > > @@ -300,16 +300,16 @@ main(int argc, char *argv[])
> > >   /* only router advertisements */
> > >   ICMP6_FILTER_SETBLOCKALL(&filt);
> > >   ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filt);
> > >   if (setsockopt(icmp6sock, IPPROTO_ICMPV6, ICMP6_FILTER, &filt,
> > >       sizeof(filt)) == -1)
> > >           fatal("ICMP6_FILTER");
> > >  
> > > - if ((frontend_routesock = socket(PF_ROUTE, SOCK_RAW | SOCK_CLOEXEC, 0))
> > > -     < 0)
> > > + if ((frontend_routesock = socket(PF_ROUTE, SOCK_RAW | SOCK_CLOEXEC,
> > > +     AF_INET6)) < 0)
> > >           fatal("route socket");
> > >  
> > >   rtfilter = ROUTE_FILTER(RTM_IFINFO) | ROUTE_FILTER(RTM_NEWADDR) |
> > >       ROUTE_FILTER(RTM_DELADDR) | ROUTE_FILTER(RTM_PROPOSAL) |
> > >       ROUTE_FILTER(RTM_DELETE);
> > >   if (setsockopt(frontend_routesock, PF_ROUTE, ROUTE_MSGFILTER,
> > >       &rtfilter, sizeof(rtfilter)) < 0)
> > > 
> > 
> > -- 
> > :wq Claudio
> > 
> 

Reply via email to