diff mbox series

[net-next,3/3] selftests/net: expand cmsg_ip with MSG_MORE

Message ID 20250307033620.411611-4-willemdebruijn.kernel@gmail.com (mailing list archive)
State Accepted
Commit 0922cb68edfde9e3920bb3aedea203d333af9f10
Delegated to: Netdev Maintainers
Headers show
Series follow-up on deduplicate cookie logic | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for net-next
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 0 this patch: 0
netdev/build_tools success Errors and warnings before: 26 (+0) this patch: 26 (+0)
netdev/cc_maintainers warning 2 maintainers not CCed: shuah@kernel.org linux-kselftest@vger.kernel.org
netdev/build_clang success Errors and warnings before: 0 this patch: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success net selftest script(s) already in Makefile
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 0 this patch: 0
netdev/checkpatch warning WARNING: line length of 84 exceeds 80 columns
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
netdev/contest success net-next-2025-03-07--06-00 (tests: 894)

Commit Message

Willem de Bruijn March 7, 2025, 3:34 a.m. UTC
From: Willem de Bruijn <willemb@google.com>

UDP send with MSG_MORE takes a slightly different path than the
lockless fast path.

For completeness, add coverage to this case too.

Pass MSG_MORE on the initial sendmsg, then follow up with a zero byte
write to unplug the cork.

Unrelated: also add two missing endlines in usage().

Signed-off-by: Willem de Bruijn <willemb@google.com>
---
 tools/testing/selftests/net/cmsg_ip.sh    | 11 +++++++----
 tools/testing/selftests/net/cmsg_sender.c | 24 ++++++++++++++++++-----
 2 files changed, 26 insertions(+), 9 deletions(-)

Comments

Eric Dumazet March 7, 2025, 10:10 a.m. UTC | #1
On Fri, Mar 7, 2025 at 4:36 AM Willem de Bruijn
<willemdebruijn.kernel@gmail.com> wrote:
>
> From: Willem de Bruijn <willemb@google.com>
>
> UDP send with MSG_MORE takes a slightly different path than the
> lockless fast path.
>
> For completeness, add coverage to this case too.
>
> Pass MSG_MORE on the initial sendmsg, then follow up with a zero byte
> write to unplug the cork.
>
> Unrelated: also add two missing endlines in usage().
>
> Signed-off-by: Willem de Bruijn <willemb@google.com>

Reviewed-by: Eric Dumazet <edumazet@google.com>
diff mbox series

Patch

diff --git a/tools/testing/selftests/net/cmsg_ip.sh b/tools/testing/selftests/net/cmsg_ip.sh
index 2a52520aca32..b55680e081ad 100755
--- a/tools/testing/selftests/net/cmsg_ip.sh
+++ b/tools/testing/selftests/net/cmsg_ip.sh
@@ -50,8 +50,9 @@  check_result() {
 # IPV6_DONTFRAG
 for ovr in setsock cmsg both diff; do
     for df in 0 1; do
-	for p in u i r; do
+	for p in u U i r; do
 	    [ $p == "u" ] && prot=UDP
+	    [ $p == "U" ] && prot=UDP
 	    [ $p == "i" ] && prot=ICMP
 	    [ $p == "r" ] && prot=RAW
 
@@ -81,8 +82,9 @@  test_dscp() {
     ip $IPVER -netns $NS route add table 300 prohibit any
 
     for ovr in setsock cmsg both diff; do
-	for p in u i r; do
+	for p in u U i r; do
 	    [ $p == "u" ] && prot=UDP
+	    [ $p == "U" ] && prot=UDP
 	    [ $p == "i" ] && prot=ICMP
 	    [ $p == "r" ] && prot=RAW
 
@@ -134,8 +136,9 @@  test_ttl_hoplimit() {
     local -r LIM=4
 
     for ovr in setsock cmsg both diff; do
-	for p in u i r; do
+	for p in u U i r; do
 	    [ $p == "u" ] && prot=UDP
+	    [ $p == "U" ] && prot=UDP
 	    [ $p == "i" ] && prot=ICMP
 	    [ $p == "r" ] && prot=RAW
 
@@ -166,7 +169,7 @@  test_ttl_hoplimit -4 $TGT4 ttl
 test_ttl_hoplimit -6 $TGT6 hlim
 
 # IPV6 exthdr
-for p in u i r; do
+for p in u U i r; do
     # Very basic "does it crash" test
     for h in h d r; do
 	$NSEXE ./cmsg_sender -p $p -6 -H $h $TGT6 1234
diff --git a/tools/testing/selftests/net/cmsg_sender.c b/tools/testing/selftests/net/cmsg_sender.c
index 19bd8499031b..a825e628aee7 100644
--- a/tools/testing/selftests/net/cmsg_sender.c
+++ b/tools/testing/selftests/net/cmsg_sender.c
@@ -33,6 +33,7 @@  enum {
 	ERN_RECVERR,
 	ERN_CMSG_RD,
 	ERN_CMSG_RCV,
+	ERN_SEND_MORE,
 };
 
 struct option_cmsg_u32 {
@@ -46,6 +47,7 @@  struct options {
 	const char *service;
 	unsigned int size;
 	unsigned int num_pkt;
+	bool msg_more;
 	struct {
 		unsigned int mark;
 		unsigned int dontfrag;
@@ -94,7 +96,8 @@  static void __attribute__((noreturn)) cs_usage(const char *bin)
 	       "\t\t-S      send() size\n"
 	       "\t\t-4/-6   Force IPv4 / IPv6 only\n"
 	       "\t\t-p prot Socket protocol\n"
-	       "\t\t        (u = UDP (default); i = ICMP; r = RAW)\n"
+	       "\t\t        (u = UDP (default); i = ICMP; r = RAW;\n"
+	       "\t\t         U = UDP with MSG_MORE)\n"
 	       "\n"
 	       "\t\t-m val  Set SO_MARK with given value\n"
 	       "\t\t-M val  Set SO_MARK via setsockopt\n"
@@ -109,8 +112,8 @@  static void __attribute__((noreturn)) cs_usage(const char *bin)
 	       "\t\t-l val  Set TTL/HOPLIMIT via cmsg\n"
 	       "\t\t-L val  Set TTL/HOPLIMIT via setsockopt\n"
 	       "\t\t-H type Add an IPv6 header option\n"
-	       "\t\t        (h = HOP; d = DST; r = RTDST)"
-	       "");
+	       "\t\t        (h = HOP; d = DST; r = RTDST)\n"
+	       "\n");
 	exit(ERN_HELP);
 }
 
@@ -133,8 +136,11 @@  static void cs_parse_args(int argc, char *argv[])
 			opt.sock.family = AF_INET6;
 			break;
 		case 'p':
-			if (*optarg == 'u' || *optarg == 'U') {
+			if (*optarg == 'u') {
 				opt.sock.proto = IPPROTO_UDP;
+			} else if (*optarg == 'U') {
+				opt.sock.proto = IPPROTO_UDP;
+				opt.msg_more = true;
 			} else if (*optarg == 'i' || *optarg == 'I') {
 				opt.sock.proto = IPPROTO_ICMP;
 			} else if (*optarg == 'r') {
@@ -531,7 +537,7 @@  int main(int argc, char *argv[])
 	cs_write_cmsg(fd, &msg, cbuf, sizeof(cbuf));
 
 	for (i = 0; i < opt.num_pkt; i++) {
-		err = sendmsg(fd, &msg, 0);
+		err = sendmsg(fd, &msg, opt.msg_more ? MSG_MORE : 0);
 		if (err < 0) {
 			if (!opt.silent_send)
 				fprintf(stderr, "send failed: %s\n", strerror(errno));
@@ -542,6 +548,14 @@  int main(int argc, char *argv[])
 			err = ERN_SEND_SHORT;
 			goto err_out;
 		}
+		if (opt.msg_more) {
+			err = write(fd, NULL, 0);
+			if (err < 0) {
+				fprintf(stderr, "send more: %s\n", strerror(errno));
+				err = ERN_SEND_MORE;
+				goto err_out;
+			}
+		}
 	}
 	err = ERN_SUCCESS;