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?




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)

Reply via email to