Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests: udp gso with corking

Corked sockets take a different path to construct a udp datagram than
the lockless fast path. Test this alternate path.

Signed-off-by: Willem de Bruijn <willemb@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Willem de Bruijn and committed by
David S. Miller
3f12817f e5b2d91c

+38 -10
+32 -10
tools/testing/selftests/net/udpgso.c
··· 49 49 static bool cfg_do_ipv6; 50 50 static bool cfg_do_connected; 51 51 static bool cfg_do_connectionless; 52 + static bool cfg_do_msgmore; 52 53 static bool cfg_do_setsockopt; 53 54 static int cfg_specific_test_id = -1; 54 55 ··· 370 369 fprintf(stderr, "route mtu (test): %u\n", mtu); 371 370 } 372 371 372 + static bool __send_one(int fd, struct msghdr *msg, int flags) 373 + { 374 + int ret; 375 + 376 + ret = sendmsg(fd, msg, flags); 377 + if (ret == -1 && (errno == EMSGSIZE || errno == ENOMEM)) 378 + return false; 379 + if (ret == -1) 380 + error(1, errno, "sendmsg"); 381 + if (ret != msg->msg_iov->iov_len) 382 + error(1, 0, "sendto: %d != %lu", ret, msg->msg_iov->iov_len); 383 + if (msg->msg_flags) 384 + error(1, 0, "sendmsg: return flags 0x%x\n", msg->msg_flags); 385 + 386 + return true; 387 + } 388 + 373 389 static bool send_one(int fd, int len, int gso_len, 374 390 struct sockaddr *addr, socklen_t alen) 375 391 { ··· 394 376 struct msghdr msg = {0}; 395 377 struct iovec iov = {0}; 396 378 struct cmsghdr *cm; 397 - int ret; 398 379 399 380 iov.iov_base = buf; 400 381 iov.iov_len = len; ··· 415 398 *((uint16_t *) CMSG_DATA(cm)) = gso_len; 416 399 } 417 400 418 - ret = sendmsg(fd, &msg, 0); 419 - if (ret == -1 && (errno == EMSGSIZE || errno == ENOMEM)) 420 - return false; 421 - if (ret == -1) 422 - error(1, errno, "sendmsg"); 423 - if (ret != len) 424 - error(1, 0, "sendto: %d != %u", ret, len); 401 + /* If MSG_MORE, send 1 byte followed by remainder */ 402 + if (cfg_do_msgmore && len > 1) { 403 + iov.iov_len = 1; 404 + if (!__send_one(fd, &msg, MSG_MORE)) 405 + error(1, 0, "send 1B failed"); 425 406 426 - return true; 407 + iov.iov_base++; 408 + iov.iov_len = len - 1; 409 + } 410 + 411 + return __send_one(fd, &msg, 0); 427 412 } 428 413 429 414 static int recv_one(int fd, int flags) ··· 577 558 { 578 559 int c; 579 560 580 - while ((c = getopt(argc, argv, "46cCst:")) != -1) { 561 + while ((c = getopt(argc, argv, "46cCmst:")) != -1) { 581 562 switch (c) { 582 563 case '4': 583 564 cfg_do_ipv4 = true; ··· 590 571 break; 591 572 case 'C': 592 573 cfg_do_connectionless = true; 574 + break; 575 + case 'm': 576 + cfg_do_msgmore = true; 593 577 break; 594 578 case 's': 595 579 cfg_do_setsockopt = true;
+6
tools/testing/selftests/net/udpgso.sh
··· 21 21 # blocked on 2nd loopback address 22 22 # echo "ipv6 connected" 23 23 # ./in_netns.sh ./udpgso -6 -c 24 + 25 + echo "ipv4 msg_more" 26 + ./in_netns.sh ./udpgso -4 -C -m 27 + 28 + echo "ipv6 msg_more" 29 + ./in_netns.sh ./udpgso -6 -C -m