lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <65b95b8b3e4d0_ce3aa29444@willemb.c.googlers.com.notmuch>
Date: Tue, 30 Jan 2024 15:26:51 -0500
From: Willem de Bruijn <willemdebruijn.kernel@...il.com>
To: Jakub Sitnicki <jakub@...udflare.com>, 
 netdev@...r.kernel.org, 
 Willem de Bruijn <willemb@...gle.com>
Cc: "David S. Miller" <davem@...emloft.net>, 
 Eric Dumazet <edumazet@...gle.com>, 
 Jakub Kicinski <kuba@...nel.org>, 
 Paolo Abeni <pabeni@...hat.com>, 
 kernel-team@...udflare.com
Subject: Re: [PATCH net-next] selftests: udpgso: Pull up network setup into
 shell script

Jakub Sitnicki wrote:
> 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.

Nice!

Just a few small nits.

> 
> [1] https://lore.kernel.org/netdev/87jzqsld6q.fsf@cloudflare.com/
> 
> Signed-off-by: Jakub Sitnicki <jakub@...udflare.com>
> ---
>  tools/testing/selftests/net/udpgso.c  | 134 ++------------------------
>  tools/testing/selftests/net/udpgso.sh |  50 ++++++++--
>  2 files changed, 48 insertions(+), 136 deletions(-)
> 
> diff --git a/tools/testing/selftests/net/udpgso.c b/tools/testing/selftests/net/udpgso.c
> index 7badaf215de2..79fd3287ff60 100644
> --- a/tools/testing/selftests/net/udpgso.c
> +++ b/tools/testing/selftests/net/udpgso.c
> @@ -56,7 +56,6 @@ static bool		cfg_do_msgmore;
>  static bool		cfg_do_setsockopt;
>  static int		cfg_specific_test_id = -1;
>  
> -static const char	cfg_ifname[] = "lo";
>  static unsigned short	cfg_port = 9000;
>  
>  static char buf[ETH_MAX_MTU];
> @@ -69,8 +68,13 @@ struct testcase {
>  	int r_len_last;		/* recv(): size of last non-mss dgram, if any */
>  };
>  
> -const struct in6_addr addr6 = IN6ADDR_LOOPBACK_INIT;
> -const struct in_addr addr4 = { .s_addr = __constant_htonl(INADDR_LOOPBACK + 2) };
> +const struct in6_addr addr6 = {
> +	{ { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0x01 } },
> +};
> +
> +const struct in_addr addr4 = {
> +	__constant_htonl(0xc0000201), /* 192.0.2.1 */
> +};

Prefer an address from a private range?

>  struct testcase testcases_v4[] = {
>  	{
> @@ -274,48 +278,6 @@ struct testcase testcases_v6[] = {
>  	}
>  };
>  
> -static unsigned int get_device_mtu(int fd, const char *ifname)
> -{
> -	struct ifreq ifr;
> -
> -	memset(&ifr, 0, sizeof(ifr));
> -
> -	strcpy(ifr.ifr_name, ifname);
> -
> -	if (ioctl(fd, SIOCGIFMTU, &ifr))
> -		error(1, errno, "ioctl get mtu");
> -
> -	return ifr.ifr_mtu;
> -}
> -
> -static void __set_device_mtu(int fd, const char *ifname, unsigned int mtu)
> -{
> -	struct ifreq ifr;
> -
> -	memset(&ifr, 0, sizeof(ifr));
> -
> -	ifr.ifr_mtu = mtu;
> -	strcpy(ifr.ifr_name, ifname);
> -
> -	if (ioctl(fd, SIOCSIFMTU, &ifr))
> -		error(1, errno, "ioctl set mtu");
> -}
> -
> -static void set_device_mtu(int fd, int mtu)
> -{
> -	int val;
> -
> -	val = get_device_mtu(fd, cfg_ifname);
> -	fprintf(stderr, "device mtu (orig): %u\n", val);
> -
> -	__set_device_mtu(fd, cfg_ifname, mtu);
> -	val = get_device_mtu(fd, cfg_ifname);
> -	if (val != mtu)
> -		error(1, 0, "unable to set device mtu to %u\n", val);
> -
> -	fprintf(stderr, "device mtu (test): %u\n", val);
> -}
> -
>  static void set_pmtu_discover(int fd, bool is_ipv4)
>  {
>  	int level, name, val;
> @@ -354,81 +316,6 @@ static unsigned int get_path_mtu(int fd, bool is_ipv4)
>  	return mtu;
>  }
>  
> -/* very wordy version of system("ip route add dev lo mtu 1500 127.0.0.3/32") */
> -static void set_route_mtu(int mtu, bool is_ipv4)
> -{
> -	struct sockaddr_nl nladdr = { .nl_family = AF_NETLINK };
> -	struct nlmsghdr *nh;
> -	struct rtattr *rta;
> -	struct rtmsg *rt;
> -	char data[NLMSG_ALIGN(sizeof(*nh)) +
> -		  NLMSG_ALIGN(sizeof(*rt)) +
> -		  NLMSG_ALIGN(RTA_LENGTH(sizeof(addr6))) +
> -		  NLMSG_ALIGN(RTA_LENGTH(sizeof(int))) +
> -		  NLMSG_ALIGN(RTA_LENGTH(0) + RTA_LENGTH(sizeof(int)))];
> -	int fd, ret, alen, off = 0;
> -
> -	alen = is_ipv4 ? sizeof(addr4) : sizeof(addr6);
> -
> -	fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
> -	if (fd == -1)
> -		error(1, errno, "socket netlink");
> -
> -	memset(data, 0, sizeof(data));
> -
> -	nh = (void *)data;
> -	nh->nlmsg_type = RTM_NEWROUTE;
> -	nh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE;
> -	off += NLMSG_ALIGN(sizeof(*nh));
> -
> -	rt = (void *)(data + off);
> -	rt->rtm_family = is_ipv4 ? AF_INET : AF_INET6;
> -	rt->rtm_table = RT_TABLE_MAIN;
> -	rt->rtm_dst_len = alen << 3;
> -	rt->rtm_protocol = RTPROT_BOOT;
> -	rt->rtm_scope = RT_SCOPE_UNIVERSE;
> -	rt->rtm_type = RTN_UNICAST;
> -	off += NLMSG_ALIGN(sizeof(*rt));
> -
> -	rta = (void *)(data + off);
> -	rta->rta_type = RTA_DST;
> -	rta->rta_len = RTA_LENGTH(alen);
> -	if (is_ipv4)
> -		memcpy(RTA_DATA(rta), &addr4, alen);
> -	else
> -		memcpy(RTA_DATA(rta), &addr6, alen);
> -	off += NLMSG_ALIGN(rta->rta_len);
> -
> -	rta = (void *)(data + off);
> -	rta->rta_type = RTA_OIF;
> -	rta->rta_len = RTA_LENGTH(sizeof(int));
> -	*((int *)(RTA_DATA(rta))) = 1; //if_nametoindex("lo");
> -	off += NLMSG_ALIGN(rta->rta_len);
> -
> -	/* MTU is a subtype in a metrics type */
> -	rta = (void *)(data + off);
> -	rta->rta_type = RTA_METRICS;
> -	rta->rta_len = RTA_LENGTH(0) + RTA_LENGTH(sizeof(int));
> -	off += NLMSG_ALIGN(rta->rta_len);
> -
> -	/* now fill MTU subtype. Note that it fits within above rta_len */
> -	rta = (void *)(((char *) rta) + RTA_LENGTH(0));
> -	rta->rta_type = RTAX_MTU;
> -	rta->rta_len = RTA_LENGTH(sizeof(int));
> -	*((int *)(RTA_DATA(rta))) = mtu;
> -
> -	nh->nlmsg_len = off;
> -
> -	ret = sendto(fd, data, off, 0, (void *)&nladdr, sizeof(nladdr));
> -	if (ret != off)
> -		error(1, errno, "send netlink: %uB != %uB\n", ret, off);
> -
> -	if (close(fd))
> -		error(1, errno, "close netlink");
> -
> -	fprintf(stderr, "route mtu (test): %u\n", mtu);
> -}
> -

Oh no, my handcrafted artisanal netlink code!

Yeah, concise shell commands are a better model.

>  static bool __send_one(int fd, struct msghdr *msg, int flags)
>  {
>  	int ret;
> @@ -591,15 +478,10 @@ static void run_test(struct sockaddr *addr, socklen_t alen)
>  	/* Do not fragment these datagrams: only succeed if GSO works */
>  	set_pmtu_discover(fdt, addr->sa_family == AF_INET);
>  
> -	if (cfg_do_connectionless) {
> -		set_device_mtu(fdt, CONST_MTU_TEST);
> +	if (cfg_do_connectionless)
>  		run_all(fdt, fdr, addr, alen);
> -	}
>  
>  	if (cfg_do_connected) {
> -		set_device_mtu(fdt, CONST_MTU_TEST + 100);
> -		set_route_mtu(CONST_MTU_TEST, addr->sa_family == AF_INET);
> -
>  		if (connect(fdt, addr, alen))
>  			error(1, errno, "connect");
>  
> diff --git a/tools/testing/selftests/net/udpgso.sh b/tools/testing/selftests/net/udpgso.sh
> index fec24f584fe9..d7fb71e132bb 100755
> --- a/tools/testing/selftests/net/udpgso.sh
> +++ b/tools/testing/selftests/net/udpgso.sh
> @@ -3,27 +3,57 @@
>  #
>  # Run a series of udpgso regression tests
>  
> +set -o errexit
> +set -o nounset
> +# set -o xtrace

Leftover debug comment?

> +
> +setup_loopback() {
> +  ip addr add dev lo 192.0.2.1/32
> +  ip addr add dev lo 2001:db8::1/128 nodad noprefixroute
> +}
> +
> +test_dev_mtu() {
> +  setup_loopback
> +  # Reduce loopback MTU
> +  ip link set dev lo mtu 1500
> +}
> +
> +test_route_mtu() {
> +  setup_loopback
> +  # Remove default local routes
> +  ip route del local 192.0.2.1/32 table local dev lo
> +  ip route del local 2001:db8::1/128 table local dev lo
> +  # Install local routes with reduced MTU
> +  ip route add local 192.0.2.1/32 table local dev lo mtu 1500
> +  ip route add local 2001:db8::1/128 table local dev lo mtu 1500

ip route change?

> +}
> +
> +if [ "$#" -gt 0 ]; then
> +  "$1"
> +  shift 2 # pop "test_*" function arg and "--" delimiter
> +  exec "$@"
> +fi
> +
>  echo "ipv4 cmsg"
> -./in_netns.sh ./udpgso -4 -C
> +./in_netns.sh "$0" test_dev_mtu -- ./udpgso -4 -C
>  
>  echo "ipv4 setsockopt"
> -./in_netns.sh ./udpgso -4 -C -s
> +./in_netns.sh "$0" test_dev_mtu -- ./udpgso -4 -C -s
>  
>  echo "ipv6 cmsg"
> -./in_netns.sh ./udpgso -6 -C
> +./in_netns.sh "$0" test_dev_mtu -- ./udpgso -6 -C
>  
>  echo "ipv6 setsockopt"
> -./in_netns.sh ./udpgso -6 -C -s
> +./in_netns.sh "$0" test_dev_mtu -- ./udpgso -6 -C -s
>  
>  echo "ipv4 connected"
> -./in_netns.sh ./udpgso -4 -c
> +./in_netns.sh "$0" test_route_mtu -- ./udpgso -4 -c
>  
> -# blocked on 2nd loopback address
> -# echo "ipv6 connected"
> -# ./in_netns.sh ./udpgso -6 -c
> +echo "ipv6 connected"
> +./in_netns.sh "$0" test_route_mtu -- ./udpgso -6 -c
>  
>  echo "ipv4 msg_more"
> -./in_netns.sh ./udpgso -4 -C -m
> +./in_netns.sh "$0" test_dev_mtu -- ./udpgso -4 -C -m
>  
>  echo "ipv6 msg_more"
> -./in_netns.sh ./udpgso -6 -C -m
> +./in_netns.sh "$0" test_dev_mtu -- ./udpgso -6 -C -m
> -- 
> 2.43.0
> 



Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ