xref: /linux/net/ipv4/ip_tunnel.c (revision 7371e0221c7721a1486fef745abaa8ae84571621)
1c5441932SPravin B Shelar /*
2c5441932SPravin B Shelar  * Copyright (c) 2013 Nicira, Inc.
3c5441932SPravin B Shelar  *
4c5441932SPravin B Shelar  * This program is free software; you can redistribute it and/or
5c5441932SPravin B Shelar  * modify it under the terms of version 2 of the GNU General Public
6c5441932SPravin B Shelar  * License as published by the Free Software Foundation.
7c5441932SPravin B Shelar  *
8c5441932SPravin B Shelar  * This program is distributed in the hope that it will be useful, but
9c5441932SPravin B Shelar  * WITHOUT ANY WARRANTY; without even the implied warranty of
10c5441932SPravin B Shelar  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11c5441932SPravin B Shelar  * General Public License for more details.
12c5441932SPravin B Shelar  *
13c5441932SPravin B Shelar  * You should have received a copy of the GNU General Public License
14c5441932SPravin B Shelar  * along with this program; if not, write to the Free Software
15c5441932SPravin B Shelar  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16c5441932SPravin B Shelar  * 02110-1301, USA
17c5441932SPravin B Shelar  */
18c5441932SPravin B Shelar 
19c5441932SPravin B Shelar #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
20c5441932SPravin B Shelar 
21c5441932SPravin B Shelar #include <linux/capability.h>
22c5441932SPravin B Shelar #include <linux/module.h>
23c5441932SPravin B Shelar #include <linux/types.h>
24c5441932SPravin B Shelar #include <linux/kernel.h>
25c5441932SPravin B Shelar #include <linux/slab.h>
26c5441932SPravin B Shelar #include <linux/uaccess.h>
27c5441932SPravin B Shelar #include <linux/skbuff.h>
28c5441932SPravin B Shelar #include <linux/netdevice.h>
29c5441932SPravin B Shelar #include <linux/in.h>
30c5441932SPravin B Shelar #include <linux/tcp.h>
31c5441932SPravin B Shelar #include <linux/udp.h>
32c5441932SPravin B Shelar #include <linux/if_arp.h>
33c5441932SPravin B Shelar #include <linux/mroute.h>
34c5441932SPravin B Shelar #include <linux/init.h>
35c5441932SPravin B Shelar #include <linux/in6.h>
36c5441932SPravin B Shelar #include <linux/inetdevice.h>
37c5441932SPravin B Shelar #include <linux/igmp.h>
38c5441932SPravin B Shelar #include <linux/netfilter_ipv4.h>
39c5441932SPravin B Shelar #include <linux/etherdevice.h>
40c5441932SPravin B Shelar #include <linux/if_ether.h>
41c5441932SPravin B Shelar #include <linux/if_vlan.h>
42c5441932SPravin B Shelar #include <linux/rculist.h>
4327d79f3bSSachin Kamat #include <linux/err.h>
44c5441932SPravin B Shelar 
45c5441932SPravin B Shelar #include <net/sock.h>
46c5441932SPravin B Shelar #include <net/ip.h>
47c5441932SPravin B Shelar #include <net/icmp.h>
48c5441932SPravin B Shelar #include <net/protocol.h>
49c5441932SPravin B Shelar #include <net/ip_tunnels.h>
50c5441932SPravin B Shelar #include <net/arp.h>
51c5441932SPravin B Shelar #include <net/checksum.h>
52c5441932SPravin B Shelar #include <net/dsfield.h>
53c5441932SPravin B Shelar #include <net/inet_ecn.h>
54c5441932SPravin B Shelar #include <net/xfrm.h>
55c5441932SPravin B Shelar #include <net/net_namespace.h>
56c5441932SPravin B Shelar #include <net/netns/generic.h>
57c5441932SPravin B Shelar #include <net/rtnetlink.h>
5856328486STom Herbert #include <net/udp.h>
59c5441932SPravin B Shelar 
60c5441932SPravin B Shelar #if IS_ENABLED(CONFIG_IPV6)
61c5441932SPravin B Shelar #include <net/ipv6.h>
62c5441932SPravin B Shelar #include <net/ip6_fib.h>
63c5441932SPravin B Shelar #include <net/ip6_route.h>
64c5441932SPravin B Shelar #endif
65c5441932SPravin B Shelar 
66967680e0SDuan Jiong static unsigned int ip_tunnel_hash(__be32 key, __be32 remote)
67c5441932SPravin B Shelar {
68c5441932SPravin B Shelar 	return hash_32((__force u32)key ^ (__force u32)remote,
69c5441932SPravin B Shelar 			 IP_TNL_HASH_BITS);
70c5441932SPravin B Shelar }
71c5441932SPravin B Shelar 
726c7e7610SEric Dumazet static void __tunnel_dst_set(struct ip_tunnel_dst *idst,
7395cb5745SDmitry Popov 			     struct dst_entry *dst, __be32 saddr)
747d442fabSTom Herbert {
757d442fabSTom Herbert 	struct dst_entry *old_dst;
767d442fabSTom Herbert 
776c7e7610SEric Dumazet 	dst_clone(dst);
786c7e7610SEric Dumazet 	old_dst = xchg((__force struct dst_entry **)&idst->dst, dst);
797d442fabSTom Herbert 	dst_release(old_dst);
8095cb5745SDmitry Popov 	idst->saddr = saddr;
817d442fabSTom Herbert }
827d442fabSTom Herbert 
83a35165caSEric Dumazet static noinline void tunnel_dst_set(struct ip_tunnel *t,
8495cb5745SDmitry Popov 			   struct dst_entry *dst, __be32 saddr)
857d442fabSTom Herbert {
86a35165caSEric Dumazet 	__tunnel_dst_set(raw_cpu_ptr(t->dst_cache), dst, saddr);
877d442fabSTom Herbert }
887d442fabSTom Herbert 
896c7e7610SEric Dumazet static void tunnel_dst_reset(struct ip_tunnel *t)
907d442fabSTom Herbert {
9195cb5745SDmitry Popov 	tunnel_dst_set(t, NULL, 0);
927d442fabSTom Herbert }
937d442fabSTom Herbert 
94cf71d2bcSNicolas Dichtel void ip_tunnel_dst_reset_all(struct ip_tunnel *t)
959a4aa9afSTom Herbert {
969a4aa9afSTom Herbert 	int i;
979a4aa9afSTom Herbert 
989a4aa9afSTom Herbert 	for_each_possible_cpu(i)
9995cb5745SDmitry Popov 		__tunnel_dst_set(per_cpu_ptr(t->dst_cache, i), NULL, 0);
1009a4aa9afSTom Herbert }
101cf71d2bcSNicolas Dichtel EXPORT_SYMBOL(ip_tunnel_dst_reset_all);
1029a4aa9afSTom Herbert 
10395cb5745SDmitry Popov static struct rtable *tunnel_rtable_get(struct ip_tunnel *t,
10495cb5745SDmitry Popov 					u32 cookie, __be32 *saddr)
1057d442fabSTom Herbert {
10695cb5745SDmitry Popov 	struct ip_tunnel_dst *idst;
1077d442fabSTom Herbert 	struct dst_entry *dst;
1087d442fabSTom Herbert 
1097d442fabSTom Herbert 	rcu_read_lock();
110a35165caSEric Dumazet 	idst = raw_cpu_ptr(t->dst_cache);
11195cb5745SDmitry Popov 	dst = rcu_dereference(idst->dst);
112f8864972SEric Dumazet 	if (dst && !atomic_inc_not_zero(&dst->__refcnt))
113f8864972SEric Dumazet 		dst = NULL;
114b045d37bSEric Dumazet 	if (dst) {
11595cb5745SDmitry Popov 		if (!dst->obsolete || dst->ops->check(dst, cookie)) {
11695cb5745SDmitry Popov 			*saddr = idst->saddr;
11795cb5745SDmitry Popov 		} else {
1187d442fabSTom Herbert 			tunnel_dst_reset(t);
119f8864972SEric Dumazet 			dst_release(dst);
120f8864972SEric Dumazet 			dst = NULL;
1217d442fabSTom Herbert 		}
122b045d37bSEric Dumazet 	}
123b045d37bSEric Dumazet 	rcu_read_unlock();
124b045d37bSEric Dumazet 	return (struct rtable *)dst;
1257d442fabSTom Herbert }
1267d442fabSTom Herbert 
127c5441932SPravin B Shelar static bool ip_tunnel_key_match(const struct ip_tunnel_parm *p,
128c5441932SPravin B Shelar 				__be16 flags, __be32 key)
129c5441932SPravin B Shelar {
130c5441932SPravin B Shelar 	if (p->i_flags & TUNNEL_KEY) {
131c5441932SPravin B Shelar 		if (flags & TUNNEL_KEY)
132c5441932SPravin B Shelar 			return key == p->i_key;
133c5441932SPravin B Shelar 		else
134c5441932SPravin B Shelar 			/* key expected, none present */
135c5441932SPravin B Shelar 			return false;
136c5441932SPravin B Shelar 	} else
137c5441932SPravin B Shelar 		return !(flags & TUNNEL_KEY);
138c5441932SPravin B Shelar }
139c5441932SPravin B Shelar 
140c5441932SPravin B Shelar /* Fallback tunnel: no source, no destination, no key, no options
141c5441932SPravin B Shelar 
142c5441932SPravin B Shelar    Tunnel hash table:
143c5441932SPravin B Shelar    We require exact key match i.e. if a key is present in packet
144c5441932SPravin B Shelar    it will match only tunnel with the same key; if it is not present,
145c5441932SPravin B Shelar    it will match only keyless tunnel.
146c5441932SPravin B Shelar 
147c5441932SPravin B Shelar    All keysless packets, if not matched configured keyless tunnels
148c5441932SPravin B Shelar    will match fallback tunnel.
149c5441932SPravin B Shelar    Given src, dst and key, find appropriate for input tunnel.
150c5441932SPravin B Shelar */
151c5441932SPravin B Shelar struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn,
152c5441932SPravin B Shelar 				   int link, __be16 flags,
153c5441932SPravin B Shelar 				   __be32 remote, __be32 local,
154c5441932SPravin B Shelar 				   __be32 key)
155c5441932SPravin B Shelar {
156c5441932SPravin B Shelar 	unsigned int hash;
157c5441932SPravin B Shelar 	struct ip_tunnel *t, *cand = NULL;
158c5441932SPravin B Shelar 	struct hlist_head *head;
159c5441932SPravin B Shelar 
160967680e0SDuan Jiong 	hash = ip_tunnel_hash(key, remote);
161c5441932SPravin B Shelar 	head = &itn->tunnels[hash];
162c5441932SPravin B Shelar 
163c5441932SPravin B Shelar 	hlist_for_each_entry_rcu(t, head, hash_node) {
164c5441932SPravin B Shelar 		if (local != t->parms.iph.saddr ||
165c5441932SPravin B Shelar 		    remote != t->parms.iph.daddr ||
166c5441932SPravin B Shelar 		    !(t->dev->flags & IFF_UP))
167c5441932SPravin B Shelar 			continue;
168c5441932SPravin B Shelar 
169c5441932SPravin B Shelar 		if (!ip_tunnel_key_match(&t->parms, flags, key))
170c5441932SPravin B Shelar 			continue;
171c5441932SPravin B Shelar 
172c5441932SPravin B Shelar 		if (t->parms.link == link)
173c5441932SPravin B Shelar 			return t;
174c5441932SPravin B Shelar 		else
175c5441932SPravin B Shelar 			cand = t;
176c5441932SPravin B Shelar 	}
177c5441932SPravin B Shelar 
178c5441932SPravin B Shelar 	hlist_for_each_entry_rcu(t, head, hash_node) {
179c5441932SPravin B Shelar 		if (remote != t->parms.iph.daddr ||
180e0056593SDmitry Popov 		    t->parms.iph.saddr != 0 ||
181c5441932SPravin B Shelar 		    !(t->dev->flags & IFF_UP))
182c5441932SPravin B Shelar 			continue;
183c5441932SPravin B Shelar 
184c5441932SPravin B Shelar 		if (!ip_tunnel_key_match(&t->parms, flags, key))
185c5441932SPravin B Shelar 			continue;
186c5441932SPravin B Shelar 
187c5441932SPravin B Shelar 		if (t->parms.link == link)
188c5441932SPravin B Shelar 			return t;
189c5441932SPravin B Shelar 		else if (!cand)
190c5441932SPravin B Shelar 			cand = t;
191c5441932SPravin B Shelar 	}
192c5441932SPravin B Shelar 
193967680e0SDuan Jiong 	hash = ip_tunnel_hash(key, 0);
194c5441932SPravin B Shelar 	head = &itn->tunnels[hash];
195c5441932SPravin B Shelar 
196c5441932SPravin B Shelar 	hlist_for_each_entry_rcu(t, head, hash_node) {
197e0056593SDmitry Popov 		if ((local != t->parms.iph.saddr || t->parms.iph.daddr != 0) &&
198e0056593SDmitry Popov 		    (local != t->parms.iph.daddr || !ipv4_is_multicast(local)))
199e0056593SDmitry Popov 			continue;
200e0056593SDmitry Popov 
201e0056593SDmitry Popov 		if (!(t->dev->flags & IFF_UP))
202c5441932SPravin B Shelar 			continue;
203c5441932SPravin B Shelar 
204c5441932SPravin B Shelar 		if (!ip_tunnel_key_match(&t->parms, flags, key))
205c5441932SPravin B Shelar 			continue;
206c5441932SPravin B Shelar 
207c5441932SPravin B Shelar 		if (t->parms.link == link)
208c5441932SPravin B Shelar 			return t;
209c5441932SPravin B Shelar 		else if (!cand)
210c5441932SPravin B Shelar 			cand = t;
211c5441932SPravin B Shelar 	}
212c5441932SPravin B Shelar 
213c5441932SPravin B Shelar 	if (flags & TUNNEL_NO_KEY)
214c5441932SPravin B Shelar 		goto skip_key_lookup;
215c5441932SPravin B Shelar 
216c5441932SPravin B Shelar 	hlist_for_each_entry_rcu(t, head, hash_node) {
217c5441932SPravin B Shelar 		if (t->parms.i_key != key ||
218e0056593SDmitry Popov 		    t->parms.iph.saddr != 0 ||
219e0056593SDmitry Popov 		    t->parms.iph.daddr != 0 ||
220c5441932SPravin B Shelar 		    !(t->dev->flags & IFF_UP))
221c5441932SPravin B Shelar 			continue;
222c5441932SPravin B Shelar 
223c5441932SPravin B Shelar 		if (t->parms.link == link)
224c5441932SPravin B Shelar 			return t;
225c5441932SPravin B Shelar 		else if (!cand)
226c5441932SPravin B Shelar 			cand = t;
227c5441932SPravin B Shelar 	}
228c5441932SPravin B Shelar 
229c5441932SPravin B Shelar skip_key_lookup:
230c5441932SPravin B Shelar 	if (cand)
231c5441932SPravin B Shelar 		return cand;
232c5441932SPravin B Shelar 
233c5441932SPravin B Shelar 	if (itn->fb_tunnel_dev && itn->fb_tunnel_dev->flags & IFF_UP)
234c5441932SPravin B Shelar 		return netdev_priv(itn->fb_tunnel_dev);
235c5441932SPravin B Shelar 
236c5441932SPravin B Shelar 
237c5441932SPravin B Shelar 	return NULL;
238c5441932SPravin B Shelar }
239c5441932SPravin B Shelar EXPORT_SYMBOL_GPL(ip_tunnel_lookup);
240c5441932SPravin B Shelar 
241c5441932SPravin B Shelar static struct hlist_head *ip_bucket(struct ip_tunnel_net *itn,
242c5441932SPravin B Shelar 				    struct ip_tunnel_parm *parms)
243c5441932SPravin B Shelar {
244c5441932SPravin B Shelar 	unsigned int h;
245c5441932SPravin B Shelar 	__be32 remote;
2466d608f06SSteffen Klassert 	__be32 i_key = parms->i_key;
247c5441932SPravin B Shelar 
248c5441932SPravin B Shelar 	if (parms->iph.daddr && !ipv4_is_multicast(parms->iph.daddr))
249c5441932SPravin B Shelar 		remote = parms->iph.daddr;
250c5441932SPravin B Shelar 	else
251c5441932SPravin B Shelar 		remote = 0;
252c5441932SPravin B Shelar 
2536d608f06SSteffen Klassert 	if (!(parms->i_flags & TUNNEL_KEY) && (parms->i_flags & VTI_ISVTI))
2546d608f06SSteffen Klassert 		i_key = 0;
2556d608f06SSteffen Klassert 
2566d608f06SSteffen Klassert 	h = ip_tunnel_hash(i_key, remote);
257c5441932SPravin B Shelar 	return &itn->tunnels[h];
258c5441932SPravin B Shelar }
259c5441932SPravin B Shelar 
260c5441932SPravin B Shelar static void ip_tunnel_add(struct ip_tunnel_net *itn, struct ip_tunnel *t)
261c5441932SPravin B Shelar {
262c5441932SPravin B Shelar 	struct hlist_head *head = ip_bucket(itn, &t->parms);
263c5441932SPravin B Shelar 
264c5441932SPravin B Shelar 	hlist_add_head_rcu(&t->hash_node, head);
265c5441932SPravin B Shelar }
266c5441932SPravin B Shelar 
267c5441932SPravin B Shelar static void ip_tunnel_del(struct ip_tunnel *t)
268c5441932SPravin B Shelar {
269c5441932SPravin B Shelar 	hlist_del_init_rcu(&t->hash_node);
270c5441932SPravin B Shelar }
271c5441932SPravin B Shelar 
272c5441932SPravin B Shelar static struct ip_tunnel *ip_tunnel_find(struct ip_tunnel_net *itn,
273c5441932SPravin B Shelar 					struct ip_tunnel_parm *parms,
274c5441932SPravin B Shelar 					int type)
275c5441932SPravin B Shelar {
276c5441932SPravin B Shelar 	__be32 remote = parms->iph.daddr;
277c5441932SPravin B Shelar 	__be32 local = parms->iph.saddr;
278c5441932SPravin B Shelar 	__be32 key = parms->i_key;
2795ce54af1SDmitry Popov 	__be16 flags = parms->i_flags;
280c5441932SPravin B Shelar 	int link = parms->link;
281c5441932SPravin B Shelar 	struct ip_tunnel *t = NULL;
282c5441932SPravin B Shelar 	struct hlist_head *head = ip_bucket(itn, parms);
283c5441932SPravin B Shelar 
284c5441932SPravin B Shelar 	hlist_for_each_entry_rcu(t, head, hash_node) {
285c5441932SPravin B Shelar 		if (local == t->parms.iph.saddr &&
286c5441932SPravin B Shelar 		    remote == t->parms.iph.daddr &&
287c5441932SPravin B Shelar 		    link == t->parms.link &&
2885ce54af1SDmitry Popov 		    type == t->dev->type &&
2895ce54af1SDmitry Popov 		    ip_tunnel_key_match(&t->parms, flags, key))
290c5441932SPravin B Shelar 			break;
291c5441932SPravin B Shelar 	}
292c5441932SPravin B Shelar 	return t;
293c5441932SPravin B Shelar }
294c5441932SPravin B Shelar 
295c5441932SPravin B Shelar static struct net_device *__ip_tunnel_create(struct net *net,
296c5441932SPravin B Shelar 					     const struct rtnl_link_ops *ops,
297c5441932SPravin B Shelar 					     struct ip_tunnel_parm *parms)
298c5441932SPravin B Shelar {
299c5441932SPravin B Shelar 	int err;
300c5441932SPravin B Shelar 	struct ip_tunnel *tunnel;
301c5441932SPravin B Shelar 	struct net_device *dev;
302c5441932SPravin B Shelar 	char name[IFNAMSIZ];
303c5441932SPravin B Shelar 
304c5441932SPravin B Shelar 	if (parms->name[0])
305c5441932SPravin B Shelar 		strlcpy(name, parms->name, IFNAMSIZ);
306c5441932SPravin B Shelar 	else {
30754a5d382SPravin B Shelar 		if (strlen(ops->kind) > (IFNAMSIZ - 3)) {
308c5441932SPravin B Shelar 			err = -E2BIG;
309c5441932SPravin B Shelar 			goto failed;
310c5441932SPravin B Shelar 		}
311c5441932SPravin B Shelar 		strlcpy(name, ops->kind, IFNAMSIZ);
312c5441932SPravin B Shelar 		strncat(name, "%d", 2);
313c5441932SPravin B Shelar 	}
314c5441932SPravin B Shelar 
315c5441932SPravin B Shelar 	ASSERT_RTNL();
316c835a677STom Gundersen 	dev = alloc_netdev(ops->priv_size, name, NET_NAME_UNKNOWN, ops->setup);
317c5441932SPravin B Shelar 	if (!dev) {
318c5441932SPravin B Shelar 		err = -ENOMEM;
319c5441932SPravin B Shelar 		goto failed;
320c5441932SPravin B Shelar 	}
321c5441932SPravin B Shelar 	dev_net_set(dev, net);
322c5441932SPravin B Shelar 
323c5441932SPravin B Shelar 	dev->rtnl_link_ops = ops;
324c5441932SPravin B Shelar 
325c5441932SPravin B Shelar 	tunnel = netdev_priv(dev);
326c5441932SPravin B Shelar 	tunnel->parms = *parms;
3275e6700b3SNicolas Dichtel 	tunnel->net = net;
328c5441932SPravin B Shelar 
329c5441932SPravin B Shelar 	err = register_netdevice(dev);
330c5441932SPravin B Shelar 	if (err)
331c5441932SPravin B Shelar 		goto failed_free;
332c5441932SPravin B Shelar 
333c5441932SPravin B Shelar 	return dev;
334c5441932SPravin B Shelar 
335c5441932SPravin B Shelar failed_free:
336c5441932SPravin B Shelar 	free_netdev(dev);
337c5441932SPravin B Shelar failed:
338c5441932SPravin B Shelar 	return ERR_PTR(err);
339c5441932SPravin B Shelar }
340c5441932SPravin B Shelar 
3417d442fabSTom Herbert static inline void init_tunnel_flow(struct flowi4 *fl4,
342c5441932SPravin B Shelar 				    int proto,
343c5441932SPravin B Shelar 				    __be32 daddr, __be32 saddr,
344c5441932SPravin B Shelar 				    __be32 key, __u8 tos, int oif)
345c5441932SPravin B Shelar {
346c5441932SPravin B Shelar 	memset(fl4, 0, sizeof(*fl4));
347c5441932SPravin B Shelar 	fl4->flowi4_oif = oif;
348c5441932SPravin B Shelar 	fl4->daddr = daddr;
349c5441932SPravin B Shelar 	fl4->saddr = saddr;
350c5441932SPravin B Shelar 	fl4->flowi4_tos = tos;
351c5441932SPravin B Shelar 	fl4->flowi4_proto = proto;
352c5441932SPravin B Shelar 	fl4->fl4_gre_key = key;
353c5441932SPravin B Shelar }
354c5441932SPravin B Shelar 
355c5441932SPravin B Shelar static int ip_tunnel_bind_dev(struct net_device *dev)
356c5441932SPravin B Shelar {
357c5441932SPravin B Shelar 	struct net_device *tdev = NULL;
358c5441932SPravin B Shelar 	struct ip_tunnel *tunnel = netdev_priv(dev);
359c5441932SPravin B Shelar 	const struct iphdr *iph;
360c5441932SPravin B Shelar 	int hlen = LL_MAX_HEADER;
361c5441932SPravin B Shelar 	int mtu = ETH_DATA_LEN;
362c5441932SPravin B Shelar 	int t_hlen = tunnel->hlen + sizeof(struct iphdr);
363c5441932SPravin B Shelar 
364c5441932SPravin B Shelar 	iph = &tunnel->parms.iph;
365c5441932SPravin B Shelar 
366c5441932SPravin B Shelar 	/* Guess output device to choose reasonable mtu and needed_headroom */
367c5441932SPravin B Shelar 	if (iph->daddr) {
368c5441932SPravin B Shelar 		struct flowi4 fl4;
369c5441932SPravin B Shelar 		struct rtable *rt;
370c5441932SPravin B Shelar 
3717d442fabSTom Herbert 		init_tunnel_flow(&fl4, iph->protocol, iph->daddr,
3727d442fabSTom Herbert 				 iph->saddr, tunnel->parms.o_key,
3737d442fabSTom Herbert 				 RT_TOS(iph->tos), tunnel->parms.link);
3747d442fabSTom Herbert 		rt = ip_route_output_key(tunnel->net, &fl4);
3757d442fabSTom Herbert 
376c5441932SPravin B Shelar 		if (!IS_ERR(rt)) {
377c5441932SPravin B Shelar 			tdev = rt->dst.dev;
37895cb5745SDmitry Popov 			tunnel_dst_set(tunnel, &rt->dst, fl4.saddr);
379c5441932SPravin B Shelar 			ip_rt_put(rt);
380c5441932SPravin B Shelar 		}
381c5441932SPravin B Shelar 		if (dev->type != ARPHRD_ETHER)
382c5441932SPravin B Shelar 			dev->flags |= IFF_POINTOPOINT;
383c5441932SPravin B Shelar 	}
384c5441932SPravin B Shelar 
385c5441932SPravin B Shelar 	if (!tdev && tunnel->parms.link)
3866c742e71SNicolas Dichtel 		tdev = __dev_get_by_index(tunnel->net, tunnel->parms.link);
387c5441932SPravin B Shelar 
388c5441932SPravin B Shelar 	if (tdev) {
389c5441932SPravin B Shelar 		hlen = tdev->hard_header_len + tdev->needed_headroom;
390c5441932SPravin B Shelar 		mtu = tdev->mtu;
391c5441932SPravin B Shelar 	}
392c5441932SPravin B Shelar 	dev->iflink = tunnel->parms.link;
393c5441932SPravin B Shelar 
394c5441932SPravin B Shelar 	dev->needed_headroom = t_hlen + hlen;
395c5441932SPravin B Shelar 	mtu -= (dev->hard_header_len + t_hlen);
396c5441932SPravin B Shelar 
397c5441932SPravin B Shelar 	if (mtu < 68)
398c5441932SPravin B Shelar 		mtu = 68;
399c5441932SPravin B Shelar 
400c5441932SPravin B Shelar 	return mtu;
401c5441932SPravin B Shelar }
402c5441932SPravin B Shelar 
403c5441932SPravin B Shelar static struct ip_tunnel *ip_tunnel_create(struct net *net,
404c5441932SPravin B Shelar 					  struct ip_tunnel_net *itn,
405c5441932SPravin B Shelar 					  struct ip_tunnel_parm *parms)
406c5441932SPravin B Shelar {
4074929fd8cSJulia Lawall 	struct ip_tunnel *nt;
408c5441932SPravin B Shelar 	struct net_device *dev;
409c5441932SPravin B Shelar 
410c5441932SPravin B Shelar 	BUG_ON(!itn->fb_tunnel_dev);
411c5441932SPravin B Shelar 	dev = __ip_tunnel_create(net, itn->fb_tunnel_dev->rtnl_link_ops, parms);
412c5441932SPravin B Shelar 	if (IS_ERR(dev))
4136dd3c9ecSFlorian Westphal 		return ERR_CAST(dev);
414c5441932SPravin B Shelar 
415c5441932SPravin B Shelar 	dev->mtu = ip_tunnel_bind_dev(dev);
416c5441932SPravin B Shelar 
417c5441932SPravin B Shelar 	nt = netdev_priv(dev);
418c5441932SPravin B Shelar 	ip_tunnel_add(itn, nt);
419c5441932SPravin B Shelar 	return nt;
420c5441932SPravin B Shelar }
421c5441932SPravin B Shelar 
422c5441932SPravin B Shelar int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb,
423c5441932SPravin B Shelar 		  const struct tnl_ptk_info *tpi, bool log_ecn_error)
424c5441932SPravin B Shelar {
4258f84985fSLi RongQing 	struct pcpu_sw_netstats *tstats;
426c5441932SPravin B Shelar 	const struct iphdr *iph = ip_hdr(skb);
427c5441932SPravin B Shelar 	int err;
428c5441932SPravin B Shelar 
429c5441932SPravin B Shelar #ifdef CONFIG_NET_IPGRE_BROADCAST
430c5441932SPravin B Shelar 	if (ipv4_is_multicast(iph->daddr)) {
431c5441932SPravin B Shelar 		tunnel->dev->stats.multicast++;
432c5441932SPravin B Shelar 		skb->pkt_type = PACKET_BROADCAST;
433c5441932SPravin B Shelar 	}
434c5441932SPravin B Shelar #endif
435c5441932SPravin B Shelar 
436c5441932SPravin B Shelar 	if ((!(tpi->flags&TUNNEL_CSUM) &&  (tunnel->parms.i_flags&TUNNEL_CSUM)) ||
437c5441932SPravin B Shelar 	     ((tpi->flags&TUNNEL_CSUM) && !(tunnel->parms.i_flags&TUNNEL_CSUM))) {
438c5441932SPravin B Shelar 		tunnel->dev->stats.rx_crc_errors++;
439c5441932SPravin B Shelar 		tunnel->dev->stats.rx_errors++;
440c5441932SPravin B Shelar 		goto drop;
441c5441932SPravin B Shelar 	}
442c5441932SPravin B Shelar 
443c5441932SPravin B Shelar 	if (tunnel->parms.i_flags&TUNNEL_SEQ) {
444c5441932SPravin B Shelar 		if (!(tpi->flags&TUNNEL_SEQ) ||
445c5441932SPravin B Shelar 		    (tunnel->i_seqno && (s32)(ntohl(tpi->seq) - tunnel->i_seqno) < 0)) {
446c5441932SPravin B Shelar 			tunnel->dev->stats.rx_fifo_errors++;
447c5441932SPravin B Shelar 			tunnel->dev->stats.rx_errors++;
448c5441932SPravin B Shelar 			goto drop;
449c5441932SPravin B Shelar 		}
450c5441932SPravin B Shelar 		tunnel->i_seqno = ntohl(tpi->seq) + 1;
451c5441932SPravin B Shelar 	}
452c5441932SPravin B Shelar 
453e96f2e7cSYing Cai 	skb_reset_network_header(skb);
454e96f2e7cSYing Cai 
455c5441932SPravin B Shelar 	err = IP_ECN_decapsulate(iph, skb);
456c5441932SPravin B Shelar 	if (unlikely(err)) {
457c5441932SPravin B Shelar 		if (log_ecn_error)
458c5441932SPravin B Shelar 			net_info_ratelimited("non-ECT from %pI4 with TOS=%#x\n",
459c5441932SPravin B Shelar 					&iph->saddr, iph->tos);
460c5441932SPravin B Shelar 		if (err > 1) {
461c5441932SPravin B Shelar 			++tunnel->dev->stats.rx_frame_errors;
462c5441932SPravin B Shelar 			++tunnel->dev->stats.rx_errors;
463c5441932SPravin B Shelar 			goto drop;
464c5441932SPravin B Shelar 		}
465c5441932SPravin B Shelar 	}
466c5441932SPravin B Shelar 
467c5441932SPravin B Shelar 	tstats = this_cpu_ptr(tunnel->dev->tstats);
468c5441932SPravin B Shelar 	u64_stats_update_begin(&tstats->syncp);
469c5441932SPravin B Shelar 	tstats->rx_packets++;
470c5441932SPravin B Shelar 	tstats->rx_bytes += skb->len;
471c5441932SPravin B Shelar 	u64_stats_update_end(&tstats->syncp);
472c5441932SPravin B Shelar 
47381b9eab5SAlexei Starovoitov 	skb_scrub_packet(skb, !net_eq(tunnel->net, dev_net(tunnel->dev)));
47481b9eab5SAlexei Starovoitov 
4753d7b46cdSPravin B Shelar 	if (tunnel->dev->type == ARPHRD_ETHER) {
4763d7b46cdSPravin B Shelar 		skb->protocol = eth_type_trans(skb, tunnel->dev);
4773d7b46cdSPravin B Shelar 		skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
4783d7b46cdSPravin B Shelar 	} else {
4793d7b46cdSPravin B Shelar 		skb->dev = tunnel->dev;
4803d7b46cdSPravin B Shelar 	}
48164261f23SNicolas Dichtel 
482c5441932SPravin B Shelar 	gro_cells_receive(&tunnel->gro_cells, skb);
483c5441932SPravin B Shelar 	return 0;
484c5441932SPravin B Shelar 
485c5441932SPravin B Shelar drop:
486c5441932SPravin B Shelar 	kfree_skb(skb);
487c5441932SPravin B Shelar 	return 0;
488c5441932SPravin B Shelar }
489c5441932SPravin B Shelar EXPORT_SYMBOL_GPL(ip_tunnel_rcv);
490c5441932SPravin B Shelar 
49156328486STom Herbert static int ip_encap_hlen(struct ip_tunnel_encap *e)
49256328486STom Herbert {
49356328486STom Herbert 	switch (e->type) {
49456328486STom Herbert 	case TUNNEL_ENCAP_NONE:
49556328486STom Herbert 		return 0;
49656328486STom Herbert 	case TUNNEL_ENCAP_FOU:
49756328486STom Herbert 		return sizeof(struct udphdr);
49856328486STom Herbert 	default:
49956328486STom Herbert 		return -EINVAL;
50056328486STom Herbert 	}
50156328486STom Herbert }
50256328486STom Herbert 
50356328486STom Herbert int ip_tunnel_encap_setup(struct ip_tunnel *t,
50456328486STom Herbert 			  struct ip_tunnel_encap *ipencap)
50556328486STom Herbert {
50656328486STom Herbert 	int hlen;
50756328486STom Herbert 
50856328486STom Herbert 	memset(&t->encap, 0, sizeof(t->encap));
50956328486STom Herbert 
51056328486STom Herbert 	hlen = ip_encap_hlen(ipencap);
51156328486STom Herbert 	if (hlen < 0)
51256328486STom Herbert 		return hlen;
51356328486STom Herbert 
51456328486STom Herbert 	t->encap.type = ipencap->type;
51556328486STom Herbert 	t->encap.sport = ipencap->sport;
51656328486STom Herbert 	t->encap.dport = ipencap->dport;
51756328486STom Herbert 	t->encap.flags = ipencap->flags;
51856328486STom Herbert 
51956328486STom Herbert 	t->encap_hlen = hlen;
52056328486STom Herbert 	t->hlen = t->encap_hlen + t->tun_hlen;
52156328486STom Herbert 
52256328486STom Herbert 	return 0;
52356328486STom Herbert }
52456328486STom Herbert EXPORT_SYMBOL_GPL(ip_tunnel_encap_setup);
52556328486STom Herbert 
52656328486STom Herbert static int fou_build_header(struct sk_buff *skb, struct ip_tunnel_encap *e,
52756328486STom Herbert 			    size_t hdr_len, u8 *protocol, struct flowi4 *fl4)
52856328486STom Herbert {
52956328486STom Herbert 	struct udphdr *uh;
53056328486STom Herbert 	__be16 sport;
53156328486STom Herbert 	bool csum = !!(e->flags & TUNNEL_ENCAP_FLAG_CSUM);
53256328486STom Herbert 	int type = csum ? SKB_GSO_UDP_TUNNEL_CSUM : SKB_GSO_UDP_TUNNEL;
53356328486STom Herbert 
53456328486STom Herbert 	skb = iptunnel_handle_offloads(skb, csum, type);
53556328486STom Herbert 
53656328486STom Herbert 	if (IS_ERR(skb))
53756328486STom Herbert 		return PTR_ERR(skb);
53856328486STom Herbert 
53956328486STom Herbert 	/* Get length and hash before making space in skb */
54056328486STom Herbert 
54156328486STom Herbert 	sport = e->sport ? : udp_flow_src_port(dev_net(skb->dev),
54256328486STom Herbert 					       skb, 0, 0, false);
54356328486STom Herbert 
54456328486STom Herbert 	skb_push(skb, hdr_len);
54556328486STom Herbert 
54656328486STom Herbert 	skb_reset_transport_header(skb);
54756328486STom Herbert 	uh = udp_hdr(skb);
54856328486STom Herbert 
54956328486STom Herbert 	uh->dest = e->dport;
55056328486STom Herbert 	uh->source = sport;
55156328486STom Herbert 	uh->len = htons(skb->len);
55256328486STom Herbert 	uh->check = 0;
55356328486STom Herbert 	udp_set_csum(!(e->flags & TUNNEL_ENCAP_FLAG_CSUM), skb,
55456328486STom Herbert 		     fl4->saddr, fl4->daddr, skb->len);
55556328486STom Herbert 
55656328486STom Herbert 	*protocol = IPPROTO_UDP;
55756328486STom Herbert 
55856328486STom Herbert 	return 0;
55956328486STom Herbert }
56056328486STom Herbert 
56156328486STom Herbert int ip_tunnel_encap(struct sk_buff *skb, struct ip_tunnel *t,
56256328486STom Herbert 		    u8 *protocol, struct flowi4 *fl4)
56356328486STom Herbert {
56456328486STom Herbert 	switch (t->encap.type) {
56556328486STom Herbert 	case TUNNEL_ENCAP_NONE:
56656328486STom Herbert 		return 0;
56756328486STom Herbert 	case TUNNEL_ENCAP_FOU:
56856328486STom Herbert 		return fou_build_header(skb, &t->encap, t->encap_hlen,
56956328486STom Herbert 					protocol, fl4);
57056328486STom Herbert 	default:
57156328486STom Herbert 		return -EINVAL;
57256328486STom Herbert 	}
57356328486STom Herbert }
57456328486STom Herbert EXPORT_SYMBOL(ip_tunnel_encap);
57556328486STom Herbert 
57623a3647bSPravin B Shelar static int tnl_update_pmtu(struct net_device *dev, struct sk_buff *skb,
57723a3647bSPravin B Shelar 			    struct rtable *rt, __be16 df)
57823a3647bSPravin B Shelar {
57923a3647bSPravin B Shelar 	struct ip_tunnel *tunnel = netdev_priv(dev);
5808c91e162SAlexander Duyck 	int pkt_size = skb->len - tunnel->hlen - dev->hard_header_len;
58123a3647bSPravin B Shelar 	int mtu;
58223a3647bSPravin B Shelar 
58323a3647bSPravin B Shelar 	if (df)
58423a3647bSPravin B Shelar 		mtu = dst_mtu(&rt->dst) - dev->hard_header_len
58523a3647bSPravin B Shelar 					- sizeof(struct iphdr) - tunnel->hlen;
58623a3647bSPravin B Shelar 	else
58723a3647bSPravin B Shelar 		mtu = skb_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu;
58823a3647bSPravin B Shelar 
58923a3647bSPravin B Shelar 	if (skb_dst(skb))
59023a3647bSPravin B Shelar 		skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu);
59123a3647bSPravin B Shelar 
59223a3647bSPravin B Shelar 	if (skb->protocol == htons(ETH_P_IP)) {
59323a3647bSPravin B Shelar 		if (!skb_is_gso(skb) &&
59423a3647bSPravin B Shelar 		    (df & htons(IP_DF)) && mtu < pkt_size) {
59523a3647bSPravin B Shelar 			memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
59623a3647bSPravin B Shelar 			icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));
59723a3647bSPravin B Shelar 			return -E2BIG;
59823a3647bSPravin B Shelar 		}
59923a3647bSPravin B Shelar 	}
60023a3647bSPravin B Shelar #if IS_ENABLED(CONFIG_IPV6)
60123a3647bSPravin B Shelar 	else if (skb->protocol == htons(ETH_P_IPV6)) {
60223a3647bSPravin B Shelar 		struct rt6_info *rt6 = (struct rt6_info *)skb_dst(skb);
60323a3647bSPravin B Shelar 
60423a3647bSPravin B Shelar 		if (rt6 && mtu < dst_mtu(skb_dst(skb)) &&
60523a3647bSPravin B Shelar 			   mtu >= IPV6_MIN_MTU) {
60623a3647bSPravin B Shelar 			if ((tunnel->parms.iph.daddr &&
60723a3647bSPravin B Shelar 			    !ipv4_is_multicast(tunnel->parms.iph.daddr)) ||
60823a3647bSPravin B Shelar 			    rt6->rt6i_dst.plen == 128) {
60923a3647bSPravin B Shelar 				rt6->rt6i_flags |= RTF_MODIFIED;
61023a3647bSPravin B Shelar 				dst_metric_set(skb_dst(skb), RTAX_MTU, mtu);
61123a3647bSPravin B Shelar 			}
61223a3647bSPravin B Shelar 		}
61323a3647bSPravin B Shelar 
61423a3647bSPravin B Shelar 		if (!skb_is_gso(skb) && mtu >= IPV6_MIN_MTU &&
61523a3647bSPravin B Shelar 					mtu < pkt_size) {
61623a3647bSPravin B Shelar 			icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
61723a3647bSPravin B Shelar 			return -E2BIG;
61823a3647bSPravin B Shelar 		}
61923a3647bSPravin B Shelar 	}
62023a3647bSPravin B Shelar #endif
62123a3647bSPravin B Shelar 	return 0;
62223a3647bSPravin B Shelar }
62323a3647bSPravin B Shelar 
624c5441932SPravin B Shelar void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
62556328486STom Herbert 		    const struct iphdr *tnl_params, u8 protocol)
626c5441932SPravin B Shelar {
627c5441932SPravin B Shelar 	struct ip_tunnel *tunnel = netdev_priv(dev);
628c5441932SPravin B Shelar 	const struct iphdr *inner_iph;
629c5441932SPravin B Shelar 	struct flowi4 fl4;
630c5441932SPravin B Shelar 	u8     tos, ttl;
631c5441932SPravin B Shelar 	__be16 df;
632b045d37bSEric Dumazet 	struct rtable *rt;		/* Route to the other host */
633c5441932SPravin B Shelar 	unsigned int max_headroom;	/* The extra header space needed */
634c5441932SPravin B Shelar 	__be32 dst;
6350e6fbc5bSPravin B Shelar 	int err;
63622fb22eaSTimo Teräs 	bool connected;
637c5441932SPravin B Shelar 
638c5441932SPravin B Shelar 	inner_iph = (const struct iphdr *)skb_inner_network_header(skb);
63922fb22eaSTimo Teräs 	connected = (tunnel->parms.iph.daddr != 0);
640c5441932SPravin B Shelar 
641c5441932SPravin B Shelar 	dst = tnl_params->daddr;
642c5441932SPravin B Shelar 	if (dst == 0) {
643c5441932SPravin B Shelar 		/* NBMA tunnel */
644c5441932SPravin B Shelar 
645c5441932SPravin B Shelar 		if (skb_dst(skb) == NULL) {
646c5441932SPravin B Shelar 			dev->stats.tx_fifo_errors++;
647c5441932SPravin B Shelar 			goto tx_error;
648c5441932SPravin B Shelar 		}
649c5441932SPravin B Shelar 
650c5441932SPravin B Shelar 		if (skb->protocol == htons(ETH_P_IP)) {
651c5441932SPravin B Shelar 			rt = skb_rtable(skb);
652c5441932SPravin B Shelar 			dst = rt_nexthop(rt, inner_iph->daddr);
653c5441932SPravin B Shelar 		}
654c5441932SPravin B Shelar #if IS_ENABLED(CONFIG_IPV6)
655c5441932SPravin B Shelar 		else if (skb->protocol == htons(ETH_P_IPV6)) {
656c5441932SPravin B Shelar 			const struct in6_addr *addr6;
657c5441932SPravin B Shelar 			struct neighbour *neigh;
658c5441932SPravin B Shelar 			bool do_tx_error_icmp;
659c5441932SPravin B Shelar 			int addr_type;
660c5441932SPravin B Shelar 
661c5441932SPravin B Shelar 			neigh = dst_neigh_lookup(skb_dst(skb),
662c5441932SPravin B Shelar 						 &ipv6_hdr(skb)->daddr);
663c5441932SPravin B Shelar 			if (neigh == NULL)
664c5441932SPravin B Shelar 				goto tx_error;
665c5441932SPravin B Shelar 
666c5441932SPravin B Shelar 			addr6 = (const struct in6_addr *)&neigh->primary_key;
667c5441932SPravin B Shelar 			addr_type = ipv6_addr_type(addr6);
668c5441932SPravin B Shelar 
669c5441932SPravin B Shelar 			if (addr_type == IPV6_ADDR_ANY) {
670c5441932SPravin B Shelar 				addr6 = &ipv6_hdr(skb)->daddr;
671c5441932SPravin B Shelar 				addr_type = ipv6_addr_type(addr6);
672c5441932SPravin B Shelar 			}
673c5441932SPravin B Shelar 
674c5441932SPravin B Shelar 			if ((addr_type & IPV6_ADDR_COMPATv4) == 0)
675c5441932SPravin B Shelar 				do_tx_error_icmp = true;
676c5441932SPravin B Shelar 			else {
677c5441932SPravin B Shelar 				do_tx_error_icmp = false;
678c5441932SPravin B Shelar 				dst = addr6->s6_addr32[3];
679c5441932SPravin B Shelar 			}
680c5441932SPravin B Shelar 			neigh_release(neigh);
681c5441932SPravin B Shelar 			if (do_tx_error_icmp)
682c5441932SPravin B Shelar 				goto tx_error_icmp;
683c5441932SPravin B Shelar 		}
684c5441932SPravin B Shelar #endif
685c5441932SPravin B Shelar 		else
686c5441932SPravin B Shelar 			goto tx_error;
6877d442fabSTom Herbert 
6887d442fabSTom Herbert 		connected = false;
689c5441932SPravin B Shelar 	}
690c5441932SPravin B Shelar 
691c5441932SPravin B Shelar 	tos = tnl_params->tos;
692c5441932SPravin B Shelar 	if (tos & 0x1) {
693c5441932SPravin B Shelar 		tos &= ~0x1;
6947d442fabSTom Herbert 		if (skb->protocol == htons(ETH_P_IP)) {
695c5441932SPravin B Shelar 			tos = inner_iph->tos;
6967d442fabSTom Herbert 			connected = false;
6977d442fabSTom Herbert 		} else if (skb->protocol == htons(ETH_P_IPV6)) {
698c5441932SPravin B Shelar 			tos = ipv6_get_dsfield((const struct ipv6hdr *)inner_iph);
6997d442fabSTom Herbert 			connected = false;
7007d442fabSTom Herbert 		}
701c5441932SPravin B Shelar 	}
702c5441932SPravin B Shelar 
7037d442fabSTom Herbert 	init_tunnel_flow(&fl4, protocol, dst, tnl_params->saddr,
7047d442fabSTom Herbert 			 tunnel->parms.o_key, RT_TOS(tos), tunnel->parms.link);
7057d442fabSTom Herbert 
70656328486STom Herbert 	if (ip_tunnel_encap(skb, tunnel, &protocol, &fl4) < 0)
70756328486STom Herbert 		goto tx_error;
70856328486STom Herbert 
70995cb5745SDmitry Popov 	rt = connected ? tunnel_rtable_get(tunnel, 0, &fl4.saddr) : NULL;
7107d442fabSTom Herbert 
7117d442fabSTom Herbert 	if (!rt) {
7127d442fabSTom Herbert 		rt = ip_route_output_key(tunnel->net, &fl4);
7137d442fabSTom Herbert 
714c5441932SPravin B Shelar 		if (IS_ERR(rt)) {
715c5441932SPravin B Shelar 			dev->stats.tx_carrier_errors++;
716c5441932SPravin B Shelar 			goto tx_error;
717c5441932SPravin B Shelar 		}
7187d442fabSTom Herbert 		if (connected)
71995cb5745SDmitry Popov 			tunnel_dst_set(tunnel, &rt->dst, fl4.saddr);
7207d442fabSTom Herbert 	}
7217d442fabSTom Herbert 
7220e6fbc5bSPravin B Shelar 	if (rt->dst.dev == dev) {
723c5441932SPravin B Shelar 		ip_rt_put(rt);
724c5441932SPravin B Shelar 		dev->stats.collisions++;
725c5441932SPravin B Shelar 		goto tx_error;
726c5441932SPravin B Shelar 	}
727c5441932SPravin B Shelar 
72823a3647bSPravin B Shelar 	if (tnl_update_pmtu(dev, skb, rt, tnl_params->frag_off)) {
729c5441932SPravin B Shelar 		ip_rt_put(rt);
730c5441932SPravin B Shelar 		goto tx_error;
731c5441932SPravin B Shelar 	}
732c5441932SPravin B Shelar 
733c5441932SPravin B Shelar 	if (tunnel->err_count > 0) {
734c5441932SPravin B Shelar 		if (time_before(jiffies,
735c5441932SPravin B Shelar 				tunnel->err_time + IPTUNNEL_ERR_TIMEO)) {
736c5441932SPravin B Shelar 			tunnel->err_count--;
737c5441932SPravin B Shelar 
73811c21a30SDuan Jiong 			memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
739c5441932SPravin B Shelar 			dst_link_failure(skb);
740c5441932SPravin B Shelar 		} else
741c5441932SPravin B Shelar 			tunnel->err_count = 0;
742c5441932SPravin B Shelar 	}
743c5441932SPravin B Shelar 
744d4a71b15SPravin B Shelar 	tos = ip_tunnel_ecn_encap(tos, inner_iph, skb);
745c5441932SPravin B Shelar 	ttl = tnl_params->ttl;
746c5441932SPravin B Shelar 	if (ttl == 0) {
747c5441932SPravin B Shelar 		if (skb->protocol == htons(ETH_P_IP))
748c5441932SPravin B Shelar 			ttl = inner_iph->ttl;
749c5441932SPravin B Shelar #if IS_ENABLED(CONFIG_IPV6)
750c5441932SPravin B Shelar 		else if (skb->protocol == htons(ETH_P_IPV6))
751c5441932SPravin B Shelar 			ttl = ((const struct ipv6hdr *)inner_iph)->hop_limit;
752c5441932SPravin B Shelar #endif
753c5441932SPravin B Shelar 		else
754c5441932SPravin B Shelar 			ttl = ip4_dst_hoplimit(&rt->dst);
755c5441932SPravin B Shelar 	}
756c5441932SPravin B Shelar 
75723a3647bSPravin B Shelar 	df = tnl_params->frag_off;
75823a3647bSPravin B Shelar 	if (skb->protocol == htons(ETH_P_IP))
75923a3647bSPravin B Shelar 		df |= (inner_iph->frag_off&htons(IP_DF));
76023a3647bSPravin B Shelar 
7610e6fbc5bSPravin B Shelar 	max_headroom = LL_RESERVED_SPACE(rt->dst.dev) + sizeof(struct iphdr)
762*7371e022STom Herbert 			+ rt->dst.header_len + ip_encap_hlen(&tunnel->encap);
7633e08f4a7SSteffen Klassert 	if (max_headroom > dev->needed_headroom)
764c5441932SPravin B Shelar 		dev->needed_headroom = max_headroom;
7653e08f4a7SSteffen Klassert 
766c5441932SPravin B Shelar 	if (skb_cow_head(skb, dev->needed_headroom)) {
767586d5fc8SDmitry Popov 		ip_rt_put(rt);
768c5441932SPravin B Shelar 		dev->stats.tx_dropped++;
7693acfa1e7SEric Dumazet 		kfree_skb(skb);
770c5441932SPravin B Shelar 		return;
771c5441932SPravin B Shelar 	}
772c5441932SPravin B Shelar 
773aad88724SEric Dumazet 	err = iptunnel_xmit(skb->sk, rt, skb, fl4.saddr, fl4.daddr, protocol,
774d4a71b15SPravin B Shelar 			    tos, ttl, df, !net_eq(tunnel->net, dev_net(dev)));
7750e6fbc5bSPravin B Shelar 	iptunnel_xmit_stats(err, &dev->stats, dev->tstats);
776c5441932SPravin B Shelar 
777c5441932SPravin B Shelar 	return;
778c5441932SPravin B Shelar 
779c5441932SPravin B Shelar #if IS_ENABLED(CONFIG_IPV6)
780c5441932SPravin B Shelar tx_error_icmp:
781c5441932SPravin B Shelar 	dst_link_failure(skb);
782c5441932SPravin B Shelar #endif
783c5441932SPravin B Shelar tx_error:
784c5441932SPravin B Shelar 	dev->stats.tx_errors++;
7853acfa1e7SEric Dumazet 	kfree_skb(skb);
786c5441932SPravin B Shelar }
787c5441932SPravin B Shelar EXPORT_SYMBOL_GPL(ip_tunnel_xmit);
788c5441932SPravin B Shelar 
789c5441932SPravin B Shelar static void ip_tunnel_update(struct ip_tunnel_net *itn,
790c5441932SPravin B Shelar 			     struct ip_tunnel *t,
791c5441932SPravin B Shelar 			     struct net_device *dev,
792c5441932SPravin B Shelar 			     struct ip_tunnel_parm *p,
793c5441932SPravin B Shelar 			     bool set_mtu)
794c5441932SPravin B Shelar {
795c5441932SPravin B Shelar 	ip_tunnel_del(t);
796c5441932SPravin B Shelar 	t->parms.iph.saddr = p->iph.saddr;
797c5441932SPravin B Shelar 	t->parms.iph.daddr = p->iph.daddr;
798c5441932SPravin B Shelar 	t->parms.i_key = p->i_key;
799c5441932SPravin B Shelar 	t->parms.o_key = p->o_key;
800c5441932SPravin B Shelar 	if (dev->type != ARPHRD_ETHER) {
801c5441932SPravin B Shelar 		memcpy(dev->dev_addr, &p->iph.saddr, 4);
802c5441932SPravin B Shelar 		memcpy(dev->broadcast, &p->iph.daddr, 4);
803c5441932SPravin B Shelar 	}
804c5441932SPravin B Shelar 	ip_tunnel_add(itn, t);
805c5441932SPravin B Shelar 
806c5441932SPravin B Shelar 	t->parms.iph.ttl = p->iph.ttl;
807c5441932SPravin B Shelar 	t->parms.iph.tos = p->iph.tos;
808c5441932SPravin B Shelar 	t->parms.iph.frag_off = p->iph.frag_off;
809c5441932SPravin B Shelar 
810c5441932SPravin B Shelar 	if (t->parms.link != p->link) {
811c5441932SPravin B Shelar 		int mtu;
812c5441932SPravin B Shelar 
813c5441932SPravin B Shelar 		t->parms.link = p->link;
814c5441932SPravin B Shelar 		mtu = ip_tunnel_bind_dev(dev);
815c5441932SPravin B Shelar 		if (set_mtu)
816c5441932SPravin B Shelar 			dev->mtu = mtu;
817c5441932SPravin B Shelar 	}
818cf71d2bcSNicolas Dichtel 	ip_tunnel_dst_reset_all(t);
819c5441932SPravin B Shelar 	netdev_state_change(dev);
820c5441932SPravin B Shelar }
821c5441932SPravin B Shelar 
822c5441932SPravin B Shelar int ip_tunnel_ioctl(struct net_device *dev, struct ip_tunnel_parm *p, int cmd)
823c5441932SPravin B Shelar {
824c5441932SPravin B Shelar 	int err = 0;
8258c923ce2SNicolas Dichtel 	struct ip_tunnel *t = netdev_priv(dev);
8268c923ce2SNicolas Dichtel 	struct net *net = t->net;
8278c923ce2SNicolas Dichtel 	struct ip_tunnel_net *itn = net_generic(net, t->ip_tnl_net_id);
828c5441932SPravin B Shelar 
829c5441932SPravin B Shelar 	BUG_ON(!itn->fb_tunnel_dev);
830c5441932SPravin B Shelar 	switch (cmd) {
831c5441932SPravin B Shelar 	case SIOCGETTUNNEL:
8328c923ce2SNicolas Dichtel 		if (dev == itn->fb_tunnel_dev) {
833c5441932SPravin B Shelar 			t = ip_tunnel_find(itn, p, itn->fb_tunnel_dev->type);
834c5441932SPravin B Shelar 			if (t == NULL)
835c5441932SPravin B Shelar 				t = netdev_priv(dev);
8368c923ce2SNicolas Dichtel 		}
837c5441932SPravin B Shelar 		memcpy(p, &t->parms, sizeof(*p));
838c5441932SPravin B Shelar 		break;
839c5441932SPravin B Shelar 
840c5441932SPravin B Shelar 	case SIOCADDTUNNEL:
841c5441932SPravin B Shelar 	case SIOCCHGTUNNEL:
842c5441932SPravin B Shelar 		err = -EPERM;
843c5441932SPravin B Shelar 		if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
844c5441932SPravin B Shelar 			goto done;
845c5441932SPravin B Shelar 		if (p->iph.ttl)
846c5441932SPravin B Shelar 			p->iph.frag_off |= htons(IP_DF);
8477c8e6b9cSDmitry Popov 		if (!(p->i_flags & VTI_ISVTI)) {
848c5441932SPravin B Shelar 			if (!(p->i_flags & TUNNEL_KEY))
849c5441932SPravin B Shelar 				p->i_key = 0;
850c5441932SPravin B Shelar 			if (!(p->o_flags & TUNNEL_KEY))
851c5441932SPravin B Shelar 				p->o_key = 0;
8527c8e6b9cSDmitry Popov 		}
853c5441932SPravin B Shelar 
854c5441932SPravin B Shelar 		t = ip_tunnel_find(itn, p, itn->fb_tunnel_dev->type);
855c5441932SPravin B Shelar 
856d61746b2SSteffen Klassert 		if (cmd == SIOCADDTUNNEL) {
857d61746b2SSteffen Klassert 			if (!t) {
858c5441932SPravin B Shelar 				t = ip_tunnel_create(net, itn, p);
859ee30ef4dSDuan Jiong 				err = PTR_ERR_OR_ZERO(t);
8606dd3c9ecSFlorian Westphal 				break;
8616dd3c9ecSFlorian Westphal 			}
862d61746b2SSteffen Klassert 
863d61746b2SSteffen Klassert 			err = -EEXIST;
864d61746b2SSteffen Klassert 			break;
865d61746b2SSteffen Klassert 		}
866c5441932SPravin B Shelar 		if (dev != itn->fb_tunnel_dev && cmd == SIOCCHGTUNNEL) {
867c5441932SPravin B Shelar 			if (t != NULL) {
868c5441932SPravin B Shelar 				if (t->dev != dev) {
869c5441932SPravin B Shelar 					err = -EEXIST;
870c5441932SPravin B Shelar 					break;
871c5441932SPravin B Shelar 				}
872c5441932SPravin B Shelar 			} else {
873c5441932SPravin B Shelar 				unsigned int nflags = 0;
874c5441932SPravin B Shelar 
875c5441932SPravin B Shelar 				if (ipv4_is_multicast(p->iph.daddr))
876c5441932SPravin B Shelar 					nflags = IFF_BROADCAST;
877c5441932SPravin B Shelar 				else if (p->iph.daddr)
878c5441932SPravin B Shelar 					nflags = IFF_POINTOPOINT;
879c5441932SPravin B Shelar 
880c5441932SPravin B Shelar 				if ((dev->flags^nflags)&(IFF_POINTOPOINT|IFF_BROADCAST)) {
881c5441932SPravin B Shelar 					err = -EINVAL;
882c5441932SPravin B Shelar 					break;
883c5441932SPravin B Shelar 				}
884c5441932SPravin B Shelar 
885c5441932SPravin B Shelar 				t = netdev_priv(dev);
886c5441932SPravin B Shelar 			}
887c5441932SPravin B Shelar 		}
888c5441932SPravin B Shelar 
889c5441932SPravin B Shelar 		if (t) {
890c5441932SPravin B Shelar 			err = 0;
891c5441932SPravin B Shelar 			ip_tunnel_update(itn, t, dev, p, true);
8926dd3c9ecSFlorian Westphal 		} else {
8936dd3c9ecSFlorian Westphal 			err = -ENOENT;
8946dd3c9ecSFlorian Westphal 		}
895c5441932SPravin B Shelar 		break;
896c5441932SPravin B Shelar 
897c5441932SPravin B Shelar 	case SIOCDELTUNNEL:
898c5441932SPravin B Shelar 		err = -EPERM;
899c5441932SPravin B Shelar 		if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
900c5441932SPravin B Shelar 			goto done;
901c5441932SPravin B Shelar 
902c5441932SPravin B Shelar 		if (dev == itn->fb_tunnel_dev) {
903c5441932SPravin B Shelar 			err = -ENOENT;
904c5441932SPravin B Shelar 			t = ip_tunnel_find(itn, p, itn->fb_tunnel_dev->type);
905c5441932SPravin B Shelar 			if (t == NULL)
906c5441932SPravin B Shelar 				goto done;
907c5441932SPravin B Shelar 			err = -EPERM;
908c5441932SPravin B Shelar 			if (t == netdev_priv(itn->fb_tunnel_dev))
909c5441932SPravin B Shelar 				goto done;
910c5441932SPravin B Shelar 			dev = t->dev;
911c5441932SPravin B Shelar 		}
912c5441932SPravin B Shelar 		unregister_netdevice(dev);
913c5441932SPravin B Shelar 		err = 0;
914c5441932SPravin B Shelar 		break;
915c5441932SPravin B Shelar 
916c5441932SPravin B Shelar 	default:
917c5441932SPravin B Shelar 		err = -EINVAL;
918c5441932SPravin B Shelar 	}
919c5441932SPravin B Shelar 
920c5441932SPravin B Shelar done:
921c5441932SPravin B Shelar 	return err;
922c5441932SPravin B Shelar }
923c5441932SPravin B Shelar EXPORT_SYMBOL_GPL(ip_tunnel_ioctl);
924c5441932SPravin B Shelar 
925c5441932SPravin B Shelar int ip_tunnel_change_mtu(struct net_device *dev, int new_mtu)
926c5441932SPravin B Shelar {
927c5441932SPravin B Shelar 	struct ip_tunnel *tunnel = netdev_priv(dev);
928c5441932SPravin B Shelar 	int t_hlen = tunnel->hlen + sizeof(struct iphdr);
929c5441932SPravin B Shelar 
930c5441932SPravin B Shelar 	if (new_mtu < 68 ||
931c5441932SPravin B Shelar 	    new_mtu > 0xFFF8 - dev->hard_header_len - t_hlen)
932c5441932SPravin B Shelar 		return -EINVAL;
933c5441932SPravin B Shelar 	dev->mtu = new_mtu;
934c5441932SPravin B Shelar 	return 0;
935c5441932SPravin B Shelar }
936c5441932SPravin B Shelar EXPORT_SYMBOL_GPL(ip_tunnel_change_mtu);
937c5441932SPravin B Shelar 
938c5441932SPravin B Shelar static void ip_tunnel_dev_free(struct net_device *dev)
939c5441932SPravin B Shelar {
940c5441932SPravin B Shelar 	struct ip_tunnel *tunnel = netdev_priv(dev);
941c5441932SPravin B Shelar 
942c5441932SPravin B Shelar 	gro_cells_destroy(&tunnel->gro_cells);
9439a4aa9afSTom Herbert 	free_percpu(tunnel->dst_cache);
944c5441932SPravin B Shelar 	free_percpu(dev->tstats);
945c5441932SPravin B Shelar 	free_netdev(dev);
946c5441932SPravin B Shelar }
947c5441932SPravin B Shelar 
948c5441932SPravin B Shelar void ip_tunnel_dellink(struct net_device *dev, struct list_head *head)
949c5441932SPravin B Shelar {
950c5441932SPravin B Shelar 	struct ip_tunnel *tunnel = netdev_priv(dev);
951c5441932SPravin B Shelar 	struct ip_tunnel_net *itn;
952c5441932SPravin B Shelar 
9536c742e71SNicolas Dichtel 	itn = net_generic(tunnel->net, tunnel->ip_tnl_net_id);
954c5441932SPravin B Shelar 
955c5441932SPravin B Shelar 	if (itn->fb_tunnel_dev != dev) {
956c5441932SPravin B Shelar 		ip_tunnel_del(netdev_priv(dev));
957c5441932SPravin B Shelar 		unregister_netdevice_queue(dev, head);
958c5441932SPravin B Shelar 	}
959c5441932SPravin B Shelar }
960c5441932SPravin B Shelar EXPORT_SYMBOL_GPL(ip_tunnel_dellink);
961c5441932SPravin B Shelar 
962d3b6f614SEric Dumazet int ip_tunnel_init_net(struct net *net, int ip_tnl_net_id,
963c5441932SPravin B Shelar 				  struct rtnl_link_ops *ops, char *devname)
964c5441932SPravin B Shelar {
965c5441932SPravin B Shelar 	struct ip_tunnel_net *itn = net_generic(net, ip_tnl_net_id);
966c5441932SPravin B Shelar 	struct ip_tunnel_parm parms;
9676261d983Sstephen hemminger 	unsigned int i;
968c5441932SPravin B Shelar 
9696261d983Sstephen hemminger 	for (i = 0; i < IP_TNL_HASH_SIZE; i++)
9706261d983Sstephen hemminger 		INIT_HLIST_HEAD(&itn->tunnels[i]);
971c5441932SPravin B Shelar 
972c5441932SPravin B Shelar 	if (!ops) {
973c5441932SPravin B Shelar 		itn->fb_tunnel_dev = NULL;
974c5441932SPravin B Shelar 		return 0;
975c5441932SPravin B Shelar 	}
9766261d983Sstephen hemminger 
977c5441932SPravin B Shelar 	memset(&parms, 0, sizeof(parms));
978c5441932SPravin B Shelar 	if (devname)
979c5441932SPravin B Shelar 		strlcpy(parms.name, devname, IFNAMSIZ);
980c5441932SPravin B Shelar 
981c5441932SPravin B Shelar 	rtnl_lock();
982c5441932SPravin B Shelar 	itn->fb_tunnel_dev = __ip_tunnel_create(net, ops, &parms);
983ea857f28SDan Carpenter 	/* FB netdevice is special: we have one, and only one per netns.
984ea857f28SDan Carpenter 	 * Allowing to move it to another netns is clearly unsafe.
985ea857f28SDan Carpenter 	 */
98667013282SSteffen Klassert 	if (!IS_ERR(itn->fb_tunnel_dev)) {
987ea857f28SDan Carpenter 		itn->fb_tunnel_dev->features |= NETIF_F_NETNS_LOCAL;
98878ff4be4SSteffen Klassert 		itn->fb_tunnel_dev->mtu = ip_tunnel_bind_dev(itn->fb_tunnel_dev);
98967013282SSteffen Klassert 		ip_tunnel_add(itn, netdev_priv(itn->fb_tunnel_dev));
99067013282SSteffen Klassert 	}
991b4de77adSDan Carpenter 	rtnl_unlock();
992c5441932SPravin B Shelar 
99327d79f3bSSachin Kamat 	return PTR_ERR_OR_ZERO(itn->fb_tunnel_dev);
994c5441932SPravin B Shelar }
995c5441932SPravin B Shelar EXPORT_SYMBOL_GPL(ip_tunnel_init_net);
996c5441932SPravin B Shelar 
9976c742e71SNicolas Dichtel static void ip_tunnel_destroy(struct ip_tunnel_net *itn, struct list_head *head,
9986c742e71SNicolas Dichtel 			      struct rtnl_link_ops *ops)
999c5441932SPravin B Shelar {
10006c742e71SNicolas Dichtel 	struct net *net = dev_net(itn->fb_tunnel_dev);
10016c742e71SNicolas Dichtel 	struct net_device *dev, *aux;
1002c5441932SPravin B Shelar 	int h;
1003c5441932SPravin B Shelar 
10046c742e71SNicolas Dichtel 	for_each_netdev_safe(net, dev, aux)
10056c742e71SNicolas Dichtel 		if (dev->rtnl_link_ops == ops)
10066c742e71SNicolas Dichtel 			unregister_netdevice_queue(dev, head);
10076c742e71SNicolas Dichtel 
1008c5441932SPravin B Shelar 	for (h = 0; h < IP_TNL_HASH_SIZE; h++) {
1009c5441932SPravin B Shelar 		struct ip_tunnel *t;
1010c5441932SPravin B Shelar 		struct hlist_node *n;
1011c5441932SPravin B Shelar 		struct hlist_head *thead = &itn->tunnels[h];
1012c5441932SPravin B Shelar 
1013c5441932SPravin B Shelar 		hlist_for_each_entry_safe(t, n, thead, hash_node)
10146c742e71SNicolas Dichtel 			/* If dev is in the same netns, it has already
10156c742e71SNicolas Dichtel 			 * been added to the list by the previous loop.
10166c742e71SNicolas Dichtel 			 */
10176c742e71SNicolas Dichtel 			if (!net_eq(dev_net(t->dev), net))
1018c5441932SPravin B Shelar 				unregister_netdevice_queue(t->dev, head);
1019c5441932SPravin B Shelar 	}
1020c5441932SPravin B Shelar }
1021c5441932SPravin B Shelar 
10226c742e71SNicolas Dichtel void ip_tunnel_delete_net(struct ip_tunnel_net *itn, struct rtnl_link_ops *ops)
1023c5441932SPravin B Shelar {
1024c5441932SPravin B Shelar 	LIST_HEAD(list);
1025c5441932SPravin B Shelar 
1026c5441932SPravin B Shelar 	rtnl_lock();
10276c742e71SNicolas Dichtel 	ip_tunnel_destroy(itn, &list, ops);
1028c5441932SPravin B Shelar 	unregister_netdevice_many(&list);
1029c5441932SPravin B Shelar 	rtnl_unlock();
1030c5441932SPravin B Shelar }
1031c5441932SPravin B Shelar EXPORT_SYMBOL_GPL(ip_tunnel_delete_net);
1032c5441932SPravin B Shelar 
1033c5441932SPravin B Shelar int ip_tunnel_newlink(struct net_device *dev, struct nlattr *tb[],
1034c5441932SPravin B Shelar 		      struct ip_tunnel_parm *p)
1035c5441932SPravin B Shelar {
1036c5441932SPravin B Shelar 	struct ip_tunnel *nt;
1037c5441932SPravin B Shelar 	struct net *net = dev_net(dev);
1038c5441932SPravin B Shelar 	struct ip_tunnel_net *itn;
1039c5441932SPravin B Shelar 	int mtu;
1040c5441932SPravin B Shelar 	int err;
1041c5441932SPravin B Shelar 
1042c5441932SPravin B Shelar 	nt = netdev_priv(dev);
1043c5441932SPravin B Shelar 	itn = net_generic(net, nt->ip_tnl_net_id);
1044c5441932SPravin B Shelar 
1045c5441932SPravin B Shelar 	if (ip_tunnel_find(itn, p, dev->type))
1046c5441932SPravin B Shelar 		return -EEXIST;
1047c5441932SPravin B Shelar 
10485e6700b3SNicolas Dichtel 	nt->net = net;
1049c5441932SPravin B Shelar 	nt->parms = *p;
1050c5441932SPravin B Shelar 	err = register_netdevice(dev);
1051c5441932SPravin B Shelar 	if (err)
1052c5441932SPravin B Shelar 		goto out;
1053c5441932SPravin B Shelar 
1054c5441932SPravin B Shelar 	if (dev->type == ARPHRD_ETHER && !tb[IFLA_ADDRESS])
1055c5441932SPravin B Shelar 		eth_hw_addr_random(dev);
1056c5441932SPravin B Shelar 
1057c5441932SPravin B Shelar 	mtu = ip_tunnel_bind_dev(dev);
1058c5441932SPravin B Shelar 	if (!tb[IFLA_MTU])
1059c5441932SPravin B Shelar 		dev->mtu = mtu;
1060c5441932SPravin B Shelar 
1061c5441932SPravin B Shelar 	ip_tunnel_add(itn, nt);
1062c5441932SPravin B Shelar 
1063c5441932SPravin B Shelar out:
1064c5441932SPravin B Shelar 	return err;
1065c5441932SPravin B Shelar }
1066c5441932SPravin B Shelar EXPORT_SYMBOL_GPL(ip_tunnel_newlink);
1067c5441932SPravin B Shelar 
1068c5441932SPravin B Shelar int ip_tunnel_changelink(struct net_device *dev, struct nlattr *tb[],
1069c5441932SPravin B Shelar 			 struct ip_tunnel_parm *p)
1070c5441932SPravin B Shelar {
10716c742e71SNicolas Dichtel 	struct ip_tunnel *t;
1072c5441932SPravin B Shelar 	struct ip_tunnel *tunnel = netdev_priv(dev);
10736c742e71SNicolas Dichtel 	struct net *net = tunnel->net;
1074c5441932SPravin B Shelar 	struct ip_tunnel_net *itn = net_generic(net, tunnel->ip_tnl_net_id);
1075c5441932SPravin B Shelar 
1076c5441932SPravin B Shelar 	if (dev == itn->fb_tunnel_dev)
1077c5441932SPravin B Shelar 		return -EINVAL;
1078c5441932SPravin B Shelar 
1079c5441932SPravin B Shelar 	t = ip_tunnel_find(itn, p, dev->type);
1080c5441932SPravin B Shelar 
1081c5441932SPravin B Shelar 	if (t) {
1082c5441932SPravin B Shelar 		if (t->dev != dev)
1083c5441932SPravin B Shelar 			return -EEXIST;
1084c5441932SPravin B Shelar 	} else {
10856c742e71SNicolas Dichtel 		t = tunnel;
1086c5441932SPravin B Shelar 
1087c5441932SPravin B Shelar 		if (dev->type != ARPHRD_ETHER) {
1088c5441932SPravin B Shelar 			unsigned int nflags = 0;
1089c5441932SPravin B Shelar 
1090c5441932SPravin B Shelar 			if (ipv4_is_multicast(p->iph.daddr))
1091c5441932SPravin B Shelar 				nflags = IFF_BROADCAST;
1092c5441932SPravin B Shelar 			else if (p->iph.daddr)
1093c5441932SPravin B Shelar 				nflags = IFF_POINTOPOINT;
1094c5441932SPravin B Shelar 
1095c5441932SPravin B Shelar 			if ((dev->flags ^ nflags) &
1096c5441932SPravin B Shelar 			    (IFF_POINTOPOINT | IFF_BROADCAST))
1097c5441932SPravin B Shelar 				return -EINVAL;
1098c5441932SPravin B Shelar 		}
1099c5441932SPravin B Shelar 	}
1100c5441932SPravin B Shelar 
1101c5441932SPravin B Shelar 	ip_tunnel_update(itn, t, dev, p, !tb[IFLA_MTU]);
1102c5441932SPravin B Shelar 	return 0;
1103c5441932SPravin B Shelar }
1104c5441932SPravin B Shelar EXPORT_SYMBOL_GPL(ip_tunnel_changelink);
1105c5441932SPravin B Shelar 
1106c5441932SPravin B Shelar int ip_tunnel_init(struct net_device *dev)
1107c5441932SPravin B Shelar {
1108c5441932SPravin B Shelar 	struct ip_tunnel *tunnel = netdev_priv(dev);
1109c5441932SPravin B Shelar 	struct iphdr *iph = &tunnel->parms.iph;
11101c213bd2SWANG Cong 	int err;
1111c5441932SPravin B Shelar 
1112c5441932SPravin B Shelar 	dev->destructor	= ip_tunnel_dev_free;
11131c213bd2SWANG Cong 	dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
1114c5441932SPravin B Shelar 	if (!dev->tstats)
1115c5441932SPravin B Shelar 		return -ENOMEM;
1116c5441932SPravin B Shelar 
11179a4aa9afSTom Herbert 	tunnel->dst_cache = alloc_percpu(struct ip_tunnel_dst);
11189a4aa9afSTom Herbert 	if (!tunnel->dst_cache) {
11199a4aa9afSTom Herbert 		free_percpu(dev->tstats);
11209a4aa9afSTom Herbert 		return -ENOMEM;
11219a4aa9afSTom Herbert 	}
11229a4aa9afSTom Herbert 
1123c5441932SPravin B Shelar 	err = gro_cells_init(&tunnel->gro_cells, dev);
1124c5441932SPravin B Shelar 	if (err) {
11259a4aa9afSTom Herbert 		free_percpu(tunnel->dst_cache);
1126c5441932SPravin B Shelar 		free_percpu(dev->tstats);
1127c5441932SPravin B Shelar 		return err;
1128c5441932SPravin B Shelar 	}
1129c5441932SPravin B Shelar 
1130c5441932SPravin B Shelar 	tunnel->dev = dev;
11316c742e71SNicolas Dichtel 	tunnel->net = dev_net(dev);
1132c5441932SPravin B Shelar 	strcpy(tunnel->parms.name, dev->name);
1133c5441932SPravin B Shelar 	iph->version		= 4;
1134c5441932SPravin B Shelar 	iph->ihl		= 5;
1135c5441932SPravin B Shelar 
1136c5441932SPravin B Shelar 	return 0;
1137c5441932SPravin B Shelar }
1138c5441932SPravin B Shelar EXPORT_SYMBOL_GPL(ip_tunnel_init);
1139c5441932SPravin B Shelar 
1140c5441932SPravin B Shelar void ip_tunnel_uninit(struct net_device *dev)
1141c5441932SPravin B Shelar {
1142c5441932SPravin B Shelar 	struct ip_tunnel *tunnel = netdev_priv(dev);
11436c742e71SNicolas Dichtel 	struct net *net = tunnel->net;
1144c5441932SPravin B Shelar 	struct ip_tunnel_net *itn;
1145c5441932SPravin B Shelar 
1146c5441932SPravin B Shelar 	itn = net_generic(net, tunnel->ip_tnl_net_id);
1147c5441932SPravin B Shelar 	/* fb_tunnel_dev will be unregisted in net-exit call. */
1148c5441932SPravin B Shelar 	if (itn->fb_tunnel_dev != dev)
1149c5441932SPravin B Shelar 		ip_tunnel_del(netdev_priv(dev));
11507d442fabSTom Herbert 
1151cf71d2bcSNicolas Dichtel 	ip_tunnel_dst_reset_all(tunnel);
1152c5441932SPravin B Shelar }
1153c5441932SPravin B Shelar EXPORT_SYMBOL_GPL(ip_tunnel_uninit);
1154c5441932SPravin B Shelar 
1155c5441932SPravin B Shelar /* Do least required initialization, rest of init is done in tunnel_init call */
1156c5441932SPravin B Shelar void ip_tunnel_setup(struct net_device *dev, int net_id)
1157c5441932SPravin B Shelar {
1158c5441932SPravin B Shelar 	struct ip_tunnel *tunnel = netdev_priv(dev);
1159c5441932SPravin B Shelar 	tunnel->ip_tnl_net_id = net_id;
1160c5441932SPravin B Shelar }
1161c5441932SPravin B Shelar EXPORT_SYMBOL_GPL(ip_tunnel_setup);
1162c5441932SPravin B Shelar 
1163c5441932SPravin B Shelar MODULE_LICENSE("GPL");
1164