The branch main has been updated by harti:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=ded77e0237a8534230746031f373d8a8ae80cdaa

commit ded77e0237a8534230746031f373d8a8ae80cdaa
Author:     Hartmut Brandt <ha...@freebsd.org>
AuthorDate: 2021-10-10 15:03:51 +0000
Commit:     Hartmut Brandt <ha...@freebsd.org>
CommitDate: 2021-10-10 15:03:51 +0000

    Allow the BPF to be select for write. This is needed for boost:asio
    which otherwise fails to handle BPFs.
    Reviewed by:    ae
    Differential Revision:  https://reviews.freebsd.org/D31967
---
 lib/libc/sys/kqueue.2 |  9 +++++++--
 sys/net/bpf.c         | 35 ++++++++++++++++++++++++++++++++---
 2 files changed, 39 insertions(+), 5 deletions(-)

diff --git a/lib/libc/sys/kqueue.2 b/lib/libc/sys/kqueue.2
index f80c89f75d78..68929e973dc0 100644
--- a/lib/libc/sys/kqueue.2
+++ b/lib/libc/sys/kqueue.2
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd September 30, 2021
+.Dd October 12, 2021
 .Dt KQUEUE 2
 .Os
 .Sh NAME
@@ -378,7 +378,7 @@ The filter will set
 .Dv EV_EOF
 when the reader disconnects, and for the fifo case, this will be cleared
 when a new reader connects.
-Note that this filter is not supported for vnodes or BPF devices.
+Note that this filter is not supported for vnodes.
 .Pp
 For sockets, the low water mark and socket error handling is
 identical to the
@@ -389,6 +389,11 @@ For eventfds,
 .Va data
 will contain the maximum value that can be added to the counter
 without blocking.
+.Pp
+For BPF devices, the filter always indicates that it is possible to
+write and
+.Va data
+will contain the MTU size of the underlying interface.
 .It Dv EVFILT_EMPTY
 Takes a descriptor as the identifier, and returns whenever
 there is no remaining data in the write buffer.
diff --git a/sys/net/bpf.c b/sys/net/bpf.c
index 77c85cc91aae..ce7aba5a9bcd 100644
--- a/sys/net/bpf.c
+++ b/sys/net/bpf.c
@@ -213,6 +213,7 @@ static int  bpf_getdltlist(struct bpf_d *, struct 
bpf_dltlist *);
 static int     bpf_setdlt(struct bpf_d *, u_int);
 static void    filt_bpfdetach(struct knote *);
 static int     filt_bpfread(struct knote *, long);
+static int     filt_bpfwrite(struct knote *, long);
 static void    bpf_drvinit(void *);
 static int     bpf_stats_sysctl(SYSCTL_HANDLER_ARGS);
 
@@ -257,6 +258,12 @@ static struct filterops bpfread_filtops = {
        .f_event = filt_bpfread,
 };
 
+static struct filterops bpfwrite_filtops = {
+       .f_isfd = 1,
+       .f_detach = filt_bpfdetach,
+       .f_event = filt_bpfwrite,
+};
+
 /*
  * LOCKING MODEL USED BY BPF
  *
@@ -2158,16 +2165,27 @@ bpfkqfilter(struct cdev *dev, struct knote *kn)
 {
        struct bpf_d *d;
 
-       if (devfs_get_cdevpriv((void **)&d) != 0 ||
-           kn->kn_filter != EVFILT_READ)
+       if (devfs_get_cdevpriv((void **)&d) != 0)
                return (1);
 
+       switch (kn->kn_filter) {
+       case EVFILT_READ:
+               kn->kn_fop = &bpfread_filtops;
+               break;
+
+       case EVFILT_WRITE:
+               kn->kn_fop = &bpfwrite_filtops;
+               break;
+
+       default:
+               return (1);
+       }
+
        /*
         * Refresh PID associated with this descriptor.
         */
        BPFD_LOCK(d);
        BPF_PID_REFRESH_CUR(d);
-       kn->kn_fop = &bpfread_filtops;
        kn->kn_hook = d;
        knlist_add(&d->bd_sel.si_note, kn, 1);
        BPFD_UNLOCK(d);
@@ -2207,6 +2225,17 @@ filt_bpfread(struct knote *kn, long hint)
        return (ready);
 }
 
+static int
+filt_bpfwrite(struct knote *kn, long hint)
+{
+       struct bpf_d *d = (struct bpf_d *)kn->kn_hook;
+       BPFD_LOCK_ASSERT(d);
+
+       kn->kn_data = d->bd_bif->bif_ifp->if_mtu;
+
+       return (1);
+}
+
 #define        BPF_TSTAMP_NONE         0
 #define        BPF_TSTAMP_FAST         1
 #define        BPF_TSTAMP_NORMAL       2

Reply via email to