bin/120974: [patch] bsnmpd snmp_pf module work incorrect when DIOCGETALTQ return queue list not in qid order

Mykola Dzham i at levsha.org.ua
Fri Feb 22 17:40:02 UTC 2008


>Number:         120974
>Category:       bin
>Synopsis:       [patch] bsnmpd snmp_pf module work incorrect when DIOCGETALTQ return queue list not in qid order
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Feb 22 17:40:01 UTC 2008
>Closed-Date:
>Last-Modified:
>Originator:     Mykola Dzham
>Release:        7.0-RC1
>Organization:
>Environment:
FreeBSD ruslan 7.0-RC1 FreeBSD 7.0-RC1 #0: Tue Jan 15 21:48:25 EET 2008     levsha at notebook.levsha.org.ua:/usr/obj/nanobsd.full/usr/src/sys/NANOBSD  i386
>Description:
bsnmpd pf_snmp module use code:
for (i = 0; i < numqs; i++) {
 ...
 pa.nr = i;
 ioctl(dev, DIOCGETALTQ, &pa)
 ...
}
to request queue list from kernel, then use pa.altq.qid as queue id. Kernel can return queue list not in pa.altq.qid order. If this occur, then snmpwalk return only part of queue list.
>How-To-Repeat:
Use small program to test queue order, returned from kernel:
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/fcntl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <net/pfvar.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <errno.h>

int main(int argc, char *argv[])
{
        int dev;
        struct pfioc_altq pa;
        int i, numqs, ticket;

        dev = open("/dev/pf", O_RDWR);
        if (dev == -1)
                err(1, "open(\"/dev/pf\") failed");

        bzero(&pa, sizeof(pa));
        if (ioctl(dev, DIOCGETALTQS, &pa)) {
                err(1, "ioctl(DIOCGETALTQS): %s", strerror(errno));
        }
        numqs = pa.nr;
        ticket = pa.ticket;
        for (i = 0; i < numqs; i++) {
                pa.ticket = ticket;
                pa.nr = i;
                if (ioctl(dev, DIOCGETALTQ, &pa)) {
                        err(1,"ioctl(DIOCGETALTQ): %s", strerror(errno));
                }
                if (pa.altq.qid > 0) {
                        printf("%d: %s\n", pa.altq.qid, pa.altq.qname);
                }
        }
        return 0;
}
If program return all queue list, but not in pa.altq.qid order, then you can reproduce problem: snmpwalk ... .1.3.6.1.4.1.12325.1.200.1.10 return only part of tree
>Fix:
Use INSERT_OBJECT_INT_LINK_INDEX macro instead of TAILQ_INSERT_TAIL (patch attached)

Patch attached with submission follows:

--- pf_snmp.c.orig	2008-02-22 19:01:50.000000000 +0200
+++ pf_snmp.c	2008-02-22 19:10:27.000000000 +0200
@@ -1025,7 +1025,7 @@
 			memcpy(&e->altq, &pa.altq, sizeof(struct pf_altq));
 			e->index = pa.altq.qid;
 			pfq_table_count = i;
-			TAILQ_INSERT_TAIL(&pfq_table, e, link);
+			INSERT_OBJECT_INT_LINK_INDEX(e, &pfq_table, link, index);
 		}
 	}
 	


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list