From patchwork Fri Oct 15 07:26:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Leonard Crestez X-Patchwork-Id: 12560249 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 592D6C433EF for ; Fri, 15 Oct 2021 07:26:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4305F61073 for ; Fri, 15 Oct 2021 07:26:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233389AbhJOH3C (ORCPT ); Fri, 15 Oct 2021 03:29:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42198 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235990AbhJOH27 (ORCPT ); Fri, 15 Oct 2021 03:28:59 -0400 Received: from mail-ed1-x52b.google.com (mail-ed1-x52b.google.com [IPv6:2a00:1450:4864:20::52b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 29B9BC061570; Fri, 15 Oct 2021 00:26:53 -0700 (PDT) Received: by mail-ed1-x52b.google.com with SMTP id 5so4520194edw.7; Fri, 15 Oct 2021 00:26: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=DhHz8eH8N2xPyxOD62X+So2Azq25vjiSqD7wX9RfBH8=; b=oyqr0HIZJDSM8ya0EVRJWZaEtfJf+S38v9KEsYykCHcoVWo3W2LQHmlEXUJ63d6PuD Onm8MfIe3l/0lnj5V+gpqAr2tkRKHgB3piXeHycCu2xsuhjC9ZHgW/X5NMNZr8Xcz7l2 7rF7AzyS2lLnD/oUlRFov6lJtOvLp5SpxyXLHwfZwnVMtw5C2MllfYw2nnayIFavAhru BhofPOKWQop/B9v7wqpkRRdClQdL45x9xdHBFcFNeTKw4qN/Cx4ZSgPSJ57jGry5tdbi ke9QKXLXEWxEBQMbVOr7nxiz5EdKis/v8t1zpnBud1Fz1dG96OZj0o9FwxI/ouGeInrm bHfg== 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=DhHz8eH8N2xPyxOD62X+So2Azq25vjiSqD7wX9RfBH8=; b=LwRTLxnBYordyjzxn/Moylei9bZ0YNSdg4xyo5VxPmS/FDxybKPBSsRzgs4sIrDj7j X1ym3hSYYGkIxogeBwlYjcS7HpVjDEVmQQImZKwALxYu0qcbF6GAzOpdOIBX3cvdDvqA f5Hxww9k0xPLJP2IjoW8mu3mDN+o6keKpTlETyzoFHkqFS1CAjtvsVSqglNOADv93qgt Ib4EPYbixLnd8fDm12rS8QsbV+oa6zGx2k7nxQzayKzkAQLp1mZGzYDr2dFsPD8+v0ls 7DU/ndjh/U6PcgsAEY2c0u+e8llhx7pTHS64u3tYd1aOqfRVUNSt/agQJzoVq4VlG4Y5 /tHA== X-Gm-Message-State: AOAM530gnQUpUho1GyejH9SUxuRcepNdGLwWIdo8an8L0s1QTJZ3z61t NmZFnsNk+dBr/AK/L1D0ao0= X-Google-Smtp-Source: ABdhPJxWCNBBlTt3rX6Gr+axUFVIsuJzKQtGCSUhuqAtmJ5TJjb3MDo+xl7FDvAsH4zPjfJHa6Y2rQ== X-Received: by 2002:a05:6402:1778:: with SMTP id da24mr15349517edb.318.1634282811780; Fri, 15 Oct 2021 00:26:51 -0700 (PDT) Received: from ponky.lan ([2a04:241e:501:3870:bac1:743:3859:80df]) by smtp.gmail.com with ESMTPSA id l25sm3873107edc.31.2021.10.15.00.26.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Oct 2021 00:26:51 -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 v3 1/4] tcp: md5: Fix overlap between vrf and non-vrf keys Date: Fri, 15 Oct 2021 10:26:04 +0300 Message-Id: <4b574659c7a3bcf2a2d3821acf1cf14c1cea3c61.1634282515.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 Fri Oct 15 07:26:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Leonard Crestez X-Patchwork-Id: 12560251 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 2FECCC433FE for ; Fri, 15 Oct 2021 07:27:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0914161040 for ; Fri, 15 Oct 2021 07:27:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236067AbhJOH3F (ORCPT ); Fri, 15 Oct 2021 03:29:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42202 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236041AbhJOH3A (ORCPT ); Fri, 15 Oct 2021 03:29:00 -0400 Received: from mail-ed1-x534.google.com (mail-ed1-x534.google.com [IPv6:2a00:1450:4864:20::534]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C276BC061570; Fri, 15 Oct 2021 00:26:54 -0700 (PDT) Received: by mail-ed1-x534.google.com with SMTP id z20so34568707edc.13; Fri, 15 Oct 2021 00:26: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=3b1OMdSUKflX4oZao36kMMzRJWDmrPvgJ1eHyV20vsA=; b=gfmyn8G5Mjp8DrSTFuswPKUVCuhWwTc/FtmzJpE9ymkgTWWcPazUeBfIjFRbg2itnm TKkyODGWNjIMn8eu0PbbouCqnMQKMqP3Iv8iqd+IYOcGiausgk348gZmgOt8vMxdthlP 56TRGzZOc2a0Cb0EMp2Vitt3cvqNg3tX8t64buRYDX+qT4N7EPK0NT7MaEg3dILnTMW2 atO6I05N8opedZr3NPbTiM74+DJtpTjs4Yy4EtfEbdPfjWIHldqmmYnPsXruw0Wt14vZ ctVthN4e7oCyyEnXyg+NHAdWB1zLBlYMRW/bwk9f3ZfgGBC4mmwEBSw0Myc6pOctBeZB IWxA== 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=3b1OMdSUKflX4oZao36kMMzRJWDmrPvgJ1eHyV20vsA=; b=W/LolORTrIU1L1Oz0RPk2L1ZLphdNgdcGBheWBgGImBx5R24VdbK8PPTK4YqxNh4Md hc3B0GhWsJ6u4PNLnjGd6hI5Zlcxz/BnTyaE5LWg3VsQzH7uCOU3+IhmUZhj4iV8ri0Q FPTL0LGbXez74YgfDD5vUMijvPOfuXrOGKxsRE9PoxjpciPshfDar5zmSr7EkHP3P4OQ 4M6CTrTV4WfhyvbFvrJyZ7rKQkt/89CZmjuSS8GfzPswVvOmCMPM9RzS/BSYC5H8GOfW veI9CVpUp0dz0yTh1Lape8gdlJC64bg2gXj2LvXj1t7U3R4dTRzSDXyiSrDAbOdsYToH UAJQ== X-Gm-Message-State: AOAM5300mlk25V5VfvcjjrucLlAA+hvDE1BmACiMM/KrcO2PhYP82vqn Rlc28XRSNzL62s27TLNZiDE= X-Google-Smtp-Source: ABdhPJx+DOqZ/iphPFdt/Y6z5ZlD01YP/CAEjcD29po5JpeWX4oHFenVljwH6k+PALpsD5F/j7aYOg== X-Received: by 2002:a17:906:884:: with SMTP id n4mr4571539eje.54.1634282813351; Fri, 15 Oct 2021 00:26:53 -0700 (PDT) Received: from ponky.lan ([2a04:241e:501:3870:bac1:743:3859:80df]) by smtp.gmail.com with ESMTPSA id l25sm3873107edc.31.2021.10.15.00.26.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Oct 2021 00:26: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 v3 2/4] tcp: md5: Allow MD5SIG_FLAG_IFINDEX with ifindex=0 Date: Fri, 15 Oct 2021 10:26:05 +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 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_FLAG_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 Fri Oct 15 07:26:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Leonard Crestez X-Patchwork-Id: 12560253 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 6E595C433EF for ; Fri, 15 Oct 2021 07:27:08 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 58DB061073 for ; Fri, 15 Oct 2021 07:27:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236116AbhJOH3M (ORCPT ); Fri, 15 Oct 2021 03:29:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42212 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236045AbhJOH3C (ORCPT ); Fri, 15 Oct 2021 03:29:02 -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 01B6AC061753; Fri, 15 Oct 2021 00:26:56 -0700 (PDT) Received: by mail-ed1-x52e.google.com with SMTP id d9so34116304edh.5; Fri, 15 Oct 2021 00:26:55 -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=cbn2O/IuIC1N4BTjq1m4QTF3DvYmfJ/PJDBU5ZUFZwU=; b=ZH8M5/P68PDyO66dkz8xwMfv14P6PVYtKSBcFYRUdCIhnn6vURAFhh7PvAr7KyzGF9 xxuGInmz3qWMpcFiP4EoLxBEnH8EoRJS2y8NULgmQkO5y17LnpwBqt6bnG2PysV7A8dR fhYrSS9n7+azVjjZb9ztyCnQByYRK+/hvS84CVfsS61ov/Z0Rdno/TdMkCfMr2veicrI F56vAEhmlKUYOv08+Ffm6FZkF74HxDEu8cmJdcyKRC+zDcXmvG8BmWWgf1FGV72JlX1L G6uFtLhrY+pY9O7mScRW6x12zQSviRZFMRlAldhDRdn+bvd0A+uBAeK5VIXkGZkWY+Le OT9g== 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=cbn2O/IuIC1N4BTjq1m4QTF3DvYmfJ/PJDBU5ZUFZwU=; b=5JSXOl7971eJUcgC5HfpSoZUxW4+1liA8iDDBecjZDQyssQ+jrPbi4H/gV1zxWoIK0 L9vZuDZ3aJd+VmMSuR3AuIZk5OshFPgzp8v4QGxXwgBYLHHY6rGgT6lOuq8u1WaPRsoU UFo4uC/irVi/H8Nx6yGkYzZX2/hFOzupqzuZYRPz4/YLbtqOcsDfxL6X6W4V8P1ciSnA ORe1wKBSaYTftB+9G0c58guLA5atLOE2MLqYDq1vr+/INpRRe3HLVS5cen3Wizt7bitj wUTuQBjMSuwxlYa7Gap+P3C1QhuU4FbgZGmJ6Iyy5+6b7EU+0apIo30dlK7rdrUWPJ7X scuw== X-Gm-Message-State: AOAM530+QlUmi9VaGxc2MGFpoRiWbGoBBPM81x06HJuKuh6CTNMos0Mv PMgxUsY9oS6Xp2NItF23VI0= X-Google-Smtp-Source: ABdhPJz061JKy2uInEKwfVUf/BIfvyMXP0rM8AelWiqtieULl0lpFb/Os8TxHXg7s9/Q7SOVoZZpmg== X-Received: by 2002:aa7:cb41:: with SMTP id w1mr15709697edt.327.1634282814640; Fri, 15 Oct 2021 00:26:54 -0700 (PDT) Received: from ponky.lan ([2a04:241e:501:3870:bac1:743:3859:80df]) by smtp.gmail.com with ESMTPSA id l25sm3873107edc.31.2021.10.15.00.26.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Oct 2021 00:26: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 v3 3/4] selftests: nettest: Add --{force,no}-bind-key-ifindex Date: Fri, 15 Oct 2021 10:26:06 +0300 Message-Id: <111eb35784dbc9d509ed52d833209f3655008d61.1634282515.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..b599003eb5ba 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_FORCE_BIND_KEY_IFINDEX 1001 +#define OPT_NO_BIND_KEY_IFINDEX 1002 + +static struct option long_opts[] = { + {"force-bind-key-ifindex", 0, 0, OPT_FORCE_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" + " --force-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_FORCE_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 Fri Oct 15 07:26:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Leonard Crestez X-Patchwork-Id: 12560255 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 090F1C433F5 for ; Fri, 15 Oct 2021 07:27:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E01A161041 for ; Fri, 15 Oct 2021 07:27:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236126AbhJOH3N (ORCPT ); Fri, 15 Oct 2021 03:29:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42220 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236050AbhJOH3D (ORCPT ); Fri, 15 Oct 2021 03:29:03 -0400 Received: from mail-ed1-x532.google.com (mail-ed1-x532.google.com [IPv6:2a00:1450:4864:20::532]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4E2B7C061760; Fri, 15 Oct 2021 00:26:57 -0700 (PDT) Received: by mail-ed1-x532.google.com with SMTP id y30so17315035edi.0; Fri, 15 Oct 2021 00:26: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=AX2BpCwAHsJ9vAVMGMg+034+7Y/IY2VhzAS++Px6BtQ=; b=Gl6loNmsS/lpioR+G0SjkAxS4RdAdyW3fzUgX3JY7yXFMfJ6EnQsDW4M+vSGk/F/V2 JvHqTR4LP/hzaWfq8ImEKbWJJAG/EpIkZoOthUG+eIq6B6jXWaomiZsb2hII7oWEx9yu Au6kLkTAvNpPhnFmL93z+F83nbQpWq3q6m6HM4en+xW3wr+TFnSvbFaVh+sbgjIO9ZUS vHboQ6fBEp58dxiQEKuVykzUypOkcgtZtT9K4cz9mzPl3E0Dk08eSI1OLrSIL2Il7y62 SzZc0rAxdOL0+pzsnPVePqXnQQKBJN9zbtXSWxF/Ozmc2DPvf/xnjf6QTtMYGlDj4rUt EZDg== 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=AX2BpCwAHsJ9vAVMGMg+034+7Y/IY2VhzAS++Px6BtQ=; b=FAr6gwSW8iUN6+lgT0AhaVXFpvX0r6dTaVI86d8QMod6DXW94QYDA1QsB9iBblDobo XZViASqYgUOgMnNiQoK7CYoin94Yca/8VljJejNmMmFGsxu7E49ZOJb6dg1fWv/gw8Z4 +X/GM8BTJibBU50fTm8Gwv0HcCjQgyacnsbXsXT7NGWo5UbwahgRy8glOiDhvtTS4rvu 4EDwWkjiBpW7Vr1ybAXdSMBtytWv/LILUCay5LX5aCRcUzk6h5yoMZs1snVjmCWvwKDz 0QydoSC9fr/R4d9aokn8VaO2j06Yh7fqWyJqqJCqlOQbyJ+Thu6S6BIAtYDlkxmvvuNc eEhg== X-Gm-Message-State: AOAM532JNyQFEmRrkhhUZ4Z6o55wMZ+6Tol1Py5VXA1YzYBAhkJnJFHg svs8j1fzpNwZJcMZBokR7pg= X-Google-Smtp-Source: ABdhPJwh4HvHQcedjSGAlTEY+pXeFSAT3UYiM/HjyPORXRzWpcbgwIJ8nm8uj/2+P618AoXTaGjfpw== X-Received: by 2002:aa7:ca0d:: with SMTP id y13mr15325489eds.335.1634282815944; Fri, 15 Oct 2021 00:26:55 -0700 (PDT) Received: from ponky.lan ([2a04:241e:501:3870:bac1:743:3859:80df]) by smtp.gmail.com with ESMTPSA id l25sm3873107edc.31.2021.10.15.00.26.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Oct 2021 00:26: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 v3 4/4] selftests: net/fcnal: Test --{force,no}-bind-key-ifindex Date: Fri, 15 Oct 2021 10:26:07 +0300 Message-Id: <9b00cba5116604773554db98405691076c66b71a.1634282515.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 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 --force-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..8e67a252b672 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} --force-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} --force-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} --force-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