blob: 95649ebd2874347197f03267e16d91263681a0b3 [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;
329 ip_rt_put(rt);
330 }
331 if (dev->type != ARPHRD_ETHER)
332 dev->flags |= IFF_POINTOPOINT;
Paolo Abenif27337e2016-04-28 11:04:51 +0200333
334 dst_cache_reset(&tunnel->dst_cache);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000335 }
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 Herberta8c5f902014-11-12 11:54:09 -0800446int ip_tunnel_encap_add_ops(const struct ip_tunnel_encap_ops *ops,
447 unsigned int num)
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 return !cmpxchg((const struct ip_tunnel_encap_ops **)
453 &iptun_encaps[num],
454 NULL, ops) ? 0 : -1;
455}
456EXPORT_SYMBOL(ip_tunnel_encap_add_ops);
457
458int ip_tunnel_encap_del_ops(const struct ip_tunnel_encap_ops *ops,
459 unsigned int num)
460{
461 int ret;
462
Thomas Grafbb1553c2014-12-16 21:05:20 +0100463 if (num >= MAX_IPTUN_ENCAP_OPS)
464 return -ERANGE;
465
Tom Herberta8c5f902014-11-12 11:54:09 -0800466 ret = (cmpxchg((const struct ip_tunnel_encap_ops **)
467 &iptun_encaps[num],
468 ops, NULL) == ops) ? 0 : -1;
469
470 synchronize_net();
471
472 return ret;
473}
474EXPORT_SYMBOL(ip_tunnel_encap_del_ops);
475
Tom Herbert56328482014-09-17 12:25:58 -0700476int ip_tunnel_encap_setup(struct ip_tunnel *t,
477 struct ip_tunnel_encap *ipencap)
478{
479 int hlen;
480
481 memset(&t->encap, 0, sizeof(t->encap));
482
483 hlen = ip_encap_hlen(ipencap);
484 if (hlen < 0)
485 return hlen;
486
487 t->encap.type = ipencap->type;
488 t->encap.sport = ipencap->sport;
489 t->encap.dport = ipencap->dport;
490 t->encap.flags = ipencap->flags;
491
492 t->encap_hlen = hlen;
493 t->hlen = t->encap_hlen + t->tun_hlen;
494
495 return 0;
496}
497EXPORT_SYMBOL_GPL(ip_tunnel_encap_setup);
498
Pravin B Shelar23a36472013-07-02 10:57:33 -0700499static int tnl_update_pmtu(struct net_device *dev, struct sk_buff *skb,
Timo Teräsfc24f2b2015-07-07 08:34:13 +0300500 struct rtable *rt, __be16 df,
501 const struct iphdr *inner_iph)
Pravin B Shelar23a36472013-07-02 10:57:33 -0700502{
503 struct ip_tunnel *tunnel = netdev_priv(dev);
Alexander Duyck8c91e162013-07-11 13:12:22 -0700504 int pkt_size = skb->len - tunnel->hlen - dev->hard_header_len;
Pravin B Shelar23a36472013-07-02 10:57:33 -0700505 int mtu;
506
507 if (df)
508 mtu = dst_mtu(&rt->dst) - dev->hard_header_len
509 - sizeof(struct iphdr) - tunnel->hlen;
510 else
511 mtu = skb_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu;
512
513 if (skb_dst(skb))
514 skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu);
515
516 if (skb->protocol == htons(ETH_P_IP)) {
517 if (!skb_is_gso(skb) &&
Timo Teräsfc24f2b2015-07-07 08:34:13 +0300518 (inner_iph->frag_off & htons(IP_DF)) &&
519 mtu < pkt_size) {
Pravin B Shelar23a36472013-07-02 10:57:33 -0700520 memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
521 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));
522 return -E2BIG;
523 }
524 }
525#if IS_ENABLED(CONFIG_IPV6)
526 else if (skb->protocol == htons(ETH_P_IPV6)) {
527 struct rt6_info *rt6 = (struct rt6_info *)skb_dst(skb);
528
529 if (rt6 && mtu < dst_mtu(skb_dst(skb)) &&
530 mtu >= IPV6_MIN_MTU) {
531 if ((tunnel->parms.iph.daddr &&
532 !ipv4_is_multicast(tunnel->parms.iph.daddr)) ||
533 rt6->rt6i_dst.plen == 128) {
534 rt6->rt6i_flags |= RTF_MODIFIED;
535 dst_metric_set(skb_dst(skb), RTAX_MTU, mtu);
536 }
537 }
538
539 if (!skb_is_gso(skb) && mtu >= IPV6_MIN_MTU &&
540 mtu < pkt_size) {
541 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
542 return -E2BIG;
543 }
544 }
545#endif
546 return 0;
547}
548
Pravin B Shelarc5441932013-03-25 14:49:35 +0000549void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
Tom Herbert56328482014-09-17 12:25:58 -0700550 const struct iphdr *tnl_params, u8 protocol)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000551{
552 struct ip_tunnel *tunnel = netdev_priv(dev);
553 const struct iphdr *inner_iph;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000554 struct flowi4 fl4;
555 u8 tos, ttl;
556 __be16 df;
Eric Dumazetb045d372014-02-03 12:52:14 -0800557 struct rtable *rt; /* Route to the other host */
Pravin B Shelarc5441932013-03-25 14:49:35 +0000558 unsigned int max_headroom; /* The extra header space needed */
559 __be32 dst;
Timo Teräs22fb22e2014-05-16 08:34:39 +0300560 bool connected;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000561
562 inner_iph = (const struct iphdr *)skb_inner_network_header(skb);
Timo Teräs22fb22e2014-05-16 08:34:39 +0300563 connected = (tunnel->parms.iph.daddr != 0);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000564
Bernie Harris5146d1f2016-02-22 12:58:05 +1300565 memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
566
Pravin B Shelarc5441932013-03-25 14:49:35 +0000567 dst = tnl_params->daddr;
568 if (dst == 0) {
569 /* NBMA tunnel */
570
Ian Morris51456b22015-04-03 09:17:26 +0100571 if (!skb_dst(skb)) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000572 dev->stats.tx_fifo_errors++;
573 goto tx_error;
574 }
575
576 if (skb->protocol == htons(ETH_P_IP)) {
577 rt = skb_rtable(skb);
578 dst = rt_nexthop(rt, inner_iph->daddr);
579 }
580#if IS_ENABLED(CONFIG_IPV6)
581 else if (skb->protocol == htons(ETH_P_IPV6)) {
582 const struct in6_addr *addr6;
583 struct neighbour *neigh;
584 bool do_tx_error_icmp;
585 int addr_type;
586
587 neigh = dst_neigh_lookup(skb_dst(skb),
588 &ipv6_hdr(skb)->daddr);
Ian Morris51456b22015-04-03 09:17:26 +0100589 if (!neigh)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000590 goto tx_error;
591
592 addr6 = (const struct in6_addr *)&neigh->primary_key;
593 addr_type = ipv6_addr_type(addr6);
594
595 if (addr_type == IPV6_ADDR_ANY) {
596 addr6 = &ipv6_hdr(skb)->daddr;
597 addr_type = ipv6_addr_type(addr6);
598 }
599
600 if ((addr_type & IPV6_ADDR_COMPATv4) == 0)
601 do_tx_error_icmp = true;
602 else {
603 do_tx_error_icmp = false;
604 dst = addr6->s6_addr32[3];
605 }
606 neigh_release(neigh);
607 if (do_tx_error_icmp)
608 goto tx_error_icmp;
609 }
610#endif
611 else
612 goto tx_error;
Tom Herbert7d442fa2014-01-02 11:48:26 -0800613
614 connected = false;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000615 }
616
617 tos = tnl_params->tos;
618 if (tos & 0x1) {
619 tos &= ~0x1;
Tom Herbert7d442fa2014-01-02 11:48:26 -0800620 if (skb->protocol == htons(ETH_P_IP)) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000621 tos = inner_iph->tos;
Tom Herbert7d442fa2014-01-02 11:48:26 -0800622 connected = false;
623 } else if (skb->protocol == htons(ETH_P_IPV6)) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000624 tos = ipv6_get_dsfield((const struct ipv6hdr *)inner_iph);
Tom Herbert7d442fa2014-01-02 11:48:26 -0800625 connected = false;
626 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000627 }
628
Tom Herbert7d442fa2014-01-02 11:48:26 -0800629 init_tunnel_flow(&fl4, protocol, dst, tnl_params->saddr,
630 tunnel->parms.o_key, RT_TOS(tos), tunnel->parms.link);
631
Tom Herbert56328482014-09-17 12:25:58 -0700632 if (ip_tunnel_encap(skb, tunnel, &protocol, &fl4) < 0)
633 goto tx_error;
634
Paolo Abenie09acdd2016-02-12 15:43:55 +0100635 rt = connected ? dst_cache_get_ip4(&tunnel->dst_cache, &fl4.saddr) :
636 NULL;
Tom Herbert7d442fa2014-01-02 11:48:26 -0800637
638 if (!rt) {
639 rt = ip_route_output_key(tunnel->net, &fl4);
640
641 if (IS_ERR(rt)) {
642 dev->stats.tx_carrier_errors++;
643 goto tx_error;
644 }
645 if (connected)
Paolo Abenie09acdd2016-02-12 15:43:55 +0100646 dst_cache_set_ip4(&tunnel->dst_cache, &rt->dst,
647 fl4.saddr);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000648 }
Tom Herbert7d442fa2014-01-02 11:48:26 -0800649
Pravin B Shelar0e6fbc52013-06-17 17:49:56 -0700650 if (rt->dst.dev == dev) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000651 ip_rt_put(rt);
652 dev->stats.collisions++;
653 goto tx_error;
654 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000655
Timo Teräsfc24f2b2015-07-07 08:34:13 +0300656 if (tnl_update_pmtu(dev, skb, rt, tnl_params->frag_off, inner_iph)) {
Pravin B Shelar23a36472013-07-02 10:57:33 -0700657 ip_rt_put(rt);
658 goto tx_error;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000659 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000660
661 if (tunnel->err_count > 0) {
662 if (time_before(jiffies,
663 tunnel->err_time + IPTUNNEL_ERR_TIMEO)) {
664 tunnel->err_count--;
665
666 dst_link_failure(skb);
667 } else
668 tunnel->err_count = 0;
669 }
670
Pravin B Shelard4a71b12013-09-25 09:57:47 -0700671 tos = ip_tunnel_ecn_encap(tos, inner_iph, skb);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000672 ttl = tnl_params->ttl;
673 if (ttl == 0) {
674 if (skb->protocol == htons(ETH_P_IP))
675 ttl = inner_iph->ttl;
676#if IS_ENABLED(CONFIG_IPV6)
677 else if (skb->protocol == htons(ETH_P_IPV6))
678 ttl = ((const struct ipv6hdr *)inner_iph)->hop_limit;
679#endif
680 else
681 ttl = ip4_dst_hoplimit(&rt->dst);
682 }
683
Pravin B Shelar23a36472013-07-02 10:57:33 -0700684 df = tnl_params->frag_off;
Philip Prindeville22a59be2016-06-14 15:53:02 -0600685 if (skb->protocol == htons(ETH_P_IP) && !tunnel->ignore_df)
Pravin B Shelar23a36472013-07-02 10:57:33 -0700686 df |= (inner_iph->frag_off&htons(IP_DF));
687
Pravin B Shelar0e6fbc52013-06-17 17:49:56 -0700688 max_headroom = LL_RESERVED_SPACE(rt->dst.dev) + sizeof(struct iphdr)
Tom Herbert7371e022014-10-03 15:48:07 -0700689 + rt->dst.header_len + ip_encap_hlen(&tunnel->encap);
Steffen Klassert3e08f4a2013-10-01 11:33:59 +0200690 if (max_headroom > dev->needed_headroom)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000691 dev->needed_headroom = max_headroom;
Steffen Klassert3e08f4a2013-10-01 11:33:59 +0200692
693 if (skb_cow_head(skb, dev->needed_headroom)) {
Dmitry Popov586d5fc2014-06-06 04:34:37 +0400694 ip_rt_put(rt);
Steffen Klassert3e08f4a2013-10-01 11:33:59 +0200695 dev->stats.tx_dropped++;
Eric Dumazet3acfa1e2014-01-18 18:27:49 -0800696 kfree_skb(skb);
Steffen Klassert3e08f4a2013-10-01 11:33:59 +0200697 return;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000698 }
699
Pravin B Shelar039f5062015-12-24 14:34:54 -0800700 iptunnel_xmit(NULL, rt, skb, fl4.saddr, fl4.daddr, protocol, tos, ttl,
701 df, !net_eq(tunnel->net, dev_net(dev)));
Pravin B Shelarc5441932013-03-25 14:49:35 +0000702 return;
703
704#if IS_ENABLED(CONFIG_IPV6)
705tx_error_icmp:
706 dst_link_failure(skb);
707#endif
708tx_error:
709 dev->stats.tx_errors++;
Eric Dumazet3acfa1e2014-01-18 18:27:49 -0800710 kfree_skb(skb);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000711}
712EXPORT_SYMBOL_GPL(ip_tunnel_xmit);
713
714static void ip_tunnel_update(struct ip_tunnel_net *itn,
715 struct ip_tunnel *t,
716 struct net_device *dev,
717 struct ip_tunnel_parm *p,
718 bool set_mtu)
719{
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700720 ip_tunnel_del(itn, t);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000721 t->parms.iph.saddr = p->iph.saddr;
722 t->parms.iph.daddr = p->iph.daddr;
723 t->parms.i_key = p->i_key;
724 t->parms.o_key = p->o_key;
725 if (dev->type != ARPHRD_ETHER) {
726 memcpy(dev->dev_addr, &p->iph.saddr, 4);
727 memcpy(dev->broadcast, &p->iph.daddr, 4);
728 }
729 ip_tunnel_add(itn, t);
730
731 t->parms.iph.ttl = p->iph.ttl;
732 t->parms.iph.tos = p->iph.tos;
733 t->parms.iph.frag_off = p->iph.frag_off;
734
735 if (t->parms.link != p->link) {
736 int mtu;
737
738 t->parms.link = p->link;
739 mtu = ip_tunnel_bind_dev(dev);
740 if (set_mtu)
741 dev->mtu = mtu;
742 }
Paolo Abenie09acdd2016-02-12 15:43:55 +0100743 dst_cache_reset(&t->dst_cache);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000744 netdev_state_change(dev);
745}
746
747int ip_tunnel_ioctl(struct net_device *dev, struct ip_tunnel_parm *p, int cmd)
748{
749 int err = 0;
Nicolas Dichtel8c923ce2014-04-16 11:19:32 +0200750 struct ip_tunnel *t = netdev_priv(dev);
751 struct net *net = t->net;
752 struct ip_tunnel_net *itn = net_generic(net, t->ip_tnl_net_id);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000753
754 BUG_ON(!itn->fb_tunnel_dev);
755 switch (cmd) {
756 case SIOCGETTUNNEL:
Nicolas Dichtel8c923ce2014-04-16 11:19:32 +0200757 if (dev == itn->fb_tunnel_dev) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000758 t = ip_tunnel_find(itn, p, itn->fb_tunnel_dev->type);
Ian Morris51456b22015-04-03 09:17:26 +0100759 if (!t)
Nicolas Dichtel8c923ce2014-04-16 11:19:32 +0200760 t = netdev_priv(dev);
761 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000762 memcpy(p, &t->parms, sizeof(*p));
763 break;
764
765 case SIOCADDTUNNEL:
766 case SIOCCHGTUNNEL:
767 err = -EPERM;
768 if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
769 goto done;
770 if (p->iph.ttl)
771 p->iph.frag_off |= htons(IP_DF);
Dmitry Popov7c8e6b92014-06-08 02:06:25 +0400772 if (!(p->i_flags & VTI_ISVTI)) {
773 if (!(p->i_flags & TUNNEL_KEY))
774 p->i_key = 0;
775 if (!(p->o_flags & TUNNEL_KEY))
776 p->o_key = 0;
777 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000778
779 t = ip_tunnel_find(itn, p, itn->fb_tunnel_dev->type);
780
Steffen Klassertd61746b2014-09-22 09:11:08 +0200781 if (cmd == SIOCADDTUNNEL) {
782 if (!t) {
783 t = ip_tunnel_create(net, itn, p);
784 err = PTR_ERR_OR_ZERO(t);
785 break;
786 }
787
788 err = -EEXIST;
Duan Jiongee30ef42014-05-15 13:07:02 +0800789 break;
Florian Westphal6dd3c9e2014-02-14 13:14:39 +0100790 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000791 if (dev != itn->fb_tunnel_dev && cmd == SIOCCHGTUNNEL) {
Ian Morris00db4122015-04-03 09:17:27 +0100792 if (t) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000793 if (t->dev != dev) {
794 err = -EEXIST;
795 break;
796 }
797 } else {
798 unsigned int nflags = 0;
799
800 if (ipv4_is_multicast(p->iph.daddr))
801 nflags = IFF_BROADCAST;
802 else if (p->iph.daddr)
803 nflags = IFF_POINTOPOINT;
804
805 if ((dev->flags^nflags)&(IFF_POINTOPOINT|IFF_BROADCAST)) {
806 err = -EINVAL;
807 break;
808 }
809
810 t = netdev_priv(dev);
811 }
812 }
813
814 if (t) {
815 err = 0;
816 ip_tunnel_update(itn, t, dev, p, true);
Florian Westphal6dd3c9e2014-02-14 13:14:39 +0100817 } else {
818 err = -ENOENT;
819 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000820 break;
821
822 case SIOCDELTUNNEL:
823 err = -EPERM;
824 if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
825 goto done;
826
827 if (dev == itn->fb_tunnel_dev) {
828 err = -ENOENT;
829 t = ip_tunnel_find(itn, p, itn->fb_tunnel_dev->type);
Ian Morris51456b22015-04-03 09:17:26 +0100830 if (!t)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000831 goto done;
832 err = -EPERM;
833 if (t == netdev_priv(itn->fb_tunnel_dev))
834 goto done;
835 dev = t->dev;
836 }
837 unregister_netdevice(dev);
838 err = 0;
839 break;
840
841 default:
842 err = -EINVAL;
843 }
844
845done:
846 return err;
847}
848EXPORT_SYMBOL_GPL(ip_tunnel_ioctl);
849
David Wragg7e059152016-02-10 00:05:58 +0000850int __ip_tunnel_change_mtu(struct net_device *dev, int new_mtu, bool strict)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000851{
852 struct ip_tunnel *tunnel = netdev_priv(dev);
853 int t_hlen = tunnel->hlen + sizeof(struct iphdr);
David Wragg7e059152016-02-10 00:05:58 +0000854 int max_mtu = 0xFFF8 - dev->hard_header_len - t_hlen;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000855
David Wragg7e059152016-02-10 00:05:58 +0000856 if (new_mtu < 68)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000857 return -EINVAL;
David Wragg7e059152016-02-10 00:05:58 +0000858
859 if (new_mtu > max_mtu) {
860 if (strict)
861 return -EINVAL;
862
863 new_mtu = max_mtu;
864 }
865
Pravin B Shelarc5441932013-03-25 14:49:35 +0000866 dev->mtu = new_mtu;
867 return 0;
868}
David Wragg7e059152016-02-10 00:05:58 +0000869EXPORT_SYMBOL_GPL(__ip_tunnel_change_mtu);
870
871int ip_tunnel_change_mtu(struct net_device *dev, int new_mtu)
872{
873 return __ip_tunnel_change_mtu(dev, new_mtu, true);
874}
Pravin B Shelarc5441932013-03-25 14:49:35 +0000875EXPORT_SYMBOL_GPL(ip_tunnel_change_mtu);
876
877static void ip_tunnel_dev_free(struct net_device *dev)
878{
879 struct ip_tunnel *tunnel = netdev_priv(dev);
880
881 gro_cells_destroy(&tunnel->gro_cells);
Paolo Abenie09acdd2016-02-12 15:43:55 +0100882 dst_cache_destroy(&tunnel->dst_cache);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000883 free_percpu(dev->tstats);
884 free_netdev(dev);
885}
886
887void ip_tunnel_dellink(struct net_device *dev, struct list_head *head)
888{
Pravin B Shelarc5441932013-03-25 14:49:35 +0000889 struct ip_tunnel *tunnel = netdev_priv(dev);
890 struct ip_tunnel_net *itn;
891
Nicolas Dichtel6c742e72013-08-13 17:51:11 +0200892 itn = net_generic(tunnel->net, tunnel->ip_tnl_net_id);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000893
894 if (itn->fb_tunnel_dev != dev) {
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700895 ip_tunnel_del(itn, netdev_priv(dev));
Pravin B Shelarc5441932013-03-25 14:49:35 +0000896 unregister_netdevice_queue(dev, head);
897 }
898}
899EXPORT_SYMBOL_GPL(ip_tunnel_dellink);
900
Nicolas Dichtel1728d4f2015-01-15 15:11:17 +0100901struct net *ip_tunnel_get_link_net(const struct net_device *dev)
902{
903 struct ip_tunnel *tunnel = netdev_priv(dev);
904
905 return tunnel->net;
906}
907EXPORT_SYMBOL(ip_tunnel_get_link_net);
908
Nicolas Dichtel1e995842015-04-02 17:07:02 +0200909int ip_tunnel_get_iflink(const struct net_device *dev)
910{
911 struct ip_tunnel *tunnel = netdev_priv(dev);
912
913 return tunnel->parms.link;
914}
915EXPORT_SYMBOL(ip_tunnel_get_iflink);
916
Eric Dumazetd3b6f612013-06-07 13:26:05 -0700917int ip_tunnel_init_net(struct net *net, int ip_tnl_net_id,
Pravin B Shelarc5441932013-03-25 14:49:35 +0000918 struct rtnl_link_ops *ops, char *devname)
919{
920 struct ip_tunnel_net *itn = net_generic(net, ip_tnl_net_id);
921 struct ip_tunnel_parm parms;
stephen hemminger6261d982013-08-05 22:51:37 -0700922 unsigned int i;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000923
stephen hemminger6261d982013-08-05 22:51:37 -0700924 for (i = 0; i < IP_TNL_HASH_SIZE; i++)
925 INIT_HLIST_HEAD(&itn->tunnels[i]);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000926
927 if (!ops) {
928 itn->fb_tunnel_dev = NULL;
929 return 0;
930 }
stephen hemminger6261d982013-08-05 22:51:37 -0700931
Pravin B Shelarc5441932013-03-25 14:49:35 +0000932 memset(&parms, 0, sizeof(parms));
933 if (devname)
934 strlcpy(parms.name, devname, IFNAMSIZ);
935
936 rtnl_lock();
937 itn->fb_tunnel_dev = __ip_tunnel_create(net, ops, &parms);
Dan Carpenterea857f22013-08-19 10:05:10 +0300938 /* FB netdevice is special: we have one, and only one per netns.
939 * Allowing to move it to another netns is clearly unsafe.
940 */
Steffen Klassert67013282013-10-01 11:34:48 +0200941 if (!IS_ERR(itn->fb_tunnel_dev)) {
Dan Carpenterb4de77a2013-08-23 11:15:37 +0300942 itn->fb_tunnel_dev->features |= NETIF_F_NETNS_LOCAL;
Steffen Klassert78ff4be2014-05-19 11:36:56 +0200943 itn->fb_tunnel_dev->mtu = ip_tunnel_bind_dev(itn->fb_tunnel_dev);
Steffen Klassert67013282013-10-01 11:34:48 +0200944 ip_tunnel_add(itn, netdev_priv(itn->fb_tunnel_dev));
945 }
Dan Carpenterb4de77a2013-08-23 11:15:37 +0300946 rtnl_unlock();
Pravin B Shelarc5441932013-03-25 14:49:35 +0000947
Sachin Kamat27d79f32014-01-27 12:13:57 +0530948 return PTR_ERR_OR_ZERO(itn->fb_tunnel_dev);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000949}
950EXPORT_SYMBOL_GPL(ip_tunnel_init_net);
951
Nicolas Dichtel6c742e72013-08-13 17:51:11 +0200952static void ip_tunnel_destroy(struct ip_tunnel_net *itn, struct list_head *head,
953 struct rtnl_link_ops *ops)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000954{
Nicolas Dichtel6c742e72013-08-13 17:51:11 +0200955 struct net *net = dev_net(itn->fb_tunnel_dev);
956 struct net_device *dev, *aux;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000957 int h;
958
Nicolas Dichtel6c742e72013-08-13 17:51:11 +0200959 for_each_netdev_safe(net, dev, aux)
960 if (dev->rtnl_link_ops == ops)
961 unregister_netdevice_queue(dev, head);
962
Pravin B Shelarc5441932013-03-25 14:49:35 +0000963 for (h = 0; h < IP_TNL_HASH_SIZE; h++) {
964 struct ip_tunnel *t;
965 struct hlist_node *n;
966 struct hlist_head *thead = &itn->tunnels[h];
967
968 hlist_for_each_entry_safe(t, n, thead, hash_node)
Nicolas Dichtel6c742e72013-08-13 17:51:11 +0200969 /* If dev is in the same netns, it has already
970 * been added to the list by the previous loop.
971 */
972 if (!net_eq(dev_net(t->dev), net))
973 unregister_netdevice_queue(t->dev, head);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000974 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000975}
976
Nicolas Dichtel6c742e72013-08-13 17:51:11 +0200977void ip_tunnel_delete_net(struct ip_tunnel_net *itn, struct rtnl_link_ops *ops)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000978{
979 LIST_HEAD(list);
980
981 rtnl_lock();
Nicolas Dichtel6c742e72013-08-13 17:51:11 +0200982 ip_tunnel_destroy(itn, &list, ops);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000983 unregister_netdevice_many(&list);
984 rtnl_unlock();
Pravin B Shelarc5441932013-03-25 14:49:35 +0000985}
986EXPORT_SYMBOL_GPL(ip_tunnel_delete_net);
987
988int ip_tunnel_newlink(struct net_device *dev, struct nlattr *tb[],
989 struct ip_tunnel_parm *p)
990{
991 struct ip_tunnel *nt;
992 struct net *net = dev_net(dev);
993 struct ip_tunnel_net *itn;
994 int mtu;
995 int err;
996
997 nt = netdev_priv(dev);
998 itn = net_generic(net, nt->ip_tnl_net_id);
999
Pravin B Shelar2e15ea32015-08-07 23:51:42 -07001000 if (nt->collect_md) {
1001 if (rtnl_dereference(itn->collect_md_tun))
1002 return -EEXIST;
1003 } else {
1004 if (ip_tunnel_find(itn, p, dev->type))
1005 return -EEXIST;
1006 }
Pravin B Shelarc5441932013-03-25 14:49:35 +00001007
Nicolas Dichtel5e6700b2013-06-26 16:11:28 +02001008 nt->net = net;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001009 nt->parms = *p;
1010 err = register_netdevice(dev);
1011 if (err)
1012 goto out;
1013
1014 if (dev->type == ARPHRD_ETHER && !tb[IFLA_ADDRESS])
1015 eth_hw_addr_random(dev);
1016
1017 mtu = ip_tunnel_bind_dev(dev);
1018 if (!tb[IFLA_MTU])
1019 dev->mtu = mtu;
1020
1021 ip_tunnel_add(itn, nt);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001022out:
1023 return err;
1024}
1025EXPORT_SYMBOL_GPL(ip_tunnel_newlink);
1026
1027int ip_tunnel_changelink(struct net_device *dev, struct nlattr *tb[],
1028 struct ip_tunnel_parm *p)
1029{
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001030 struct ip_tunnel *t;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001031 struct ip_tunnel *tunnel = netdev_priv(dev);
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001032 struct net *net = tunnel->net;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001033 struct ip_tunnel_net *itn = net_generic(net, tunnel->ip_tnl_net_id);
1034
1035 if (dev == itn->fb_tunnel_dev)
1036 return -EINVAL;
1037
Pravin B Shelarc5441932013-03-25 14:49:35 +00001038 t = ip_tunnel_find(itn, p, dev->type);
1039
1040 if (t) {
1041 if (t->dev != dev)
1042 return -EEXIST;
1043 } else {
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001044 t = tunnel;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001045
1046 if (dev->type != ARPHRD_ETHER) {
1047 unsigned int nflags = 0;
1048
1049 if (ipv4_is_multicast(p->iph.daddr))
1050 nflags = IFF_BROADCAST;
1051 else if (p->iph.daddr)
1052 nflags = IFF_POINTOPOINT;
1053
1054 if ((dev->flags ^ nflags) &
1055 (IFF_POINTOPOINT | IFF_BROADCAST))
1056 return -EINVAL;
1057 }
1058 }
1059
1060 ip_tunnel_update(itn, t, dev, p, !tb[IFLA_MTU]);
1061 return 0;
1062}
1063EXPORT_SYMBOL_GPL(ip_tunnel_changelink);
1064
1065int ip_tunnel_init(struct net_device *dev)
1066{
1067 struct ip_tunnel *tunnel = netdev_priv(dev);
1068 struct iphdr *iph = &tunnel->parms.iph;
WANG Cong1c213bd2014-02-13 11:46:28 -08001069 int err;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001070
1071 dev->destructor = ip_tunnel_dev_free;
WANG Cong1c213bd2014-02-13 11:46:28 -08001072 dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001073 if (!dev->tstats)
1074 return -ENOMEM;
1075
Paolo Abenie09acdd2016-02-12 15:43:55 +01001076 err = dst_cache_init(&tunnel->dst_cache, GFP_KERNEL);
1077 if (err) {
Tom Herbert9a4aa9a2014-01-02 11:48:33 -08001078 free_percpu(dev->tstats);
Paolo Abenie09acdd2016-02-12 15:43:55 +01001079 return err;
Tom Herbert9a4aa9a2014-01-02 11:48:33 -08001080 }
1081
Pravin B Shelarc5441932013-03-25 14:49:35 +00001082 err = gro_cells_init(&tunnel->gro_cells, dev);
1083 if (err) {
Paolo Abenie09acdd2016-02-12 15:43:55 +01001084 dst_cache_destroy(&tunnel->dst_cache);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001085 free_percpu(dev->tstats);
1086 return err;
1087 }
1088
1089 tunnel->dev = dev;
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001090 tunnel->net = dev_net(dev);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001091 strcpy(tunnel->parms.name, dev->name);
1092 iph->version = 4;
1093 iph->ihl = 5;
1094
Pravin B Shelar2e15ea32015-08-07 23:51:42 -07001095 if (tunnel->collect_md) {
1096 dev->features |= NETIF_F_NETNS_LOCAL;
1097 netif_keep_dst(dev);
1098 }
Pravin B Shelarc5441932013-03-25 14:49:35 +00001099 return 0;
1100}
1101EXPORT_SYMBOL_GPL(ip_tunnel_init);
1102
1103void ip_tunnel_uninit(struct net_device *dev)
1104{
Pravin B Shelarc5441932013-03-25 14:49:35 +00001105 struct ip_tunnel *tunnel = netdev_priv(dev);
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001106 struct net *net = tunnel->net;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001107 struct ip_tunnel_net *itn;
1108
1109 itn = net_generic(net, tunnel->ip_tnl_net_id);
1110 /* fb_tunnel_dev will be unregisted in net-exit call. */
1111 if (itn->fb_tunnel_dev != dev)
Pravin B Shelar2e15ea32015-08-07 23:51:42 -07001112 ip_tunnel_del(itn, netdev_priv(dev));
Tom Herbert7d442fa2014-01-02 11:48:26 -08001113
Paolo Abenie09acdd2016-02-12 15:43:55 +01001114 dst_cache_reset(&tunnel->dst_cache);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001115}
1116EXPORT_SYMBOL_GPL(ip_tunnel_uninit);
1117
1118/* Do least required initialization, rest of init is done in tunnel_init call */
1119void ip_tunnel_setup(struct net_device *dev, int net_id)
1120{
1121 struct ip_tunnel *tunnel = netdev_priv(dev);
1122 tunnel->ip_tnl_net_id = net_id;
1123}
1124EXPORT_SYMBOL_GPL(ip_tunnel_setup);
1125
1126MODULE_LICENSE("GPL");