From patchwork Thu Feb 17 01:21:16 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Kicinski X-Patchwork-Id: 543547 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3450CC433EF for ; Thu, 17 Feb 2022 01:21:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230203AbiBQBVo (ORCPT ); Wed, 16 Feb 2022 20:21:44 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:48220 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230173AbiBQBVn (ORCPT ); Wed, 16 Feb 2022 20:21:43 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 512E1C79; Wed, 16 Feb 2022 17:21:27 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id A0785616D2; Thu, 17 Feb 2022 01:21:26 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id A8492C340F1; Thu, 17 Feb 2022 01:21:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1645060886; bh=PyfBm3JdbqZgg6lEYzHxWbG1mDXoWMsCqP0jN55ZWaA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mtNJojPtKoq8pmHhOOjdVgVbQD71b+SR4H/IwoHiLsDMgBemQQFbXhNIv+avIz1PV 3vuVmwNruRiyXcB2MOO7GQEbIiRmVXMYS+RNTcF0NBeJgdXaMbbBpjJpiQKRpHwWxU HmKY6suo70GLVpl7sRSQVns/IJScgxFUPyGzF1j884Du694iLvxtMypen+blPUWDF7 DMyAuvu7r3llbow7zrL+/LExnKkI4VPh1fv0CX8WFt0wH0EcQw3XiaeReN2j6RAU6k UVy9ZUhhEuZAR5noxhc1t/hxObVkjQr+usltu9cc/kpuzQ03b86RgPR74sQbzeDkTf HGwjLcglvVenQ== From: Jakub Kicinski To: davem@davemloft.net Cc: netdev@vger.kernel.org, willemb@google.com, lorenzo@google.com, maze@google.com, dsahern@kernel.org, yoshfuji@linux-ipv6.org, shuah@kernel.org, linux-kselftest@vger.kernel.org, Jakub Kicinski Subject: [PATCH net-next 1/5] net: ping6: support setting basic SOL_IPV6 options via cmsg Date: Wed, 16 Feb 2022 17:21:16 -0800 Message-Id: <20220217012120.61250-2-kuba@kernel.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220217012120.61250-1-kuba@kernel.org> References: <20220217012120.61250-1-kuba@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org Support setting IPV6_HOPLIMIT, IPV6_TCLASS, IPV6_DONTFRAG during sendmsg via SOL_IPV6 cmsgs. tclass and dontfrag are init'ed from struct ipv6_pinfo in ipcm6_init_sk(), while hlimit is inited to -1, so we need to handle it being populated via cmsg explicitly. Leave extension headers and flowlabel unimplemented. Those are slightly more laborious to test and users seem to primarily care about IPV6_TCLASS. Signed-off-by: Jakub Kicinski --- net/ipv6/ip6_output.c | 1 + net/ipv6/ping.c | 21 ++++++++++++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 0c6c971ce0a5..3286b64ec03d 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -1487,6 +1487,7 @@ static int __ip6_append_data(struct sock *sk, if (cork->length + length > mtu - headersize && ipc6->dontfrag && (sk->sk_protocol == IPPROTO_UDP || + sk->sk_protocol == IPPROTO_ICMPV6 || sk->sk_protocol == IPPROTO_RAW)) { ipv6_local_rxpmtu(sk, fl6, mtu - headersize + sizeof(struct ipv6hdr)); diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c index d5544cf67ffe..ff033d16549e 100644 --- a/net/ipv6/ping.c +++ b/net/ipv6/ping.c @@ -101,11 +101,21 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ipc6.sockc.tsflags = sk->sk_tsflags; ipc6.sockc.mark = sk->sk_mark; - err = sock_cmsg_send(sk, msg, &ipc6.sockc); - if (err) - return err; + if (msg->msg_controllen) { + struct ipv6_txoptions opt = {}; + + opt.tot_len = sizeof(opt); + ipc6.opt = &opt; - /* TODO: use ip6_datagram_send_ctl to get options from cmsg */ + err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, &ipc6); + if (err < 0) + return err; + + /* Changes to txoptions and flow info are not implemented, yet. + * Drop the options, fl6 is wiped below. + */ + ipc6.opt = NULL; + } memset(&fl6, 0, sizeof(fl6)); @@ -140,7 +150,8 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) pfh.wcheck = 0; pfh.family = AF_INET6; - ipc6.hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst); + if (ipc6.hlimit < 0) + ipc6.hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst); lock_sock(sk); err = ip6_append_data(sk, ping_getfrag, &pfh, len, From patchwork Thu Feb 17 01:21:17 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Kicinski X-Patchwork-Id: 544144 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5B1DFC433F5 for ; Thu, 17 Feb 2022 01:21:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230219AbiBQBVp (ORCPT ); Wed, 16 Feb 2022 20:21:45 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:48226 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230194AbiBQBVn (ORCPT ); Wed, 16 Feb 2022 20:21:43 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A41B6D81; Wed, 16 Feb 2022 17:21:27 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 3D6DF61CB3; Thu, 17 Feb 2022 01:21:27 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3D195C340F3; Thu, 17 Feb 2022 01:21:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1645060886; bh=+OCt0log3K2xs5sjl3CiOmfN5eEpTzA4BA1coaL2ZOA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=pFxQrZA5DXCBRjFS7VIWqfDblSK9kcqsY8FuknpPONMroOxJsPR1gXcqEl347t+YO qfNaU7m6KLgMegKnyG43HMX054lIwV0OEl+vSkf8ZMnCnON4zJkrEyvgd9bH+4hz3i 9y4BITj7zSquc4mrofbdzYPBx0FtP9hr2hqYXFT+uDn37MR28iDsrVPWrtqV1ldXXM P28SaBFgcn41i2KSBUapbb8dhHy2xk6ENoSVLCTOc7kw/zadWPweKNs4F+MSUwdA9w 1VMY1ON0RyT2cVRJ2yRyTFXgP2alasj9YblT6V+Fz2o1A/r2FnsZ2uUHxw7zloCfX2 CTTNowZT+HAYw== From: Jakub Kicinski To: davem@davemloft.net Cc: netdev@vger.kernel.org, willemb@google.com, lorenzo@google.com, maze@google.com, dsahern@kernel.org, yoshfuji@linux-ipv6.org, shuah@kernel.org, linux-kselftest@vger.kernel.org, Jakub Kicinski Subject: [PATCH net-next 2/5] selftests: net: test IPV6_DONTFRAG Date: Wed, 16 Feb 2022 17:21:17 -0800 Message-Id: <20220217012120.61250-3-kuba@kernel.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220217012120.61250-1-kuba@kernel.org> References: <20220217012120.61250-1-kuba@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org Test setting IPV6_DONTFRAG via setsockopt and cmsg across socket types. Output without the kernel support (this series): Case DONTFRAG ICMP setsock returned 0, expected 1 Case DONTFRAG ICMP cmsg returned 0, expected 1 Case DONTFRAG ICMP both returned 0, expected 1 Case DONTFRAG ICMP diff returned 0, expected 1 FAIL - 4/24 cases failed Signed-off-by: Jakub Kicinski --- tools/testing/selftests/net/cmsg_ipv6.sh | 65 ++++++++++++++ tools/testing/selftests/net/cmsg_sender.c | 105 +++++++++++++++++----- 2 files changed, 147 insertions(+), 23 deletions(-) create mode 100755 tools/testing/selftests/net/cmsg_ipv6.sh diff --git a/tools/testing/selftests/net/cmsg_ipv6.sh b/tools/testing/selftests/net/cmsg_ipv6.sh new file mode 100755 index 000000000000..fb5a8ab7c909 --- /dev/null +++ b/tools/testing/selftests/net/cmsg_ipv6.sh @@ -0,0 +1,65 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +NS=ns +IP6=2001:db8:1::1/64 +TGT6=2001:db8:1::2 + +cleanup() +{ + ip netns del $NS +} + +trap cleanup EXIT + +NSEXE="ip netns exec $NS" + +# Namespaces +ip netns add $NS + +$NSEXE sysctl -w net.ipv4.ping_group_range='0 2147483647' > /dev/null + +# Connectivity +ip -netns $NS link add type dummy +ip -netns $NS link set dev dummy0 up +ip -netns $NS addr add $IP6 dev dummy0 + +# Test +BAD=0 +TOTAL=0 + +check_result() { + ((TOTAL++)) + if [ $1 -ne $2 ]; then + echo " Case $3 returned $1, expected $2" + ((BAD++)) + fi +} + +# IPV6_DONTFRAG +for ovr in setsock cmsg both diff; do + for df in 0 1; do + for p in u i r; do + [ $p == "u" ] && prot=UDP + [ $p == "i" ] && prot=ICMP + [ $p == "r" ] && prot=RAW + + [ $ovr == "setsock" ] && m="-F $df" + [ $ovr == "cmsg" ] && m="-f $df" + [ $ovr == "both" ] && m="-F $df -f $df" + [ $ovr == "diff" ] && m="-F $((1 - df)) -f $df" + + $NSEXE ./cmsg_sender -s -S 2000 -6 -p $p $m $TGT6 1234 + check_result $? $df "DONTFRAG $prot $ovr" + done + done +done + +# Summary +if [ $BAD -ne 0 ]; then + echo "FAIL - $BAD/$TOTAL cases failed" + exit 1 +else + echo "OK" + exit 0 +fi diff --git a/tools/testing/selftests/net/cmsg_sender.c b/tools/testing/selftests/net/cmsg_sender.c index efa617bd34e2..844ca6134662 100644 --- a/tools/testing/selftests/net/cmsg_sender.c +++ b/tools/testing/selftests/net/cmsg_sender.c @@ -33,22 +33,26 @@ enum { ERN_CMSG_RCV, }; +struct option_cmsg_u32 { + bool ena; + unsigned int val; +}; + struct options { bool silent_send; const char *host; const char *service; + unsigned int size; struct { unsigned int mark; + unsigned int dontfrag; } sockopt; struct { unsigned int family; unsigned int type; unsigned int proto; } sock; - struct { - bool ena; - unsigned int val; - } mark; + struct option_cmsg_u32 mark; struct { bool ena; unsigned int delay; @@ -56,7 +60,11 @@ struct options { struct { bool ena; } ts; + struct { + struct option_cmsg_u32 dontfrag; + } v6; } opt = { + .size = 13, .sock = { .family = AF_UNSPEC, .type = SOCK_DGRAM, @@ -72,6 +80,7 @@ static void __attribute__((noreturn)) cs_usage(const char *bin) printf("Usage: %s [opts] \n", bin); printf("Options:\n" "\t\t-s Silent send() failures\n" + "\t\t-S send() size\n" "\t\t-4/-6 Force IPv4 / IPv6 only\n" "\t\t-p prot Socket protocol\n" "\t\t (u = UDP (default); i = ICMP; r = RAW)\n" @@ -80,6 +89,8 @@ static void __attribute__((noreturn)) cs_usage(const char *bin) "\t\t-M val Set SO_MARK via setsockopt\n" "\t\t-d val Set SO_TXTIME with given delay (usec)\n" "\t\t-t Enable time stamp reporting\n" + "\t\t-f val Set don't fragment via cmsg\n" + "\t\t-F val Set don't fragment via setsockopt\n" ""); exit(ERN_HELP); } @@ -88,11 +99,14 @@ static void cs_parse_args(int argc, char *argv[]) { char o; - while ((o = getopt(argc, argv, "46sp:m:M:d:t")) != -1) { + while ((o = getopt(argc, argv, "46sS:p:m:M:d:tf:F:")) != -1) { switch (o) { case 's': opt.silent_send = true; break; + case 'S': + opt.size = atoi(optarg); + break; case '4': opt.sock.family = AF_INET; break; @@ -126,6 +140,13 @@ static void cs_parse_args(int argc, char *argv[]) case 't': opt.ts.ena = true; break; + case 'f': + opt.v6.dontfrag.ena = true; + opt.v6.dontfrag.val = atoi(optarg); + break; + case 'F': + opt.sockopt.dontfrag = atoi(optarg); + break; } } @@ -136,6 +157,38 @@ static void cs_parse_args(int argc, char *argv[]) opt.service = argv[optind + 1]; } +static void memrnd(void *s, size_t n) +{ + int *dword = s; + char *byte; + + for (; n >= 4; n -= 4) + *dword++ = rand(); + byte = (void *)dword; + while (n--) + *byte++ = rand(); +} + +static void +ca_write_cmsg_u32(char *cbuf, size_t cbuf_sz, size_t *cmsg_len, + int level, int optname, struct option_cmsg_u32 *uopt) +{ + struct cmsghdr *cmsg; + + if (!uopt->ena) + return; + + cmsg = (struct cmsghdr *)(cbuf + *cmsg_len); + *cmsg_len += CMSG_SPACE(sizeof(__u32)); + if (cbuf_sz < *cmsg_len) + error(ERN_CMSG_WR, EFAULT, "cmsg buffer too small"); + + cmsg->cmsg_level = level; + cmsg->cmsg_type = optname; + cmsg->cmsg_len = CMSG_LEN(sizeof(__u32)); + *(__u32 *)CMSG_DATA(cmsg) = uopt->val; +} + static void cs_write_cmsg(int fd, struct msghdr *msg, char *cbuf, size_t cbuf_sz) { @@ -145,17 +198,11 @@ cs_write_cmsg(int fd, struct msghdr *msg, char *cbuf, size_t cbuf_sz) msg->msg_control = cbuf; cmsg_len = 0; - if (opt.mark.ena) { - cmsg = (struct cmsghdr *)(cbuf + cmsg_len); - cmsg_len += CMSG_SPACE(sizeof(__u32)); - if (cbuf_sz < cmsg_len) - error(ERN_CMSG_WR, EFAULT, "cmsg buffer too small"); + ca_write_cmsg_u32(cbuf, cbuf_sz, &cmsg_len, + SOL_SOCKET, SO_MARK, &opt.mark); + ca_write_cmsg_u32(cbuf, cbuf_sz, &cmsg_len, + SOL_IPV6, IPV6_DONTFRAG, &opt.v6.dontfrag); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SO_MARK; - cmsg->cmsg_len = CMSG_LEN(sizeof(__u32)); - *(__u32 *)CMSG_DATA(cmsg) = opt.mark.val; - } if (opt.txtime.ena) { struct sock_txtime so_txtime = { .clockid = CLOCK_MONOTONIC, @@ -286,18 +333,33 @@ cs_read_cmsg(int fd, struct msghdr *msg, char *cbuf, size_t cbuf_sz) } } +static void ca_set_sockopts(int fd) +{ + if (opt.sockopt.mark && + setsockopt(fd, SOL_SOCKET, SO_MARK, + &opt.sockopt.mark, sizeof(opt.sockopt.mark))) + error(ERN_SOCKOPT, errno, "setsockopt SO_MARK"); + if (opt.sockopt.dontfrag && + setsockopt(fd, SOL_IPV6, IPV6_DONTFRAG, + &opt.sockopt.dontfrag, sizeof(opt.sockopt.dontfrag))) + error(ERN_SOCKOPT, errno, "setsockopt IPV6_DONTFRAG"); +} + int main(int argc, char *argv[]) { - char buf[] = "blablablabla"; struct addrinfo hints, *ai; struct iovec iov[1]; struct msghdr msg; char cbuf[1024]; + char *buf; int err; int fd; cs_parse_args(argc, argv); + buf = malloc(opt.size); + memrnd(buf, opt.size); + memset(&hints, 0, sizeof(hints)); hints.ai_family = opt.sock.family; @@ -326,17 +388,14 @@ int main(int argc, char *argv[]) buf[0] = ICMPV6_ECHO_REQUEST; buf[1] = 0; } else if (opt.sock.type == SOCK_RAW) { - struct udphdr hdr = { 1, 2, htons(sizeof(buf)), 0 }; + struct udphdr hdr = { 1, 2, htons(opt.size), 0 }; struct sockaddr_in6 *sin6 = (void *)ai->ai_addr;; memcpy(buf, &hdr, sizeof(hdr)); sin6->sin6_port = htons(opt.sock.proto); } - if (opt.sockopt.mark && - setsockopt(fd, SOL_SOCKET, SO_MARK, - &opt.sockopt.mark, sizeof(opt.sockopt.mark))) - error(ERN_SOCKOPT, errno, "setsockopt SO_MARK"); + ca_set_sockopts(fd); if (clock_gettime(CLOCK_REALTIME, &time_start_real)) error(ERN_GETTIME, errno, "gettime REALTIME"); @@ -344,7 +403,7 @@ int main(int argc, char *argv[]) error(ERN_GETTIME, errno, "gettime MONOTONIC"); iov[0].iov_base = buf; - iov[0].iov_len = sizeof(buf); + iov[0].iov_len = opt.size; memset(&msg, 0, sizeof(msg)); msg.msg_name = ai->ai_addr; @@ -360,7 +419,7 @@ int main(int argc, char *argv[]) fprintf(stderr, "send failed: %s\n", strerror(errno)); err = ERN_SEND; goto err_out; - } else if (err != sizeof(buf)) { + } else if (err != (int)opt.size) { fprintf(stderr, "short send\n"); err = ERN_SEND_SHORT; goto err_out; From patchwork Thu Feb 17 01:21:18 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Kicinski X-Patchwork-Id: 543545 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 17B11C433F5 for ; Thu, 17 Feb 2022 01:21:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230241AbiBQBVw (ORCPT ); Wed, 16 Feb 2022 20:21:52 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:48328 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230226AbiBQBVp (ORCPT ); Wed, 16 Feb 2022 20:21:45 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CB59AE7A; Wed, 16 Feb 2022 17:21:29 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 8EBB1B820E4; Thu, 17 Feb 2022 01:21:28 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id CCF5EC340F1; Thu, 17 Feb 2022 01:21:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1645060887; bh=7NWE1IVVDLfrvjPsykbQ9S4y+9dQ21toLFLjCQGo6dw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dVUq/WUgqq0Za7/Tbm0XOJAHWaVlQw4NTU0jgnx3a+aCa7JZQPEUCofjKMOBhx6Ia AClpjobJsEuYtDVSHvaAEy3pmr1hHVxjChjDPa9fDMIst47TSUrg6ReqWqzV357JBI oGsDYRKrS3hTuT/yxs5lALpIs8o3Pw6WBHxg0ThgeBn8bibLBDGCleQUbjem567ufn leXRuxrwQTjI6RYqr2xNxqqvSJnsF4Yxj48lyYROsjICA/pP5amKlDcWDOVCZOb/mZ D9ENW6krw+2Zshi9FcUIQvjVslvxWI1ptYkrRhoh0MwoabVmRVmxt8R/1c58ggu9ou B/agV6spBZk/A== From: Jakub Kicinski To: davem@davemloft.net Cc: netdev@vger.kernel.org, willemb@google.com, lorenzo@google.com, maze@google.com, dsahern@kernel.org, yoshfuji@linux-ipv6.org, shuah@kernel.org, linux-kselftest@vger.kernel.org, Jakub Kicinski Subject: [PATCH net-next 3/5] selftests: net: test IPV6_TCLASS Date: Wed, 16 Feb 2022 17:21:18 -0800 Message-Id: <20220217012120.61250-4-kuba@kernel.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220217012120.61250-1-kuba@kernel.org> References: <20220217012120.61250-1-kuba@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org Test setting IPV6_TCLASS via setsockopt and cmsg across socket types. Output without the kernel support (this series): Case TCLASS ICMP cmsg - packet data returned 1, expected 0 Case TCLASS ICMP cmsg - rejection returned 0, expected 1 Case TCLASS ICMP diff - pass returned 1, expected 0 Case TCLASS ICMP diff - packet data returned 1, expected 0 Case TCLASS ICMP diff - rejection returned 0, expected 1 Signed-off-by: Jakub Kicinski --- tools/testing/selftests/net/cmsg_ipv6.sh | 51 +++++++++++++++++++++++ tools/testing/selftests/net/cmsg_sender.c | 19 ++++++++- 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/net/cmsg_ipv6.sh b/tools/testing/selftests/net/cmsg_ipv6.sh index fb5a8ab7c909..f7bb6ce68c88 100755 --- a/tools/testing/selftests/net/cmsg_ipv6.sh +++ b/tools/testing/selftests/net/cmsg_ipv6.sh @@ -1,12 +1,16 @@ #!/bin/bash # SPDX-License-Identifier: GPL-2.0 +ksft_skip=4 + NS=ns IP6=2001:db8:1::1/64 TGT6=2001:db8:1::2 +TMPF=`mktemp` cleanup() { + rm -f $TMPF ip netns del $NS } @@ -14,6 +18,12 @@ trap cleanup EXIT NSEXE="ip netns exec $NS" +tcpdump -h | grep immediate-mode >> /dev/null +if [ $? -ne 0 ]; then + echo "SKIP - tcpdump with --immediate-mode option required" + exit $ksft_skip +fi + # Namespaces ip netns add $NS @@ -55,6 +65,47 @@ for ovr in setsock cmsg both diff; do done done +# IPV6_TCLASS +TOS=0x10 +TOS2=0x20 + +ip -6 -netns $NS rule add tos $TOS lookup 300 +ip -6 -netns $NS route add table 300 prohibit any + +for ovr in setsock cmsg both diff; do + for p in u i r; do + [ $p == "u" ] && prot=UDP + [ $p == "i" ] && prot=ICMP + [ $p == "r" ] && prot=RAW + + [ $ovr == "setsock" ] && m="-C" + [ $ovr == "cmsg" ] && m="-c" + [ $ovr == "both" ] && m="-C $((TOS2)) -c" + [ $ovr == "diff" ] && m="-C $((TOS )) -c" + + $NSEXE nohup tcpdump --immediate-mode -p -ni dummy0 -w $TMPF -c 4 2> /dev/null & + BG=$! + sleep 0.05 + + $NSEXE ./cmsg_sender -6 -p $p $m $((TOS2)) $TGT6 1234 + check_result $? 0 "TCLASS $prot $ovr - pass" + + while [ -d /proc/$BG ]; do + $NSEXE ./cmsg_sender -6 -p u $TGT6 1234 + done + + tcpdump -r $TMPF -v 2>&1 | grep "class $TOS2" >> /dev/null + check_result $? 0 "TCLASS $prot $ovr - packet data" + rm $TMPF + + [ $ovr == "both" ] && m="-C $((TOS )) -c" + [ $ovr == "diff" ] && m="-C $((TOS2)) -c" + + $NSEXE ./cmsg_sender -6 -p $p $m $((TOS)) -s $TGT6 1234 + check_result $? 1 "TCLASS $prot $ovr - rejection" + done +done + # Summary if [ $BAD -ne 0 ]; then echo "FAIL - $BAD/$TOTAL cases failed" diff --git a/tools/testing/selftests/net/cmsg_sender.c b/tools/testing/selftests/net/cmsg_sender.c index 844ca6134662..4033cf93eabf 100644 --- a/tools/testing/selftests/net/cmsg_sender.c +++ b/tools/testing/selftests/net/cmsg_sender.c @@ -46,6 +46,7 @@ struct options { struct { unsigned int mark; unsigned int dontfrag; + unsigned int tclass; } sockopt; struct { unsigned int family; @@ -62,6 +63,7 @@ struct options { } ts; struct { struct option_cmsg_u32 dontfrag; + struct option_cmsg_u32 tclass; } v6; } opt = { .size = 13, @@ -91,6 +93,8 @@ static void __attribute__((noreturn)) cs_usage(const char *bin) "\t\t-t Enable time stamp reporting\n" "\t\t-f val Set don't fragment via cmsg\n" "\t\t-F val Set don't fragment via setsockopt\n" + "\t\t-c val Set TCLASS via cmsg\n" + "\t\t-C val Set TCLASS via setsockopt\n" ""); exit(ERN_HELP); } @@ -99,7 +103,7 @@ static void cs_parse_args(int argc, char *argv[]) { char o; - while ((o = getopt(argc, argv, "46sS:p:m:M:d:tf:F:")) != -1) { + while ((o = getopt(argc, argv, "46sS:p:m:M:d:tf:F:c:C:")) != -1) { switch (o) { case 's': opt.silent_send = true; @@ -147,6 +151,13 @@ static void cs_parse_args(int argc, char *argv[]) case 'F': opt.sockopt.dontfrag = atoi(optarg); break; + case 'c': + opt.v6.tclass.ena = true; + opt.v6.tclass.val = atoi(optarg); + break; + case 'C': + opt.sockopt.tclass = atoi(optarg); + break; } } @@ -202,6 +213,8 @@ cs_write_cmsg(int fd, struct msghdr *msg, char *cbuf, size_t cbuf_sz) SOL_SOCKET, SO_MARK, &opt.mark); ca_write_cmsg_u32(cbuf, cbuf_sz, &cmsg_len, SOL_IPV6, IPV6_DONTFRAG, &opt.v6.dontfrag); + ca_write_cmsg_u32(cbuf, cbuf_sz, &cmsg_len, + SOL_IPV6, IPV6_TCLASS, &opt.v6.tclass); if (opt.txtime.ena) { struct sock_txtime so_txtime = { @@ -343,6 +356,10 @@ static void ca_set_sockopts(int fd) setsockopt(fd, SOL_IPV6, IPV6_DONTFRAG, &opt.sockopt.dontfrag, sizeof(opt.sockopt.dontfrag))) error(ERN_SOCKOPT, errno, "setsockopt IPV6_DONTFRAG"); + if (opt.sockopt.tclass && + setsockopt(fd, SOL_IPV6, IPV6_TCLASS, + &opt.sockopt.tclass, sizeof(opt.sockopt.tclass))) + error(ERN_SOCKOPT, errno, "setsockopt IPV6_TCLASS"); } int main(int argc, char *argv[]) From patchwork Thu Feb 17 01:21:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Kicinski X-Patchwork-Id: 544143 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 23A64C433FE for ; Thu, 17 Feb 2022 01:21:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230227AbiBQBVq (ORCPT ); Wed, 16 Feb 2022 20:21:46 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:48232 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230195AbiBQBVn (ORCPT ); Wed, 16 Feb 2022 20:21:43 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 646D1DDD; Wed, 16 Feb 2022 17:21:28 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id EDC9761CB9; Thu, 17 Feb 2022 01:21:27 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 61AEAC004E1; Thu, 17 Feb 2022 01:21:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1645060887; bh=FTEGWojkjlNcaaT3CzuuFlK8HbLnKzp/gldta9M8Abo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=invhP+bhIdD+ym+gXRyNqQsVpFTn5YAflx+Hu/a4wg3EuwMN0nbZF7T93401z0NA0 vTUF2ldmXKEXyIg53U9J2ZSGDl8XyT+RDVpkvSpURyIOCzmjpfqdjgYCNHwe7K7/xx Ebibl0/7+VjSSYEHkSlvUJtp6dRMe+0H0/b9/199nDAaMB4TqKE5Ej74JaeJ/QSkYo +QIqLWPh7u/J3dBpYEBDKErxgPvZ3cfFV2SuWu2tDjdt1pntYDLGnpYq90WJPZ6N48 NRiBCw30H11UPhsGqeuj4SO45k2ZrEIfvbA2KybtVsGxXs5T/MYp5+cVIaFnSozqtb 61HPJ6UD0ETAQ== From: Jakub Kicinski To: davem@davemloft.net Cc: netdev@vger.kernel.org, willemb@google.com, lorenzo@google.com, maze@google.com, dsahern@kernel.org, yoshfuji@linux-ipv6.org, shuah@kernel.org, linux-kselftest@vger.kernel.org, Jakub Kicinski Subject: [PATCH net-next 4/5] selftests: net: test IPV6_HOPLIMIT Date: Wed, 16 Feb 2022 17:21:19 -0800 Message-Id: <20220217012120.61250-5-kuba@kernel.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220217012120.61250-1-kuba@kernel.org> References: <20220217012120.61250-1-kuba@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org Test setting IPV6_HOPLIMIT via setsockopt and cmsg across socket types. Output without the kernel support (this series): Case HOPLIMIT ICMP cmsg - packet data returned 1, expected 0 Case HOPLIMIT ICMP diff - packet data returned 1, expected 0 Signed-off-by: Jakub Kicinski --- tools/testing/selftests/net/cmsg_ipv6.sh | 31 +++++++++++++++++++++++ tools/testing/selftests/net/cmsg_sender.c | 19 +++++++++++++- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/net/cmsg_ipv6.sh b/tools/testing/selftests/net/cmsg_ipv6.sh index f7bb6ce68c88..e42c36e0d741 100755 --- a/tools/testing/selftests/net/cmsg_ipv6.sh +++ b/tools/testing/selftests/net/cmsg_ipv6.sh @@ -106,6 +106,37 @@ for ovr in setsock cmsg both diff; do done done +# IPV6_HOPLIMIT +LIM=4 + +for ovr in setsock cmsg both diff; do + for p in u i r; do + [ $p == "u" ] && prot=UDP + [ $p == "i" ] && prot=ICMP + [ $p == "r" ] && prot=RAW + + [ $ovr == "setsock" ] && m="-L" + [ $ovr == "cmsg" ] && m="-l" + [ $ovr == "both" ] && m="-L $LIM -l" + [ $ovr == "diff" ] && m="-L $((LIM + 1)) -l" + + $NSEXE nohup tcpdump --immediate-mode -p -ni dummy0 -w $TMPF -c 4 2> /dev/null & + BG=$! + sleep 0.05 + + $NSEXE ./cmsg_sender -6 -p $p $m $LIM $TGT6 1234 + check_result $? 0 "HOPLIMIT $prot $ovr - pass" + + while [ -d /proc/$BG ]; do + $NSEXE ./cmsg_sender -6 -p u $TGT6 1234 + done + + tcpdump -r $TMPF -v 2>&1 | grep "hlim $LIM[^0-9]" >> /dev/null + check_result $? 0 "HOPLIMIT $prot $ovr - packet data" + rm $TMPF + done +done + # Summary if [ $BAD -ne 0 ]; then echo "FAIL - $BAD/$TOTAL cases failed" diff --git a/tools/testing/selftests/net/cmsg_sender.c b/tools/testing/selftests/net/cmsg_sender.c index 4033cf93eabf..6136aa7df1c4 100644 --- a/tools/testing/selftests/net/cmsg_sender.c +++ b/tools/testing/selftests/net/cmsg_sender.c @@ -47,6 +47,7 @@ struct options { unsigned int mark; unsigned int dontfrag; unsigned int tclass; + unsigned int hlimit; } sockopt; struct { unsigned int family; @@ -64,6 +65,7 @@ struct options { struct { struct option_cmsg_u32 dontfrag; struct option_cmsg_u32 tclass; + struct option_cmsg_u32 hlimit; } v6; } opt = { .size = 13, @@ -95,6 +97,8 @@ static void __attribute__((noreturn)) cs_usage(const char *bin) "\t\t-F val Set don't fragment via setsockopt\n" "\t\t-c val Set TCLASS via cmsg\n" "\t\t-C val Set TCLASS via setsockopt\n" + "\t\t-l val Set HOPLIMIT via cmsg\n" + "\t\t-L val Set HOPLIMIT via setsockopt\n" ""); exit(ERN_HELP); } @@ -103,7 +107,7 @@ static void cs_parse_args(int argc, char *argv[]) { char o; - while ((o = getopt(argc, argv, "46sS:p:m:M:d:tf:F:c:C:")) != -1) { + while ((o = getopt(argc, argv, "46sS:p:m:M:d:tf:F:c:C:l:L:")) != -1) { switch (o) { case 's': opt.silent_send = true; @@ -158,6 +162,13 @@ static void cs_parse_args(int argc, char *argv[]) case 'C': opt.sockopt.tclass = atoi(optarg); break; + case 'l': + opt.v6.hlimit.ena = true; + opt.v6.hlimit.val = atoi(optarg); + break; + case 'L': + opt.sockopt.hlimit = atoi(optarg); + break; } } @@ -215,6 +226,8 @@ cs_write_cmsg(int fd, struct msghdr *msg, char *cbuf, size_t cbuf_sz) SOL_IPV6, IPV6_DONTFRAG, &opt.v6.dontfrag); ca_write_cmsg_u32(cbuf, cbuf_sz, &cmsg_len, SOL_IPV6, IPV6_TCLASS, &opt.v6.tclass); + ca_write_cmsg_u32(cbuf, cbuf_sz, &cmsg_len, + SOL_IPV6, IPV6_HOPLIMIT, &opt.v6.hlimit); if (opt.txtime.ena) { struct sock_txtime so_txtime = { @@ -360,6 +373,10 @@ static void ca_set_sockopts(int fd) setsockopt(fd, SOL_IPV6, IPV6_TCLASS, &opt.sockopt.tclass, sizeof(opt.sockopt.tclass))) error(ERN_SOCKOPT, errno, "setsockopt IPV6_TCLASS"); + if (opt.sockopt.hlimit && + setsockopt(fd, SOL_IPV6, IPV6_UNICAST_HOPS, + &opt.sockopt.hlimit, sizeof(opt.sockopt.hlimit))) + error(ERN_SOCKOPT, errno, "setsockopt IPV6_HOPLIMIT"); } int main(int argc, char *argv[]) From patchwork Thu Feb 17 01:21:20 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Kicinski X-Patchwork-Id: 543546 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6B31CC43217 for ; Thu, 17 Feb 2022 01:21:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230235AbiBQBVr (ORCPT ); Wed, 16 Feb 2022 20:21:47 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:48242 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230199AbiBQBVn (ORCPT ); Wed, 16 Feb 2022 20:21:43 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 35D52E43; Wed, 16 Feb 2022 17:21:29 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id BACBB61CB2; Thu, 17 Feb 2022 01:21:28 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id EA50FC340F4; Thu, 17 Feb 2022 01:21:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1645060888; bh=HZVCUt/+nmRvfzJPKLWQYPFJ0Jhkwie0cI7OG0z0bWk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tclIz1UHRsJIMBoPSBmNid6qZPPSkc+0CdRoRJMM1saTDHwFj0tJ2RWkBMmaP+VMW 6oZUrxdMnbvSFt0E2OLLVhL+K0hTfKHYXAUynE1iAhXepKh1BSZbI+rQ7refDg5qRp 5M0ACwAl6qHe9E634T1HIqBxog0i0vTcSX8pUogAJWKM99KPbLEwejy78sFPffmXg3 3896Duv9nCRbL4t2OiFZc161I35muyplZ5fuWq1nJxza4rnmA1COEZZ7ep4hHMGe6B VgXjP25B9sapTqC/G8/pKbsb/oCmVqunR617MufxQmEh0Olzcg6JiIbmmo8lE9Tw8O oSzHQG0XA6VOQ== From: Jakub Kicinski To: davem@davemloft.net Cc: netdev@vger.kernel.org, willemb@google.com, lorenzo@google.com, maze@google.com, dsahern@kernel.org, yoshfuji@linux-ipv6.org, shuah@kernel.org, linux-kselftest@vger.kernel.org, Jakub Kicinski Subject: [PATCH net-next 5/5] selftests: net: basic test for IPV6_2292* Date: Wed, 16 Feb 2022 17:21:20 -0800 Message-Id: <20220217012120.61250-6-kuba@kernel.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220217012120.61250-1-kuba@kernel.org> References: <20220217012120.61250-1-kuba@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org Add a basic test to make sure ping sockets don't crash with IPV6_2292* options. Signed-off-by: Jakub Kicinski --- tools/testing/selftests/net/cmsg_ipv6.sh | 9 +++++++ tools/testing/selftests/net/cmsg_sender.c | 33 ++++++++++++++++++++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/net/cmsg_ipv6.sh b/tools/testing/selftests/net/cmsg_ipv6.sh index e42c36e0d741..2d89cb0ad288 100755 --- a/tools/testing/selftests/net/cmsg_ipv6.sh +++ b/tools/testing/selftests/net/cmsg_ipv6.sh @@ -137,6 +137,15 @@ for ovr in setsock cmsg both diff; do done done +# IPV6 exthdr +for p in u i r; do + # Very basic "does it crash" test + for h in h d r; do + $NSEXE ./cmsg_sender -p $p -6 -H $h $TGT6 1234 + check_result $? 0 "ExtHdr $prot $ovr - pass" + done +done + # Summary if [ $BAD -ne 0 ]; then echo "FAIL - $BAD/$TOTAL cases failed" diff --git a/tools/testing/selftests/net/cmsg_sender.c b/tools/testing/selftests/net/cmsg_sender.c index 6136aa7df1c4..aed7845c08a8 100644 --- a/tools/testing/selftests/net/cmsg_sender.c +++ b/tools/testing/selftests/net/cmsg_sender.c @@ -66,6 +66,7 @@ struct options { struct option_cmsg_u32 dontfrag; struct option_cmsg_u32 tclass; struct option_cmsg_u32 hlimit; + struct option_cmsg_u32 exthdr; } v6; } opt = { .size = 13, @@ -99,6 +100,8 @@ static void __attribute__((noreturn)) cs_usage(const char *bin) "\t\t-C val Set TCLASS via setsockopt\n" "\t\t-l val Set HOPLIMIT via cmsg\n" "\t\t-L val Set HOPLIMIT via setsockopt\n" + "\t\t-H type Add an IPv6 header option\n" + "\t\t (h = HOP; d = DST; r = RTDST)" ""); exit(ERN_HELP); } @@ -107,7 +110,7 @@ static void cs_parse_args(int argc, char *argv[]) { char o; - while ((o = getopt(argc, argv, "46sS:p:m:M:d:tf:F:c:C:l:L:")) != -1) { + while ((o = getopt(argc, argv, "46sS:p:m:M:d:tf:F:c:C:l:L:H:")) != -1) { switch (o) { case 's': opt.silent_send = true; @@ -169,6 +172,23 @@ static void cs_parse_args(int argc, char *argv[]) case 'L': opt.sockopt.hlimit = atoi(optarg); break; + case 'H': + opt.v6.exthdr.ena = true; + switch (optarg[0]) { + case 'h': + opt.v6.exthdr.val = IPV6_HOPOPTS; + break; + case 'd': + opt.v6.exthdr.val = IPV6_DSTOPTS; + break; + case 'r': + opt.v6.exthdr.val = IPV6_RTHDRDSTOPTS; + break; + default: + printf("Error: hdr type: %s\n", optarg); + break; + } + break; } } @@ -272,6 +292,17 @@ cs_write_cmsg(int fd, struct msghdr *msg, char *cbuf, size_t cbuf_sz) *(__u32 *)CMSG_DATA(cmsg) = SOF_TIMESTAMPING_TX_SCHED | SOF_TIMESTAMPING_TX_SOFTWARE; } + if (opt.v6.exthdr.ena) { + cmsg = (struct cmsghdr *)(cbuf + cmsg_len); + cmsg_len += CMSG_SPACE(8); + if (cbuf_sz < cmsg_len) + error(ERN_CMSG_WR, EFAULT, "cmsg buffer too small"); + + cmsg->cmsg_level = SOL_IPV6; + cmsg->cmsg_type = opt.v6.exthdr.val; + cmsg->cmsg_len = CMSG_LEN(8); + *(__u64 *)CMSG_DATA(cmsg) = 0; + } if (cmsg_len) msg->msg_controllen = cmsg_len;