I'm on the fence about this. So if you feel strongly about this go
ahead if it works.
I am however somewhat confused about your description. You say it
times out, but considering it (by default) only retrieves 10 entries
per packet it should return somewhat quick and not cause a timeout.
If you want to move through it quicker you can increase the amount
retrieved per request by setting -CrX where X can be any value.
I reckon -Cr40 is a decent number.

Another option is to just skip that OID altogether by specifying
-CE <oid> which terminates the walk at that OID and continue from
there in one form or the other.

A third option is for snmp(1), the diff below could give a more general
solution, but won't work with a bulkwalk and it hits objects that
actually cause a timeout (although playing around with -t might help
there).
Note that this diff is hacked together in a couple of minutes and not
very well tested, but seems to work:

$ ./obj/snmp bulkwalk -Cp -Cs sysORIndex -Cs sysOrDescr 127.0.0.1 sysORTable
sysORID.1 = OID: mib_2
sysORID.2 = OID: ipMIB
sysORID.3 = OID: ipfMIB
sysORID.4 = OID: snmp
sysORID.5 = OID: dot1dBridge
sysORID.6 = OID: host
sysORID.7 = OID: ifMIB
sysORID.8 = OID: ucdDiskIOMIB
sysORID.9 = OID: pfMIBObjects
sysORID.10 = OID: sensorsMIBObjects
sysORID.11 = OID: memMIBObjects
sysORID.12 = OID: carpMIBObjects
sysORID.13 = OID: snmpEngine
sysORID.14 = OID: usmStats
sysORUpTime.1 = Timeticks: (0) 0:00:00.00
sysORUpTime.2 = Timeticks: (0) 0:00:00.00
sysORUpTime.3 = Timeticks: (0) 0:00:00.00
sysORUpTime.4 = Timeticks: (0) 0:00:00.00
sysORUpTime.5 = Timeticks: (0) 0:00:00.00
sysORUpTime.6 = Timeticks: (0) 0:00:00.00
sysORUpTime.7 = Timeticks: (0) 0:00:00.00
sysORUpTime.8 = Timeticks: (0) 0:00:00.00
sysORUpTime.9 = Timeticks: (0) 0:00:00.00
sysORUpTime.10 = Timeticks: (0) 0:00:00.00
sysORUpTime.11 = Timeticks: (0) 0:00:00.00
sysORUpTime.12 = Timeticks: (0) 0:00:00.00
sysORUpTime.13 = Timeticks: (0) 0:00:00.00
sysORUpTime.14 = Timeticks: (0) 0:00:00.00
Variables found: 28

martijn@

On 12/30/19 10:08 PM, Florian Obser wrote:
> 
> My MXs store about 300k addresses in block lists. Trying to export
> them via the OPENBSD-PF-MIB::pfTblAddrTable oid is not working out.
> It's also not sensible. snmpbulkwalk will eventually just time out and
> while snmpd tries to export the tables it spins at 100% cpu.
> 
> This adds filter-pf-addresses similar to filter-routers to stop snmpd
> from exporting under OPENBSD-PF-MIB::pfTblAddrTable.
> 
> (Happy to hear suggestions for a better name.)
> 
> I'm new to this, is this the right way to do this? Comments, OKs?
> 

Index: snmp.1
===================================================================
RCS file: /cvs/src/usr.bin/snmp/snmp.1,v
retrieving revision 1.8
diff -u -p -r1.8 snmp.1
--- snmp.1      26 Oct 2019 17:43:52 -0000      1.8
+++ snmp.1      31 Dec 2019 10:10:21 -0000
@@ -256,6 +256,17 @@ This determines the amount of MIBs to re
 This value defaults to 10.
 No blank is allowed before
 .Ar maxrep .
+.It Cm s Ar skipoid
+For
+.Cm walk
+or
+.Cm bulkwalk
+don't include
+.Ar skipoid
+or its children in the walk output.
+The blank before
+.Ar skipoid
+is mandatory.
 .It Cm t
 For
 .Cm walk ,
Index: snmpc.c
===================================================================
RCS file: /cvs/src/usr.bin/snmp/snmpc.c,v
retrieving revision 1.17
diff -u -p -r1.17 snmpc.c
--- snmpc.c     26 Oct 2019 19:34:15 -0000      1.17
+++ snmpc.c     31 Dec 2019 10:10:21 -0000
@@ -95,6 +95,8 @@ int smi_print_hint = 1;
 int non_repeaters = 0;
 int max_repetitions = 10;
 struct ber_oid walk_end = {{0}, 0};
+struct ber_oid *walk_skip = NULL;
+size_t walk_skip_len = 0;
 enum smi_oid_lookup oid_lookup = smi_oidl_short;
 enum smi_output_string output_string = smi_os_default;
 
@@ -327,6 +329,23 @@ main(int argc, char *argv[])
                                                errx(1, "-Cr invalid argument");
                                        i = strtolp - optarg - 1;
                                        break;
+                               case 's':
+                                       if (strcmp(snmp_app->name, "walk") &&
+                                           strcmp(snmp_app->name, "bulkwalk"))
+                                               usage();
+                                       if ((walk_skip = recallocarray(
+                                           walk_skip, walk_skip_len,
+                                           walk_skip_len + 1,
+                                           sizeof(*walk_skip))) == NULL)
+                                               errx(1, "malloc");
+                                       if (smi_string2oid(argv[optind],
+                                           &(walk_skip[walk_skip_len])) != 0)
+                                               errx(1, "%s: %s",
+                                                   "Unknown Object Identifier",
+                                                   argv[optind]);
+                                       walk_skip_len++;
+                                       optind++;
+                                       break;
                                case 't':
                                        if (strcmp(snmp_app->name, "walk"))
                                                usage();
@@ -548,9 +567,10 @@ snmpc_walk(int argc, char *argv[])
        struct timespec start, finish;
        struct snmp_agent *agent;
        const char *oids;
-       int n = 0, prev_cmp;
+       int n = 0, prev_cmp, skip_cmp;
        int errorstatus, errorindex;
        int class;
+       size_t i;
        unsigned type;
 
        if (strcmp(snmp_app->name, "bulkwalk") == 0 && version < SNMP_V2C)
@@ -592,6 +612,14 @@ snmpc_walk(int argc, char *argv[])
                n++;
        }
        while (1) {
+               for (i = 0; i < walk_skip_len; i++) {
+                       skip_cmp = ober_oid_cmp(&(walk_skip[i]), &noid);
+                       if (skip_cmp == 0 || skip_cmp == 2) {
+                               bcopy(&(walk_skip[i]), &noid, sizeof(noid));
+                               noid.bo_id[noid.bo_n -1]++;
+                               break;
+                       }
+               }
                bcopy(&noid, &loid, sizeof(loid));
                if (strcmp(snmp_app->name, "bulkwalk") == 0) {
                        if ((pdu = snmp_getbulk(agent, &noid, 1,
@@ -617,6 +645,13 @@ snmpc_walk(int argc, char *argv[])
                        if (value->be_class == BER_CLASS_CONTEXT &&
                            value->be_type == BER_TYPE_EOC)
                                break;
+                       for (i = 0; i < walk_skip_len; i++) {
+                               skip_cmp = ober_oid_cmp(&(walk_skip[i]), &noid);
+                               if (skip_cmp == 0 || skip_cmp == 2)
+                                       break;
+                       }
+                       if (i < walk_skip_len)
+                               continue;
                        prev_cmp = ober_oid_cmp(&loid, &noid);
                        if (walk_check_increase && prev_cmp == -1)
                                errx(1, "OID not increasing");

Reply via email to