git: 8e629780d32f - stable/15 - bpf: fix handling the read timeout on ppc64
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 26 Apr 2026 08:09:34 UTC
The branch stable/15 has been updated by tuexen:
URL: https://cgit.FreeBSD.org/src/commit/?id=8e629780d32f4405359e33f128e57a7bb704f684
commit 8e629780d32f4405359e33f128e57a7bb704f684
Author: Michael Tuexen <tuexen@FreeBSD.org>
AuthorDate: 2026-04-15 19:24:05 +0000
Commit: Michael Tuexen <tuexen@FreeBSD.org>
CommitDate: 2026-04-26 08:08:05 +0000
bpf: fix handling the read timeout on ppc64
On platforms other than amd64, BIOCSRTIMEOUT is equal to
BIOCSRTIMEOUT32. Therefore, running the COMPAT_FREEBSD32 code
basically clears tv_usec on big endian platforms. When tcpdump is
used, the timeout requested is 100ms, which gets cleared to 0 on
ppc64 platforms. This results in tcpdump showing the packets only
when the read buffer is full.
Thanks to kib for guiding me to the correct fix.
Reported by: ivy
Reviewed by: adrian, kib
Differential Revision: https://reviews.freebsd.org/D56399
Event: Wiesbaden Hackathon 2026
(cherry picked from commit 04b994d19eec68a6b5d27ff4b0fa223a05f00e1f)
---
sys/net/bpf.c | 42 ++++++++++++++++++++++--------------------
1 file changed, 22 insertions(+), 20 deletions(-)
diff --git a/sys/net/bpf.c b/sys/net/bpf.c
index f598733773d0..ff30aa7a3a9a 100644
--- a/sys/net/bpf.c
+++ b/sys/net/bpf.c
@@ -1439,7 +1439,7 @@ bpfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags,
case BIOCGDLTLIST32:
case BIOCGRTIMEOUT32:
case BIOCSRTIMEOUT32:
- if (SV_PROC_FLAG(td->td_proc, SV_ILP32)) {
+ if (SV_CURPROC_FLAG(SV_ILP32)) {
BPFD_LOCK(d);
d->bd_compat32 = 1;
BPFD_UNLOCK(d);
@@ -1447,6 +1447,19 @@ bpfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags,
}
#endif
+#if defined(COMPAT_FREEBSD32)
+ if (SV_CURPROC_FLAG(SV_ILP32)) {
+ /*
+ * On platforms other than amd64, BIOC[GS]RTIMEOUT32 is equal to
+ * BIOC[GS]RTIMEOUT. Since this is difficult to handle in the
+ * switch command, map them.
+ */
+ if (cmd == BIOCSRTIMEOUT32)
+ cmd = BIOCSRTIMEOUT;
+ if (cmd == BIOCGRTIMEOUT32)
+ cmd = BIOCGRTIMEOUT;
+ }
+#endif
CURVNET_SET(TD_TO_VNET(td));
switch (cmd) {
default:
@@ -1641,23 +1654,19 @@ bpfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags,
* Set read timeout.
*/
case BIOCSRTIMEOUT:
-#if defined(COMPAT_FREEBSD32) && defined(__amd64__)
- case BIOCSRTIMEOUT32:
-#endif
{
struct timeval *tv = (struct timeval *)addr;
-#if defined(COMPAT_FREEBSD32)
+#ifdef COMPAT_FREEBSD32
struct timeval32 *tv32;
struct timeval tv64;
- if (cmd == BIOCSRTIMEOUT32) {
+ if (SV_CURPROC_FLAG(SV_ILP32)) {
tv32 = (struct timeval32 *)addr;
tv = &tv64;
tv->tv_sec = tv32->tv_sec;
tv->tv_usec = tv32->tv_usec;
- } else
+ }
#endif
- tv = (struct timeval *)addr;
/*
* Subtract 1 tick from tvtohz() since this isn't
@@ -1672,31 +1681,24 @@ bpfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags,
* Get read timeout.
*/
case BIOCGRTIMEOUT:
-#if defined(COMPAT_FREEBSD32) && defined(__amd64__)
- case BIOCGRTIMEOUT32:
-#endif
{
- struct timeval *tv;
-#if defined(COMPAT_FREEBSD32) && defined(__amd64__)
+ struct timeval *tv = (struct timeval *)addr;
+#ifdef COMPAT_FREEBSD32
struct timeval32 *tv32;
struct timeval tv64;
- if (cmd == BIOCGRTIMEOUT32)
+ if (SV_CURPROC_FLAG(SV_ILP32))
tv = &tv64;
- else
#endif
- tv = (struct timeval *)addr;
-
tv->tv_sec = d->bd_rtout / hz;
tv->tv_usec = (d->bd_rtout % hz) * tick;
-#if defined(COMPAT_FREEBSD32) && defined(__amd64__)
- if (cmd == BIOCGRTIMEOUT32) {
+#ifdef COMPAT_FREEBSD32
+ if (SV_CURPROC_FLAG(SV_ILP32)) {
tv32 = (struct timeval32 *)addr;
tv32->tv_sec = tv->tv_sec;
tv32->tv_usec = tv->tv_usec;
}
#endif
-
break;
}