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

Configure Feed

Select the types of activity you want to include in your feed.

selftests: udpgso: Pull up network setup into shell script

udpgso regression test configures routing and device MTU directly through
uAPI (Netlink, ioctl) to do its job. While there is nothing wrong with it,
it takes more effort than doing it from shell.

Looking forward, we would like to extend the udpgso regression tests to
cover the EIO corner case [1], once it gets addressed. That will require a
dummy device and device feature manipulation to set it up. Which means more
Netlink code.

So, in preparation, pull out network configuration into the shell script
part of the test, so it is easily extendable in the future.

Also, because it now easy to setup routing, add a second local IPv6
address. Because the second address is not managed by the kernel, we can
"replace" the corresponding local route with a reduced-MTU one. This
unblocks the disabled "ipv6 connected" test case. Add a similar setup for
IPv4 for symmetry.

[1] https://lore.kernel.org/netdev/87jzqsld6q.fsf@cloudflare.com/

Reviewed-by: Willem de Bruijn <willemb@google.com>
Signed-off-by: Jakub Sitnicki <jakub@cloudflare.com>
Link: https://lore.kernel.org/r/20240207-jakub-krn-635-v3-1-3dfa3da8a7d3@cloudflare.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Jakub Sitnicki and committed by
Jakub Kicinski
d45f5fa8 32b80333

+47 -136
+8 -126
tools/testing/selftests/net/udpgso.c
··· 56 56 static bool cfg_do_setsockopt; 57 57 static int cfg_specific_test_id = -1; 58 58 59 - static const char cfg_ifname[] = "lo"; 60 59 static unsigned short cfg_port = 9000; 61 60 62 61 static char buf[ETH_MAX_MTU]; ··· 68 69 int r_len_last; /* recv(): size of last non-mss dgram, if any */ 69 70 }; 70 71 71 - const struct in6_addr addr6 = IN6ADDR_LOOPBACK_INIT; 72 - const struct in_addr addr4 = { .s_addr = __constant_htonl(INADDR_LOOPBACK + 2) }; 72 + const struct in6_addr addr6 = { 73 + { { 0xfd, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } }, /* fd00::1 */ 74 + }; 75 + 76 + const struct in_addr addr4 = { 77 + __constant_htonl(0x0a000001), /* 10.0.0.1 */ 78 + }; 73 79 74 80 struct testcase testcases_v4[] = { 75 81 { ··· 278 274 } 279 275 }; 280 276 281 - static unsigned int get_device_mtu(int fd, const char *ifname) 282 - { 283 - struct ifreq ifr; 284 - 285 - memset(&ifr, 0, sizeof(ifr)); 286 - 287 - strcpy(ifr.ifr_name, ifname); 288 - 289 - if (ioctl(fd, SIOCGIFMTU, &ifr)) 290 - error(1, errno, "ioctl get mtu"); 291 - 292 - return ifr.ifr_mtu; 293 - } 294 - 295 - static void __set_device_mtu(int fd, const char *ifname, unsigned int mtu) 296 - { 297 - struct ifreq ifr; 298 - 299 - memset(&ifr, 0, sizeof(ifr)); 300 - 301 - ifr.ifr_mtu = mtu; 302 - strcpy(ifr.ifr_name, ifname); 303 - 304 - if (ioctl(fd, SIOCSIFMTU, &ifr)) 305 - error(1, errno, "ioctl set mtu"); 306 - } 307 - 308 - static void set_device_mtu(int fd, int mtu) 309 - { 310 - int val; 311 - 312 - val = get_device_mtu(fd, cfg_ifname); 313 - fprintf(stderr, "device mtu (orig): %u\n", val); 314 - 315 - __set_device_mtu(fd, cfg_ifname, mtu); 316 - val = get_device_mtu(fd, cfg_ifname); 317 - if (val != mtu) 318 - error(1, 0, "unable to set device mtu to %u\n", val); 319 - 320 - fprintf(stderr, "device mtu (test): %u\n", val); 321 - } 322 - 323 277 static void set_pmtu_discover(int fd, bool is_ipv4) 324 278 { 325 279 int level, name, val; ··· 314 352 315 353 fprintf(stderr, "path mtu (read): %u\n", mtu); 316 354 return mtu; 317 - } 318 - 319 - /* very wordy version of system("ip route add dev lo mtu 1500 127.0.0.3/32") */ 320 - static void set_route_mtu(int mtu, bool is_ipv4) 321 - { 322 - struct sockaddr_nl nladdr = { .nl_family = AF_NETLINK }; 323 - struct nlmsghdr *nh; 324 - struct rtattr *rta; 325 - struct rtmsg *rt; 326 - char data[NLMSG_ALIGN(sizeof(*nh)) + 327 - NLMSG_ALIGN(sizeof(*rt)) + 328 - NLMSG_ALIGN(RTA_LENGTH(sizeof(addr6))) + 329 - NLMSG_ALIGN(RTA_LENGTH(sizeof(int))) + 330 - NLMSG_ALIGN(RTA_LENGTH(0) + RTA_LENGTH(sizeof(int)))]; 331 - int fd, ret, alen, off = 0; 332 - 333 - alen = is_ipv4 ? sizeof(addr4) : sizeof(addr6); 334 - 335 - fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); 336 - if (fd == -1) 337 - error(1, errno, "socket netlink"); 338 - 339 - memset(data, 0, sizeof(data)); 340 - 341 - nh = (void *)data; 342 - nh->nlmsg_type = RTM_NEWROUTE; 343 - nh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE; 344 - off += NLMSG_ALIGN(sizeof(*nh)); 345 - 346 - rt = (void *)(data + off); 347 - rt->rtm_family = is_ipv4 ? AF_INET : AF_INET6; 348 - rt->rtm_table = RT_TABLE_MAIN; 349 - rt->rtm_dst_len = alen << 3; 350 - rt->rtm_protocol = RTPROT_BOOT; 351 - rt->rtm_scope = RT_SCOPE_UNIVERSE; 352 - rt->rtm_type = RTN_UNICAST; 353 - off += NLMSG_ALIGN(sizeof(*rt)); 354 - 355 - rta = (void *)(data + off); 356 - rta->rta_type = RTA_DST; 357 - rta->rta_len = RTA_LENGTH(alen); 358 - if (is_ipv4) 359 - memcpy(RTA_DATA(rta), &addr4, alen); 360 - else 361 - memcpy(RTA_DATA(rta), &addr6, alen); 362 - off += NLMSG_ALIGN(rta->rta_len); 363 - 364 - rta = (void *)(data + off); 365 - rta->rta_type = RTA_OIF; 366 - rta->rta_len = RTA_LENGTH(sizeof(int)); 367 - *((int *)(RTA_DATA(rta))) = 1; //if_nametoindex("lo"); 368 - off += NLMSG_ALIGN(rta->rta_len); 369 - 370 - /* MTU is a subtype in a metrics type */ 371 - rta = (void *)(data + off); 372 - rta->rta_type = RTA_METRICS; 373 - rta->rta_len = RTA_LENGTH(0) + RTA_LENGTH(sizeof(int)); 374 - off += NLMSG_ALIGN(rta->rta_len); 375 - 376 - /* now fill MTU subtype. Note that it fits within above rta_len */ 377 - rta = (void *)(((char *) rta) + RTA_LENGTH(0)); 378 - rta->rta_type = RTAX_MTU; 379 - rta->rta_len = RTA_LENGTH(sizeof(int)); 380 - *((int *)(RTA_DATA(rta))) = mtu; 381 - 382 - nh->nlmsg_len = off; 383 - 384 - ret = sendto(fd, data, off, 0, (void *)&nladdr, sizeof(nladdr)); 385 - if (ret != off) 386 - error(1, errno, "send netlink: %uB != %uB\n", ret, off); 387 - 388 - if (close(fd)) 389 - error(1, errno, "close netlink"); 390 - 391 - fprintf(stderr, "route mtu (test): %u\n", mtu); 392 355 } 393 356 394 357 static bool __send_one(int fd, struct msghdr *msg, int flags) ··· 478 591 /* Do not fragment these datagrams: only succeed if GSO works */ 479 592 set_pmtu_discover(fdt, addr->sa_family == AF_INET); 480 593 481 - if (cfg_do_connectionless) { 482 - set_device_mtu(fdt, CONST_MTU_TEST); 594 + if (cfg_do_connectionless) 483 595 run_all(fdt, fdr, addr, alen); 484 - } 485 596 486 597 if (cfg_do_connected) { 487 - set_device_mtu(fdt, CONST_MTU_TEST + 100); 488 - set_route_mtu(CONST_MTU_TEST, addr->sa_family == AF_INET); 489 - 490 598 if (connect(fdt, addr, alen)) 491 599 error(1, errno, "connect"); 492 600
+39 -10
tools/testing/selftests/net/udpgso.sh
··· 3 3 # 4 4 # Run a series of udpgso regression tests 5 5 6 + set -o errexit 7 + set -o nounset 8 + 9 + setup_loopback() { 10 + ip addr add dev lo 10.0.0.1/32 11 + ip addr add dev lo fd00::1/128 nodad noprefixroute 12 + } 13 + 14 + test_dev_mtu() { 15 + setup_loopback 16 + # Reduce loopback MTU 17 + ip link set dev lo mtu 1500 18 + } 19 + 20 + test_route_mtu() { 21 + setup_loopback 22 + # Remove default local routes 23 + ip route del local 10.0.0.1/32 table local dev lo 24 + ip route del local fd00::1/128 table local dev lo 25 + # Install local routes with reduced MTU 26 + ip route add local 10.0.0.1/32 table local dev lo mtu 1500 27 + ip route add local fd00::1/128 table local dev lo mtu 1500 28 + } 29 + 30 + if [ "$#" -gt 0 ]; then 31 + "$1" 32 + shift 2 # pop "test_*" arg and "--" delimiter 33 + exec "$@" 34 + fi 35 + 6 36 echo "ipv4 cmsg" 7 - ./in_netns.sh ./udpgso -4 -C 37 + ./in_netns.sh "$0" test_dev_mtu -- ./udpgso -4 -C 8 38 9 39 echo "ipv4 setsockopt" 10 - ./in_netns.sh ./udpgso -4 -C -s 40 + ./in_netns.sh "$0" test_dev_mtu -- ./udpgso -4 -C -s 11 41 12 42 echo "ipv6 cmsg" 13 - ./in_netns.sh ./udpgso -6 -C 43 + ./in_netns.sh "$0" test_dev_mtu -- ./udpgso -6 -C 14 44 15 45 echo "ipv6 setsockopt" 16 - ./in_netns.sh ./udpgso -6 -C -s 46 + ./in_netns.sh "$0" test_dev_mtu -- ./udpgso -6 -C -s 17 47 18 48 echo "ipv4 connected" 19 - ./in_netns.sh ./udpgso -4 -c 49 + ./in_netns.sh "$0" test_route_mtu -- ./udpgso -4 -c 20 50 21 - # blocked on 2nd loopback address 22 - # echo "ipv6 connected" 23 - # ./in_netns.sh ./udpgso -6 -c 51 + echo "ipv6 connected" 52 + ./in_netns.sh "$0" test_route_mtu -- ./udpgso -6 -c 24 53 25 54 echo "ipv4 msg_more" 26 - ./in_netns.sh ./udpgso -4 -C -m 55 + ./in_netns.sh "$0" test_dev_mtu -- ./udpgso -4 -C -m 27 56 28 57 echo "ipv6 msg_more" 29 - ./in_netns.sh ./udpgso -6 -C -m 58 + ./in_netns.sh "$0" test_dev_mtu -- ./udpgso -6 -C -m