Skip to content

Commit d45f5fa

Browse files
jsitnickikuba-moo
authored andcommitted
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/[email protected]/ Reviewed-by: Willem de Bruijn <[email protected]> Signed-off-by: Jakub Sitnicki <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 32b8033 commit d45f5fa

File tree

2 files changed

+47
-136
lines changed

2 files changed

+47
-136
lines changed

tools/testing/selftests/net/udpgso.c

Lines changed: 8 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ static bool cfg_do_msgmore;
5656
static bool cfg_do_setsockopt;
5757
static int cfg_specific_test_id = -1;
5858

59-
static const char cfg_ifname[] = "lo";
6059
static unsigned short cfg_port = 9000;
6160

6261
static char buf[ETH_MAX_MTU];
@@ -69,8 +68,13 @@ struct testcase {
6968
int r_len_last; /* recv(): size of last non-mss dgram, if any */
7069
};
7170

72-
const struct in6_addr addr6 = IN6ADDR_LOOPBACK_INIT;
73-
const struct in_addr addr4 = { .s_addr = __constant_htonl(INADDR_LOOPBACK + 2) };
71+
const struct in6_addr addr6 = {
72+
{ { 0xfd, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } }, /* fd00::1 */
73+
};
74+
75+
const struct in_addr addr4 = {
76+
__constant_htonl(0x0a000001), /* 10.0.0.1 */
77+
};
7478

7579
struct testcase testcases_v4[] = {
7680
{
@@ -274,48 +278,6 @@ struct testcase testcases_v6[] = {
274278
}
275279
};
276280

277-
static unsigned int get_device_mtu(int fd, const char *ifname)
278-
{
279-
struct ifreq ifr;
280-
281-
memset(&ifr, 0, sizeof(ifr));
282-
283-
strcpy(ifr.ifr_name, ifname);
284-
285-
if (ioctl(fd, SIOCGIFMTU, &ifr))
286-
error(1, errno, "ioctl get mtu");
287-
288-
return ifr.ifr_mtu;
289-
}
290-
291-
static void __set_device_mtu(int fd, const char *ifname, unsigned int mtu)
292-
{
293-
struct ifreq ifr;
294-
295-
memset(&ifr, 0, sizeof(ifr));
296-
297-
ifr.ifr_mtu = mtu;
298-
strcpy(ifr.ifr_name, ifname);
299-
300-
if (ioctl(fd, SIOCSIFMTU, &ifr))
301-
error(1, errno, "ioctl set mtu");
302-
}
303-
304-
static void set_device_mtu(int fd, int mtu)
305-
{
306-
int val;
307-
308-
val = get_device_mtu(fd, cfg_ifname);
309-
fprintf(stderr, "device mtu (orig): %u\n", val);
310-
311-
__set_device_mtu(fd, cfg_ifname, mtu);
312-
val = get_device_mtu(fd, cfg_ifname);
313-
if (val != mtu)
314-
error(1, 0, "unable to set device mtu to %u\n", val);
315-
316-
fprintf(stderr, "device mtu (test): %u\n", val);
317-
}
318-
319281
static void set_pmtu_discover(int fd, bool is_ipv4)
320282
{
321283
int level, name, val;
@@ -354,81 +316,6 @@ static unsigned int get_path_mtu(int fd, bool is_ipv4)
354316
return mtu;
355317
}
356318

357-
/* very wordy version of system("ip route add dev lo mtu 1500 127.0.0.3/32") */
358-
static void set_route_mtu(int mtu, bool is_ipv4)
359-
{
360-
struct sockaddr_nl nladdr = { .nl_family = AF_NETLINK };
361-
struct nlmsghdr *nh;
362-
struct rtattr *rta;
363-
struct rtmsg *rt;
364-
char data[NLMSG_ALIGN(sizeof(*nh)) +
365-
NLMSG_ALIGN(sizeof(*rt)) +
366-
NLMSG_ALIGN(RTA_LENGTH(sizeof(addr6))) +
367-
NLMSG_ALIGN(RTA_LENGTH(sizeof(int))) +
368-
NLMSG_ALIGN(RTA_LENGTH(0) + RTA_LENGTH(sizeof(int)))];
369-
int fd, ret, alen, off = 0;
370-
371-
alen = is_ipv4 ? sizeof(addr4) : sizeof(addr6);
372-
373-
fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
374-
if (fd == -1)
375-
error(1, errno, "socket netlink");
376-
377-
memset(data, 0, sizeof(data));
378-
379-
nh = (void *)data;
380-
nh->nlmsg_type = RTM_NEWROUTE;
381-
nh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE;
382-
off += NLMSG_ALIGN(sizeof(*nh));
383-
384-
rt = (void *)(data + off);
385-
rt->rtm_family = is_ipv4 ? AF_INET : AF_INET6;
386-
rt->rtm_table = RT_TABLE_MAIN;
387-
rt->rtm_dst_len = alen << 3;
388-
rt->rtm_protocol = RTPROT_BOOT;
389-
rt->rtm_scope = RT_SCOPE_UNIVERSE;
390-
rt->rtm_type = RTN_UNICAST;
391-
off += NLMSG_ALIGN(sizeof(*rt));
392-
393-
rta = (void *)(data + off);
394-
rta->rta_type = RTA_DST;
395-
rta->rta_len = RTA_LENGTH(alen);
396-
if (is_ipv4)
397-
memcpy(RTA_DATA(rta), &addr4, alen);
398-
else
399-
memcpy(RTA_DATA(rta), &addr6, alen);
400-
off += NLMSG_ALIGN(rta->rta_len);
401-
402-
rta = (void *)(data + off);
403-
rta->rta_type = RTA_OIF;
404-
rta->rta_len = RTA_LENGTH(sizeof(int));
405-
*((int *)(RTA_DATA(rta))) = 1; //if_nametoindex("lo");
406-
off += NLMSG_ALIGN(rta->rta_len);
407-
408-
/* MTU is a subtype in a metrics type */
409-
rta = (void *)(data + off);
410-
rta->rta_type = RTA_METRICS;
411-
rta->rta_len = RTA_LENGTH(0) + RTA_LENGTH(sizeof(int));
412-
off += NLMSG_ALIGN(rta->rta_len);
413-
414-
/* now fill MTU subtype. Note that it fits within above rta_len */
415-
rta = (void *)(((char *) rta) + RTA_LENGTH(0));
416-
rta->rta_type = RTAX_MTU;
417-
rta->rta_len = RTA_LENGTH(sizeof(int));
418-
*((int *)(RTA_DATA(rta))) = mtu;
419-
420-
nh->nlmsg_len = off;
421-
422-
ret = sendto(fd, data, off, 0, (void *)&nladdr, sizeof(nladdr));
423-
if (ret != off)
424-
error(1, errno, "send netlink: %uB != %uB\n", ret, off);
425-
426-
if (close(fd))
427-
error(1, errno, "close netlink");
428-
429-
fprintf(stderr, "route mtu (test): %u\n", mtu);
430-
}
431-
432319
static bool __send_one(int fd, struct msghdr *msg, int flags)
433320
{
434321
int ret;
@@ -591,15 +478,10 @@ static void run_test(struct sockaddr *addr, socklen_t alen)
591478
/* Do not fragment these datagrams: only succeed if GSO works */
592479
set_pmtu_discover(fdt, addr->sa_family == AF_INET);
593480

594-
if (cfg_do_connectionless) {
595-
set_device_mtu(fdt, CONST_MTU_TEST);
481+
if (cfg_do_connectionless)
596482
run_all(fdt, fdr, addr, alen);
597-
}
598483

599484
if (cfg_do_connected) {
600-
set_device_mtu(fdt, CONST_MTU_TEST + 100);
601-
set_route_mtu(CONST_MTU_TEST, addr->sa_family == AF_INET);
602-
603485
if (connect(fdt, addr, alen))
604486
error(1, errno, "connect");
605487

tools/testing/selftests/net/udpgso.sh

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,56 @@
33
#
44
# Run a series of udpgso regression tests
55

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+
636
echo "ipv4 cmsg"
7-
./in_netns.sh ./udpgso -4 -C
37+
./in_netns.sh "$0" test_dev_mtu -- ./udpgso -4 -C
838

939
echo "ipv4 setsockopt"
10-
./in_netns.sh ./udpgso -4 -C -s
40+
./in_netns.sh "$0" test_dev_mtu -- ./udpgso -4 -C -s
1141

1242
echo "ipv6 cmsg"
13-
./in_netns.sh ./udpgso -6 -C
43+
./in_netns.sh "$0" test_dev_mtu -- ./udpgso -6 -C
1444

1545
echo "ipv6 setsockopt"
16-
./in_netns.sh ./udpgso -6 -C -s
46+
./in_netns.sh "$0" test_dev_mtu -- ./udpgso -6 -C -s
1747

1848
echo "ipv4 connected"
19-
./in_netns.sh ./udpgso -4 -c
49+
./in_netns.sh "$0" test_route_mtu -- ./udpgso -4 -c
2050

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
2453

2554
echo "ipv4 msg_more"
26-
./in_netns.sh ./udpgso -4 -C -m
55+
./in_netns.sh "$0" test_dev_mtu -- ./udpgso -4 -C -m
2756

2857
echo "ipv6 msg_more"
29-
./in_netns.sh ./udpgso -6 -C -m
58+
./in_netns.sh "$0" test_dev_mtu -- ./udpgso -6 -C -m

0 commit comments

Comments
 (0)