blob: cd4b84310d9295c4eec478a4e12136716dfa9e0c [file] [log] [blame]
Thomas Gleixnerc9422992019-05-29 07:12:43 -07001// SPDX-License-Identifier: GPL-2.0-only
Pravin B Shelarc5441932013-03-25 14:49:35 +00002/*
3 * Copyright (c) 2013 Nicira, Inc.
Pravin B Shelarc5441932013-03-25 14:49:35 +00004 */
5
6#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
7
8#include <linux/capability.h>
9#include <linux/module.h>
10#include <linux/types.h>
11#include <linux/kernel.h>
12#include <linux/slab.h>
13#include <linux/uaccess.h>
14#include <linux/skbuff.h>
15#include <linux/netdevice.h>
16#include <linux/in.h>
17#include <linux/tcp.h>
18#include <linux/udp.h>
19#include <linux/if_arp.h>
Pravin B Shelarc5441932013-03-25 14:49:35 +000020#include <linux/init.h>
21#include <linux/in6.h>
22#include <linux/inetdevice.h>
23#include <linux/igmp.h>
24#include <linux/netfilter_ipv4.h>
25#include <linux/etherdevice.h>
26#include <linux/if_ether.h>
27#include <linux/if_vlan.h>
28#include <linux/rculist.h>
Sachin Kamat27d79f32014-01-27 12:13:57 +053029#include <linux/err.h>
Pravin B Shelarc5441932013-03-25 14:49:35 +000030
31#include <net/sock.h>
32#include <net/ip.h>
33#include <net/icmp.h>
34#include <net/protocol.h>
35#include <net/ip_tunnels.h>
36#include <net/arp.h>
37#include <net/checksum.h>
38#include <net/dsfield.h>
39#include <net/inet_ecn.h>
40#include <net/xfrm.h>
41#include <net/net_namespace.h>
42#include <net/netns/generic.h>
43#include <net/rtnetlink.h>
Tom Herbert56328482014-09-17 12:25:58 -070044#include <net/udp.h>
Alexei Starovoitovcfc73812016-09-15 13:00:29 -070045#include <net/dst_metadata.h>
Tom Herbert63487ba2014-11-04 09:06:51 -080046
Pravin B Shelarc5441932013-03-25 14:49:35 +000047#if IS_ENABLED(CONFIG_IPV6)
48#include <net/ipv6.h>
49#include <net/ip6_fib.h>
50#include <net/ip6_route.h>
51#endif
52
Duan Jiong967680e2014-01-19 16:43:42 +080053static unsigned int ip_tunnel_hash(__be32 key, __be32 remote)
Pravin B Shelarc5441932013-03-25 14:49:35 +000054{
55 return hash_32((__force u32)key ^ (__force u32)remote,
56 IP_TNL_HASH_BITS);
57}
58
Pravin B Shelarc5441932013-03-25 14:49:35 +000059static bool ip_tunnel_key_match(const struct ip_tunnel_parm *p,
60 __be16 flags, __be32 key)
61{
62 if (p->i_flags & TUNNEL_KEY) {
63 if (flags & TUNNEL_KEY)
64 return key == p->i_key;
65 else
66 /* key expected, none present */
67 return false;
68 } else
69 return !(flags & TUNNEL_KEY);
70}
71
72/* Fallback tunnel: no source, no destination, no key, no options
73
74 Tunnel hash table:
75 We require exact key match i.e. if a key is present in packet
76 it will match only tunnel with the same key; if it is not present,
77 it will match only keyless tunnel.
78
79 All keysless packets, if not matched configured keyless tunnels
80 will match fallback tunnel.
81 Given src, dst and key, find appropriate for input tunnel.
82*/
83struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn,
84 int link, __be16 flags,
85 __be32 remote, __be32 local,
86 __be32 key)
87{
88 unsigned int hash;
89 struct ip_tunnel *t, *cand = NULL;
90 struct hlist_head *head;
91
Duan Jiong967680e2014-01-19 16:43:42 +080092 hash = ip_tunnel_hash(key, remote);
Pravin B Shelarc5441932013-03-25 14:49:35 +000093 head = &itn->tunnels[hash];
94
95 hlist_for_each_entry_rcu(t, head, hash_node) {
96 if (local != t->parms.iph.saddr ||
97 remote != t->parms.iph.daddr ||
98 !(t->dev->flags & IFF_UP))
99 continue;
100
101 if (!ip_tunnel_key_match(&t->parms, flags, key))
102 continue;
103
104 if (t->parms.link == link)
105 return t;
106 else
107 cand = t;
108 }
109
110 hlist_for_each_entry_rcu(t, head, hash_node) {
111 if (remote != t->parms.iph.daddr ||
Dmitry Popove0056592014-07-05 02:26:37 +0400112 t->parms.iph.saddr != 0 ||
Pravin B Shelarc5441932013-03-25 14:49:35 +0000113 !(t->dev->flags & IFF_UP))
114 continue;
115
116 if (!ip_tunnel_key_match(&t->parms, flags, key))
117 continue;
118
119 if (t->parms.link == link)
120 return t;
121 else if (!cand)
122 cand = t;
123 }
124
Duan Jiong967680e2014-01-19 16:43:42 +0800125 hash = ip_tunnel_hash(key, 0);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000126 head = &itn->tunnels[hash];
127
128 hlist_for_each_entry_rcu(t, head, hash_node) {
Dmitry Popove0056592014-07-05 02:26:37 +0400129 if ((local != t->parms.iph.saddr || t->parms.iph.daddr != 0) &&
130 (local != t->parms.iph.daddr || !ipv4_is_multicast(local)))
131 continue;
132
133 if (!(t->dev->flags & IFF_UP))
Pravin B Shelarc5441932013-03-25 14:49:35 +0000134 continue;
135
136 if (!ip_tunnel_key_match(&t->parms, flags, key))
137 continue;
138
139 if (t->parms.link == link)
140 return t;
141 else if (!cand)
142 cand = t;
143 }
144
Pravin B Shelarc5441932013-03-25 14:49:35 +0000145 hlist_for_each_entry_rcu(t, head, hash_node) {
William Dauchy25629fd2020-03-27 19:56:39 +0100146 if ((!(flags & TUNNEL_NO_KEY) && t->parms.i_key != key) ||
Dmitry Popove0056592014-07-05 02:26:37 +0400147 t->parms.iph.saddr != 0 ||
148 t->parms.iph.daddr != 0 ||
Pravin B Shelarc5441932013-03-25 14:49:35 +0000149 !(t->dev->flags & IFF_UP))
150 continue;
151
152 if (t->parms.link == link)
153 return t;
154 else if (!cand)
155 cand = t;
156 }
157
Pravin B Shelarc5441932013-03-25 14:49:35 +0000158 if (cand)
159 return cand;
160
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700161 t = rcu_dereference(itn->collect_md_tun);
Haishuang Yan833a8b42017-09-12 17:47:56 +0800162 if (t && t->dev->flags & IFF_UP)
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700163 return t;
164
Pravin B Shelarc5441932013-03-25 14:49:35 +0000165 if (itn->fb_tunnel_dev && itn->fb_tunnel_dev->flags & IFF_UP)
166 return netdev_priv(itn->fb_tunnel_dev);
167
Pravin B Shelarc5441932013-03-25 14:49:35 +0000168 return NULL;
169}
170EXPORT_SYMBOL_GPL(ip_tunnel_lookup);
171
172static struct hlist_head *ip_bucket(struct ip_tunnel_net *itn,
173 struct ip_tunnel_parm *parms)
174{
175 unsigned int h;
176 __be32 remote;
Steffen Klassert6d608f02014-02-21 08:41:09 +0100177 __be32 i_key = parms->i_key;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000178
179 if (parms->iph.daddr && !ipv4_is_multicast(parms->iph.daddr))
180 remote = parms->iph.daddr;
181 else
182 remote = 0;
183
Steffen Klassert6d608f02014-02-21 08:41:09 +0100184 if (!(parms->i_flags & TUNNEL_KEY) && (parms->i_flags & VTI_ISVTI))
185 i_key = 0;
186
187 h = ip_tunnel_hash(i_key, remote);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000188 return &itn->tunnels[h];
189}
190
191static void ip_tunnel_add(struct ip_tunnel_net *itn, struct ip_tunnel *t)
192{
193 struct hlist_head *head = ip_bucket(itn, &t->parms);
194
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700195 if (t->collect_md)
196 rcu_assign_pointer(itn->collect_md_tun, t);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000197 hlist_add_head_rcu(&t->hash_node, head);
198}
199
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700200static void ip_tunnel_del(struct ip_tunnel_net *itn, struct ip_tunnel *t)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000201{
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700202 if (t->collect_md)
203 rcu_assign_pointer(itn->collect_md_tun, NULL);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000204 hlist_del_init_rcu(&t->hash_node);
205}
206
207static struct ip_tunnel *ip_tunnel_find(struct ip_tunnel_net *itn,
208 struct ip_tunnel_parm *parms,
209 int type)
210{
211 __be32 remote = parms->iph.daddr;
212 __be32 local = parms->iph.saddr;
213 __be32 key = parms->i_key;
Dmitry Popov5ce54af2014-06-08 03:03:08 +0400214 __be16 flags = parms->i_flags;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000215 int link = parms->link;
216 struct ip_tunnel *t = NULL;
217 struct hlist_head *head = ip_bucket(itn, parms);
218
219 hlist_for_each_entry_rcu(t, head, hash_node) {
220 if (local == t->parms.iph.saddr &&
221 remote == t->parms.iph.daddr &&
Pravin B Shelarc5441932013-03-25 14:49:35 +0000222 link == t->parms.link &&
Dmitry Popov5ce54af2014-06-08 03:03:08 +0400223 type == t->dev->type &&
224 ip_tunnel_key_match(&t->parms, flags, key))
Pravin B Shelarc5441932013-03-25 14:49:35 +0000225 break;
226 }
227 return t;
228}
229
230static struct net_device *__ip_tunnel_create(struct net *net,
231 const struct rtnl_link_ops *ops,
232 struct ip_tunnel_parm *parms)
233{
234 int err;
235 struct ip_tunnel *tunnel;
236 struct net_device *dev;
237 char name[IFNAMSIZ];
238
Eric Dumazet9cb726a2018-04-05 06:39:27 -0700239 err = -E2BIG;
240 if (parms->name[0]) {
241 if (!dev_valid_name(parms->name))
Pravin B Shelarc5441932013-03-25 14:49:35 +0000242 goto failed;
Eric Dumazet9cb726a2018-04-05 06:39:27 -0700243 strlcpy(name, parms->name, IFNAMSIZ);
244 } else {
245 if (strlen(ops->kind) > (IFNAMSIZ - 3))
246 goto failed;
Sultan Alsawaf000ade82018-06-06 15:56:54 -0700247 strcpy(name, ops->kind);
248 strcat(name, "%d");
Pravin B Shelarc5441932013-03-25 14:49:35 +0000249 }
250
251 ASSERT_RTNL();
Tom Gundersenc835a672014-07-14 16:37:24 +0200252 dev = alloc_netdev(ops->priv_size, name, NET_NAME_UNKNOWN, ops->setup);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000253 if (!dev) {
254 err = -ENOMEM;
255 goto failed;
256 }
257 dev_net_set(dev, net);
258
259 dev->rtnl_link_ops = ops;
260
261 tunnel = netdev_priv(dev);
262 tunnel->parms = *parms;
Nicolas Dichtel5e6700b2013-06-26 16:11:28 +0200263 tunnel->net = net;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000264
265 err = register_netdevice(dev);
266 if (err)
267 goto failed_free;
268
269 return dev;
270
271failed_free:
272 free_netdev(dev);
273failed:
274 return ERR_PTR(err);
275}
276
Pravin B Shelarc5441932013-03-25 14:49:35 +0000277static int ip_tunnel_bind_dev(struct net_device *dev)
278{
279 struct net_device *tdev = NULL;
280 struct ip_tunnel *tunnel = netdev_priv(dev);
281 const struct iphdr *iph;
282 int hlen = LL_MAX_HEADER;
283 int mtu = ETH_DATA_LEN;
284 int t_hlen = tunnel->hlen + sizeof(struct iphdr);
285
286 iph = &tunnel->parms.iph;
287
288 /* Guess output device to choose reasonable mtu and needed_headroom */
289 if (iph->daddr) {
290 struct flowi4 fl4;
291 struct rtable *rt;
292
Petr Machatab0066da2018-02-27 14:53:38 +0100293 ip_tunnel_init_flow(&fl4, iph->protocol, iph->daddr,
294 iph->saddr, tunnel->parms.o_key,
295 RT_TOS(iph->tos), tunnel->parms.link,
wenxu24ba1442019-02-24 11:36:20 +0800296 tunnel->fwmark, 0);
Tom Herbert7d442fa2014-01-02 11:48:26 -0800297 rt = ip_route_output_key(tunnel->net, &fl4);
298
Pravin B Shelarc5441932013-03-25 14:49:35 +0000299 if (!IS_ERR(rt)) {
300 tdev = rt->dst.dev;
301 ip_rt_put(rt);
302 }
303 if (dev->type != ARPHRD_ETHER)
304 dev->flags |= IFF_POINTOPOINT;
Paolo Abenif27337e2016-04-28 11:04:51 +0200305
306 dst_cache_reset(&tunnel->dst_cache);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000307 }
308
309 if (!tdev && tunnel->parms.link)
Nicolas Dichtel6c742e72013-08-13 17:51:11 +0200310 tdev = __dev_get_by_index(tunnel->net, tunnel->parms.link);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000311
312 if (tdev) {
313 hlen = tdev->hard_header_len + tdev->needed_headroom;
Nicolas Dichtel82612de2018-05-31 10:59:32 +0200314 mtu = min(tdev->mtu, IP_MAX_MTU);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000315 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000316
317 dev->needed_headroom = t_hlen + hlen;
318 mtu -= (dev->hard_header_len + t_hlen);
319
Eric Dumazetb5476022017-12-11 07:17:39 -0800320 if (mtu < IPV4_MIN_MTU)
321 mtu = IPV4_MIN_MTU;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000322
323 return mtu;
324}
325
326static struct ip_tunnel *ip_tunnel_create(struct net *net,
327 struct ip_tunnel_net *itn,
328 struct ip_tunnel_parm *parms)
329{
Julia Lawall4929fd82014-05-15 05:43:20 +0200330 struct ip_tunnel *nt;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000331 struct net_device *dev;
Jarod Wilsonb96f9af2016-10-20 13:55:24 -0400332 int t_hlen;
Petr Machataf6cc9c02018-03-22 19:53:33 +0200333 int mtu;
334 int err;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000335
Eric Dumazet79134e62018-03-08 12:51:41 -0800336 dev = __ip_tunnel_create(net, itn->rtnl_link_ops, parms);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000337 if (IS_ERR(dev))
Florian Westphal6dd3c9e2014-02-14 13:14:39 +0100338 return ERR_CAST(dev);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000339
Petr Machataf6cc9c02018-03-22 19:53:33 +0200340 mtu = ip_tunnel_bind_dev(dev);
341 err = dev_set_mtu(dev, mtu);
342 if (err)
343 goto err_dev_set_mtu;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000344
345 nt = netdev_priv(dev);
Jarod Wilsonb96f9af2016-10-20 13:55:24 -0400346 t_hlen = nt->hlen + sizeof(struct iphdr);
347 dev->min_mtu = ETH_MIN_MTU;
Nicolas Dichtel82612de2018-05-31 10:59:32 +0200348 dev->max_mtu = IP_MAX_MTU - dev->hard_header_len - t_hlen;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000349 ip_tunnel_add(itn, nt);
350 return nt;
Petr Machataf6cc9c02018-03-22 19:53:33 +0200351
352err_dev_set_mtu:
353 unregister_netdevice(dev);
354 return ERR_PTR(err);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000355}
356
357int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb,
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700358 const struct tnl_ptk_info *tpi, struct metadata_dst *tun_dst,
359 bool log_ecn_error)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000360{
Li RongQing8f849852014-01-04 13:57:59 +0800361 struct pcpu_sw_netstats *tstats;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000362 const struct iphdr *iph = ip_hdr(skb);
363 int err;
364
Pravin B Shelarc5441932013-03-25 14:49:35 +0000365#ifdef CONFIG_NET_IPGRE_BROADCAST
366 if (ipv4_is_multicast(iph->daddr)) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000367 tunnel->dev->stats.multicast++;
368 skb->pkt_type = PACKET_BROADCAST;
369 }
370#endif
371
372 if ((!(tpi->flags&TUNNEL_CSUM) && (tunnel->parms.i_flags&TUNNEL_CSUM)) ||
373 ((tpi->flags&TUNNEL_CSUM) && !(tunnel->parms.i_flags&TUNNEL_CSUM))) {
374 tunnel->dev->stats.rx_crc_errors++;
375 tunnel->dev->stats.rx_errors++;
376 goto drop;
377 }
378
379 if (tunnel->parms.i_flags&TUNNEL_SEQ) {
380 if (!(tpi->flags&TUNNEL_SEQ) ||
381 (tunnel->i_seqno && (s32)(ntohl(tpi->seq) - tunnel->i_seqno) < 0)) {
382 tunnel->dev->stats.rx_fifo_errors++;
383 tunnel->dev->stats.rx_errors++;
384 goto drop;
385 }
386 tunnel->i_seqno = ntohl(tpi->seq) + 1;
387 }
388
Ying Caie96f2e72014-05-04 15:20:04 -0700389 skb_reset_network_header(skb);
390
Pravin B Shelarc5441932013-03-25 14:49:35 +0000391 err = IP_ECN_decapsulate(iph, skb);
392 if (unlikely(err)) {
393 if (log_ecn_error)
394 net_info_ratelimited("non-ECT from %pI4 with TOS=%#x\n",
395 &iph->saddr, iph->tos);
396 if (err > 1) {
397 ++tunnel->dev->stats.rx_frame_errors;
398 ++tunnel->dev->stats.rx_errors;
399 goto drop;
400 }
401 }
402
403 tstats = this_cpu_ptr(tunnel->dev->tstats);
404 u64_stats_update_begin(&tstats->syncp);
405 tstats->rx_packets++;
406 tstats->rx_bytes += skb->len;
407 u64_stats_update_end(&tstats->syncp);
408
Alexei Starovoitov81b9eab2013-11-12 14:39:13 -0800409 skb_scrub_packet(skb, !net_eq(tunnel->net, dev_net(tunnel->dev)));
410
Pravin B Shelar3d7b46c2013-06-17 17:50:02 -0700411 if (tunnel->dev->type == ARPHRD_ETHER) {
412 skb->protocol = eth_type_trans(skb, tunnel->dev);
413 skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
414 } else {
415 skb->dev = tunnel->dev;
416 }
Nicolas Dichtel64261f22013-08-13 17:51:09 +0200417
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700418 if (tun_dst)
419 skb_dst_set(skb, (struct dst_entry *)tun_dst);
420
Pravin B Shelarc5441932013-03-25 14:49:35 +0000421 gro_cells_receive(&tunnel->gro_cells, skb);
422 return 0;
423
424drop:
Haishuang Yan469f87e2017-06-15 10:29:29 +0800425 if (tun_dst)
426 dst_release((struct dst_entry *)tun_dst);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000427 kfree_skb(skb);
428 return 0;
429}
430EXPORT_SYMBOL_GPL(ip_tunnel_rcv);
431
Tom Herberta8c5f902014-11-12 11:54:09 -0800432int ip_tunnel_encap_add_ops(const struct ip_tunnel_encap_ops *ops,
433 unsigned int num)
434{
Thomas Grafbb1553c2014-12-16 21:05:20 +0100435 if (num >= MAX_IPTUN_ENCAP_OPS)
436 return -ERANGE;
437
Tom Herberta8c5f902014-11-12 11:54:09 -0800438 return !cmpxchg((const struct ip_tunnel_encap_ops **)
439 &iptun_encaps[num],
440 NULL, ops) ? 0 : -1;
441}
442EXPORT_SYMBOL(ip_tunnel_encap_add_ops);
443
444int ip_tunnel_encap_del_ops(const struct ip_tunnel_encap_ops *ops,
445 unsigned int num)
446{
447 int ret;
448
Thomas Grafbb1553c2014-12-16 21:05:20 +0100449 if (num >= MAX_IPTUN_ENCAP_OPS)
450 return -ERANGE;
451
Tom Herberta8c5f902014-11-12 11:54:09 -0800452 ret = (cmpxchg((const struct ip_tunnel_encap_ops **)
453 &iptun_encaps[num],
454 ops, NULL) == ops) ? 0 : -1;
455
456 synchronize_net();
457
458 return ret;
459}
460EXPORT_SYMBOL(ip_tunnel_encap_del_ops);
461
Tom Herbert56328482014-09-17 12:25:58 -0700462int ip_tunnel_encap_setup(struct ip_tunnel *t,
463 struct ip_tunnel_encap *ipencap)
464{
465 int hlen;
466
467 memset(&t->encap, 0, sizeof(t->encap));
468
469 hlen = ip_encap_hlen(ipencap);
470 if (hlen < 0)
471 return hlen;
472
473 t->encap.type = ipencap->type;
474 t->encap.sport = ipencap->sport;
475 t->encap.dport = ipencap->dport;
476 t->encap.flags = ipencap->flags;
477
478 t->encap_hlen = hlen;
479 t->hlen = t->encap_hlen + t->tun_hlen;
480
481 return 0;
482}
483EXPORT_SYMBOL_GPL(ip_tunnel_encap_setup);
484
Pravin B Shelar23a36472013-07-02 10:57:33 -0700485static int tnl_update_pmtu(struct net_device *dev, struct sk_buff *skb,
Timo Teräsfc24f2b22015-07-07 08:34:13 +0300486 struct rtable *rt, __be16 df,
wenxuc8b34e62019-01-22 18:39:50 +0800487 const struct iphdr *inner_iph,
488 int tunnel_hlen, __be32 dst, bool md)
Pravin B Shelar23a36472013-07-02 10:57:33 -0700489{
490 struct ip_tunnel *tunnel = netdev_priv(dev);
wenxuc8b34e62019-01-22 18:39:50 +0800491 int pkt_size;
Pravin B Shelar23a36472013-07-02 10:57:33 -0700492 int mtu;
493
wenxuc8b34e62019-01-22 18:39:50 +0800494 tunnel_hlen = md ? tunnel_hlen : tunnel->hlen;
495 pkt_size = skb->len - tunnel_hlen - dev->hard_header_len;
496
Pravin B Shelar23a36472013-07-02 10:57:33 -0700497 if (df)
498 mtu = dst_mtu(&rt->dst) - dev->hard_header_len
wenxuc8b34e62019-01-22 18:39:50 +0800499 - sizeof(struct iphdr) - tunnel_hlen;
Pravin B Shelar23a36472013-07-02 10:57:33 -0700500 else
Alan Maguiref4b3ec42019-03-06 10:25:42 +0000501 mtu = skb_valid_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu;
Pravin B Shelar23a36472013-07-02 10:57:33 -0700502
Alan Maguiref4b3ec42019-03-06 10:25:42 +0000503 if (skb_valid_dst(skb))
Hangbin Liu7a1592b2019-12-22 10:51:13 +0800504 skb_dst_update_pmtu_no_confirm(skb, mtu);
Pravin B Shelar23a36472013-07-02 10:57:33 -0700505
506 if (skb->protocol == htons(ETH_P_IP)) {
507 if (!skb_is_gso(skb) &&
Timo Teräsfc24f2b22015-07-07 08:34:13 +0300508 (inner_iph->frag_off & htons(IP_DF)) &&
509 mtu < pkt_size) {
Pravin B Shelar23a36472013-07-02 10:57:33 -0700510 memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
511 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));
512 return -E2BIG;
513 }
514 }
515#if IS_ENABLED(CONFIG_IPV6)
516 else if (skb->protocol == htons(ETH_P_IPV6)) {
Alan Maguiref4b3ec42019-03-06 10:25:42 +0000517 struct rt6_info *rt6;
wenxuc8b34e62019-01-22 18:39:50 +0800518 __be32 daddr;
519
Alan Maguiref4b3ec42019-03-06 10:25:42 +0000520 rt6 = skb_valid_dst(skb) ? (struct rt6_info *)skb_dst(skb) :
521 NULL;
wenxuc8b34e62019-01-22 18:39:50 +0800522 daddr = md ? dst : tunnel->parms.iph.daddr;
Pravin B Shelar23a36472013-07-02 10:57:33 -0700523
524 if (rt6 && mtu < dst_mtu(skb_dst(skb)) &&
525 mtu >= IPV6_MIN_MTU) {
wenxuc8b34e62019-01-22 18:39:50 +0800526 if ((daddr && !ipv4_is_multicast(daddr)) ||
Pravin B Shelar23a36472013-07-02 10:57:33 -0700527 rt6->rt6i_dst.plen == 128) {
528 rt6->rt6i_flags |= RTF_MODIFIED;
529 dst_metric_set(skb_dst(skb), RTAX_MTU, mtu);
530 }
531 }
532
533 if (!skb_is_gso(skb) && mtu >= IPV6_MIN_MTU &&
534 mtu < pkt_size) {
535 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
536 return -E2BIG;
537 }
538 }
539#endif
540 return 0;
541}
542
wenxuc8b34e62019-01-22 18:39:50 +0800543void ip_md_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
544 u8 proto, int tunnel_hlen)
Alexei Starovoitovcfc73812016-09-15 13:00:29 -0700545{
546 struct ip_tunnel *tunnel = netdev_priv(dev);
547 u32 headroom = sizeof(struct iphdr);
548 struct ip_tunnel_info *tun_info;
549 const struct ip_tunnel_key *key;
550 const struct iphdr *inner_iph;
wenxuf46fe4f2019-01-22 18:39:49 +0800551 struct rtable *rt = NULL;
Alexei Starovoitovcfc73812016-09-15 13:00:29 -0700552 struct flowi4 fl4;
553 __be16 df = 0;
554 u8 tos, ttl;
wenxuf46fe4f2019-01-22 18:39:49 +0800555 bool use_cache;
Alexei Starovoitovcfc73812016-09-15 13:00:29 -0700556
557 tun_info = skb_tunnel_info(skb);
558 if (unlikely(!tun_info || !(tun_info->mode & IP_TUNNEL_INFO_TX) ||
559 ip_tunnel_info_af(tun_info) != AF_INET))
560 goto tx_error;
561 key = &tun_info->key;
562 memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
563 inner_iph = (const struct iphdr *)skb_inner_network_header(skb);
564 tos = key->tos;
565 if (tos == 1) {
566 if (skb->protocol == htons(ETH_P_IP))
567 tos = inner_iph->tos;
568 else if (skb->protocol == htons(ETH_P_IPV6))
569 tos = ipv6_get_dsfield((const struct ipv6hdr *)inner_iph);
570 }
wenxu6e6b9042019-01-22 18:39:51 +0800571 ip_tunnel_init_flow(&fl4, proto, key->u.ipv4.dst, key->u.ipv4.src,
572 tunnel_id_to_key32(key->tun_id), RT_TOS(tos),
wenxu24ba1442019-02-24 11:36:20 +0800573 0, skb->mark, skb_get_hash(skb));
Alexei Starovoitovcfc73812016-09-15 13:00:29 -0700574 if (tunnel->encap.type != TUNNEL_ENCAP_NONE)
575 goto tx_error;
wenxuf46fe4f2019-01-22 18:39:49 +0800576
577 use_cache = ip_tunnel_dst_cache_usable(skb, tun_info);
578 if (use_cache)
579 rt = dst_cache_get_ip4(&tun_info->dst_cache, &fl4.saddr);
580 if (!rt) {
581 rt = ip_route_output_key(tunnel->net, &fl4);
582 if (IS_ERR(rt)) {
583 dev->stats.tx_carrier_errors++;
584 goto tx_error;
585 }
586 if (use_cache)
587 dst_cache_set_ip4(&tun_info->dst_cache, &rt->dst,
588 fl4.saddr);
Alexei Starovoitovcfc73812016-09-15 13:00:29 -0700589 }
590 if (rt->dst.dev == dev) {
591 ip_rt_put(rt);
592 dev->stats.collisions++;
593 goto tx_error;
594 }
wenxuc8b34e62019-01-22 18:39:50 +0800595
596 if (key->tun_flags & TUNNEL_DONT_FRAGMENT)
597 df = htons(IP_DF);
598 if (tnl_update_pmtu(dev, skb, rt, df, inner_iph, tunnel_hlen,
599 key->u.ipv4.dst, true)) {
600 ip_rt_put(rt);
601 goto tx_error;
602 }
603
Alexei Starovoitovcfc73812016-09-15 13:00:29 -0700604 tos = ip_tunnel_ecn_encap(tos, inner_iph, skb);
605 ttl = key->ttl;
606 if (ttl == 0) {
607 if (skb->protocol == htons(ETH_P_IP))
608 ttl = inner_iph->ttl;
609 else if (skb->protocol == htons(ETH_P_IPV6))
610 ttl = ((const struct ipv6hdr *)inner_iph)->hop_limit;
611 else
612 ttl = ip4_dst_hoplimit(&rt->dst);
613 }
wenxuc8b34e62019-01-22 18:39:50 +0800614
615 if (!df && skb->protocol == htons(ETH_P_IP))
Alexei Starovoitovcfc73812016-09-15 13:00:29 -0700616 df = inner_iph->frag_off & htons(IP_DF);
wenxuc8b34e62019-01-22 18:39:50 +0800617
Alexei Starovoitovcfc73812016-09-15 13:00:29 -0700618 headroom += LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len;
619 if (headroom > dev->needed_headroom)
620 dev->needed_headroom = headroom;
621
622 if (skb_cow_head(skb, dev->needed_headroom)) {
623 ip_rt_put(rt);
624 goto tx_dropped;
625 }
Haishuang Yan0f693f12017-09-07 14:08:34 +0800626 iptunnel_xmit(NULL, rt, skb, fl4.saddr, fl4.daddr, proto, tos, ttl,
627 df, !net_eq(tunnel->net, dev_net(dev)));
Alexei Starovoitovcfc73812016-09-15 13:00:29 -0700628 return;
629tx_error:
630 dev->stats.tx_errors++;
631 goto kfree;
632tx_dropped:
633 dev->stats.tx_dropped++;
634kfree:
635 kfree_skb(skb);
636}
637EXPORT_SYMBOL_GPL(ip_md_tunnel_xmit);
638
Pravin B Shelarc5441932013-03-25 14:49:35 +0000639void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
Tom Herbert56328482014-09-17 12:25:58 -0700640 const struct iphdr *tnl_params, u8 protocol)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000641{
642 struct ip_tunnel *tunnel = netdev_priv(dev);
wenxu186d9362019-02-24 08:24:45 +0800643 struct ip_tunnel_info *tun_info = NULL;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000644 const struct iphdr *inner_iph;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000645 unsigned int max_headroom; /* The extra header space needed */
wenxu186d9362019-02-24 08:24:45 +0800646 struct rtable *rt = NULL; /* Route to the other host */
647 bool use_cache = false;
648 struct flowi4 fl4;
649 bool md = false;
Timo Teräs22fb22e2014-05-16 08:34:39 +0300650 bool connected;
wenxu186d9362019-02-24 08:24:45 +0800651 u8 tos, ttl;
652 __be32 dst;
653 __be16 df;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000654
655 inner_iph = (const struct iphdr *)skb_inner_network_header(skb);
Timo Teräs22fb22e2014-05-16 08:34:39 +0300656 connected = (tunnel->parms.iph.daddr != 0);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000657
Bernie Harris5146d1f2016-02-22 12:58:05 +1300658 memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
659
Pravin B Shelarc5441932013-03-25 14:49:35 +0000660 dst = tnl_params->daddr;
661 if (dst == 0) {
662 /* NBMA tunnel */
663
Ian Morris51456b22015-04-03 09:17:26 +0100664 if (!skb_dst(skb)) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000665 dev->stats.tx_fifo_errors++;
666 goto tx_error;
667 }
668
wenxud71b57532019-01-19 13:11:25 +0800669 tun_info = skb_tunnel_info(skb);
670 if (tun_info && (tun_info->mode & IP_TUNNEL_INFO_TX) &&
671 ip_tunnel_info_af(tun_info) == AF_INET &&
wenxu186d9362019-02-24 08:24:45 +0800672 tun_info->key.u.ipv4.dst) {
wenxud71b57532019-01-19 13:11:25 +0800673 dst = tun_info->key.u.ipv4.dst;
wenxu186d9362019-02-24 08:24:45 +0800674 md = true;
675 connected = true;
676 }
wenxud71b57532019-01-19 13:11:25 +0800677 else if (skb->protocol == htons(ETH_P_IP)) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000678 rt = skb_rtable(skb);
679 dst = rt_nexthop(rt, inner_iph->daddr);
680 }
681#if IS_ENABLED(CONFIG_IPV6)
682 else if (skb->protocol == htons(ETH_P_IPV6)) {
683 const struct in6_addr *addr6;
684 struct neighbour *neigh;
685 bool do_tx_error_icmp;
686 int addr_type;
687
688 neigh = dst_neigh_lookup(skb_dst(skb),
689 &ipv6_hdr(skb)->daddr);
Ian Morris51456b22015-04-03 09:17:26 +0100690 if (!neigh)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000691 goto tx_error;
692
693 addr6 = (const struct in6_addr *)&neigh->primary_key;
694 addr_type = ipv6_addr_type(addr6);
695
696 if (addr_type == IPV6_ADDR_ANY) {
697 addr6 = &ipv6_hdr(skb)->daddr;
698 addr_type = ipv6_addr_type(addr6);
699 }
700
701 if ((addr_type & IPV6_ADDR_COMPATv4) == 0)
702 do_tx_error_icmp = true;
703 else {
704 do_tx_error_icmp = false;
705 dst = addr6->s6_addr32[3];
706 }
707 neigh_release(neigh);
708 if (do_tx_error_icmp)
709 goto tx_error_icmp;
710 }
711#endif
712 else
713 goto tx_error;
Tom Herbert7d442fa2014-01-02 11:48:26 -0800714
wenxu186d9362019-02-24 08:24:45 +0800715 if (!md)
716 connected = false;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000717 }
718
719 tos = tnl_params->tos;
720 if (tos & 0x1) {
721 tos &= ~0x1;
Tom Herbert7d442fa2014-01-02 11:48:26 -0800722 if (skb->protocol == htons(ETH_P_IP)) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000723 tos = inner_iph->tos;
Tom Herbert7d442fa2014-01-02 11:48:26 -0800724 connected = false;
725 } else if (skb->protocol == htons(ETH_P_IPV6)) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000726 tos = ipv6_get_dsfield((const struct ipv6hdr *)inner_iph);
Tom Herbert7d442fa2014-01-02 11:48:26 -0800727 connected = false;
728 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000729 }
730
David S. Miller0f3e9c92018-03-06 00:53:44 -0500731 ip_tunnel_init_flow(&fl4, protocol, dst, tnl_params->saddr,
732 tunnel->parms.o_key, RT_TOS(tos), tunnel->parms.link,
wenxu24ba1442019-02-24 11:36:20 +0800733 tunnel->fwmark, skb_get_hash(skb));
Tom Herbert7d442fa2014-01-02 11:48:26 -0800734
Tom Herbert56328482014-09-17 12:25:58 -0700735 if (ip_tunnel_encap(skb, tunnel, &protocol, &fl4) < 0)
736 goto tx_error;
737
wenxu186d9362019-02-24 08:24:45 +0800738 if (connected && md) {
739 use_cache = ip_tunnel_dst_cache_usable(skb, tun_info);
740 if (use_cache)
741 rt = dst_cache_get_ip4(&tun_info->dst_cache,
742 &fl4.saddr);
743 } else {
744 rt = connected ? dst_cache_get_ip4(&tunnel->dst_cache,
745 &fl4.saddr) : NULL;
746 }
Tom Herbert7d442fa2014-01-02 11:48:26 -0800747
748 if (!rt) {
749 rt = ip_route_output_key(tunnel->net, &fl4);
750
751 if (IS_ERR(rt)) {
752 dev->stats.tx_carrier_errors++;
753 goto tx_error;
754 }
wenxu186d9362019-02-24 08:24:45 +0800755 if (use_cache)
756 dst_cache_set_ip4(&tun_info->dst_cache, &rt->dst,
757 fl4.saddr);
758 else if (!md && connected)
Paolo Abenie09acdd2016-02-12 15:43:55 +0100759 dst_cache_set_ip4(&tunnel->dst_cache, &rt->dst,
760 fl4.saddr);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000761 }
Tom Herbert7d442fa2014-01-02 11:48:26 -0800762
Pravin B Shelar0e6fbc52013-06-17 17:49:56 -0700763 if (rt->dst.dev == dev) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000764 ip_rt_put(rt);
765 dev->stats.collisions++;
766 goto tx_error;
767 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000768
wenxuc8b34e62019-01-22 18:39:50 +0800769 if (tnl_update_pmtu(dev, skb, rt, tnl_params->frag_off, inner_iph,
770 0, 0, false)) {
Pravin B Shelar23a36472013-07-02 10:57:33 -0700771 ip_rt_put(rt);
772 goto tx_error;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000773 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000774
775 if (tunnel->err_count > 0) {
776 if (time_before(jiffies,
777 tunnel->err_time + IPTUNNEL_ERR_TIMEO)) {
778 tunnel->err_count--;
779
780 dst_link_failure(skb);
781 } else
782 tunnel->err_count = 0;
783 }
784
Pravin B Shelard4a71b12013-09-25 09:57:47 -0700785 tos = ip_tunnel_ecn_encap(tos, inner_iph, skb);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000786 ttl = tnl_params->ttl;
787 if (ttl == 0) {
788 if (skb->protocol == htons(ETH_P_IP))
789 ttl = inner_iph->ttl;
790#if IS_ENABLED(CONFIG_IPV6)
791 else if (skb->protocol == htons(ETH_P_IPV6))
792 ttl = ((const struct ipv6hdr *)inner_iph)->hop_limit;
793#endif
794 else
795 ttl = ip4_dst_hoplimit(&rt->dst);
796 }
797
Pravin B Shelar23a36472013-07-02 10:57:33 -0700798 df = tnl_params->frag_off;
Philip Prindeville22a59be2016-06-14 15:53:02 -0600799 if (skb->protocol == htons(ETH_P_IP) && !tunnel->ignore_df)
Pravin B Shelar23a36472013-07-02 10:57:33 -0700800 df |= (inner_iph->frag_off&htons(IP_DF));
801
Pravin B Shelar0e6fbc52013-06-17 17:49:56 -0700802 max_headroom = LL_RESERVED_SPACE(rt->dst.dev) + sizeof(struct iphdr)
Tom Herbert7371e022014-10-03 15:48:07 -0700803 + rt->dst.header_len + ip_encap_hlen(&tunnel->encap);
Steffen Klassert3e08f4a2013-10-01 11:33:59 +0200804 if (max_headroom > dev->needed_headroom)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000805 dev->needed_headroom = max_headroom;
Steffen Klassert3e08f4a2013-10-01 11:33:59 +0200806
807 if (skb_cow_head(skb, dev->needed_headroom)) {
Dmitry Popov586d5fc2014-06-06 04:34:37 +0400808 ip_rt_put(rt);
Steffen Klassert3e08f4a2013-10-01 11:33:59 +0200809 dev->stats.tx_dropped++;
Eric Dumazet3acfa1e2014-01-18 18:27:49 -0800810 kfree_skb(skb);
Steffen Klassert3e08f4a2013-10-01 11:33:59 +0200811 return;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000812 }
813
Pravin B Shelar039f5062015-12-24 14:34:54 -0800814 iptunnel_xmit(NULL, rt, skb, fl4.saddr, fl4.daddr, protocol, tos, ttl,
815 df, !net_eq(tunnel->net, dev_net(dev)));
Pravin B Shelarc5441932013-03-25 14:49:35 +0000816 return;
817
818#if IS_ENABLED(CONFIG_IPV6)
819tx_error_icmp:
820 dst_link_failure(skb);
821#endif
822tx_error:
823 dev->stats.tx_errors++;
Eric Dumazet3acfa1e2014-01-18 18:27:49 -0800824 kfree_skb(skb);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000825}
826EXPORT_SYMBOL_GPL(ip_tunnel_xmit);
827
828static void ip_tunnel_update(struct ip_tunnel_net *itn,
829 struct ip_tunnel *t,
830 struct net_device *dev,
831 struct ip_tunnel_parm *p,
Craig Gallek9830ad42017-04-19 12:30:54 -0400832 bool set_mtu,
833 __u32 fwmark)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000834{
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700835 ip_tunnel_del(itn, t);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000836 t->parms.iph.saddr = p->iph.saddr;
837 t->parms.iph.daddr = p->iph.daddr;
838 t->parms.i_key = p->i_key;
839 t->parms.o_key = p->o_key;
840 if (dev->type != ARPHRD_ETHER) {
841 memcpy(dev->dev_addr, &p->iph.saddr, 4);
842 memcpy(dev->broadcast, &p->iph.daddr, 4);
843 }
844 ip_tunnel_add(itn, t);
845
846 t->parms.iph.ttl = p->iph.ttl;
847 t->parms.iph.tos = p->iph.tos;
848 t->parms.iph.frag_off = p->iph.frag_off;
849
Craig Gallek9830ad42017-04-19 12:30:54 -0400850 if (t->parms.link != p->link || t->fwmark != fwmark) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000851 int mtu;
852
853 t->parms.link = p->link;
Craig Gallek9830ad42017-04-19 12:30:54 -0400854 t->fwmark = fwmark;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000855 mtu = ip_tunnel_bind_dev(dev);
856 if (set_mtu)
857 dev->mtu = mtu;
858 }
Paolo Abenie09acdd2016-02-12 15:43:55 +0100859 dst_cache_reset(&t->dst_cache);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000860 netdev_state_change(dev);
861}
862
863int ip_tunnel_ioctl(struct net_device *dev, struct ip_tunnel_parm *p, int cmd)
864{
865 int err = 0;
Nicolas Dichtel8c923ce2014-04-16 11:19:32 +0200866 struct ip_tunnel *t = netdev_priv(dev);
867 struct net *net = t->net;
868 struct ip_tunnel_net *itn = net_generic(net, t->ip_tnl_net_id);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000869
Pravin B Shelarc5441932013-03-25 14:49:35 +0000870 switch (cmd) {
871 case SIOCGETTUNNEL:
Nicolas Dichtel8c923ce2014-04-16 11:19:32 +0200872 if (dev == itn->fb_tunnel_dev) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000873 t = ip_tunnel_find(itn, p, itn->fb_tunnel_dev->type);
Ian Morris51456b22015-04-03 09:17:26 +0100874 if (!t)
Nicolas Dichtel8c923ce2014-04-16 11:19:32 +0200875 t = netdev_priv(dev);
876 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000877 memcpy(p, &t->parms, sizeof(*p));
878 break;
879
880 case SIOCADDTUNNEL:
881 case SIOCCHGTUNNEL:
882 err = -EPERM;
883 if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
884 goto done;
885 if (p->iph.ttl)
886 p->iph.frag_off |= htons(IP_DF);
Dmitry Popov7c8e6b92014-06-08 02:06:25 +0400887 if (!(p->i_flags & VTI_ISVTI)) {
888 if (!(p->i_flags & TUNNEL_KEY))
889 p->i_key = 0;
890 if (!(p->o_flags & TUNNEL_KEY))
891 p->o_key = 0;
892 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000893
Eric Dumazet79134e62018-03-08 12:51:41 -0800894 t = ip_tunnel_find(itn, p, itn->type);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000895
Steffen Klassertd61746b2014-09-22 09:11:08 +0200896 if (cmd == SIOCADDTUNNEL) {
897 if (!t) {
898 t = ip_tunnel_create(net, itn, p);
899 err = PTR_ERR_OR_ZERO(t);
900 break;
901 }
902
903 err = -EEXIST;
Duan Jiongee30ef4d2014-05-15 13:07:02 +0800904 break;
Florian Westphal6dd3c9e2014-02-14 13:14:39 +0100905 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000906 if (dev != itn->fb_tunnel_dev && cmd == SIOCCHGTUNNEL) {
Ian Morris00db4122015-04-03 09:17:27 +0100907 if (t) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000908 if (t->dev != dev) {
909 err = -EEXIST;
910 break;
911 }
912 } else {
913 unsigned int nflags = 0;
914
915 if (ipv4_is_multicast(p->iph.daddr))
916 nflags = IFF_BROADCAST;
917 else if (p->iph.daddr)
918 nflags = IFF_POINTOPOINT;
919
920 if ((dev->flags^nflags)&(IFF_POINTOPOINT|IFF_BROADCAST)) {
921 err = -EINVAL;
922 break;
923 }
924
925 t = netdev_priv(dev);
926 }
927 }
928
929 if (t) {
930 err = 0;
Craig Gallek9830ad42017-04-19 12:30:54 -0400931 ip_tunnel_update(itn, t, dev, p, true, 0);
Florian Westphal6dd3c9e2014-02-14 13:14:39 +0100932 } else {
933 err = -ENOENT;
934 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000935 break;
936
937 case SIOCDELTUNNEL:
938 err = -EPERM;
939 if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
940 goto done;
941
942 if (dev == itn->fb_tunnel_dev) {
943 err = -ENOENT;
944 t = ip_tunnel_find(itn, p, itn->fb_tunnel_dev->type);
Ian Morris51456b22015-04-03 09:17:26 +0100945 if (!t)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000946 goto done;
947 err = -EPERM;
948 if (t == netdev_priv(itn->fb_tunnel_dev))
949 goto done;
950 dev = t->dev;
951 }
952 unregister_netdevice(dev);
953 err = 0;
954 break;
955
956 default:
957 err = -EINVAL;
958 }
959
960done:
961 return err;
962}
963EXPORT_SYMBOL_GPL(ip_tunnel_ioctl);
964
David Wragg7e059152016-02-10 00:05:58 +0000965int __ip_tunnel_change_mtu(struct net_device *dev, int new_mtu, bool strict)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000966{
967 struct ip_tunnel *tunnel = netdev_priv(dev);
968 int t_hlen = tunnel->hlen + sizeof(struct iphdr);
Nicolas Dichtel82612de2018-05-31 10:59:32 +0200969 int max_mtu = IP_MAX_MTU - dev->hard_header_len - t_hlen;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000970
Jarod Wilsonb96f9af2016-10-20 13:55:24 -0400971 if (new_mtu < ETH_MIN_MTU)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000972 return -EINVAL;
David Wragg7e059152016-02-10 00:05:58 +0000973
974 if (new_mtu > max_mtu) {
975 if (strict)
976 return -EINVAL;
977
978 new_mtu = max_mtu;
979 }
980
Pravin B Shelarc5441932013-03-25 14:49:35 +0000981 dev->mtu = new_mtu;
982 return 0;
983}
David Wragg7e059152016-02-10 00:05:58 +0000984EXPORT_SYMBOL_GPL(__ip_tunnel_change_mtu);
985
986int ip_tunnel_change_mtu(struct net_device *dev, int new_mtu)
987{
988 return __ip_tunnel_change_mtu(dev, new_mtu, true);
989}
Pravin B Shelarc5441932013-03-25 14:49:35 +0000990EXPORT_SYMBOL_GPL(ip_tunnel_change_mtu);
991
992static void ip_tunnel_dev_free(struct net_device *dev)
993{
994 struct ip_tunnel *tunnel = netdev_priv(dev);
995
996 gro_cells_destroy(&tunnel->gro_cells);
Paolo Abenie09acdd2016-02-12 15:43:55 +0100997 dst_cache_destroy(&tunnel->dst_cache);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000998 free_percpu(dev->tstats);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000999}
1000
1001void ip_tunnel_dellink(struct net_device *dev, struct list_head *head)
1002{
Pravin B Shelarc5441932013-03-25 14:49:35 +00001003 struct ip_tunnel *tunnel = netdev_priv(dev);
1004 struct ip_tunnel_net *itn;
1005
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001006 itn = net_generic(tunnel->net, tunnel->ip_tnl_net_id);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001007
1008 if (itn->fb_tunnel_dev != dev) {
Pravin B Shelar2e15ea32015-08-07 23:51:42 -07001009 ip_tunnel_del(itn, netdev_priv(dev));
Pravin B Shelarc5441932013-03-25 14:49:35 +00001010 unregister_netdevice_queue(dev, head);
1011 }
1012}
1013EXPORT_SYMBOL_GPL(ip_tunnel_dellink);
1014
Nicolas Dichtel1728d4f2015-01-15 15:11:17 +01001015struct net *ip_tunnel_get_link_net(const struct net_device *dev)
1016{
1017 struct ip_tunnel *tunnel = netdev_priv(dev);
1018
1019 return tunnel->net;
1020}
1021EXPORT_SYMBOL(ip_tunnel_get_link_net);
1022
Nicolas Dichtel1e995842015-04-02 17:07:02 +02001023int ip_tunnel_get_iflink(const struct net_device *dev)
1024{
1025 struct ip_tunnel *tunnel = netdev_priv(dev);
1026
1027 return tunnel->parms.link;
1028}
1029EXPORT_SYMBOL(ip_tunnel_get_iflink);
1030
Alexey Dobriyanc7d03a02016-11-17 04:58:21 +03001031int ip_tunnel_init_net(struct net *net, unsigned int ip_tnl_net_id,
Pravin B Shelarc5441932013-03-25 14:49:35 +00001032 struct rtnl_link_ops *ops, char *devname)
1033{
1034 struct ip_tunnel_net *itn = net_generic(net, ip_tnl_net_id);
1035 struct ip_tunnel_parm parms;
stephen hemminger6261d982013-08-05 22:51:37 -07001036 unsigned int i;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001037
Eric Dumazet79134e62018-03-08 12:51:41 -08001038 itn->rtnl_link_ops = ops;
stephen hemminger6261d982013-08-05 22:51:37 -07001039 for (i = 0; i < IP_TNL_HASH_SIZE; i++)
1040 INIT_HLIST_HEAD(&itn->tunnels[i]);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001041
Eric Dumazet79134e62018-03-08 12:51:41 -08001042 if (!ops || !net_has_fallback_tunnels(net)) {
1043 struct ip_tunnel_net *it_init_net;
1044
1045 it_init_net = net_generic(&init_net, ip_tnl_net_id);
1046 itn->type = it_init_net->type;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001047 itn->fb_tunnel_dev = NULL;
1048 return 0;
1049 }
stephen hemminger6261d982013-08-05 22:51:37 -07001050
Pravin B Shelarc5441932013-03-25 14:49:35 +00001051 memset(&parms, 0, sizeof(parms));
1052 if (devname)
1053 strlcpy(parms.name, devname, IFNAMSIZ);
1054
1055 rtnl_lock();
1056 itn->fb_tunnel_dev = __ip_tunnel_create(net, ops, &parms);
Dan Carpenterea857f22013-08-19 10:05:10 +03001057 /* FB netdevice is special: we have one, and only one per netns.
1058 * Allowing to move it to another netns is clearly unsafe.
1059 */
Steffen Klassert67013282013-10-01 11:34:48 +02001060 if (!IS_ERR(itn->fb_tunnel_dev)) {
Dan Carpenterb4de77a2013-08-23 11:15:37 +03001061 itn->fb_tunnel_dev->features |= NETIF_F_NETNS_LOCAL;
Steffen Klassert78ff4be2014-05-19 11:36:56 +02001062 itn->fb_tunnel_dev->mtu = ip_tunnel_bind_dev(itn->fb_tunnel_dev);
Steffen Klassert67013282013-10-01 11:34:48 +02001063 ip_tunnel_add(itn, netdev_priv(itn->fb_tunnel_dev));
Eric Dumazet79134e62018-03-08 12:51:41 -08001064 itn->type = itn->fb_tunnel_dev->type;
Steffen Klassert67013282013-10-01 11:34:48 +02001065 }
Dan Carpenterb4de77a2013-08-23 11:15:37 +03001066 rtnl_unlock();
Pravin B Shelarc5441932013-03-25 14:49:35 +00001067
Sachin Kamat27d79f32014-01-27 12:13:57 +05301068 return PTR_ERR_OR_ZERO(itn->fb_tunnel_dev);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001069}
1070EXPORT_SYMBOL_GPL(ip_tunnel_init_net);
1071
Eric Dumazet79134e62018-03-08 12:51:41 -08001072static void ip_tunnel_destroy(struct net *net, struct ip_tunnel_net *itn,
1073 struct list_head *head,
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001074 struct rtnl_link_ops *ops)
Pravin B Shelarc5441932013-03-25 14:49:35 +00001075{
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001076 struct net_device *dev, *aux;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001077 int h;
1078
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001079 for_each_netdev_safe(net, dev, aux)
1080 if (dev->rtnl_link_ops == ops)
1081 unregister_netdevice_queue(dev, head);
1082
Pravin B Shelarc5441932013-03-25 14:49:35 +00001083 for (h = 0; h < IP_TNL_HASH_SIZE; h++) {
1084 struct ip_tunnel *t;
1085 struct hlist_node *n;
1086 struct hlist_head *thead = &itn->tunnels[h];
1087
1088 hlist_for_each_entry_safe(t, n, thead, hash_node)
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001089 /* If dev is in the same netns, it has already
1090 * been added to the list by the previous loop.
1091 */
1092 if (!net_eq(dev_net(t->dev), net))
1093 unregister_netdevice_queue(t->dev, head);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001094 }
Pravin B Shelarc5441932013-03-25 14:49:35 +00001095}
1096
Eric Dumazet64bc1782017-09-19 16:27:09 -07001097void ip_tunnel_delete_nets(struct list_head *net_list, unsigned int id,
1098 struct rtnl_link_ops *ops)
Pravin B Shelarc5441932013-03-25 14:49:35 +00001099{
Eric Dumazet64bc1782017-09-19 16:27:09 -07001100 struct ip_tunnel_net *itn;
1101 struct net *net;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001102 LIST_HEAD(list);
1103
1104 rtnl_lock();
Eric Dumazet64bc1782017-09-19 16:27:09 -07001105 list_for_each_entry(net, net_list, exit_list) {
1106 itn = net_generic(net, id);
Eric Dumazet79134e62018-03-08 12:51:41 -08001107 ip_tunnel_destroy(net, itn, &list, ops);
Eric Dumazet64bc1782017-09-19 16:27:09 -07001108 }
Pravin B Shelarc5441932013-03-25 14:49:35 +00001109 unregister_netdevice_many(&list);
1110 rtnl_unlock();
Pravin B Shelarc5441932013-03-25 14:49:35 +00001111}
Eric Dumazet64bc1782017-09-19 16:27:09 -07001112EXPORT_SYMBOL_GPL(ip_tunnel_delete_nets);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001113
1114int ip_tunnel_newlink(struct net_device *dev, struct nlattr *tb[],
Craig Gallek9830ad42017-04-19 12:30:54 -04001115 struct ip_tunnel_parm *p, __u32 fwmark)
Pravin B Shelarc5441932013-03-25 14:49:35 +00001116{
1117 struct ip_tunnel *nt;
1118 struct net *net = dev_net(dev);
1119 struct ip_tunnel_net *itn;
1120 int mtu;
1121 int err;
1122
1123 nt = netdev_priv(dev);
1124 itn = net_generic(net, nt->ip_tnl_net_id);
1125
Pravin B Shelar2e15ea32015-08-07 23:51:42 -07001126 if (nt->collect_md) {
1127 if (rtnl_dereference(itn->collect_md_tun))
1128 return -EEXIST;
1129 } else {
1130 if (ip_tunnel_find(itn, p, dev->type))
1131 return -EEXIST;
1132 }
Pravin B Shelarc5441932013-03-25 14:49:35 +00001133
Nicolas Dichtel5e6700b2013-06-26 16:11:28 +02001134 nt->net = net;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001135 nt->parms = *p;
Craig Gallek9830ad42017-04-19 12:30:54 -04001136 nt->fwmark = fwmark;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001137 err = register_netdevice(dev);
1138 if (err)
Petr Machataf6cc9c02018-03-22 19:53:33 +02001139 goto err_register_netdevice;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001140
1141 if (dev->type == ARPHRD_ETHER && !tb[IFLA_ADDRESS])
1142 eth_hw_addr_random(dev);
1143
1144 mtu = ip_tunnel_bind_dev(dev);
Stefano Brivio24fc7972018-03-15 17:16:28 +01001145 if (tb[IFLA_MTU]) {
Nicolas Dichtel82612de2018-05-31 10:59:32 +02001146 unsigned int max = IP_MAX_MTU - dev->hard_header_len - nt->hlen;
Stefano Brivio24fc7972018-03-15 17:16:28 +01001147
David S. Miller5568cdc2018-03-29 11:42:14 -04001148 mtu = clamp(dev->mtu, (unsigned int)ETH_MIN_MTU,
1149 (unsigned int)(max - sizeof(struct iphdr)));
Petr Machataf6cc9c02018-03-22 19:53:33 +02001150 }
Pravin B Shelarc5441932013-03-25 14:49:35 +00001151
David S. Miller5568cdc2018-03-29 11:42:14 -04001152 err = dev_set_mtu(dev, mtu);
1153 if (err)
1154 goto err_dev_set_mtu;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001155
1156 ip_tunnel_add(itn, nt);
Petr Machataf6cc9c02018-03-22 19:53:33 +02001157 return 0;
1158
1159err_dev_set_mtu:
1160 unregister_netdevice(dev);
1161err_register_netdevice:
Pravin B Shelarc5441932013-03-25 14:49:35 +00001162 return err;
1163}
1164EXPORT_SYMBOL_GPL(ip_tunnel_newlink);
1165
1166int ip_tunnel_changelink(struct net_device *dev, struct nlattr *tb[],
Craig Gallek9830ad42017-04-19 12:30:54 -04001167 struct ip_tunnel_parm *p, __u32 fwmark)
Pravin B Shelarc5441932013-03-25 14:49:35 +00001168{
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001169 struct ip_tunnel *t;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001170 struct ip_tunnel *tunnel = netdev_priv(dev);
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001171 struct net *net = tunnel->net;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001172 struct ip_tunnel_net *itn = net_generic(net, tunnel->ip_tnl_net_id);
1173
1174 if (dev == itn->fb_tunnel_dev)
1175 return -EINVAL;
1176
Pravin B Shelarc5441932013-03-25 14:49:35 +00001177 t = ip_tunnel_find(itn, p, dev->type);
1178
1179 if (t) {
1180 if (t->dev != dev)
1181 return -EEXIST;
1182 } else {
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001183 t = tunnel;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001184
1185 if (dev->type != ARPHRD_ETHER) {
1186 unsigned int nflags = 0;
1187
1188 if (ipv4_is_multicast(p->iph.daddr))
1189 nflags = IFF_BROADCAST;
1190 else if (p->iph.daddr)
1191 nflags = IFF_POINTOPOINT;
1192
1193 if ((dev->flags ^ nflags) &
1194 (IFF_POINTOPOINT | IFF_BROADCAST))
1195 return -EINVAL;
1196 }
1197 }
1198
Craig Gallek9830ad42017-04-19 12:30:54 -04001199 ip_tunnel_update(itn, t, dev, p, !tb[IFLA_MTU], fwmark);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001200 return 0;
1201}
1202EXPORT_SYMBOL_GPL(ip_tunnel_changelink);
1203
1204int ip_tunnel_init(struct net_device *dev)
1205{
1206 struct ip_tunnel *tunnel = netdev_priv(dev);
1207 struct iphdr *iph = &tunnel->parms.iph;
WANG Cong1c213bd2014-02-13 11:46:28 -08001208 int err;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001209
David S. Millercf124db2017-05-08 12:52:56 -04001210 dev->needs_free_netdev = true;
1211 dev->priv_destructor = ip_tunnel_dev_free;
WANG Cong1c213bd2014-02-13 11:46:28 -08001212 dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001213 if (!dev->tstats)
1214 return -ENOMEM;
1215
Paolo Abenie09acdd2016-02-12 15:43:55 +01001216 err = dst_cache_init(&tunnel->dst_cache, GFP_KERNEL);
1217 if (err) {
Tom Herbert9a4aa9a2014-01-02 11:48:33 -08001218 free_percpu(dev->tstats);
Paolo Abenie09acdd2016-02-12 15:43:55 +01001219 return err;
Tom Herbert9a4aa9a2014-01-02 11:48:33 -08001220 }
1221
Pravin B Shelarc5441932013-03-25 14:49:35 +00001222 err = gro_cells_init(&tunnel->gro_cells, dev);
1223 if (err) {
Paolo Abenie09acdd2016-02-12 15:43:55 +01001224 dst_cache_destroy(&tunnel->dst_cache);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001225 free_percpu(dev->tstats);
1226 return err;
1227 }
1228
1229 tunnel->dev = dev;
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001230 tunnel->net = dev_net(dev);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001231 strcpy(tunnel->parms.name, dev->name);
1232 iph->version = 4;
1233 iph->ihl = 5;
1234
William Dauchyd0f41852020-01-21 15:26:24 +01001235 if (tunnel->collect_md)
Pravin B Shelar2e15ea32015-08-07 23:51:42 -07001236 netif_keep_dst(dev);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001237 return 0;
1238}
1239EXPORT_SYMBOL_GPL(ip_tunnel_init);
1240
1241void ip_tunnel_uninit(struct net_device *dev)
1242{
Pravin B Shelarc5441932013-03-25 14:49:35 +00001243 struct ip_tunnel *tunnel = netdev_priv(dev);
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001244 struct net *net = tunnel->net;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001245 struct ip_tunnel_net *itn;
1246
1247 itn = net_generic(net, tunnel->ip_tnl_net_id);
1248 /* fb_tunnel_dev will be unregisted in net-exit call. */
1249 if (itn->fb_tunnel_dev != dev)
Pravin B Shelar2e15ea32015-08-07 23:51:42 -07001250 ip_tunnel_del(itn, netdev_priv(dev));
Tom Herbert7d442fa2014-01-02 11:48:26 -08001251
Paolo Abenie09acdd2016-02-12 15:43:55 +01001252 dst_cache_reset(&tunnel->dst_cache);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001253}
1254EXPORT_SYMBOL_GPL(ip_tunnel_uninit);
1255
1256/* Do least required initialization, rest of init is done in tunnel_init call */
Alexey Dobriyanc7d03a02016-11-17 04:58:21 +03001257void ip_tunnel_setup(struct net_device *dev, unsigned int net_id)
Pravin B Shelarc5441932013-03-25 14:49:35 +00001258{
1259 struct ip_tunnel *tunnel = netdev_priv(dev);
1260 tunnel->ip_tnl_net_id = net_id;
1261}
1262EXPORT_SYMBOL_GPL(ip_tunnel_setup);
1263
1264MODULE_LICENSE("GPL");