Skip to contentSkip to conversation

Patch "ip_tunnel: replace dst_cache with generic implementation" has been added to the 4.4-stable tree

PATCH [email protected] 1 participant 1 message Feb 26, 2018

Subsystems (3)
lore
Share & tools
lore

[email protected]

author maintainer Applied
#0 lore raw

This is a note to let you know that I've just added the patch titled

ip_tunnel: replace dst_cache with generic implementation

to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
ip_tunnel-replace-dst_cache-with-generic-implementation.patch
and it can be found in the queue-4.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

Quoted 1 line

From e09acddf873bf775b208b452a4c3a3fd26fa9427 Mon Sep 17 00:00:00 2001

From: Paolo Abeni <[email protected]>
Date: Fri, 12 Feb 2016 15:43:55 +0100
Subject: ip_tunnel: replace dst_cache with generic implementation

From: Paolo Abeni <[email protected]>

commit e09acddf873bf775b208b452a4c3a3fd26fa9427 upstream.

The current ip_tunnel cache implementation is prone to a race that will cause the wrong dst to be cached on cuncurrent dst cache miss and ip tunnel update via netlink.

Replacing with the generic implementation fix the issue.

---
 include/net/ip_tunnels.h |    9 +----
 net/ipv4/Kconfig         |    1 
 net/ipv4/ip_tunnel.c     |   78 +++++++----------------------------------------
 net/ipv6/sit.c           |   17 +++++-----
 4 files changed, 25 insertions(+), 80 deletions(-)
include/net/ip_tunnels.h +2 -7
@@ -13,6 +13,7 @@
 #include <net/netns/generic.h>
 #include <net/rtnetlink.h>
 #include <net/lwtunnel.h>
+#include <net/dst_cache.h>
 
 #if IS_ENABLED(CONFIG_IPV6)
 #include <net/ipv6.h>
@@ -85,11 +86,6 @@ struct ip_tunnel_prl_entry {
 	struct rcu_head			rcu_head;
 };
 
-struct ip_tunnel_dst {
-	struct dst_entry __rcu 		*dst;
-	__be32				 saddr;
-};
-
 struct metadata_dst;
 
 struct ip_tunnel {
@@ -108,7 +104,7 @@ struct ip_tunnel {
 	int		tun_hlen;	/* Precalculated header length */
 	int		mlink;
 
-	struct ip_tunnel_dst __percpu *dst_cache;
+	struct dst_cache dst_cache;
 
 	struct ip_tunnel_parm parms;
 
@@ -248,7 +244,6 @@ int ip_tunnel_changelink(struct net_devi
 int ip_tunnel_newlink(struct net_device *dev, struct nlattr *tb[],
 		      struct ip_tunnel_parm *p);
 void ip_tunnel_setup(struct net_device *dev, int net_id);
-void ip_tunnel_dst_reset_all(struct ip_tunnel *t);
 int ip_tunnel_encap_setup(struct ip_tunnel *t,
 			  struct ip_tunnel_encap *ipencap);
 
net/ipv4/Kconfig +1 -0
@@ -186,6 +186,7 @@ config NET_IPGRE_DEMUX
 
 config NET_IP_TUNNEL
 	tristate
+	select DST_CACHE
 	default n
 
 config NET_IPGRE
net/ipv4/ip_tunnel.c +13 -65

131 lines not on this page · raw message

net/ipv6/sit.c +9 -8
@@ -475,7 +475,7 @@ static void ipip6_tunnel_uninit(struct n
 		ipip6_tunnel_unlink(sitn, tunnel);
 		ipip6_tunnel_del_prl(tunnel, NULL);
 	}
-	ip_tunnel_dst_reset_all(tunnel);
+	dst_cache_reset(&tunnel->dst_cache);
 	dev_put(dev);
 }
 
@@ -1098,7 +1098,7 @@ static void ipip6_tunnel_update(struct i
 		t->parms.link = p->link;
 		ipip6_tunnel_bind_dev(t->dev);
 	}
-	ip_tunnel_dst_reset_all(t);
+	dst_cache_reset(&t->dst_cache);
 	netdev_state_change(t->dev);
 }
 
@@ -1129,7 +1129,7 @@ static int ipip6_tunnel_update_6rd(struc
 	t->ip6rd.relay_prefix = relay_prefix;
 	t->ip6rd.prefixlen = ip6rd->prefixlen;
 	t->ip6rd.relay_prefixlen = ip6rd->relay_prefixlen;
-	ip_tunnel_dst_reset_all(t);
+	dst_cache_reset(&t->dst_cache);
 	netdev_state_change(t->dev);
 	return 0;
 }
@@ -1283,7 +1283,7 @@ ipip6_tunnel_ioctl(struct net_device *de
 			err = ipip6_tunnel_add_prl(t, &prl, cmd == SIOCCHGPRL);
 			break;
 		}
-		ip_tunnel_dst_reset_all(t);
+		dst_cache_reset(&t->dst_cache);
 		netdev_state_change(dev);
 		break;
 
@@ -1344,7 +1344,7 @@ static void ipip6_dev_free(struct net_de
 {
 	struct ip_tunnel *tunnel = netdev_priv(dev);
 
-	free_percpu(tunnel->dst_cache);
+	dst_cache_destroy(&tunnel->dst_cache);
 	free_percpu(dev->tstats);
 	free_netdev(dev);
 }
@@ -1377,6 +1377,7 @@ static void ipip6_tunnel_setup(struct ne
 static int ipip6_tunnel_init(struct net_device *dev)
 {
 	struct ip_tunnel *tunnel = netdev_priv(dev);
+	int err;
 
 	tunnel->dev = dev;
 	tunnel->net = dev_net(dev);
@@ -1387,11 +1388,11 @@ static int ipip6_tunnel_init(struct net_
 	if (!dev->tstats)
 		return -ENOMEM;
 
-	tunnel->dst_cache = alloc_percpu(struct ip_tunnel_dst);
-	if (!tunnel->dst_cache) {
+	err = dst_cache_init(&tunnel->dst_cache, GFP_KERNEL);
+	if (err) {
 		free_percpu(dev->tstats);
 		dev->tstats = NULL;
-		return -ENOMEM;
+		return err;
 	}
 
 	return 0;

Patches currently in stable-queue which might be from [email protected] are

queue-4.4/ip_tunnel-fix-preempt-warning-in-ip-tunnel-creation-updating.patch queue-4.4/ip_tunnel-replace-dst_cache-with-generic-implementation.patch queue-4.4/netfilter-drop-outermost-socket-lock-in-getsockopt.patch