aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHartmut Brandt <harti@FreeBSD.org>2021-10-10 15:03:51 +0000
committerHartmut Brandt <harti@FreeBSD.org>2021-10-10 15:03:51 +0000
commitded77e0237a8534230746031f373d8a8ae80cdaa (patch)
tree04a79b6985b68f7db2d7070d2d38ec50f2e805ec
parentf656df586ad1aa86a2b9f076a224f746d5308613 (diff)
downloadsrc-ded77e0237a8534230746031f373d8a8ae80cdaa.tar.gz
src-ded77e0237a8534230746031f373d8a8ae80cdaa.zip
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
-rw-r--r--lib/libc/sys/kqueue.29
-rw-r--r--sys/net/bpf.c35
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