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