From patchwork Thu Apr 26 17:42:23 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Willem de Bruijn X-Patchwork-Id: 905286 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="FowvpSQx"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40X4Cn1v6Dz9ryr for ; Fri, 27 Apr 2018 03:43:01 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932308AbeDZRm6 (ORCPT ); Thu, 26 Apr 2018 13:42:58 -0400 Received: from mail-qk0-f193.google.com ([209.85.220.193]:38902 "EHLO mail-qk0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756840AbeDZRmg (ORCPT ); Thu, 26 Apr 2018 13:42:36 -0400 Received: by mail-qk0-f193.google.com with SMTP id b39so26244580qkb.5 for ; Thu, 26 Apr 2018 10:42:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=oUr6zSgFTOWXInw37pxXUdObfF/NQw7+/9JkHNecV/k=; b=FowvpSQxibklcpcKotRzvP1jMegowaaG7o8hjSCQmi3U5D1TzXapyezwntFLKFeKlG TwKvGocvHi2csmaB09Rk1lteuDq5iL4g2sA7DnpPfYwsFYqbQUt4KEybUCOAteUpUbDX b8ZC38xD3uv2eqakyX/p84bJmSsjaCkXxVeuRilRD8HE64BYo18F8JQG2a86FuRLixEa QVMeG4+u+FlJNPUr0ZiW+hMt74mxJNvUFWAPw/Doz53qr90hTPKmcki/Jvr8p7DqsaZi bZgSDH0a71wWX/j6XfeshBEH2O/3+VVceMk+cSRdm/Idqsouy7FbsXLpS8jkhtXLb7b4 0QyA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=oUr6zSgFTOWXInw37pxXUdObfF/NQw7+/9JkHNecV/k=; b=SZMBw3t3eN9Z4Jvu/yuaM+GQ0IxhYIkpwaVSlHfcBvCP+L9sQbKJlVHy0fSwc2Oo0a 2dWkQrQ5tLjJSjJz7LIPMuAxmZ5xXNZzFow2t+ANgxix8Q5Ho8a3XH8GuUUtVRHZZSFx tX/mB1xL3iX2jVrcEcEkyrGk1qaoMeNdGog3MIx6Va0FeRye9wMcuM4IT5jGVlba5qyL g4nR2yy8b/T8sigL9uTc2SrafctcvTuDzAquzmbq1FLbna85mqGJ/81U5NqRIlkibpot w+MBRr9YyBhHkI84RjbDFknAsuVzGAZInAXStw7RSB8MauliqakAkuxpCYmtobElArjS YgIA== X-Gm-Message-State: ALQs6tD1gCCSigy6NhkcxmkMutp8lzLVOgEPEwDBr04N/JwAZTIkvMvH 3iyACr7fIX8uGwlr03koo9LQDlJc X-Google-Smtp-Source: AIpwx48MplJBMdsqWGBv5w1BIJrX7vh+V5sM4zdCJNrtjMJpLvr7/eHrbgV6r0x67gcYkU9TB0kmTQ== X-Received: by 10.55.26.41 with SMTP id a41mr34229201qka.401.1524764554887; Thu, 26 Apr 2018 10:42:34 -0700 (PDT) Received: from willemb1.nyc.corp.google.com ([2620:0:1003:315:3fa1:a34c:1128:1d39]) by smtp.gmail.com with ESMTPSA id o14-v6sm12927515qta.23.2018.04.26.10.42.34 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 26 Apr 2018 10:42:34 -0700 (PDT) From: Willem de Bruijn To: netdev@vger.kernel.org Cc: davem@davemloft.net, alexander.duyck@gmail.com, Willem de Bruijn Subject: [PATCH net-next v2 09/11] selftests: udp gso with connected sockets Date: Thu, 26 Apr 2018 13:42:23 -0400 Message-Id: <20180426174225.246388-10-willemdebruijn.kernel@gmail.com> X-Mailer: git-send-email 2.17.0.484.g0c8726318c-goog In-Reply-To: <20180426174225.246388-1-willemdebruijn.kernel@gmail.com> References: <20180426174225.246388-1-willemdebruijn.kernel@gmail.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Willem de Bruijn Connected sockets use path mtu instead of device mtu. Test this path by inserting a route mtu that is lower than the device mtu. Verify that the path mtu for the connection matches this lower number, then run the same test as in the connectionless case. Signed-off-by: Willem de Bruijn --- tools/testing/selftests/net/udpgso.c | 117 +++++++++++++++++++++++++- tools/testing/selftests/net/udpgso.sh | 7 ++ 2 files changed, 122 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/net/udpgso.c b/tools/testing/selftests/net/udpgso.c index 68a230dfee73..a47dca025346 100644 --- a/tools/testing/selftests/net/udpgso.c +++ b/tools/testing/selftests/net/udpgso.c @@ -47,6 +47,7 @@ static bool cfg_do_ipv4; static bool cfg_do_ipv6; +static bool cfg_do_connected; static bool cfg_do_connectionless; static bool cfg_do_setsockopt; static int cfg_specific_test_id = -1; @@ -273,6 +274,101 @@ static void set_pmtu_discover(int fd, bool is_ipv4) error(1, errno, "setsockopt path mtu"); } +static unsigned int get_path_mtu(int fd, bool is_ipv4) +{ + socklen_t vallen; + unsigned int mtu; + int ret; + + vallen = sizeof(mtu); + if (is_ipv4) + ret = getsockopt(fd, SOL_IP, IP_MTU, &mtu, &vallen); + else + ret = getsockopt(fd, SOL_IPV6, IPV6_MTU, &mtu, &vallen); + + if (ret) + error(1, errno, "getsockopt mtu"); + + + fprintf(stderr, "path mtu (read): %u\n", mtu); + 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); +} + static bool send_one(int fd, int len, int gso_len, struct sockaddr *addr, socklen_t alen) { @@ -391,7 +487,7 @@ static void run_all(int fdt, int fdr, struct sockaddr *addr, socklen_t alen) static void run_test(struct sockaddr *addr, socklen_t alen) { struct timeval tv = { .tv_usec = 100 * 1000 }; - int fdr, fdt; + int fdr, fdt, val; fdr = socket(addr->sa_family, SOCK_DGRAM, 0); if (fdr == -1) @@ -416,6 +512,20 @@ static void run_test(struct sockaddr *addr, socklen_t alen) 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"); + + val = get_path_mtu(fdt, addr->sa_family == AF_INET); + if (val != CONST_MTU_TEST) + error(1, 0, "bad path mtu %u\n", val); + + run_all(fdt, fdr, addr, 0 /* use connected addr */); + } + if (close(fdt)) error(1, errno, "close t"); if (close(fdr)) @@ -448,7 +558,7 @@ static void parse_opts(int argc, char **argv) { int c; - while ((c = getopt(argc, argv, "46Cst:")) != -1) { + while ((c = getopt(argc, argv, "46cCst:")) != -1) { switch (c) { case '4': cfg_do_ipv4 = true; @@ -456,6 +566,9 @@ static void parse_opts(int argc, char **argv) case '6': cfg_do_ipv6 = true; break; + case 'c': + cfg_do_connected = true; + break; case 'C': cfg_do_connectionless = true; break; diff --git a/tools/testing/selftests/net/udpgso.sh b/tools/testing/selftests/net/udpgso.sh index 7977b97e060c..7cdf0e7c1dde 100755 --- a/tools/testing/selftests/net/udpgso.sh +++ b/tools/testing/selftests/net/udpgso.sh @@ -14,3 +14,10 @@ echo "ipv6 cmsg" echo "ipv6 setsockopt" ./in_netns.sh ./udpgso -6 -C -s + +echo "ipv4 connected" +./in_netns.sh ./udpgso -4 -c + +# blocked on 2nd loopback address +# echo "ipv6 connected" +# ./in_netns.sh ./udpgso -6 -c