xref: /linux/net/ipv4/ip_tunnel.c (revision 227adfb2b1dfbc53dfc53b9dd7a93a6298ff7c56)
1c9422999SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2c5441932SPravin B Shelar /*
3c5441932SPravin B Shelar  * Copyright (c) 2013 Nicira, Inc.
4c5441932SPravin B Shelar  */
5c5441932SPravin B Shelar 
6c5441932SPravin B Shelar #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
7c5441932SPravin B Shelar 
8c5441932SPravin B Shelar #include <linux/capability.h>
9c5441932SPravin B Shelar #include <linux/module.h>
10c5441932SPravin B Shelar #include <linux/types.h>
11c5441932SPravin B Shelar #include <linux/kernel.h>
12c5441932SPravin B Shelar #include <linux/slab.h>
13c5441932SPravin B Shelar #include <linux/uaccess.h>
14c5441932SPravin B Shelar #include <linux/skbuff.h>
15c5441932SPravin B Shelar #include <linux/netdevice.h>
16c5441932SPravin B Shelar #include <linux/in.h>
17c5441932SPravin B Shelar #include <linux/tcp.h>
18c5441932SPravin B Shelar #include <linux/udp.h>
19c5441932SPravin B Shelar #include <linux/if_arp.h>
20c5441932SPravin B Shelar #include <linux/init.h>
21c5441932SPravin B Shelar #include <linux/in6.h>
22c5441932SPravin B Shelar #include <linux/inetdevice.h>
23c5441932SPravin B Shelar #include <linux/igmp.h>
24c5441932SPravin B Shelar #include <linux/netfilter_ipv4.h>
25c5441932SPravin B Shelar #include <linux/etherdevice.h>
26c5441932SPravin B Shelar #include <linux/if_ether.h>
27c5441932SPravin B Shelar #include <linux/if_vlan.h>
28c5441932SPravin B Shelar #include <linux/rculist.h>
2927d79f3bSSachin Kamat #include <linux/err.h>
30c5441932SPravin B Shelar 
31c5441932SPravin B Shelar #include <net/sock.h>
32c5441932SPravin B Shelar #include <net/ip.h>
33c5441932SPravin B Shelar #include <net/icmp.h>
34c5441932SPravin B Shelar #include <net/protocol.h>
35c5441932SPravin B Shelar #include <net/ip_tunnels.h>
36c5441932SPravin B Shelar #include <net/arp.h>
37c5441932SPravin B Shelar #include <net/checksum.h>
38c5441932SPravin B Shelar #include <net/dsfield.h>
39c5441932SPravin B Shelar #include <net/inet_ecn.h>
40c5441932SPravin B Shelar #include <net/xfrm.h>
41c5441932SPravin B Shelar #include <net/net_namespace.h>
42c5441932SPravin B Shelar #include <net/netns/generic.h>
43c5441932SPravin B Shelar #include <net/rtnetlink.h>
4456328486STom Herbert #include <net/udp.h>
45cfc7381bSAlexei Starovoitov #include <net/dst_metadata.h>
4663487babSTom Herbert 
47c5441932SPravin B Shelar #if IS_ENABLED(CONFIG_IPV6)
48c5441932SPravin B Shelar #include <net/ipv6.h>
49c5441932SPravin B Shelar #include <net/ip6_fib.h>
50c5441932SPravin B Shelar #include <net/ip6_route.h>
51c5441932SPravin B Shelar #endif
52c5441932SPravin B Shelar 
53967680e0SDuan Jiong static unsigned int ip_tunnel_hash(__be32 key, __be32 remote)
54c5441932SPravin B Shelar {
55c5441932SPravin B Shelar 	return hash_32((__force u32)key ^ (__force u32)remote,
56c5441932SPravin B Shelar 			 IP_TNL_HASH_BITS);
57c5441932SPravin B Shelar }
58c5441932SPravin B Shelar 
59c5441932SPravin B Shelar static bool ip_tunnel_key_match(const struct ip_tunnel_parm *p,
60c5441932SPravin B Shelar 				__be16 flags, __be32 key)
61c5441932SPravin B Shelar {
62c5441932SPravin B Shelar 	if (p->i_flags & TUNNEL_KEY) {
63c5441932SPravin B Shelar 		if (flags & TUNNEL_KEY)
64c5441932SPravin B Shelar 			return key == p->i_key;
65c5441932SPravin B Shelar 		else
66c5441932SPravin B Shelar 			/* key expected, none present */
67c5441932SPravin B Shelar 			return false;
68c5441932SPravin B Shelar 	} else
69c5441932SPravin B Shelar 		return !(flags & TUNNEL_KEY);
70c5441932SPravin B Shelar }
71c5441932SPravin B Shelar 
72c5441932SPravin B Shelar /* Fallback tunnel: no source, no destination, no key, no options
73c5441932SPravin B Shelar 
74c5441932SPravin B Shelar    Tunnel hash table:
75c5441932SPravin B Shelar    We require exact key match i.e. if a key is present in packet
76c5441932SPravin B Shelar    it will match only tunnel with the same key; if it is not present,
77c5441932SPravin B Shelar    it will match only keyless tunnel.
78c5441932SPravin B Shelar 
79c5441932SPravin B Shelar    All keysless packets, if not matched configured keyless tunnels
80c5441932SPravin B Shelar    will match fallback tunnel.
81c5441932SPravin B Shelar    Given src, dst and key, find appropriate for input tunnel.
82c5441932SPravin B Shelar */
83c5441932SPravin B Shelar struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn,
84c5441932SPravin B Shelar 				   int link, __be16 flags,
85c5441932SPravin B Shelar 				   __be32 remote, __be32 local,
86c5441932SPravin B Shelar 				   __be32 key)
87c5441932SPravin B Shelar {
88c5441932SPravin B Shelar 	struct ip_tunnel *t, *cand = NULL;
89c5441932SPravin B Shelar 	struct hlist_head *head;
90ba61539cSTaehee Yoo 	struct net_device *ndev;
91ba61539cSTaehee Yoo 	unsigned int hash;
92c5441932SPravin B Shelar 
93967680e0SDuan Jiong 	hash = ip_tunnel_hash(key, remote);
94c5441932SPravin B Shelar 	head = &itn->tunnels[hash];
95c5441932SPravin B Shelar 
96c5441932SPravin B Shelar 	hlist_for_each_entry_rcu(t, head, hash_node) {
97c5441932SPravin B Shelar 		if (local != t->parms.iph.saddr ||
98c5441932SPravin B Shelar 		    remote != t->parms.iph.daddr ||
99c5441932SPravin B Shelar 		    !(t->dev->flags & IFF_UP))
100c5441932SPravin B Shelar 			continue;
101c5441932SPravin B Shelar 
102c5441932SPravin B Shelar 		if (!ip_tunnel_key_match(&t->parms, flags, key))
103c5441932SPravin B Shelar 			continue;
104c5441932SPravin B Shelar 
105c5441932SPravin B Shelar 		if (t->parms.link == link)
106c5441932SPravin B Shelar 			return t;
107c5441932SPravin B Shelar 		else
108c5441932SPravin B Shelar 			cand = t;
109c5441932SPravin B Shelar 	}
110c5441932SPravin B Shelar 
111c5441932SPravin B Shelar 	hlist_for_each_entry_rcu(t, head, hash_node) {
112c5441932SPravin B Shelar 		if (remote != t->parms.iph.daddr ||
113e0056593SDmitry Popov 		    t->parms.iph.saddr != 0 ||
114c5441932SPravin B Shelar 		    !(t->dev->flags & IFF_UP))
115c5441932SPravin B Shelar 			continue;
116c5441932SPravin B Shelar 
117c5441932SPravin B Shelar 		if (!ip_tunnel_key_match(&t->parms, flags, key))
118c5441932SPravin B Shelar 			continue;
119c5441932SPravin B Shelar 
120c5441932SPravin B Shelar 		if (t->parms.link == link)
121c5441932SPravin B Shelar 			return t;
122c5441932SPravin B Shelar 		else if (!cand)
123c5441932SPravin B Shelar 			cand = t;
124c5441932SPravin B Shelar 	}
125c5441932SPravin B Shelar 
126967680e0SDuan Jiong 	hash = ip_tunnel_hash(key, 0);
127c5441932SPravin B Shelar 	head = &itn->tunnels[hash];
128c5441932SPravin B Shelar 
129c5441932SPravin B Shelar 	hlist_for_each_entry_rcu(t, head, hash_node) {
130e0056593SDmitry Popov 		if ((local != t->parms.iph.saddr || t->parms.iph.daddr != 0) &&
131e0056593SDmitry Popov 		    (local != t->parms.iph.daddr || !ipv4_is_multicast(local)))
132e0056593SDmitry Popov 			continue;
133e0056593SDmitry Popov 
134e0056593SDmitry Popov 		if (!(t->dev->flags & IFF_UP))
135c5441932SPravin B Shelar 			continue;
136c5441932SPravin B Shelar 
137c5441932SPravin B Shelar 		if (!ip_tunnel_key_match(&t->parms, flags, key))
138c5441932SPravin B Shelar 			continue;
139c5441932SPravin B Shelar 
140c5441932SPravin B Shelar 		if (t->parms.link == link)
141c5441932SPravin B Shelar 			return t;
142c5441932SPravin B Shelar 		else if (!cand)
143c5441932SPravin B Shelar 			cand = t;
144c5441932SPravin B Shelar 	}
145c5441932SPravin B Shelar 
146c5441932SPravin B Shelar 	hlist_for_each_entry_rcu(t, head, hash_node) {
14725629fdaSWilliam Dauchy 		if ((!(flags & TUNNEL_NO_KEY) && t->parms.i_key != key) ||
148e0056593SDmitry Popov 		    t->parms.iph.saddr != 0 ||
149e0056593SDmitry Popov 		    t->parms.iph.daddr != 0 ||
150c5441932SPravin B Shelar 		    !(t->dev->flags & IFF_UP))
151c5441932SPravin B Shelar 			continue;
152c5441932SPravin B Shelar 
153c5441932SPravin B Shelar 		if (t->parms.link == link)
154c5441932SPravin B Shelar 			return t;
155c5441932SPravin B Shelar 		else if (!cand)
156c5441932SPravin B Shelar 			cand = t;
157c5441932SPravin B Shelar 	}
158c5441932SPravin B Shelar 
159c5441932SPravin B Shelar 	if (cand)
160c5441932SPravin B Shelar 		return cand;
161c5441932SPravin B Shelar 
1622e15ea39SPravin B Shelar 	t = rcu_dereference(itn->collect_md_tun);
163833a8b40SHaishuang Yan 	if (t && t->dev->flags & IFF_UP)
1642e15ea39SPravin B Shelar 		return t;
1652e15ea39SPravin B Shelar 
166ba61539cSTaehee Yoo 	ndev = READ_ONCE(itn->fb_tunnel_dev);
167ba61539cSTaehee Yoo 	if (ndev && ndev->flags & IFF_UP)
168ba61539cSTaehee Yoo 		return netdev_priv(ndev);
169c5441932SPravin B Shelar 
170c5441932SPravin B Shelar 	return NULL;
171c5441932SPravin B Shelar }
172c5441932SPravin B Shelar EXPORT_SYMBOL_GPL(ip_tunnel_lookup);
173c5441932SPravin B Shelar 
174c5441932SPravin B Shelar static struct hlist_head *ip_bucket(struct ip_tunnel_net *itn,
175c5441932SPravin B Shelar 				    struct ip_tunnel_parm *parms)
176c5441932SPravin B Shelar {
177c5441932SPravin B Shelar 	unsigned int h;
178c5441932SPravin B Shelar 	__be32 remote;
1796d608f06SSteffen Klassert 	__be32 i_key = parms->i_key;
180c5441932SPravin B Shelar 
181c5441932SPravin B Shelar 	if (parms->iph.daddr && !ipv4_is_multicast(parms->iph.daddr))
182c5441932SPravin B Shelar 		remote = parms->iph.daddr;
183c5441932SPravin B Shelar 	else
184c5441932SPravin B Shelar 		remote = 0;
185c5441932SPravin B Shelar 
1866d608f06SSteffen Klassert 	if (!(parms->i_flags & TUNNEL_KEY) && (parms->i_flags & VTI_ISVTI))
1876d608f06SSteffen Klassert 		i_key = 0;
1886d608f06SSteffen Klassert 
1896d608f06SSteffen Klassert 	h = ip_tunnel_hash(i_key, remote);
190c5441932SPravin B Shelar 	return &itn->tunnels[h];
191c5441932SPravin B Shelar }
192c5441932SPravin B Shelar 
193c5441932SPravin B Shelar static void ip_tunnel_add(struct ip_tunnel_net *itn, struct ip_tunnel *t)
194c5441932SPravin B Shelar {
195c5441932SPravin B Shelar 	struct hlist_head *head = ip_bucket(itn, &t->parms);
196c5441932SPravin B Shelar 
1972e15ea39SPravin B Shelar 	if (t->collect_md)
1982e15ea39SPravin B Shelar 		rcu_assign_pointer(itn->collect_md_tun, t);
199c5441932SPravin B Shelar 	hlist_add_head_rcu(&t->hash_node, head);
200c5441932SPravin B Shelar }
201c5441932SPravin B Shelar 
2022e15ea39SPravin B Shelar static void ip_tunnel_del(struct ip_tunnel_net *itn, struct ip_tunnel *t)
203c5441932SPravin B Shelar {
2042e15ea39SPravin B Shelar 	if (t->collect_md)
2052e15ea39SPravin B Shelar 		rcu_assign_pointer(itn->collect_md_tun, NULL);
206c5441932SPravin B Shelar 	hlist_del_init_rcu(&t->hash_node);
207c5441932SPravin B Shelar }
208c5441932SPravin B Shelar 
209c5441932SPravin B Shelar static struct ip_tunnel *ip_tunnel_find(struct ip_tunnel_net *itn,
210c5441932SPravin B Shelar 					struct ip_tunnel_parm *parms,
211c5441932SPravin B Shelar 					int type)
212c5441932SPravin B Shelar {
213c5441932SPravin B Shelar 	__be32 remote = parms->iph.daddr;
214c5441932SPravin B Shelar 	__be32 local = parms->iph.saddr;
215c5441932SPravin B Shelar 	__be32 key = parms->i_key;
2165ce54af1SDmitry Popov 	__be16 flags = parms->i_flags;
217c5441932SPravin B Shelar 	int link = parms->link;
218c5441932SPravin B Shelar 	struct ip_tunnel *t = NULL;
219c5441932SPravin B Shelar 	struct hlist_head *head = ip_bucket(itn, parms);
220c5441932SPravin B Shelar 
221c5441932SPravin B Shelar 	hlist_for_each_entry_rcu(t, head, hash_node) {
222c5441932SPravin B Shelar 		if (local == t->parms.iph.saddr &&
223c5441932SPravin B Shelar 		    remote == t->parms.iph.daddr &&
224c5441932SPravin B Shelar 		    link == t->parms.link &&
2255ce54af1SDmitry Popov 		    type == t->dev->type &&
2265ce54af1SDmitry Popov 		    ip_tunnel_key_match(&t->parms, flags, key))
227c5441932SPravin B Shelar 			break;
228c5441932SPravin B Shelar 	}
229c5441932SPravin B Shelar 	return t;
230c5441932SPravin B Shelar }
231c5441932SPravin B Shelar 
232c5441932SPravin B Shelar static struct net_device *__ip_tunnel_create(struct net *net,
233c5441932SPravin B Shelar 					     const struct rtnl_link_ops *ops,
234c5441932SPravin B Shelar 					     struct ip_tunnel_parm *parms)
235c5441932SPravin B Shelar {
236c5441932SPravin B Shelar 	int err;
237c5441932SPravin B Shelar 	struct ip_tunnel *tunnel;
238c5441932SPravin B Shelar 	struct net_device *dev;
239c5441932SPravin B Shelar 	char name[IFNAMSIZ];
240c5441932SPravin B Shelar 
241c5441932SPravin B Shelar 	err = -E2BIG;
2429cb726a2SEric Dumazet 	if (parms->name[0]) {
2439cb726a2SEric Dumazet 		if (!dev_valid_name(parms->name))
244c5441932SPravin B Shelar 			goto failed;
2459cb726a2SEric Dumazet 		strlcpy(name, parms->name, IFNAMSIZ);
2469cb726a2SEric Dumazet 	} else {
2479cb726a2SEric Dumazet 		if (strlen(ops->kind) > (IFNAMSIZ - 3))
2489cb726a2SEric Dumazet 			goto failed;
249000ade80SSultan Alsawaf 		strcpy(name, ops->kind);
250000ade80SSultan Alsawaf 		strcat(name, "%d");
251c5441932SPravin B Shelar 	}
252c5441932SPravin B Shelar 
253c5441932SPravin B Shelar 	ASSERT_RTNL();
254c835a677STom Gundersen 	dev = alloc_netdev(ops->priv_size, name, NET_NAME_UNKNOWN, ops->setup);
255c5441932SPravin B Shelar 	if (!dev) {
256c5441932SPravin B Shelar 		err = -ENOMEM;
257c5441932SPravin B Shelar 		goto failed;
258c5441932SPravin B Shelar 	}
259c5441932SPravin B Shelar 	dev_net_set(dev, net);
260c5441932SPravin B Shelar 
261c5441932SPravin B Shelar 	dev->rtnl_link_ops = ops;
262c5441932SPravin B Shelar 
263c5441932SPravin B Shelar 	tunnel = netdev_priv(dev);
264c5441932SPravin B Shelar 	tunnel->parms = *parms;
2655e6700b3SNicolas Dichtel 	tunnel->net = net;
266c5441932SPravin B Shelar 
267c5441932SPravin B Shelar 	err = register_netdevice(dev);
268c5441932SPravin B Shelar 	if (err)
269c5441932SPravin B Shelar 		goto failed_free;
270c5441932SPravin B Shelar 
271c5441932SPravin B Shelar 	return dev;
272c5441932SPravin B Shelar 
273c5441932SPravin B Shelar failed_free:
274c5441932SPravin B Shelar 	free_netdev(dev);
275c5441932SPravin B Shelar failed:
276c5441932SPravin B Shelar 	return ERR_PTR(err);
277c5441932SPravin B Shelar }
278c5441932SPravin B Shelar 
279c5441932SPravin B Shelar static int ip_tunnel_bind_dev(struct net_device *dev)
280c5441932SPravin B Shelar {
281c5441932SPravin B Shelar 	struct net_device *tdev = NULL;
282c5441932SPravin B Shelar 	struct ip_tunnel *tunnel = netdev_priv(dev);
283c5441932SPravin B Shelar 	const struct iphdr *iph;
284c5441932SPravin B Shelar 	int hlen = LL_MAX_HEADER;
285c5441932SPravin B Shelar 	int mtu = ETH_DATA_LEN;
286c5441932SPravin B Shelar 	int t_hlen = tunnel->hlen + sizeof(struct iphdr);
287c5441932SPravin B Shelar 
288c5441932SPravin B Shelar 	iph = &tunnel->parms.iph;
289c5441932SPravin B Shelar 
290c5441932SPravin B Shelar 	/* Guess output device to choose reasonable mtu and needed_headroom */
291c5441932SPravin B Shelar 	if (iph->daddr) {
292c5441932SPravin B Shelar 		struct flowi4 fl4;
293c5441932SPravin B Shelar 		struct rtable *rt;
294c5441932SPravin B Shelar 
295b0066da5SPetr Machata 		ip_tunnel_init_flow(&fl4, iph->protocol, iph->daddr,
2967d442fabSTom Herbert 				    iph->saddr, tunnel->parms.o_key,
2979830ad4cSCraig Gallek 				    RT_TOS(iph->tos), tunnel->parms.link,
29824ba1440Swenxu 				    tunnel->fwmark, 0);
2997d442fabSTom Herbert 		rt = ip_route_output_key(tunnel->net, &fl4);
3007d442fabSTom Herbert 
301c5441932SPravin B Shelar 		if (!IS_ERR(rt)) {
302c5441932SPravin B Shelar 			tdev = rt->dst.dev;
303c5441932SPravin B Shelar 			ip_rt_put(rt);
304c5441932SPravin B Shelar 		}
305c5441932SPravin B Shelar 		if (dev->type != ARPHRD_ETHER)
306c5441932SPravin B Shelar 			dev->flags |= IFF_POINTOPOINT;
307f27337e1SPaolo Abeni 
308f27337e1SPaolo Abeni 		dst_cache_reset(&tunnel->dst_cache);
309c5441932SPravin B Shelar 	}
310c5441932SPravin B Shelar 
311c5441932SPravin B Shelar 	if (!tdev && tunnel->parms.link)
3126c742e71SNicolas Dichtel 		tdev = __dev_get_by_index(tunnel->net, tunnel->parms.link);
313c5441932SPravin B Shelar 
314c5441932SPravin B Shelar 	if (tdev) {
315c5441932SPravin B Shelar 		hlen = tdev->hard_header_len + tdev->needed_headroom;
31682612de1SNicolas Dichtel 		mtu = min(tdev->mtu, IP_MAX_MTU);
317c5441932SPravin B Shelar 	}
318c5441932SPravin B Shelar 
319c5441932SPravin B Shelar 	dev->needed_headroom = t_hlen + hlen;
3209992a078SHangbin Liu 	mtu -= t_hlen + (dev->type == ARPHRD_ETHER ? dev->hard_header_len : 0);
321c5441932SPravin B Shelar 
322b5476022SEric Dumazet 	if (mtu < IPV4_MIN_MTU)
323b5476022SEric Dumazet 		mtu = IPV4_MIN_MTU;
324c5441932SPravin B Shelar 
325c5441932SPravin B Shelar 	return mtu;
326c5441932SPravin B Shelar }
327c5441932SPravin B Shelar 
328c5441932SPravin B Shelar static struct ip_tunnel *ip_tunnel_create(struct net *net,
329c5441932SPravin B Shelar 					  struct ip_tunnel_net *itn,
330c5441932SPravin B Shelar 					  struct ip_tunnel_parm *parms)
331c5441932SPravin B Shelar {
3324929fd8cSJulia Lawall 	struct ip_tunnel *nt;
333c5441932SPravin B Shelar 	struct net_device *dev;
334b96f9afeSJarod Wilson 	int t_hlen;
335f6cc9c05SPetr Machata 	int mtu;
336f6cc9c05SPetr Machata 	int err;
337c5441932SPravin B Shelar 
33879134e6cSEric Dumazet 	dev = __ip_tunnel_create(net, itn->rtnl_link_ops, parms);
339c5441932SPravin B Shelar 	if (IS_ERR(dev))
3406dd3c9ecSFlorian Westphal 		return ERR_CAST(dev);
341c5441932SPravin B Shelar 
342f6cc9c05SPetr Machata 	mtu = ip_tunnel_bind_dev(dev);
343f6cc9c05SPetr Machata 	err = dev_set_mtu(dev, mtu);
344f6cc9c05SPetr Machata 	if (err)
345f6cc9c05SPetr Machata 		goto err_dev_set_mtu;
346c5441932SPravin B Shelar 
347c5441932SPravin B Shelar 	nt = netdev_priv(dev);
348b96f9afeSJarod Wilson 	t_hlen = nt->hlen + sizeof(struct iphdr);
349b96f9afeSJarod Wilson 	dev->min_mtu = ETH_MIN_MTU;
35028e104d0SVadim Fedorenko 	dev->max_mtu = IP_MAX_MTU - t_hlen;
3519992a078SHangbin Liu 	if (dev->type == ARPHRD_ETHER)
3529992a078SHangbin Liu 		dev->max_mtu -= dev->hard_header_len;
3539992a078SHangbin Liu 
354c5441932SPravin B Shelar 	ip_tunnel_add(itn, nt);
355c5441932SPravin B Shelar 	return nt;
356f6cc9c05SPetr Machata 
357f6cc9c05SPetr Machata err_dev_set_mtu:
358f6cc9c05SPetr Machata 	unregister_netdevice(dev);
359f6cc9c05SPetr Machata 	return ERR_PTR(err);
360c5441932SPravin B Shelar }
361c5441932SPravin B Shelar 
362c5441932SPravin B Shelar int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb,
3632e15ea39SPravin B Shelar 		  const struct tnl_ptk_info *tpi, struct metadata_dst *tun_dst,
3642e15ea39SPravin B Shelar 		  bool log_ecn_error)
365c5441932SPravin B Shelar {
366c5441932SPravin B Shelar 	const struct iphdr *iph = ip_hdr(skb);
367c5441932SPravin B Shelar 	int err;
368c5441932SPravin B Shelar 
369c5441932SPravin B Shelar #ifdef CONFIG_NET_IPGRE_BROADCAST
370c5441932SPravin B Shelar 	if (ipv4_is_multicast(iph->daddr)) {
371c5441932SPravin B Shelar 		tunnel->dev->stats.multicast++;
372c5441932SPravin B Shelar 		skb->pkt_type = PACKET_BROADCAST;
373c5441932SPravin B Shelar 	}
374c5441932SPravin B Shelar #endif
375c5441932SPravin B Shelar 
376c5441932SPravin B Shelar 	if ((!(tpi->flags&TUNNEL_CSUM) &&  (tunnel->parms.i_flags&TUNNEL_CSUM)) ||
377c5441932SPravin B Shelar 	     ((tpi->flags&TUNNEL_CSUM) && !(tunnel->parms.i_flags&TUNNEL_CSUM))) {
378c5441932SPravin B Shelar 		tunnel->dev->stats.rx_crc_errors++;
379c5441932SPravin B Shelar 		tunnel->dev->stats.rx_errors++;
380c5441932SPravin B Shelar 		goto drop;
381c5441932SPravin B Shelar 	}
382c5441932SPravin B Shelar 
383c5441932SPravin B Shelar 	if (tunnel->parms.i_flags&TUNNEL_SEQ) {
384c5441932SPravin B Shelar 		if (!(tpi->flags&TUNNEL_SEQ) ||
385c5441932SPravin B Shelar 		    (tunnel->i_seqno && (s32)(ntohl(tpi->seq) - tunnel->i_seqno) < 0)) {
386c5441932SPravin B Shelar 			tunnel->dev->stats.rx_fifo_errors++;
387c5441932SPravin B Shelar 			tunnel->dev->stats.rx_errors++;
388c5441932SPravin B Shelar 			goto drop;
389c5441932SPravin B Shelar 		}
390c5441932SPravin B Shelar 		tunnel->i_seqno = ntohl(tpi->seq) + 1;
391c5441932SPravin B Shelar 	}
392c5441932SPravin B Shelar 
393227adfb2SGilad Naaman 	skb_set_network_header(skb, (tunnel->dev->type == ARPHRD_ETHER) ? ETH_HLEN : 0);
394e96f2e7cSYing Cai 
395c5441932SPravin B Shelar 	err = IP_ECN_decapsulate(iph, skb);
396c5441932SPravin B Shelar 	if (unlikely(err)) {
397c5441932SPravin B Shelar 		if (log_ecn_error)
398c5441932SPravin B Shelar 			net_info_ratelimited("non-ECT from %pI4 with TOS=%#x\n",
399c5441932SPravin B Shelar 					&iph->saddr, iph->tos);
400c5441932SPravin B Shelar 		if (err > 1) {
401c5441932SPravin B Shelar 			++tunnel->dev->stats.rx_frame_errors;
402c5441932SPravin B Shelar 			++tunnel->dev->stats.rx_errors;
403c5441932SPravin B Shelar 			goto drop;
404c5441932SPravin B Shelar 		}
405c5441932SPravin B Shelar 	}
406c5441932SPravin B Shelar 
407560b50cfSFabian Frederick 	dev_sw_netstats_rx_add(tunnel->dev, skb->len);
40881b9eab5SAlexei Starovoitov 	skb_scrub_packet(skb, !net_eq(tunnel->net, dev_net(tunnel->dev)));
40981b9eab5SAlexei Starovoitov 
4103d7b46cdSPravin B Shelar 	if (tunnel->dev->type == ARPHRD_ETHER) {
4113d7b46cdSPravin B Shelar 		skb->protocol = eth_type_trans(skb, tunnel->dev);
4123d7b46cdSPravin B Shelar 		skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
4133d7b46cdSPravin B Shelar 	} else {
4143d7b46cdSPravin B Shelar 		skb->dev = tunnel->dev;
4153d7b46cdSPravin B Shelar 	}
41664261f23SNicolas Dichtel 
4172e15ea39SPravin B Shelar 	if (tun_dst)
4182e15ea39SPravin B Shelar 		skb_dst_set(skb, (struct dst_entry *)tun_dst);
4192e15ea39SPravin B Shelar 
420c5441932SPravin B Shelar 	gro_cells_receive(&tunnel->gro_cells, skb);
421c5441932SPravin B Shelar 	return 0;
422c5441932SPravin B Shelar 
423c5441932SPravin B Shelar drop:
424469f87e1SHaishuang Yan 	if (tun_dst)
425469f87e1SHaishuang Yan 		dst_release((struct dst_entry *)tun_dst);
426c5441932SPravin B Shelar 	kfree_skb(skb);
427c5441932SPravin B Shelar 	return 0;
428c5441932SPravin B Shelar }
429c5441932SPravin B Shelar EXPORT_SYMBOL_GPL(ip_tunnel_rcv);
430c5441932SPravin B Shelar 
431a8c5f90fSTom Herbert int ip_tunnel_encap_add_ops(const struct ip_tunnel_encap_ops *ops,
432a8c5f90fSTom Herbert 			    unsigned int num)
433a8c5f90fSTom Herbert {
434bb1553c8SThomas Graf 	if (num >= MAX_IPTUN_ENCAP_OPS)
435bb1553c8SThomas Graf 		return -ERANGE;
436bb1553c8SThomas Graf 
437a8c5f90fSTom Herbert 	return !cmpxchg((const struct ip_tunnel_encap_ops **)
438a8c5f90fSTom Herbert 			&iptun_encaps[num],
439a8c5f90fSTom Herbert 			NULL, ops) ? 0 : -1;
44056328486STom Herbert }
441a8c5f90fSTom Herbert EXPORT_SYMBOL(ip_tunnel_encap_add_ops);
442a8c5f90fSTom Herbert 
443a8c5f90fSTom Herbert int ip_tunnel_encap_del_ops(const struct ip_tunnel_encap_ops *ops,
444a8c5f90fSTom Herbert 			    unsigned int num)
445a8c5f90fSTom Herbert {
446a8c5f90fSTom Herbert 	int ret;
447a8c5f90fSTom Herbert 
448bb1553c8SThomas Graf 	if (num >= MAX_IPTUN_ENCAP_OPS)
449bb1553c8SThomas Graf 		return -ERANGE;
450bb1553c8SThomas Graf 
451a8c5f90fSTom Herbert 	ret = (cmpxchg((const struct ip_tunnel_encap_ops **)
452a8c5f90fSTom Herbert 		       &iptun_encaps[num],
453a8c5f90fSTom Herbert 		       ops, NULL) == ops) ? 0 : -1;
454a8c5f90fSTom Herbert 
455a8c5f90fSTom Herbert 	synchronize_net();
456a8c5f90fSTom Herbert 
457a8c5f90fSTom Herbert 	return ret;
458a8c5f90fSTom Herbert }
459a8c5f90fSTom Herbert EXPORT_SYMBOL(ip_tunnel_encap_del_ops);
46056328486STom Herbert 
46156328486STom Herbert int ip_tunnel_encap_setup(struct ip_tunnel *t,
46256328486STom Herbert 			  struct ip_tunnel_encap *ipencap)
46356328486STom Herbert {
46456328486STom Herbert 	int hlen;
46556328486STom Herbert 
46656328486STom Herbert 	memset(&t->encap, 0, sizeof(t->encap));
46756328486STom Herbert 
46856328486STom Herbert 	hlen = ip_encap_hlen(ipencap);
46956328486STom Herbert 	if (hlen < 0)
47056328486STom Herbert 		return hlen;
47156328486STom Herbert 
47256328486STom Herbert 	t->encap.type = ipencap->type;
47356328486STom Herbert 	t->encap.sport = ipencap->sport;
47456328486STom Herbert 	t->encap.dport = ipencap->dport;
47556328486STom Herbert 	t->encap.flags = ipencap->flags;
47656328486STom Herbert 
47756328486STom Herbert 	t->encap_hlen = hlen;
47856328486STom Herbert 	t->hlen = t->encap_hlen + t->tun_hlen;
47956328486STom Herbert 
48056328486STom Herbert 	return 0;
48156328486STom Herbert }
48256328486STom Herbert EXPORT_SYMBOL_GPL(ip_tunnel_encap_setup);
48356328486STom Herbert 
48423a3647bSPravin B Shelar static int tnl_update_pmtu(struct net_device *dev, struct sk_buff *skb,
485fc24f2b2STimo Teräs 			    struct rtable *rt, __be16 df,
486c8b34e68Swenxu 			    const struct iphdr *inner_iph,
487c8b34e68Swenxu 			    int tunnel_hlen, __be32 dst, bool md)
48823a3647bSPravin B Shelar {
48923a3647bSPravin B Shelar 	struct ip_tunnel *tunnel = netdev_priv(dev);
490c8b34e68Swenxu 	int pkt_size;
49123a3647bSPravin B Shelar 	int mtu;
49223a3647bSPravin B Shelar 
493c8b34e68Swenxu 	tunnel_hlen = md ? tunnel_hlen : tunnel->hlen;
49428e104d0SVadim Fedorenko 	pkt_size = skb->len - tunnel_hlen;
4959992a078SHangbin Liu 	pkt_size -= dev->type == ARPHRD_ETHER ? dev->hard_header_len : 0;
496c8b34e68Swenxu 
4979992a078SHangbin Liu 	if (df) {
49828e104d0SVadim Fedorenko 		mtu = dst_mtu(&rt->dst) - (sizeof(struct iphdr) + tunnel_hlen);
4999992a078SHangbin Liu 		mtu -= dev->type == ARPHRD_ETHER ? dev->hard_header_len : 0;
5009992a078SHangbin Liu 	} else {
501f4b3ec4eSAlan Maguire 		mtu = skb_valid_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu;
5029992a078SHangbin Liu 	}
50323a3647bSPravin B Shelar 
504f4b3ec4eSAlan Maguire 	if (skb_valid_dst(skb))
5057a1592bcSHangbin Liu 		skb_dst_update_pmtu_no_confirm(skb, mtu);
50623a3647bSPravin B Shelar 
50723a3647bSPravin B Shelar 	if (skb->protocol == htons(ETH_P_IP)) {
50823a3647bSPravin B Shelar 		if (!skb_is_gso(skb) &&
509fc24f2b2STimo Teräs 		    (inner_iph->frag_off & htons(IP_DF)) &&
510fc24f2b2STimo Teräs 		    mtu < pkt_size) {
5114372339eSJason A. Donenfeld 			icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));
51223a3647bSPravin B Shelar 			return -E2BIG;
51323a3647bSPravin B Shelar 		}
51423a3647bSPravin B Shelar 	}
51523a3647bSPravin B Shelar #if IS_ENABLED(CONFIG_IPV6)
51623a3647bSPravin B Shelar 	else if (skb->protocol == htons(ETH_P_IPV6)) {
517f4b3ec4eSAlan Maguire 		struct rt6_info *rt6;
518c8b34e68Swenxu 		__be32 daddr;
519c8b34e68Swenxu 
520f4b3ec4eSAlan Maguire 		rt6 = skb_valid_dst(skb) ? (struct rt6_info *)skb_dst(skb) :
521f4b3ec4eSAlan Maguire 					   NULL;
522c8b34e68Swenxu 		daddr = md ? dst : tunnel->parms.iph.daddr;
52323a3647bSPravin B Shelar 
52423a3647bSPravin B Shelar 		if (rt6 && mtu < dst_mtu(skb_dst(skb)) &&
52523a3647bSPravin B Shelar 			   mtu >= IPV6_MIN_MTU) {
526c8b34e68Swenxu 			if ((daddr && !ipv4_is_multicast(daddr)) ||
52723a3647bSPravin B Shelar 			    rt6->rt6i_dst.plen == 128) {
52823a3647bSPravin B Shelar 				rt6->rt6i_flags |= RTF_MODIFIED;
52923a3647bSPravin B Shelar 				dst_metric_set(skb_dst(skb), RTAX_MTU, mtu);
53023a3647bSPravin B Shelar 			}
53123a3647bSPravin B Shelar 		}
53223a3647bSPravin B Shelar 
53323a3647bSPravin B Shelar 		if (!skb_is_gso(skb) && mtu >= IPV6_MIN_MTU &&
53423a3647bSPravin B Shelar 					mtu < pkt_size) {
5354372339eSJason A. Donenfeld 			icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
53623a3647bSPravin B Shelar 			return -E2BIG;
53723a3647bSPravin B Shelar 		}
53823a3647bSPravin B Shelar 	}
53923a3647bSPravin B Shelar #endif
54023a3647bSPravin B Shelar 	return 0;
54123a3647bSPravin B Shelar }
54223a3647bSPravin B Shelar 
543c8b34e68Swenxu void ip_md_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
544c8b34e68Swenxu 		       u8 proto, int tunnel_hlen)
545cfc7381bSAlexei Starovoitov {
546cfc7381bSAlexei Starovoitov 	struct ip_tunnel *tunnel = netdev_priv(dev);
547cfc7381bSAlexei Starovoitov 	u32 headroom = sizeof(struct iphdr);
548cfc7381bSAlexei Starovoitov 	struct ip_tunnel_info *tun_info;
549cfc7381bSAlexei Starovoitov 	const struct ip_tunnel_key *key;
550cfc7381bSAlexei Starovoitov 	const struct iphdr *inner_iph;
551f46fe4f8Swenxu 	struct rtable *rt = NULL;
552cfc7381bSAlexei Starovoitov 	struct flowi4 fl4;
553cfc7381bSAlexei Starovoitov 	__be16 df = 0;
554cfc7381bSAlexei Starovoitov 	u8 tos, ttl;
555f46fe4f8Swenxu 	bool use_cache;
556cfc7381bSAlexei Starovoitov 
557cfc7381bSAlexei Starovoitov 	tun_info = skb_tunnel_info(skb);
558cfc7381bSAlexei Starovoitov 	if (unlikely(!tun_info || !(tun_info->mode & IP_TUNNEL_INFO_TX) ||
559cfc7381bSAlexei Starovoitov 		     ip_tunnel_info_af(tun_info) != AF_INET))
560cfc7381bSAlexei Starovoitov 		goto tx_error;
561cfc7381bSAlexei Starovoitov 	key = &tun_info->key;
562cfc7381bSAlexei Starovoitov 	memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
563cfc7381bSAlexei Starovoitov 	inner_iph = (const struct iphdr *)skb_inner_network_header(skb);
564cfc7381bSAlexei Starovoitov 	tos = key->tos;
565cfc7381bSAlexei Starovoitov 	if (tos == 1) {
566cfc7381bSAlexei Starovoitov 		if (skb->protocol == htons(ETH_P_IP))
567cfc7381bSAlexei Starovoitov 			tos = inner_iph->tos;
568cfc7381bSAlexei Starovoitov 		else if (skb->protocol == htons(ETH_P_IPV6))
569cfc7381bSAlexei Starovoitov 			tos = ipv6_get_dsfield((const struct ipv6hdr *)inner_iph);
570cfc7381bSAlexei Starovoitov 	}
5716e6b904aSwenxu 	ip_tunnel_init_flow(&fl4, proto, key->u.ipv4.dst, key->u.ipv4.src,
5726e6b904aSwenxu 			    tunnel_id_to_key32(key->tun_id), RT_TOS(tos),
57324ba1440Swenxu 			    0, skb->mark, skb_get_hash(skb));
574cfc7381bSAlexei Starovoitov 	if (tunnel->encap.type != TUNNEL_ENCAP_NONE)
575cfc7381bSAlexei Starovoitov 		goto tx_error;
576f46fe4f8Swenxu 
577f46fe4f8Swenxu 	use_cache = ip_tunnel_dst_cache_usable(skb, tun_info);
578f46fe4f8Swenxu 	if (use_cache)
579f46fe4f8Swenxu 		rt = dst_cache_get_ip4(&tun_info->dst_cache, &fl4.saddr);
580f46fe4f8Swenxu 	if (!rt) {
581cfc7381bSAlexei Starovoitov 		rt = ip_route_output_key(tunnel->net, &fl4);
582cfc7381bSAlexei Starovoitov 		if (IS_ERR(rt)) {
583cfc7381bSAlexei Starovoitov 			dev->stats.tx_carrier_errors++;
584cfc7381bSAlexei Starovoitov 			goto tx_error;
585cfc7381bSAlexei Starovoitov 		}
586f46fe4f8Swenxu 		if (use_cache)
587f46fe4f8Swenxu 			dst_cache_set_ip4(&tun_info->dst_cache, &rt->dst,
588f46fe4f8Swenxu 					  fl4.saddr);
589f46fe4f8Swenxu 	}
590cfc7381bSAlexei Starovoitov 	if (rt->dst.dev == dev) {
591cfc7381bSAlexei Starovoitov 		ip_rt_put(rt);
592cfc7381bSAlexei Starovoitov 		dev->stats.collisions++;
593cfc7381bSAlexei Starovoitov 		goto tx_error;
594cfc7381bSAlexei Starovoitov 	}
595c8b34e68Swenxu 
596c8b34e68Swenxu 	if (key->tun_flags & TUNNEL_DONT_FRAGMENT)
597c8b34e68Swenxu 		df = htons(IP_DF);
598c8b34e68Swenxu 	if (tnl_update_pmtu(dev, skb, rt, df, inner_iph, tunnel_hlen,
599c8b34e68Swenxu 			    key->u.ipv4.dst, true)) {
600c8b34e68Swenxu 		ip_rt_put(rt);
601c8b34e68Swenxu 		goto tx_error;
602c8b34e68Swenxu 	}
603c8b34e68Swenxu 
604cfc7381bSAlexei Starovoitov 	tos = ip_tunnel_ecn_encap(tos, inner_iph, skb);
605cfc7381bSAlexei Starovoitov 	ttl = key->ttl;
606cfc7381bSAlexei Starovoitov 	if (ttl == 0) {
607cfc7381bSAlexei Starovoitov 		if (skb->protocol == htons(ETH_P_IP))
608cfc7381bSAlexei Starovoitov 			ttl = inner_iph->ttl;
609cfc7381bSAlexei Starovoitov 		else if (skb->protocol == htons(ETH_P_IPV6))
610cfc7381bSAlexei Starovoitov 			ttl = ((const struct ipv6hdr *)inner_iph)->hop_limit;
611cfc7381bSAlexei Starovoitov 		else
612cfc7381bSAlexei Starovoitov 			ttl = ip4_dst_hoplimit(&rt->dst);
613cfc7381bSAlexei Starovoitov 	}
614c8b34e68Swenxu 
615cfc7381bSAlexei Starovoitov 	headroom += LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len;
616cfc7381bSAlexei Starovoitov 	if (headroom > dev->needed_headroom)
617cfc7381bSAlexei Starovoitov 		dev->needed_headroom = headroom;
618cfc7381bSAlexei Starovoitov 
619cfc7381bSAlexei Starovoitov 	if (skb_cow_head(skb, dev->needed_headroom)) {
620cfc7381bSAlexei Starovoitov 		ip_rt_put(rt);
621cfc7381bSAlexei Starovoitov 		goto tx_dropped;
622cfc7381bSAlexei Starovoitov 	}
6230f693f19SHaishuang Yan 	iptunnel_xmit(NULL, rt, skb, fl4.saddr, fl4.daddr, proto, tos, ttl,
6240f693f19SHaishuang Yan 		      df, !net_eq(tunnel->net, dev_net(dev)));
625cfc7381bSAlexei Starovoitov 	return;
626cfc7381bSAlexei Starovoitov tx_error:
627cfc7381bSAlexei Starovoitov 	dev->stats.tx_errors++;
628cfc7381bSAlexei Starovoitov 	goto kfree;
629cfc7381bSAlexei Starovoitov tx_dropped:
630cfc7381bSAlexei Starovoitov 	dev->stats.tx_dropped++;
631cfc7381bSAlexei Starovoitov kfree:
632cfc7381bSAlexei Starovoitov 	kfree_skb(skb);
633cfc7381bSAlexei Starovoitov }
634cfc7381bSAlexei Starovoitov EXPORT_SYMBOL_GPL(ip_md_tunnel_xmit);
635cfc7381bSAlexei Starovoitov 
636c5441932SPravin B Shelar void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
63756328486STom Herbert 		    const struct iphdr *tnl_params, u8 protocol)
638c5441932SPravin B Shelar {
639c5441932SPravin B Shelar 	struct ip_tunnel *tunnel = netdev_priv(dev);
640186d9366Swenxu 	struct ip_tunnel_info *tun_info = NULL;
641c5441932SPravin B Shelar 	const struct iphdr *inner_iph;
642c5441932SPravin B Shelar 	unsigned int max_headroom;	/* The extra header space needed */
643186d9366Swenxu 	struct rtable *rt = NULL;		/* Route to the other host */
644186d9366Swenxu 	bool use_cache = false;
645186d9366Swenxu 	struct flowi4 fl4;
646186d9366Swenxu 	bool md = false;
64722fb22eaSTimo Teräs 	bool connected;
648186d9366Swenxu 	u8 tos, ttl;
649186d9366Swenxu 	__be32 dst;
650186d9366Swenxu 	__be16 df;
651c5441932SPravin B Shelar 
652c5441932SPravin B Shelar 	inner_iph = (const struct iphdr *)skb_inner_network_header(skb);
65322fb22eaSTimo Teräs 	connected = (tunnel->parms.iph.daddr != 0);
654c5441932SPravin B Shelar 
6555146d1f1SBernie Harris 	memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
6565146d1f1SBernie Harris 
657c5441932SPravin B Shelar 	dst = tnl_params->daddr;
658c5441932SPravin B Shelar 	if (dst == 0) {
659c5441932SPravin B Shelar 		/* NBMA tunnel */
660c5441932SPravin B Shelar 
66151456b29SIan Morris 		if (!skb_dst(skb)) {
662c5441932SPravin B Shelar 			dev->stats.tx_fifo_errors++;
663c5441932SPravin B Shelar 			goto tx_error;
664c5441932SPravin B Shelar 		}
665c5441932SPravin B Shelar 
666d71b5753Swenxu 		tun_info = skb_tunnel_info(skb);
667d71b5753Swenxu 		if (tun_info && (tun_info->mode & IP_TUNNEL_INFO_TX) &&
668d71b5753Swenxu 		    ip_tunnel_info_af(tun_info) == AF_INET &&
669186d9366Swenxu 		    tun_info->key.u.ipv4.dst) {
670d71b5753Swenxu 			dst = tun_info->key.u.ipv4.dst;
671186d9366Swenxu 			md = true;
672186d9366Swenxu 			connected = true;
673186d9366Swenxu 		}
674d71b5753Swenxu 		else if (skb->protocol == htons(ETH_P_IP)) {
675c5441932SPravin B Shelar 			rt = skb_rtable(skb);
676c5441932SPravin B Shelar 			dst = rt_nexthop(rt, inner_iph->daddr);
677c5441932SPravin B Shelar 		}
678c5441932SPravin B Shelar #if IS_ENABLED(CONFIG_IPV6)
679c5441932SPravin B Shelar 		else if (skb->protocol == htons(ETH_P_IPV6)) {
680c5441932SPravin B Shelar 			const struct in6_addr *addr6;
681c5441932SPravin B Shelar 			struct neighbour *neigh;
682c5441932SPravin B Shelar 			bool do_tx_error_icmp;
683c5441932SPravin B Shelar 			int addr_type;
684c5441932SPravin B Shelar 
685c5441932SPravin B Shelar 			neigh = dst_neigh_lookup(skb_dst(skb),
686c5441932SPravin B Shelar 						 &ipv6_hdr(skb)->daddr);
68751456b29SIan Morris 			if (!neigh)
688c5441932SPravin B Shelar 				goto tx_error;
689c5441932SPravin B Shelar 
690c5441932SPravin B Shelar 			addr6 = (const struct in6_addr *)&neigh->primary_key;
691c5441932SPravin B Shelar 			addr_type = ipv6_addr_type(addr6);
692c5441932SPravin B Shelar 
693c5441932SPravin B Shelar 			if (addr_type == IPV6_ADDR_ANY) {
694c5441932SPravin B Shelar 				addr6 = &ipv6_hdr(skb)->daddr;
695c5441932SPravin B Shelar 				addr_type = ipv6_addr_type(addr6);
696c5441932SPravin B Shelar 			}
697c5441932SPravin B Shelar 
698c5441932SPravin B Shelar 			if ((addr_type & IPV6_ADDR_COMPATv4) == 0)
699c5441932SPravin B Shelar 				do_tx_error_icmp = true;
700c5441932SPravin B Shelar 			else {
701c5441932SPravin B Shelar 				do_tx_error_icmp = false;
702c5441932SPravin B Shelar 				dst = addr6->s6_addr32[3];
703c5441932SPravin B Shelar 			}
704c5441932SPravin B Shelar 			neigh_release(neigh);
705c5441932SPravin B Shelar 			if (do_tx_error_icmp)
706c5441932SPravin B Shelar 				goto tx_error_icmp;
707c5441932SPravin B Shelar 		}
708c5441932SPravin B Shelar #endif
709c5441932SPravin B Shelar 		else
710c5441932SPravin B Shelar 			goto tx_error;
7117d442fabSTom Herbert 
712186d9366Swenxu 		if (!md)
7137d442fabSTom Herbert 			connected = false;
714c5441932SPravin B Shelar 	}
715c5441932SPravin B Shelar 
716c5441932SPravin B Shelar 	tos = tnl_params->tos;
717c5441932SPravin B Shelar 	if (tos & 0x1) {
718c5441932SPravin B Shelar 		tos &= ~0x1;
7197d442fabSTom Herbert 		if (skb->protocol == htons(ETH_P_IP)) {
720c5441932SPravin B Shelar 			tos = inner_iph->tos;
7217d442fabSTom Herbert 			connected = false;
7227d442fabSTom Herbert 		} else if (skb->protocol == htons(ETH_P_IPV6)) {
723c5441932SPravin B Shelar 			tos = ipv6_get_dsfield((const struct ipv6hdr *)inner_iph);
7247d442fabSTom Herbert 			connected = false;
7257d442fabSTom Herbert 		}
726c5441932SPravin B Shelar 	}
727c5441932SPravin B Shelar 
728b0066da5SPetr Machata 	ip_tunnel_init_flow(&fl4, protocol, dst, tnl_params->saddr,
7299830ad4cSCraig Gallek 			    tunnel->parms.o_key, RT_TOS(tos), tunnel->parms.link,
73024ba1440Swenxu 			    tunnel->fwmark, skb_get_hash(skb));
7317d442fabSTom Herbert 
73256328486STom Herbert 	if (ip_tunnel_encap(skb, tunnel, &protocol, &fl4) < 0)
73356328486STom Herbert 		goto tx_error;
73456328486STom Herbert 
735186d9366Swenxu 	if (connected && md) {
736186d9366Swenxu 		use_cache = ip_tunnel_dst_cache_usable(skb, tun_info);
737186d9366Swenxu 		if (use_cache)
738186d9366Swenxu 			rt = dst_cache_get_ip4(&tun_info->dst_cache,
739186d9366Swenxu 					       &fl4.saddr);
740186d9366Swenxu 	} else {
741186d9366Swenxu 		rt = connected ? dst_cache_get_ip4(&tunnel->dst_cache,
742186d9366Swenxu 						&fl4.saddr) : NULL;
743186d9366Swenxu 	}
7447d442fabSTom Herbert 
7457d442fabSTom Herbert 	if (!rt) {
7467d442fabSTom Herbert 		rt = ip_route_output_key(tunnel->net, &fl4);
7477d442fabSTom Herbert 
748c5441932SPravin B Shelar 		if (IS_ERR(rt)) {
749c5441932SPravin B Shelar 			dev->stats.tx_carrier_errors++;
750c5441932SPravin B Shelar 			goto tx_error;
751c5441932SPravin B Shelar 		}
752186d9366Swenxu 		if (use_cache)
753186d9366Swenxu 			dst_cache_set_ip4(&tun_info->dst_cache, &rt->dst,
754186d9366Swenxu 					  fl4.saddr);
755186d9366Swenxu 		else if (!md && connected)
756e09acddfSPaolo Abeni 			dst_cache_set_ip4(&tunnel->dst_cache, &rt->dst,
757e09acddfSPaolo Abeni 					  fl4.saddr);
7587d442fabSTom Herbert 	}
7597d442fabSTom Herbert 
7600e6fbc5bSPravin B Shelar 	if (rt->dst.dev == dev) {
761c5441932SPravin B Shelar 		ip_rt_put(rt);
762c5441932SPravin B Shelar 		dev->stats.collisions++;
763c5441932SPravin B Shelar 		goto tx_error;
764c5441932SPravin B Shelar 	}
765c5441932SPravin B Shelar 
76650c66167SFlorian Westphal 	df = tnl_params->frag_off;
76750c66167SFlorian Westphal 	if (skb->protocol == htons(ETH_P_IP) && !tunnel->ignore_df)
76850c66167SFlorian Westphal 		df |= (inner_iph->frag_off & htons(IP_DF));
76950c66167SFlorian Westphal 
77050c66167SFlorian Westphal 	if (tnl_update_pmtu(dev, skb, rt, df, inner_iph, 0, 0, false)) {
771c5441932SPravin B Shelar 		ip_rt_put(rt);
772c5441932SPravin B Shelar 		goto tx_error;
773c5441932SPravin B Shelar 	}
774c5441932SPravin B Shelar 
775c5441932SPravin B Shelar 	if (tunnel->err_count > 0) {
776c5441932SPravin B Shelar 		if (time_before(jiffies,
777c5441932SPravin B Shelar 				tunnel->err_time + IPTUNNEL_ERR_TIMEO)) {
778c5441932SPravin B Shelar 			tunnel->err_count--;
779c5441932SPravin B Shelar 
780c5441932SPravin B Shelar 			dst_link_failure(skb);
781c5441932SPravin B Shelar 		} else
782c5441932SPravin B Shelar 			tunnel->err_count = 0;
783c5441932SPravin B Shelar 	}
784c5441932SPravin B Shelar 
785d4a71b15SPravin B Shelar 	tos = ip_tunnel_ecn_encap(tos, inner_iph, skb);
786c5441932SPravin B Shelar 	ttl = tnl_params->ttl;
787c5441932SPravin B Shelar 	if (ttl == 0) {
788c5441932SPravin B Shelar 		if (skb->protocol == htons(ETH_P_IP))
789c5441932SPravin B Shelar 			ttl = inner_iph->ttl;
790c5441932SPravin B Shelar #if IS_ENABLED(CONFIG_IPV6)
791c5441932SPravin B Shelar 		else if (skb->protocol == htons(ETH_P_IPV6))
792c5441932SPravin B Shelar 			ttl = ((const struct ipv6hdr *)inner_iph)->hop_limit;
793c5441932SPravin B Shelar #endif
794c5441932SPravin B Shelar 		else
795c5441932SPravin B Shelar 			ttl = ip4_dst_hoplimit(&rt->dst);
796c5441932SPravin B Shelar 	}
797c5441932SPravin B Shelar 
7980e6fbc5bSPravin B Shelar 	max_headroom = LL_RESERVED_SPACE(rt->dst.dev) + sizeof(struct iphdr)
7997371e022STom Herbert 			+ rt->dst.header_len + ip_encap_hlen(&tunnel->encap);
8003e08f4a7SSteffen Klassert 	if (max_headroom > dev->needed_headroom)
801c5441932SPravin B Shelar 		dev->needed_headroom = max_headroom;
8023e08f4a7SSteffen Klassert 
803c5441932SPravin B Shelar 	if (skb_cow_head(skb, dev->needed_headroom)) {
804586d5fc8SDmitry Popov 		ip_rt_put(rt);
805c5441932SPravin B Shelar 		dev->stats.tx_dropped++;
8063acfa1e7SEric Dumazet 		kfree_skb(skb);
807c5441932SPravin B Shelar 		return;
808c5441932SPravin B Shelar 	}
809c5441932SPravin B Shelar 
810039f5062SPravin B Shelar 	iptunnel_xmit(NULL, rt, skb, fl4.saddr, fl4.daddr, protocol, tos, ttl,
811039f5062SPravin B Shelar 		      df, !net_eq(tunnel->net, dev_net(dev)));
812c5441932SPravin B Shelar 	return;
813c5441932SPravin B Shelar 
814c5441932SPravin B Shelar #if IS_ENABLED(CONFIG_IPV6)
815c5441932SPravin B Shelar tx_error_icmp:
816c5441932SPravin B Shelar 	dst_link_failure(skb);
817c5441932SPravin B Shelar #endif
818c5441932SPravin B Shelar tx_error:
819c5441932SPravin B Shelar 	dev->stats.tx_errors++;
8203acfa1e7SEric Dumazet 	kfree_skb(skb);
821c5441932SPravin B Shelar }
822c5441932SPravin B Shelar EXPORT_SYMBOL_GPL(ip_tunnel_xmit);
823c5441932SPravin B Shelar 
824c5441932SPravin B Shelar static void ip_tunnel_update(struct ip_tunnel_net *itn,
825c5441932SPravin B Shelar 			     struct ip_tunnel *t,
826c5441932SPravin B Shelar 			     struct net_device *dev,
827c5441932SPravin B Shelar 			     struct ip_tunnel_parm *p,
8289830ad4cSCraig Gallek 			     bool set_mtu,
8299830ad4cSCraig Gallek 			     __u32 fwmark)
830c5441932SPravin B Shelar {
8312e15ea39SPravin B Shelar 	ip_tunnel_del(itn, t);
832c5441932SPravin B Shelar 	t->parms.iph.saddr = p->iph.saddr;
833c5441932SPravin B Shelar 	t->parms.iph.daddr = p->iph.daddr;
834c5441932SPravin B Shelar 	t->parms.i_key = p->i_key;
835c5441932SPravin B Shelar 	t->parms.o_key = p->o_key;
836c5441932SPravin B Shelar 	if (dev->type != ARPHRD_ETHER) {
837c5441932SPravin B Shelar 		memcpy(dev->dev_addr, &p->iph.saddr, 4);
838c5441932SPravin B Shelar 		memcpy(dev->broadcast, &p->iph.daddr, 4);
839c5441932SPravin B Shelar 	}
840c5441932SPravin B Shelar 	ip_tunnel_add(itn, t);
841c5441932SPravin B Shelar 
842c5441932SPravin B Shelar 	t->parms.iph.ttl = p->iph.ttl;
843c5441932SPravin B Shelar 	t->parms.iph.tos = p->iph.tos;
844c5441932SPravin B Shelar 	t->parms.iph.frag_off = p->iph.frag_off;
845c5441932SPravin B Shelar 
8469830ad4cSCraig Gallek 	if (t->parms.link != p->link || t->fwmark != fwmark) {
847c5441932SPravin B Shelar 		int mtu;
848c5441932SPravin B Shelar 
849c5441932SPravin B Shelar 		t->parms.link = p->link;
8509830ad4cSCraig Gallek 		t->fwmark = fwmark;
851c5441932SPravin B Shelar 		mtu = ip_tunnel_bind_dev(dev);
852c5441932SPravin B Shelar 		if (set_mtu)
853c5441932SPravin B Shelar 			dev->mtu = mtu;
854c5441932SPravin B Shelar 	}
855e09acddfSPaolo Abeni 	dst_cache_reset(&t->dst_cache);
856c5441932SPravin B Shelar 	netdev_state_change(dev);
857c5441932SPravin B Shelar }
858c5441932SPravin B Shelar 
859607259a6SChristoph Hellwig int ip_tunnel_ctl(struct net_device *dev, struct ip_tunnel_parm *p, int cmd)
860c5441932SPravin B Shelar {
861c5441932SPravin B Shelar 	int err = 0;
8628c923ce2SNicolas Dichtel 	struct ip_tunnel *t = netdev_priv(dev);
8638c923ce2SNicolas Dichtel 	struct net *net = t->net;
8648c923ce2SNicolas Dichtel 	struct ip_tunnel_net *itn = net_generic(net, t->ip_tnl_net_id);
865c5441932SPravin B Shelar 
866c5441932SPravin B Shelar 	switch (cmd) {
867c5441932SPravin B Shelar 	case SIOCGETTUNNEL:
8688c923ce2SNicolas Dichtel 		if (dev == itn->fb_tunnel_dev) {
869c5441932SPravin B Shelar 			t = ip_tunnel_find(itn, p, itn->fb_tunnel_dev->type);
87051456b29SIan Morris 			if (!t)
871c5441932SPravin B Shelar 				t = netdev_priv(dev);
8728c923ce2SNicolas Dichtel 		}
873c5441932SPravin B Shelar 		memcpy(p, &t->parms, sizeof(*p));
874c5441932SPravin B Shelar 		break;
875c5441932SPravin B Shelar 
876c5441932SPravin B Shelar 	case SIOCADDTUNNEL:
877c5441932SPravin B Shelar 	case SIOCCHGTUNNEL:
878c5441932SPravin B Shelar 		err = -EPERM;
879c5441932SPravin B Shelar 		if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
880c5441932SPravin B Shelar 			goto done;
881c5441932SPravin B Shelar 		if (p->iph.ttl)
882c5441932SPravin B Shelar 			p->iph.frag_off |= htons(IP_DF);
8837c8e6b9cSDmitry Popov 		if (!(p->i_flags & VTI_ISVTI)) {
884c5441932SPravin B Shelar 			if (!(p->i_flags & TUNNEL_KEY))
885c5441932SPravin B Shelar 				p->i_key = 0;
886c5441932SPravin B Shelar 			if (!(p->o_flags & TUNNEL_KEY))
887c5441932SPravin B Shelar 				p->o_key = 0;
8887c8e6b9cSDmitry Popov 		}
889c5441932SPravin B Shelar 
89079134e6cSEric Dumazet 		t = ip_tunnel_find(itn, p, itn->type);
891c5441932SPravin B Shelar 
892d61746b2SSteffen Klassert 		if (cmd == SIOCADDTUNNEL) {
893d61746b2SSteffen Klassert 			if (!t) {
894c5441932SPravin B Shelar 				t = ip_tunnel_create(net, itn, p);
895ee30ef4dSDuan Jiong 				err = PTR_ERR_OR_ZERO(t);
8966dd3c9ecSFlorian Westphal 				break;
8976dd3c9ecSFlorian Westphal 			}
898d61746b2SSteffen Klassert 
899d61746b2SSteffen Klassert 			err = -EEXIST;
900d61746b2SSteffen Klassert 			break;
901d61746b2SSteffen Klassert 		}
902c5441932SPravin B Shelar 		if (dev != itn->fb_tunnel_dev && cmd == SIOCCHGTUNNEL) {
90300db4124SIan Morris 			if (t) {
904c5441932SPravin B Shelar 				if (t->dev != dev) {
905c5441932SPravin B Shelar 					err = -EEXIST;
906c5441932SPravin B Shelar 					break;
907c5441932SPravin B Shelar 				}
908c5441932SPravin B Shelar 			} else {
909c5441932SPravin B Shelar 				unsigned int nflags = 0;
910c5441932SPravin B Shelar 
911c5441932SPravin B Shelar 				if (ipv4_is_multicast(p->iph.daddr))
912c5441932SPravin B Shelar 					nflags = IFF_BROADCAST;
913c5441932SPravin B Shelar 				else if (p->iph.daddr)
914c5441932SPravin B Shelar 					nflags = IFF_POINTOPOINT;
915c5441932SPravin B Shelar 
916c5441932SPravin B Shelar 				if ((dev->flags^nflags)&(IFF_POINTOPOINT|IFF_BROADCAST)) {
917c5441932SPravin B Shelar 					err = -EINVAL;
918c5441932SPravin B Shelar 					break;
919c5441932SPravin B Shelar 				}
920c5441932SPravin B Shelar 
921c5441932SPravin B Shelar 				t = netdev_priv(dev);
922c5441932SPravin B Shelar 			}
923c5441932SPravin B Shelar 		}
924c5441932SPravin B Shelar 
925c5441932SPravin B Shelar 		if (t) {
926c5441932SPravin B Shelar 			err = 0;
9279830ad4cSCraig Gallek 			ip_tunnel_update(itn, t, dev, p, true, 0);
9286dd3c9ecSFlorian Westphal 		} else {
9296dd3c9ecSFlorian Westphal 			err = -ENOENT;
9306dd3c9ecSFlorian Westphal 		}
931c5441932SPravin B Shelar 		break;
932c5441932SPravin B Shelar 
933c5441932SPravin B Shelar 	case SIOCDELTUNNEL:
934c5441932SPravin B Shelar 		err = -EPERM;
935c5441932SPravin B Shelar 		if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
936c5441932SPravin B Shelar 			goto done;
937c5441932SPravin B Shelar 
938c5441932SPravin B Shelar 		if (dev == itn->fb_tunnel_dev) {
939c5441932SPravin B Shelar 			err = -ENOENT;
940c5441932SPravin B Shelar 			t = ip_tunnel_find(itn, p, itn->fb_tunnel_dev->type);
94151456b29SIan Morris 			if (!t)
942c5441932SPravin B Shelar 				goto done;
943c5441932SPravin B Shelar 			err = -EPERM;
944c5441932SPravin B Shelar 			if (t == netdev_priv(itn->fb_tunnel_dev))
945c5441932SPravin B Shelar 				goto done;
946c5441932SPravin B Shelar 			dev = t->dev;
947c5441932SPravin B Shelar 		}
948c5441932SPravin B Shelar 		unregister_netdevice(dev);
949c5441932SPravin B Shelar 		err = 0;
950c5441932SPravin B Shelar 		break;
951c5441932SPravin B Shelar 
952c5441932SPravin B Shelar 	default:
953c5441932SPravin B Shelar 		err = -EINVAL;
954c5441932SPravin B Shelar 	}
955c5441932SPravin B Shelar 
956c5441932SPravin B Shelar done:
957c5441932SPravin B Shelar 	return err;
958c5441932SPravin B Shelar }
959607259a6SChristoph Hellwig EXPORT_SYMBOL_GPL(ip_tunnel_ctl);
960607259a6SChristoph Hellwig 
961607259a6SChristoph Hellwig int ip_tunnel_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
962607259a6SChristoph Hellwig {
963607259a6SChristoph Hellwig 	struct ip_tunnel_parm p;
964607259a6SChristoph Hellwig 	int err;
965607259a6SChristoph Hellwig 
966607259a6SChristoph Hellwig 	if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p)))
967607259a6SChristoph Hellwig 		return -EFAULT;
968607259a6SChristoph Hellwig 	err = dev->netdev_ops->ndo_tunnel_ctl(dev, &p, cmd);
969607259a6SChristoph Hellwig 	if (!err && copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p)))
970607259a6SChristoph Hellwig 		return -EFAULT;
971607259a6SChristoph Hellwig 	return err;
972607259a6SChristoph Hellwig }
973c5441932SPravin B Shelar EXPORT_SYMBOL_GPL(ip_tunnel_ioctl);
974c5441932SPravin B Shelar 
9757e059158SDavid Wragg int __ip_tunnel_change_mtu(struct net_device *dev, int new_mtu, bool strict)
976c5441932SPravin B Shelar {
977c5441932SPravin B Shelar 	struct ip_tunnel *tunnel = netdev_priv(dev);
978c5441932SPravin B Shelar 	int t_hlen = tunnel->hlen + sizeof(struct iphdr);
97928e104d0SVadim Fedorenko 	int max_mtu = IP_MAX_MTU - t_hlen;
980c5441932SPravin B Shelar 
9819992a078SHangbin Liu 	if (dev->type == ARPHRD_ETHER)
9829992a078SHangbin Liu 		max_mtu -= dev->hard_header_len;
9839992a078SHangbin Liu 
984b96f9afeSJarod Wilson 	if (new_mtu < ETH_MIN_MTU)
985c5441932SPravin B Shelar 		return -EINVAL;
9867e059158SDavid Wragg 
9877e059158SDavid Wragg 	if (new_mtu > max_mtu) {
9887e059158SDavid Wragg 		if (strict)
9897e059158SDavid Wragg 			return -EINVAL;
9907e059158SDavid Wragg 
9917e059158SDavid Wragg 		new_mtu = max_mtu;
9927e059158SDavid Wragg 	}
9937e059158SDavid Wragg 
994c5441932SPravin B Shelar 	dev->mtu = new_mtu;
995c5441932SPravin B Shelar 	return 0;
996c5441932SPravin B Shelar }
9977e059158SDavid Wragg EXPORT_SYMBOL_GPL(__ip_tunnel_change_mtu);
9987e059158SDavid Wragg 
9997e059158SDavid Wragg int ip_tunnel_change_mtu(struct net_device *dev, int new_mtu)
10007e059158SDavid Wragg {
10017e059158SDavid Wragg 	return __ip_tunnel_change_mtu(dev, new_mtu, true);
10027e059158SDavid Wragg }
1003c5441932SPravin B Shelar EXPORT_SYMBOL_GPL(ip_tunnel_change_mtu);
1004c5441932SPravin B Shelar 
1005c5441932SPravin B Shelar static void ip_tunnel_dev_free(struct net_device *dev)
1006c5441932SPravin B Shelar {
1007c5441932SPravin B Shelar 	struct ip_tunnel *tunnel = netdev_priv(dev);
1008c5441932SPravin B Shelar 
1009c5441932SPravin B Shelar 	gro_cells_destroy(&tunnel->gro_cells);
1010e09acddfSPaolo Abeni 	dst_cache_destroy(&tunnel->dst_cache);
1011c5441932SPravin B Shelar 	free_percpu(dev->tstats);
1012c5441932SPravin B Shelar }
1013c5441932SPravin B Shelar 
1014c5441932SPravin B Shelar void ip_tunnel_dellink(struct net_device *dev, struct list_head *head)
1015c5441932SPravin B Shelar {
1016c5441932SPravin B Shelar 	struct ip_tunnel *tunnel = netdev_priv(dev);
1017c5441932SPravin B Shelar 	struct ip_tunnel_net *itn;
1018c5441932SPravin B Shelar 
10196c742e71SNicolas Dichtel 	itn = net_generic(tunnel->net, tunnel->ip_tnl_net_id);
1020c5441932SPravin B Shelar 
1021c5441932SPravin B Shelar 	if (itn->fb_tunnel_dev != dev) {
10222e15ea39SPravin B Shelar 		ip_tunnel_del(itn, netdev_priv(dev));
1023c5441932SPravin B Shelar 		unregister_netdevice_queue(dev, head);
1024c5441932SPravin B Shelar 	}
1025c5441932SPravin B Shelar }
1026c5441932SPravin B Shelar EXPORT_SYMBOL_GPL(ip_tunnel_dellink);
1027c5441932SPravin B Shelar 
10281728d4faSNicolas Dichtel struct net *ip_tunnel_get_link_net(const struct net_device *dev)
10291728d4faSNicolas Dichtel {
10301728d4faSNicolas Dichtel 	struct ip_tunnel *tunnel = netdev_priv(dev);
10311728d4faSNicolas Dichtel 
10321728d4faSNicolas Dichtel 	return tunnel->net;
10331728d4faSNicolas Dichtel }
10341728d4faSNicolas Dichtel EXPORT_SYMBOL(ip_tunnel_get_link_net);
10351728d4faSNicolas Dichtel 
10361e99584bSNicolas Dichtel int ip_tunnel_get_iflink(const struct net_device *dev)
10371e99584bSNicolas Dichtel {
10381e99584bSNicolas Dichtel 	struct ip_tunnel *tunnel = netdev_priv(dev);
10391e99584bSNicolas Dichtel 
10401e99584bSNicolas Dichtel 	return tunnel->parms.link;
10411e99584bSNicolas Dichtel }
10421e99584bSNicolas Dichtel EXPORT_SYMBOL(ip_tunnel_get_iflink);
10431e99584bSNicolas Dichtel 
1044c7d03a00SAlexey Dobriyan int ip_tunnel_init_net(struct net *net, unsigned int ip_tnl_net_id,
1045c5441932SPravin B Shelar 				  struct rtnl_link_ops *ops, char *devname)
1046c5441932SPravin B Shelar {
1047c5441932SPravin B Shelar 	struct ip_tunnel_net *itn = net_generic(net, ip_tnl_net_id);
1048c5441932SPravin B Shelar 	struct ip_tunnel_parm parms;
10496261d983Sstephen hemminger 	unsigned int i;
1050c5441932SPravin B Shelar 
105179134e6cSEric Dumazet 	itn->rtnl_link_ops = ops;
10526261d983Sstephen hemminger 	for (i = 0; i < IP_TNL_HASH_SIZE; i++)
10536261d983Sstephen hemminger 		INIT_HLIST_HEAD(&itn->tunnels[i]);
1054c5441932SPravin B Shelar 
105579134e6cSEric Dumazet 	if (!ops || !net_has_fallback_tunnels(net)) {
105679134e6cSEric Dumazet 		struct ip_tunnel_net *it_init_net;
105779134e6cSEric Dumazet 
105879134e6cSEric Dumazet 		it_init_net = net_generic(&init_net, ip_tnl_net_id);
105979134e6cSEric Dumazet 		itn->type = it_init_net->type;
1060c5441932SPravin B Shelar 		itn->fb_tunnel_dev = NULL;
1061c5441932SPravin B Shelar 		return 0;
1062c5441932SPravin B Shelar 	}
10636261d983Sstephen hemminger 
1064c5441932SPravin B Shelar 	memset(&parms, 0, sizeof(parms));
1065c5441932SPravin B Shelar 	if (devname)
1066c5441932SPravin B Shelar 		strlcpy(parms.name, devname, IFNAMSIZ);
1067c5441932SPravin B Shelar 
1068c5441932SPravin B Shelar 	rtnl_lock();
1069c5441932SPravin B Shelar 	itn->fb_tunnel_dev = __ip_tunnel_create(net, ops, &parms);
1070ea857f28SDan Carpenter 	/* FB netdevice is special: we have one, and only one per netns.
1071ea857f28SDan Carpenter 	 * Allowing to move it to another netns is clearly unsafe.
1072ea857f28SDan Carpenter 	 */
107367013282SSteffen Klassert 	if (!IS_ERR(itn->fb_tunnel_dev)) {
1074ea857f28SDan Carpenter 		itn->fb_tunnel_dev->features |= NETIF_F_NETNS_LOCAL;
107578ff4be4SSteffen Klassert 		itn->fb_tunnel_dev->mtu = ip_tunnel_bind_dev(itn->fb_tunnel_dev);
107667013282SSteffen Klassert 		ip_tunnel_add(itn, netdev_priv(itn->fb_tunnel_dev));
107779134e6cSEric Dumazet 		itn->type = itn->fb_tunnel_dev->type;
107867013282SSteffen Klassert 	}
1079b4de77adSDan Carpenter 	rtnl_unlock();
1080c5441932SPravin B Shelar 
108127d79f3bSSachin Kamat 	return PTR_ERR_OR_ZERO(itn->fb_tunnel_dev);
1082c5441932SPravin B Shelar }
1083c5441932SPravin B Shelar EXPORT_SYMBOL_GPL(ip_tunnel_init_net);
1084c5441932SPravin B Shelar 
108579134e6cSEric Dumazet static void ip_tunnel_destroy(struct net *net, struct ip_tunnel_net *itn,
108679134e6cSEric Dumazet 			      struct list_head *head,
10876c742e71SNicolas Dichtel 			      struct rtnl_link_ops *ops)
1088c5441932SPravin B Shelar {
10896c742e71SNicolas Dichtel 	struct net_device *dev, *aux;
1090c5441932SPravin B Shelar 	int h;
1091c5441932SPravin B Shelar 
10926c742e71SNicolas Dichtel 	for_each_netdev_safe(net, dev, aux)
10936c742e71SNicolas Dichtel 		if (dev->rtnl_link_ops == ops)
10946c742e71SNicolas Dichtel 			unregister_netdevice_queue(dev, head);
10956c742e71SNicolas Dichtel 
1096c5441932SPravin B Shelar 	for (h = 0; h < IP_TNL_HASH_SIZE; h++) {
1097c5441932SPravin B Shelar 		struct ip_tunnel *t;
1098c5441932SPravin B Shelar 		struct hlist_node *n;
1099c5441932SPravin B Shelar 		struct hlist_head *thead = &itn->tunnels[h];
1100c5441932SPravin B Shelar 
1101c5441932SPravin B Shelar 		hlist_for_each_entry_safe(t, n, thead, hash_node)
11026c742e71SNicolas Dichtel 			/* If dev is in the same netns, it has already
11036c742e71SNicolas Dichtel 			 * been added to the list by the previous loop.
11046c742e71SNicolas Dichtel 			 */
11056c742e71SNicolas Dichtel 			if (!net_eq(dev_net(t->dev), net))
1106c5441932SPravin B Shelar 				unregister_netdevice_queue(t->dev, head);
1107c5441932SPravin B Shelar 	}
1108c5441932SPravin B Shelar }
1109c5441932SPravin B Shelar 
111064bc1781SEric Dumazet void ip_tunnel_delete_nets(struct list_head *net_list, unsigned int id,
111164bc1781SEric Dumazet 			   struct rtnl_link_ops *ops)
1112c5441932SPravin B Shelar {
111364bc1781SEric Dumazet 	struct ip_tunnel_net *itn;
111464bc1781SEric Dumazet 	struct net *net;
1115c5441932SPravin B Shelar 	LIST_HEAD(list);
1116c5441932SPravin B Shelar 
1117c5441932SPravin B Shelar 	rtnl_lock();
111864bc1781SEric Dumazet 	list_for_each_entry(net, net_list, exit_list) {
111964bc1781SEric Dumazet 		itn = net_generic(net, id);
112079134e6cSEric Dumazet 		ip_tunnel_destroy(net, itn, &list, ops);
112164bc1781SEric Dumazet 	}
1122c5441932SPravin B Shelar 	unregister_netdevice_many(&list);
1123c5441932SPravin B Shelar 	rtnl_unlock();
1124c5441932SPravin B Shelar }
112564bc1781SEric Dumazet EXPORT_SYMBOL_GPL(ip_tunnel_delete_nets);
1126c5441932SPravin B Shelar 
1127c5441932SPravin B Shelar int ip_tunnel_newlink(struct net_device *dev, struct nlattr *tb[],
11289830ad4cSCraig Gallek 		      struct ip_tunnel_parm *p, __u32 fwmark)
1129c5441932SPravin B Shelar {
1130c5441932SPravin B Shelar 	struct ip_tunnel *nt;
1131c5441932SPravin B Shelar 	struct net *net = dev_net(dev);
1132c5441932SPravin B Shelar 	struct ip_tunnel_net *itn;
1133c5441932SPravin B Shelar 	int mtu;
1134c5441932SPravin B Shelar 	int err;
1135c5441932SPravin B Shelar 
1136c5441932SPravin B Shelar 	nt = netdev_priv(dev);
1137c5441932SPravin B Shelar 	itn = net_generic(net, nt->ip_tnl_net_id);
1138c5441932SPravin B Shelar 
11392e15ea39SPravin B Shelar 	if (nt->collect_md) {
11402e15ea39SPravin B Shelar 		if (rtnl_dereference(itn->collect_md_tun))
11412e15ea39SPravin B Shelar 			return -EEXIST;
11422e15ea39SPravin B Shelar 	} else {
1143c5441932SPravin B Shelar 		if (ip_tunnel_find(itn, p, dev->type))
1144c5441932SPravin B Shelar 			return -EEXIST;
11452e15ea39SPravin B Shelar 	}
1146c5441932SPravin B Shelar 
11475e6700b3SNicolas Dichtel 	nt->net = net;
1148c5441932SPravin B Shelar 	nt->parms = *p;
11499830ad4cSCraig Gallek 	nt->fwmark = fwmark;
1150c5441932SPravin B Shelar 	err = register_netdevice(dev);
1151c5441932SPravin B Shelar 	if (err)
1152f6cc9c05SPetr Machata 		goto err_register_netdevice;
1153c5441932SPravin B Shelar 
1154c5441932SPravin B Shelar 	if (dev->type == ARPHRD_ETHER && !tb[IFLA_ADDRESS])
1155c5441932SPravin B Shelar 		eth_hw_addr_random(dev);
1156c5441932SPravin B Shelar 
1157c5441932SPravin B Shelar 	mtu = ip_tunnel_bind_dev(dev);
115824fc7979SStefano Brivio 	if (tb[IFLA_MTU]) {
115928e104d0SVadim Fedorenko 		unsigned int max = IP_MAX_MTU - (nt->hlen + sizeof(struct iphdr));
116024fc7979SStefano Brivio 
11619992a078SHangbin Liu 		if (dev->type == ARPHRD_ETHER)
11629992a078SHangbin Liu 			max -= dev->hard_header_len;
11639992a078SHangbin Liu 
116428e104d0SVadim Fedorenko 		mtu = clamp(dev->mtu, (unsigned int)ETH_MIN_MTU, max);
11655568cdc3SDavid S. Miller 	}
11665568cdc3SDavid S. Miller 
1167f6cc9c05SPetr Machata 	err = dev_set_mtu(dev, mtu);
1168f6cc9c05SPetr Machata 	if (err)
1169f6cc9c05SPetr Machata 		goto err_dev_set_mtu;
1170c5441932SPravin B Shelar 
1171c5441932SPravin B Shelar 	ip_tunnel_add(itn, nt);
1172f6cc9c05SPetr Machata 	return 0;
1173f6cc9c05SPetr Machata 
1174f6cc9c05SPetr Machata err_dev_set_mtu:
1175f6cc9c05SPetr Machata 	unregister_netdevice(dev);
1176f6cc9c05SPetr Machata err_register_netdevice:
1177c5441932SPravin B Shelar 	return err;
1178c5441932SPravin B Shelar }
1179c5441932SPravin B Shelar EXPORT_SYMBOL_GPL(ip_tunnel_newlink);
1180c5441932SPravin B Shelar 
1181c5441932SPravin B Shelar int ip_tunnel_changelink(struct net_device *dev, struct nlattr *tb[],
11829830ad4cSCraig Gallek 			 struct ip_tunnel_parm *p, __u32 fwmark)
1183c5441932SPravin B Shelar {
11846c742e71SNicolas Dichtel 	struct ip_tunnel *t;
1185c5441932SPravin B Shelar 	struct ip_tunnel *tunnel = netdev_priv(dev);
11866c742e71SNicolas Dichtel 	struct net *net = tunnel->net;
1187c5441932SPravin B Shelar 	struct ip_tunnel_net *itn = net_generic(net, tunnel->ip_tnl_net_id);
1188c5441932SPravin B Shelar 
1189c5441932SPravin B Shelar 	if (dev == itn->fb_tunnel_dev)
1190c5441932SPravin B Shelar 		return -EINVAL;
1191c5441932SPravin B Shelar 
1192c5441932SPravin B Shelar 	t = ip_tunnel_find(itn, p, dev->type);
1193c5441932SPravin B Shelar 
1194c5441932SPravin B Shelar 	if (t) {
1195c5441932SPravin B Shelar 		if (t->dev != dev)
1196c5441932SPravin B Shelar 			return -EEXIST;
1197c5441932SPravin B Shelar 	} else {
11986c742e71SNicolas Dichtel 		t = tunnel;
1199c5441932SPravin B Shelar 
1200c5441932SPravin B Shelar 		if (dev->type != ARPHRD_ETHER) {
1201c5441932SPravin B Shelar 			unsigned int nflags = 0;
1202c5441932SPravin B Shelar 
1203c5441932SPravin B Shelar 			if (ipv4_is_multicast(p->iph.daddr))
1204c5441932SPravin B Shelar 				nflags = IFF_BROADCAST;
1205c5441932SPravin B Shelar 			else if (p->iph.daddr)
1206c5441932SPravin B Shelar 				nflags = IFF_POINTOPOINT;
1207c5441932SPravin B Shelar 
1208c5441932SPravin B Shelar 			if ((dev->flags ^ nflags) &
1209c5441932SPravin B Shelar 			    (IFF_POINTOPOINT | IFF_BROADCAST))
1210c5441932SPravin B Shelar 				return -EINVAL;
1211c5441932SPravin B Shelar 		}
1212c5441932SPravin B Shelar 	}
1213c5441932SPravin B Shelar 
12149830ad4cSCraig Gallek 	ip_tunnel_update(itn, t, dev, p, !tb[IFLA_MTU], fwmark);
1215c5441932SPravin B Shelar 	return 0;
1216c5441932SPravin B Shelar }
1217c5441932SPravin B Shelar EXPORT_SYMBOL_GPL(ip_tunnel_changelink);
1218c5441932SPravin B Shelar 
1219c5441932SPravin B Shelar int ip_tunnel_init(struct net_device *dev)
1220c5441932SPravin B Shelar {
1221c5441932SPravin B Shelar 	struct ip_tunnel *tunnel = netdev_priv(dev);
1222c5441932SPravin B Shelar 	struct iphdr *iph = &tunnel->parms.iph;
12231c213bd2SWANG Cong 	int err;
1224c5441932SPravin B Shelar 
1225cf124db5SDavid S. Miller 	dev->needs_free_netdev = true;
1226cf124db5SDavid S. Miller 	dev->priv_destructor = ip_tunnel_dev_free;
12271c213bd2SWANG Cong 	dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
1228c5441932SPravin B Shelar 	if (!dev->tstats)
1229c5441932SPravin B Shelar 		return -ENOMEM;
1230c5441932SPravin B Shelar 
1231e09acddfSPaolo Abeni 	err = dst_cache_init(&tunnel->dst_cache, GFP_KERNEL);
1232e09acddfSPaolo Abeni 	if (err) {
12339a4aa9afSTom Herbert 		free_percpu(dev->tstats);
1234e09acddfSPaolo Abeni 		return err;
12359a4aa9afSTom Herbert 	}
12369a4aa9afSTom Herbert 
1237c5441932SPravin B Shelar 	err = gro_cells_init(&tunnel->gro_cells, dev);
1238c5441932SPravin B Shelar 	if (err) {
1239e09acddfSPaolo Abeni 		dst_cache_destroy(&tunnel->dst_cache);
1240c5441932SPravin B Shelar 		free_percpu(dev->tstats);
1241c5441932SPravin B Shelar 		return err;
1242c5441932SPravin B Shelar 	}
1243c5441932SPravin B Shelar 
1244c5441932SPravin B Shelar 	tunnel->dev = dev;
12456c742e71SNicolas Dichtel 	tunnel->net = dev_net(dev);
1246c5441932SPravin B Shelar 	strcpy(tunnel->parms.name, dev->name);
1247c5441932SPravin B Shelar 	iph->version		= 4;
1248c5441932SPravin B Shelar 	iph->ihl		= 5;
1249c5441932SPravin B Shelar 
1250d0f41851SWilliam Dauchy 	if (tunnel->collect_md)
12512e15ea39SPravin B Shelar 		netif_keep_dst(dev);
1252c5441932SPravin B Shelar 	return 0;
1253c5441932SPravin B Shelar }
1254c5441932SPravin B Shelar EXPORT_SYMBOL_GPL(ip_tunnel_init);
1255c5441932SPravin B Shelar 
1256c5441932SPravin B Shelar void ip_tunnel_uninit(struct net_device *dev)
1257c5441932SPravin B Shelar {
1258c5441932SPravin B Shelar 	struct ip_tunnel *tunnel = netdev_priv(dev);
12596c742e71SNicolas Dichtel 	struct net *net = tunnel->net;
1260c5441932SPravin B Shelar 	struct ip_tunnel_net *itn;
1261c5441932SPravin B Shelar 
1262c5441932SPravin B Shelar 	itn = net_generic(net, tunnel->ip_tnl_net_id);
12632e15ea39SPravin B Shelar 	ip_tunnel_del(itn, netdev_priv(dev));
1264ba61539cSTaehee Yoo 	if (itn->fb_tunnel_dev == dev)
1265ba61539cSTaehee Yoo 		WRITE_ONCE(itn->fb_tunnel_dev, NULL);
12667d442fabSTom Herbert 
1267e09acddfSPaolo Abeni 	dst_cache_reset(&tunnel->dst_cache);
1268c5441932SPravin B Shelar }
1269c5441932SPravin B Shelar EXPORT_SYMBOL_GPL(ip_tunnel_uninit);
1270c5441932SPravin B Shelar 
1271c5441932SPravin B Shelar /* Do least required initialization, rest of init is done in tunnel_init call */
1272c7d03a00SAlexey Dobriyan void ip_tunnel_setup(struct net_device *dev, unsigned int net_id)
1273c5441932SPravin B Shelar {
1274c5441932SPravin B Shelar 	struct ip_tunnel *tunnel = netdev_priv(dev);
1275c5441932SPravin B Shelar 	tunnel->ip_tnl_net_id = net_id;
1276c5441932SPravin B Shelar }
1277c5441932SPravin B Shelar EXPORT_SYMBOL_GPL(ip_tunnel_setup);
1278c5441932SPravin B Shelar 
1279c5441932SPravin B Shelar MODULE_LICENSE("GPL");
1280