blob: 336e6892a93ce99aabf1794133c9567ee0effde7 [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
Eric Dumazet6c7e7612014-01-16 16:41:19 -080071static void __tunnel_dst_set(struct ip_tunnel_dst *idst,
Dmitry Popov95cb5742014-07-29 03:07:52 +040072 struct dst_entry *dst, __be32 saddr)
Tom Herbert7d442fa2014-01-02 11:48:26 -080073{
74 struct dst_entry *old_dst;
75
Eric Dumazetf8864972014-06-24 10:05:11 -070076 dst_clone(dst);
Eric Dumazet6c7e7612014-01-16 16:41:19 -080077 old_dst = xchg((__force struct dst_entry **)&idst->dst, dst);
Tom Herbert7d442fa2014-01-02 11:48:26 -080078 dst_release(old_dst);
Dmitry Popov95cb5742014-07-29 03:07:52 +040079 idst->saddr = saddr;
Tom Herbert7d442fa2014-01-02 11:48:26 -080080}
81
Eric Dumazeta35165c2014-09-22 10:38:16 -070082static noinline void tunnel_dst_set(struct ip_tunnel *t,
Dmitry Popov95cb5742014-07-29 03:07:52 +040083 struct dst_entry *dst, __be32 saddr)
Tom Herbert7d442fa2014-01-02 11:48:26 -080084{
Eric Dumazeta35165c2014-09-22 10:38:16 -070085 __tunnel_dst_set(raw_cpu_ptr(t->dst_cache), dst, saddr);
Tom Herbert7d442fa2014-01-02 11:48:26 -080086}
87
Eric Dumazet6c7e7612014-01-16 16:41:19 -080088static void tunnel_dst_reset(struct ip_tunnel *t)
Tom Herbert7d442fa2014-01-02 11:48:26 -080089{
Dmitry Popov95cb5742014-07-29 03:07:52 +040090 tunnel_dst_set(t, NULL, 0);
Tom Herbert7d442fa2014-01-02 11:48:26 -080091}
92
Nicolas Dichtelcf71d2bc2014-02-20 10:19:31 +010093void ip_tunnel_dst_reset_all(struct ip_tunnel *t)
Tom Herbert9a4aa9a2014-01-02 11:48:33 -080094{
95 int i;
96
97 for_each_possible_cpu(i)
Dmitry Popov95cb5742014-07-29 03:07:52 +040098 __tunnel_dst_set(per_cpu_ptr(t->dst_cache, i), NULL, 0);
Tom Herbert9a4aa9a2014-01-02 11:48:33 -080099}
Nicolas Dichtelcf71d2bc2014-02-20 10:19:31 +0100100EXPORT_SYMBOL(ip_tunnel_dst_reset_all);
Tom Herbert9a4aa9a2014-01-02 11:48:33 -0800101
Dmitry Popov95cb5742014-07-29 03:07:52 +0400102static struct rtable *tunnel_rtable_get(struct ip_tunnel *t,
103 u32 cookie, __be32 *saddr)
Tom Herbert7d442fa2014-01-02 11:48:26 -0800104{
Dmitry Popov95cb5742014-07-29 03:07:52 +0400105 struct ip_tunnel_dst *idst;
Tom Herbert7d442fa2014-01-02 11:48:26 -0800106 struct dst_entry *dst;
107
108 rcu_read_lock();
Eric Dumazeta35165c2014-09-22 10:38:16 -0700109 idst = raw_cpu_ptr(t->dst_cache);
Dmitry Popov95cb5742014-07-29 03:07:52 +0400110 dst = rcu_dereference(idst->dst);
Eric Dumazetf8864972014-06-24 10:05:11 -0700111 if (dst && !atomic_inc_not_zero(&dst->__refcnt))
112 dst = NULL;
Eric Dumazetb045d372014-02-03 12:52:14 -0800113 if (dst) {
Dmitry Popov95cb5742014-07-29 03:07:52 +0400114 if (!dst->obsolete || dst->ops->check(dst, cookie)) {
115 *saddr = idst->saddr;
116 } else {
Eric Dumazetb045d372014-02-03 12:52:14 -0800117 tunnel_dst_reset(t);
Eric Dumazetf8864972014-06-24 10:05:11 -0700118 dst_release(dst);
119 dst = NULL;
Eric Dumazetb045d372014-02-03 12:52:14 -0800120 }
Tom Herbert7d442fa2014-01-02 11:48:26 -0800121 }
Eric Dumazetb045d372014-02-03 12:52:14 -0800122 rcu_read_unlock();
123 return (struct rtable *)dst;
Tom Herbert7d442fa2014-01-02 11:48:26 -0800124}
125
Pravin B Shelarc5441932013-03-25 14:49:35 +0000126static bool ip_tunnel_key_match(const struct ip_tunnel_parm *p,
127 __be16 flags, __be32 key)
128{
129 if (p->i_flags & TUNNEL_KEY) {
130 if (flags & TUNNEL_KEY)
131 return key == p->i_key;
132 else
133 /* key expected, none present */
134 return false;
135 } else
136 return !(flags & TUNNEL_KEY);
137}
138
139/* Fallback tunnel: no source, no destination, no key, no options
140
141 Tunnel hash table:
142 We require exact key match i.e. if a key is present in packet
143 it will match only tunnel with the same key; if it is not present,
144 it will match only keyless tunnel.
145
146 All keysless packets, if not matched configured keyless tunnels
147 will match fallback tunnel.
148 Given src, dst and key, find appropriate for input tunnel.
149*/
150struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn,
151 int link, __be16 flags,
152 __be32 remote, __be32 local,
153 __be32 key)
154{
155 unsigned int hash;
156 struct ip_tunnel *t, *cand = NULL;
157 struct hlist_head *head;
158
Duan Jiong967680e2014-01-19 16:43:42 +0800159 hash = ip_tunnel_hash(key, remote);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000160 head = &itn->tunnels[hash];
161
162 hlist_for_each_entry_rcu(t, head, hash_node) {
163 if (local != t->parms.iph.saddr ||
164 remote != t->parms.iph.daddr ||
165 !(t->dev->flags & IFF_UP))
166 continue;
167
168 if (!ip_tunnel_key_match(&t->parms, flags, key))
169 continue;
170
171 if (t->parms.link == link)
172 return t;
173 else
174 cand = t;
175 }
176
177 hlist_for_each_entry_rcu(t, head, hash_node) {
178 if (remote != t->parms.iph.daddr ||
Dmitry Popove0056592014-07-05 02:26:37 +0400179 t->parms.iph.saddr != 0 ||
Pravin B Shelarc5441932013-03-25 14:49:35 +0000180 !(t->dev->flags & IFF_UP))
181 continue;
182
183 if (!ip_tunnel_key_match(&t->parms, flags, key))
184 continue;
185
186 if (t->parms.link == link)
187 return t;
188 else if (!cand)
189 cand = t;
190 }
191
Duan Jiong967680e2014-01-19 16:43:42 +0800192 hash = ip_tunnel_hash(key, 0);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000193 head = &itn->tunnels[hash];
194
195 hlist_for_each_entry_rcu(t, head, hash_node) {
Dmitry Popove0056592014-07-05 02:26:37 +0400196 if ((local != t->parms.iph.saddr || t->parms.iph.daddr != 0) &&
197 (local != t->parms.iph.daddr || !ipv4_is_multicast(local)))
198 continue;
199
200 if (!(t->dev->flags & IFF_UP))
Pravin B Shelarc5441932013-03-25 14:49:35 +0000201 continue;
202
203 if (!ip_tunnel_key_match(&t->parms, flags, key))
204 continue;
205
206 if (t->parms.link == link)
207 return t;
208 else if (!cand)
209 cand = t;
210 }
211
212 if (flags & TUNNEL_NO_KEY)
213 goto skip_key_lookup;
214
215 hlist_for_each_entry_rcu(t, head, hash_node) {
216 if (t->parms.i_key != key ||
Dmitry Popove0056592014-07-05 02:26:37 +0400217 t->parms.iph.saddr != 0 ||
218 t->parms.iph.daddr != 0 ||
Pravin B Shelarc5441932013-03-25 14:49:35 +0000219 !(t->dev->flags & IFF_UP))
220 continue;
221
222 if (t->parms.link == link)
223 return t;
224 else if (!cand)
225 cand = t;
226 }
227
228skip_key_lookup:
229 if (cand)
230 return cand;
231
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700232 t = rcu_dereference(itn->collect_md_tun);
233 if (t)
234 return t;
235
Pravin B Shelarc5441932013-03-25 14:49:35 +0000236 if (itn->fb_tunnel_dev && itn->fb_tunnel_dev->flags & IFF_UP)
237 return netdev_priv(itn->fb_tunnel_dev);
238
Pravin B Shelarc5441932013-03-25 14:49:35 +0000239 return NULL;
240}
241EXPORT_SYMBOL_GPL(ip_tunnel_lookup);
242
243static struct hlist_head *ip_bucket(struct ip_tunnel_net *itn,
244 struct ip_tunnel_parm *parms)
245{
246 unsigned int h;
247 __be32 remote;
Steffen Klassert6d608f02014-02-21 08:41:09 +0100248 __be32 i_key = parms->i_key;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000249
250 if (parms->iph.daddr && !ipv4_is_multicast(parms->iph.daddr))
251 remote = parms->iph.daddr;
252 else
253 remote = 0;
254
Steffen Klassert6d608f02014-02-21 08:41:09 +0100255 if (!(parms->i_flags & TUNNEL_KEY) && (parms->i_flags & VTI_ISVTI))
256 i_key = 0;
257
258 h = ip_tunnel_hash(i_key, remote);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000259 return &itn->tunnels[h];
260}
261
262static void ip_tunnel_add(struct ip_tunnel_net *itn, struct ip_tunnel *t)
263{
264 struct hlist_head *head = ip_bucket(itn, &t->parms);
265
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700266 if (t->collect_md)
267 rcu_assign_pointer(itn->collect_md_tun, t);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000268 hlist_add_head_rcu(&t->hash_node, head);
269}
270
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700271static void ip_tunnel_del(struct ip_tunnel_net *itn, struct ip_tunnel *t)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000272{
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700273 if (t->collect_md)
274 rcu_assign_pointer(itn->collect_md_tun, NULL);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000275 hlist_del_init_rcu(&t->hash_node);
276}
277
278static struct ip_tunnel *ip_tunnel_find(struct ip_tunnel_net *itn,
279 struct ip_tunnel_parm *parms,
280 int type)
281{
282 __be32 remote = parms->iph.daddr;
283 __be32 local = parms->iph.saddr;
284 __be32 key = parms->i_key;
Dmitry Popov5ce54af2014-06-08 03:03:08 +0400285 __be16 flags = parms->i_flags;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000286 int link = parms->link;
287 struct ip_tunnel *t = NULL;
288 struct hlist_head *head = ip_bucket(itn, parms);
289
290 hlist_for_each_entry_rcu(t, head, hash_node) {
291 if (local == t->parms.iph.saddr &&
292 remote == t->parms.iph.daddr &&
Pravin B Shelarc5441932013-03-25 14:49:35 +0000293 link == t->parms.link &&
Dmitry Popov5ce54af2014-06-08 03:03:08 +0400294 type == t->dev->type &&
295 ip_tunnel_key_match(&t->parms, flags, key))
Pravin B Shelarc5441932013-03-25 14:49:35 +0000296 break;
297 }
298 return t;
299}
300
301static struct net_device *__ip_tunnel_create(struct net *net,
302 const struct rtnl_link_ops *ops,
303 struct ip_tunnel_parm *parms)
304{
305 int err;
306 struct ip_tunnel *tunnel;
307 struct net_device *dev;
308 char name[IFNAMSIZ];
309
310 if (parms->name[0])
311 strlcpy(name, parms->name, IFNAMSIZ);
312 else {
Pravin B Shelar54a5d382013-03-28 08:21:46 +0000313 if (strlen(ops->kind) > (IFNAMSIZ - 3)) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000314 err = -E2BIG;
315 goto failed;
316 }
317 strlcpy(name, ops->kind, IFNAMSIZ);
318 strncat(name, "%d", 2);
319 }
320
321 ASSERT_RTNL();
Tom Gundersenc835a672014-07-14 16:37:24 +0200322 dev = alloc_netdev(ops->priv_size, name, NET_NAME_UNKNOWN, ops->setup);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000323 if (!dev) {
324 err = -ENOMEM;
325 goto failed;
326 }
327 dev_net_set(dev, net);
328
329 dev->rtnl_link_ops = ops;
330
331 tunnel = netdev_priv(dev);
332 tunnel->parms = *parms;
Nicolas Dichtel5e6700b2013-06-26 16:11:28 +0200333 tunnel->net = net;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000334
335 err = register_netdevice(dev);
336 if (err)
337 goto failed_free;
338
339 return dev;
340
341failed_free:
342 free_netdev(dev);
343failed:
344 return ERR_PTR(err);
345}
346
Tom Herbert7d442fa2014-01-02 11:48:26 -0800347static inline void init_tunnel_flow(struct flowi4 *fl4,
348 int proto,
349 __be32 daddr, __be32 saddr,
350 __be32 key, __u8 tos, int oif)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000351{
352 memset(fl4, 0, sizeof(*fl4));
353 fl4->flowi4_oif = oif;
354 fl4->daddr = daddr;
355 fl4->saddr = saddr;
356 fl4->flowi4_tos = tos;
357 fl4->flowi4_proto = proto;
358 fl4->fl4_gre_key = key;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000359}
360
361static int ip_tunnel_bind_dev(struct net_device *dev)
362{
363 struct net_device *tdev = NULL;
364 struct ip_tunnel *tunnel = netdev_priv(dev);
365 const struct iphdr *iph;
366 int hlen = LL_MAX_HEADER;
367 int mtu = ETH_DATA_LEN;
368 int t_hlen = tunnel->hlen + sizeof(struct iphdr);
369
370 iph = &tunnel->parms.iph;
371
372 /* Guess output device to choose reasonable mtu and needed_headroom */
373 if (iph->daddr) {
374 struct flowi4 fl4;
375 struct rtable *rt;
376
Tom Herbert7d442fa2014-01-02 11:48:26 -0800377 init_tunnel_flow(&fl4, iph->protocol, iph->daddr,
378 iph->saddr, tunnel->parms.o_key,
379 RT_TOS(iph->tos), tunnel->parms.link);
380 rt = ip_route_output_key(tunnel->net, &fl4);
381
Pravin B Shelarc5441932013-03-25 14:49:35 +0000382 if (!IS_ERR(rt)) {
383 tdev = rt->dst.dev;
Dmitry Popov95cb5742014-07-29 03:07:52 +0400384 tunnel_dst_set(tunnel, &rt->dst, fl4.saddr);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000385 ip_rt_put(rt);
386 }
387 if (dev->type != ARPHRD_ETHER)
388 dev->flags |= IFF_POINTOPOINT;
389 }
390
391 if (!tdev && tunnel->parms.link)
Nicolas Dichtel6c742e72013-08-13 17:51:11 +0200392 tdev = __dev_get_by_index(tunnel->net, tunnel->parms.link);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000393
394 if (tdev) {
395 hlen = tdev->hard_header_len + tdev->needed_headroom;
396 mtu = tdev->mtu;
397 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000398
399 dev->needed_headroom = t_hlen + hlen;
400 mtu -= (dev->hard_header_len + t_hlen);
401
402 if (mtu < 68)
403 mtu = 68;
404
405 return mtu;
406}
407
408static struct ip_tunnel *ip_tunnel_create(struct net *net,
409 struct ip_tunnel_net *itn,
410 struct ip_tunnel_parm *parms)
411{
Julia Lawall4929fd82014-05-15 05:43:20 +0200412 struct ip_tunnel *nt;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000413 struct net_device *dev;
414
415 BUG_ON(!itn->fb_tunnel_dev);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000416 dev = __ip_tunnel_create(net, itn->fb_tunnel_dev->rtnl_link_ops, parms);
417 if (IS_ERR(dev))
Florian Westphal6dd3c9e2014-02-14 13:14:39 +0100418 return ERR_CAST(dev);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000419
420 dev->mtu = ip_tunnel_bind_dev(dev);
421
422 nt = netdev_priv(dev);
423 ip_tunnel_add(itn, nt);
424 return nt;
425}
426
427int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb,
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700428 const struct tnl_ptk_info *tpi, struct metadata_dst *tun_dst,
429 bool log_ecn_error)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000430{
Li RongQing8f849852014-01-04 13:57:59 +0800431 struct pcpu_sw_netstats *tstats;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000432 const struct iphdr *iph = ip_hdr(skb);
433 int err;
434
Pravin B Shelarc5441932013-03-25 14:49:35 +0000435#ifdef CONFIG_NET_IPGRE_BROADCAST
436 if (ipv4_is_multicast(iph->daddr)) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000437 tunnel->dev->stats.multicast++;
438 skb->pkt_type = PACKET_BROADCAST;
439 }
440#endif
441
442 if ((!(tpi->flags&TUNNEL_CSUM) && (tunnel->parms.i_flags&TUNNEL_CSUM)) ||
443 ((tpi->flags&TUNNEL_CSUM) && !(tunnel->parms.i_flags&TUNNEL_CSUM))) {
444 tunnel->dev->stats.rx_crc_errors++;
445 tunnel->dev->stats.rx_errors++;
446 goto drop;
447 }
448
449 if (tunnel->parms.i_flags&TUNNEL_SEQ) {
450 if (!(tpi->flags&TUNNEL_SEQ) ||
451 (tunnel->i_seqno && (s32)(ntohl(tpi->seq) - tunnel->i_seqno) < 0)) {
452 tunnel->dev->stats.rx_fifo_errors++;
453 tunnel->dev->stats.rx_errors++;
454 goto drop;
455 }
456 tunnel->i_seqno = ntohl(tpi->seq) + 1;
457 }
458
Ying Caie96f2e72014-05-04 15:20:04 -0700459 skb_reset_network_header(skb);
460
Pravin B Shelarc5441932013-03-25 14:49:35 +0000461 err = IP_ECN_decapsulate(iph, skb);
462 if (unlikely(err)) {
463 if (log_ecn_error)
464 net_info_ratelimited("non-ECT from %pI4 with TOS=%#x\n",
465 &iph->saddr, iph->tos);
466 if (err > 1) {
467 ++tunnel->dev->stats.rx_frame_errors;
468 ++tunnel->dev->stats.rx_errors;
469 goto drop;
470 }
471 }
472
473 tstats = this_cpu_ptr(tunnel->dev->tstats);
474 u64_stats_update_begin(&tstats->syncp);
475 tstats->rx_packets++;
476 tstats->rx_bytes += skb->len;
477 u64_stats_update_end(&tstats->syncp);
478
Alexei Starovoitov81b9eab2013-11-12 14:39:13 -0800479 skb_scrub_packet(skb, !net_eq(tunnel->net, dev_net(tunnel->dev)));
480
Pravin B Shelar3d7b46c2013-06-17 17:50:02 -0700481 if (tunnel->dev->type == ARPHRD_ETHER) {
482 skb->protocol = eth_type_trans(skb, tunnel->dev);
483 skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
484 } else {
485 skb->dev = tunnel->dev;
486 }
Nicolas Dichtel64261f22013-08-13 17:51:09 +0200487
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700488 if (tun_dst)
489 skb_dst_set(skb, (struct dst_entry *)tun_dst);
490
Pravin B Shelarc5441932013-03-25 14:49:35 +0000491 gro_cells_receive(&tunnel->gro_cells, skb);
492 return 0;
493
494drop:
495 kfree_skb(skb);
496 return 0;
497}
498EXPORT_SYMBOL_GPL(ip_tunnel_rcv);
499
Tom Herbert56328482014-09-17 12:25:58 -0700500static int ip_encap_hlen(struct ip_tunnel_encap *e)
501{
Tom Herberta8c5f902014-11-12 11:54:09 -0800502 const struct ip_tunnel_encap_ops *ops;
503 int hlen = -EINVAL;
504
505 if (e->type == TUNNEL_ENCAP_NONE)
Tom Herbert56328482014-09-17 12:25:58 -0700506 return 0;
Tom Herberta8c5f902014-11-12 11:54:09 -0800507
508 if (e->type >= MAX_IPTUN_ENCAP_OPS)
Tom Herbert56328482014-09-17 12:25:58 -0700509 return -EINVAL;
Tom Herberta8c5f902014-11-12 11:54:09 -0800510
511 rcu_read_lock();
512 ops = rcu_dereference(iptun_encaps[e->type]);
513 if (likely(ops && ops->encap_hlen))
514 hlen = ops->encap_hlen(e);
515 rcu_read_unlock();
516
517 return hlen;
Tom Herbert56328482014-09-17 12:25:58 -0700518}
519
Tom Herberta8c5f902014-11-12 11:54:09 -0800520const struct ip_tunnel_encap_ops __rcu *
521 iptun_encaps[MAX_IPTUN_ENCAP_OPS] __read_mostly;
522
523int ip_tunnel_encap_add_ops(const struct ip_tunnel_encap_ops *ops,
524 unsigned int num)
525{
Thomas Grafbb1553c2014-12-16 21:05:20 +0100526 if (num >= MAX_IPTUN_ENCAP_OPS)
527 return -ERANGE;
528
Tom Herberta8c5f902014-11-12 11:54:09 -0800529 return !cmpxchg((const struct ip_tunnel_encap_ops **)
530 &iptun_encaps[num],
531 NULL, ops) ? 0 : -1;
532}
533EXPORT_SYMBOL(ip_tunnel_encap_add_ops);
534
535int ip_tunnel_encap_del_ops(const struct ip_tunnel_encap_ops *ops,
536 unsigned int num)
537{
538 int ret;
539
Thomas Grafbb1553c2014-12-16 21:05:20 +0100540 if (num >= MAX_IPTUN_ENCAP_OPS)
541 return -ERANGE;
542
Tom Herberta8c5f902014-11-12 11:54:09 -0800543 ret = (cmpxchg((const struct ip_tunnel_encap_ops **)
544 &iptun_encaps[num],
545 ops, NULL) == ops) ? 0 : -1;
546
547 synchronize_net();
548
549 return ret;
550}
551EXPORT_SYMBOL(ip_tunnel_encap_del_ops);
552
Tom Herbert56328482014-09-17 12:25:58 -0700553int ip_tunnel_encap_setup(struct ip_tunnel *t,
554 struct ip_tunnel_encap *ipencap)
555{
556 int hlen;
557
558 memset(&t->encap, 0, sizeof(t->encap));
559
560 hlen = ip_encap_hlen(ipencap);
561 if (hlen < 0)
562 return hlen;
563
564 t->encap.type = ipencap->type;
565 t->encap.sport = ipencap->sport;
566 t->encap.dport = ipencap->dport;
567 t->encap.flags = ipencap->flags;
568
569 t->encap_hlen = hlen;
570 t->hlen = t->encap_hlen + t->tun_hlen;
571
572 return 0;
573}
574EXPORT_SYMBOL_GPL(ip_tunnel_encap_setup);
575
Tom Herbert56328482014-09-17 12:25:58 -0700576int ip_tunnel_encap(struct sk_buff *skb, struct ip_tunnel *t,
577 u8 *protocol, struct flowi4 *fl4)
578{
Tom Herberta8c5f902014-11-12 11:54:09 -0800579 const struct ip_tunnel_encap_ops *ops;
580 int ret = -EINVAL;
581
582 if (t->encap.type == TUNNEL_ENCAP_NONE)
Tom Herbert56328482014-09-17 12:25:58 -0700583 return 0;
Tom Herberta8c5f902014-11-12 11:54:09 -0800584
Thomas Graff1fb5212014-12-16 21:05:21 +0100585 if (t->encap.type >= MAX_IPTUN_ENCAP_OPS)
586 return -EINVAL;
587
Tom Herberta8c5f902014-11-12 11:54:09 -0800588 rcu_read_lock();
589 ops = rcu_dereference(iptun_encaps[t->encap.type]);
590 if (likely(ops && ops->build_header))
591 ret = ops->build_header(skb, &t->encap, protocol, fl4);
592 rcu_read_unlock();
593
594 return ret;
Tom Herbert56328482014-09-17 12:25:58 -0700595}
596EXPORT_SYMBOL(ip_tunnel_encap);
597
Pravin B Shelar23a36472013-07-02 10:57:33 -0700598static int tnl_update_pmtu(struct net_device *dev, struct sk_buff *skb,
Timo Teräsfc24f2b2015-07-07 08:34:13 +0300599 struct rtable *rt, __be16 df,
600 const struct iphdr *inner_iph)
Pravin B Shelar23a36472013-07-02 10:57:33 -0700601{
602 struct ip_tunnel *tunnel = netdev_priv(dev);
Alexander Duyck8c91e162013-07-11 13:12:22 -0700603 int pkt_size = skb->len - tunnel->hlen - dev->hard_header_len;
Pravin B Shelar23a36472013-07-02 10:57:33 -0700604 int mtu;
605
606 if (df)
607 mtu = dst_mtu(&rt->dst) - dev->hard_header_len
608 - sizeof(struct iphdr) - tunnel->hlen;
609 else
610 mtu = skb_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu;
611
612 if (skb_dst(skb))
613 skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu);
614
615 if (skb->protocol == htons(ETH_P_IP)) {
616 if (!skb_is_gso(skb) &&
Timo Teräsfc24f2b2015-07-07 08:34:13 +0300617 (inner_iph->frag_off & htons(IP_DF)) &&
618 mtu < pkt_size) {
Pravin B Shelar23a36472013-07-02 10:57:33 -0700619 memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
620 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));
621 return -E2BIG;
622 }
623 }
624#if IS_ENABLED(CONFIG_IPV6)
625 else if (skb->protocol == htons(ETH_P_IPV6)) {
626 struct rt6_info *rt6 = (struct rt6_info *)skb_dst(skb);
627
628 if (rt6 && mtu < dst_mtu(skb_dst(skb)) &&
629 mtu >= IPV6_MIN_MTU) {
630 if ((tunnel->parms.iph.daddr &&
631 !ipv4_is_multicast(tunnel->parms.iph.daddr)) ||
632 rt6->rt6i_dst.plen == 128) {
633 rt6->rt6i_flags |= RTF_MODIFIED;
634 dst_metric_set(skb_dst(skb), RTAX_MTU, mtu);
635 }
636 }
637
638 if (!skb_is_gso(skb) && mtu >= IPV6_MIN_MTU &&
639 mtu < pkt_size) {
640 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
641 return -E2BIG;
642 }
643 }
644#endif
645 return 0;
646}
647
Pravin B Shelarc5441932013-03-25 14:49:35 +0000648void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
Tom Herbert56328482014-09-17 12:25:58 -0700649 const struct iphdr *tnl_params, u8 protocol)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000650{
651 struct ip_tunnel *tunnel = netdev_priv(dev);
652 const struct iphdr *inner_iph;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000653 struct flowi4 fl4;
654 u8 tos, ttl;
655 __be16 df;
Eric Dumazetb045d372014-02-03 12:52:14 -0800656 struct rtable *rt; /* Route to the other host */
Pravin B Shelarc5441932013-03-25 14:49:35 +0000657 unsigned int max_headroom; /* The extra header space needed */
658 __be32 dst;
Timo Teräs22fb22e2014-05-16 08:34:39 +0300659 bool connected;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000660
661 inner_iph = (const struct iphdr *)skb_inner_network_header(skb);
Timo Teräs22fb22e2014-05-16 08:34:39 +0300662 connected = (tunnel->parms.iph.daddr != 0);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000663
Bernie Harris5146d1f2016-02-22 12:58:05 +1300664 memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
665
Pravin B Shelarc5441932013-03-25 14:49:35 +0000666 dst = tnl_params->daddr;
667 if (dst == 0) {
668 /* NBMA tunnel */
669
Ian Morris51456b22015-04-03 09:17:26 +0100670 if (!skb_dst(skb)) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000671 dev->stats.tx_fifo_errors++;
672 goto tx_error;
673 }
674
675 if (skb->protocol == htons(ETH_P_IP)) {
676 rt = skb_rtable(skb);
677 dst = rt_nexthop(rt, inner_iph->daddr);
678 }
679#if IS_ENABLED(CONFIG_IPV6)
680 else if (skb->protocol == htons(ETH_P_IPV6)) {
681 const struct in6_addr *addr6;
682 struct neighbour *neigh;
683 bool do_tx_error_icmp;
684 int addr_type;
685
686 neigh = dst_neigh_lookup(skb_dst(skb),
687 &ipv6_hdr(skb)->daddr);
Ian Morris51456b22015-04-03 09:17:26 +0100688 if (!neigh)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000689 goto tx_error;
690
691 addr6 = (const struct in6_addr *)&neigh->primary_key;
692 addr_type = ipv6_addr_type(addr6);
693
694 if (addr_type == IPV6_ADDR_ANY) {
695 addr6 = &ipv6_hdr(skb)->daddr;
696 addr_type = ipv6_addr_type(addr6);
697 }
698
699 if ((addr_type & IPV6_ADDR_COMPATv4) == 0)
700 do_tx_error_icmp = true;
701 else {
702 do_tx_error_icmp = false;
703 dst = addr6->s6_addr32[3];
704 }
705 neigh_release(neigh);
706 if (do_tx_error_icmp)
707 goto tx_error_icmp;
708 }
709#endif
710 else
711 goto tx_error;
Tom Herbert7d442fa2014-01-02 11:48:26 -0800712
713 connected = false;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000714 }
715
716 tos = tnl_params->tos;
717 if (tos & 0x1) {
718 tos &= ~0x1;
Tom Herbert7d442fa2014-01-02 11:48:26 -0800719 if (skb->protocol == htons(ETH_P_IP)) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000720 tos = inner_iph->tos;
Tom Herbert7d442fa2014-01-02 11:48:26 -0800721 connected = false;
722 } else if (skb->protocol == htons(ETH_P_IPV6)) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000723 tos = ipv6_get_dsfield((const struct ipv6hdr *)inner_iph);
Tom Herbert7d442fa2014-01-02 11:48:26 -0800724 connected = false;
725 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000726 }
727
Tom Herbert7d442fa2014-01-02 11:48:26 -0800728 init_tunnel_flow(&fl4, protocol, dst, tnl_params->saddr,
729 tunnel->parms.o_key, RT_TOS(tos), tunnel->parms.link);
730
Tom Herbert56328482014-09-17 12:25:58 -0700731 if (ip_tunnel_encap(skb, tunnel, &protocol, &fl4) < 0)
732 goto tx_error;
733
Dmitry Popov95cb5742014-07-29 03:07:52 +0400734 rt = connected ? tunnel_rtable_get(tunnel, 0, &fl4.saddr) : NULL;
Tom Herbert7d442fa2014-01-02 11:48:26 -0800735
736 if (!rt) {
737 rt = ip_route_output_key(tunnel->net, &fl4);
738
739 if (IS_ERR(rt)) {
740 dev->stats.tx_carrier_errors++;
741 goto tx_error;
742 }
743 if (connected)
Dmitry Popov95cb5742014-07-29 03:07:52 +0400744 tunnel_dst_set(tunnel, &rt->dst, fl4.saddr);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000745 }
Tom Herbert7d442fa2014-01-02 11:48:26 -0800746
Pravin B Shelar0e6fbc52013-06-17 17:49:56 -0700747 if (rt->dst.dev == dev) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000748 ip_rt_put(rt);
749 dev->stats.collisions++;
750 goto tx_error;
751 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000752
Timo Teräsfc24f2b2015-07-07 08:34:13 +0300753 if (tnl_update_pmtu(dev, skb, rt, tnl_params->frag_off, inner_iph)) {
Pravin B Shelar23a36472013-07-02 10:57:33 -0700754 ip_rt_put(rt);
755 goto tx_error;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000756 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000757
758 if (tunnel->err_count > 0) {
759 if (time_before(jiffies,
760 tunnel->err_time + IPTUNNEL_ERR_TIMEO)) {
761 tunnel->err_count--;
762
763 dst_link_failure(skb);
764 } else
765 tunnel->err_count = 0;
766 }
767
Pravin B Shelard4a71b12013-09-25 09:57:47 -0700768 tos = ip_tunnel_ecn_encap(tos, inner_iph, skb);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000769 ttl = tnl_params->ttl;
770 if (ttl == 0) {
771 if (skb->protocol == htons(ETH_P_IP))
772 ttl = inner_iph->ttl;
773#if IS_ENABLED(CONFIG_IPV6)
774 else if (skb->protocol == htons(ETH_P_IPV6))
775 ttl = ((const struct ipv6hdr *)inner_iph)->hop_limit;
776#endif
777 else
778 ttl = ip4_dst_hoplimit(&rt->dst);
779 }
780
Pravin B Shelar23a36472013-07-02 10:57:33 -0700781 df = tnl_params->frag_off;
782 if (skb->protocol == htons(ETH_P_IP))
783 df |= (inner_iph->frag_off&htons(IP_DF));
784
Pravin B Shelar0e6fbc52013-06-17 17:49:56 -0700785 max_headroom = LL_RESERVED_SPACE(rt->dst.dev) + sizeof(struct iphdr)
Tom Herbert7371e022014-10-03 15:48:07 -0700786 + rt->dst.header_len + ip_encap_hlen(&tunnel->encap);
Steffen Klassert3e08f4a2013-10-01 11:33:59 +0200787 if (max_headroom > dev->needed_headroom)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000788 dev->needed_headroom = max_headroom;
Steffen Klassert3e08f4a2013-10-01 11:33:59 +0200789
790 if (skb_cow_head(skb, dev->needed_headroom)) {
Dmitry Popov586d5fc2014-06-06 04:34:37 +0400791 ip_rt_put(rt);
Steffen Klassert3e08f4a2013-10-01 11:33:59 +0200792 dev->stats.tx_dropped++;
Eric Dumazet3acfa1e2014-01-18 18:27:49 -0800793 kfree_skb(skb);
Steffen Klassert3e08f4a2013-10-01 11:33:59 +0200794 return;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000795 }
796
Pravin B Shelar039f5062015-12-24 14:34:54 -0800797 iptunnel_xmit(NULL, rt, skb, fl4.saddr, fl4.daddr, protocol, tos, ttl,
798 df, !net_eq(tunnel->net, dev_net(dev)));
Pravin B Shelarc5441932013-03-25 14:49:35 +0000799 return;
800
801#if IS_ENABLED(CONFIG_IPV6)
802tx_error_icmp:
803 dst_link_failure(skb);
804#endif
805tx_error:
806 dev->stats.tx_errors++;
Eric Dumazet3acfa1e2014-01-18 18:27:49 -0800807 kfree_skb(skb);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000808}
809EXPORT_SYMBOL_GPL(ip_tunnel_xmit);
810
811static void ip_tunnel_update(struct ip_tunnel_net *itn,
812 struct ip_tunnel *t,
813 struct net_device *dev,
814 struct ip_tunnel_parm *p,
815 bool set_mtu)
816{
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700817 ip_tunnel_del(itn, t);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000818 t->parms.iph.saddr = p->iph.saddr;
819 t->parms.iph.daddr = p->iph.daddr;
820 t->parms.i_key = p->i_key;
821 t->parms.o_key = p->o_key;
822 if (dev->type != ARPHRD_ETHER) {
823 memcpy(dev->dev_addr, &p->iph.saddr, 4);
824 memcpy(dev->broadcast, &p->iph.daddr, 4);
825 }
826 ip_tunnel_add(itn, t);
827
828 t->parms.iph.ttl = p->iph.ttl;
829 t->parms.iph.tos = p->iph.tos;
830 t->parms.iph.frag_off = p->iph.frag_off;
831
832 if (t->parms.link != p->link) {
833 int mtu;
834
835 t->parms.link = p->link;
836 mtu = ip_tunnel_bind_dev(dev);
837 if (set_mtu)
838 dev->mtu = mtu;
839 }
Nicolas Dichtelcf71d2bc2014-02-20 10:19:31 +0100840 ip_tunnel_dst_reset_all(t);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000841 netdev_state_change(dev);
842}
843
844int ip_tunnel_ioctl(struct net_device *dev, struct ip_tunnel_parm *p, int cmd)
845{
846 int err = 0;
Nicolas Dichtel8c923ce2014-04-16 11:19:32 +0200847 struct ip_tunnel *t = netdev_priv(dev);
848 struct net *net = t->net;
849 struct ip_tunnel_net *itn = net_generic(net, t->ip_tnl_net_id);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000850
851 BUG_ON(!itn->fb_tunnel_dev);
852 switch (cmd) {
853 case SIOCGETTUNNEL:
Nicolas Dichtel8c923ce2014-04-16 11:19:32 +0200854 if (dev == itn->fb_tunnel_dev) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000855 t = ip_tunnel_find(itn, p, itn->fb_tunnel_dev->type);
Ian Morris51456b22015-04-03 09:17:26 +0100856 if (!t)
Nicolas Dichtel8c923ce2014-04-16 11:19:32 +0200857 t = netdev_priv(dev);
858 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000859 memcpy(p, &t->parms, sizeof(*p));
860 break;
861
862 case SIOCADDTUNNEL:
863 case SIOCCHGTUNNEL:
864 err = -EPERM;
865 if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
866 goto done;
867 if (p->iph.ttl)
868 p->iph.frag_off |= htons(IP_DF);
Dmitry Popov7c8e6b92014-06-08 02:06:25 +0400869 if (!(p->i_flags & VTI_ISVTI)) {
870 if (!(p->i_flags & TUNNEL_KEY))
871 p->i_key = 0;
872 if (!(p->o_flags & TUNNEL_KEY))
873 p->o_key = 0;
874 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000875
876 t = ip_tunnel_find(itn, p, itn->fb_tunnel_dev->type);
877
Steffen Klassertd61746b2014-09-22 09:11:08 +0200878 if (cmd == SIOCADDTUNNEL) {
879 if (!t) {
880 t = ip_tunnel_create(net, itn, p);
881 err = PTR_ERR_OR_ZERO(t);
882 break;
883 }
884
885 err = -EEXIST;
Duan Jiongee30ef42014-05-15 13:07:02 +0800886 break;
Florian Westphal6dd3c9e2014-02-14 13:14:39 +0100887 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000888 if (dev != itn->fb_tunnel_dev && cmd == SIOCCHGTUNNEL) {
Ian Morris00db4122015-04-03 09:17:27 +0100889 if (t) {
Pravin B Shelarc5441932013-03-25 14:49:35 +0000890 if (t->dev != dev) {
891 err = -EEXIST;
892 break;
893 }
894 } else {
895 unsigned int nflags = 0;
896
897 if (ipv4_is_multicast(p->iph.daddr))
898 nflags = IFF_BROADCAST;
899 else if (p->iph.daddr)
900 nflags = IFF_POINTOPOINT;
901
902 if ((dev->flags^nflags)&(IFF_POINTOPOINT|IFF_BROADCAST)) {
903 err = -EINVAL;
904 break;
905 }
906
907 t = netdev_priv(dev);
908 }
909 }
910
911 if (t) {
912 err = 0;
913 ip_tunnel_update(itn, t, dev, p, true);
Florian Westphal6dd3c9e2014-02-14 13:14:39 +0100914 } else {
915 err = -ENOENT;
916 }
Pravin B Shelarc5441932013-03-25 14:49:35 +0000917 break;
918
919 case SIOCDELTUNNEL:
920 err = -EPERM;
921 if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
922 goto done;
923
924 if (dev == itn->fb_tunnel_dev) {
925 err = -ENOENT;
926 t = ip_tunnel_find(itn, p, itn->fb_tunnel_dev->type);
Ian Morris51456b22015-04-03 09:17:26 +0100927 if (!t)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000928 goto done;
929 err = -EPERM;
930 if (t == netdev_priv(itn->fb_tunnel_dev))
931 goto done;
932 dev = t->dev;
933 }
934 unregister_netdevice(dev);
935 err = 0;
936 break;
937
938 default:
939 err = -EINVAL;
940 }
941
942done:
943 return err;
944}
945EXPORT_SYMBOL_GPL(ip_tunnel_ioctl);
946
David Wragg7e059152016-02-10 00:05:58 +0000947int __ip_tunnel_change_mtu(struct net_device *dev, int new_mtu, bool strict)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000948{
949 struct ip_tunnel *tunnel = netdev_priv(dev);
950 int t_hlen = tunnel->hlen + sizeof(struct iphdr);
David Wragg7e059152016-02-10 00:05:58 +0000951 int max_mtu = 0xFFF8 - dev->hard_header_len - t_hlen;
Pravin B Shelarc5441932013-03-25 14:49:35 +0000952
David Wragg7e059152016-02-10 00:05:58 +0000953 if (new_mtu < 68)
Pravin B Shelarc5441932013-03-25 14:49:35 +0000954 return -EINVAL;
David Wragg7e059152016-02-10 00:05:58 +0000955
956 if (new_mtu > max_mtu) {
957 if (strict)
958 return -EINVAL;
959
960 new_mtu = max_mtu;
961 }
962
Pravin B Shelarc5441932013-03-25 14:49:35 +0000963 dev->mtu = new_mtu;
964 return 0;
965}
David Wragg7e059152016-02-10 00:05:58 +0000966EXPORT_SYMBOL_GPL(__ip_tunnel_change_mtu);
967
968int ip_tunnel_change_mtu(struct net_device *dev, int new_mtu)
969{
970 return __ip_tunnel_change_mtu(dev, new_mtu, true);
971}
Pravin B Shelarc5441932013-03-25 14:49:35 +0000972EXPORT_SYMBOL_GPL(ip_tunnel_change_mtu);
973
974static void ip_tunnel_dev_free(struct net_device *dev)
975{
976 struct ip_tunnel *tunnel = netdev_priv(dev);
977
978 gro_cells_destroy(&tunnel->gro_cells);
Tom Herbert9a4aa9a2014-01-02 11:48:33 -0800979 free_percpu(tunnel->dst_cache);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000980 free_percpu(dev->tstats);
981 free_netdev(dev);
982}
983
984void ip_tunnel_dellink(struct net_device *dev, struct list_head *head)
985{
Pravin B Shelarc5441932013-03-25 14:49:35 +0000986 struct ip_tunnel *tunnel = netdev_priv(dev);
987 struct ip_tunnel_net *itn;
988
Nicolas Dichtel6c742e72013-08-13 17:51:11 +0200989 itn = net_generic(tunnel->net, tunnel->ip_tnl_net_id);
Pravin B Shelarc5441932013-03-25 14:49:35 +0000990
991 if (itn->fb_tunnel_dev != dev) {
Pravin B Shelar2e15ea32015-08-07 23:51:42 -0700992 ip_tunnel_del(itn, netdev_priv(dev));
Pravin B Shelarc5441932013-03-25 14:49:35 +0000993 unregister_netdevice_queue(dev, head);
994 }
995}
996EXPORT_SYMBOL_GPL(ip_tunnel_dellink);
997
Nicolas Dichtel1728d4f2015-01-15 15:11:17 +0100998struct net *ip_tunnel_get_link_net(const struct net_device *dev)
999{
1000 struct ip_tunnel *tunnel = netdev_priv(dev);
1001
1002 return tunnel->net;
1003}
1004EXPORT_SYMBOL(ip_tunnel_get_link_net);
1005
Nicolas Dichtel1e995842015-04-02 17:07:02 +02001006int ip_tunnel_get_iflink(const struct net_device *dev)
1007{
1008 struct ip_tunnel *tunnel = netdev_priv(dev);
1009
1010 return tunnel->parms.link;
1011}
1012EXPORT_SYMBOL(ip_tunnel_get_iflink);
1013
Eric Dumazetd3b6f612013-06-07 13:26:05 -07001014int ip_tunnel_init_net(struct net *net, int ip_tnl_net_id,
Pravin B Shelarc5441932013-03-25 14:49:35 +00001015 struct rtnl_link_ops *ops, char *devname)
1016{
1017 struct ip_tunnel_net *itn = net_generic(net, ip_tnl_net_id);
1018 struct ip_tunnel_parm parms;
stephen hemminger6261d982013-08-05 22:51:37 -07001019 unsigned int i;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001020
stephen hemminger6261d982013-08-05 22:51:37 -07001021 for (i = 0; i < IP_TNL_HASH_SIZE; i++)
1022 INIT_HLIST_HEAD(&itn->tunnels[i]);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001023
1024 if (!ops) {
1025 itn->fb_tunnel_dev = NULL;
1026 return 0;
1027 }
stephen hemminger6261d982013-08-05 22:51:37 -07001028
Pravin B Shelarc5441932013-03-25 14:49:35 +00001029 memset(&parms, 0, sizeof(parms));
1030 if (devname)
1031 strlcpy(parms.name, devname, IFNAMSIZ);
1032
1033 rtnl_lock();
1034 itn->fb_tunnel_dev = __ip_tunnel_create(net, ops, &parms);
Dan Carpenterea857f22013-08-19 10:05:10 +03001035 /* FB netdevice is special: we have one, and only one per netns.
1036 * Allowing to move it to another netns is clearly unsafe.
1037 */
Steffen Klassert67013282013-10-01 11:34:48 +02001038 if (!IS_ERR(itn->fb_tunnel_dev)) {
Dan Carpenterb4de77a2013-08-23 11:15:37 +03001039 itn->fb_tunnel_dev->features |= NETIF_F_NETNS_LOCAL;
Steffen Klassert78ff4be2014-05-19 11:36:56 +02001040 itn->fb_tunnel_dev->mtu = ip_tunnel_bind_dev(itn->fb_tunnel_dev);
Steffen Klassert67013282013-10-01 11:34:48 +02001041 ip_tunnel_add(itn, netdev_priv(itn->fb_tunnel_dev));
1042 }
Dan Carpenterb4de77a2013-08-23 11:15:37 +03001043 rtnl_unlock();
Pravin B Shelarc5441932013-03-25 14:49:35 +00001044
Sachin Kamat27d79f32014-01-27 12:13:57 +05301045 return PTR_ERR_OR_ZERO(itn->fb_tunnel_dev);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001046}
1047EXPORT_SYMBOL_GPL(ip_tunnel_init_net);
1048
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001049static void ip_tunnel_destroy(struct ip_tunnel_net *itn, struct list_head *head,
1050 struct rtnl_link_ops *ops)
Pravin B Shelarc5441932013-03-25 14:49:35 +00001051{
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001052 struct net *net = dev_net(itn->fb_tunnel_dev);
1053 struct net_device *dev, *aux;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001054 int h;
1055
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001056 for_each_netdev_safe(net, dev, aux)
1057 if (dev->rtnl_link_ops == ops)
1058 unregister_netdevice_queue(dev, head);
1059
Pravin B Shelarc5441932013-03-25 14:49:35 +00001060 for (h = 0; h < IP_TNL_HASH_SIZE; h++) {
1061 struct ip_tunnel *t;
1062 struct hlist_node *n;
1063 struct hlist_head *thead = &itn->tunnels[h];
1064
1065 hlist_for_each_entry_safe(t, n, thead, hash_node)
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001066 /* If dev is in the same netns, it has already
1067 * been added to the list by the previous loop.
1068 */
1069 if (!net_eq(dev_net(t->dev), net))
1070 unregister_netdevice_queue(t->dev, head);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001071 }
Pravin B Shelarc5441932013-03-25 14:49:35 +00001072}
1073
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001074void ip_tunnel_delete_net(struct ip_tunnel_net *itn, struct rtnl_link_ops *ops)
Pravin B Shelarc5441932013-03-25 14:49:35 +00001075{
1076 LIST_HEAD(list);
1077
1078 rtnl_lock();
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001079 ip_tunnel_destroy(itn, &list, ops);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001080 unregister_netdevice_many(&list);
1081 rtnl_unlock();
Pravin B Shelarc5441932013-03-25 14:49:35 +00001082}
1083EXPORT_SYMBOL_GPL(ip_tunnel_delete_net);
1084
1085int ip_tunnel_newlink(struct net_device *dev, struct nlattr *tb[],
1086 struct ip_tunnel_parm *p)
1087{
1088 struct ip_tunnel *nt;
1089 struct net *net = dev_net(dev);
1090 struct ip_tunnel_net *itn;
1091 int mtu;
1092 int err;
1093
1094 nt = netdev_priv(dev);
1095 itn = net_generic(net, nt->ip_tnl_net_id);
1096
Pravin B Shelar2e15ea32015-08-07 23:51:42 -07001097 if (nt->collect_md) {
1098 if (rtnl_dereference(itn->collect_md_tun))
1099 return -EEXIST;
1100 } else {
1101 if (ip_tunnel_find(itn, p, dev->type))
1102 return -EEXIST;
1103 }
Pravin B Shelarc5441932013-03-25 14:49:35 +00001104
Nicolas Dichtel5e6700b2013-06-26 16:11:28 +02001105 nt->net = net;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001106 nt->parms = *p;
1107 err = register_netdevice(dev);
1108 if (err)
1109 goto out;
1110
1111 if (dev->type == ARPHRD_ETHER && !tb[IFLA_ADDRESS])
1112 eth_hw_addr_random(dev);
1113
1114 mtu = ip_tunnel_bind_dev(dev);
1115 if (!tb[IFLA_MTU])
1116 dev->mtu = mtu;
1117
1118 ip_tunnel_add(itn, nt);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001119out:
1120 return err;
1121}
1122EXPORT_SYMBOL_GPL(ip_tunnel_newlink);
1123
1124int ip_tunnel_changelink(struct net_device *dev, struct nlattr *tb[],
1125 struct ip_tunnel_parm *p)
1126{
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001127 struct ip_tunnel *t;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001128 struct ip_tunnel *tunnel = netdev_priv(dev);
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001129 struct net *net = tunnel->net;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001130 struct ip_tunnel_net *itn = net_generic(net, tunnel->ip_tnl_net_id);
1131
1132 if (dev == itn->fb_tunnel_dev)
1133 return -EINVAL;
1134
Pravin B Shelarc5441932013-03-25 14:49:35 +00001135 t = ip_tunnel_find(itn, p, dev->type);
1136
1137 if (t) {
1138 if (t->dev != dev)
1139 return -EEXIST;
1140 } else {
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001141 t = tunnel;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001142
1143 if (dev->type != ARPHRD_ETHER) {
1144 unsigned int nflags = 0;
1145
1146 if (ipv4_is_multicast(p->iph.daddr))
1147 nflags = IFF_BROADCAST;
1148 else if (p->iph.daddr)
1149 nflags = IFF_POINTOPOINT;
1150
1151 if ((dev->flags ^ nflags) &
1152 (IFF_POINTOPOINT | IFF_BROADCAST))
1153 return -EINVAL;
1154 }
1155 }
1156
1157 ip_tunnel_update(itn, t, dev, p, !tb[IFLA_MTU]);
1158 return 0;
1159}
1160EXPORT_SYMBOL_GPL(ip_tunnel_changelink);
1161
1162int ip_tunnel_init(struct net_device *dev)
1163{
1164 struct ip_tunnel *tunnel = netdev_priv(dev);
1165 struct iphdr *iph = &tunnel->parms.iph;
WANG Cong1c213bd2014-02-13 11:46:28 -08001166 int err;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001167
1168 dev->destructor = ip_tunnel_dev_free;
WANG Cong1c213bd2014-02-13 11:46:28 -08001169 dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001170 if (!dev->tstats)
1171 return -ENOMEM;
1172
Tom Herbert9a4aa9a2014-01-02 11:48:33 -08001173 tunnel->dst_cache = alloc_percpu(struct ip_tunnel_dst);
1174 if (!tunnel->dst_cache) {
1175 free_percpu(dev->tstats);
1176 return -ENOMEM;
1177 }
1178
Pravin B Shelarc5441932013-03-25 14:49:35 +00001179 err = gro_cells_init(&tunnel->gro_cells, dev);
1180 if (err) {
Tom Herbert9a4aa9a2014-01-02 11:48:33 -08001181 free_percpu(tunnel->dst_cache);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001182 free_percpu(dev->tstats);
1183 return err;
1184 }
1185
1186 tunnel->dev = dev;
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001187 tunnel->net = dev_net(dev);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001188 strcpy(tunnel->parms.name, dev->name);
1189 iph->version = 4;
1190 iph->ihl = 5;
1191
Pravin B Shelar2e15ea32015-08-07 23:51:42 -07001192 if (tunnel->collect_md) {
1193 dev->features |= NETIF_F_NETNS_LOCAL;
1194 netif_keep_dst(dev);
1195 }
Pravin B Shelarc5441932013-03-25 14:49:35 +00001196 return 0;
1197}
1198EXPORT_SYMBOL_GPL(ip_tunnel_init);
1199
1200void ip_tunnel_uninit(struct net_device *dev)
1201{
Pravin B Shelarc5441932013-03-25 14:49:35 +00001202 struct ip_tunnel *tunnel = netdev_priv(dev);
Nicolas Dichtel6c742e72013-08-13 17:51:11 +02001203 struct net *net = tunnel->net;
Pravin B Shelarc5441932013-03-25 14:49:35 +00001204 struct ip_tunnel_net *itn;
1205
1206 itn = net_generic(net, tunnel->ip_tnl_net_id);
1207 /* fb_tunnel_dev will be unregisted in net-exit call. */
1208 if (itn->fb_tunnel_dev != dev)
Pravin B Shelar2e15ea32015-08-07 23:51:42 -07001209 ip_tunnel_del(itn, netdev_priv(dev));
Tom Herbert7d442fa2014-01-02 11:48:26 -08001210
Nicolas Dichtelcf71d2bc2014-02-20 10:19:31 +01001211 ip_tunnel_dst_reset_all(tunnel);
Pravin B Shelarc5441932013-03-25 14:49:35 +00001212}
1213EXPORT_SYMBOL_GPL(ip_tunnel_uninit);
1214
1215/* Do least required initialization, rest of init is done in tunnel_init call */
1216void ip_tunnel_setup(struct net_device *dev, int net_id)
1217{
1218 struct ip_tunnel *tunnel = netdev_priv(dev);
1219 tunnel->ip_tnl_net_id = net_id;
1220}
1221EXPORT_SYMBOL_GPL(ip_tunnel_setup);
1222
1223MODULE_LICENSE("GPL");