From patchwork Wed Dec 20 17:06:01 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Colitti X-Patchwork-Id: 851553 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="JDnBH3t0"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3z21QZ5wnFz9s83 for ; Thu, 21 Dec 2017 04:06:46 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755503AbdLTRGd (ORCPT ); Wed, 20 Dec 2017 12:06:33 -0500 Received: from mail-pf0-f195.google.com ([209.85.192.195]:39211 "EHLO mail-pf0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755292AbdLTRG2 (ORCPT ); Wed, 20 Dec 2017 12:06:28 -0500 Received: by mail-pf0-f195.google.com with SMTP id l24so12809636pfj.6 for ; Wed, 20 Dec 2017 09:06:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=pYpFkwn3PYDZLJ9r3bZjVIZ6dJdzqEXaML5njxMop4M=; b=JDnBH3t0GjQJIXo+7C6ctf7YOPlwC976XRVBXRI5mstMx8NcKA2vYiMuOAIYVc6pyx rKt+LCOMsM9L3q1fAGShpfkwXEH1TYYG0PPX68D4ZAKjXqtZ59HOGO1dwlEyqXN0uHcS VX8rd9dCuGpuFoCE2H4J0uJFUk7NnPoCuvX1vuukic15YYbSSD5QOD/zox+zpOnZDLPK j2zFcuapIrEMoSY1VtZdC1j46aY8IyqrsjWN5YqcXR65Q9me+l9+fQ31aRgRnwawcd+y TPBCveAqhxP168oOW/ZLff29FrQGZ1R8z5GkVtPoQRL+M8Cq8iKQGuvnE601FNZl2pY/ ieIQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=pYpFkwn3PYDZLJ9r3bZjVIZ6dJdzqEXaML5njxMop4M=; b=U5qUN+l4bJ3OYaU8tDWj4OcEJQW4jWbTiZaaulkCT/EMOhfX1J524QzHwSgGByO/Pe ncK6mlubThqv5/jEnYRwTio++Cjzz9MLmK5iyNmrlL8kzmZ1opDUFezj7sQ1hLK5nsV0 Jnf5PAolcKv+B5mHIWQAajnaMNvYF02IPm7qD2riMFrnx0H1Ro78WDQV5Bk8znWJ+8Dz PbfoDeN4QcifHAujUDXC5RFUziZvM84uOvzlL9Ey9NNZh4DIWzQVN6CafiEIepCcllNS VZRGbxk3kqwNy5suKdbCPsEfkF8kpMfvK06Dkq40TRrKOVry0AkZpL5aFRXtdoKZSNQe FTZg== X-Gm-Message-State: AKGB3mLU8hfNkMDDaFYdKNq2U1CdyYP96KQK1pvovFKfv77Q+UDzVXjA jHcTUNdx/oL4KblITnlgxJW5MSYQcc0= X-Google-Smtp-Source: ACJfBouhbtfNv/cjefGPG+UonA6QzKQOGdkk1XPkanMMKn1JW/oC8C1tV7xRe6KqjJ7c3LnvpmBd9A== X-Received: by 10.98.147.28 with SMTP id b28mr7563850pfe.5.1513789587037; Wed, 20 Dec 2017 09:06:27 -0800 (PST) Received: from lorenzo.tok.corp.google.com ([100.103.3.232]) by smtp.gmail.com with ESMTPSA id t62sm29103067pgt.23.2017.12.20.09.06.24 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 20 Dec 2017 09:06:26 -0800 (PST) From: Lorenzo Colitti To: netdev@vger.kernel.org Cc: steffen.klassert@secunet.com, subashab@codeaurora.org, nharold@google.com, davem@davemloft.net, Lorenzo Colitti Subject: [PATCH ipsec-next 1/7] net: xfrm: Don't check for TUNNEL_KEY when hashing VTI tunnels. Date: Thu, 21 Dec 2017 02:06:01 +0900 Message-Id: <20171220170607.41516-2-lorenzo@google.com> X-Mailer: git-send-email 2.15.1.620.gb9897f4670-goog In-Reply-To: <20171220170607.41516-1-lorenzo@google.com> References: <20171220170607.41516-1-lorenzo@google.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Currently, ip_bucket sets the lookup i_key to 0 if the tunnel's i_flags have VTI_ISVTI flag set but not TUNNEL_KEY. However, it can can never happen that TUNNEL_KEY is set if VTI_ISVTI is also set (see below). Therefore, just drop the check for TUNNEL_KEY and only set i_key to 0 on VTI_ISVTI. This will allow the VTI code to set TUNNEL_KEY on certain tunnels in a future change. None of the callers of ip_bucket pass in TUNNEL_KEY | VTI_ISVTI. The call graph is as follows: - ip_tunnel_add - ip_tunnel_create - ip_tunnel_ioctl - ipgre_tunnel_ioctl: can set TUNNEL_KEY but not VTI_ISVTI - ipip_tunnel_ioctl: hardcodes i_flags to 0 - vti_tunnel_ioctl: hardcodes i_flags to VTI_ISVTI - ip_tunnel_update: doesn't touch i_flags - ip_tunnel_init_net: memsets flags to 0 - ip_tunnel_newlink - ipgre_newlink - ipgre_netlink_parms: can set TUNNEL_KEY but not VTI_ISVTI - vti_newlink: hardcodes i_flags to VTI_ISVTI - ip_tunnel_changelink: doesn't set flags - ip_tunnel_find - ip_tunnel_ioctl (see above) - ip_tunnel_newlink (see above) - ip_tunnel_changelink (see above) VTI_ISVTI has the same value as TUNNEL_DONT_FRAGMENT, but that is never set into tunnel parameters. Signed-off-by: Lorenzo Colitti --- net/ipv4/ip_tunnel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index 5ddb1cb52b..539c8f22c4 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c @@ -198,7 +198,7 @@ static struct hlist_head *ip_bucket(struct ip_tunnel_net *itn, else remote = 0; - if (!(parms->i_flags & TUNNEL_KEY) && (parms->i_flags & VTI_ISVTI)) + if (parms->i_flags & VTI_ISVTI) i_key = 0; h = ip_tunnel_hash(i_key, remote); From patchwork Wed Dec 20 17:06:02 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Colitti X-Patchwork-Id: 851558 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="h8U7v7bD"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3z21R534BGz9s83 for ; Thu, 21 Dec 2017 04:07:13 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755615AbdLTRGh (ORCPT ); Wed, 20 Dec 2017 12:06:37 -0500 Received: from mail-pg0-f68.google.com ([74.125.83.68]:37573 "EHLO mail-pg0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753452AbdLTRGa (ORCPT ); Wed, 20 Dec 2017 12:06:30 -0500 Received: by mail-pg0-f68.google.com with SMTP id o13so1410447pgp.4 for ; Wed, 20 Dec 2017 09:06:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=E9/kNJjVaBws9ibGb8hCsNgLrtLjyDytdiO//N0da6E=; b=h8U7v7bDFSRQlb0uPbVVQzQ1sKMeYlfJw0+08zJkZPITJkugQHLSBCNy93pMU2Q/6i xiG38MQ2IxwDfOkToR8xSY37YIJ1gbV78mfq9OSzKR6vvjbBLVKOnJFyTL+MZ1hkxXgg hiP52hrNBats6bepa5WrbLe2iJ2Y6oaajFBP0LGJYYBD5Jh6y+y7BLNNmNNUILWdBD9v WYjbTb5uad0edzeEIRaWV91jQtJz66Eao4dDpxLgOBrrRq3UVcxT5UuKtCD1ZpEZ4MVy GoLAGRaCaXNaD1iZ50JfxEStYsmquF2osXmgEjjChze0CGaeHveT9TuN9KQbtxW0wGdT 2ftg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=E9/kNJjVaBws9ibGb8hCsNgLrtLjyDytdiO//N0da6E=; b=Lu2caMWZuB31AybKXZHTRMW+bMBZF1vEHLBuU4x/UOK1Y+w8yxXJF3T9+5nD25LFmZ AiQLvQeNFxOHMLLpPBpubzU4i3c+UUFJYZ3RqFDEaFDAJLRgNPbfGHUOtqrne89udffR uJhaTyM+41ekt+Gd9BhMA4BtYGxfnTqNPIKhLy53wXW1aulVGm4dOFnrfuub1m3dj1ON 4DwZ/AOHsM1wNykuRuVr5r5yQcbx5q/hFxj44CInr1+R5bNCbrRB8k+pAbTXXjQP/bRk NKvEkkrFE9wUZAtXVmYes9iG35f1xkOhWI5/ZxMHq7iSjQttUXAoe/Aief0uDWqBPNxR zVHg== X-Gm-Message-State: AKGB3mI4fEM+Zs1XzplSRtHfUET7/KhTHgqmUmZrBs1dp44K+angv6Ff +rDTUKQXpC0+Bt7oE/mbWdOl2lYQVjw= X-Google-Smtp-Source: ACJfBouJUOOOV8MRZaB/hWt5ErUskOLMs2z3+/6AzactL9BzLxX0XFUmGrZ0AVoUGNBvjFKAhAjD0A== X-Received: by 10.99.124.16 with SMTP id x16mr7035756pgc.124.1513789589356; Wed, 20 Dec 2017 09:06:29 -0800 (PST) Received: from lorenzo.tok.corp.google.com ([100.103.3.232]) by smtp.gmail.com with ESMTPSA id t62sm29103067pgt.23.2017.12.20.09.06.27 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 20 Dec 2017 09:06:28 -0800 (PST) From: Lorenzo Colitti To: netdev@vger.kernel.org Cc: steffen.klassert@secunet.com, subashab@codeaurora.org, nharold@google.com, davem@davemloft.net, Lorenzo Colitti Subject: [PATCH ipsec-next 2/7] net: ipv4: Add new flags to tunnel lookup. Date: Thu, 21 Dec 2017 02:06:02 +0900 Message-Id: <20171220170607.41516-3-lorenzo@google.com> X-Mailer: git-send-email 2.15.1.620.gb9897f4670-goog In-Reply-To: <20171220170607.41516-1-lorenzo@google.com> References: <20171220170607.41516-1-lorenzo@google.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This patch adds support for two new flags to ip_tunnel_lookup. - TUNNEL_LOOKUP_NO_KEY: ignores the tunnel's i_key when determining which hash bucket to look up the tunnel in. This is useful for tunnels such as VTI, which have i_keys, but are always hashed into bucket 0. - TUNNEL_LOOKUP_OKEY: finds the tunnel by o_key instead of i_key. Together, these flags allow processing ICMP errors correctly on keyed tunnels where i_key != o_key. If such tunnels receive an ICMP error, the only information available in the packet is the o_key, so we must be able to find a tunnel by o_key alone. For that to work, the tunnel hash must not depend on the i_key, because if it does, we won't be able to find it by o_key alone. TUNNEL_LOOKUP_NO_KEY is very similar to TUNNEL_NO_KEY so it might be possible just to use TUNNEL_NO_KEY instead. However, it might be confusing to see code simultaneously pass in both TUNNEL_NO_KEY and TUNNEL_KEY. These flags are numbered separately from tunnel flags because they are not tunnel properties but properties of tunnel lookups. (Also, the tunnel flags are 16 bits and all but one is unused.) The flags are passed into ip_lookup by adding a new parameter. This could also be done by expanding the existing flags parameter from __be16 to __be32 and ensuring that the new flags are all above the 16-bit boundary. Signed-off-by: Lorenzo Colitti --- include/net/ip_tunnels.h | 6 +++++- net/ipv4/ip_gre.c | 6 +++--- net/ipv4/ip_tunnel.c | 22 +++++++++++++--------- net/ipv4/ip_vti.c | 4 ++-- net/ipv4/ipip.c | 6 +++--- 5 files changed, 26 insertions(+), 18 deletions(-) diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h index 1f16773cfd..19d97b993a 100644 --- a/include/net/ip_tunnels.h +++ b/include/net/ip_tunnels.h @@ -163,6 +163,10 @@ struct ip_tunnel { #define TUNNEL_OPTIONS_PRESENT \ (TUNNEL_GENEVE_OPT | TUNNEL_VXLAN_OPT | TUNNEL_ERSPAN_OPT) +/* Flags for ip_tunnel_lookup. */ +#define TUNNEL_LOOKUP_NO_KEY 0x01 +#define TUNNEL_LOOKUP_OKEY 0x02 + struct tnl_ptk_info { __be16 flags; __be16 proto; @@ -276,7 +280,7 @@ int ip_tunnel_change_mtu(struct net_device *dev, int new_mtu); void ip_tunnel_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *tot); struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn, - int link, __be16 flags, + int link, __be16 flags, u8 lookup_flags, __be32 remote, __be32 local, __be32 key); diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index fd4d6e96da..f16a46cb19 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -182,7 +182,7 @@ static void ipgre_err(struct sk_buff *skb, u32 info, itn = net_generic(net, ipgre_net_id); iph = (const struct iphdr *)(icmp_hdr(skb) + 1); - t = ip_tunnel_lookup(itn, skb->dev->ifindex, tpi->flags, + t = ip_tunnel_lookup(itn, skb->dev->ifindex, tpi->flags, 0, iph->daddr, iph->saddr, tpi->key); if (!t) @@ -280,7 +280,7 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi, */ tpi->key = cpu_to_be32(ntohs(ershdr->session_id) & ID_MASK); tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, - tpi->flags | TUNNEL_KEY, + tpi->flags | TUNNEL_KEY, 0, iph->saddr, iph->daddr, tpi->key); if (tunnel) { @@ -356,7 +356,7 @@ static int __ipgre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *tpi, struct ip_tunnel *tunnel; iph = ip_hdr(skb); - tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, tpi->flags, + tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, tpi->flags, 0, iph->saddr, iph->daddr, tpi->key); if (tunnel) { diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index 539c8f22c4..f45968bb81 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c @@ -70,11 +70,13 @@ static unsigned int ip_tunnel_hash(__be32 key, __be32 remote) } static bool ip_tunnel_key_match(const struct ip_tunnel_parm *p, - __be16 flags, __be32 key) + __be32 flags, u8 lookup_flags, __be32 key) { + __be32 tunnel_key = (lookup_flags & TUNNEL_LOOKUP_OKEY) ? p->o_key : + p->i_key; if (p->i_flags & TUNNEL_KEY) { if (flags & TUNNEL_KEY) - return key == p->i_key; + return key == tunnel_key; else /* key expected, none present */ return false; @@ -94,15 +96,17 @@ static bool ip_tunnel_key_match(const struct ip_tunnel_parm *p, Given src, dst and key, find appropriate for input tunnel. */ struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn, - int link, __be16 flags, + int link, __be16 flags, u8 lookup_flags, __be32 remote, __be32 local, __be32 key) { unsigned int hash; struct ip_tunnel *t, *cand = NULL; struct hlist_head *head; + __be32 hash_key; - hash = ip_tunnel_hash(key, remote); + hash_key = (lookup_flags & TUNNEL_LOOKUP_NO_KEY) ? 0 : key; + hash = ip_tunnel_hash(hash_key, remote); head = &itn->tunnels[hash]; hlist_for_each_entry_rcu(t, head, hash_node) { @@ -111,7 +115,7 @@ struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn, !(t->dev->flags & IFF_UP)) continue; - if (!ip_tunnel_key_match(&t->parms, flags, key)) + if (!ip_tunnel_key_match(&t->parms, flags, lookup_flags, key)) continue; if (t->parms.link == link) @@ -126,7 +130,7 @@ struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn, !(t->dev->flags & IFF_UP)) continue; - if (!ip_tunnel_key_match(&t->parms, flags, key)) + if (!ip_tunnel_key_match(&t->parms, flags, lookup_flags, key)) continue; if (t->parms.link == link) @@ -135,7 +139,7 @@ struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn, cand = t; } - hash = ip_tunnel_hash(key, 0); + hash = ip_tunnel_hash(hash_key, 0); head = &itn->tunnels[hash]; hlist_for_each_entry_rcu(t, head, hash_node) { @@ -146,7 +150,7 @@ struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn, if (!(t->dev->flags & IFF_UP)) continue; - if (!ip_tunnel_key_match(&t->parms, flags, key)) + if (!ip_tunnel_key_match(&t->parms, flags, lookup_flags, key)) continue; if (t->parms.link == link) @@ -238,7 +242,7 @@ static struct ip_tunnel *ip_tunnel_find(struct ip_tunnel_net *itn, remote == t->parms.iph.daddr && link == t->parms.link && type == t->dev->type && - ip_tunnel_key_match(&t->parms, flags, key)) + ip_tunnel_key_match(&t->parms, flags, 0, key)) break; } return t; diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c index 949f432a5f..804cee8126 100644 --- a/net/ipv4/ip_vti.c +++ b/net/ipv4/ip_vti.c @@ -57,7 +57,7 @@ static int vti_input(struct sk_buff *skb, int nexthdr, __be32 spi, struct net *net = dev_net(skb->dev); struct ip_tunnel_net *itn = net_generic(net, vti_net_id); - tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_NO_KEY, + tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_NO_KEY, 0, iph->saddr, iph->daddr, 0); if (tunnel) { if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) @@ -278,7 +278,7 @@ static int vti4_err(struct sk_buff *skb, u32 info) int protocol = iph->protocol; struct ip_tunnel_net *itn = net_generic(net, vti_net_id); - tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_NO_KEY, + tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_NO_KEY, 0, iph->daddr, iph->saddr, 0); if (!tunnel) return -1; diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index c891235b49..81f94ffb92 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c @@ -167,7 +167,7 @@ static int ipip_err(struct sk_buff *skb, u32 info) goto out; } - t = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_NO_KEY, + t = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_NO_KEY, 0, iph->daddr, iph->saddr, 0); if (!t) { err = -ENOENT; @@ -224,8 +224,8 @@ static int ipip_tunnel_rcv(struct sk_buff *skb, u8 ipproto) const struct iphdr *iph; iph = ip_hdr(skb); - tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_NO_KEY, - iph->saddr, iph->daddr, 0); + tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_NO_KEY, 0, + iph->saddr, iph->daddr, 0); if (tunnel) { const struct tnl_ptk_info *tpi; From patchwork Wed Dec 20 17:06:03 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Colitti X-Patchwork-Id: 851554 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="Awp6uwn/"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3z21Qc74kZz9sBd for ; Thu, 21 Dec 2017 04:06:48 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755668AbdLTRGj (ORCPT ); Wed, 20 Dec 2017 12:06:39 -0500 Received: from mail-pg0-f67.google.com ([74.125.83.67]:38041 "EHLO mail-pg0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755453AbdLTRGd (ORCPT ); Wed, 20 Dec 2017 12:06:33 -0500 Received: by mail-pg0-f67.google.com with SMTP id f12so12150291pgo.5 for ; Wed, 20 Dec 2017 09:06:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=8SDjKF/74/cSVQULw+jqdy/InHXizM2CBMKHEvIrPDc=; b=Awp6uwn/YwnRv0mN0iQ6qnRlcoAORBRX6wuT7dhEJlMn7dwlrJ1OtdPxMmcwzQfqGv AfwS9+tLxtuLrz6HuPMOSeAUkFgvwu/obMGn5ccuiuKwEUUASuDo1XFxahiRc/4pQMyp jTP/kpnBDCULhrsSic9PHBpG6D4+sxmCHbTVCJyPqcom3RQosqwfnn2Arms7z6HgO/XT YYkydWwHMHufS6sKo9BERutfl0voj4YjuaQitjD4JIDpeZNpuBQgH1CXGNGgwYzNu2dT zLlZEUrXMi5MtD59Tg1sPDLUxYkel8YADlYjzjyaLvKvkKjQncUkMmS7y23HtGNkO24p QGtg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=8SDjKF/74/cSVQULw+jqdy/InHXizM2CBMKHEvIrPDc=; b=UU1PC7Z4mmw3zW6qklVIQZFvl7GxcFmY8q9/TTIXm9vJGNM7zcTk4r8DBHv+gJ3z2S Aa8O7jO986YFVrY77R6Uuss25fO9KOSB6g8JVnQHCx5b9BdNPs1fppPG0Xz/7WQCjGPN hKT6qjpUeiQe5XK3Ye1njTlUlSq8U7rqu2ZRfIhECA3uoqp1316WioMWk5QPvXVVheKt A8dTBkl+MAyJVL7yJ+6vq4pHlRX7TBPYFiIIIwuqSM7cTp59q+mg+jnHktgR/UMnU2i3 Z9UTbFlYnNQx2kE3boOnuJa/DFTzE44FLmn9NbHW+xM2do6Tsn9riFucf44RCSb7SJbl svDA== X-Gm-Message-State: AKGB3mJVNg3N2CBsww5Y5pqejGxCf6ptcUWk9CPfAhKVkMgjIQR/LBMD +gU/de3v6fEG7ij/M2bDBLs2dcCM5EM= X-Google-Smtp-Source: ACJfBouARerJTbqG0pgRYXQV2G++9GQjcx18AdijrV1IVU+01pwg4k+R2v+e1OOOMBtww8ekzSPNug== X-Received: by 10.99.111.8 with SMTP id k8mr6679366pgc.74.1513789591870; Wed, 20 Dec 2017 09:06:31 -0800 (PST) Received: from lorenzo.tok.corp.google.com ([100.103.3.232]) by smtp.gmail.com with ESMTPSA id t62sm29103067pgt.23.2017.12.20.09.06.29 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 20 Dec 2017 09:06:30 -0800 (PST) From: Lorenzo Colitti To: netdev@vger.kernel.org Cc: steffen.klassert@secunet.com, subashab@codeaurora.org, nharold@google.com, davem@davemloft.net, Lorenzo Colitti Subject: [PATCH ipsec-next 3/7] net: xfrm: Add an xfrm lookup that ignores the mark. Date: Thu, 21 Dec 2017 02:06:03 +0900 Message-Id: <20171220170607.41516-4-lorenzo@google.com> X-Mailer: git-send-email 2.15.1.620.gb9897f4670-goog In-Reply-To: <20171220170607.41516-1-lorenzo@google.com> References: <20171220170607.41516-1-lorenzo@google.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The xfrm inbound and ICMP error paths can match inbound XFRM states that have a mark, but only if the skb mark is already correctly set to match the state mark. This typically requires iptables rules (potentially even per SA iptables rules), which impose configuration complexity. In some cases, it may be useful to match such an SA anyway. An example is when processing an ICMP error to an ESP packet that we previously sent. In this case, the only information available to match the SA are the IP addresses and the outbound SPI. Therefore, if the output SA has a mark, the lookup will fail and the ICMP packet cannot be processed unless the packet is somehow already marked. Signed-off-by: Lorenzo Colitti --- include/net/xfrm.h | 4 ++++ net/xfrm/xfrm_state.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 1ec0c47606..9d3b7c0ac6 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -1550,6 +1550,10 @@ struct xfrm_state *xfrm_state_lookup_byaddr(struct net *net, u32 mark, const xfrm_address_t *saddr, u8 proto, unsigned short family); +struct xfrm_state *xfrm_state_lookup_loose(struct net *net, u32 mark, + const xfrm_address_t *daddr, + __be32 spi, u8 proto, + unsigned short family); #ifdef CONFIG_XFRM_SUB_POLICY int xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n, unsigned short family, struct net *net); diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 1b7856be3e..cff151c714 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -839,6 +839,39 @@ static struct xfrm_state *__xfrm_state_lookup(struct net *net, u32 mark, return NULL; } +struct xfrm_state *xfrm_state_lookup_loose(struct net *net, u32 mark, + const xfrm_address_t *daddr, + __be32 spi, u8 proto, + unsigned short family) +{ + unsigned int h = xfrm_spi_hash(net, daddr, spi, proto, family); + struct xfrm_state *x, *cand = NULL; + + rcu_read_lock(); + hlist_for_each_entry_rcu(x, net->xfrm.state_byspi + h, byspi) { + if (x->props.family != family || + x->id.spi != spi || + x->id.proto != proto || + !xfrm_addr_equal(&x->id.daddr, daddr, family)) + continue; + + if (((mark & x->mark.m) == x->mark.v) && + xfrm_state_hold_rcu(x)) { + if (cand) + xfrm_state_put(cand); + rcu_read_unlock(); + return x; + } + + if (!cand && xfrm_state_hold_rcu(x)) + cand = x; + } + + rcu_read_unlock(); + return cand; +} +EXPORT_SYMBOL(xfrm_state_lookup_loose); + static struct xfrm_state *__xfrm_state_lookup_byaddr(struct net *net, u32 mark, const xfrm_address_t *daddr, const xfrm_address_t *saddr, From patchwork Wed Dec 20 17:06:04 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Colitti X-Patchwork-Id: 851555 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="nHoLvIwx"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3z21Qh1wCyz9s83 for ; Thu, 21 Dec 2017 04:06:52 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755753AbdLTRGu (ORCPT ); Wed, 20 Dec 2017 12:06:50 -0500 Received: from mail-pl0-f65.google.com ([209.85.160.65]:42420 "EHLO mail-pl0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755542AbdLTRGf (ORCPT ); Wed, 20 Dec 2017 12:06:35 -0500 Received: by mail-pl0-f65.google.com with SMTP id bd8so9357350plb.9 for ; Wed, 20 Dec 2017 09:06:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=gF8876HYFwuqhUt/opmyqZKDZljvycAAKgiXVP5f0CM=; b=nHoLvIwxcF3oBFNmIjl3ikL8ysC9hPy0DD3y+tQ6pUcoiucq/OO2jI4BF3XUSLUxxk csU4NntzM7iRyVE19dRHSpC9YLOPZjBXQaQDJXmBV2Ney/fyvNNbHUSA6N6h1HVfRi9b Ynbj9eMxTORCfZxtxD69P7P6O0XmM9LH3/NmRplm1DI6g/SCNfWTsfg1185E5TlRsEVr gImw5MpRWQy0+cc3HX72xJcuOaaPwyAj4dIc+0GtiDEI+nvWf/fQ9apLnYjInBuvpNmY JH0CQlpvGs4iXF3lEf6nKBOl372cv4sCYWZO0ZnvTn6HLK5+NgWzfTOX1dUcvPYlHe51 +peQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=gF8876HYFwuqhUt/opmyqZKDZljvycAAKgiXVP5f0CM=; b=dW50ij8K0WXcH88hYXGljxPfNlv84t8U/l3acJOD4J3+Dg0tn+Nial0+bb8d4G4El4 YV3ffvjpyDU2Vyq4QFxandr0XEvRDCyouc5DsXkoqArb9Pitrr3D1Xvw+U2RNAQmJFoH pnzzmL13IwuCqh9yo0rzyP0OjMG47yl+V8e7GiII+kFC7JIqM6UOB36w6H+LAw7R3mDY 01c+U++7WlMlVJNC5seUSZOwKhoSgSFz5AafdbREAYzsStgSkzHMsjcBdRfBRlbQj4Ud y+zch/Ew+TIqmX1ZctjxVRYh+TOOnRoJywpZdcU0ciPbTaxPMmrIlP4fHMgIqFMJB8UQ GD6w== X-Gm-Message-State: AKGB3mJYgqt6lnqw4NDOytTllNZYnl7vHKxh+owWE+yL6wtFTS/izweQ JpeBCoCZZHN+Df212eeqHcG8SHbhByY= X-Google-Smtp-Source: ACJfBou1ll/MG3J0YXdLf7GC3FsQ8BcVYqEMi8L2yOgDVMBiH4WIEYMUBMQcIX8+8Ybb15UUlQxpqA== X-Received: by 10.84.172.195 with SMTP id n61mr7649537plb.49.1513789594204; Wed, 20 Dec 2017 09:06:34 -0800 (PST) Received: from lorenzo.tok.corp.google.com ([100.103.3.232]) by smtp.gmail.com with ESMTPSA id t62sm29103067pgt.23.2017.12.20.09.06.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 20 Dec 2017 09:06:33 -0800 (PST) From: Lorenzo Colitti To: netdev@vger.kernel.org Cc: steffen.klassert@secunet.com, subashab@codeaurora.org, nharold@google.com, davem@davemloft.net, Lorenzo Colitti Subject: [PATCH ipsec-next 4/7] net: xfrm: Find VTI interfaces from xfrm_input. Date: Thu, 21 Dec 2017 02:06:04 +0900 Message-Id: <20171220170607.41516-5-lorenzo@google.com> X-Mailer: git-send-email 2.15.1.620.gb9897f4670-goog In-Reply-To: <20171220170607.41516-1-lorenzo@google.com> References: <20171220170607.41516-1-lorenzo@google.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Currently, the VTI input path works by first looking up the VTI by its IP addresses, then setting the tunnel pointer in the XFRM_TUNNEL_SKB_CB, and then having xfrm_input override the mark with the mark in the tunnel. This patch changes the order so that the tunnel is found by a callback from xfrm_input. Each tunnel type (currently only ip_vti and ip6_vti) implements a lookup function pointer that finds the tunnel and sets it in the CB, and also does a state lookup. This has the advantage that much more information is available to the tunnel lookup function, including the looked-up XFRM state. This will be used in a future change to allow finding the tunnel based on the result of the xfrm lookup and not just on IP addresses, which will allow multiple tunnels on the same IP address pair. The lookup function pointer occupies the same space in the XFRM_TUNNEL_SKB_CB as the IPv4/IPv6 tunnel pointer. The semantics of the field are: - When not running a handler that uses tunnels: always null. - At the beginning of xfrm_input: lookup function pointer. - After xfrm_input calls the lookup function: tunnel if found, else null. Signed-off-by: Lorenzo Colitti --- include/net/xfrm.h | 2 ++ net/ipv4/ip_vti.c | 43 ++++++++++++++++++++++++++++++++++++---- net/ipv6/ip6_vti.c | 53 +++++++++++++++++++++++++++++++++++++++++++++----- net/ipv6/xfrm6_input.c | 1 - net/xfrm/xfrm_input.c | 34 +++++++++++++++++++------------- 5 files changed, 109 insertions(+), 24 deletions(-) diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 9d3b7c0ac6..3d245f2f6f 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -653,6 +653,8 @@ struct xfrm_tunnel_skb_cb { } header; union { + int (*lookup)(struct sk_buff *skb, int nexthdr, __be32 spi, + __be32 seq, struct xfrm_state **x); struct ip_tunnel *ip4; struct ip6_tnl *ip6; } tunnel; diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c index 804cee8126..21f93e398e 100644 --- a/net/ipv4/ip_vti.c +++ b/net/ipv4/ip_vti.c @@ -49,8 +49,8 @@ static struct rtnl_link_ops vti_link_ops __read_mostly; static unsigned int vti_net_id __read_mostly; static int vti_tunnel_init(struct net_device *dev); -static int vti_input(struct sk_buff *skb, int nexthdr, __be32 spi, - int encap_type) +static struct ip_tunnel * +vti4_find_tunnel(struct sk_buff *skb, __be32 spi, struct xfrm_state **x) { struct ip_tunnel *tunnel; const struct iphdr *iph = ip_hdr(skb); @@ -59,19 +59,52 @@ static int vti_input(struct sk_buff *skb, int nexthdr, __be32 spi, tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_NO_KEY, 0, iph->saddr, iph->daddr, 0); + if (tunnel) { + *x = xfrm_state_lookup(net, be32_to_cpu(tunnel->parms.i_key), + (xfrm_address_t *)&iph->daddr, + spi, iph->protocol, AF_INET); + } + + return tunnel; +} + +static int vti_lookup(struct sk_buff *skb, int nexthdr, __be32 spi, __be32 seq, + struct xfrm_state **x) +{ + struct net *net = dev_net(skb->dev); + struct ip_tunnel *tunnel; + + tunnel = vti4_find_tunnel(skb, spi, x); if (tunnel) { if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) goto drop; + if (!*x) { + XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOSTATES); + xfrm_audit_state_notfound(skb, AF_INET, spi, seq); + tunnel->dev->stats.rx_errors++; + tunnel->dev->stats.rx_dropped++; + goto drop; + } + XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = tunnel; - return xfrm_input(skb, nexthdr, spi, encap_type); + return 0; } return -EINVAL; drop: + if (*x) + xfrm_state_put(*x); kfree_skb(skb); - return 0; + return -ESRCH; +} + +static int vti_input(struct sk_buff *skb, int nexthdr, __be32 spi, + int encap_type) +{ + XFRM_TUNNEL_SKB_CB(skb)->tunnel.lookup = vti_lookup; + return xfrm_input(skb, nexthdr, spi, encap_type); } static int vti_rcv(struct sk_buff *skb) @@ -93,6 +126,8 @@ static int vti_rcv_cb(struct sk_buff *skb, int err) u32 orig_mark = skb->mark; int ret; + XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = NULL; + if (!tunnel) return 1; diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c index dbb74f3c57..5994fedd19 100644 --- a/net/ipv6/ip6_vti.c +++ b/net/ipv6/ip6_vti.c @@ -297,13 +297,33 @@ static void vti6_dev_uninit(struct net_device *dev) dev_put(dev); } -static int vti6_rcv(struct sk_buff *skb) +static struct ip6_tnl * +vti6_find_tunnel(struct sk_buff *skb, __be32 spi, struct xfrm_state **x) { + const struct ipv6hdr *ipv6h = ipv6_hdr(skb); + struct net *net = dev_net(skb->dev); struct ip6_tnl *t; + + t = vti6_tnl_lookup(net, &ipv6h->saddr, &ipv6h->daddr); + if (t) { + *x = xfrm_state_lookup(net, be32_to_cpu(t->parms.i_key), + (xfrm_address_t *)&ipv6h->daddr, + spi, ipv6h->nexthdr, AF_INET6); + } + + return t; +} + +static int +vti6_lookup(struct sk_buff *skb, int nexthdr, __be32 spi, __be32 seq, + struct xfrm_state **x) +{ const struct ipv6hdr *ipv6h = ipv6_hdr(skb); + struct net *net = dev_net(skb->dev); + struct ip6_tnl *t; rcu_read_lock(); - t = vti6_tnl_lookup(dev_net(skb->dev), &ipv6h->saddr, &ipv6h->daddr); + t = vti6_find_tunnel(skb, spi, x); if (t) { if (t->parms.proto != IPPROTO_IPV6 && t->parms.proto != 0) { rcu_read_unlock(); @@ -312,7 +332,7 @@ static int vti6_rcv(struct sk_buff *skb) if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) { rcu_read_unlock(); - return 0; + goto discard; } if (!ip6_tnl_rcv_ctl(t, &ipv6h->daddr, &ipv6h->saddr)) { @@ -321,15 +341,36 @@ static int vti6_rcv(struct sk_buff *skb) goto discard; } + if (!*x) { + XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOSTATES); + xfrm_audit_state_notfound(skb, AF_INET6, spi, seq); + t->dev->stats.rx_errors++; + t->dev->stats.rx_dropped++; + rcu_read_unlock(); + goto discard; + } + rcu_read_unlock(); - return xfrm6_rcv_tnl(skb, t); + XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6 = t; + + return 0; } rcu_read_unlock(); return -EINVAL; discard: + if (*x) + xfrm_state_put(*x); kfree_skb(skb); - return 0; + return -ESRCH; +} + +static int vti6_rcv(struct sk_buff *skb) +{ + int nexthdr = skb_network_header(skb)[IP6CB(skb)->nhoff]; + + XFRM_TUNNEL_SKB_CB(skb)->tunnel.lookup = vti6_lookup; + return xfrm6_rcv_spi(skb, nexthdr, 0, NULL); } static int vti6_rcv_cb(struct sk_buff *skb, int err) @@ -343,6 +384,8 @@ static int vti6_rcv_cb(struct sk_buff *skb, int err) u32 orig_mark = skb->mark; int ret; + XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6 = NULL; + if (!t) return 1; diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c index fe04e23af9..6d1b734fef 100644 --- a/net/ipv6/xfrm6_input.c +++ b/net/ipv6/xfrm6_input.c @@ -25,7 +25,6 @@ int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb) int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi, struct ip6_tnl *t) { - XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6 = t; XFRM_SPI_SKB_CB(skb)->family = AF_INET6; XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct ipv6hdr, daddr); return xfrm_input(skb, nexthdr, spi, 0); diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c index ac277b97e0..7b54f58454 100644 --- a/net/xfrm/xfrm_input.c +++ b/net/xfrm/xfrm_input.c @@ -267,18 +267,6 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) family = XFRM_SPI_SKB_CB(skb)->family; - /* if tunnel is present override skb->mark value with tunnel i_key */ - switch (family) { - case AF_INET: - if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4) - mark = be32_to_cpu(XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4->parms.i_key); - break; - case AF_INET6: - if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6) - mark = be32_to_cpu(XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6->parms.i_key); - break; - } - err = secpath_set(skb); if (err) { XFRM_INC_STATS(net, LINUX_MIB_XFRMINERROR); @@ -293,14 +281,29 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) daddr = (xfrm_address_t *)(skb_network_header(skb) + XFRM_SPI_SKB_CB(skb)->daddroff); + + if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.lookup) { + err = XFRM_TUNNEL_SKB_CB(skb)->tunnel.lookup(skb, nexthdr, + spi, seq, &x); + if (err) { + XFRM_TUNNEL_SKB_CB(skb)->tunnel.lookup = NULL; + return err; + } + } + do { if (skb->sp->len == XFRM_MAX_DEPTH) { XFRM_INC_STATS(net, LINUX_MIB_XFRMINBUFFERERROR); + if (x) + xfrm_state_put(x); goto drop; } - x = xfrm_state_lookup(net, mark, daddr, spi, nexthdr, family); - if (x == NULL) { + if (!x) + x = xfrm_state_lookup(net, mark, daddr, spi, nexthdr, + family); + + if (!x) { XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOSTATES); xfrm_audit_state_notfound(skb, family, spi, seq); goto drop; @@ -420,6 +423,9 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) XFRM_INC_STATS(net, LINUX_MIB_XFRMINHDRERROR); goto drop; } + + if (!err) + x = NULL; } while (!err); err = xfrm_rcv_cb(skb, family, x->type->proto, 0); From patchwork Wed Dec 20 17:06:05 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Colitti X-Patchwork-Id: 851559 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="RsyL7pdU"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3z21R846Vfz9s83 for ; Thu, 21 Dec 2017 04:07:16 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755819AbdLTRHN (ORCPT ); Wed, 20 Dec 2017 12:07:13 -0500 Received: from mail-pl0-f67.google.com ([209.85.160.67]:38315 "EHLO mail-pl0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755607AbdLTRGh (ORCPT ); Wed, 20 Dec 2017 12:06:37 -0500 Received: by mail-pl0-f67.google.com with SMTP id s10so9355238plj.5 for ; Wed, 20 Dec 2017 09:06:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=8YJkZzbgj2ng1KMqPg88zsHzS5oUB7f5ECd+oNJ/tsU=; b=RsyL7pdULI9fqsoTat0sXJyDgo6beZB1Wh8xsKe87VpkcUA1bLO+M9ek3XS2gmwF1T nbOHVjknnALrxk//T8vmJlS7ET/HemgoNRYWFwwxQAKigBHpgiCGD8elkyRtimcKYt8G 52wwKfqemJzZm6NMmnsbqhFJdGqhSyLemyzf/IC8EEZ8LT6oEEyA61SRxg6sMUc70JBj ie6UikWMxPKHJrP+/e0kHegMa/PmKp0RXL4qQCS8RTCkJiIbxLAzXM/CRiRU9HWOGGjC fd1gVuEI/zPC5sa0kpxQpu5QKjjVEO7rdRBQ1SNu/wjeYjjOyf9UP2gxXcio9g7QMT56 tZFA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=8YJkZzbgj2ng1KMqPg88zsHzS5oUB7f5ECd+oNJ/tsU=; b=AVSqF86GbQh/RK4PYThf1zBN+iYYr1BiS0b5JPQzc08GceIONthFwPmVe5D3j+6Vid HeLBQyDDgeHbsH5EII7RzwFSoFeVvTycO3W7Z1qc5Tm76y6kdMqJsdfvnWlKJguxncx/ kx1frvVfUwwdsoih5ttBbI+QkVExang9u4zPl7revPOfMtvIZ5Z+mK5n5esg2mckPRPv gYl7zfcgDq0Ovgvg4coYoWnEJv5D3xif0tDWOHU+bRjJwYAvW6WDmCnAv7xZRgj9wVhh SC7JvCKPmno/3dJMFs6WBQP2blMCKy3ITBNJssRwQl3TM5IxxQwBv3l1Jj+zk2D4H5Ip 6CJw== X-Gm-Message-State: AKGB3mJU92vklSWmiPNI25AATp96uMzBKBfeWWRXhUrZmD46BHcOVXn5 RJpiOvLQTVCne/QZZcw7PJ2WP6ynGG0= X-Google-Smtp-Source: ACJfBovGuurosOKB3w9P3PPjOY4tVKULXF8MeqkkWro9oEM111HYb11OmJgzT8tHK1hTfu8zrURS6w== X-Received: by 10.84.193.129 with SMTP id f1mr7587907pld.355.1513789596600; Wed, 20 Dec 2017 09:06:36 -0800 (PST) Received: from lorenzo.tok.corp.google.com ([100.103.3.232]) by smtp.gmail.com with ESMTPSA id t62sm29103067pgt.23.2017.12.20.09.06.34 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 20 Dec 2017 09:06:35 -0800 (PST) From: Lorenzo Colitti To: netdev@vger.kernel.org Cc: steffen.klassert@secunet.com, subashab@codeaurora.org, nharold@google.com, davem@davemloft.net, Lorenzo Colitti Subject: [PATCH ipsec-next 5/7] net: xfrm: Deliver packets to keyed VTI tunnels. Date: Thu, 21 Dec 2017 02:06:05 +0900 Message-Id: <20171220170607.41516-6-lorenzo@google.com> X-Mailer: git-send-email 2.15.1.620.gb9897f4670-goog In-Reply-To: <20171220170607.41516-1-lorenzo@google.com> References: <20171220170607.41516-1-lorenzo@google.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org - Input works as follows: 1. Attempt to match a regular VTI by IP addresses only. If that succeeds, use the i_key as the mark to look up the xfrm state. 2. If the match failed, do an XFRM state lookup that ignores the mark. If that finds an state, then use the state match's mark to find the tunnel by its i_key. - ICMP errors: similar to input, except the search is for the outbound XFRM state and the tunnel is found by o_key instead of by i_key. - The output path is the same as existing VTIs. A routing lookup matches a VTI interface. The VTI uses its o_key as the mark to select an XFRM state. The state transforms the packet. Signed-off-by: Lorenzo Colitti --- net/ipv4/ip_vti.c | 52 ++++++++++++++++++++++++++++++------------ net/ipv6/ip6_vti.c | 67 ++++++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 88 insertions(+), 31 deletions(-) diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c index 21f93e398e..9d28433a60 100644 --- a/net/ipv4/ip_vti.c +++ b/net/ipv4/ip_vti.c @@ -63,6 +63,18 @@ vti4_find_tunnel(struct sk_buff *skb, __be32 spi, struct xfrm_state **x) *x = xfrm_state_lookup(net, be32_to_cpu(tunnel->parms.i_key), (xfrm_address_t *)&iph->daddr, spi, iph->protocol, AF_INET); + } else { + *x = xfrm_state_lookup_loose(net, skb->mark, + (xfrm_address_t *)&iph->daddr, + spi, iph->protocol, AF_INET); + if (!*x) + return NULL; + tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_KEY, + TUNNEL_LOOKUP_NO_KEY, + iph->saddr, iph->daddr, + cpu_to_be32((*x)->mark.v)); + if (!tunnel) + xfrm_state_put(*x); } return tunnel; @@ -302,7 +314,6 @@ static netdev_tx_t vti_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) static int vti4_err(struct sk_buff *skb, u32 info) { __be32 spi; - __u32 mark; struct xfrm_state *x; struct ip_tunnel *tunnel; struct ip_esp_hdr *esph; @@ -313,13 +324,6 @@ static int vti4_err(struct sk_buff *skb, u32 info) int protocol = iph->protocol; struct ip_tunnel_net *itn = net_generic(net, vti_net_id); - tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_NO_KEY, 0, - iph->daddr, iph->saddr, 0); - if (!tunnel) - return -1; - - mark = be32_to_cpu(tunnel->parms.o_key); - switch (protocol) { case IPPROTO_ESP: esph = (struct ip_esp_hdr *)(skb->data+(iph->ihl<<2)); @@ -347,18 +351,38 @@ static int vti4_err(struct sk_buff *skb, u32 info) return 0; } - x = xfrm_state_lookup(net, mark, (const xfrm_address_t *)&iph->daddr, - spi, protocol, AF_INET); - if (!x) - return 0; + tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_NO_KEY, 0, + iph->daddr, iph->saddr, 0); + if (tunnel) { + x = xfrm_state_lookup(net, be32_to_cpu(tunnel->parms.o_key), + (xfrm_address_t *)&iph->daddr, + spi, iph->protocol, AF_INET); + } else { + x = xfrm_state_lookup_loose(net, skb->mark, + (xfrm_address_t *)&iph->daddr, + spi, iph->protocol, AF_INET); + if (!x) + goto out; + tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_KEY, + TUNNEL_LOOKUP_NO_KEY | + TUNNEL_LOOKUP_OKEY, + iph->daddr, iph->saddr, + cpu_to_be32(x->mark.v)); + } + + if (!tunnel || !x) + goto out; if (icmp_hdr(skb)->type == ICMP_DEST_UNREACH) ipv4_update_pmtu(skb, net, info, 0, 0, protocol, 0); else ipv4_redirect(skb, net, 0, 0, protocol, 0); - xfrm_state_put(x); - return 0; +out: + if (x) + xfrm_state_put(x); + + return tunnel ? 0 : -1; } static int diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c index 5994fedd19..bf64821b8a 100644 --- a/net/ipv6/ip6_vti.c +++ b/net/ipv6/ip6_vti.c @@ -78,11 +78,21 @@ struct vti6_net { #define for_each_vti6_tunnel_rcu(start) \ for (t = rcu_dereference(start); t; t = rcu_dereference(t->next)) +static bool vti6_match_key(const struct ip6_tnl *t, __be32 key, bool in) +{ + __be16 tunnel_key = in ? t->parms.i_key : t->parms.o_key; + __be16 flags = in ? t->parms.i_flags : t->parms.o_flags; + + return !(flags & TUNNEL_KEY) || tunnel_key == key; +} + /** - * vti6_tnl_lookup - fetch tunnel matching the end-point addresses + * vti6_tnl_lookup - fetch tunnel matching the end-point addresses and key * @net: network namespace * @remote: the address of the tunnel exit-point * @local: the address of the tunnel entry-point + * @key: the key of the tunnel + * @in: whether to match i_key or i_key * * Return: * tunnel matching given end-points if found, @@ -91,7 +101,7 @@ struct vti6_net { **/ static struct ip6_tnl * vti6_tnl_lookup(struct net *net, const struct in6_addr *remote, - const struct in6_addr *local) + const struct in6_addr *local, __be32 key, bool in) { unsigned int hash = HASH(remote, local); struct ip6_tnl *t; @@ -101,6 +111,7 @@ vti6_tnl_lookup(struct net *net, const struct in6_addr *remote, for_each_vti6_tunnel_rcu(ip6n->tnls_r_l[hash]) { if (ipv6_addr_equal(local, &t->parms.laddr) && ipv6_addr_equal(remote, &t->parms.raddr) && + vti6_match_key(t, key, in) && (t->dev->flags & IFF_UP)) return t; } @@ -109,6 +120,7 @@ vti6_tnl_lookup(struct net *net, const struct in6_addr *remote, hash = HASH(&any, local); for_each_vti6_tunnel_rcu(ip6n->tnls_r_l[hash]) { if (ipv6_addr_equal(local, &t->parms.laddr) && + vti6_match_key(t, key, in) && (t->dev->flags & IFF_UP)) return t; } @@ -116,6 +128,7 @@ vti6_tnl_lookup(struct net *net, const struct in6_addr *remote, hash = HASH(remote, &any); for_each_vti6_tunnel_rcu(ip6n->tnls_r_l[hash]) { if (ipv6_addr_equal(remote, &t->parms.raddr) && + vti6_match_key(t, key, in) && (t->dev->flags & IFF_UP)) return t; } @@ -266,7 +279,8 @@ static struct ip6_tnl *vti6_locate(struct net *net, struct __ip6_tnl_parm *p, (t = rtnl_dereference(*tp)) != NULL; tp = &t->next) { if (ipv6_addr_equal(local, &t->parms.laddr) && - ipv6_addr_equal(remote, &t->parms.raddr)) { + ipv6_addr_equal(remote, &t->parms.raddr) && + vti6_match_key(t, p->i_key, true)) { if (create) return NULL; @@ -304,11 +318,21 @@ vti6_find_tunnel(struct sk_buff *skb, __be32 spi, struct xfrm_state **x) struct net *net = dev_net(skb->dev); struct ip6_tnl *t; - t = vti6_tnl_lookup(net, &ipv6h->saddr, &ipv6h->daddr); + t = vti6_tnl_lookup(net, &ipv6h->saddr, &ipv6h->daddr, 0, true); if (t) { *x = xfrm_state_lookup(net, be32_to_cpu(t->parms.i_key), (xfrm_address_t *)&ipv6h->daddr, spi, ipv6h->nexthdr, AF_INET6); + } else { + *x = xfrm_state_lookup_loose(net, skb->mark, + (xfrm_address_t *)&ipv6h->daddr, + spi, ipv6h->nexthdr, AF_INET6); + if (!*x) + return NULL; + t = vti6_tnl_lookup(net, &ipv6h->saddr, &ipv6h->daddr, + cpu_to_be32((*x)->mark.v), true); + if (!t) + xfrm_state_put(*x); } return t; @@ -613,7 +637,6 @@ static int vti6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, u8 type, u8 code, int offset, __be32 info) { __be32 spi; - __u32 mark; struct xfrm_state *x; struct ip6_tnl *t; struct ip_esp_hdr *esph; @@ -623,12 +646,6 @@ static int vti6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, const struct ipv6hdr *iph = (const struct ipv6hdr *)skb->data; int protocol = iph->nexthdr; - t = vti6_tnl_lookup(dev_net(skb->dev), &iph->daddr, &iph->saddr); - if (!t) - return -1; - - mark = be32_to_cpu(t->parms.o_key); - switch (protocol) { case IPPROTO_ESP: esph = (struct ip_esp_hdr *)(skb->data + offset); @@ -650,19 +667,35 @@ static int vti6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, type != NDISC_REDIRECT) return 0; - x = xfrm_state_lookup(net, mark, (const xfrm_address_t *)&iph->daddr, - spi, protocol, AF_INET6); - if (!x) - return 0; + t = vti6_tnl_lookup(net, &iph->daddr, &iph->saddr, 0, false); + if (t) { + x = xfrm_state_lookup(net, be32_to_cpu(t->parms.o_key), + (xfrm_address_t *)&iph->daddr, + spi, protocol, AF_INET6); + } else { + x = xfrm_state_lookup_loose(net, skb->mark, + (xfrm_address_t *)&iph->daddr, + spi, protocol, AF_INET6); + if (!x) + goto out; + t = vti6_tnl_lookup(net, &iph->daddr, &iph->saddr, + cpu_to_be32(x->mark.v), false); + } + + if (!t || !x) + goto out; if (type == NDISC_REDIRECT) ip6_redirect(skb, net, skb->dev->ifindex, 0, sock_net_uid(net, NULL)); else ip6_update_pmtu(skb, net, info, 0, 0, sock_net_uid(net, NULL)); - xfrm_state_put(x); - return 0; +out: + if (x) + xfrm_state_put(x); + + return t ? 0 : -1; } static void vti6_link_config(struct ip6_tnl *t) From patchwork Wed Dec 20 17:06:06 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Colitti X-Patchwork-Id: 851556 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="fIe2yuLz"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3z21Qn2N1Gz9s83 for ; Thu, 21 Dec 2017 04:06:57 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755759AbdLTRGy (ORCPT ); Wed, 20 Dec 2017 12:06:54 -0500 Received: from mail-pf0-f193.google.com ([209.85.192.193]:36837 "EHLO mail-pf0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755698AbdLTRGk (ORCPT ); Wed, 20 Dec 2017 12:06:40 -0500 Received: by mail-pf0-f193.google.com with SMTP id p84so12815857pfd.3 for ; Wed, 20 Dec 2017 09:06:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=GHsIO1OXZMa+Iq5ufSp0RT+Zh8x7bH7aaEyCZHvh4po=; b=fIe2yuLzcV7sASlupzI6GEU1LdGKGkajVJzKnFwqC5npC5EjamVDH0tgc+gTgDN0rm +gRe4KdwmV9OimW9RaKr7FjrAH5ffckRxV9xHC7Jfg+QM+2IbKp9z8t4NOaiy5JiiVvW HFeafo1do/0PtXjrLXTFzJjNjDIW0IH+Z5gd+DMhhiRIah6yBH3tHGaGda0AZ+X8hQJM QGMqapwkAOslIAJIXA9LYB4iC2CPyudLLXFPq88BtG6WfhaJ862Bd8qd2IF4EJ0KpKjB +SVG9pnCOtejgpidQVzgBwsTYAA8qEpj5Dqu/uVyosLLtZdQFp044K09mPB6Ho2I0j1K kDhg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=GHsIO1OXZMa+Iq5ufSp0RT+Zh8x7bH7aaEyCZHvh4po=; b=RPQedeJWpYTGyQGNxe/safEULraOCrOJQbMS0AQpBunkjJJBhjc2N/cFKecOTq26fq j0e9ScVBDHkwgGd3bamZBSxK1gLe0b+et0zHgo2Iyn7mhkJuQ9Ry/0v02yEDGy2gKb8K Yz/p1ngQOGO49m+4/xs/lRy12HQyEdK9OZxJA9sZotwCYJgKu7XDQKRKITbM96XsZhlc sf4k/pvdZmQfwss4HOX0Z1DBIwbhssXnBzUiQOignIXnXnhUNZAdWrtbbfz45I0qYfiW G8pd8wMsr2k8bDegqqGfh+PlfoqBneM4vMZM+8bxsv76uf7hiukZfULW4DHLtMfkFGu6 Bt2w== X-Gm-Message-State: AKGB3mLqJTz10Qj7BjEQNf1vBO2D4YnTLjSJ6k/x5MYeMAfAqdIyYpRf EaT9+h4PdzXnq/H8Ojo7ssnYJksIwX4= X-Google-Smtp-Source: ACJfBoui5prNM6JJJbSzClvkkrak9NlGdP+g7BraoZ4ZvmXeHnSrGRiqqm/tloakUw3F2g4kjI5rsw== X-Received: by 10.99.49.215 with SMTP id x206mr6874099pgx.372.1513789598839; Wed, 20 Dec 2017 09:06:38 -0800 (PST) Received: from lorenzo.tok.corp.google.com ([100.103.3.232]) by smtp.gmail.com with ESMTPSA id t62sm29103067pgt.23.2017.12.20.09.06.36 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 20 Dec 2017 09:06:38 -0800 (PST) From: Lorenzo Colitti To: netdev@vger.kernel.org Cc: steffen.klassert@secunet.com, subashab@codeaurora.org, nharold@google.com, davem@davemloft.net, Lorenzo Colitti Subject: [PATCH ipsec-next 6/7] net: xfrm: Allow userspace to configure keyed VTI tunnels. Date: Thu, 21 Dec 2017 02:06:06 +0900 Message-Id: <20171220170607.41516-7-lorenzo@google.com> X-Mailer: git-send-email 2.15.1.620.gb9897f4670-goog In-Reply-To: <20171220170607.41516-1-lorenzo@google.com> References: <20171220170607.41516-1-lorenzo@google.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This commit allows userspace to configure keyed VTI tunnels by adding a IFLA_VTI_FLAGS attribute and a VTI_KEYED flag. When set, the flag causes the tunnel parameter i_flags to be set to TUNNEL_KEY. Creating both a non-keyed VTI and a keyed VTI on the same IP src+dst pair is not useful. Because non-keyed VTIs always accept packets, in such a configuration the keyed VTI would not receive any traffic. This is disallowed by modifying the ip_tunnel_find and vti6_locate functions to treat VTIs on the same src+dst pair as identical unless they are both keyed (in which case they can coexist, by design). So attempts to create such duplicate tunnels - or to change one tunnel in such a way that it would duplicate another - will fail with EEXIST. Signed-off-by: Lorenzo Colitti --- include/uapi/linux/if_tunnel.h | 4 ++++ net/ipv4/ip_tunnel.c | 10 +++++++++- net/ipv4/ip_vti.c | 26 +++++++++++++++++++++++--- net/ipv6/ip6_vti.c | 33 +++++++++++++++++++++++++++++++-- 4 files changed, 67 insertions(+), 6 deletions(-) diff --git a/include/uapi/linux/if_tunnel.h b/include/uapi/linux/if_tunnel.h index 1b3d148c45..b431b1c209 100644 --- a/include/uapi/linux/if_tunnel.h +++ b/include/uapi/linux/if_tunnel.h @@ -148,6 +148,9 @@ enum { /* VTI-mode i_flags */ #define VTI_ISVTI ((__force __be16)0x0001) +/* VTI netlink iflags. */ +#define VTI_KEYED 0x0001 + enum { IFLA_VTI_UNSPEC, IFLA_VTI_LINK, @@ -156,6 +159,7 @@ enum { IFLA_VTI_LOCAL, IFLA_VTI_REMOTE, IFLA_VTI_FWMARK, + IFLA_VTI_FLAGS, __IFLA_VTI_MAX, }; diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index f45968bb81..9a0a56b491 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c @@ -84,6 +84,14 @@ static bool ip_tunnel_key_match(const struct ip_tunnel_parm *p, return !(flags & TUNNEL_KEY); } +static bool ip_tunnel_match(const struct ip_tunnel_parm *p, + __be32 flags, u8 lookup_flags, __be32 key) +{ + return ip_tunnel_key_match(p, flags, lookup_flags, key) || + ((p->i_flags & flags & VTI_ISVTI) && + !(p->i_flags & flags & TUNNEL_KEY)); +} + /* Fallback tunnel: no source, no destination, no key, no options Tunnel hash table: @@ -242,7 +250,7 @@ static struct ip_tunnel *ip_tunnel_find(struct ip_tunnel_net *itn, remote == t->parms.iph.daddr && link == t->parms.link && type == t->dev->type && - ip_tunnel_key_match(&t->parms, flags, 0, key)) + ip_tunnel_match(&t->parms, flags, 0, key)) break; } return t; diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c index 9d28433a60..1f52719228 100644 --- a/net/ipv4/ip_vti.c +++ b/net/ipv4/ip_vti.c @@ -385,6 +385,16 @@ static int vti4_err(struct sk_buff *skb, u32 info) return tunnel ? 0 : -1; } +static __be16 vti_flags_to_tnl_flags(__u16 flags) +{ + return VTI_ISVTI | ((flags & VTI_KEYED) ? TUNNEL_KEY : 0); +} + +static __u16 tnl_flags_to_vti_flags(__be16 i_flags) +{ + return (i_flags & TUNNEL_KEY) ? VTI_KEYED : 0; +} + static int vti_tunnel_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { @@ -525,6 +535,8 @@ static void vti_netlink_parms(struct nlattr *data[], struct ip_tunnel_parm *parms, __u32 *fwmark) { + __u16 flags = 0; + memset(parms, 0, sizeof(*parms)); parms->iph.protocol = IPPROTO_IPIP; @@ -532,8 +544,6 @@ static void vti_netlink_parms(struct nlattr *data[], if (!data) return; - parms->i_flags = VTI_ISVTI; - if (data[IFLA_VTI_LINK]) parms->link = nla_get_u32(data[IFLA_VTI_LINK]); @@ -551,6 +561,11 @@ static void vti_netlink_parms(struct nlattr *data[], if (data[IFLA_VTI_FWMARK]) *fwmark = nla_get_u32(data[IFLA_VTI_FWMARK]); + + if (data[IFLA_VTI_FLAGS]) + flags = nla_get_u16(data[IFLA_VTI_FLAGS]); + + parms->i_flags = vti_flags_to_tnl_flags(flags); } static int vti_newlink(struct net *src_net, struct net_device *dev, @@ -591,6 +606,8 @@ static size_t vti_get_size(const struct net_device *dev) nla_total_size(4) + /* IFLA_VTI_FWMARK */ nla_total_size(4) + + /* IFLA_VTI_FLAGS */ + nla_total_size(2) + 0; } @@ -604,7 +621,9 @@ static int vti_fill_info(struct sk_buff *skb, const struct net_device *dev) nla_put_be32(skb, IFLA_VTI_OKEY, p->o_key) || nla_put_in_addr(skb, IFLA_VTI_LOCAL, p->iph.saddr) || nla_put_in_addr(skb, IFLA_VTI_REMOTE, p->iph.daddr) || - nla_put_u32(skb, IFLA_VTI_FWMARK, t->fwmark)) + nla_put_u32(skb, IFLA_VTI_FWMARK, t->fwmark) || + nla_put_u16(skb, IFLA_VTI_FLAGS, + tnl_flags_to_vti_flags(p->i_flags))) return -EMSGSIZE; return 0; @@ -617,6 +636,7 @@ static const struct nla_policy vti_policy[IFLA_VTI_MAX + 1] = { [IFLA_VTI_LOCAL] = { .len = FIELD_SIZEOF(struct iphdr, saddr) }, [IFLA_VTI_REMOTE] = { .len = FIELD_SIZEOF(struct iphdr, daddr) }, [IFLA_VTI_FWMARK] = { .type = NLA_U32 }, + [IFLA_VTI_FLAGS] = { .type = NLA_U16 }, }; static struct rtnl_link_ops vti_link_ops __read_mostly = { diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c index bf64821b8a..18c2695dc3 100644 --- a/net/ipv6/ip6_vti.c +++ b/net/ipv6/ip6_vti.c @@ -86,6 +86,13 @@ static bool vti6_match_key(const struct ip6_tnl *t, __be32 key, bool in) return !(flags & TUNNEL_KEY) || tunnel_key == key; } +static bool vti6_match_tunnel(const struct ip6_tnl *t, struct __ip6_tnl_parm *p) +{ + return !(t->parms.i_flags & TUNNEL_KEY) || + !(p->i_flags & TUNNEL_KEY) || + vti6_match_key(t, p->i_key, true); +} + /** * vti6_tnl_lookup - fetch tunnel matching the end-point addresses and key * @net: network namespace @@ -280,7 +287,7 @@ static struct ip6_tnl *vti6_locate(struct net *net, struct __ip6_tnl_parm *p, tp = &t->next) { if (ipv6_addr_equal(local, &t->parms.laddr) && ipv6_addr_equal(remote, &t->parms.raddr) && - vti6_match_key(t, p->i_key, true)) { + vti6_match_tunnel(t, p)) { if (create) return NULL; @@ -990,9 +997,21 @@ static int vti6_validate(struct nlattr *tb[], struct nlattr *data[], return 0; } +static __be16 vti_flags_to_tnl_flags(__u16 i_flags) +{ + return VTI_ISVTI | ((i_flags & VTI_KEYED) ? TUNNEL_KEY : 0); +} + +static __u16 tnl_flags_to_vti_flags(__be16 i_flags) +{ + return (i_flags & TUNNEL_KEY) ? VTI_KEYED : 0; +} + static void vti6_netlink_parms(struct nlattr *data[], struct __ip6_tnl_parm *parms) { + __u16 flags = 0; + memset(parms, 0, sizeof(*parms)); if (!data) @@ -1015,6 +1034,11 @@ static void vti6_netlink_parms(struct nlattr *data[], if (data[IFLA_VTI_FWMARK]) parms->fwmark = nla_get_u32(data[IFLA_VTI_FWMARK]); + + if (data[IFLA_VTI_FLAGS]) + flags = nla_get_u16(data[IFLA_VTI_FLAGS]); + + parms->i_flags = vti_flags_to_tnl_flags(flags); } static int vti6_newlink(struct net *src_net, struct net_device *dev, @@ -1084,6 +1108,8 @@ static size_t vti6_get_size(const struct net_device *dev) nla_total_size(4) + /* IFLA_VTI_FWMARK */ nla_total_size(4) + + /* IFLA_VTI_FLAGS */ + nla_total_size(2) + 0; } @@ -1097,7 +1123,9 @@ static int vti6_fill_info(struct sk_buff *skb, const struct net_device *dev) nla_put_in6_addr(skb, IFLA_VTI_REMOTE, &parm->raddr) || nla_put_be32(skb, IFLA_VTI_IKEY, parm->i_key) || nla_put_be32(skb, IFLA_VTI_OKEY, parm->o_key) || - nla_put_u32(skb, IFLA_VTI_FWMARK, parm->fwmark)) + nla_put_u32(skb, IFLA_VTI_FWMARK, parm->fwmark) || + nla_put_u16(skb, IFLA_VTI_FLAGS, + tnl_flags_to_vti_flags(parm->i_flags))) goto nla_put_failure; return 0; @@ -1112,6 +1140,7 @@ static const struct nla_policy vti6_policy[IFLA_VTI_MAX + 1] = { [IFLA_VTI_IKEY] = { .type = NLA_U32 }, [IFLA_VTI_OKEY] = { .type = NLA_U32 }, [IFLA_VTI_FWMARK] = { .type = NLA_U32 }, + [IFLA_VTI_FLAGS] = { .type = NLA_U16 }, }; static struct rtnl_link_ops vti6_link_ops __read_mostly = { From patchwork Wed Dec 20 17:06:07 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Colitti X-Patchwork-Id: 851557 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="dYDfwG/z"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3z21Qp2CF9z9sBd for ; Thu, 21 Dec 2017 04:06:58 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755778AbdLTRG4 (ORCPT ); Wed, 20 Dec 2017 12:06:56 -0500 Received: from mail-pf0-f196.google.com ([209.85.192.196]:43074 "EHLO mail-pf0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755712AbdLTRGm (ORCPT ); Wed, 20 Dec 2017 12:06:42 -0500 Received: by mail-pf0-f196.google.com with SMTP id e3so12799866pfi.10 for ; Wed, 20 Dec 2017 09:06:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=C6Z4p0vckqoS2hXDyq3YAJkSF0Esspb6jfj88l+6kus=; b=dYDfwG/zCfjMu1089KOe449EvL3wnMda/81JWIH0uySLqCIeGvUeFKHX+Sm+PjsojY GnH5WuZF25WvxT54zfHQbWr3CkszwlNLBlgm43Qrbdg2Lwy/4TPNVuOGL8ykET/IKXht 2WcEMP6n1HsIRJ3SQUxxjGGcwcjc/UxqccoXTkhtD8HNEl1Hp7HWV0NQvTLZQgXi8mVD 1KG1qh1T1EyMzWo9901mHs7ai0KA03hf/cfiJGot1Z4f2dmS4T9Iiz5EsQ8uqIgre4BK 2M01G+iivmpQq1wy/XxNduLGRMSHsrKtgWEi6usj3pvnzBLczS1zeIwRbn9LPegA4Wmj abdQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=C6Z4p0vckqoS2hXDyq3YAJkSF0Esspb6jfj88l+6kus=; b=AUT6PIiwRvMp4eLJ/EQYOWqJif1rd64e5B2Tbab9K8Oli/f3fSsS/3145eg+badxE3 7mMSf74hxRfg1fW1WeljZHb3d+uo4iofYiRi2xhcC0dJuJj/7g4605xoWViqEapAaajO xkwyh2Fer7iPXpgTwecJshqZypfZcQqELFoLsIz8mddlN5J9wFTk63Z2K/IMbROcGhwt ZQe4NlR4BGJ3xvbvhuvbc9SUz/0qxL+ckqGqOnS9CQEUK5OTJS20pVfsI6hHG8EvUGJA +DR4IsrWY7HsXY6zcsnvbDH2YV2o1B7DB6eB7iypdwb5QD1ysiZvVwvOoyEkMwDV57aT U9Kw== X-Gm-Message-State: AKGB3mIFz3lRrpGek+5CfCAEzUU98XVhoCswXINSneXnUdtiVpfqMtfs 7Ou+2F82AvnsaSscktCysowjQ4tt64s= X-Google-Smtp-Source: ACJfBoso5oQWBCicfNl35HfNCz14E+P/Jc2fZzcQ3hpgqyfxR64sy8lYxl1osLOnILfAkc7BrCD9Vg== X-Received: by 10.98.103.156 with SMTP id t28mr7530044pfj.234.1513789601243; Wed, 20 Dec 2017 09:06:41 -0800 (PST) Received: from lorenzo.tok.corp.google.com ([100.103.3.232]) by smtp.gmail.com with ESMTPSA id t62sm29103067pgt.23.2017.12.20.09.06.39 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 20 Dec 2017 09:06:40 -0800 (PST) From: Lorenzo Colitti To: netdev@vger.kernel.org Cc: steffen.klassert@secunet.com, subashab@codeaurora.org, nharold@google.com, davem@davemloft.net, Lorenzo Colitti Subject: [PATCH ipsec-next 7/7] net: xfrm: Don't pass tunnel objects to xfrm6_rcv_spi. Date: Thu, 21 Dec 2017 02:06:07 +0900 Message-Id: <20171220170607.41516-8-lorenzo@google.com> X-Mailer: git-send-email 2.15.1.620.gb9897f4670-goog In-Reply-To: <20171220170607.41516-1-lorenzo@google.com> References: <20171220170607.41516-1-lorenzo@google.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This change removes the tunnel parameter from xfrm6_rcv_spi and deletes xfrm6_rcv_tnl. These were only used by the VTI code and are now unused. Tested: https://android-review.googlesource.com/571524 Signed-off-by: Lorenzo Colitti --- include/net/xfrm.h | 4 +--- net/ipv6/ip6_vti.c | 2 +- net/ipv6/xfrm6_input.c | 13 +++---------- net/ipv6/xfrm6_tunnel.c | 2 +- 4 files changed, 6 insertions(+), 15 deletions(-) diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 3d245f2f6f..fc19dda73c 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -1638,10 +1638,8 @@ int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family); void xfrm4_local_error(struct sk_buff *skb, u32 mtu); int xfrm6_extract_header(struct sk_buff *skb); int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb); -int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi, - struct ip6_tnl *t); +int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi); int xfrm6_transport_finish(struct sk_buff *skb, int async); -int xfrm6_rcv_tnl(struct sk_buff *skb, struct ip6_tnl *t); int xfrm6_rcv(struct sk_buff *skb); int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto); diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c index 18c2695dc3..2ac0bfff0f 100644 --- a/net/ipv6/ip6_vti.c +++ b/net/ipv6/ip6_vti.c @@ -401,7 +401,7 @@ static int vti6_rcv(struct sk_buff *skb) int nexthdr = skb_network_header(skb)[IP6CB(skb)->nhoff]; XFRM_TUNNEL_SKB_CB(skb)->tunnel.lookup = vti6_lookup; - return xfrm6_rcv_spi(skb, nexthdr, 0, NULL); + return xfrm6_rcv_spi(skb, nexthdr, 0); } static int vti6_rcv_cb(struct sk_buff *skb, int err) diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c index 6d1b734fef..5f20e30926 100644 --- a/net/ipv6/xfrm6_input.c +++ b/net/ipv6/xfrm6_input.c @@ -22,8 +22,7 @@ int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb) return xfrm6_extract_header(skb); } -int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi, - struct ip6_tnl *t) +int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi) { XFRM_SPI_SKB_CB(skb)->family = AF_INET6; XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct ipv6hdr, daddr); @@ -59,16 +58,10 @@ int xfrm6_transport_finish(struct sk_buff *skb, int async) return -1; } -int xfrm6_rcv_tnl(struct sk_buff *skb, struct ip6_tnl *t) -{ - return xfrm6_rcv_spi(skb, skb_network_header(skb)[IP6CB(skb)->nhoff], - 0, t); -} -EXPORT_SYMBOL(xfrm6_rcv_tnl); - int xfrm6_rcv(struct sk_buff *skb) { - return xfrm6_rcv_tnl(skb, NULL); + return xfrm6_rcv_spi(skb, skb_network_header(skb)[IP6CB(skb)->nhoff], + 0); } EXPORT_SYMBOL(xfrm6_rcv); int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c index f85f0d7480..02161543a9 100644 --- a/net/ipv6/xfrm6_tunnel.c +++ b/net/ipv6/xfrm6_tunnel.c @@ -236,7 +236,7 @@ static int xfrm6_tunnel_rcv(struct sk_buff *skb) __be32 spi; spi = xfrm6_tunnel_spi_lookup(net, (const xfrm_address_t *)&iph->saddr); - return xfrm6_rcv_spi(skb, IPPROTO_IPV6, spi, NULL); + return xfrm6_rcv_spi(skb, IPPROTO_IPV6, spi); } static int xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt,