From patchwork Wed Oct 13 06:50:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Leonard Crestez X-Patchwork-Id: 12554935 X-Patchwork-Delegate: kuba@kernel.org 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0AC01C433F5 for ; Wed, 13 Oct 2021 06:50:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E40E4600D3 for ; Wed, 13 Oct 2021 06:50:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238094AbhJMGw6 (ORCPT ); Wed, 13 Oct 2021 02:52:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56116 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233247AbhJMGw4 (ORCPT ); Wed, 13 Oct 2021 02:52:56 -0400 Received: from mail-ed1-x52e.google.com (mail-ed1-x52e.google.com [IPv6:2a00:1450:4864:20::52e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 18ADFC061570; Tue, 12 Oct 2021 23:50:53 -0700 (PDT) Received: by mail-ed1-x52e.google.com with SMTP id w19so5882495edd.2; Tue, 12 Oct 2021 23:50:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=RYCKTVD13R38t3WR/vos+HLpCIiXFIXTlTL/zxQSSKw=; b=SnEw/GhaqO5KlOEO8Hzvk0UBbd1OS83DRJyCeWeH1RscJs+pMIu0dOxxyT6cawkP7t sYXtHVWsTnzk5QGYtH0a1GeDmtRC0H0L1hDZOx+c8M+Sl6W36viaG1RXrsan6gIwAQVX 8S3Wvk9RVqdy1zSWBcABrIqxREbEAk9Zk9S5lZsC7evYe2RNfou5kRV87hnuqOEMeO/y X9EympOYFd4ZgH63RnxxqLn+jEklYri7Uj3V/ecrROX2BftFAQ199xF7sWxpCI4xvpJ9 Z0KBzQhm8ESQHzFtl/f/dY4Al6a/1dO8o0i55n0Mstx7TRKdh4cMntkJmUzOKbZ+zBHh xUjg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=RYCKTVD13R38t3WR/vos+HLpCIiXFIXTlTL/zxQSSKw=; b=Am7R8xz4X1Ap6a+NbqUKk4M1UDj1jo1DLjGO/fzqSqfpuLsw3lctfsRYzSfC6o3xwx goMBtuf3I8kLE0eyxDms8qstawgM9v8DS+WgNI8SO+TbYXZu3hRM4e9Aq0ZDG40LOLYQ nGUUhoUUap40IaW85c2Fi3qFWz1S0903iZGrXjvsMQH+AS2ZmlOJZRX1uoKNTxVpFr2w 0MRmC3agg97m7TJaan7ojWaM91Lr7F9fxGjpUr0LIjLZ+ASAiWI0D+x7gS9n0ON++v/+ XajW8DsrkqAcCitP7Leqgyiv2pFUpDAyWvk7CbGYUCNPXeZeO4Kk3+8ltDdScHnE8OsN AcRw== X-Gm-Message-State: AOAM532fRFvYVeFA9xeu1RAfq0c+VCE9Ezc+T74O4q2quDftdvTQFoFK DIKMmHpeqd8Q5Qt9XOl8kfI= X-Google-Smtp-Source: ABdhPJw4Omo9b4Hq97vOhIHDiwGyV/cs39eLeCUzvUb1XQeIZd9/WydchaaorVIjOHJjh4zTM/9uRw== X-Received: by 2002:a50:e184:: with SMTP id k4mr7047706edl.217.1634107851671; Tue, 12 Oct 2021 23:50:51 -0700 (PDT) Received: from ponky.lan ([2a04:241e:501:3870:6346:a6a3:f7ea:349e]) by smtp.gmail.com with ESMTPSA id m15sm4568710edd.5.2021.10.12.23.50.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Oct 2021 23:50:49 -0700 (PDT) From: Leonard Crestez To: David Ahern , Eric Dumazet Cc: "David S. Miller" , Hideaki YOSHIFUJI , Jakub Kicinski , Martin KaFai Lau , Kuniyuki Iwashima , Yonghong Song , Alexander Duyck , Florian Westphal , netdev@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 1/4] tcp: md5: Fix overlap between vrf and non-vrf keys Date: Wed, 13 Oct 2021 09:50:35 +0300 Message-Id: <6d99312c4863c37ad394c815f8529ee635bdb0d0.1634107317.git.cdleonard@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org With net.ipv4.tcp_l3mdev_accept=1 it is possible for a listen socket to accept connection from the same client address in different VRFs. It is also possible to set different MD5 keys for these clients which differ only in the tcpm_l3index field. This appears to work when distinguishing between different VRFs but not between non-VRF and VRF connections. In particular: * tcp_md5_do_lookup_exact will match a non-vrf key against a vrf key. This means that adding a key with l3index != 0 after a key with l3index == 0 will cause the earlier key to be deleted. Both keys can be present if the non-vrf key is added later. * _tcp_md5_do_lookup can match a non-vrf key before a vrf key. This casues failures if the passwords differ. Fix this by making tcp_md5_do_lookup_exact perform an actual exact comparison on l3index and by making __tcp_md5_do_lookup perfer vrf-bound keys above other considerations like prefixlen. Fixes: dea53bb80e07 ("tcp: Add l3index to tcp_md5sig_key and md5 functions") Signed-off-by: Leonard Crestez Reviewed-by: David Ahern --- net/ipv4/tcp_ipv4.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 29a57bd159f0..a9a6a6d598c6 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1035,10 +1035,24 @@ static void tcp_v4_reqsk_destructor(struct request_sock *req) */ DEFINE_STATIC_KEY_FALSE(tcp_md5_needed); EXPORT_SYMBOL(tcp_md5_needed); +static bool better_md5_match(struct tcp_md5sig_key *old, struct tcp_md5sig_key *new) +{ + if (!old) + return true; + + /* l3index always overrides non-l3index */ + if (old->l3index && new->l3index == 0) + return false; + if (old->l3index == 0 && new->l3index) + return true; + + return old->prefixlen < new->prefixlen; +} + /* Find the Key structure for an address. */ struct tcp_md5sig_key *__tcp_md5_do_lookup(const struct sock *sk, int l3index, const union tcp_md5_addr *addr, int family) { @@ -1072,12 +1086,11 @@ struct tcp_md5sig_key *__tcp_md5_do_lookup(const struct sock *sk, int l3index, #endif } else { match = false; } - if (match && (!best_match || - key->prefixlen > best_match->prefixlen)) + if (match && better_md5_match(best_match, key)) best_match = key; } return best_match; } EXPORT_SYMBOL(__tcp_md5_do_lookup); @@ -1103,11 +1116,11 @@ static struct tcp_md5sig_key *tcp_md5_do_lookup_exact(const struct sock *sk, #endif hlist_for_each_entry_rcu(key, &md5sig->head, node, lockdep_sock_is_held(sk)) { if (key->family != family) continue; - if (key->l3index && key->l3index != l3index) + if (key->l3index != l3index) continue; if (!memcmp(&key->addr, addr, size) && key->prefixlen == prefixlen) return key; } From patchwork Wed Oct 13 06:50:36 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Leonard Crestez X-Patchwork-Id: 12554937 X-Patchwork-Delegate: kuba@kernel.org 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6AA9CC433EF for ; Wed, 13 Oct 2021 06:50:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4813F61027 for ; Wed, 13 Oct 2021 06:50:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238106AbhJMGw7 (ORCPT ); Wed, 13 Oct 2021 02:52:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56126 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238008AbhJMGw5 (ORCPT ); Wed, 13 Oct 2021 02:52:57 -0400 Received: from mail-ed1-x533.google.com (mail-ed1-x533.google.com [IPv6:2a00:1450:4864:20::533]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8C24EC061570; Tue, 12 Oct 2021 23:50:54 -0700 (PDT) Received: by mail-ed1-x533.google.com with SMTP id r18so5668746edv.12; Tue, 12 Oct 2021 23:50:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=jI/HQWJNxag0LtWKfS+LsJ8x2RXsbHwVUNIAO3SgoGk=; b=J28jL3G32bZRp8wMRdcW1/HLu++Hx0gdGrtbhjn1hVlIcZsht7NFb3AlXcSxNUsXaS WTaLAtHP8tOlklMM6EDSghQQVB1zvn8qB61QxAXi7FNnvGFUgpe9/WnDx4BknMxlGnuF zeFbMdZbIvTzQTCnbYZ6GCS5uzYheh+pv5brLBLt/9pEFahDoeLf2dWdL51R5DMUc9nf m+mrOLpWdxYNPDDYi4qRndYOZdnL41mc9EjVqRZLqJ1bMu3U87foFpT6mfFSpDNGRTHS KGRUFA8zSIj0NzH4S3S7D2uTEVSG+gFQ8Q5Yij8H7Cl/97HgMvR++y8RAYGFtFktkh4/ M2rw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=jI/HQWJNxag0LtWKfS+LsJ8x2RXsbHwVUNIAO3SgoGk=; b=qkAgDqWpMFq6BqooMM8j4UUvaL/zSLrNjYC8NqMDiJm00ZJ+DhVQggNSemSBriCNIt 9x/3OShvciPm/KYLqBYMkujIyJSRxJlmsKyO/yfx8ZVxuc6VY1/ocNuDbmfyqZWqgv9z ljnKo/lYYS5QtR8BvtpOLU0bWv7d/9v1rSFD7KP/VrnUKM1KytMw3pDZsaNI4nY5hbsl Rygnaz5x6XnM4mJe3YQHmnTQiKGxeaqE+Bi7Fk2qAOyr8Y1R2MexzBTKQ9K+X1ijqqyP t5BKAcnQ4vc/qFrWc+Rao+A+W9dYky3tZcFG5/MXWRbJaZOJg/7Vj+0wCVlIgLE3z/vO 7L3Q== X-Gm-Message-State: AOAM533QYaKtkwLDud+CjaahDSx610F/I7ll+c8C5hzGaB/wWJhWXUg9 l5gF5QeSehbgsWPI2fw+EwU= X-Google-Smtp-Source: ABdhPJzY1BrP1SwJq13GrHDfcpibPHujWnCMEGpws/5ylITiG+CMrJxf9gIDQvr5I1cO2su4FdoylQ== X-Received: by 2002:a17:906:17d5:: with SMTP id u21mr16430299eje.16.1634107853093; Tue, 12 Oct 2021 23:50:53 -0700 (PDT) Received: from ponky.lan ([2a04:241e:501:3870:6346:a6a3:f7ea:349e]) by smtp.gmail.com with ESMTPSA id m15sm4568710edd.5.2021.10.12.23.50.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Oct 2021 23:50:52 -0700 (PDT) From: Leonard Crestez To: David Ahern , Eric Dumazet Cc: "David S. Miller" , Hideaki YOSHIFUJI , Jakub Kicinski , Martin KaFai Lau , Kuniyuki Iwashima , Yonghong Song , Alexander Duyck , Florian Westphal , netdev@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 2/4] tcp: md5: Allow MD5SIG_FLAG_IFINDEX with ifindex=0 Date: Wed, 13 Oct 2021 09:50:36 +0300 Message-Id: <9eb867a3751ee4213d8019139cf1af42570e9e91.1634107317.git.cdleonard@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Multiple VRFs are generally meant to be "separate" but right now md5 keys for the default VRF also affect connections inside VRFs if the IP addresses happen to overlap. So far the combination of TCP_MD5SIG_IFINDEX with tcpm_ifindex == 0 was an error, accept this to mean "key only applies to default VRF". This is what applications using VRFs for traffic separation want. Signed-off-by: Leonard Crestez Reviewed-by: David Ahern --- include/net/tcp.h | 5 +++-- net/ipv4/tcp_ipv4.c | 26 ++++++++++++++++---------- net/ipv6/tcp_ipv6.c | 15 +++++++++------ 3 files changed, 28 insertions(+), 18 deletions(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index 4c2898ac6569..10f3a37eceb2 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -1588,10 +1588,11 @@ union tcp_md5_addr { struct tcp_md5sig_key { struct hlist_node node; u8 keylen; u8 family; /* AF_INET or AF_INET6 */ u8 prefixlen; + u8 flags; union tcp_md5_addr addr; int l3index; /* set if key added with L3 scope */ u8 key[TCP_MD5SIG_MAXKEYLEN]; struct rcu_head rcu; }; @@ -1633,14 +1634,14 @@ struct tcp_md5sig_pool { /* - functions */ int tcp_v4_md5_hash_skb(char *md5_hash, const struct tcp_md5sig_key *key, const struct sock *sk, const struct sk_buff *skb); int tcp_md5_do_add(struct sock *sk, const union tcp_md5_addr *addr, - int family, u8 prefixlen, int l3index, + int family, u8 prefixlen, int l3index, u8 flags, const u8 *newkey, u8 newkeylen, gfp_t gfp); int tcp_md5_do_del(struct sock *sk, const union tcp_md5_addr *addr, - int family, u8 prefixlen, int l3index); + int family, u8 prefixlen, int l3index, u8 flags); struct tcp_md5sig_key *tcp_v4_md5_lookup(const struct sock *sk, const struct sock *addr_sk); #ifdef CONFIG_TCP_MD5SIG #include diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index a9a6a6d598c6..5e6d8cb82ce5 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1071,11 +1071,11 @@ struct tcp_md5sig_key *__tcp_md5_do_lookup(const struct sock *sk, int l3index, hlist_for_each_entry_rcu(key, &md5sig->head, node, lockdep_sock_is_held(sk)) { if (key->family != family) continue; - if (key->l3index && key->l3index != l3index) + if (key->flags & TCP_MD5SIG_FLAG_IFINDEX && key->l3index != l3index) continue; if (family == AF_INET) { mask = inet_make_mask(key->prefixlen); match = (key->addr.a4.s_addr & mask) == (addr->a4.s_addr & mask); @@ -1096,11 +1096,11 @@ struct tcp_md5sig_key *__tcp_md5_do_lookup(const struct sock *sk, int l3index, EXPORT_SYMBOL(__tcp_md5_do_lookup); static struct tcp_md5sig_key *tcp_md5_do_lookup_exact(const struct sock *sk, const union tcp_md5_addr *addr, int family, u8 prefixlen, - int l3index) + int l3index, u8 flags) { const struct tcp_sock *tp = tcp_sk(sk); struct tcp_md5sig_key *key; unsigned int size = sizeof(struct in_addr); const struct tcp_md5sig_info *md5sig; @@ -1116,10 +1116,12 @@ static struct tcp_md5sig_key *tcp_md5_do_lookup_exact(const struct sock *sk, #endif hlist_for_each_entry_rcu(key, &md5sig->head, node, lockdep_sock_is_held(sk)) { if (key->family != family) continue; + if ((key->flags & TCP_MD5SIG_FLAG_IFINDEX) != (flags & TCP_MD5SIG_FLAG_IFINDEX)) + continue; if (key->l3index != l3index) continue; if (!memcmp(&key->addr, addr, size) && key->prefixlen == prefixlen) return key; @@ -1140,19 +1142,19 @@ struct tcp_md5sig_key *tcp_v4_md5_lookup(const struct sock *sk, } EXPORT_SYMBOL(tcp_v4_md5_lookup); /* This can be called on a newly created socket, from other files */ int tcp_md5_do_add(struct sock *sk, const union tcp_md5_addr *addr, - int family, u8 prefixlen, int l3index, + int family, u8 prefixlen, int l3index, u8 flags, const u8 *newkey, u8 newkeylen, gfp_t gfp) { /* Add Key to the list */ struct tcp_md5sig_key *key; struct tcp_sock *tp = tcp_sk(sk); struct tcp_md5sig_info *md5sig; - key = tcp_md5_do_lookup_exact(sk, addr, family, prefixlen, l3index); + key = tcp_md5_do_lookup_exact(sk, addr, family, prefixlen, l3index, flags); if (key) { /* Pre-existing entry - just update that one. * Note that the key might be used concurrently. * data_race() is telling kcsan that we do not care of * key mismatches, since changing MD5 key on live flows @@ -1193,24 +1195,25 @@ int tcp_md5_do_add(struct sock *sk, const union tcp_md5_addr *addr, memcpy(key->key, newkey, newkeylen); key->keylen = newkeylen; key->family = family; key->prefixlen = prefixlen; key->l3index = l3index; + key->flags = flags; memcpy(&key->addr, addr, (family == AF_INET6) ? sizeof(struct in6_addr) : sizeof(struct in_addr)); hlist_add_head_rcu(&key->node, &md5sig->head); return 0; } EXPORT_SYMBOL(tcp_md5_do_add); int tcp_md5_do_del(struct sock *sk, const union tcp_md5_addr *addr, int family, - u8 prefixlen, int l3index) + u8 prefixlen, int l3index, u8 flags) { struct tcp_md5sig_key *key; - key = tcp_md5_do_lookup_exact(sk, addr, family, prefixlen, l3index); + key = tcp_md5_do_lookup_exact(sk, addr, family, prefixlen, l3index, flags); if (!key) return -ENOENT; hlist_del_rcu(&key->node); atomic_sub(sizeof(*key), &sk->sk_omem_alloc); kfree_rcu(key, rcu); @@ -1240,28 +1243,31 @@ static int tcp_v4_parse_md5_keys(struct sock *sk, int optname, struct tcp_md5sig cmd; struct sockaddr_in *sin = (struct sockaddr_in *)&cmd.tcpm_addr; const union tcp_md5_addr *addr; u8 prefixlen = 32; int l3index = 0; + u8 flags; if (optlen < sizeof(cmd)) return -EINVAL; if (copy_from_sockptr(&cmd, optval, sizeof(cmd))) return -EFAULT; if (sin->sin_family != AF_INET) return -EINVAL; + flags = cmd.tcpm_flags & TCP_MD5SIG_FLAG_IFINDEX; + if (optname == TCP_MD5SIG_EXT && cmd.tcpm_flags & TCP_MD5SIG_FLAG_PREFIX) { prefixlen = cmd.tcpm_prefixlen; if (prefixlen > 32) return -EINVAL; } - if (optname == TCP_MD5SIG_EXT && + if (optname == TCP_MD5SIG_EXT && cmd.tcpm_ifindex && cmd.tcpm_flags & TCP_MD5SIG_FLAG_IFINDEX) { struct net_device *dev; rcu_read_lock(); dev = dev_get_by_index_rcu(sock_net(sk), cmd.tcpm_ifindex); @@ -1278,16 +1284,16 @@ static int tcp_v4_parse_md5_keys(struct sock *sk, int optname, } addr = (union tcp_md5_addr *)&sin->sin_addr.s_addr; if (!cmd.tcpm_keylen) - return tcp_md5_do_del(sk, addr, AF_INET, prefixlen, l3index); + return tcp_md5_do_del(sk, addr, AF_INET, prefixlen, l3index, flags); if (cmd.tcpm_keylen > TCP_MD5SIG_MAXKEYLEN) return -EINVAL; - return tcp_md5_do_add(sk, addr, AF_INET, prefixlen, l3index, + return tcp_md5_do_add(sk, addr, AF_INET, prefixlen, l3index, flags, cmd.tcpm_key, cmd.tcpm_keylen, GFP_KERNEL); } static int tcp_v4_md5_hash_headers(struct tcp_md5sig_pool *hp, __be32 daddr, __be32 saddr, @@ -1607,11 +1613,11 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, * We're using one, so create a matching key * on the newsk structure. If we fail to get * memory, then we end up not copying the key * across. Shucks. */ - tcp_md5_do_add(newsk, addr, AF_INET, 32, l3index, + tcp_md5_do_add(newsk, addr, AF_INET, 32, l3index, key->flags, key->key, key->keylen, GFP_ATOMIC); sk_nocaps_add(newsk, NETIF_F_GSO_MASK); } #endif diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 8cf5ff2e9504..1ef27cd7dbff 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -597,31 +597,34 @@ static int tcp_v6_parse_md5_keys(struct sock *sk, int optname, { struct tcp_md5sig cmd; struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&cmd.tcpm_addr; int l3index = 0; u8 prefixlen; + u8 flags; if (optlen < sizeof(cmd)) return -EINVAL; if (copy_from_sockptr(&cmd, optval, sizeof(cmd))) return -EFAULT; if (sin6->sin6_family != AF_INET6) return -EINVAL; + flags = cmd.tcpm_flags & TCP_MD5SIG_FLAG_IFINDEX; + if (optname == TCP_MD5SIG_EXT && cmd.tcpm_flags & TCP_MD5SIG_FLAG_PREFIX) { prefixlen = cmd.tcpm_prefixlen; if (prefixlen > 128 || (ipv6_addr_v4mapped(&sin6->sin6_addr) && prefixlen > 32)) return -EINVAL; } else { prefixlen = ipv6_addr_v4mapped(&sin6->sin6_addr) ? 32 : 128; } - if (optname == TCP_MD5SIG_EXT && + if (optname == TCP_MD5SIG_EXT && cmd.tcpm_ifindex && cmd.tcpm_flags & TCP_MD5SIG_FLAG_IFINDEX) { struct net_device *dev; rcu_read_lock(); dev = dev_get_by_index_rcu(sock_net(sk), cmd.tcpm_ifindex); @@ -638,26 +641,26 @@ static int tcp_v6_parse_md5_keys(struct sock *sk, int optname, if (!cmd.tcpm_keylen) { if (ipv6_addr_v4mapped(&sin6->sin6_addr)) return tcp_md5_do_del(sk, (union tcp_md5_addr *)&sin6->sin6_addr.s6_addr32[3], AF_INET, prefixlen, - l3index); + l3index, flags); return tcp_md5_do_del(sk, (union tcp_md5_addr *)&sin6->sin6_addr, - AF_INET6, prefixlen, l3index); + AF_INET6, prefixlen, l3index, flags); } if (cmd.tcpm_keylen > TCP_MD5SIG_MAXKEYLEN) return -EINVAL; if (ipv6_addr_v4mapped(&sin6->sin6_addr)) return tcp_md5_do_add(sk, (union tcp_md5_addr *)&sin6->sin6_addr.s6_addr32[3], - AF_INET, prefixlen, l3index, + AF_INET, prefixlen, l3index, flags, cmd.tcpm_key, cmd.tcpm_keylen, GFP_KERNEL); return tcp_md5_do_add(sk, (union tcp_md5_addr *)&sin6->sin6_addr, - AF_INET6, prefixlen, l3index, + AF_INET6, prefixlen, l3index, flags, cmd.tcpm_key, cmd.tcpm_keylen, GFP_KERNEL); } static int tcp_v6_md5_hash_headers(struct tcp_md5sig_pool *hp, const struct in6_addr *daddr, @@ -1402,11 +1405,11 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff * * on the newsk structure. If we fail to get * memory, then we end up not copying the key * across. Shucks. */ tcp_md5_do_add(newsk, (union tcp_md5_addr *)&newsk->sk_v6_daddr, - AF_INET6, 128, l3index, key->key, key->keylen, + AF_INET6, 128, l3index, key->flags, key->key, key->keylen, sk_gfp_mask(sk, GFP_ATOMIC)); } #endif if (__inet_inherit_port(sk, newsk) < 0) { From patchwork Wed Oct 13 06:50:37 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Leonard Crestez X-Patchwork-Id: 12554939 X-Patchwork-Delegate: kuba@kernel.org 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 128D6C433FE for ; Wed, 13 Oct 2021 06:51:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E8A38600D3 for ; Wed, 13 Oct 2021 06:51:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238155AbhJMGxE (ORCPT ); Wed, 13 Oct 2021 02:53:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56134 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238124AbhJMGw7 (ORCPT ); Wed, 13 Oct 2021 02:52:59 -0400 Received: from mail-ed1-x529.google.com (mail-ed1-x529.google.com [IPv6:2a00:1450:4864:20::529]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CEC59C061570; Tue, 12 Oct 2021 23:50:56 -0700 (PDT) Received: by mail-ed1-x529.google.com with SMTP id d3so5850159edp.3; Tue, 12 Oct 2021 23:50:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=6N39G7ZGCVEFusy0Xx0rScelbxpLk6pfw5D48AWuodI=; b=iiGu5rUuqINXoeXJUal9rU7i/ufLOqi883k0R9zY26ivnP0Ey1Ial4tu3/Mr8csIx2 AKVi6Yj7426iy8nJsbhyj5TJ5FZrwdgyQBmfivKhICpGJIZAWaBLo4xahssDdEnphTPN 3qMrK8knr2tMoaTV+n0gRp20IYekBjqoQxYT55042Qzo4Vmz5IENiLuC4ntygeS9lWPQ LhFh50Mt7IA40Az8RuN8BBILGYP0Xq9WqslXNHfSbbEQGqkQ7yuy7wK8aplCAXcpcyhx PF8jMyFB+GZi/j1e0nY6l+21m3qejIQAuwOeEDn0u9NIpNmsH9dBb9qIpCk567OTYRDt RBmA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=6N39G7ZGCVEFusy0Xx0rScelbxpLk6pfw5D48AWuodI=; b=Vf9y3kJwvmHbeUuqNNt6uqGI/tdRrWt70EG/Ugv5vDLNAQ9nMD2Ucq6CbSItmWJ2by y5HT8PnhMHPM1ZB6e4ZHskVkSdF1wP0H6qlIEbXY78/FlfcFYynrYqG3Qm05Yu9jerCJ wHyS2+xzlwvGNqZcw9t8XZZ2aWdnb0aTY+3kK1jzHmoDWYFcnLqm8oWGZZN8b3Srfl0t 1gNnD4SKRWg1ba+IhQuPg/FkDBsvsgWj9bJke6nhHGkm5cQVrCbrsfAmpmONPZ6B3q5w Mb6F4tGU9+O3w7YxqKP7vAbqrWgbgGzCWuyxgAhMg8dPlxlbLJEU2EVVrwBn/GBK9Cz2 SDRQ== X-Gm-Message-State: AOAM531qYIQIdNdOyN5ggcAb+6hu7c7XkN37Jt/YA8ftlhg83wbQbiyM FATP4i3VGwDxVnJa1WmKwa4= X-Google-Smtp-Source: ABdhPJzuhPKi1h4s7u01kxsEHsUMUCyENeBE03vzAX0K7Wx/YZboJUVO9bSf2toSclju9qQ+6f0eDg== X-Received: by 2002:a50:d84c:: with SMTP id v12mr6731644edj.201.1634107854528; Tue, 12 Oct 2021 23:50:54 -0700 (PDT) Received: from ponky.lan ([2a04:241e:501:3870:6346:a6a3:f7ea:349e]) by smtp.gmail.com with ESMTPSA id m15sm4568710edd.5.2021.10.12.23.50.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Oct 2021 23:50:54 -0700 (PDT) From: Leonard Crestez To: David Ahern , Eric Dumazet Cc: "David S. Miller" , Hideaki YOSHIFUJI , Jakub Kicinski , Martin KaFai Lau , Kuniyuki Iwashima , Yonghong Song , Alexander Duyck , Florian Westphal , netdev@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 3/4] selftests: nettest: Add --{do,no}-bind-key-ifindex Date: Wed, 13 Oct 2021 09:50:37 +0300 Message-Id: <122a68cd7fd28e9a5580f16f650826437f7397a1.1634107317.git.cdleonard@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org These options allow explicit control over the TCP_MD5SIG_FLAG_IFINDEX flag instead of always setting it based on binding to an interface. Do this by converting to getopt_long because nettest has too many single-character flags already and getopt_long is widely used in selftests. Signed-off-by: Leonard Crestez Reviewed-by: David Ahern --- tools/testing/selftests/net/nettest.c | 28 +++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/net/nettest.c b/tools/testing/selftests/net/nettest.c index bd6288302094..acf5cd153eaf 100644 --- a/tools/testing/selftests/net/nettest.c +++ b/tools/testing/selftests/net/nettest.c @@ -26,10 +26,11 @@ #include #include #include #include #include +#include #include #include #include @@ -99,10 +100,12 @@ struct sock_args { union { struct sockaddr_in v4; struct sockaddr_in6 v6; } md5_prefix; unsigned int prefix_len; + /* 0: default, -1: force off, +1: force on */ + int bind_key_ifindex; /* expected addresses and device index for connection */ const char *expected_dev; const char *expected_server_dev; int expected_ifindex; @@ -269,15 +272,18 @@ static int tcp_md5sig(int sd, void *addr, socklen_t alen, struct sock_args *args md5sig.tcpm_prefixlen = args->prefix_len; addr = &args->md5_prefix; } memcpy(&md5sig.tcpm_addr, addr, alen); - if (args->ifindex) { + if ((args->ifindex && args->bind_key_ifindex >= 0) || args->bind_key_ifindex >= 1) { opt = TCP_MD5SIG_EXT; md5sig.tcpm_flags |= TCP_MD5SIG_FLAG_IFINDEX; md5sig.tcpm_ifindex = args->ifindex; + log_msg("TCP_MD5SIG_FLAG_IFINDEX set tcpm_ifindex=%d\n", md5sig.tcpm_ifindex); + } else { + log_msg("TCP_MD5SIG_FLAG_IFINDEX off\n", md5sig.tcpm_ifindex); } rc = setsockopt(sd, IPPROTO_TCP, opt, &md5sig, sizeof(md5sig)); if (rc < 0) { /* ENOENT is harmless. Returned when a password is cleared */ @@ -1820,10 +1826,18 @@ static int ipc_parent(int cpid, int fd, struct sock_args *args) wait(&status); return client_status; } #define GETOPT_STR "sr:l:c:p:t:g:P:DRn:M:X:m:d:I:BN:O:SCi6xL:0:1:2:3:Fbq" +#define OPT_DO_BIND_KEY_IFINDEX 1001 +#define OPT_NO_BIND_KEY_IFINDEX 1002 + +static struct option long_opts[] = { + {"do-bind-key-ifindex", 0, 0, OPT_DO_BIND_KEY_IFINDEX}, + {"no-bind-key-ifindex", 0, 0, OPT_NO_BIND_KEY_IFINDEX}, + {0, 0, 0, 0} +}; static void print_usage(char *prog) { printf( "usage: %s OPTS\n" @@ -1856,10 +1870,14 @@ static void print_usage(char *prog) " -n num number of times to send message\n" "\n" " -M password use MD5 sum protection\n" " -X password MD5 password for client mode\n" " -m prefix/len prefix and length to use for MD5 key\n" + " --no-bind-key-ifindex: Force TCP_MD5SIG_FLAG_IFINDEX off\n" + " --do-bind-key-ifindex: Force TCP_MD5SIG_FLAG_IFINDEX on\n" + " (default: only if -I is passed)\n" + "\n" " -g grp multicast group (e.g., 239.1.1.1)\n" " -i interactive mode (default is echo and terminate)\n" "\n" " -0 addr Expected local address\n" " -1 addr Expected remote address\n" @@ -1891,11 +1909,11 @@ int main(int argc, char *argv[]) /* * process input args */ - while ((rc = getopt(argc, argv, GETOPT_STR)) != -1) { + while ((rc = getopt_long(argc, argv, GETOPT_STR, long_opts, NULL)) != -1) { switch (rc) { case 'B': both_mode = 1; break; case 's': @@ -1964,10 +1982,16 @@ int main(int argc, char *argv[]) msg = random_msg(atoi(optarg)); break; case 'M': args.password = optarg; break; + case OPT_DO_BIND_KEY_IFINDEX: + args.bind_key_ifindex = 1; + break; + case OPT_NO_BIND_KEY_IFINDEX: + args.bind_key_ifindex = -1; + break; case 'X': args.client_pw = optarg; break; case 'm': args.md5_prefix_str = optarg; From patchwork Wed Oct 13 06:50:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Leonard Crestez X-Patchwork-Id: 12554941 X-Patchwork-Delegate: kuba@kernel.org 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6A936C433FE for ; Wed, 13 Oct 2021 06:51:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4FFEE60F11 for ; Wed, 13 Oct 2021 06:51:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238251AbhJMGxN (ORCPT ); Wed, 13 Oct 2021 02:53:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56140 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238132AbhJMGxA (ORCPT ); Wed, 13 Oct 2021 02:53:00 -0400 Received: from mail-ed1-x52f.google.com (mail-ed1-x52f.google.com [IPv6:2a00:1450:4864:20::52f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6C9A9C061746; Tue, 12 Oct 2021 23:50:57 -0700 (PDT) Received: by mail-ed1-x52f.google.com with SMTP id d3so5850301edp.3; Tue, 12 Oct 2021 23:50:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=sYEkYt6iYNeaWn6bOb0NNKmx0bUVH+EyDgknjG8Vdgs=; b=NzXBqU13rCw8j2apKxQY9Nim2YLIxyaDipJlLu9zwTAvehJX/ngIG6JAvNaSQs2hh3 g2MoPFfu43wK4Jh48R8A8mtUDIFcCwh+C7kIMHwiU/JVzWHNSb8PepdNjiRwrf/YbvUp Me9DBjxHW78XZ7ezplTqldHVIJBKzOMZtMGG2EK6Bp6JVf5nh9OaoiWUfsNHTrKxokyW Ka5XxLGGHjEHwds2x+f4Q+bchB6mNFs5kLZiVzHgjc6JeNobYxDSeVPs7Pkz7CxCc+jX RnsXshYR9hIcdWPi1WbObWmRDGLPibcgCjSR38GSf/doC3Xed7H9jjrZocXBOzEuXDdI f9ig== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=sYEkYt6iYNeaWn6bOb0NNKmx0bUVH+EyDgknjG8Vdgs=; b=uhNpPa/iMLPB+PvJTakoVIKvOi6qjun466C0JseONebm41LqUJWYHbLnXxCSyo8aM+ 0jDyWRWrb27gVLnaQOim04cA2EediN9VqGSQJNX3cITaeTXxAWfG31EycX9uI0Kd9hbz 1nb+rCSKl81DORPLnmsPv1ESiq3qV1UiwAa/HbhTxzG5BdNptS9X4fgr4ba8elDG3PjN WNpC0jlNAZ0ZANq0kTJMt7R5Quc2s6WyB9knsgshBKk2E3PfdYAe1RJZYU1i95yfz+1a Z512MC7nnjbOHIrDaoOnxaUGn5OylUd62J2U0SqeTXyP9U2DYoOmnG24hJeRr74mYBNO KO/Q== X-Gm-Message-State: AOAM531+K7s4Rt23KheWH0njS4/L7rNsRPrDR5mLG/Jf7j31D4TjqNCL 04A6EKuApfuHW5Oo1ZMIZJc= X-Google-Smtp-Source: ABdhPJw2rNGppb9Gi5pZ6k5YuQdmOaDBkSi9jE/UxHZJSRAyHSAV+GHVlMoNAs1jdBu5UuygfsufGg== X-Received: by 2002:a05:6402:40d2:: with SMTP id z18mr6900904edb.362.1634107855825; Tue, 12 Oct 2021 23:50:55 -0700 (PDT) Received: from ponky.lan ([2a04:241e:501:3870:6346:a6a3:f7ea:349e]) by smtp.gmail.com with ESMTPSA id m15sm4568710edd.5.2021.10.12.23.50.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Oct 2021 23:50:55 -0700 (PDT) From: Leonard Crestez To: David Ahern , Eric Dumazet Cc: "David S. Miller" , Hideaki YOSHIFUJI , Jakub Kicinski , Martin KaFai Lau , Kuniyuki Iwashima , Yonghong Song , Alexander Duyck , Florian Westphal , netdev@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 4/4] selftests: net/fcnal: Test --{do,no}-bind-key-ifindex Date: Wed, 13 Oct 2021 09:50:38 +0300 Message-Id: X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Test that applications binding listening sockets to VRFs without specifying TCP_MD5SIG_FLAG_IFINDEX will work as expected. This would be broken if __tcp_md5_do_lookup always made a strict comparison on l3index. See this email: https://lore.kernel.org/netdev/209548b5-27d2-2059-f2e9-2148f5a0291b@gmail.com/ Applications using tcp_l3mdev_accept=1 and a single global socket (not bound to any interface) also should have a way to specify keys that are only for the default VRF, this is done by --do-bind-key-ifindex without otherwise binding to a device. Signed-off-by: Leonard Crestez Reviewed-by: David Ahern --- tools/testing/selftests/net/fcnal-test.sh | 60 +++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/tools/testing/selftests/net/fcnal-test.sh b/tools/testing/selftests/net/fcnal-test.sh index 13350cd5c8ac..28728e2f3eae 100755 --- a/tools/testing/selftests/net/fcnal-test.sh +++ b/tools/testing/selftests/net/fcnal-test.sh @@ -287,10 +287,16 @@ set_sysctl() echo "SYSCTL: $*" echo run_cmd sysctl -q -w $* } +# get sysctl values in NS-A +get_sysctl() +{ + ${NSA_CMD} sysctl -n $* +} + ################################################################################ # Setup for tests addr2str() { @@ -1001,10 +1007,64 @@ ipv4_tcp_md5() log_start run_cmd nettest -s -I ${NSA_DEV} -M ${MD5_PW} -m ${NS_NET} log_test $? 1 "MD5: VRF: Device must be a VRF - prefix" + test_ipv4_md5_vrf__vrf_server__no_bind_ifindex + test_ipv4_md5_vrf__global_server__bind_ifindex0 +} + +test_ipv4_md5_vrf__vrf_server__no_bind_ifindex() +{ + log_start + show_hint "Simulates applications using VRF without TCP_MD5SIG_FLAG_IFINDEX" + run_cmd nettest -s -I ${VRF} -M ${MD5_PW} -m ${NS_NET} --no-bind-key-ifindex & + sleep 1 + run_cmd_nsb nettest -r ${NSA_IP} -X ${MD5_PW} + log_test $? 0 "MD5: VRF: VRF-bound server, unbound key accepts connection" + + log_start + show_hint "Binding both the socket and the key is not required but it works" + run_cmd nettest -s -I ${VRF} -M ${MD5_PW} -m ${NS_NET} --do-bind-key-ifindex & + sleep 1 + run_cmd_nsb nettest -r ${NSA_IP} -X ${MD5_PW} + log_test $? 0 "MD5: VRF: VRF-bound server, bound key accepts connection" +} + +test_ipv4_md5_vrf__global_server__bind_ifindex0() +{ + # This particular test needs tcp_l3mdev_accept=1 for Global server to accept VRF connections + local old_tcp_l3mdev_accept + old_tcp_l3mdev_accept=$(get_sysctl net.ipv4.tcp_l3mdev_accept) + set_sysctl net.ipv4.tcp_l3mdev_accept=1 + + log_start + run_cmd nettest -s -M ${MD5_PW} -m ${NS_NET} --do-bind-key-ifindex & + sleep 1 + run_cmd_nsb nettest -r ${NSA_IP} -X ${MD5_PW} + log_test $? 2 "MD5: VRF: Global server, Key bound to ifindex=0 rejects VRF connection" + + log_start + run_cmd nettest -s -M ${MD5_PW} -m ${NS_NET} --do-bind-key-ifindex & + sleep 1 + run_cmd_nsc nettest -r ${NSA_IP} -X ${MD5_PW} + log_test $? 0 "MD5: VRF: Global server, key bound to ifindex=0 accepts non-VRF connection" + log_start + + run_cmd nettest -s -M ${MD5_PW} -m ${NS_NET} --no-bind-key-ifindex & + sleep 1 + run_cmd_nsb nettest -r ${NSA_IP} -X ${MD5_PW} + log_test $? 0 "MD5: VRF: Global server, key not bound to ifindex accepts VRF connection" + + log_start + run_cmd nettest -s -M ${MD5_PW} -m ${NS_NET} --no-bind-key-ifindex & + sleep 1 + run_cmd_nsc nettest -r ${NSA_IP} -X ${MD5_PW} + log_test $? 0 "MD5: VRF: Global server, key not bound to ifindex accepts non-VRF connection" + + # restore value + set_sysctl net.ipv4.tcp_l3mdev_accept="$old_tcp_l3mdev_accept" } ipv4_tcp_novrf() { local a