blob: 4569da7dfa880ef6f39bfcef4048a0dd37ed189a [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>
Tom Herbert63487ba2014-11-04 09:06:51 -080058
Pravin B Shelarc5441932013-03-25 14:49:35 +000059#if IS_ENABLED(CONFIG_IPV6)
60#include <net/ipv6.h>
61#include <net/ip6_fib.h>
62#include <net/ip6_route.h>
63#endif
64
Duan Jiong967680e2014-01-19 16:43:42 +080065static unsigned int ip_tunnel_hash(__be32 key, __be32 remote)
Pravin B Shelarc5441932013-03-25 14:49:35 +000066{
67 return hash_32((__force u32)key ^ (__force u32)remote,
68 IP_TNL_HASH_BITS);
69}
70
Pravin B Shelarc5441932013-03-25 14:49:35 +000071static bool ip_tunnel_key_match(const struct ip_tunnel_parm *p,
72 __be16 flags, __be32 key)
73{
74 if (p->i_flags & TUNNEL_KEY) {
75 if (flags & TUNNEL_KEY)
76 return key == p->i_key;
77 else
78 /* key expected, none present */
79 return false;
80 } else
81 return !(flags & TUNNEL_KEY);
82}
83
84/* Fallback tunnel: no source, no destination, no key, no options
85
86 Tunnel hash table:
87 We require exact key match i.e. if a key is present in packet
88 it will match only tunnel with the same key; if it is not present,
89 it will match only keyless tunnel.
90
91 All keysless packets, if not matched configured keyless tunnels
92 will match fallback tunnel.
93 Given src, dst and key, find appropriate for input tunnel.
94*/
95struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn,
96 int link, __be16 flags,
97 __be32 remote, __be32 local,
98 __be32 key)
99{
100 unsigned int hash;
101 struct ip_tunnel *t, *cand = NULL;
102 struct hlist_head *head;
103
Duan Jiong967680e2014-01-19 16:43:42 +0800104 hash = ip_tunnel_hash(key, remote);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000105 head = &itn->tunnels[hash];
106
107 hlist_for_each_entry_rcu(t, head, hash_node) {
108 if (local != t->parms.iph.saddr ||
109 remote != t->parms.iph.daddr ||
110 !(t->dev->flags & IFF_UP))
111 continue;
112
113 if (!ip_tunnel_key_match(&t->parms, flags, key))
114 continue;
115
116 if (t->parms.link == link)
117 return t;
118 else
119 cand = t;
120 }
121
122 hlist_for_each_entry_rcu(t, head, hash_node) {
123 if (remote != t->parms.iph.daddr ||
Dmitry Popove0056592014-07-05 02:26:37 +0400124 t->parms.iph.saddr != 0 ||
Pravin B Shelarc5441932013-03-25 14:49:35 +0000125 !(t->dev->flags & IFF_UP))
126 continue;
127
128 if (!ip_tunnel_key_match(&t->parms, flags, key))
129 continue;
130
131 if (t->parms.link == link)
132 return t;
133 else if (!cand)
134 cand = t;
135 }
136
Duan Jiong967680e2014-01-19 16:43:42 +0800137 hash = ip_tunnel_hash(key, 0);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000138 head = &itn->tunnels[hash];
139
140 hlist_for_each_entry_rcu(t, head, hash_node) {
Dmitry Popove0056592014-07-05 02:26:37 +0400141 if ((local != t->parms.iph.saddr || t->parms.iph.daddr != 0) &&
142 (local != t->parms.iph.daddr || !ipv4_is_multicast(local)))
143 continue;
144
145 if (!(t->dev->flags & IFF_UP))
Pravin B Shelarc5441932013-03-25 14:49:35 +0000146 continue;
147
148 if (!ip_tunnel_key_match(&t->parms, flags, key))
149 continue;
150
151 if (t->parms.link == link)
152 return t;
153 else if (!cand)
154 cand = t;
155 }
156
157 if (flags & TUNNEL_NO_KEY)
158 goto skip_key_lookup;
159
160 hlist_for_each_entry_rcu(t, head, hash_node) {
161 if (t->parms.i_key != key ||
Dmitry Popove0056592014-07-05 02:26:37 +0400162 t->parms.iph.saddr != 0 ||
163 t->parms.iph.daddr != 0 ||
Pravin B Shelarc5441932013-03-25 14:49:35 +0000164 !(t->dev->flags & IFF_UP))
165 continue;
166
167 if (t->parms.link == link)
168 return t;
169 else if (!cand)
170 cand = t;
171 }
172
173skip_key_lookup:
174 if (cand)
175 return cand;
176
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700177 t = rcu_dereference(itn->collect_md_tun);
178 if (t)
179 return t;
180
Pravin B Shelarc5441932013-03-25 14:49:35 +0000181 if (itn->fb_tunnel_dev && itn->fb_tunnel_dev->flags & IFF_UP)
182 return netdev_priv(itn->fb_tunnel_dev);
183
Pravin B Shelarc5441932013-03-25 14:49:35 +0000184 return NULL;
185}
186EXPORT_SYMBOL_GPL(ip_tunnel_lookup);
187
188static struct hlist_head *ip_bucket(struct ip_tunnel_net *itn,
189 struct ip_tunnel_parm *parms)
190{
191 unsigned int h;
192 __be32 remote;
Steffen Klassert6d608f02014-02-21 08:41:09 +0100193 __be32 i_key = parms->i_key;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000194
195 if (parms->iph.daddr && !ipv4_is_multicast(parms->iph.daddr))
196 remote = parms->iph.daddr;
197 else
198 remote = 0;
199
Steffen Klassert6d608f02014-02-21 08:41:09 +0100200 if (!(parms->i_flags & TUNNEL_KEY) && (parms->i_flags & VTI_ISVTI))
201 i_key = 0;
202
203 h = ip_tunnel_hash(i_key, remote);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000204 return &itn->tunnels[h];
205}
206
207static void ip_tunnel_add(struct ip_tunnel_net *itn, struct ip_tunnel *t)
208{
209 struct hlist_head *head = ip_bucket(itn, &t->parms);
210
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700211 if (t->collect_md)
212 rcu_assign_pointer(itn->collect_md_tun, t);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000213 hlist_add_head_rcu(&t->hash_node, head);
214}
215
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700216static void ip_tunnel_del(struct ip_tunnel_net *itn, struct ip_tunnel *t)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000217{
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700218 if (t->collect_md)
219 rcu_assign_pointer(itn->collect_md_tun, NULL);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000220 hlist_del_init_rcu(&t->hash_node);
221}
222
223static struct ip_tunnel *ip_tunnel_find(struct ip_tunnel_net *itn,
224 struct ip_tunnel_parm *parms,
225 int type)
226{
227 __be32 remote = parms->iph.daddr;
228 __be32 local = parms->iph.saddr;
229 __be32 key = parms->i_key;
Dmitry Popov5ce54af2014-06-08 03:03:08 +0400230 __be16 flags = parms->i_flags;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000231 int link = parms->link;
232 struct ip_tunnel *t = NULL;
233 struct hlist_head *head = ip_bucket(itn, parms);
234
235 hlist_for_each_entry_rcu(t, head, hash_node) {
236 if (local == t->parms.iph.saddr &&
237 remote == t->parms.iph.daddr &&
Pravin B Shelarc5441932013-03-25 14:49:35 +0000238 link == t->parms.link &&
Dmitry Popov5ce54af2014-06-08 03:03:08 +0400239 type == t->dev->type &&
240 ip_tunnel_key_match(&t->parms, flags, key))
Pravin B Shelarc5441932013-03-25 14:49:35 +0000241 break;
242 }
243 return t;
244}
245
246static struct net_device *__ip_tunnel_create(struct net *net,
247 const struct rtnl_link_ops *ops,
248 struct ip_tunnel_parm *parms)
249{
250 int err;
251 struct ip_tunnel *tunnel;
252 struct net_device *dev;
253 char name[IFNAMSIZ];
254
255 if (parms->name[0])
256 strlcpy(name, parms->name, IFNAMSIZ);
257 else {
Pravin B Shelar54a5d382013-03-28 08:21:46 +0000258 if (strlen(ops->kind) > (IFNAMSIZ - 3)) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000259 err = -E2BIG;
260 goto failed;
261 }
262 strlcpy(name, ops->kind, IFNAMSIZ);
263 strncat(name, "%d", 2);
264 }
265
266 ASSERT_RTNL();
Tom Gundersenc835a672014-07-14 16:37:24 +0200267 dev = alloc_netdev(ops->priv_size, name, NET_NAME_UNKNOWN, ops->setup);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000268 if (!dev) {
269 err = -ENOMEM;
270 goto failed;
271 }
272 dev_net_set(dev, net);
273
274 dev->rtnl_link_ops = ops;
275
276 tunnel = netdev_priv(dev);
277 tunnel->parms = *parms;
Nicolas Dichtel5e6700b2013-06-26 16:11:28 +0200278 tunnel->net = net;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000279
280 err = register_netdevice(dev);
281 if (err)
282 goto failed_free;
283
284 return dev;
285
286failed_free:
287 free_netdev(dev);
288failed:
289 return ERR_PTR(err);
290}
291
Tom Herbert7d442fa2014-01-02 11:48:26 -0800292static inline void init_tunnel_flow(struct flowi4 *fl4,
293 int proto,
294 __be32 daddr, __be32 saddr,
295 __be32 key, __u8 tos, int oif)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000296{
297 memset(fl4, 0, sizeof(*fl4));
298 fl4->flowi4_oif = oif;
299 fl4->daddr = daddr;
300 fl4->saddr = saddr;
301 fl4->flowi4_tos = tos;
302 fl4->flowi4_proto = proto;
303 fl4->fl4_gre_key = key;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000304}
305
306static int ip_tunnel_bind_dev(struct net_device *dev)
307{
308 struct net_device *tdev = NULL;
309 struct ip_tunnel *tunnel = netdev_priv(dev);
310 const struct iphdr *iph;
311 int hlen = LL_MAX_HEADER;
312 int mtu = ETH_DATA_LEN;
313 int t_hlen = tunnel->hlen + sizeof(struct iphdr);
314
315 iph = &tunnel->parms.iph;
316
317 /* Guess output device to choose reasonable mtu and needed_headroom */
318 if (iph->daddr) {
319 struct flowi4 fl4;
320 struct rtable *rt;
321
Tom Herbert7d442fa2014-01-02 11:48:26 -0800322 init_tunnel_flow(&fl4, iph->protocol, iph->daddr,
323 iph->saddr, tunnel->parms.o_key,
324 RT_TOS(iph->tos), tunnel->parms.link);
325 rt = ip_route_output_key(tunnel->net, &fl4);
326
Pravin B Shelarc5441932013-03-25 14:49:35 +0000327 if (!IS_ERR(rt)) {
328 tdev = rt->dst.dev;
Paolo Abenie09acdd2016-02-12 15:43:55 +0100329 dst_cache_set_ip4(&tunnel->dst_cache, &rt->dst,
330 fl4.saddr);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000331 ip_rt_put(rt);
332 }
333 if (dev->type != ARPHRD_ETHER)
334 dev->flags |= IFF_POINTOPOINT;
335 }
336
337 if (!tdev && tunnel->parms.link)
Nicolas Dichtel6c742e72013-08-13 17:51:11 +0200338 tdev = __dev_get_by_index(tunnel->net, tunnel->parms.link);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000339
340 if (tdev) {
341 hlen = tdev->hard_header_len + tdev->needed_headroom;
342 mtu = tdev->mtu;
343 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000344
345 dev->needed_headroom = t_hlen + hlen;
346 mtu -= (dev->hard_header_len + t_hlen);
347
348 if (mtu < 68)
349 mtu = 68;
350
351 return mtu;
352}
353
354static struct ip_tunnel *ip_tunnel_create(struct net *net,
355 struct ip_tunnel_net *itn,
356 struct ip_tunnel_parm *parms)
357{
Julia Lawall4929fd82014-05-15 05:43:20 +0200358 struct ip_tunnel *nt;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000359 struct net_device *dev;
360
361 BUG_ON(!itn->fb_tunnel_dev);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000362 dev = __ip_tunnel_create(net, itn->fb_tunnel_dev->rtnl_link_ops, parms);
363 if (IS_ERR(dev))
Florian Westphal6dd3c9e2014-02-14 13:14:39 +0100364 return ERR_CAST(dev);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000365
366 dev->mtu = ip_tunnel_bind_dev(dev);
367
368 nt = netdev_priv(dev);
369 ip_tunnel_add(itn, nt);
370 return nt;
371}
372
373int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb,
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700374 const struct tnl_ptk_info *tpi, struct metadata_dst *tun_dst,
375 bool log_ecn_error)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000376{
Li RongQing8f849852014-01-04 13:57:59 +0800377 struct pcpu_sw_netstats *tstats;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000378 const struct iphdr *iph = ip_hdr(skb);
379 int err;
380
Pravin B Shelarc5441932013-03-25 14:49:35 +0000381#ifdef CONFIG_NET_IPGRE_BROADCAST
382 if (ipv4_is_multicast(iph->daddr)) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000383 tunnel->dev->stats.multicast++;
384 skb->pkt_type = PACKET_BROADCAST;
385 }
386#endif
387
388 if ((!(tpi->flags&TUNNEL_CSUM) && (tunnel->parms.i_flags&TUNNEL_CSUM)) ||
389 ((tpi->flags&TUNNEL_CSUM) && !(tunnel->parms.i_flags&TUNNEL_CSUM))) {
390 tunnel->dev->stats.rx_crc_errors++;
391 tunnel->dev->stats.rx_errors++;
392 goto drop;
393 }
394
395 if (tunnel->parms.i_flags&TUNNEL_SEQ) {
396 if (!(tpi->flags&TUNNEL_SEQ) ||
397 (tunnel->i_seqno && (s32)(ntohl(tpi->seq) - tunnel->i_seqno) < 0)) {
398 tunnel->dev->stats.rx_fifo_errors++;
399 tunnel->dev->stats.rx_errors++;
400 goto drop;
401 }
402 tunnel->i_seqno = ntohl(tpi->seq) + 1;
403 }
404
Ying Caie96f2e72014-05-04 15:20:04 -0700405 skb_reset_network_header(skb);
406
Pravin B Shelarc5441932013-03-25 14:49:35 +0000407 err = IP_ECN_decapsulate(iph, skb);
408 if (unlikely(err)) {
409 if (log_ecn_error)
410 net_info_ratelimited("non-ECT from %pI4 with TOS=%#x\n",
411 &iph->saddr, iph->tos);
412 if (err > 1) {
413 ++tunnel->dev->stats.rx_frame_errors;
414 ++tunnel->dev->stats.rx_errors;
415 goto drop;
416 }
417 }
418
419 tstats = this_cpu_ptr(tunnel->dev->tstats);
420 u64_stats_update_begin(&tstats->syncp);
421 tstats->rx_packets++;
422 tstats->rx_bytes += skb->len;
423 u64_stats_update_end(&tstats->syncp);
424
Alexei Starovoitov81b9eab2013-11-12 14:39:13 -0800425 skb_scrub_packet(skb, !net_eq(tunnel->net, dev_net(tunnel->dev)));
426
Pravin B Shelar3d7b46c2013-06-17 17:50:02 -0700427 if (tunnel->dev->type == ARPHRD_ETHER) {
428 skb->protocol = eth_type_trans(skb, tunnel->dev);
429 skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
430 } else {
431 skb->dev = tunnel->dev;
432 }
Nicolas Dichtel64261f22013-08-13 17:51:09 +0200433
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700434 if (tun_dst)
435 skb_dst_set(skb, (struct dst_entry *)tun_dst);
436
Pravin B Shelarc5441932013-03-25 14:49:35 +0000437 gro_cells_receive(&tunnel->gro_cells, skb);
438 return 0;
439
440drop:
441 kfree_skb(skb);
442 return 0;
443}
444EXPORT_SYMBOL_GPL(ip_tunnel_rcv);
445
Tom Herbert56328482014-09-17 12:25:58 -0700446static int ip_encap_hlen(struct ip_tunnel_encap *e)
447{
Tom Herberta8c5f902014-11-12 11:54:09 -0800448 const struct ip_tunnel_encap_ops *ops;
449 int hlen = -EINVAL;
450
451 if (e->type == TUNNEL_ENCAP_NONE)
Tom Herbert56328482014-09-17 12:25:58 -0700452 return 0;
Tom Herberta8c5f902014-11-12 11:54:09 -0800453
454 if (e->type >= MAX_IPTUN_ENCAP_OPS)
Tom Herbert56328482014-09-17 12:25:58 -0700455 return -EINVAL;
Tom Herberta8c5f902014-11-12 11:54:09 -0800456
457 rcu_read_lock();
458 ops = rcu_dereference(iptun_encaps[e->type]);
459 if (likely(ops && ops->encap_hlen))
460 hlen = ops->encap_hlen(e);
461 rcu_read_unlock();
462
463 return hlen;
Tom Herbert56328482014-09-17 12:25:58 -0700464}
465
Tom Herberta8c5f902014-11-12 11:54:09 -0800466const struct ip_tunnel_encap_ops __rcu *
467 iptun_encaps[MAX_IPTUN_ENCAP_OPS] __read_mostly;
468
469int ip_tunnel_encap_add_ops(const struct ip_tunnel_encap_ops *ops,
470 unsigned int num)
471{
Thomas Grafbb1553c2014-12-16 21:05:20 +0100472 if (num >= MAX_IPTUN_ENCAP_OPS)
473 return -ERANGE;
474
Tom Herberta8c5f902014-11-12 11:54:09 -0800475 return !cmpxchg((const struct ip_tunnel_encap_ops **)
476 &iptun_encaps[num],
477 NULL, ops) ? 0 : -1;
478}
479EXPORT_SYMBOL(ip_tunnel_encap_add_ops);
480
481int ip_tunnel_encap_del_ops(const struct ip_tunnel_encap_ops *ops,
482 unsigned int num)
483{
484 int ret;
485
Thomas Grafbb1553c2014-12-16 21:05:20 +0100486 if (num >= MAX_IPTUN_ENCAP_OPS)
487 return -ERANGE;
488
Tom Herberta8c5f902014-11-12 11:54:09 -0800489 ret = (cmpxchg((const struct ip_tunnel_encap_ops **)
490 &iptun_encaps[num],
491 ops, NULL) == ops) ? 0 : -1;
492
493 synchronize_net();
494
495 return ret;
496}
497EXPORT_SYMBOL(ip_tunnel_encap_del_ops);
498
Tom Herbert56328482014-09-17 12:25:58 -0700499int ip_tunnel_encap_setup(struct ip_tunnel *t,
500 struct ip_tunnel_encap *ipencap)
501{
502 int hlen;
503
504 memset(&t->encap, 0, sizeof(t->encap));
505
506 hlen = ip_encap_hlen(ipencap);
507 if (hlen < 0)
508 return hlen;
509
510 t->encap.type = ipencap->type;
511 t->encap.sport = ipencap->sport;
512 t->encap.dport = ipencap->dport;
513 t->encap.flags = ipencap->flags;
514
515 t->encap_hlen = hlen;
516 t->hlen = t->encap_hlen + t->tun_hlen;
517
518 return 0;
519}
520EXPORT_SYMBOL_GPL(ip_tunnel_encap_setup);
521
Tom Herbert56328482014-09-17 12:25:58 -0700522int ip_tunnel_encap(struct sk_buff *skb, struct ip_tunnel *t,
523 u8 *protocol, struct flowi4 *fl4)
524{
Tom Herberta8c5f902014-11-12 11:54:09 -0800525 const struct ip_tunnel_encap_ops *ops;
526 int ret = -EINVAL;
527
528 if (t->encap.type == TUNNEL_ENCAP_NONE)
Tom Herbert56328482014-09-17 12:25:58 -0700529 return 0;
Tom Herberta8c5f902014-11-12 11:54:09 -0800530
Thomas Graff1fb5212014-12-16 21:05:21 +0100531 if (t->encap.type >= MAX_IPTUN_ENCAP_OPS)
532 return -EINVAL;
533
Tom Herberta8c5f902014-11-12 11:54:09 -0800534 rcu_read_lock();
535 ops = rcu_dereference(iptun_encaps[t->encap.type]);
536 if (likely(ops && ops->build_header))
537 ret = ops->build_header(skb, &t->encap, protocol, fl4);
538 rcu_read_unlock();
539
540 return ret;
Tom Herbert56328482014-09-17 12:25:58 -0700541}
542EXPORT_SYMBOL(ip_tunnel_encap);
543
Pravin B Shelar23a36472013-07-02 10:57:33 -0700544static int tnl_update_pmtu(struct net_device *dev, struct sk_buff *skb,
Timo Teräsfc24f2b2015-07-07 08:34:13 +0300545 struct rtable *rt, __be16 df,
546 const struct iphdr *inner_iph)
Pravin B Shelar23a36472013-07-02 10:57:33 -0700547{
548 struct ip_tunnel *tunnel = netdev_priv(dev);
Alexander Duyck8c91e162013-07-11 13:12:22 -0700549 int pkt_size = skb->len - tunnel->hlen - dev->hard_header_len;
Pravin B Shelar23a36472013-07-02 10:57:33 -0700550 int mtu;
551
552 if (df)
553 mtu = dst_mtu(&rt->dst) - dev->hard_header_len
554 - sizeof(struct iphdr) - tunnel->hlen;
555 else
556 mtu = skb_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu;
557
558 if (skb_dst(skb))
559 skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu);
560
561 if (skb->protocol == htons(ETH_P_IP)) {
562 if (!skb_is_gso(skb) &&
Timo Teräsfc24f2b2015-07-07 08:34:13 +0300563 (inner_iph->frag_off & htons(IP_DF)) &&
564 mtu < pkt_size) {
Pravin B Shelar23a36472013-07-02 10:57:33 -0700565 memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
566 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));
567 return -E2BIG;
568 }
569 }
570#if IS_ENABLED(CONFIG_IPV6)
571 else if (skb->protocol == htons(ETH_P_IPV6)) {
572 struct rt6_info *rt6 = (struct rt6_info *)skb_dst(skb);
573
574 if (rt6 && mtu < dst_mtu(skb_dst(skb)) &&
575 mtu >= IPV6_MIN_MTU) {
576 if ((tunnel->parms.iph.daddr &&
577 !ipv4_is_multicast(tunnel->parms.iph.daddr)) ||
578 rt6->rt6i_dst.plen == 128) {
579 rt6->rt6i_flags |= RTF_MODIFIED;
580 dst_metric_set(skb_dst(skb), RTAX_MTU, mtu);
581 }
582 }
583
584 if (!skb_is_gso(skb) && mtu >= IPV6_MIN_MTU &&
585 mtu < pkt_size) {
586 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
587 return -E2BIG;
588 }
589 }
590#endif
591 return 0;
592}
593
Pravin B Shelarc5441932013-03-25 14:49:35 +0000594void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
Tom Herbert56328482014-09-17 12:25:58 -0700595 const struct iphdr *tnl_params, u8 protocol)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000596{
597 struct ip_tunnel *tunnel = netdev_priv(dev);
598 const struct iphdr *inner_iph;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000599 struct flowi4 fl4;
600 u8 tos, ttl;
601 __be16 df;
Eric Dumazetb045d372014-02-03 12:52:14 -0800602 struct rtable *rt; /* Route to the other host */
Pravin B Shelarc5441932013-03-25 14:49:35 +0000603 unsigned int max_headroom; /* The extra header space needed */
604 __be32 dst;
Timo Teräs22fb22e2014-05-16 08:34:39 +0300605 bool connected;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000606
607 inner_iph = (const struct iphdr *)skb_inner_network_header(skb);
Timo Teräs22fb22e2014-05-16 08:34:39 +0300608 connected = (tunnel->parms.iph.daddr != 0);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000609
610 dst = tnl_params->daddr;
611 if (dst == 0) {
612 /* NBMA tunnel */
613
Ian Morris51456b22015-04-03 09:17:26 +0100614 if (!skb_dst(skb)) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000615 dev->stats.tx_fifo_errors++;
616 goto tx_error;
617 }
618
619 if (skb->protocol == htons(ETH_P_IP)) {
620 rt = skb_rtable(skb);
621 dst = rt_nexthop(rt, inner_iph->daddr);
622 }
623#if IS_ENABLED(CONFIG_IPV6)
624 else if (skb->protocol == htons(ETH_P_IPV6)) {
625 const struct in6_addr *addr6;
626 struct neighbour *neigh;
627 bool do_tx_error_icmp;
628 int addr_type;
629
630 neigh = dst_neigh_lookup(skb_dst(skb),
631 &ipv6_hdr(skb)->daddr);
Ian Morris51456b22015-04-03 09:17:26 +0100632 if (!neigh)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000633 goto tx_error;
634
635 addr6 = (const struct in6_addr *)&neigh->primary_key;
636 addr_type = ipv6_addr_type(addr6);
637
638 if (addr_type == IPV6_ADDR_ANY) {
639 addr6 = &ipv6_hdr(skb)->daddr;
640 addr_type = ipv6_addr_type(addr6);
641 }
642
643 if ((addr_type & IPV6_ADDR_COMPATv4) == 0)
644 do_tx_error_icmp = true;
645 else {
646 do_tx_error_icmp = false;
647 dst = addr6->s6_addr32[3];
648 }
649 neigh_release(neigh);
650 if (do_tx_error_icmp)
651 goto tx_error_icmp;
652 }
653#endif
654 else
655 goto tx_error;
Tom Herbert7d442fa2014-01-02 11:48:26 -0800656
657 connected = false;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000658 }
659
660 tos = tnl_params->tos;
661 if (tos & 0x1) {
662 tos &= ~0x1;
Tom Herbert7d442fa2014-01-02 11:48:26 -0800663 if (skb->protocol == htons(ETH_P_IP)) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000664 tos = inner_iph->tos;
Tom Herbert7d442fa2014-01-02 11:48:26 -0800665 connected = false;
666 } else if (skb->protocol == htons(ETH_P_IPV6)) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000667 tos = ipv6_get_dsfield((const struct ipv6hdr *)inner_iph);
Tom Herbert7d442fa2014-01-02 11:48:26 -0800668 connected = false;
669 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000670 }
671
Tom Herbert7d442fa2014-01-02 11:48:26 -0800672 init_tunnel_flow(&fl4, protocol, dst, tnl_params->saddr,
673 tunnel->parms.o_key, RT_TOS(tos), tunnel->parms.link);
674
Tom Herbert56328482014-09-17 12:25:58 -0700675 if (ip_tunnel_encap(skb, tunnel, &protocol, &fl4) < 0)
676 goto tx_error;
677
Paolo Abenie09acdd2016-02-12 15:43:55 +0100678 rt = connected ? dst_cache_get_ip4(&tunnel->dst_cache, &fl4.saddr) :
679 NULL;
Tom Herbert7d442fa2014-01-02 11:48:26 -0800680
681 if (!rt) {
682 rt = ip_route_output_key(tunnel->net, &fl4);
683
684 if (IS_ERR(rt)) {
685 dev->stats.tx_carrier_errors++;
686 goto tx_error;
687 }
688 if (connected)
Paolo Abenie09acdd2016-02-12 15:43:55 +0100689 dst_cache_set_ip4(&tunnel->dst_cache, &rt->dst,
690 fl4.saddr);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000691 }
Tom Herbert7d442fa2014-01-02 11:48:26 -0800692
Pravin B Shelar0e6fbc52013-06-17 17:49:56 -0700693 if (rt->dst.dev == dev) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000694 ip_rt_put(rt);
695 dev->stats.collisions++;
696 goto tx_error;
697 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000698
Timo Teräsfc24f2b2015-07-07 08:34:13 +0300699 if (tnl_update_pmtu(dev, skb, rt, tnl_params->frag_off, inner_iph)) {
Pravin B Shelar23a36472013-07-02 10:57:33 -0700700 ip_rt_put(rt);
701 goto tx_error;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000702 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000703
704 if (tunnel->err_count > 0) {
705 if (time_before(jiffies,
706 tunnel->err_time + IPTUNNEL_ERR_TIMEO)) {
707 tunnel->err_count--;
708
Duan Jiong11c21a32014-01-23 14:00:25 +0800709 memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
Pravin B Shelarc5441932013-03-25 14:49:35 +0000710 dst_link_failure(skb);
711 } else
712 tunnel->err_count = 0;
713 }
714
Pravin B Shelard4a71b12013-09-25 09:57:47 -0700715 tos = ip_tunnel_ecn_encap(tos, inner_iph, skb);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000716 ttl = tnl_params->ttl;
717 if (ttl == 0) {
718 if (skb->protocol == htons(ETH_P_IP))
719 ttl = inner_iph->ttl;
720#if IS_ENABLED(CONFIG_IPV6)
721 else if (skb->protocol == htons(ETH_P_IPV6))
722 ttl = ((const struct ipv6hdr *)inner_iph)->hop_limit;
723#endif
724 else
725 ttl = ip4_dst_hoplimit(&rt->dst);
726 }
727
Pravin B Shelar23a36472013-07-02 10:57:33 -0700728 df = tnl_params->frag_off;
729 if (skb->protocol == htons(ETH_P_IP))
730 df |= (inner_iph->frag_off&htons(IP_DF));
731
Pravin B Shelar0e6fbc52013-06-17 17:49:56 -0700732 max_headroom = LL_RESERVED_SPACE(rt->dst.dev) + sizeof(struct iphdr)
Tom Herbert7371e022014-10-03 15:48:07 -0700733 + rt->dst.header_len + ip_encap_hlen(&tunnel->encap);
Steffen Klassert3e08f4a2013-10-01 11:33:59 +0200734 if (max_headroom > dev->needed_headroom)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000735 dev->needed_headroom = max_headroom;
Steffen Klassert3e08f4a2013-10-01 11:33:59 +0200736
737 if (skb_cow_head(skb, dev->needed_headroom)) {
Dmitry Popov586d5fc2014-06-06 04:34:37 +0400738 ip_rt_put(rt);
Steffen Klassert3e08f4a2013-10-01 11:33:59 +0200739 dev->stats.tx_dropped++;
Eric Dumazet3acfa1e2014-01-18 18:27:49 -0800740 kfree_skb(skb);
Steffen Klassert3e08f4a2013-10-01 11:33:59 +0200741 return;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000742 }
743
Pravin B Shelar039f5062015-12-24 14:34:54 -0800744 iptunnel_xmit(NULL, rt, skb, fl4.saddr, fl4.daddr, protocol, tos, ttl,
745 df, !net_eq(tunnel->net, dev_net(dev)));
Pravin B Shelarc5441932013-03-25 14:49:35 +0000746 return;
747
748#if IS_ENABLED(CONFIG_IPV6)
749tx_error_icmp:
750 dst_link_failure(skb);
751#endif
752tx_error:
753 dev->stats.tx_errors++;
Eric Dumazet3acfa1e2014-01-18 18:27:49 -0800754 kfree_skb(skb);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000755}
756EXPORT_SYMBOL_GPL(ip_tunnel_xmit);
757
758static void ip_tunnel_update(struct ip_tunnel_net *itn,
759 struct ip_tunnel *t,
760 struct net_device *dev,
761 struct ip_tunnel_parm *p,
762 bool set_mtu)
763{
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700764 ip_tunnel_del(itn, t);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000765 t->parms.iph.saddr = p->iph.saddr;
766 t->parms.iph.daddr = p->iph.daddr;
767 t->parms.i_key = p->i_key;
768 t->parms.o_key = p->o_key;
769 if (dev->type != ARPHRD_ETHER) {
770 memcpy(dev->dev_addr, &p->iph.saddr, 4);
771 memcpy(dev->broadcast, &p->iph.daddr, 4);
772 }
773 ip_tunnel_add(itn, t);
774
775 t->parms.iph.ttl = p->iph.ttl;
776 t->parms.iph.tos = p->iph.tos;
777 t->parms.iph.frag_off = p->iph.frag_off;
778
779 if (t->parms.link != p->link) {
780 int mtu;
781
782 t->parms.link = p->link;
783 mtu = ip_tunnel_bind_dev(dev);
784 if (set_mtu)
785 dev->mtu = mtu;
786 }
Paolo Abenie09acdd2016-02-12 15:43:55 +0100787 dst_cache_reset(&t->dst_cache);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000788 netdev_state_change(dev);
789}
790
791int ip_tunnel_ioctl(struct net_device *dev, struct ip_tunnel_parm *p, int cmd)
792{
793 int err = 0;
Nicolas Dichtel8c923ce2014-04-16 11:19:32 +0200794 struct ip_tunnel *t = netdev_priv(dev);
795 struct net *net = t->net;
796 struct ip_tunnel_net *itn = net_generic(net, t->ip_tnl_net_id);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000797
798 BUG_ON(!itn->fb_tunnel_dev);
799 switch (cmd) {
800 case SIOCGETTUNNEL:
Nicolas Dichtel8c923ce2014-04-16 11:19:32 +0200801 if (dev == itn->fb_tunnel_dev) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000802 t = ip_tunnel_find(itn, p, itn->fb_tunnel_dev->type);
Ian Morris51456b22015-04-03 09:17:26 +0100803 if (!t)
Nicolas Dichtel8c923ce2014-04-16 11:19:32 +0200804 t = netdev_priv(dev);
805 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000806 memcpy(p, &t->parms, sizeof(*p));
807 break;
808
809 case SIOCADDTUNNEL:
810 case SIOCCHGTUNNEL:
811 err = -EPERM;
812 if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
813 goto done;
814 if (p->iph.ttl)
815 p->iph.frag_off |= htons(IP_DF);
Dmitry Popov7c8e6b92014-06-08 02:06:25 +0400816 if (!(p->i_flags & VTI_ISVTI)) {
817 if (!(p->i_flags & TUNNEL_KEY))
818 p->i_key = 0;
819 if (!(p->o_flags & TUNNEL_KEY))
820 p->o_key = 0;
821 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000822
823 t = ip_tunnel_find(itn, p, itn->fb_tunnel_dev->type);
824
Steffen Klassertd61746b2014-09-22 09:11:08 +0200825 if (cmd == SIOCADDTUNNEL) {
826 if (!t) {
827 t = ip_tunnel_create(net, itn, p);
828 err = PTR_ERR_OR_ZERO(t);
829 break;
830 }
831
832 err = -EEXIST;
Duan Jiongee30ef42014-05-15 13:07:02 +0800833 break;
Florian Westphal6dd3c9e2014-02-14 13:14:39 +0100834 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000835 if (dev != itn->fb_tunnel_dev && cmd == SIOCCHGTUNNEL) {
Ian Morris00db4122015-04-03 09:17:27 +0100836 if (t) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000837 if (t->dev != dev) {
838 err = -EEXIST;
839 break;
840 }
841 } else {
842 unsigned int nflags = 0;
843
844 if (ipv4_is_multicast(p->iph.daddr))
845 nflags = IFF_BROADCAST;
846 else if (p->iph.daddr)
847 nflags = IFF_POINTOPOINT;
848
849 if ((dev->flags^nflags)&(IFF_POINTOPOINT|IFF_BROADCAST)) {
850 err = -EINVAL;
851 break;
852 }
853
854 t = netdev_priv(dev);
855 }
856 }
857
858 if (t) {
859 err = 0;
860 ip_tunnel_update(itn, t, dev, p, true);
Florian Westphal6dd3c9e2014-02-14 13:14:39 +0100861 } else {
862 err = -ENOENT;
863 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000864 break;
865
866 case SIOCDELTUNNEL:
867 err = -EPERM;
868 if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
869 goto done;
870
871 if (dev == itn->fb_tunnel_dev) {
872 err = -ENOENT;
873 t = ip_tunnel_find(itn, p, itn->fb_tunnel_dev->type);
Ian Morris51456b22015-04-03 09:17:26 +0100874 if (!t)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000875 goto done;
876 err = -EPERM;
877 if (t == netdev_priv(itn->fb_tunnel_dev))
878 goto done;
879 dev = t->dev;
880 }
881 unregister_netdevice(dev);
882 err = 0;
883 break;
884
885 default:
886 err = -EINVAL;
887 }
888
889done:
890 return err;
891}
892EXPORT_SYMBOL_GPL(ip_tunnel_ioctl);
893
894int ip_tunnel_change_mtu(struct net_device *dev, int new_mtu)
895{
896 struct ip_tunnel *tunnel = netdev_priv(dev);
897 int t_hlen = tunnel->hlen + sizeof(struct iphdr);
898
899 if (new_mtu < 68 ||
900 new_mtu > 0xFFF8 - dev->hard_header_len - t_hlen)
901 return -EINVAL;
902 dev->mtu = new_mtu;
903 return 0;
904}
905EXPORT_SYMBOL_GPL(ip_tunnel_change_mtu);
906
907static void ip_tunnel_dev_free(struct net_device *dev)
908{
909 struct ip_tunnel *tunnel = netdev_priv(dev);
910
911 gro_cells_destroy(&tunnel->gro_cells);
Paolo Abenie09acdd2016-02-12 15:43:55 +0100912 dst_cache_destroy(&tunnel->dst_cache);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000913 free_percpu(dev->tstats);
914 free_netdev(dev);
915}
916
917void ip_tunnel_dellink(struct net_device *dev, struct list_head *head)
918{
Pravin B Shelarc5441932013-03-25 14:49:35 +0000919 struct ip_tunnel *tunnel = netdev_priv(dev);
920 struct ip_tunnel_net *itn;
921
Nicolas Dichtel6c742e72013-08-13 17:51:11 +0200922 itn = net_generic(tunnel->net, tunnel->ip_tnl_net_id);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000923
924 if (itn->fb_tunnel_dev != dev) {
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700925 ip_tunnel_del(itn, netdev_priv(dev));
Pravin B Shelarc5441932013-03-25 14:49:35 +0000926 unregister_netdevice_queue(dev, head);
927 }
928}
929EXPORT_SYMBOL_GPL(ip_tunnel_dellink);
930
Nicolas Dichtel1728d4f2015-01-15 15:11:17 +0100931struct net *ip_tunnel_get_link_net(const struct net_device *dev)
932{
933 struct ip_tunnel *tunnel = netdev_priv(dev);
934
935 return tunnel->net;
936}
937EXPORT_SYMBOL(ip_tunnel_get_link_net);
938
Nicolas Dichtel1e995842015-04-02 17:07:02 +0200939int ip_tunnel_get_iflink(const struct net_device *dev)
940{
941 struct ip_tunnel *tunnel = netdev_priv(dev);
942
943 return tunnel->parms.link;
944}
945EXPORT_SYMBOL(ip_tunnel_get_iflink);
946
Eric Dumazetd3b6f612013-06-07 13:26:05 -0700947int ip_tunnel_init_net(struct net *net, int ip_tnl_net_id,
Pravin B Shelarc5441932013-03-25 14:49:35 +0000948 struct rtnl_link_ops *ops, char *devname)
949{
950 struct ip_tunnel_net *itn = net_generic(net, ip_tnl_net_id);
951 struct ip_tunnel_parm parms;
stephen hemminger6261d982013-08-05 22:51:37 -0700952 unsigned int i;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000953
stephen hemminger6261d982013-08-05 22:51:37 -0700954 for (i = 0; i < IP_TNL_HASH_SIZE; i++)
955 INIT_HLIST_HEAD(&itn->tunnels[i]);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000956
957 if (!ops) {
958 itn->fb_tunnel_dev = NULL;
959 return 0;
960 }
stephen hemminger6261d982013-08-05 22:51:37 -0700961
Pravin B Shelarc5441932013-03-25 14:49:35 +0000962 memset(&parms, 0, sizeof(parms));
963 if (devname)
964 strlcpy(parms.name, devname, IFNAMSIZ);
965
966 rtnl_lock();
967 itn->fb_tunnel_dev = __ip_tunnel_create(net, ops, &parms);
Dan Carpenterea857f22013-08-19 10:05:10 +0300968 /* FB netdevice is special: we have one, and only one per netns.
969 * Allowing to move it to another netns is clearly unsafe.
970 */
Steffen Klassert67013282013-10-01 11:34:48 +0200971 if (!IS_ERR(itn->fb_tunnel_dev)) {
Dan Carpenterb4de77a2013-08-23 11:15:37 +0300972 itn->fb_tunnel_dev->features |= NETIF_F_NETNS_LOCAL;
Steffen Klassert78ff4be2014-05-19 11:36:56 +0200973 itn->fb_tunnel_dev->mtu = ip_tunnel_bind_dev(itn->fb_tunnel_dev);
Steffen Klassert67013282013-10-01 11:34:48 +0200974 ip_tunnel_add(itn, netdev_priv(itn->fb_tunnel_dev));
975 }
Dan Carpenterb4de77a2013-08-23 11:15:37 +0300976 rtnl_unlock();
Pravin B Shelarc5441932013-03-25 14:49:35 +0000977
Sachin Kamat27d79f32014-01-27 12:13:57 +0530978 return PTR_ERR_OR_ZERO(itn->fb_tunnel_dev);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000979}
980EXPORT_SYMBOL_GPL(ip_tunnel_init_net);
981
Nicolas Dichtel6c742e72013-08-13 17:51:11 +0200982static void ip_tunnel_destroy(struct ip_tunnel_net *itn, struct list_head *head,
983 struct rtnl_link_ops *ops)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000984{
Nicolas Dichtel6c742e72013-08-13 17:51:11 +0200985 struct net *net = dev_net(itn->fb_tunnel_dev);
986 struct net_device *dev, *aux;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000987 int h;
988
Nicolas Dichtel6c742e72013-08-13 17:51:11 +0200989 for_each_netdev_safe(net, dev, aux)
990 if (dev->rtnl_link_ops == ops)
991 unregister_netdevice_queue(dev, head);
992
Pravin B Shelarc5441932013-03-25 14:49:35 +0000993 for (h = 0; h < IP_TNL_HASH_SIZE; h++) {
994 struct ip_tunnel *t;
995 struct hlist_node *n;
996 struct hlist_head *thead = &itn->tunnels[h];
997
998 hlist_for_each_entry_safe(t, n, thead, hash_node)
Nicolas Dichtel6c742e72013-08-13 17:51:11 +0200999 /* If dev is in the same netns, it has already
1000 * been added to the list by the previous loop.
1001 */
1002 if (!net_eq(dev_net(t->dev), net))
1003 unregister_netdevice_queue(t->dev, head);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001004 }
Pravin B Shelarc5441932013-03-25 14:49:35 +00001005}
1006
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001007void ip_tunnel_delete_net(struct ip_tunnel_net *itn, struct rtnl_link_ops *ops)
Pravin B Shelarc5441932013-03-25 14:49:35 +00001008{
1009 LIST_HEAD(list);
1010
1011 rtnl_lock();
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001012 ip_tunnel_destroy(itn, &list, ops);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001013 unregister_netdevice_many(&list);
1014 rtnl_unlock();
Pravin B Shelarc5441932013-03-25 14:49:35 +00001015}
1016EXPORT_SYMBOL_GPL(ip_tunnel_delete_net);
1017
1018int ip_tunnel_newlink(struct net_device *dev, struct nlattr *tb[],
1019 struct ip_tunnel_parm *p)
1020{
1021 struct ip_tunnel *nt;
1022 struct net *net = dev_net(dev);
1023 struct ip_tunnel_net *itn;
1024 int mtu;
1025 int err;
1026
1027 nt = netdev_priv(dev);
1028 itn = net_generic(net, nt->ip_tnl_net_id);
1029
Pravin B Shelar2e15ea32015-08-07 23:51:42 -07001030 if (nt->collect_md) {
1031 if (rtnl_dereference(itn->collect_md_tun))
1032 return -EEXIST;
1033 } else {
1034 if (ip_tunnel_find(itn, p, dev->type))
1035 return -EEXIST;
1036 }
Pravin B Shelarc5441932013-03-25 14:49:35 +00001037
Nicolas Dichtel5e6700b2013-06-26 16:11:28 +02001038 nt->net = net;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001039 nt->parms = *p;
1040 err = register_netdevice(dev);
1041 if (err)
1042 goto out;
1043
1044 if (dev->type == ARPHRD_ETHER && !tb[IFLA_ADDRESS])
1045 eth_hw_addr_random(dev);
1046
1047 mtu = ip_tunnel_bind_dev(dev);
1048 if (!tb[IFLA_MTU])
1049 dev->mtu = mtu;
1050
1051 ip_tunnel_add(itn, nt);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001052out:
1053 return err;
1054}
1055EXPORT_SYMBOL_GPL(ip_tunnel_newlink);
1056
1057int ip_tunnel_changelink(struct net_device *dev, struct nlattr *tb[],
1058 struct ip_tunnel_parm *p)
1059{
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001060 struct ip_tunnel *t;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001061 struct ip_tunnel *tunnel = netdev_priv(dev);
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001062 struct net *net = tunnel->net;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001063 struct ip_tunnel_net *itn = net_generic(net, tunnel->ip_tnl_net_id);
1064
1065 if (dev == itn->fb_tunnel_dev)
1066 return -EINVAL;
1067
Pravin B Shelarc5441932013-03-25 14:49:35 +00001068 t = ip_tunnel_find(itn, p, dev->type);
1069
1070 if (t) {
1071 if (t->dev != dev)
1072 return -EEXIST;
1073 } else {
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001074 t = tunnel;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001075
1076 if (dev->type != ARPHRD_ETHER) {
1077 unsigned int nflags = 0;
1078
1079 if (ipv4_is_multicast(p->iph.daddr))
1080 nflags = IFF_BROADCAST;
1081 else if (p->iph.daddr)
1082 nflags = IFF_POINTOPOINT;
1083
1084 if ((dev->flags ^ nflags) &
1085 (IFF_POINTOPOINT | IFF_BROADCAST))
1086 return -EINVAL;
1087 }
1088 }
1089
1090 ip_tunnel_update(itn, t, dev, p, !tb[IFLA_MTU]);
1091 return 0;
1092}
1093EXPORT_SYMBOL_GPL(ip_tunnel_changelink);
1094
1095int ip_tunnel_init(struct net_device *dev)
1096{
1097 struct ip_tunnel *tunnel = netdev_priv(dev);
1098 struct iphdr *iph = &tunnel->parms.iph;
WANG Cong1c213bd2014-02-13 11:46:28 -08001099 int err;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001100
1101 dev->destructor = ip_tunnel_dev_free;
WANG Cong1c213bd2014-02-13 11:46:28 -08001102 dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001103 if (!dev->tstats)
1104 return -ENOMEM;
1105
Paolo Abenie09acdd2016-02-12 15:43:55 +01001106 err = dst_cache_init(&tunnel->dst_cache, GFP_KERNEL);
1107 if (err) {
Tom Herbert9a4aa9a2014-01-02 11:48:33 -08001108 free_percpu(dev->tstats);
Paolo Abenie09acdd2016-02-12 15:43:55 +01001109 return err;
Tom Herbert9a4aa9a2014-01-02 11:48:33 -08001110 }
1111
Pravin B Shelarc5441932013-03-25 14:49:35 +00001112 err = gro_cells_init(&tunnel->gro_cells, dev);
1113 if (err) {
Paolo Abenie09acdd2016-02-12 15:43:55 +01001114 dst_cache_destroy(&tunnel->dst_cache);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001115 free_percpu(dev->tstats);
1116 return err;
1117 }
1118
1119 tunnel->dev = dev;
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001120 tunnel->net = dev_net(dev);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001121 strcpy(tunnel->parms.name, dev->name);
1122 iph->version = 4;
1123 iph->ihl = 5;
1124
Pravin B Shelar2e15ea32015-08-07 23:51:42 -07001125 if (tunnel->collect_md) {
1126 dev->features |= NETIF_F_NETNS_LOCAL;
1127 netif_keep_dst(dev);
1128 }
Pravin B Shelarc5441932013-03-25 14:49:35 +00001129 return 0;
1130}
1131EXPORT_SYMBOL_GPL(ip_tunnel_init);
1132
1133void ip_tunnel_uninit(struct net_device *dev)
1134{
Pravin B Shelarc5441932013-03-25 14:49:35 +00001135 struct ip_tunnel *tunnel = netdev_priv(dev);
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001136 struct net *net = tunnel->net;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001137 struct ip_tunnel_net *itn;
1138
1139 itn = net_generic(net, tunnel->ip_tnl_net_id);
1140 /* fb_tunnel_dev will be unregisted in net-exit call. */
1141 if (itn->fb_tunnel_dev != dev)
Pravin B Shelar2e15ea32015-08-07 23:51:42 -07001142 ip_tunnel_del(itn, netdev_priv(dev));
Tom Herbert7d442fa2014-01-02 11:48:26 -08001143
Paolo Abenie09acdd2016-02-12 15:43:55 +01001144 dst_cache_reset(&tunnel->dst_cache);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001145}
1146EXPORT_SYMBOL_GPL(ip_tunnel_uninit);
1147
1148/* Do least required initialization, rest of init is done in tunnel_init call */
1149void ip_tunnel_setup(struct net_device *dev, int net_id)
1150{
1151 struct ip_tunnel *tunnel = netdev_priv(dev);
1152 tunnel->ip_tnl_net_id = net_id;
1153}
1154EXPORT_SYMBOL_GPL(ip_tunnel_setup);
1155
1156MODULE_LICENSE("GPL");