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 */