Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 26 Apr 2026 08:09:34 +0000
From:      Michael Tuexen <tuexen@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 8e629780d32f - stable/15 - bpf: fix handling the read timeout on ppc64
Message-ID:  <69edc83e.30605.3010c78@gitrepo.freebsd.org>

index | next in thread | raw e-mail

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;
 		}
 


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69edc83e.30605.3010c78>