The following patch enables device cloning for bpf, which allows to have
just one bpf device node in /dev, that services all bpf consumers (up to
1024).

Cloning bpf offers some advantages to the current situation:

- Users with high bpf usage won't have to clutter /dev with device
nodes.

- A lot of programs in base use a pattern like this to acces bpf:

        int fd, n = 0;
        do {
                (void)snprintf(device, sizeof device, "/dev/bpf%d", n++);
                fd = open(device, mode);
        } while (fd < 0 && errno == EBUSY);

A cloning bpf device would allow to replace all those loops with a
simple open() instead.

The plan forward is as follows: First, get this diff in, then reduce the
number of bpf devices in MAKEDEV to one (/dev/bpf0), add a second
identical bpf device node (/dev/bpf). The latter device node is supposed
to be the actual target, while the former node is just for compatibility
and can be removed as soon as all programs in base (and ports) have been
adapted to just open /dev/bpf instead of trying to find a free bpf
device in a loop. Does that make sense?

Diff below also disallows the usage of all but the first minor device,
so accidental use of another minor device will attract attention.

Comments/Ok?

natano


Index: sys/conf.h
===================================================================
RCS file: /cvs/src/sys/sys/conf.h,v
retrieving revision 1.139
diff -u -p -r1.139 conf.h
--- sys/conf.h  25 Feb 2016 16:48:50 -0000      1.139
+++ sys/conf.h  3 Apr 2016 18:26:05 -0000
@@ -296,7 +296,7 @@ extern struct cdevsw cdevsw[];
        dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \
        dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) enodev, \
        0, dev_init(c,n,poll), (dev_type_mmap((*))) enodev, \
-       0, 0, dev_init(c,n,kqfilter) }
+       0, D_CLONE, dev_init(c,n,kqfilter) }
 
 /* open, close, ioctl */
 #define        cdev_ch_init(c,n) { \
Index: net/bpf.c
===================================================================
RCS file: /cvs/src/sys/net/bpf.c,v
retrieving revision 1.138
diff -u -p -r1.138 bpf.c
--- net/bpf.c   2 Apr 2016 08:49:49 -0000       1.138
+++ net/bpf.c   3 Apr 2016 18:26:06 -0000
@@ -56,6 +56,7 @@
 #include <sys/rwlock.h>
 #include <sys/atomic.h>
 #include <sys/srp.h>
+#include <sys/specdev.h>
 
 #include <net/if.h>
 #include <net/bpf.h>
@@ -333,6 +334,9 @@ bpfopen(dev_t dev, int flag, int mode, s
 {
        struct bpf_d *d;
 
+       if (minor(dev) & ((1 << CLONE_SHIFT) - 1))
+               return (ENXIO);
+
        /* create on demand */
        if ((d = bpfilter_create(minor(dev))) == NULL)
                return (EBUSY);
@@ -1644,8 +1648,8 @@ bpfilter_create(int unit)
 {
        struct bpf_d *bd;
 
-       if ((bd = bpfilter_lookup(unit)) != NULL)
-               return (NULL);
+       KASSERT(bpfilter_lookup(unit) == NULL);
+
        if ((bd = malloc(sizeof(*bd), M_DEVBUF, M_NOWAIT|M_ZERO)) != NULL) {
                bd->bd_unit = unit;
                LIST_INSERT_HEAD(&bpf_d_list, bd, bd_list);

Reply via email to