ok reyk@ but we should think about putting it in all copies of kroute.c

On Thu, Apr 21, 2011 at 01:24:36PM +0100, Stuart Henderson wrote:
> 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