Diff below adds a "filter-routes" option, defaulting to "no".
"yesno" borrowed from bgpd's parser.

I've been using a similar diff (but without the config option)
for a while on my BGP routers where I want to monitor interface
information via SNMP but don't care about fetching the routing
table that way.

It seriously reduces CPU time when a major peer bounces (or
when bgp is coming back up after the rde eats all available
ram and crashes).

  PID USERNAME PRI NICE  SIZE   RES STATE     WAIT      TIME    CPU COMMAND
 7565 _bgpd      2    0  123M  124M sleep/1   poll      0:44 28.22% bgpd: route 
decision engine
30322 _snmpd     2    0   20M   21M sleep/0   kqread    0:06 10.89% snmpd: snmp 
engine
18490 root       2    0   20M   21M sleep/0   poll      0:20  9.77% bgpd: parent
23183 _bgpd      2    0  948K 1480K sleep/0   poll      0:05  1.71% bgpd: 
session engine

Any comments? ok?

Index: kroute.c
===================================================================
RCS file: /cvs/src/usr.sbin/snmpd/kroute.c,v
retrieving revision 1.16
diff -u -p -r1.16 kroute.c
--- kroute.c    7 Mar 2011 07:43:02 -0000       1.16
+++ kroute.c    21 Apr 2011 12:15:41 -0000
@@ -45,6 +45,8 @@
 
 #include "snmpd.h"
 
+extern struct snmpd    *env;
+
 struct {
        struct event             ks_ev;
        u_long                   ks_iflastchange;
@@ -159,6 +161,10 @@ kr_init(void)
        if (setsockopt(kr_state.ks_fd, SOL_SOCKET, SO_USELOOPBACK,
            &opt, sizeof(opt)) == -1)
                log_warn("kr_init: setsockopt");        /* not fatal */
+
+       if (env->sc_rtfilter && setsockopt(kr_state.ks_fd, PF_ROUTE,
+           ROUTE_MSGFILTER, &env->sc_rtfilter, sizeof(env->sc_rtfilter)) == -1)
+               log_warn("kr_init: setsockopt(ROUTE_MSGFILTER)");
 
        /* grow receive buffer, don't wanna miss messages */
        optlen = sizeof(default_rcvbuf);
Index: parse.y
===================================================================
RCS file: /cvs/src/usr.sbin/snmpd/parse.y,v
retrieving revision 1.19
diff -u -p -r1.19 parse.y
--- parse.y     18 Oct 2010 13:29:49 -0000      1.19
+++ parse.y     21 Apr 2011 12:15:41 -0000
@@ -112,13 +112,13 @@ typedef struct {
 
 %token INCLUDE
 %token  LISTEN ON
-%token SYSTEM CONTACT DESCR LOCATION NAME OBJECTID SERVICES
+%token SYSTEM CONTACT DESCR LOCATION NAME OBJECTID SERVICES RTFILTER
 %token READONLY READWRITE OCTETSTRING INTEGER COMMUNITY TRAP RECEIVER
 %token ERROR
 %token <v.string>      STRING
 %token  <v.number>     NUMBER
 %type  <v.string>      hostcmn
-%type  <v.number>      optwrite
+%type  <v.number>      optwrite yesno
 %type  <v.data>        objtype
 %type  <v.oid>         oid hostoid
 
@@ -157,6 +157,21 @@ varset             : STRING '=' STRING     {
                }
                ;
 
+yesno          :  STRING                       {
+                       if (!strcmp($1, "yes"))
+                               $$ = 1;
+                       else if (!strcmp($1, "no"))
+                               $$ = 0;
+                       else {
+                               yyerror("syntax error, "
+                                   "either yes or no expected");
+                               free($1);
+                               YYERROR;
+                       }
+                       free($1);
+               }
+               ;
+
 main           : LISTEN ON STRING              {
                        struct addresslist       al;
                        struct address          *h;
@@ -212,6 +227,15 @@ main               : LISTEN ON STRING              {
                } host                          {
                        hlist = NULL;
                }
+               | RTFILTER yesno                {
+                       if ($2 == 1)
+                               conf->sc_rtfilter = ROUTE_FILTER(RTM_NEWADDR) |
+                                   ROUTE_FILTER(RTM_DELADDR) |
+                                   ROUTE_FILTER(RTM_IFINFO) |
+                                   ROUTE_FILTER(RTM_IFANNOUNCE);
+                       else
+                               conf->sc_rtfilter = 0;
+               }
                ;
 
 system         : SYSTEM sysmib
@@ -378,6 +402,7 @@ lookup(char *s)
                { "community",          COMMUNITY },
                { "contact",            CONTACT },
                { "description",        DESCR },
+               { "filter-routes",      RTFILTER },
                { "include",            INCLUDE },
                { "integer",            INTEGER },
                { "listen",             LISTEN },
Index: snmpd.conf.5
===================================================================
RCS file: /cvs/src/usr.sbin/snmpd/snmpd.conf.5,v
retrieving revision 1.13
diff -u -p -r1.13 snmpd.conf.5
--- snmpd.conf.5        18 Jul 2010 08:03:04 -0000      1.13
+++ snmpd.conf.5        21 Apr 2011 12:15:41 -0000
@@ -85,6 +85,18 @@ Specify the name of the read-write commu
 The default value is
 .Ar private .
 .Pp
+.It Xo
+.Ic filter-routes
+.Pq Ic yes Ns \&| Ns Ic no
+.Xc
+If set to
+.Ic yes ,
+ask the kernel to filter route update messages on the routing socket.
+Routing table information will not be available, but CPU use will be
+reduced during bulk updates.
+The default is
+.Ic no .
+.Pp
 .It Ic system contact Ar string
 Specify the name or description of the system contact, typically a
 name or an e-mail address.
Index: snmpd.h
===================================================================
RCS file: /cvs/src/usr.sbin/snmpd/snmpd.h,v
retrieving revision 1.30
diff -u -p -r1.30 snmpd.h
--- snmpd.h     20 Sep 2010 08:56:16 -0000      1.30
+++ snmpd.h     21 Apr 2011 12:15:41 -0000
@@ -303,6 +303,7 @@ struct snmpd {
 
        int                      sc_ncpu;
        int64_t                 *sc_cpustates;
+       int                      sc_rtfilter;
 };
 
 /* control.c */

Reply via email to