blob: c3587e1c8b825f576c10b252077eda929109dd19 [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>
33#include <linux/mroute.h>
34#include <linux/init.h>
35#include <linux/in6.h>
36#include <linux/inetdevice.h>
37#include <linux/igmp.h>
38#include <linux/netfilter_ipv4.h>
39#include <linux/etherdevice.h>
40#include <linux/if_ether.h>
41#include <linux/if_vlan.h>
42#include <linux/rculist.h>
Sachin Kamat27d79f32014-01-27 12:13:57 +053043#include <linux/err.h>
Pravin B Shelarc5441932013-03-25 14:49:35 +000044
45#include <net/sock.h>
46#include <net/ip.h>
47#include <net/icmp.h>
48#include <net/protocol.h>
49#include <net/ip_tunnels.h>
50#include <net/arp.h>
51#include <net/checksum.h>
52#include <net/dsfield.h>
53#include <net/inet_ecn.h>
54#include <net/xfrm.h>
55#include <net/net_namespace.h>
56#include <net/netns/generic.h>
57#include <net/rtnetlink.h>
Tom Herbert56328482014-09-17 12:25:58 -070058#include <net/udp.h>
Tom Herbert63487ba2014-11-04 09:06:51 -080059
60#if IS_ENABLED(CONFIG_NET_FOU)
61#include <net/fou.h>
62#endif
Pravin B Shelarc5441932013-03-25 14:49:35 +000063
64#if IS_ENABLED(CONFIG_IPV6)
65#include <net/ipv6.h>
66#include <net/ip6_fib.h>
67#include <net/ip6_route.h>
68#endif
69
Duan Jiong967680e2014-01-19 16:43:42 +080070static unsigned int ip_tunnel_hash(__be32 key, __be32 remote)
Pravin B Shelarc5441932013-03-25 14:49:35 +000071{
72 return hash_32((__force u32)key ^ (__force u32)remote,
73 IP_TNL_HASH_BITS);
74}
75
Eric Dumazet6c7e7612014-01-16 16:41:19 -080076static void __tunnel_dst_set(struct ip_tunnel_dst *idst,
Dmitry Popov95cb5742014-07-29 03:07:52 +040077 struct dst_entry *dst, __be32 saddr)
Tom Herbert7d442fa2014-01-02 11:48:26 -080078{
79 struct dst_entry *old_dst;
80
Eric Dumazetf8864972014-06-24 10:05:11 -070081 dst_clone(dst);
Eric Dumazet6c7e7612014-01-16 16:41:19 -080082 old_dst = xchg((__force struct dst_entry **)&idst->dst, dst);
Tom Herbert7d442fa2014-01-02 11:48:26 -080083 dst_release(old_dst);
Dmitry Popov95cb5742014-07-29 03:07:52 +040084 idst->saddr = saddr;
Tom Herbert7d442fa2014-01-02 11:48:26 -080085}
86
Eric Dumazeta35165c2014-09-22 10:38:16 -070087static noinline void tunnel_dst_set(struct ip_tunnel *t,
Dmitry Popov95cb5742014-07-29 03:07:52 +040088 struct dst_entry *dst, __be32 saddr)
Tom Herbert7d442fa2014-01-02 11:48:26 -080089{
Eric Dumazeta35165c2014-09-22 10:38:16 -070090 __tunnel_dst_set(raw_cpu_ptr(t->dst_cache), dst, saddr);
Tom Herbert7d442fa2014-01-02 11:48:26 -080091}
92
Eric Dumazet6c7e7612014-01-16 16:41:19 -080093static void tunnel_dst_reset(struct ip_tunnel *t)
Tom Herbert7d442fa2014-01-02 11:48:26 -080094{
Dmitry Popov95cb5742014-07-29 03:07:52 +040095 tunnel_dst_set(t, NULL, 0);
Tom Herbert7d442fa2014-01-02 11:48:26 -080096}
97
Nicolas Dichtelcf71d2bc2014-02-20 10:19:31 +010098void ip_tunnel_dst_reset_all(struct ip_tunnel *t)
Tom Herbert9a4aa9a2014-01-02 11:48:33 -080099{
100 int i;
101
102 for_each_possible_cpu(i)
Dmitry Popov95cb5742014-07-29 03:07:52 +0400103 __tunnel_dst_set(per_cpu_ptr(t->dst_cache, i), NULL, 0);
Tom Herbert9a4aa9a2014-01-02 11:48:33 -0800104}
Nicolas Dichtelcf71d2bc2014-02-20 10:19:31 +0100105EXPORT_SYMBOL(ip_tunnel_dst_reset_all);
Tom Herbert9a4aa9a2014-01-02 11:48:33 -0800106
Dmitry Popov95cb5742014-07-29 03:07:52 +0400107static struct rtable *tunnel_rtable_get(struct ip_tunnel *t,
108 u32 cookie, __be32 *saddr)
Tom Herbert7d442fa2014-01-02 11:48:26 -0800109{
Dmitry Popov95cb5742014-07-29 03:07:52 +0400110 struct ip_tunnel_dst *idst;
Tom Herbert7d442fa2014-01-02 11:48:26 -0800111 struct dst_entry *dst;
112
113 rcu_read_lock();
Eric Dumazeta35165c2014-09-22 10:38:16 -0700114 idst = raw_cpu_ptr(t->dst_cache);
Dmitry Popov95cb5742014-07-29 03:07:52 +0400115 dst = rcu_dereference(idst->dst);
Eric Dumazetf8864972014-06-24 10:05:11 -0700116 if (dst && !atomic_inc_not_zero(&dst->__refcnt))
117 dst = NULL;
Eric Dumazetb045d372014-02-03 12:52:14 -0800118 if (dst) {
Dmitry Popov95cb5742014-07-29 03:07:52 +0400119 if (!dst->obsolete || dst->ops->check(dst, cookie)) {
120 *saddr = idst->saddr;
121 } else {
Eric Dumazetb045d372014-02-03 12:52:14 -0800122 tunnel_dst_reset(t);
Eric Dumazetf8864972014-06-24 10:05:11 -0700123 dst_release(dst);
124 dst = NULL;
Eric Dumazetb045d372014-02-03 12:52:14 -0800125 }
Tom Herbert7d442fa2014-01-02 11:48:26 -0800126 }
Eric Dumazetb045d372014-02-03 12:52:14 -0800127 rcu_read_unlock();
128 return (struct rtable *)dst;
Tom Herbert7d442fa2014-01-02 11:48:26 -0800129}
130
Pravin B Shelarc5441932013-03-25 14:49:35 +0000131static bool ip_tunnel_key_match(const struct ip_tunnel_parm *p,
132 __be16 flags, __be32 key)
133{
134 if (p->i_flags & TUNNEL_KEY) {
135 if (flags & TUNNEL_KEY)
136 return key == p->i_key;
137 else
138 /* key expected, none present */
139 return false;
140 } else
141 return !(flags & TUNNEL_KEY);
142}
143
144/* Fallback tunnel: no source, no destination, no key, no options
145
146 Tunnel hash table:
147 We require exact key match i.e. if a key is present in packet
148 it will match only tunnel with the same key; if it is not present,
149 it will match only keyless tunnel.
150
151 All keysless packets, if not matched configured keyless tunnels
152 will match fallback tunnel.
153 Given src, dst and key, find appropriate for input tunnel.
154*/
155struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn,
156 int link, __be16 flags,
157 __be32 remote, __be32 local,
158 __be32 key)
159{
160 unsigned int hash;
161 struct ip_tunnel *t, *cand = NULL;
162 struct hlist_head *head;
163
Duan Jiong967680e2014-01-19 16:43:42 +0800164 hash = ip_tunnel_hash(key, remote);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000165 head = &itn->tunnels[hash];
166
167 hlist_for_each_entry_rcu(t, head, hash_node) {
168 if (local != t->parms.iph.saddr ||
169 remote != t->parms.iph.daddr ||
170 !(t->dev->flags & IFF_UP))
171 continue;
172
173 if (!ip_tunnel_key_match(&t->parms, flags, key))
174 continue;
175
176 if (t->parms.link == link)
177 return t;
178 else
179 cand = t;
180 }
181
182 hlist_for_each_entry_rcu(t, head, hash_node) {
183 if (remote != t->parms.iph.daddr ||
Dmitry Popove0056592014-07-05 02:26:37 +0400184 t->parms.iph.saddr != 0 ||
Pravin B Shelarc5441932013-03-25 14:49:35 +0000185 !(t->dev->flags & IFF_UP))
186 continue;
187
188 if (!ip_tunnel_key_match(&t->parms, flags, key))
189 continue;
190
191 if (t->parms.link == link)
192 return t;
193 else if (!cand)
194 cand = t;
195 }
196
Duan Jiong967680e2014-01-19 16:43:42 +0800197 hash = ip_tunnel_hash(key, 0);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000198 head = &itn->tunnels[hash];
199
200 hlist_for_each_entry_rcu(t, head, hash_node) {
Dmitry Popove0056592014-07-05 02:26:37 +0400201 if ((local != t->parms.iph.saddr || t->parms.iph.daddr != 0) &&
202 (local != t->parms.iph.daddr || !ipv4_is_multicast(local)))
203 continue;
204
205 if (!(t->dev->flags & IFF_UP))
Pravin B Shelarc5441932013-03-25 14:49:35 +0000206 continue;
207
208 if (!ip_tunnel_key_match(&t->parms, flags, key))
209 continue;
210
211 if (t->parms.link == link)
212 return t;
213 else if (!cand)
214 cand = t;
215 }
216
217 if (flags & TUNNEL_NO_KEY)
218 goto skip_key_lookup;
219
220 hlist_for_each_entry_rcu(t, head, hash_node) {
221 if (t->parms.i_key != key ||
Dmitry Popove0056592014-07-05 02:26:37 +0400222 t->parms.iph.saddr != 0 ||
223 t->parms.iph.daddr != 0 ||
Pravin B Shelarc5441932013-03-25 14:49:35 +0000224 !(t->dev->flags & IFF_UP))
225 continue;
226
227 if (t->parms.link == link)
228 return t;
229 else if (!cand)
230 cand = t;
231 }
232
233skip_key_lookup:
234 if (cand)
235 return cand;
236
237 if (itn->fb_tunnel_dev && itn->fb_tunnel_dev->flags & IFF_UP)
238 return netdev_priv(itn->fb_tunnel_dev);
239
240
241 return NULL;
242}
243EXPORT_SYMBOL_GPL(ip_tunnel_lookup);
244
245static struct hlist_head *ip_bucket(struct ip_tunnel_net *itn,
246 struct ip_tunnel_parm *parms)
247{
248 unsigned int h;
249 __be32 remote;
Steffen Klassert6d608f02014-02-21 08:41:09 +0100250 __be32 i_key = parms->i_key;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000251
252 if (parms->iph.daddr && !ipv4_is_multicast(parms->iph.daddr))
253 remote = parms->iph.daddr;
254 else
255 remote = 0;
256
Steffen Klassert6d608f02014-02-21 08:41:09 +0100257 if (!(parms->i_flags & TUNNEL_KEY) && (parms->i_flags & VTI_ISVTI))
258 i_key = 0;
259
260 h = ip_tunnel_hash(i_key, remote);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000261 return &itn->tunnels[h];
262}
263
264static void ip_tunnel_add(struct ip_tunnel_net *itn, struct ip_tunnel *t)
265{
266 struct hlist_head *head = ip_bucket(itn, &t->parms);
267
268 hlist_add_head_rcu(&t->hash_node, head);
269}
270
271static void ip_tunnel_del(struct ip_tunnel *t)
272{
273 hlist_del_init_rcu(&t->hash_node);
274}
275
276static struct ip_tunnel *ip_tunnel_find(struct ip_tunnel_net *itn,
277 struct ip_tunnel_parm *parms,
278 int type)
279{
280 __be32 remote = parms->iph.daddr;
281 __be32 local = parms->iph.saddr;
282 __be32 key = parms->i_key;
Dmitry Popov5ce54af2014-06-08 03:03:08 +0400283 __be16 flags = parms->i_flags;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000284 int link = parms->link;
285 struct ip_tunnel *t = NULL;
286 struct hlist_head *head = ip_bucket(itn, parms);
287
288 hlist_for_each_entry_rcu(t, head, hash_node) {
289 if (local == t->parms.iph.saddr &&
290 remote == t->parms.iph.daddr &&
Pravin B Shelarc5441932013-03-25 14:49:35 +0000291 link == t->parms.link &&
Dmitry Popov5ce54af2014-06-08 03:03:08 +0400292 type == t->dev->type &&
293 ip_tunnel_key_match(&t->parms, flags, key))
Pravin B Shelarc5441932013-03-25 14:49:35 +0000294 break;
295 }
296 return t;
297}
298
299static struct net_device *__ip_tunnel_create(struct net *net,
300 const struct rtnl_link_ops *ops,
301 struct ip_tunnel_parm *parms)
302{
303 int err;
304 struct ip_tunnel *tunnel;
305 struct net_device *dev;
306 char name[IFNAMSIZ];
307
308 if (parms->name[0])
309 strlcpy(name, parms->name, IFNAMSIZ);
310 else {
Pravin B Shelar54a5d382013-03-28 08:21:46 +0000311 if (strlen(ops->kind) > (IFNAMSIZ - 3)) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000312 err = -E2BIG;
313 goto failed;
314 }
315 strlcpy(name, ops->kind, IFNAMSIZ);
316 strncat(name, "%d", 2);
317 }
318
319 ASSERT_RTNL();
Tom Gundersenc835a672014-07-14 16:37:24 +0200320 dev = alloc_netdev(ops->priv_size, name, NET_NAME_UNKNOWN, ops->setup);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000321 if (!dev) {
322 err = -ENOMEM;
323 goto failed;
324 }
325 dev_net_set(dev, net);
326
327 dev->rtnl_link_ops = ops;
328
329 tunnel = netdev_priv(dev);
330 tunnel->parms = *parms;
Nicolas Dichtel5e6700b2013-06-26 16:11:28 +0200331 tunnel->net = net;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000332
333 err = register_netdevice(dev);
334 if (err)
335 goto failed_free;
336
337 return dev;
338
339failed_free:
340 free_netdev(dev);
341failed:
342 return ERR_PTR(err);
343}
344
Tom Herbert7d442fa2014-01-02 11:48:26 -0800345static inline void init_tunnel_flow(struct flowi4 *fl4,
346 int proto,
347 __be32 daddr, __be32 saddr,
348 __be32 key, __u8 tos, int oif)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000349{
350 memset(fl4, 0, sizeof(*fl4));
351 fl4->flowi4_oif = oif;
352 fl4->daddr = daddr;
353 fl4->saddr = saddr;
354 fl4->flowi4_tos = tos;
355 fl4->flowi4_proto = proto;
356 fl4->fl4_gre_key = key;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000357}
358
359static int ip_tunnel_bind_dev(struct net_device *dev)
360{
361 struct net_device *tdev = NULL;
362 struct ip_tunnel *tunnel = netdev_priv(dev);
363 const struct iphdr *iph;
364 int hlen = LL_MAX_HEADER;
365 int mtu = ETH_DATA_LEN;
366 int t_hlen = tunnel->hlen + sizeof(struct iphdr);
367
368 iph = &tunnel->parms.iph;
369
370 /* Guess output device to choose reasonable mtu and needed_headroom */
371 if (iph->daddr) {
372 struct flowi4 fl4;
373 struct rtable *rt;
374
Tom Herbert7d442fa2014-01-02 11:48:26 -0800375 init_tunnel_flow(&fl4, iph->protocol, iph->daddr,
376 iph->saddr, tunnel->parms.o_key,
377 RT_TOS(iph->tos), tunnel->parms.link);
378 rt = ip_route_output_key(tunnel->net, &fl4);
379
Pravin B Shelarc5441932013-03-25 14:49:35 +0000380 if (!IS_ERR(rt)) {
381 tdev = rt->dst.dev;
Dmitry Popov95cb5742014-07-29 03:07:52 +0400382 tunnel_dst_set(tunnel, &rt->dst, fl4.saddr);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000383 ip_rt_put(rt);
384 }
385 if (dev->type != ARPHRD_ETHER)
386 dev->flags |= IFF_POINTOPOINT;
387 }
388
389 if (!tdev && tunnel->parms.link)
Nicolas Dichtel6c742e72013-08-13 17:51:11 +0200390 tdev = __dev_get_by_index(tunnel->net, tunnel->parms.link);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000391
392 if (tdev) {
393 hlen = tdev->hard_header_len + tdev->needed_headroom;
394 mtu = tdev->mtu;
395 }
396 dev->iflink = tunnel->parms.link;
397
398 dev->needed_headroom = t_hlen + hlen;
399 mtu -= (dev->hard_header_len + t_hlen);
400
401 if (mtu < 68)
402 mtu = 68;
403
404 return mtu;
405}
406
407static struct ip_tunnel *ip_tunnel_create(struct net *net,
408 struct ip_tunnel_net *itn,
409 struct ip_tunnel_parm *parms)
410{
Julia Lawall4929fd82014-05-15 05:43:20 +0200411 struct ip_tunnel *nt;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000412 struct net_device *dev;
413
414 BUG_ON(!itn->fb_tunnel_dev);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000415 dev = __ip_tunnel_create(net, itn->fb_tunnel_dev->rtnl_link_ops, parms);
416 if (IS_ERR(dev))
Florian Westphal6dd3c9e2014-02-14 13:14:39 +0100417 return ERR_CAST(dev);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000418
419 dev->mtu = ip_tunnel_bind_dev(dev);
420
421 nt = netdev_priv(dev);
422 ip_tunnel_add(itn, nt);
423 return nt;
424}
425
426int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb,
427 const struct tnl_ptk_info *tpi, bool log_ecn_error)
428{
Li RongQing8f849852014-01-04 13:57:59 +0800429 struct pcpu_sw_netstats *tstats;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000430 const struct iphdr *iph = ip_hdr(skb);
431 int err;
432
Pravin B Shelarc5441932013-03-25 14:49:35 +0000433#ifdef CONFIG_NET_IPGRE_BROADCAST
434 if (ipv4_is_multicast(iph->daddr)) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000435 tunnel->dev->stats.multicast++;
436 skb->pkt_type = PACKET_BROADCAST;
437 }
438#endif
439
440 if ((!(tpi->flags&TUNNEL_CSUM) && (tunnel->parms.i_flags&TUNNEL_CSUM)) ||
441 ((tpi->flags&TUNNEL_CSUM) && !(tunnel->parms.i_flags&TUNNEL_CSUM))) {
442 tunnel->dev->stats.rx_crc_errors++;
443 tunnel->dev->stats.rx_errors++;
444 goto drop;
445 }
446
447 if (tunnel->parms.i_flags&TUNNEL_SEQ) {
448 if (!(tpi->flags&TUNNEL_SEQ) ||
449 (tunnel->i_seqno && (s32)(ntohl(tpi->seq) - tunnel->i_seqno) < 0)) {
450 tunnel->dev->stats.rx_fifo_errors++;
451 tunnel->dev->stats.rx_errors++;
452 goto drop;
453 }
454 tunnel->i_seqno = ntohl(tpi->seq) + 1;
455 }
456
Ying Caie96f2e72014-05-04 15:20:04 -0700457 skb_reset_network_header(skb);
458
Pravin B Shelarc5441932013-03-25 14:49:35 +0000459 err = IP_ECN_decapsulate(iph, skb);
460 if (unlikely(err)) {
461 if (log_ecn_error)
462 net_info_ratelimited("non-ECT from %pI4 with TOS=%#x\n",
463 &iph->saddr, iph->tos);
464 if (err > 1) {
465 ++tunnel->dev->stats.rx_frame_errors;
466 ++tunnel->dev->stats.rx_errors;
467 goto drop;
468 }
469 }
470
471 tstats = this_cpu_ptr(tunnel->dev->tstats);
472 u64_stats_update_begin(&tstats->syncp);
473 tstats->rx_packets++;
474 tstats->rx_bytes += skb->len;
475 u64_stats_update_end(&tstats->syncp);
476
Alexei Starovoitov81b9eab52013-11-12 14:39:13 -0800477 skb_scrub_packet(skb, !net_eq(tunnel->net, dev_net(tunnel->dev)));
478
Pravin B Shelar3d7b46c2013-06-17 17:50:02 -0700479 if (tunnel->dev->type == ARPHRD_ETHER) {
480 skb->protocol = eth_type_trans(skb, tunnel->dev);
481 skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
482 } else {
483 skb->dev = tunnel->dev;
484 }
Nicolas Dichtel64261f22013-08-13 17:51:09 +0200485
Pravin B Shelarc5441932013-03-25 14:49:35 +0000486 gro_cells_receive(&tunnel->gro_cells, skb);
487 return 0;
488
489drop:
490 kfree_skb(skb);
491 return 0;
492}
493EXPORT_SYMBOL_GPL(ip_tunnel_rcv);
494
Tom Herbert56328482014-09-17 12:25:58 -0700495static int ip_encap_hlen(struct ip_tunnel_encap *e)
496{
497 switch (e->type) {
498 case TUNNEL_ENCAP_NONE:
499 return 0;
Tom Herbert63487ba2014-11-04 09:06:51 -0800500#if IS_ENABLED(CONFIG_NET_FOU)
Tom Herbert56328482014-09-17 12:25:58 -0700501 case TUNNEL_ENCAP_FOU:
Tom Herbert63487ba2014-11-04 09:06:51 -0800502 return fou_encap_hlen(e);
Tom Herbertbc1fc392014-10-03 15:48:10 -0700503 case TUNNEL_ENCAP_GUE:
Tom Herbert63487ba2014-11-04 09:06:51 -0800504 return gue_encap_hlen(e);
505#endif
Tom Herbert56328482014-09-17 12:25:58 -0700506 default:
507 return -EINVAL;
508 }
509}
510
511int ip_tunnel_encap_setup(struct ip_tunnel *t,
512 struct ip_tunnel_encap *ipencap)
513{
514 int hlen;
515
516 memset(&t->encap, 0, sizeof(t->encap));
517
518 hlen = ip_encap_hlen(ipencap);
519 if (hlen < 0)
520 return hlen;
521
522 t->encap.type = ipencap->type;
523 t->encap.sport = ipencap->sport;
524 t->encap.dport = ipencap->dport;
525 t->encap.flags = ipencap->flags;
526
527 t->encap_hlen = hlen;
528 t->hlen = t->encap_hlen + t->tun_hlen;
529
530 return 0;
531}
532EXPORT_SYMBOL_GPL(ip_tunnel_encap_setup);
533
Tom Herbert56328482014-09-17 12:25:58 -0700534int ip_tunnel_encap(struct sk_buff *skb, struct ip_tunnel *t,
535 u8 *protocol, struct flowi4 *fl4)
536{
537 switch (t->encap.type) {
538 case TUNNEL_ENCAP_NONE:
539 return 0;
Tom Herbert63487ba2014-11-04 09:06:51 -0800540#if IS_ENABLED(CONFIG_NET_FOU)
Tom Herbert56328482014-09-17 12:25:58 -0700541 case TUNNEL_ENCAP_FOU:
Tom Herbert63487ba2014-11-04 09:06:51 -0800542 return fou_build_header(skb, &t->encap, protocol, fl4);
Tom Herbertbc1fc392014-10-03 15:48:10 -0700543 case TUNNEL_ENCAP_GUE:
Tom Herbert63487ba2014-11-04 09:06:51 -0800544 return gue_build_header(skb, &t->encap, protocol, fl4);
545#endif
Tom Herbert56328482014-09-17 12:25:58 -0700546 default:
547 return -EINVAL;
548 }
549}
550EXPORT_SYMBOL(ip_tunnel_encap);
551
Pravin B Shelar23a36472013-07-02 10:57:33 -0700552static int tnl_update_pmtu(struct net_device *dev, struct sk_buff *skb,
553 struct rtable *rt, __be16 df)
554{
555 struct ip_tunnel *tunnel = netdev_priv(dev);
Alexander Duyck8c91e162013-07-11 13:12:22 -0700556 int pkt_size = skb->len - tunnel->hlen - dev->hard_header_len;
Pravin B Shelar23a36472013-07-02 10:57:33 -0700557 int mtu;
558
559 if (df)
560 mtu = dst_mtu(&rt->dst) - dev->hard_header_len
561 - sizeof(struct iphdr) - tunnel->hlen;
562 else
563 mtu = skb_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu;
564
565 if (skb_dst(skb))
566 skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu);
567
568 if (skb->protocol == htons(ETH_P_IP)) {
569 if (!skb_is_gso(skb) &&
570 (df & htons(IP_DF)) && mtu < pkt_size) {
571 memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
572 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));
573 return -E2BIG;
574 }
575 }
576#if IS_ENABLED(CONFIG_IPV6)
577 else if (skb->protocol == htons(ETH_P_IPV6)) {
578 struct rt6_info *rt6 = (struct rt6_info *)skb_dst(skb);
579
580 if (rt6 && mtu < dst_mtu(skb_dst(skb)) &&
581 mtu >= IPV6_MIN_MTU) {
582 if ((tunnel->parms.iph.daddr &&
583 !ipv4_is_multicast(tunnel->parms.iph.daddr)) ||
584 rt6->rt6i_dst.plen == 128) {
585 rt6->rt6i_flags |= RTF_MODIFIED;
586 dst_metric_set(skb_dst(skb), RTAX_MTU, mtu);
587 }
588 }
589
590 if (!skb_is_gso(skb) && mtu >= IPV6_MIN_MTU &&
591 mtu < pkt_size) {
592 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
593 return -E2BIG;
594 }
595 }
596#endif
597 return 0;
598}
599
Pravin B Shelarc5441932013-03-25 14:49:35 +0000600void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
Tom Herbert56328482014-09-17 12:25:58 -0700601 const struct iphdr *tnl_params, u8 protocol)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000602{
603 struct ip_tunnel *tunnel = netdev_priv(dev);
604 const struct iphdr *inner_iph;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000605 struct flowi4 fl4;
606 u8 tos, ttl;
607 __be16 df;
Eric Dumazetb045d372014-02-03 12:52:14 -0800608 struct rtable *rt; /* Route to the other host */
Pravin B Shelarc5441932013-03-25 14:49:35 +0000609 unsigned int max_headroom; /* The extra header space needed */
610 __be32 dst;
Pravin B Shelar0e6fbc52013-06-17 17:49:56 -0700611 int err;
Timo Teräs22fb22e2014-05-16 08:34:39 +0300612 bool connected;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000613
614 inner_iph = (const struct iphdr *)skb_inner_network_header(skb);
Timo Teräs22fb22e2014-05-16 08:34:39 +0300615 connected = (tunnel->parms.iph.daddr != 0);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000616
617 dst = tnl_params->daddr;
618 if (dst == 0) {
619 /* NBMA tunnel */
620
621 if (skb_dst(skb) == NULL) {
622 dev->stats.tx_fifo_errors++;
623 goto tx_error;
624 }
625
626 if (skb->protocol == htons(ETH_P_IP)) {
627 rt = skb_rtable(skb);
628 dst = rt_nexthop(rt, inner_iph->daddr);
629 }
630#if IS_ENABLED(CONFIG_IPV6)
631 else if (skb->protocol == htons(ETH_P_IPV6)) {
632 const struct in6_addr *addr6;
633 struct neighbour *neigh;
634 bool do_tx_error_icmp;
635 int addr_type;
636
637 neigh = dst_neigh_lookup(skb_dst(skb),
638 &ipv6_hdr(skb)->daddr);
639 if (neigh == NULL)
640 goto tx_error;
641
642 addr6 = (const struct in6_addr *)&neigh->primary_key;
643 addr_type = ipv6_addr_type(addr6);
644
645 if (addr_type == IPV6_ADDR_ANY) {
646 addr6 = &ipv6_hdr(skb)->daddr;
647 addr_type = ipv6_addr_type(addr6);
648 }
649
650 if ((addr_type & IPV6_ADDR_COMPATv4) == 0)
651 do_tx_error_icmp = true;
652 else {
653 do_tx_error_icmp = false;
654 dst = addr6->s6_addr32[3];
655 }
656 neigh_release(neigh);
657 if (do_tx_error_icmp)
658 goto tx_error_icmp;
659 }
660#endif
661 else
662 goto tx_error;
Tom Herbert7d442fa2014-01-02 11:48:26 -0800663
664 connected = false;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000665 }
666
667 tos = tnl_params->tos;
668 if (tos & 0x1) {
669 tos &= ~0x1;
Tom Herbert7d442fa2014-01-02 11:48:26 -0800670 if (skb->protocol == htons(ETH_P_IP)) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000671 tos = inner_iph->tos;
Tom Herbert7d442fa2014-01-02 11:48:26 -0800672 connected = false;
673 } else if (skb->protocol == htons(ETH_P_IPV6)) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000674 tos = ipv6_get_dsfield((const struct ipv6hdr *)inner_iph);
Tom Herbert7d442fa2014-01-02 11:48:26 -0800675 connected = false;
676 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000677 }
678
Tom Herbert7d442fa2014-01-02 11:48:26 -0800679 init_tunnel_flow(&fl4, protocol, dst, tnl_params->saddr,
680 tunnel->parms.o_key, RT_TOS(tos), tunnel->parms.link);
681
Tom Herbert56328482014-09-17 12:25:58 -0700682 if (ip_tunnel_encap(skb, tunnel, &protocol, &fl4) < 0)
683 goto tx_error;
684
Dmitry Popov95cb5742014-07-29 03:07:52 +0400685 rt = connected ? tunnel_rtable_get(tunnel, 0, &fl4.saddr) : NULL;
Tom Herbert7d442fa2014-01-02 11:48:26 -0800686
687 if (!rt) {
688 rt = ip_route_output_key(tunnel->net, &fl4);
689
690 if (IS_ERR(rt)) {
691 dev->stats.tx_carrier_errors++;
692 goto tx_error;
693 }
694 if (connected)
Dmitry Popov95cb5742014-07-29 03:07:52 +0400695 tunnel_dst_set(tunnel, &rt->dst, fl4.saddr);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000696 }
Tom Herbert7d442fa2014-01-02 11:48:26 -0800697
Pravin B Shelar0e6fbc52013-06-17 17:49:56 -0700698 if (rt->dst.dev == dev) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000699 ip_rt_put(rt);
700 dev->stats.collisions++;
701 goto tx_error;
702 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000703
Pravin B Shelar23a36472013-07-02 10:57:33 -0700704 if (tnl_update_pmtu(dev, skb, rt, tnl_params->frag_off)) {
705 ip_rt_put(rt);
706 goto tx_error;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000707 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000708
709 if (tunnel->err_count > 0) {
710 if (time_before(jiffies,
711 tunnel->err_time + IPTUNNEL_ERR_TIMEO)) {
712 tunnel->err_count--;
713
Duan Jiong11c21a32014-01-23 14:00:25 +0800714 memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
Pravin B Shelarc5441932013-03-25 14:49:35 +0000715 dst_link_failure(skb);
716 } else
717 tunnel->err_count = 0;
718 }
719
Pravin B Shelard4a71b12013-09-25 09:57:47 -0700720 tos = ip_tunnel_ecn_encap(tos, inner_iph, skb);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000721 ttl = tnl_params->ttl;
722 if (ttl == 0) {
723 if (skb->protocol == htons(ETH_P_IP))
724 ttl = inner_iph->ttl;
725#if IS_ENABLED(CONFIG_IPV6)
726 else if (skb->protocol == htons(ETH_P_IPV6))
727 ttl = ((const struct ipv6hdr *)inner_iph)->hop_limit;
728#endif
729 else
730 ttl = ip4_dst_hoplimit(&rt->dst);
731 }
732
Pravin B Shelar23a36472013-07-02 10:57:33 -0700733 df = tnl_params->frag_off;
734 if (skb->protocol == htons(ETH_P_IP))
735 df |= (inner_iph->frag_off&htons(IP_DF));
736
Pravin B Shelar0e6fbc52013-06-17 17:49:56 -0700737 max_headroom = LL_RESERVED_SPACE(rt->dst.dev) + sizeof(struct iphdr)
Tom Herbert7371e022014-10-03 15:48:07 -0700738 + rt->dst.header_len + ip_encap_hlen(&tunnel->encap);
Steffen Klassert3e08f4a2013-10-01 11:33:59 +0200739 if (max_headroom > dev->needed_headroom)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000740 dev->needed_headroom = max_headroom;
Steffen Klassert3e08f4a2013-10-01 11:33:59 +0200741
742 if (skb_cow_head(skb, dev->needed_headroom)) {
Dmitry Popov586d5fc2014-06-06 04:34:37 +0400743 ip_rt_put(rt);
Steffen Klassert3e08f4a2013-10-01 11:33:59 +0200744 dev->stats.tx_dropped++;
Eric Dumazet3acfa1e2014-01-18 18:27:49 -0800745 kfree_skb(skb);
Steffen Klassert3e08f4a2013-10-01 11:33:59 +0200746 return;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000747 }
748
Eric Dumazetaad88722014-04-15 13:47:15 -0400749 err = iptunnel_xmit(skb->sk, rt, skb, fl4.saddr, fl4.daddr, protocol,
Pravin B Shelard4a71b12013-09-25 09:57:47 -0700750 tos, ttl, df, !net_eq(tunnel->net, dev_net(dev)));
Pravin B Shelar0e6fbc52013-06-17 17:49:56 -0700751 iptunnel_xmit_stats(err, &dev->stats, dev->tstats);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000752
Pravin B Shelarc5441932013-03-25 14:49:35 +0000753 return;
754
755#if IS_ENABLED(CONFIG_IPV6)
756tx_error_icmp:
757 dst_link_failure(skb);
758#endif
759tx_error:
760 dev->stats.tx_errors++;
Eric Dumazet3acfa1e2014-01-18 18:27:49 -0800761 kfree_skb(skb);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000762}
763EXPORT_SYMBOL_GPL(ip_tunnel_xmit);
764
765static void ip_tunnel_update(struct ip_tunnel_net *itn,
766 struct ip_tunnel *t,
767 struct net_device *dev,
768 struct ip_tunnel_parm *p,
769 bool set_mtu)
770{
771 ip_tunnel_del(t);
772 t->parms.iph.saddr = p->iph.saddr;
773 t->parms.iph.daddr = p->iph.daddr;
774 t->parms.i_key = p->i_key;
775 t->parms.o_key = p->o_key;
776 if (dev->type != ARPHRD_ETHER) {
777 memcpy(dev->dev_addr, &p->iph.saddr, 4);
778 memcpy(dev->broadcast, &p->iph.daddr, 4);
779 }
780 ip_tunnel_add(itn, t);
781
782 t->parms.iph.ttl = p->iph.ttl;
783 t->parms.iph.tos = p->iph.tos;
784 t->parms.iph.frag_off = p->iph.frag_off;
785
786 if (t->parms.link != p->link) {
787 int mtu;
788
789 t->parms.link = p->link;
790 mtu = ip_tunnel_bind_dev(dev);
791 if (set_mtu)
792 dev->mtu = mtu;
793 }
Nicolas Dichtelcf71d2bc2014-02-20 10:19:31 +0100794 ip_tunnel_dst_reset_all(t);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000795 netdev_state_change(dev);
796}
797
798int ip_tunnel_ioctl(struct net_device *dev, struct ip_tunnel_parm *p, int cmd)
799{
800 int err = 0;
Nicolas Dichtel8c923ce2014-04-16 11:19:32 +0200801 struct ip_tunnel *t = netdev_priv(dev);
802 struct net *net = t->net;
803 struct ip_tunnel_net *itn = net_generic(net, t->ip_tnl_net_id);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000804
805 BUG_ON(!itn->fb_tunnel_dev);
806 switch (cmd) {
807 case SIOCGETTUNNEL:
Nicolas Dichtel8c923ce2014-04-16 11:19:32 +0200808 if (dev == itn->fb_tunnel_dev) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000809 t = ip_tunnel_find(itn, p, itn->fb_tunnel_dev->type);
Nicolas Dichtel8c923ce2014-04-16 11:19:32 +0200810 if (t == NULL)
811 t = netdev_priv(dev);
812 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000813 memcpy(p, &t->parms, sizeof(*p));
814 break;
815
816 case SIOCADDTUNNEL:
817 case SIOCCHGTUNNEL:
818 err = -EPERM;
819 if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
820 goto done;
821 if (p->iph.ttl)
822 p->iph.frag_off |= htons(IP_DF);
Dmitry Popov7c8e6b92014-06-08 02:06:25 +0400823 if (!(p->i_flags & VTI_ISVTI)) {
824 if (!(p->i_flags & TUNNEL_KEY))
825 p->i_key = 0;
826 if (!(p->o_flags & TUNNEL_KEY))
827 p->o_key = 0;
828 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000829
830 t = ip_tunnel_find(itn, p, itn->fb_tunnel_dev->type);
831
Steffen Klassertd61746b2014-09-22 09:11:08 +0200832 if (cmd == SIOCADDTUNNEL) {
833 if (!t) {
834 t = ip_tunnel_create(net, itn, p);
835 err = PTR_ERR_OR_ZERO(t);
836 break;
837 }
838
839 err = -EEXIST;
Duan Jiongee30ef42014-05-15 13:07:02 +0800840 break;
Florian Westphal6dd3c9e2014-02-14 13:14:39 +0100841 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000842 if (dev != itn->fb_tunnel_dev && cmd == SIOCCHGTUNNEL) {
843 if (t != NULL) {
844 if (t->dev != dev) {
845 err = -EEXIST;
846 break;
847 }
848 } else {
849 unsigned int nflags = 0;
850
851 if (ipv4_is_multicast(p->iph.daddr))
852 nflags = IFF_BROADCAST;
853 else if (p->iph.daddr)
854 nflags = IFF_POINTOPOINT;
855
856 if ((dev->flags^nflags)&(IFF_POINTOPOINT|IFF_BROADCAST)) {
857 err = -EINVAL;
858 break;
859 }
860
861 t = netdev_priv(dev);
862 }
863 }
864
865 if (t) {
866 err = 0;
867 ip_tunnel_update(itn, t, dev, p, true);
Florian Westphal6dd3c9e2014-02-14 13:14:39 +0100868 } else {
869 err = -ENOENT;
870 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000871 break;
872
873 case SIOCDELTUNNEL:
874 err = -EPERM;
875 if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
876 goto done;
877
878 if (dev == itn->fb_tunnel_dev) {
879 err = -ENOENT;
880 t = ip_tunnel_find(itn, p, itn->fb_tunnel_dev->type);
881 if (t == NULL)
882 goto done;
883 err = -EPERM;
884 if (t == netdev_priv(itn->fb_tunnel_dev))
885 goto done;
886 dev = t->dev;
887 }
888 unregister_netdevice(dev);
889 err = 0;
890 break;
891
892 default:
893 err = -EINVAL;
894 }
895
896done:
897 return err;
898}
899EXPORT_SYMBOL_GPL(ip_tunnel_ioctl);
900
901int ip_tunnel_change_mtu(struct net_device *dev, int new_mtu)
902{
903 struct ip_tunnel *tunnel = netdev_priv(dev);
904 int t_hlen = tunnel->hlen + sizeof(struct iphdr);
905
906 if (new_mtu < 68 ||
907 new_mtu > 0xFFF8 - dev->hard_header_len - t_hlen)
908 return -EINVAL;
909 dev->mtu = new_mtu;
910 return 0;
911}
912EXPORT_SYMBOL_GPL(ip_tunnel_change_mtu);
913
914static void ip_tunnel_dev_free(struct net_device *dev)
915{
916 struct ip_tunnel *tunnel = netdev_priv(dev);
917
918 gro_cells_destroy(&tunnel->gro_cells);
Tom Herbert9a4aa9a2014-01-02 11:48:33 -0800919 free_percpu(tunnel->dst_cache);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000920 free_percpu(dev->tstats);
921 free_netdev(dev);
922}
923
924void ip_tunnel_dellink(struct net_device *dev, struct list_head *head)
925{
Pravin B Shelarc5441932013-03-25 14:49:35 +0000926 struct ip_tunnel *tunnel = netdev_priv(dev);
927 struct ip_tunnel_net *itn;
928
Nicolas Dichtel6c742e72013-08-13 17:51:11 +0200929 itn = net_generic(tunnel->net, tunnel->ip_tnl_net_id);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000930
931 if (itn->fb_tunnel_dev != dev) {
932 ip_tunnel_del(netdev_priv(dev));
933 unregister_netdevice_queue(dev, head);
934 }
935}
936EXPORT_SYMBOL_GPL(ip_tunnel_dellink);
937
Eric Dumazetd3b6f612013-06-07 13:26:05 -0700938int ip_tunnel_init_net(struct net *net, int ip_tnl_net_id,
Pravin B Shelarc5441932013-03-25 14:49:35 +0000939 struct rtnl_link_ops *ops, char *devname)
940{
941 struct ip_tunnel_net *itn = net_generic(net, ip_tnl_net_id);
942 struct ip_tunnel_parm parms;
stephen hemminger6261d982013-08-05 22:51:37 -0700943 unsigned int i;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000944
stephen hemminger6261d982013-08-05 22:51:37 -0700945 for (i = 0; i < IP_TNL_HASH_SIZE; i++)
946 INIT_HLIST_HEAD(&itn->tunnels[i]);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000947
948 if (!ops) {
949 itn->fb_tunnel_dev = NULL;
950 return 0;
951 }
stephen hemminger6261d982013-08-05 22:51:37 -0700952
Pravin B Shelarc5441932013-03-25 14:49:35 +0000953 memset(&parms, 0, sizeof(parms));
954 if (devname)
955 strlcpy(parms.name, devname, IFNAMSIZ);
956
957 rtnl_lock();
958 itn->fb_tunnel_dev = __ip_tunnel_create(net, ops, &parms);
Dan Carpenterea857f22013-08-19 10:05:10 +0300959 /* FB netdevice is special: we have one, and only one per netns.
960 * Allowing to move it to another netns is clearly unsafe.
961 */
Steffen Klassert67013282013-10-01 11:34:48 +0200962 if (!IS_ERR(itn->fb_tunnel_dev)) {
Dan Carpenterb4de77a2013-08-23 11:15:37 +0300963 itn->fb_tunnel_dev->features |= NETIF_F_NETNS_LOCAL;
Steffen Klassert78ff4be2014-05-19 11:36:56 +0200964 itn->fb_tunnel_dev->mtu = ip_tunnel_bind_dev(itn->fb_tunnel_dev);
Steffen Klassert67013282013-10-01 11:34:48 +0200965 ip_tunnel_add(itn, netdev_priv(itn->fb_tunnel_dev));
966 }
Dan Carpenterb4de77a2013-08-23 11:15:37 +0300967 rtnl_unlock();
Pravin B Shelarc5441932013-03-25 14:49:35 +0000968
Sachin Kamat27d79f32014-01-27 12:13:57 +0530969 return PTR_ERR_OR_ZERO(itn->fb_tunnel_dev);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000970}
971EXPORT_SYMBOL_GPL(ip_tunnel_init_net);
972
Nicolas Dichtel6c742e72013-08-13 17:51:11 +0200973static void ip_tunnel_destroy(struct ip_tunnel_net *itn, struct list_head *head,
974 struct rtnl_link_ops *ops)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000975{
Nicolas Dichtel6c742e72013-08-13 17:51:11 +0200976 struct net *net = dev_net(itn->fb_tunnel_dev);
977 struct net_device *dev, *aux;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000978 int h;
979
Nicolas Dichtel6c742e72013-08-13 17:51:11 +0200980 for_each_netdev_safe(net, dev, aux)
981 if (dev->rtnl_link_ops == ops)
982 unregister_netdevice_queue(dev, head);
983
Pravin B Shelarc5441932013-03-25 14:49:35 +0000984 for (h = 0; h < IP_TNL_HASH_SIZE; h++) {
985 struct ip_tunnel *t;
986 struct hlist_node *n;
987 struct hlist_head *thead = &itn->tunnels[h];
988
989 hlist_for_each_entry_safe(t, n, thead, hash_node)
Nicolas Dichtel6c742e72013-08-13 17:51:11 +0200990 /* If dev is in the same netns, it has already
991 * been added to the list by the previous loop.
992 */
993 if (!net_eq(dev_net(t->dev), net))
994 unregister_netdevice_queue(t->dev, head);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000995 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000996}
997
Nicolas Dichtel6c742e72013-08-13 17:51:11 +0200998void ip_tunnel_delete_net(struct ip_tunnel_net *itn, struct rtnl_link_ops *ops)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000999{
1000 LIST_HEAD(list);
1001
1002 rtnl_lock();
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001003 ip_tunnel_destroy(itn, &list, ops);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001004 unregister_netdevice_many(&list);
1005 rtnl_unlock();
Pravin B Shelarc5441932013-03-25 14:49:35 +00001006}
1007EXPORT_SYMBOL_GPL(ip_tunnel_delete_net);
1008
1009int ip_tunnel_newlink(struct net_device *dev, struct nlattr *tb[],
1010 struct ip_tunnel_parm *p)
1011{
1012 struct ip_tunnel *nt;
1013 struct net *net = dev_net(dev);
1014 struct ip_tunnel_net *itn;
1015 int mtu;
1016 int err;
1017
1018 nt = netdev_priv(dev);
1019 itn = net_generic(net, nt->ip_tnl_net_id);
1020
1021 if (ip_tunnel_find(itn, p, dev->type))
1022 return -EEXIST;
1023
Nicolas Dichtel5e6700b2013-06-26 16:11:28 +02001024 nt->net = net;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001025 nt->parms = *p;
1026 err = register_netdevice(dev);
1027 if (err)
1028 goto out;
1029
1030 if (dev->type == ARPHRD_ETHER && !tb[IFLA_ADDRESS])
1031 eth_hw_addr_random(dev);
1032
1033 mtu = ip_tunnel_bind_dev(dev);
1034 if (!tb[IFLA_MTU])
1035 dev->mtu = mtu;
1036
1037 ip_tunnel_add(itn, nt);
1038
1039out:
1040 return err;
1041}
1042EXPORT_SYMBOL_GPL(ip_tunnel_newlink);
1043
1044int ip_tunnel_changelink(struct net_device *dev, struct nlattr *tb[],
1045 struct ip_tunnel_parm *p)
1046{
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001047 struct ip_tunnel *t;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001048 struct ip_tunnel *tunnel = netdev_priv(dev);
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001049 struct net *net = tunnel->net;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001050 struct ip_tunnel_net *itn = net_generic(net, tunnel->ip_tnl_net_id);
1051
1052 if (dev == itn->fb_tunnel_dev)
1053 return -EINVAL;
1054
Pravin B Shelarc5441932013-03-25 14:49:35 +00001055 t = ip_tunnel_find(itn, p, dev->type);
1056
1057 if (t) {
1058 if (t->dev != dev)
1059 return -EEXIST;
1060 } else {
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001061 t = tunnel;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001062
1063 if (dev->type != ARPHRD_ETHER) {
1064 unsigned int nflags = 0;
1065
1066 if (ipv4_is_multicast(p->iph.daddr))
1067 nflags = IFF_BROADCAST;
1068 else if (p->iph.daddr)
1069 nflags = IFF_POINTOPOINT;
1070
1071 if ((dev->flags ^ nflags) &
1072 (IFF_POINTOPOINT | IFF_BROADCAST))
1073 return -EINVAL;
1074 }
1075 }
1076
1077 ip_tunnel_update(itn, t, dev, p, !tb[IFLA_MTU]);
1078 return 0;
1079}
1080EXPORT_SYMBOL_GPL(ip_tunnel_changelink);
1081
1082int ip_tunnel_init(struct net_device *dev)
1083{
1084 struct ip_tunnel *tunnel = netdev_priv(dev);
1085 struct iphdr *iph = &tunnel->parms.iph;
WANG Cong1c213bd2014-02-13 11:46:28 -08001086 int err;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001087
1088 dev->destructor = ip_tunnel_dev_free;
WANG Cong1c213bd2014-02-13 11:46:28 -08001089 dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001090 if (!dev->tstats)
1091 return -ENOMEM;
1092
Tom Herbert9a4aa9a2014-01-02 11:48:33 -08001093 tunnel->dst_cache = alloc_percpu(struct ip_tunnel_dst);
1094 if (!tunnel->dst_cache) {
1095 free_percpu(dev->tstats);
1096 return -ENOMEM;
1097 }
1098
Pravin B Shelarc5441932013-03-25 14:49:35 +00001099 err = gro_cells_init(&tunnel->gro_cells, dev);
1100 if (err) {
Tom Herbert9a4aa9a2014-01-02 11:48:33 -08001101 free_percpu(tunnel->dst_cache);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001102 free_percpu(dev->tstats);
1103 return err;
1104 }
1105
1106 tunnel->dev = dev;
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001107 tunnel->net = dev_net(dev);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001108 strcpy(tunnel->parms.name, dev->name);
1109 iph->version = 4;
1110 iph->ihl = 5;
1111
1112 return 0;
1113}
1114EXPORT_SYMBOL_GPL(ip_tunnel_init);
1115
1116void ip_tunnel_uninit(struct net_device *dev)
1117{
Pravin B Shelarc5441932013-03-25 14:49:35 +00001118 struct ip_tunnel *tunnel = netdev_priv(dev);
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001119 struct net *net = tunnel->net;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001120 struct ip_tunnel_net *itn;
1121
1122 itn = net_generic(net, tunnel->ip_tnl_net_id);
1123 /* fb_tunnel_dev will be unregisted in net-exit call. */
1124 if (itn->fb_tunnel_dev != dev)
1125 ip_tunnel_del(netdev_priv(dev));
Tom Herbert7d442fa2014-01-02 11:48:26 -08001126
Nicolas Dichtelcf71d2bc2014-02-20 10:19:31 +01001127 ip_tunnel_dst_reset_all(tunnel);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001128}
1129EXPORT_SYMBOL_GPL(ip_tunnel_uninit);
1130
1131/* Do least required initialization, rest of init is done in tunnel_init call */
1132void ip_tunnel_setup(struct net_device *dev, int net_id)
1133{
1134 struct ip_tunnel *tunnel = netdev_priv(dev);
1135 tunnel->ip_tnl_net_id = net_id;
1136}
1137EXPORT_SYMBOL_GPL(ip_tunnel_setup);
1138
1139MODULE_LICENSE("GPL");