blob: dd5db4cc7d0669e8e899eecce1343cf62100ef50 [file] [log] [blame]
Pravin B Shelarc5441932013-03-25 14:49:35 +00001/*
2 * Copyright (c) 2013 Nicira, Inc.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of version 2 of the GNU General Public
6 * License as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16 * 02110-1301, USA
17 */
18
19#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
20
21#include <linux/capability.h>
22#include <linux/module.h>
23#include <linux/types.h>
24#include <linux/kernel.h>
25#include <linux/slab.h>
26#include <linux/uaccess.h>
27#include <linux/skbuff.h>
28#include <linux/netdevice.h>
29#include <linux/in.h>
30#include <linux/tcp.h>
31#include <linux/udp.h>
32#include <linux/if_arp.h>
Pravin B Shelarc5441932013-03-25 14:49:35 +000033#include <linux/init.h>
34#include <linux/in6.h>
35#include <linux/inetdevice.h>
36#include <linux/igmp.h>
37#include <linux/netfilter_ipv4.h>
38#include <linux/etherdevice.h>
39#include <linux/if_ether.h>
40#include <linux/if_vlan.h>
41#include <linux/rculist.h>
Sachin Kamat27d79f32014-01-27 12:13:57 +053042#include <linux/err.h>
Pravin B Shelarc5441932013-03-25 14:49:35 +000043
44#include <net/sock.h>
45#include <net/ip.h>
46#include <net/icmp.h>
47#include <net/protocol.h>
48#include <net/ip_tunnels.h>
49#include <net/arp.h>
50#include <net/checksum.h>
51#include <net/dsfield.h>
52#include <net/inet_ecn.h>
53#include <net/xfrm.h>
54#include <net/net_namespace.h>
55#include <net/netns/generic.h>
56#include <net/rtnetlink.h>
Tom Herbert56328482014-09-17 12:25:58 -070057#include <net/udp.h>
Alexei Starovoitovcfc73812016-09-15 13:00:29 -070058#include <net/dst_metadata.h>
Tom Herbert63487ba2014-11-04 09:06:51 -080059
Pravin B Shelarc5441932013-03-25 14:49:35 +000060#if IS_ENABLED(CONFIG_IPV6)
61#include <net/ipv6.h>
62#include <net/ip6_fib.h>
63#include <net/ip6_route.h>
64#endif
65
Duan Jiong967680e2014-01-19 16:43:42 +080066static unsigned int ip_tunnel_hash(__be32 key, __be32 remote)
Pravin B Shelarc5441932013-03-25 14:49:35 +000067{
68 return hash_32((__force u32)key ^ (__force u32)remote,
69 IP_TNL_HASH_BITS);
70}
71
Pravin B Shelarc5441932013-03-25 14:49:35 +000072static bool ip_tunnel_key_match(const struct ip_tunnel_parm *p,
73 __be16 flags, __be32 key)
74{
75 if (p->i_flags & TUNNEL_KEY) {
76 if (flags & TUNNEL_KEY)
77 return key == p->i_key;
78 else
79 /* key expected, none present */
80 return false;
81 } else
82 return !(flags & TUNNEL_KEY);
83}
84
85/* Fallback tunnel: no source, no destination, no key, no options
86
87 Tunnel hash table:
88 We require exact key match i.e. if a key is present in packet
89 it will match only tunnel with the same key; if it is not present,
90 it will match only keyless tunnel.
91
92 All keysless packets, if not matched configured keyless tunnels
93 will match fallback tunnel.
94 Given src, dst and key, find appropriate for input tunnel.
95*/
96struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn,
97 int link, __be16 flags,
98 __be32 remote, __be32 local,
99 __be32 key)
100{
101 unsigned int hash;
102 struct ip_tunnel *t, *cand = NULL;
103 struct hlist_head *head;
104
Duan Jiong967680e2014-01-19 16:43:42 +0800105 hash = ip_tunnel_hash(key, remote);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000106 head = &itn->tunnels[hash];
107
108 hlist_for_each_entry_rcu(t, head, hash_node) {
109 if (local != t->parms.iph.saddr ||
110 remote != t->parms.iph.daddr ||
111 !(t->dev->flags & IFF_UP))
112 continue;
113
114 if (!ip_tunnel_key_match(&t->parms, flags, key))
115 continue;
116
117 if (t->parms.link == link)
118 return t;
119 else
120 cand = t;
121 }
122
123 hlist_for_each_entry_rcu(t, head, hash_node) {
124 if (remote != t->parms.iph.daddr ||
Dmitry Popove0056592014-07-05 02:26:37 +0400125 t->parms.iph.saddr != 0 ||
Pravin B Shelarc5441932013-03-25 14:49:35 +0000126 !(t->dev->flags & IFF_UP))
127 continue;
128
129 if (!ip_tunnel_key_match(&t->parms, flags, key))
130 continue;
131
132 if (t->parms.link == link)
133 return t;
134 else if (!cand)
135 cand = t;
136 }
137
Duan Jiong967680e2014-01-19 16:43:42 +0800138 hash = ip_tunnel_hash(key, 0);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000139 head = &itn->tunnels[hash];
140
141 hlist_for_each_entry_rcu(t, head, hash_node) {
Dmitry Popove0056592014-07-05 02:26:37 +0400142 if ((local != t->parms.iph.saddr || t->parms.iph.daddr != 0) &&
143 (local != t->parms.iph.daddr || !ipv4_is_multicast(local)))
144 continue;
145
146 if (!(t->dev->flags & IFF_UP))
Pravin B Shelarc5441932013-03-25 14:49:35 +0000147 continue;
148
149 if (!ip_tunnel_key_match(&t->parms, flags, key))
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 hlist_for_each_entry_rcu(t, head, hash_node) {
William Dauchy4f1640e2020-03-27 19:56:39 +0100159 if ((!(flags & TUNNEL_NO_KEY) && t->parms.i_key != key) ||
Dmitry Popove0056592014-07-05 02:26:37 +0400160 t->parms.iph.saddr != 0 ||
161 t->parms.iph.daddr != 0 ||
Pravin B Shelarc5441932013-03-25 14:49:35 +0000162 !(t->dev->flags & IFF_UP))
163 continue;
164
165 if (t->parms.link == link)
166 return t;
167 else if (!cand)
168 cand = t;
169 }
170
Pravin B Shelarc5441932013-03-25 14:49:35 +0000171 if (cand)
172 return cand;
173
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700174 t = rcu_dereference(itn->collect_md_tun);
175 if (t)
176 return t;
177
Pravin B Shelarc5441932013-03-25 14:49:35 +0000178 if (itn->fb_tunnel_dev && itn->fb_tunnel_dev->flags & IFF_UP)
179 return netdev_priv(itn->fb_tunnel_dev);
180
Pravin B Shelarc5441932013-03-25 14:49:35 +0000181 return NULL;
182}
183EXPORT_SYMBOL_GPL(ip_tunnel_lookup);
184
185static struct hlist_head *ip_bucket(struct ip_tunnel_net *itn,
186 struct ip_tunnel_parm *parms)
187{
188 unsigned int h;
189 __be32 remote;
Steffen Klassert6d608f02014-02-21 08:41:09 +0100190 __be32 i_key = parms->i_key;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000191
192 if (parms->iph.daddr && !ipv4_is_multicast(parms->iph.daddr))
193 remote = parms->iph.daddr;
194 else
195 remote = 0;
196
Steffen Klassert6d608f02014-02-21 08:41:09 +0100197 if (!(parms->i_flags & TUNNEL_KEY) && (parms->i_flags & VTI_ISVTI))
198 i_key = 0;
199
200 h = ip_tunnel_hash(i_key, remote);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000201 return &itn->tunnels[h];
202}
203
204static void ip_tunnel_add(struct ip_tunnel_net *itn, struct ip_tunnel *t)
205{
206 struct hlist_head *head = ip_bucket(itn, &t->parms);
207
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700208 if (t->collect_md)
209 rcu_assign_pointer(itn->collect_md_tun, t);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000210 hlist_add_head_rcu(&t->hash_node, head);
211}
212
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700213static void ip_tunnel_del(struct ip_tunnel_net *itn, struct ip_tunnel *t)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000214{
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700215 if (t->collect_md)
216 rcu_assign_pointer(itn->collect_md_tun, NULL);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000217 hlist_del_init_rcu(&t->hash_node);
218}
219
220static struct ip_tunnel *ip_tunnel_find(struct ip_tunnel_net *itn,
221 struct ip_tunnel_parm *parms,
222 int type)
223{
224 __be32 remote = parms->iph.daddr;
225 __be32 local = parms->iph.saddr;
226 __be32 key = parms->i_key;
Dmitry Popov5ce54af2014-06-08 03:03:08 +0400227 __be16 flags = parms->i_flags;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000228 int link = parms->link;
229 struct ip_tunnel *t = NULL;
230 struct hlist_head *head = ip_bucket(itn, parms);
231
232 hlist_for_each_entry_rcu(t, head, hash_node) {
233 if (local == t->parms.iph.saddr &&
234 remote == t->parms.iph.daddr &&
Pravin B Shelarc5441932013-03-25 14:49:35 +0000235 link == t->parms.link &&
Dmitry Popov5ce54af2014-06-08 03:03:08 +0400236 type == t->dev->type &&
237 ip_tunnel_key_match(&t->parms, flags, key))
Pravin B Shelarc5441932013-03-25 14:49:35 +0000238 break;
239 }
240 return t;
241}
242
243static struct net_device *__ip_tunnel_create(struct net *net,
244 const struct rtnl_link_ops *ops,
245 struct ip_tunnel_parm *parms)
246{
247 int err;
248 struct ip_tunnel *tunnel;
249 struct net_device *dev;
250 char name[IFNAMSIZ];
251
Eric Dumazet6cc02902018-04-05 06:39:27 -0700252 err = -E2BIG;
253 if (parms->name[0]) {
254 if (!dev_valid_name(parms->name))
Pravin B Shelarc5441932013-03-25 14:49:35 +0000255 goto failed;
Eric Dumazet6cc02902018-04-05 06:39:27 -0700256 strlcpy(name, parms->name, IFNAMSIZ);
257 } else {
258 if (strlen(ops->kind) > (IFNAMSIZ - 3))
259 goto failed;
Sultan Alsawaf5569c102018-06-06 15:56:54 -0700260 strcpy(name, ops->kind);
261 strcat(name, "%d");
Pravin B Shelarc5441932013-03-25 14:49:35 +0000262 }
263
264 ASSERT_RTNL();
Tom Gundersenc835a672014-07-14 16:37:24 +0200265 dev = alloc_netdev(ops->priv_size, name, NET_NAME_UNKNOWN, ops->setup);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000266 if (!dev) {
267 err = -ENOMEM;
268 goto failed;
269 }
270 dev_net_set(dev, net);
271
272 dev->rtnl_link_ops = ops;
273
274 tunnel = netdev_priv(dev);
275 tunnel->parms = *parms;
Nicolas Dichtel5e6700b2013-06-26 16:11:28 +0200276 tunnel->net = net;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000277
278 err = register_netdevice(dev);
279 if (err)
280 goto failed_free;
281
282 return dev;
283
284failed_free:
285 free_netdev(dev);
286failed:
287 return ERR_PTR(err);
288}
289
Tom Herbert7d442fa2014-01-02 11:48:26 -0800290static inline void init_tunnel_flow(struct flowi4 *fl4,
291 int proto,
292 __be32 daddr, __be32 saddr,
293 __be32 key, __u8 tos, int oif)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000294{
295 memset(fl4, 0, sizeof(*fl4));
296 fl4->flowi4_oif = oif;
297 fl4->daddr = daddr;
298 fl4->saddr = saddr;
299 fl4->flowi4_tos = tos;
300 fl4->flowi4_proto = proto;
301 fl4->fl4_gre_key = key;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000302}
303
304static int ip_tunnel_bind_dev(struct net_device *dev)
305{
306 struct net_device *tdev = NULL;
307 struct ip_tunnel *tunnel = netdev_priv(dev);
308 const struct iphdr *iph;
309 int hlen = LL_MAX_HEADER;
310 int mtu = ETH_DATA_LEN;
311 int t_hlen = tunnel->hlen + sizeof(struct iphdr);
312
313 iph = &tunnel->parms.iph;
314
315 /* Guess output device to choose reasonable mtu and needed_headroom */
316 if (iph->daddr) {
317 struct flowi4 fl4;
318 struct rtable *rt;
319
Tom Herbert7d442fa2014-01-02 11:48:26 -0800320 init_tunnel_flow(&fl4, iph->protocol, iph->daddr,
321 iph->saddr, tunnel->parms.o_key,
322 RT_TOS(iph->tos), tunnel->parms.link);
323 rt = ip_route_output_key(tunnel->net, &fl4);
324
Pravin B Shelarc5441932013-03-25 14:49:35 +0000325 if (!IS_ERR(rt)) {
326 tdev = rt->dst.dev;
327 ip_rt_put(rt);
328 }
329 if (dev->type != ARPHRD_ETHER)
330 dev->flags |= IFF_POINTOPOINT;
Paolo Abenif27337e2016-04-28 11:04:51 +0200331
332 dst_cache_reset(&tunnel->dst_cache);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000333 }
334
335 if (!tdev && tunnel->parms.link)
Nicolas Dichtel6c742e72013-08-13 17:51:11 +0200336 tdev = __dev_get_by_index(tunnel->net, tunnel->parms.link);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000337
338 if (tdev) {
339 hlen = tdev->hard_header_len + tdev->needed_headroom;
340 mtu = tdev->mtu;
341 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000342
343 dev->needed_headroom = t_hlen + hlen;
344 mtu -= (dev->hard_header_len + t_hlen);
345
Eric Dumazetc2f78bf2017-12-11 07:17:39 -0800346 if (mtu < IPV4_MIN_MTU)
347 mtu = IPV4_MIN_MTU;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000348
349 return mtu;
350}
351
352static struct ip_tunnel *ip_tunnel_create(struct net *net,
353 struct ip_tunnel_net *itn,
354 struct ip_tunnel_parm *parms)
355{
Julia Lawall4929fd82014-05-15 05:43:20 +0200356 struct ip_tunnel *nt;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000357 struct net_device *dev;
358
359 BUG_ON(!itn->fb_tunnel_dev);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000360 dev = __ip_tunnel_create(net, itn->fb_tunnel_dev->rtnl_link_ops, parms);
361 if (IS_ERR(dev))
Florian Westphal6dd3c9e2014-02-14 13:14:39 +0100362 return ERR_CAST(dev);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000363
364 dev->mtu = ip_tunnel_bind_dev(dev);
365
366 nt = netdev_priv(dev);
367 ip_tunnel_add(itn, nt);
368 return nt;
369}
370
371int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb,
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700372 const struct tnl_ptk_info *tpi, struct metadata_dst *tun_dst,
373 bool log_ecn_error)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000374{
Li RongQing8f849852014-01-04 13:57:59 +0800375 struct pcpu_sw_netstats *tstats;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000376 const struct iphdr *iph = ip_hdr(skb);
377 int err;
378
Pravin B Shelarc5441932013-03-25 14:49:35 +0000379#ifdef CONFIG_NET_IPGRE_BROADCAST
380 if (ipv4_is_multicast(iph->daddr)) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000381 tunnel->dev->stats.multicast++;
382 skb->pkt_type = PACKET_BROADCAST;
383 }
384#endif
385
386 if ((!(tpi->flags&TUNNEL_CSUM) && (tunnel->parms.i_flags&TUNNEL_CSUM)) ||
387 ((tpi->flags&TUNNEL_CSUM) && !(tunnel->parms.i_flags&TUNNEL_CSUM))) {
388 tunnel->dev->stats.rx_crc_errors++;
389 tunnel->dev->stats.rx_errors++;
390 goto drop;
391 }
392
393 if (tunnel->parms.i_flags&TUNNEL_SEQ) {
394 if (!(tpi->flags&TUNNEL_SEQ) ||
395 (tunnel->i_seqno && (s32)(ntohl(tpi->seq) - tunnel->i_seqno) < 0)) {
396 tunnel->dev->stats.rx_fifo_errors++;
397 tunnel->dev->stats.rx_errors++;
398 goto drop;
399 }
400 tunnel->i_seqno = ntohl(tpi->seq) + 1;
401 }
402
Ying Caie96f2e72014-05-04 15:20:04 -0700403 skb_reset_network_header(skb);
404
Pravin B Shelarc5441932013-03-25 14:49:35 +0000405 err = IP_ECN_decapsulate(iph, skb);
406 if (unlikely(err)) {
407 if (log_ecn_error)
408 net_info_ratelimited("non-ECT from %pI4 with TOS=%#x\n",
409 &iph->saddr, iph->tos);
410 if (err > 1) {
411 ++tunnel->dev->stats.rx_frame_errors;
412 ++tunnel->dev->stats.rx_errors;
413 goto drop;
414 }
415 }
416
417 tstats = this_cpu_ptr(tunnel->dev->tstats);
418 u64_stats_update_begin(&tstats->syncp);
419 tstats->rx_packets++;
420 tstats->rx_bytes += skb->len;
421 u64_stats_update_end(&tstats->syncp);
422
Alexei Starovoitov81b9eab2013-11-12 14:39:13 -0800423 skb_scrub_packet(skb, !net_eq(tunnel->net, dev_net(tunnel->dev)));
424
Pravin B Shelar3d7b46c2013-06-17 17:50:02 -0700425 if (tunnel->dev->type == ARPHRD_ETHER) {
426 skb->protocol = eth_type_trans(skb, tunnel->dev);
427 skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
428 } else {
429 skb->dev = tunnel->dev;
430 }
Nicolas Dichtel64261f22013-08-13 17:51:09 +0200431
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700432 if (tun_dst)
433 skb_dst_set(skb, (struct dst_entry *)tun_dst);
434
Pravin B Shelarc5441932013-03-25 14:49:35 +0000435 gro_cells_receive(&tunnel->gro_cells, skb);
436 return 0;
437
438drop:
439 kfree_skb(skb);
440 return 0;
441}
442EXPORT_SYMBOL_GPL(ip_tunnel_rcv);
443
Tom Herberta8c5f902014-11-12 11:54:09 -0800444int ip_tunnel_encap_add_ops(const struct ip_tunnel_encap_ops *ops,
445 unsigned int num)
446{
Thomas Grafbb1553c2014-12-16 21:05:20 +0100447 if (num >= MAX_IPTUN_ENCAP_OPS)
448 return -ERANGE;
449
Tom Herberta8c5f902014-11-12 11:54:09 -0800450 return !cmpxchg((const struct ip_tunnel_encap_ops **)
451 &iptun_encaps[num],
452 NULL, ops) ? 0 : -1;
453}
454EXPORT_SYMBOL(ip_tunnel_encap_add_ops);
455
456int ip_tunnel_encap_del_ops(const struct ip_tunnel_encap_ops *ops,
457 unsigned int num)
458{
459 int ret;
460
Thomas Grafbb1553c2014-12-16 21:05:20 +0100461 if (num >= MAX_IPTUN_ENCAP_OPS)
462 return -ERANGE;
463
Tom Herberta8c5f902014-11-12 11:54:09 -0800464 ret = (cmpxchg((const struct ip_tunnel_encap_ops **)
465 &iptun_encaps[num],
466 ops, NULL) == ops) ? 0 : -1;
467
468 synchronize_net();
469
470 return ret;
471}
472EXPORT_SYMBOL(ip_tunnel_encap_del_ops);
473
Tom Herbert56328482014-09-17 12:25:58 -0700474int ip_tunnel_encap_setup(struct ip_tunnel *t,
475 struct ip_tunnel_encap *ipencap)
476{
477 int hlen;
478
479 memset(&t->encap, 0, sizeof(t->encap));
480
481 hlen = ip_encap_hlen(ipencap);
482 if (hlen < 0)
483 return hlen;
484
485 t->encap.type = ipencap->type;
486 t->encap.sport = ipencap->sport;
487 t->encap.dport = ipencap->dport;
488 t->encap.flags = ipencap->flags;
489
490 t->encap_hlen = hlen;
491 t->hlen = t->encap_hlen + t->tun_hlen;
492
493 return 0;
494}
495EXPORT_SYMBOL_GPL(ip_tunnel_encap_setup);
496
Pravin B Shelar23a36472013-07-02 10:57:33 -0700497static int tnl_update_pmtu(struct net_device *dev, struct sk_buff *skb,
Timo Teräsfc24f2b2015-07-07 08:34:13 +0300498 struct rtable *rt, __be16 df,
499 const struct iphdr *inner_iph)
Pravin B Shelar23a36472013-07-02 10:57:33 -0700500{
501 struct ip_tunnel *tunnel = netdev_priv(dev);
Alexander Duyck8c91e162013-07-11 13:12:22 -0700502 int pkt_size = skb->len - tunnel->hlen - dev->hard_header_len;
Pravin B Shelar23a36472013-07-02 10:57:33 -0700503 int mtu;
504
505 if (df)
506 mtu = dst_mtu(&rt->dst) - dev->hard_header_len
507 - sizeof(struct iphdr) - tunnel->hlen;
508 else
509 mtu = skb_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu;
510
511 if (skb_dst(skb))
512 skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu);
513
514 if (skb->protocol == htons(ETH_P_IP)) {
515 if (!skb_is_gso(skb) &&
Timo Teräsfc24f2b2015-07-07 08:34:13 +0300516 (inner_iph->frag_off & htons(IP_DF)) &&
517 mtu < pkt_size) {
Pravin B Shelar23a36472013-07-02 10:57:33 -0700518 memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
519 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));
520 return -E2BIG;
521 }
522 }
523#if IS_ENABLED(CONFIG_IPV6)
524 else if (skb->protocol == htons(ETH_P_IPV6)) {
525 struct rt6_info *rt6 = (struct rt6_info *)skb_dst(skb);
526
527 if (rt6 && mtu < dst_mtu(skb_dst(skb)) &&
528 mtu >= IPV6_MIN_MTU) {
529 if ((tunnel->parms.iph.daddr &&
530 !ipv4_is_multicast(tunnel->parms.iph.daddr)) ||
531 rt6->rt6i_dst.plen == 128) {
532 rt6->rt6i_flags |= RTF_MODIFIED;
533 dst_metric_set(skb_dst(skb), RTAX_MTU, mtu);
534 }
535 }
536
537 if (!skb_is_gso(skb) && mtu >= IPV6_MIN_MTU &&
538 mtu < pkt_size) {
539 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
540 return -E2BIG;
541 }
542 }
543#endif
544 return 0;
545}
546
Alexei Starovoitovcfc73812016-09-15 13:00:29 -0700547void ip_md_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, u8 proto)
548{
549 struct ip_tunnel *tunnel = netdev_priv(dev);
550 u32 headroom = sizeof(struct iphdr);
551 struct ip_tunnel_info *tun_info;
552 const struct ip_tunnel_key *key;
553 const struct iphdr *inner_iph;
554 struct rtable *rt;
555 struct flowi4 fl4;
556 __be16 df = 0;
557 u8 tos, ttl;
558
559 tun_info = skb_tunnel_info(skb);
560 if (unlikely(!tun_info || !(tun_info->mode & IP_TUNNEL_INFO_TX) ||
561 ip_tunnel_info_af(tun_info) != AF_INET))
562 goto tx_error;
563 key = &tun_info->key;
564 memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
565 inner_iph = (const struct iphdr *)skb_inner_network_header(skb);
566 tos = key->tos;
567 if (tos == 1) {
568 if (skb->protocol == htons(ETH_P_IP))
569 tos = inner_iph->tos;
570 else if (skb->protocol == htons(ETH_P_IPV6))
571 tos = ipv6_get_dsfield((const struct ipv6hdr *)inner_iph);
572 }
573 init_tunnel_flow(&fl4, proto, key->u.ipv4.dst, key->u.ipv4.src, 0,
574 RT_TOS(tos), tunnel->parms.link);
575 if (tunnel->encap.type != TUNNEL_ENCAP_NONE)
576 goto tx_error;
577 rt = ip_route_output_key(tunnel->net, &fl4);
578 if (IS_ERR(rt)) {
579 dev->stats.tx_carrier_errors++;
580 goto tx_error;
581 }
582 if (rt->dst.dev == dev) {
583 ip_rt_put(rt);
584 dev->stats.collisions++;
585 goto tx_error;
586 }
587 tos = ip_tunnel_ecn_encap(tos, inner_iph, skb);
588 ttl = key->ttl;
589 if (ttl == 0) {
590 if (skb->protocol == htons(ETH_P_IP))
591 ttl = inner_iph->ttl;
592 else if (skb->protocol == htons(ETH_P_IPV6))
593 ttl = ((const struct ipv6hdr *)inner_iph)->hop_limit;
594 else
595 ttl = ip4_dst_hoplimit(&rt->dst);
596 }
597 if (key->tun_flags & TUNNEL_DONT_FRAGMENT)
598 df = htons(IP_DF);
599 else if (skb->protocol == htons(ETH_P_IP))
600 df = inner_iph->frag_off & htons(IP_DF);
601 headroom += LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len;
602 if (headroom > dev->needed_headroom)
603 dev->needed_headroom = headroom;
604
605 if (skb_cow_head(skb, dev->needed_headroom)) {
606 ip_rt_put(rt);
607 goto tx_dropped;
608 }
Haishuang Yan60b94122017-09-07 14:08:34 +0800609 iptunnel_xmit(NULL, rt, skb, fl4.saddr, fl4.daddr, proto, tos, ttl,
610 df, !net_eq(tunnel->net, dev_net(dev)));
Alexei Starovoitovcfc73812016-09-15 13:00:29 -0700611 return;
612tx_error:
613 dev->stats.tx_errors++;
614 goto kfree;
615tx_dropped:
616 dev->stats.tx_dropped++;
617kfree:
618 kfree_skb(skb);
619}
620EXPORT_SYMBOL_GPL(ip_md_tunnel_xmit);
621
Pravin B Shelarc5441932013-03-25 14:49:35 +0000622void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
Tom Herbert56328482014-09-17 12:25:58 -0700623 const struct iphdr *tnl_params, u8 protocol)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000624{
625 struct ip_tunnel *tunnel = netdev_priv(dev);
Paolo Abeni2b7b2c42018-09-24 15:48:19 +0200626 unsigned int inner_nhdr_len = 0;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000627 const struct iphdr *inner_iph;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000628 struct flowi4 fl4;
629 u8 tos, ttl;
630 __be16 df;
Eric Dumazetb045d372014-02-03 12:52:14 -0800631 struct rtable *rt; /* Route to the other host */
Pravin B Shelarc5441932013-03-25 14:49:35 +0000632 unsigned int max_headroom; /* The extra header space needed */
633 __be32 dst;
Timo Teräs22fb22e2014-05-16 08:34:39 +0300634 bool connected;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000635
Paolo Abeni2b7b2c42018-09-24 15:48:19 +0200636 /* ensure we can access the inner net header, for several users below */
637 if (skb->protocol == htons(ETH_P_IP))
638 inner_nhdr_len = sizeof(struct iphdr);
639 else if (skb->protocol == htons(ETH_P_IPV6))
640 inner_nhdr_len = sizeof(struct ipv6hdr);
641 if (unlikely(!pskb_may_pull(skb, inner_nhdr_len)))
642 goto tx_error;
643
Pravin B Shelarc5441932013-03-25 14:49:35 +0000644 inner_iph = (const struct iphdr *)skb_inner_network_header(skb);
Timo Teräs22fb22e2014-05-16 08:34:39 +0300645 connected = (tunnel->parms.iph.daddr != 0);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000646
Bernie Harris5146d1f2016-02-22 12:58:05 +1300647 memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
648
Pravin B Shelarc5441932013-03-25 14:49:35 +0000649 dst = tnl_params->daddr;
650 if (dst == 0) {
651 /* NBMA tunnel */
wenxubc60abe2019-01-19 13:11:25 +0800652 struct ip_tunnel_info *tun_info;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000653
Ian Morris51456b22015-04-03 09:17:26 +0100654 if (!skb_dst(skb)) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000655 dev->stats.tx_fifo_errors++;
656 goto tx_error;
657 }
658
wenxubc60abe2019-01-19 13:11:25 +0800659 tun_info = skb_tunnel_info(skb);
660 if (tun_info && (tun_info->mode & IP_TUNNEL_INFO_TX) &&
661 ip_tunnel_info_af(tun_info) == AF_INET &&
662 tun_info->key.u.ipv4.dst)
663 dst = tun_info->key.u.ipv4.dst;
664 else if (skb->protocol == htons(ETH_P_IP)) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000665 rt = skb_rtable(skb);
666 dst = rt_nexthop(rt, inner_iph->daddr);
667 }
668#if IS_ENABLED(CONFIG_IPV6)
669 else if (skb->protocol == htons(ETH_P_IPV6)) {
670 const struct in6_addr *addr6;
671 struct neighbour *neigh;
672 bool do_tx_error_icmp;
673 int addr_type;
674
675 neigh = dst_neigh_lookup(skb_dst(skb),
676 &ipv6_hdr(skb)->daddr);
Ian Morris51456b22015-04-03 09:17:26 +0100677 if (!neigh)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000678 goto tx_error;
679
680 addr6 = (const struct in6_addr *)&neigh->primary_key;
681 addr_type = ipv6_addr_type(addr6);
682
683 if (addr_type == IPV6_ADDR_ANY) {
684 addr6 = &ipv6_hdr(skb)->daddr;
685 addr_type = ipv6_addr_type(addr6);
686 }
687
688 if ((addr_type & IPV6_ADDR_COMPATv4) == 0)
689 do_tx_error_icmp = true;
690 else {
691 do_tx_error_icmp = false;
692 dst = addr6->s6_addr32[3];
693 }
694 neigh_release(neigh);
695 if (do_tx_error_icmp)
696 goto tx_error_icmp;
697 }
698#endif
699 else
700 goto tx_error;
Tom Herbert7d442fa2014-01-02 11:48:26 -0800701
702 connected = false;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000703 }
704
705 tos = tnl_params->tos;
706 if (tos & 0x1) {
707 tos &= ~0x1;
Tom Herbert7d442fa2014-01-02 11:48:26 -0800708 if (skb->protocol == htons(ETH_P_IP)) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000709 tos = inner_iph->tos;
Tom Herbert7d442fa2014-01-02 11:48:26 -0800710 connected = false;
711 } else if (skb->protocol == htons(ETH_P_IPV6)) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000712 tos = ipv6_get_dsfield((const struct ipv6hdr *)inner_iph);
Tom Herbert7d442fa2014-01-02 11:48:26 -0800713 connected = false;
714 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000715 }
716
Tom Herbert7d442fa2014-01-02 11:48:26 -0800717 init_tunnel_flow(&fl4, protocol, dst, tnl_params->saddr,
718 tunnel->parms.o_key, RT_TOS(tos), tunnel->parms.link);
719
Tom Herbert56328482014-09-17 12:25:58 -0700720 if (ip_tunnel_encap(skb, tunnel, &protocol, &fl4) < 0)
721 goto tx_error;
722
Paolo Abenie09acdd2016-02-12 15:43:55 +0100723 rt = connected ? dst_cache_get_ip4(&tunnel->dst_cache, &fl4.saddr) :
724 NULL;
Tom Herbert7d442fa2014-01-02 11:48:26 -0800725
726 if (!rt) {
727 rt = ip_route_output_key(tunnel->net, &fl4);
728
729 if (IS_ERR(rt)) {
730 dev->stats.tx_carrier_errors++;
731 goto tx_error;
732 }
733 if (connected)
Paolo Abenie09acdd2016-02-12 15:43:55 +0100734 dst_cache_set_ip4(&tunnel->dst_cache, &rt->dst,
735 fl4.saddr);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000736 }
Tom Herbert7d442fa2014-01-02 11:48:26 -0800737
Pravin B Shelar0e6fbc52013-06-17 17:49:56 -0700738 if (rt->dst.dev == dev) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000739 ip_rt_put(rt);
740 dev->stats.collisions++;
741 goto tx_error;
742 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000743
Timo Teräsfc24f2b2015-07-07 08:34:13 +0300744 if (tnl_update_pmtu(dev, skb, rt, tnl_params->frag_off, inner_iph)) {
Pravin B Shelar23a36472013-07-02 10:57:33 -0700745 ip_rt_put(rt);
746 goto tx_error;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000747 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000748
749 if (tunnel->err_count > 0) {
750 if (time_before(jiffies,
751 tunnel->err_time + IPTUNNEL_ERR_TIMEO)) {
752 tunnel->err_count--;
753
754 dst_link_failure(skb);
755 } else
756 tunnel->err_count = 0;
757 }
758
Pravin B Shelard4a71b12013-09-25 09:57:47 -0700759 tos = ip_tunnel_ecn_encap(tos, inner_iph, skb);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000760 ttl = tnl_params->ttl;
761 if (ttl == 0) {
762 if (skb->protocol == htons(ETH_P_IP))
763 ttl = inner_iph->ttl;
764#if IS_ENABLED(CONFIG_IPV6)
765 else if (skb->protocol == htons(ETH_P_IPV6))
766 ttl = ((const struct ipv6hdr *)inner_iph)->hop_limit;
767#endif
768 else
769 ttl = ip4_dst_hoplimit(&rt->dst);
770 }
771
Pravin B Shelar23a36472013-07-02 10:57:33 -0700772 df = tnl_params->frag_off;
Philip Prindeville22a59be2016-06-14 15:53:02 -0600773 if (skb->protocol == htons(ETH_P_IP) && !tunnel->ignore_df)
Pravin B Shelar23a36472013-07-02 10:57:33 -0700774 df |= (inner_iph->frag_off&htons(IP_DF));
775
Pravin B Shelar0e6fbc52013-06-17 17:49:56 -0700776 max_headroom = LL_RESERVED_SPACE(rt->dst.dev) + sizeof(struct iphdr)
Tom Herbert7371e022014-10-03 15:48:07 -0700777 + rt->dst.header_len + ip_encap_hlen(&tunnel->encap);
Steffen Klassert3e08f4a2013-10-01 11:33:59 +0200778 if (max_headroom > dev->needed_headroom)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000779 dev->needed_headroom = max_headroom;
Steffen Klassert3e08f4a2013-10-01 11:33:59 +0200780
781 if (skb_cow_head(skb, dev->needed_headroom)) {
Dmitry Popov586d5fc2014-06-06 04:34:37 +0400782 ip_rt_put(rt);
Steffen Klassert3e08f4a2013-10-01 11:33:59 +0200783 dev->stats.tx_dropped++;
Eric Dumazet3acfa1e2014-01-18 18:27:49 -0800784 kfree_skb(skb);
Steffen Klassert3e08f4a2013-10-01 11:33:59 +0200785 return;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000786 }
787
Pravin B Shelar039f5062015-12-24 14:34:54 -0800788 iptunnel_xmit(NULL, rt, skb, fl4.saddr, fl4.daddr, protocol, tos, ttl,
789 df, !net_eq(tunnel->net, dev_net(dev)));
Pravin B Shelarc5441932013-03-25 14:49:35 +0000790 return;
791
792#if IS_ENABLED(CONFIG_IPV6)
793tx_error_icmp:
794 dst_link_failure(skb);
795#endif
796tx_error:
797 dev->stats.tx_errors++;
Eric Dumazet3acfa1e2014-01-18 18:27:49 -0800798 kfree_skb(skb);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000799}
800EXPORT_SYMBOL_GPL(ip_tunnel_xmit);
801
802static void ip_tunnel_update(struct ip_tunnel_net *itn,
803 struct ip_tunnel *t,
804 struct net_device *dev,
805 struct ip_tunnel_parm *p,
806 bool set_mtu)
807{
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700808 ip_tunnel_del(itn, t);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000809 t->parms.iph.saddr = p->iph.saddr;
810 t->parms.iph.daddr = p->iph.daddr;
811 t->parms.i_key = p->i_key;
812 t->parms.o_key = p->o_key;
813 if (dev->type != ARPHRD_ETHER) {
814 memcpy(dev->dev_addr, &p->iph.saddr, 4);
815 memcpy(dev->broadcast, &p->iph.daddr, 4);
816 }
817 ip_tunnel_add(itn, t);
818
819 t->parms.iph.ttl = p->iph.ttl;
820 t->parms.iph.tos = p->iph.tos;
821 t->parms.iph.frag_off = p->iph.frag_off;
822
823 if (t->parms.link != p->link) {
824 int mtu;
825
826 t->parms.link = p->link;
827 mtu = ip_tunnel_bind_dev(dev);
828 if (set_mtu)
829 dev->mtu = mtu;
830 }
Paolo Abenie09acdd2016-02-12 15:43:55 +0100831 dst_cache_reset(&t->dst_cache);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000832 netdev_state_change(dev);
833}
834
835int ip_tunnel_ioctl(struct net_device *dev, struct ip_tunnel_parm *p, int cmd)
836{
837 int err = 0;
Nicolas Dichtel8c923ce2014-04-16 11:19:32 +0200838 struct ip_tunnel *t = netdev_priv(dev);
839 struct net *net = t->net;
840 struct ip_tunnel_net *itn = net_generic(net, t->ip_tnl_net_id);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000841
842 BUG_ON(!itn->fb_tunnel_dev);
843 switch (cmd) {
844 case SIOCGETTUNNEL:
Nicolas Dichtel8c923ce2014-04-16 11:19:32 +0200845 if (dev == itn->fb_tunnel_dev) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000846 t = ip_tunnel_find(itn, p, itn->fb_tunnel_dev->type);
Ian Morris51456b22015-04-03 09:17:26 +0100847 if (!t)
Nicolas Dichtel8c923ce2014-04-16 11:19:32 +0200848 t = netdev_priv(dev);
849 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000850 memcpy(p, &t->parms, sizeof(*p));
851 break;
852
853 case SIOCADDTUNNEL:
854 case SIOCCHGTUNNEL:
855 err = -EPERM;
856 if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
857 goto done;
858 if (p->iph.ttl)
859 p->iph.frag_off |= htons(IP_DF);
Dmitry Popov7c8e6b92014-06-08 02:06:25 +0400860 if (!(p->i_flags & VTI_ISVTI)) {
861 if (!(p->i_flags & TUNNEL_KEY))
862 p->i_key = 0;
863 if (!(p->o_flags & TUNNEL_KEY))
864 p->o_key = 0;
865 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000866
867 t = ip_tunnel_find(itn, p, itn->fb_tunnel_dev->type);
868
Steffen Klassertd61746b2014-09-22 09:11:08 +0200869 if (cmd == SIOCADDTUNNEL) {
870 if (!t) {
871 t = ip_tunnel_create(net, itn, p);
872 err = PTR_ERR_OR_ZERO(t);
873 break;
874 }
875
876 err = -EEXIST;
Duan Jiongee30ef42014-05-15 13:07:02 +0800877 break;
Florian Westphal6dd3c9e2014-02-14 13:14:39 +0100878 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000879 if (dev != itn->fb_tunnel_dev && cmd == SIOCCHGTUNNEL) {
Ian Morris00db4122015-04-03 09:17:27 +0100880 if (t) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000881 if (t->dev != dev) {
882 err = -EEXIST;
883 break;
884 }
885 } else {
886 unsigned int nflags = 0;
887
888 if (ipv4_is_multicast(p->iph.daddr))
889 nflags = IFF_BROADCAST;
890 else if (p->iph.daddr)
891 nflags = IFF_POINTOPOINT;
892
893 if ((dev->flags^nflags)&(IFF_POINTOPOINT|IFF_BROADCAST)) {
894 err = -EINVAL;
895 break;
896 }
897
898 t = netdev_priv(dev);
899 }
900 }
901
902 if (t) {
903 err = 0;
904 ip_tunnel_update(itn, t, dev, p, true);
Florian Westphal6dd3c9e2014-02-14 13:14:39 +0100905 } else {
906 err = -ENOENT;
907 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000908 break;
909
910 case SIOCDELTUNNEL:
911 err = -EPERM;
912 if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
913 goto done;
914
915 if (dev == itn->fb_tunnel_dev) {
916 err = -ENOENT;
917 t = ip_tunnel_find(itn, p, itn->fb_tunnel_dev->type);
Ian Morris51456b22015-04-03 09:17:26 +0100918 if (!t)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000919 goto done;
920 err = -EPERM;
921 if (t == netdev_priv(itn->fb_tunnel_dev))
922 goto done;
923 dev = t->dev;
924 }
925 unregister_netdevice(dev);
926 err = 0;
927 break;
928
929 default:
930 err = -EINVAL;
931 }
932
933done:
934 return err;
935}
936EXPORT_SYMBOL_GPL(ip_tunnel_ioctl);
937
David Wragg7e059152016-02-10 00:05:58 +0000938int __ip_tunnel_change_mtu(struct net_device *dev, int new_mtu, bool strict)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000939{
940 struct ip_tunnel *tunnel = netdev_priv(dev);
941 int t_hlen = tunnel->hlen + sizeof(struct iphdr);
David Wragg7e059152016-02-10 00:05:58 +0000942 int max_mtu = 0xFFF8 - dev->hard_header_len - t_hlen;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000943
David Wragg7e059152016-02-10 00:05:58 +0000944 if (new_mtu < 68)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000945 return -EINVAL;
David Wragg7e059152016-02-10 00:05:58 +0000946
947 if (new_mtu > max_mtu) {
948 if (strict)
949 return -EINVAL;
950
951 new_mtu = max_mtu;
952 }
953
Pravin B Shelarc5441932013-03-25 14:49:35 +0000954 dev->mtu = new_mtu;
955 return 0;
956}
David Wragg7e059152016-02-10 00:05:58 +0000957EXPORT_SYMBOL_GPL(__ip_tunnel_change_mtu);
958
959int ip_tunnel_change_mtu(struct net_device *dev, int new_mtu)
960{
961 return __ip_tunnel_change_mtu(dev, new_mtu, true);
962}
Pravin B Shelarc5441932013-03-25 14:49:35 +0000963EXPORT_SYMBOL_GPL(ip_tunnel_change_mtu);
964
965static void ip_tunnel_dev_free(struct net_device *dev)
966{
967 struct ip_tunnel *tunnel = netdev_priv(dev);
968
969 gro_cells_destroy(&tunnel->gro_cells);
Paolo Abenie09acdd2016-02-12 15:43:55 +0100970 dst_cache_destroy(&tunnel->dst_cache);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000971 free_percpu(dev->tstats);
972 free_netdev(dev);
973}
974
975void ip_tunnel_dellink(struct net_device *dev, struct list_head *head)
976{
Pravin B Shelarc5441932013-03-25 14:49:35 +0000977 struct ip_tunnel *tunnel = netdev_priv(dev);
978 struct ip_tunnel_net *itn;
979
Nicolas Dichtel6c742e72013-08-13 17:51:11 +0200980 itn = net_generic(tunnel->net, tunnel->ip_tnl_net_id);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000981
982 if (itn->fb_tunnel_dev != dev) {
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700983 ip_tunnel_del(itn, netdev_priv(dev));
Pravin B Shelarc5441932013-03-25 14:49:35 +0000984 unregister_netdevice_queue(dev, head);
985 }
986}
987EXPORT_SYMBOL_GPL(ip_tunnel_dellink);
988
Nicolas Dichtel1728d4f2015-01-15 15:11:17 +0100989struct net *ip_tunnel_get_link_net(const struct net_device *dev)
990{
991 struct ip_tunnel *tunnel = netdev_priv(dev);
992
993 return tunnel->net;
994}
995EXPORT_SYMBOL(ip_tunnel_get_link_net);
996
Nicolas Dichtel1e995842015-04-02 17:07:02 +0200997int ip_tunnel_get_iflink(const struct net_device *dev)
998{
999 struct ip_tunnel *tunnel = netdev_priv(dev);
1000
1001 return tunnel->parms.link;
1002}
1003EXPORT_SYMBOL(ip_tunnel_get_iflink);
1004
Eric Dumazetd3b6f612013-06-07 13:26:05 -07001005int ip_tunnel_init_net(struct net *net, int ip_tnl_net_id,
Pravin B Shelarc5441932013-03-25 14:49:35 +00001006 struct rtnl_link_ops *ops, char *devname)
1007{
1008 struct ip_tunnel_net *itn = net_generic(net, ip_tnl_net_id);
1009 struct ip_tunnel_parm parms;
stephen hemminger6261d982013-08-05 22:51:37 -07001010 unsigned int i;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001011
stephen hemminger6261d982013-08-05 22:51:37 -07001012 for (i = 0; i < IP_TNL_HASH_SIZE; i++)
1013 INIT_HLIST_HEAD(&itn->tunnels[i]);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001014
1015 if (!ops) {
1016 itn->fb_tunnel_dev = NULL;
1017 return 0;
1018 }
stephen hemminger6261d982013-08-05 22:51:37 -07001019
Pravin B Shelarc5441932013-03-25 14:49:35 +00001020 memset(&parms, 0, sizeof(parms));
1021 if (devname)
1022 strlcpy(parms.name, devname, IFNAMSIZ);
1023
1024 rtnl_lock();
1025 itn->fb_tunnel_dev = __ip_tunnel_create(net, ops, &parms);
Dan Carpenterea857f22013-08-19 10:05:10 +03001026 /* FB netdevice is special: we have one, and only one per netns.
1027 * Allowing to move it to another netns is clearly unsafe.
1028 */
Steffen Klassert67013282013-10-01 11:34:48 +02001029 if (!IS_ERR(itn->fb_tunnel_dev)) {
Dan Carpenterb4de77a2013-08-23 11:15:37 +03001030 itn->fb_tunnel_dev->features |= NETIF_F_NETNS_LOCAL;
Steffen Klassert78ff4be2014-05-19 11:36:56 +02001031 itn->fb_tunnel_dev->mtu = ip_tunnel_bind_dev(itn->fb_tunnel_dev);
Steffen Klassert67013282013-10-01 11:34:48 +02001032 ip_tunnel_add(itn, netdev_priv(itn->fb_tunnel_dev));
1033 }
Dan Carpenterb4de77a2013-08-23 11:15:37 +03001034 rtnl_unlock();
Pravin B Shelarc5441932013-03-25 14:49:35 +00001035
Sachin Kamat27d79f32014-01-27 12:13:57 +05301036 return PTR_ERR_OR_ZERO(itn->fb_tunnel_dev);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001037}
1038EXPORT_SYMBOL_GPL(ip_tunnel_init_net);
1039
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001040static void ip_tunnel_destroy(struct ip_tunnel_net *itn, struct list_head *head,
1041 struct rtnl_link_ops *ops)
Pravin B Shelarc5441932013-03-25 14:49:35 +00001042{
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001043 struct net *net = dev_net(itn->fb_tunnel_dev);
1044 struct net_device *dev, *aux;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001045 int h;
1046
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001047 for_each_netdev_safe(net, dev, aux)
1048 if (dev->rtnl_link_ops == ops)
1049 unregister_netdevice_queue(dev, head);
1050
Pravin B Shelarc5441932013-03-25 14:49:35 +00001051 for (h = 0; h < IP_TNL_HASH_SIZE; h++) {
1052 struct ip_tunnel *t;
1053 struct hlist_node *n;
1054 struct hlist_head *thead = &itn->tunnels[h];
1055
1056 hlist_for_each_entry_safe(t, n, thead, hash_node)
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001057 /* If dev is in the same netns, it has already
1058 * been added to the list by the previous loop.
1059 */
1060 if (!net_eq(dev_net(t->dev), net))
1061 unregister_netdevice_queue(t->dev, head);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001062 }
Pravin B Shelarc5441932013-03-25 14:49:35 +00001063}
1064
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001065void ip_tunnel_delete_net(struct ip_tunnel_net *itn, struct rtnl_link_ops *ops)
Pravin B Shelarc5441932013-03-25 14:49:35 +00001066{
1067 LIST_HEAD(list);
1068
1069 rtnl_lock();
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001070 ip_tunnel_destroy(itn, &list, ops);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001071 unregister_netdevice_many(&list);
1072 rtnl_unlock();
Pravin B Shelarc5441932013-03-25 14:49:35 +00001073}
1074EXPORT_SYMBOL_GPL(ip_tunnel_delete_net);
1075
1076int ip_tunnel_newlink(struct net_device *dev, struct nlattr *tb[],
1077 struct ip_tunnel_parm *p)
1078{
1079 struct ip_tunnel *nt;
1080 struct net *net = dev_net(dev);
1081 struct ip_tunnel_net *itn;
1082 int mtu;
1083 int err;
1084
1085 nt = netdev_priv(dev);
1086 itn = net_generic(net, nt->ip_tnl_net_id);
1087
Pravin B Shelar2e15ea32015-08-07 23:51:42 -07001088 if (nt->collect_md) {
1089 if (rtnl_dereference(itn->collect_md_tun))
1090 return -EEXIST;
1091 } else {
1092 if (ip_tunnel_find(itn, p, dev->type))
1093 return -EEXIST;
1094 }
Pravin B Shelarc5441932013-03-25 14:49:35 +00001095
Nicolas Dichtel5e6700b2013-06-26 16:11:28 +02001096 nt->net = net;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001097 nt->parms = *p;
1098 err = register_netdevice(dev);
1099 if (err)
1100 goto out;
1101
1102 if (dev->type == ARPHRD_ETHER && !tb[IFLA_ADDRESS])
1103 eth_hw_addr_random(dev);
1104
1105 mtu = ip_tunnel_bind_dev(dev);
1106 if (!tb[IFLA_MTU])
1107 dev->mtu = mtu;
1108
1109 ip_tunnel_add(itn, nt);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001110out:
1111 return err;
1112}
1113EXPORT_SYMBOL_GPL(ip_tunnel_newlink);
1114
1115int ip_tunnel_changelink(struct net_device *dev, struct nlattr *tb[],
1116 struct ip_tunnel_parm *p)
1117{
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001118 struct ip_tunnel *t;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001119 struct ip_tunnel *tunnel = netdev_priv(dev);
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001120 struct net *net = tunnel->net;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001121 struct ip_tunnel_net *itn = net_generic(net, tunnel->ip_tnl_net_id);
1122
1123 if (dev == itn->fb_tunnel_dev)
1124 return -EINVAL;
1125
Pravin B Shelarc5441932013-03-25 14:49:35 +00001126 t = ip_tunnel_find(itn, p, dev->type);
1127
1128 if (t) {
1129 if (t->dev != dev)
1130 return -EEXIST;
1131 } else {
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001132 t = tunnel;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001133
1134 if (dev->type != ARPHRD_ETHER) {
1135 unsigned int nflags = 0;
1136
1137 if (ipv4_is_multicast(p->iph.daddr))
1138 nflags = IFF_BROADCAST;
1139 else if (p->iph.daddr)
1140 nflags = IFF_POINTOPOINT;
1141
1142 if ((dev->flags ^ nflags) &
1143 (IFF_POINTOPOINT | IFF_BROADCAST))
1144 return -EINVAL;
1145 }
1146 }
1147
1148 ip_tunnel_update(itn, t, dev, p, !tb[IFLA_MTU]);
1149 return 0;
1150}
1151EXPORT_SYMBOL_GPL(ip_tunnel_changelink);
1152
1153int ip_tunnel_init(struct net_device *dev)
1154{
1155 struct ip_tunnel *tunnel = netdev_priv(dev);
1156 struct iphdr *iph = &tunnel->parms.iph;
WANG Cong1c213bd2014-02-13 11:46:28 -08001157 int err;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001158
1159 dev->destructor = ip_tunnel_dev_free;
WANG Cong1c213bd2014-02-13 11:46:28 -08001160 dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001161 if (!dev->tstats)
1162 return -ENOMEM;
1163
Paolo Abenie09acdd2016-02-12 15:43:55 +01001164 err = dst_cache_init(&tunnel->dst_cache, GFP_KERNEL);
1165 if (err) {
Tom Herbert9a4aa9a2014-01-02 11:48:33 -08001166 free_percpu(dev->tstats);
Paolo Abenie09acdd2016-02-12 15:43:55 +01001167 return err;
Tom Herbert9a4aa9a2014-01-02 11:48:33 -08001168 }
1169
Pravin B Shelarc5441932013-03-25 14:49:35 +00001170 err = gro_cells_init(&tunnel->gro_cells, dev);
1171 if (err) {
Paolo Abenie09acdd2016-02-12 15:43:55 +01001172 dst_cache_destroy(&tunnel->dst_cache);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001173 free_percpu(dev->tstats);
1174 return err;
1175 }
1176
1177 tunnel->dev = dev;
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001178 tunnel->net = dev_net(dev);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001179 strcpy(tunnel->parms.name, dev->name);
1180 iph->version = 4;
1181 iph->ihl = 5;
1182
William Dauchy67696262020-01-21 15:26:24 +01001183 if (tunnel->collect_md)
Pravin B Shelar2e15ea32015-08-07 23:51:42 -07001184 netif_keep_dst(dev);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001185 return 0;
1186}
1187EXPORT_SYMBOL_GPL(ip_tunnel_init);
1188
1189void ip_tunnel_uninit(struct net_device *dev)
1190{
Pravin B Shelarc5441932013-03-25 14:49:35 +00001191 struct ip_tunnel *tunnel = netdev_priv(dev);
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001192 struct net *net = tunnel->net;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001193 struct ip_tunnel_net *itn;
1194
1195 itn = net_generic(net, tunnel->ip_tnl_net_id);
1196 /* fb_tunnel_dev will be unregisted in net-exit call. */
1197 if (itn->fb_tunnel_dev != dev)
Pravin B Shelar2e15ea32015-08-07 23:51:42 -07001198 ip_tunnel_del(itn, netdev_priv(dev));
Tom Herbert7d442fa2014-01-02 11:48:26 -08001199
Paolo Abenie09acdd2016-02-12 15:43:55 +01001200 dst_cache_reset(&tunnel->dst_cache);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001201}
1202EXPORT_SYMBOL_GPL(ip_tunnel_uninit);
1203
1204/* Do least required initialization, rest of init is done in tunnel_init call */
1205void ip_tunnel_setup(struct net_device *dev, int net_id)
1206{
1207 struct ip_tunnel *tunnel = netdev_priv(dev);
1208 tunnel->ip_tnl_net_id = net_id;
1209}
1210EXPORT_SYMBOL_GPL(ip_tunnel_setup);
1211
1212MODULE_LICENSE("GPL");