git: 36afb137b699 - main - netpfil tests: Make divapp packet loop handling opt-in

From: Igor Ostapenko <igoro_at_FreeBSD.org>
Date: Thu, 27 Aug 2026 11:54:56 UTC
The branch main has been updated by igoro:

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

commit 36afb137b699845be8ccf4df1da883c117f1b1aa
Author:     Igor Ostapenko <igoro@FreeBSD.org>
AuthorDate: 2026-08-27 11:42:59 +0000
Commit:     Igor Ostapenko <igoro@FreeBSD.org>
CommitDate: 2026-08-27 11:47:24 +0000

    netpfil tests: Make divapp packet loop handling opt-in
    
    This generalizes the divapp logic and makes it usable for other test
    scenarios such as diverted TCP connections.
    
    Reviewed by:    markj
    Differential Revision:  https://reviews.freebsd.org/D59067
---
 tests/sys/netpfil/common/divapp.c | 26 ++++++++++++++++++------
 tests/sys/netpfil/ipfw/divert.sh  | 12 +++++------
 tests/sys/netpfil/pf/divert-to.sh | 42 +++++++++++++++++++--------------------
 3 files changed, 47 insertions(+), 33 deletions(-)

diff --git a/tests/sys/netpfil/common/divapp.c b/tests/sys/netpfil/common/divapp.c
index b1c38fdc87b4..59630c8da45f 100644
--- a/tests/sys/netpfil/common/divapp.c
+++ b/tests/sys/netpfil/common/divapp.c
@@ -43,6 +43,7 @@
 struct context {
 	unsigned short divert_port;
 	bool divert_back;
+	bool expect_single_pkt;
 
 	int fd;
 	struct sockaddr_in sin;
@@ -116,7 +117,8 @@ main(int argc, char *argv[])
 
 	if (argc < 2)
 		errx(EX_USAGE,
-		    "Usage: %s <divert-port> [divert-back]", argv[0]);
+		    "Usage: %s <divert-port> [expect-single-pkt] [divert-back]",
+		    argv[0]);
 
 	memset(&c, 0, sizeof(struct context));
 
@@ -124,8 +126,12 @@ main(int argc, char *argv[])
 	if (c.divert_port == 0)
 		errx(EX_USAGE, "divert port is not defined.");
 
-	if (argc >= 3 && strcmp(argv[2], "divert-back") == 0)
-		c.divert_back = true;
+	for (int i = 2; i < argc; i++) {
+		if (strcmp(argv[i], "expect-single-pkt") == 0)
+			c.expect_single_pkt = true;
+		if (strcmp(argv[i], "divert-back") == 0)
+			c.divert_back = true;
+	}
 
 
 	init(&c);
@@ -135,12 +141,20 @@ main(int argc, char *argv[])
 		if (c.divert_back)
 			send_pkt(&c);
 		npkt++;
-		if (npkt >= 20)
+		if (c.expect_single_pkt && npkt >= 20) {
+			/*
+			 * Single-packet expectation detects potential packet
+			 * loops, so break the loop eventually.
+			 */
 			break;
+		}
 	}
 
-	if (npkt != 1)
-		errx(EXIT_FAILURE, "%d: npkt=%d.", c.divert_port, npkt);
+	if (npkt == 0)
+		errx(EXIT_FAILURE, "%d: no packets received.", c.divert_port);
+	if (c.expect_single_pkt && npkt != 1)
+		errx(EXIT_FAILURE, "%d: more than one received, npkt=%d.",
+		    c.divert_port, npkt);
 
 	return (EXIT_SUCCESS);
 }
diff --git a/tests/sys/netpfil/ipfw/divert.sh b/tests/sys/netpfil/ipfw/divert.sh
index 62db3f8fce98..42bef65596a4 100644
--- a/tests/sys/netpfil/ipfw/divert.sh
+++ b/tests/sys/netpfil/ipfw/divert.sh
@@ -88,7 +88,7 @@ in_div_body()
 
 	jexec div ipfw add 100 divert 2000 icmp from any to any in icmptypes 8
 
-	jexec div $(atf_get_srcdir)/../common/divapp 2000 &
+	jexec div $(atf_get_srcdir)/../common/divapp 2000 expect-single-pkt &
 	divapp_pid=$!
 	# Wait for the divapp to be ready
 	sleep 1
@@ -125,7 +125,7 @@ in_div_in_body()
 
 	jexec div ipfw add 100 divert 2000 icmp from any to any in icmptypes 8
 
-	jexec div $(atf_get_srcdir)/../common/divapp 2000 divert-back &
+	jexec div $(atf_get_srcdir)/../common/divapp 2000 expect-single-pkt divert-back &
 	divapp_pid=$!
 	# Wait for the divapp to be ready
 	sleep 1
@@ -162,7 +162,7 @@ out_div_body()
 
 	jexec div ipfw add 100 divert 2000 icmp from any to any out icmptypes 0
 
-	jexec div $(atf_get_srcdir)/../common/divapp 2000 &
+	jexec div $(atf_get_srcdir)/../common/divapp 2000 expect-single-pkt &
 	divapp_pid=$!
 	# Wait for the divapp to be ready
 	sleep 1
@@ -199,7 +199,7 @@ out_div_out_body()
 
 	jexec div ipfw add 100 divert 2000 icmp from any to any out icmptypes 0
 
-	jexec div $(atf_get_srcdir)/../common/divapp 2000 divert-back &
+	jexec div $(atf_get_srcdir)/../common/divapp 2000 expect-single-pkt divert-back &
 	divapp_pid=$!
 	# Wait for the divapp to be ready
 	sleep 1
@@ -252,9 +252,9 @@ in_div_in_fwd_out_div_out_body()
 	jexec router ipfw add 100 divert 2001 icmp from any to any in icmptypes 8
 	jexec router ipfw add 200 divert 2002 icmp from any to any out icmptypes 8
 
-	jexec router $(atf_get_srcdir)/../common/divapp 2001 divert-back &
+	jexec router $(atf_get_srcdir)/../common/divapp 2001 expect-single-pkt divert-back &
 	indivapp_pid=$!
-	jexec router $(atf_get_srcdir)/../common/divapp 2002 divert-back &
+	jexec router $(atf_get_srcdir)/../common/divapp 2002 expect-single-pkt divert-back &
 	outdivapp_pid=$!
 	# Wait for the divappS to be ready
 	sleep 1
diff --git a/tests/sys/netpfil/pf/divert-to.sh b/tests/sys/netpfil/pf/divert-to.sh
index bc4222c2bd03..30825aae5e4c 100644
--- a/tests/sys/netpfil/pf/divert-to.sh
+++ b/tests/sys/netpfil/pf/divert-to.sh
@@ -88,7 +88,7 @@ in_div_body()
 	    "pass in inet proto icmp icmp-type echoreq divert-to 127.0.0.1 port 2000" \
 	    "pass in inet6 proto icmp6 icmp6-type echoreq divert-to ::1 port 2000"
 
-	jexec div $(atf_get_srcdir)/../common/divapp 2000 &
+	jexec div $(atf_get_srcdir)/../common/divapp 2000 expect-single-pkt &
 	divapp_pid=$!
 	# Wait for the divapp to be ready
 	sleep 1
@@ -98,7 +98,7 @@ in_div_body()
 
 	wait $divapp_pid
 
-	jexec div $(atf_get_srcdir)/../common/divapp 2000 &
+	jexec div $(atf_get_srcdir)/../common/divapp 2000 expect-single-pkt &
 	divapp_pid=$!
 	# Wait for the divapp to be ready
 	sleep 1
@@ -141,7 +141,7 @@ in_div_in_body()
 	    "pass in inet proto icmp icmp-type echoreq divert-to 127.0.0.1 port 2000 no state" \
 	    "pass in inet6 proto icmp6 icmp6-type echoreq divert-to ::1 port 2000 no state"
 
-	jexec div $(atf_get_srcdir)/../common/divapp 2000 divert-back &
+	jexec div $(atf_get_srcdir)/../common/divapp 2000 expect-single-pkt divert-back &
 	divapp_pid=$!
 	# Wait for the divapp to be ready
 	sleep 1
@@ -151,7 +151,7 @@ in_div_in_body()
 
 	wait $divapp_pid
 
-	jexec div $(atf_get_srcdir)/../common/divapp 2000 divert-back &
+	jexec div $(atf_get_srcdir)/../common/divapp 2000 expect-single-pkt divert-back &
 	divapp_pid=$!
 	# Wait for the divapp to be ready
 	sleep 1
@@ -196,7 +196,7 @@ out_div_body()
 	    "pass in inet6 proto icmp6 icmp6-type echoreq no state" \
 	    "pass out inet6 proto icmp6 icmp6-type echorep divert-to ::1 port 2000 no state"
 
-	jexec div $(atf_get_srcdir)/../common/divapp 2000 &
+	jexec div $(atf_get_srcdir)/../common/divapp 2000 expect-single-pkt &
 	divapp_pid=$!
 	# Wait for the divapp to be ready
 	sleep 1
@@ -206,7 +206,7 @@ out_div_body()
 
 	wait $divapp_pid
 
-	jexec div $(atf_get_srcdir)/../common/divapp 2000 &
+	jexec div $(atf_get_srcdir)/../common/divapp 2000 expect-single-pkt &
 	divapp_pid=$!
 	# Wait for the divapp to be ready
 	sleep 1
@@ -251,7 +251,7 @@ out_div_out_body()
 	    "pass in inet6 proto icmp6 icmp6-type echoreq no state" \
 	    "pass out inet6 proto icmp6 icmp6-type echorep divert-to ::1 port 2000 no state"
 
-	jexec div $(atf_get_srcdir)/../common/divapp 2000 divert-back &
+	jexec div $(atf_get_srcdir)/../common/divapp 2000 expect-single-pkt divert-back &
 	divapp_pid=$!
 	# Wait for the divapp to be ready
 	sleep 1
@@ -261,7 +261,7 @@ out_div_out_body()
 
 	wait $divapp_pid
 
-	jexec div $(atf_get_srcdir)/../common/divapp 2000 divert-back &
+	jexec div $(atf_get_srcdir)/../common/divapp 2000 expect-single-pkt divert-back &
 	divapp_pid=$!
 	# Wait for the divapp to be ready
 	sleep 1
@@ -326,9 +326,9 @@ in_div_in_fwd_out_div_out_body()
 	    "pass in inet6 proto icmp6 icmp6-type echoreq divert-to ::1 port 2001 no state" \
 	    "pass out inet6 proto icmp6 icmp6-type echoreq divert-to ::1 port 2002 no state"
 
-	jexec router $(atf_get_srcdir)/../common/divapp 2001 divert-back &
+	jexec router $(atf_get_srcdir)/../common/divapp 2001 expect-single-pkt divert-back &
 	indivapp_pid=$!
-	jexec router $(atf_get_srcdir)/../common/divapp 2002 divert-back &
+	jexec router $(atf_get_srcdir)/../common/divapp 2002 expect-single-pkt divert-back &
 	outdivapp_pid=$!
 	# Wait for the divapps to be ready
 	sleep 1
@@ -338,9 +338,9 @@ in_div_in_fwd_out_div_out_body()
 
 	wait $indivapp_pid && wait $outdivapp_pid
 
-	jexec router $(atf_get_srcdir)/../common/divapp 2001 divert-back &
+	jexec router $(atf_get_srcdir)/../common/divapp 2001 expect-single-pkt divert-back &
 	indivapp_pid=$!
-	jexec router $(atf_get_srcdir)/../common/divapp 2002 divert-back &
+	jexec router $(atf_get_srcdir)/../common/divapp 2002 expect-single-pkt divert-back &
 	outdivapp_pid=$!
 	# Wait for the divapps to be ready
 	sleep 1
@@ -393,9 +393,9 @@ in_dn_in_div_in_out_div_out_dn_out_body()
 	    "pass in inet6 proto icmp6 icmp6-type echoreq divert-to ::1 port 1001 no state" \
 	    "pass out inet6 proto icmp6 icmp6-type echorep divert-to ::1 port 1002 no state"
 
-	jexec alcatraz $(atf_get_srcdir)/../common/divapp 1001 divert-back &
+	jexec alcatraz $(atf_get_srcdir)/../common/divapp 1001 expect-single-pkt divert-back &
 	indivapp_pid=$!
-	jexec alcatraz $(atf_get_srcdir)/../common/divapp 1002 divert-back &
+	jexec alcatraz $(atf_get_srcdir)/../common/divapp 1002 expect-single-pkt divert-back &
 	outdivapp_pid=$!
 	# Wait for the divapps to be ready
 	sleep 1
@@ -407,9 +407,9 @@ in_dn_in_div_in_out_div_out_dn_out_body()
 	wait $outdivapp_pid
 	atf_check_not_equal 0 $?
 
-	jexec alcatraz $(atf_get_srcdir)/../common/divapp 1001 divert-back &
+	jexec alcatraz $(atf_get_srcdir)/../common/divapp 1001 expect-single-pkt divert-back &
 	indivapp_pid=$!
-	jexec alcatraz $(atf_get_srcdir)/../common/divapp 1002 divert-back &
+	jexec alcatraz $(atf_get_srcdir)/../common/divapp 1002 expect-single-pkt divert-back &
 	outdivapp_pid=$!
 	# Wait for the divapps to be ready
 	sleep 1
@@ -438,9 +438,9 @@ in_dn_in_div_in_out_div_out_dn_out_body()
 	    "pass in inet6 proto icmp6 icmp6-type echoreq divert-to ::1 port 2001 no state" \
 	    "pass out inet6 proto icmp6 icmp6-type echorep divert-to ::1 port 2002 no state"
 
-	jexec alcatraz $(atf_get_srcdir)/../common/divapp 2001 divert-back &
+	jexec alcatraz $(atf_get_srcdir)/../common/divapp 2001 expect-single-pkt divert-back &
 	indivapp_pid=$!
-	jexec alcatraz $(atf_get_srcdir)/../common/divapp 2002 divert-back &
+	jexec alcatraz $(atf_get_srcdir)/../common/divapp 2002 expect-single-pkt divert-back &
 	outdivapp_pid=$!
 	# Wait for the divapps to be ready
 	sleep 1
@@ -452,9 +452,9 @@ in_dn_in_div_in_out_div_out_dn_out_body()
 	wait $outdivapp_pid
 	atf_check_equal 0 $?
 
-	jexec alcatraz $(atf_get_srcdir)/../common/divapp 2001 divert-back &
+	jexec alcatraz $(atf_get_srcdir)/../common/divapp 2001 expect-single-pkt divert-back &
 	indivapp_pid=$!
-	jexec alcatraz $(atf_get_srcdir)/../common/divapp 2002 divert-back &
+	jexec alcatraz $(atf_get_srcdir)/../common/divapp 2002 expect-single-pkt divert-back &
 	outdivapp_pid=$!
 	# Wait for the divapps to be ready
 	sleep 1
@@ -498,7 +498,7 @@ pr260867_body()
 	atf_check -o ignore ping -c3 2001:db8::2
 
 	jexec alcatraz /usr/sbin/inetd -p ${PWD}/inetd-echo.pid $(atf_get_srcdir)/echo_inetd.conf
-	jexec alcatraz $(atf_get_srcdir)/../common/divapp 1001 divert-back &
+	jexec alcatraz $(atf_get_srcdir)/../common/divapp 1001 expect-single-pkt divert-back &
 
 	jexec alcatraz pfctl -e
 	pft_set_rules alcatraz \