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. 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 :)) > > 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