ip_gre.c 40.4 KB
Newer Older
Linus Torvalds's avatar
Linus Torvalds committed
1
/*
2
 *	Linux NET3:	GRE over IP protocol decoder.
Linus Torvalds's avatar
Linus Torvalds committed
3
4
5
6
7
8
9
10
11
12
 *
 *	Authors: Alexey Kuznetsov (kuznet@ms2.inr.ac.ru)
 *
 *	This program is free software; you can redistribute it and/or
 *	modify it under the terms of the GNU General Public License
 *	as published by the Free Software Foundation; either version
 *	2 of the License, or (at your option) any later version.
 *
 */

13
#include <linux/capability.h>
Linus Torvalds's avatar
Linus Torvalds committed
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <asm/uaccess.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/in.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include <linux/if_arp.h>
#include <linux/mroute.h>
#include <linux/init.h>
#include <linux/in6.h>
#include <linux/inetdevice.h>
#include <linux/igmp.h>
#include <linux/netfilter_ipv4.h>
30
#include <linux/etherdevice.h>
31
#include <linux/if_ether.h>
Linus Torvalds's avatar
Linus Torvalds committed
32
33
34
35
36
37
38
39
40
41
42

#include <net/sock.h>
#include <net/ip.h>
#include <net/icmp.h>
#include <net/protocol.h>
#include <net/ipip.h>
#include <net/arp.h>
#include <net/checksum.h>
#include <net/dsfield.h>
#include <net/inet_ecn.h>
#include <net/xfrm.h>
43
44
#include <net/net_namespace.h>
#include <net/netns/generic.h>
Herbert Xu's avatar
Herbert Xu committed
45
#include <net/rtnetlink.h>
Linus Torvalds's avatar
Linus Torvalds committed
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68

#ifdef CONFIG_IPV6
#include <net/ipv6.h>
#include <net/ip6_fib.h>
#include <net/ip6_route.h>
#endif

/*
   Problems & solutions
   --------------------

   1. The most important issue is detecting local dead loops.
   They would cause complete host lockup in transmit, which
   would be "resolved" by stack overflow or, if queueing is enabled,
   with infinite looping in net_bh.

   We cannot track such dead loops during route installation,
   it is infeasible task. The most general solutions would be
   to keep skb->encapsulation counter (sort of local ttl),
   and silently drop packet when it expires. It is the best
   solution, but it supposes maintaing new variable in ALL
   skb, even if no tunneling is used.

69
   Current solution: t->recursion lock breaks dead loops. It looks
Linus Torvalds's avatar
Linus Torvalds committed
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
   like dev->tbusy flag, but I preferred new variable, because
   the semantics is different. One day, when hard_start_xmit
   will be multithreaded we will have to use skb->encapsulation.



   2. Networking dead loops would not kill routers, but would really
   kill network. IP hop limit plays role of "t->recursion" in this case,
   if we copy it from packet being encapsulated to upper header.
   It is very good solution, but it introduces two problems:

   - Routing protocols, using packets with ttl=1 (OSPF, RIP2),
     do not work over tunnels.
   - traceroute does not work. I planned to relay ICMP from tunnel,
     so that this problem would be solved and traceroute output
     would even more informative. This idea appeared to be wrong:
     only Linux complies to rfc1812 now (yes, guys, Linux is the only
     true router now :-)), all routers (at least, in neighbourhood of mine)
     return only 8 bytes of payload. It is the end.

   Hence, if we want that OSPF worked or traceroute said something reasonable,
   we should search for another solution.

   One of them is to parse packet trying to detect inner encapsulation
   made by our node. It is difficult or even impossible, especially,
   taking into account fragmentation. TO be short, tt is not solution at all.

   Current solution: The solution was UNEXPECTEDLY SIMPLE.
   We force DF flag on tunnels with preconfigured hop limit,
   that is ALL. :-) Well, it does not remove the problem completely,
   but exponential growth of network traffic is changed to linear
   (branches, that exceed pmtu are pruned) and tunnel mtu
   fastly degrades to value <68, where looping stops.
   Yes, it is not good if there exists a router in the loop,
   which does not force DF, even when encapsulating packets have DF set.
   But it is not our problem! Nobody could accuse us, we made
   all that we could make. Even if it is your gated who injected
   fatal route to network, even if it were you who configured
   fatal static route: you are innocent. :-)



   3. Really, ipv4/ipip.c, ipv4/ip_gre.c and ipv6/sit.c contain
   practically identical code. It would be good to glue them
   together, but it is not very evident, how to make them modular.
   sit is integral part of IPv6, ipip and gre are naturally modular.
   We could extract common parts (hash table, ioctl etc)
   to a separate module (ip_tunnel.c).

   Alexey Kuznetsov.
 */

Herbert Xu's avatar
Herbert Xu committed
122
static struct rtnl_link_ops ipgre_link_ops __read_mostly;
Linus Torvalds's avatar
Linus Torvalds committed
123
124
static int ipgre_tunnel_init(struct net_device *dev);
static void ipgre_tunnel_setup(struct net_device *dev);
125
static int ipgre_tunnel_bind_dev(struct net_device *dev);
Linus Torvalds's avatar
Linus Torvalds committed
126
127
128

/* Fallback tunnel: no source, no destination, no key, no options */

129
130
#define HASH_SIZE  16

131
132
static int ipgre_net_id;
struct ipgre_net {
133
134
	struct ip_tunnel *tunnels[4][HASH_SIZE];

135
	struct net_device *fb_tunnel_dev;
136
137
};

Linus Torvalds's avatar
Linus Torvalds committed
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/* Tunnel hash table */

/*
   4 hash tables:

   3: (remote,local)
   2: (remote,*)
   1: (*,local)
   0: (*,*)

   We require exact key match i.e. if a key is present in packet
   it will match only tunnel with the same key; if it is not present,
   it will match only keyless tunnel.

   All keysless packets, if not matched configured keyless tunnels
   will match fallback tunnel.
 */

Al Viro's avatar
Al Viro committed
156
#define HASH(addr) (((__force u32)addr^((__force u32)addr>>4))&0xF)
Linus Torvalds's avatar
Linus Torvalds committed
157

158
159
160
161
#define tunnels_r_l	tunnels[3]
#define tunnels_r	tunnels[2]
#define tunnels_l	tunnels[1]
#define tunnels_wc	tunnels[0]
Linus Torvalds's avatar
Linus Torvalds committed
162
163
164
165
166

static DEFINE_RWLOCK(ipgre_lock);

/* Given src, dst and key, find appropriate for input tunnel. */

167
static struct ip_tunnel * ipgre_tunnel_lookup(struct net_device *dev,
168
169
					      __be32 remote, __be32 local,
					      __be32 key, __be16 gre_proto)
Linus Torvalds's avatar
Linus Torvalds committed
170
{
171
172
	struct net *net = dev_net(dev);
	int link = dev->ifindex;
Linus Torvalds's avatar
Linus Torvalds committed
173
174
	unsigned h0 = HASH(remote);
	unsigned h1 = HASH(key);
175
	struct ip_tunnel *t, *sel[4] = { NULL, NULL, NULL, NULL };
176
	struct ipgre_net *ign = net_generic(net, ipgre_net_id);
177
178
	int dev_type = (gre_proto == htons(ETH_P_TEB)) ?
		       ARPHRD_ETHER : ARPHRD_IPGRE;
179
	int idx;
Linus Torvalds's avatar
Linus Torvalds committed
180

181
	for (t = ign->tunnels_r_l[h0^h1]; t; t = t->next) {
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
		if (local != t->parms.iph.saddr ||
		    remote != t->parms.iph.daddr ||
		    key != t->parms.i_key ||
		    !(t->dev->flags & IFF_UP))
			continue;

		if (t->dev->type != ARPHRD_IPGRE &&
		    t->dev->type != dev_type)
			continue;

		idx = 0;
		if (t->parms.link != link)
			idx |= 1;
		if (t->dev->type != dev_type)
			idx |= 2;
		if (idx == 0)
			return t;
		if (sel[idx] == NULL)
			sel[idx] = t;
Linus Torvalds's avatar
Linus Torvalds committed
201
	}
202

203
	for (t = ign->tunnels_r[h0^h1]; t; t = t->next) {
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
		if (remote != t->parms.iph.daddr ||
		    key != t->parms.i_key ||
		    !(t->dev->flags & IFF_UP))
			continue;

		if (t->dev->type != ARPHRD_IPGRE &&
		    t->dev->type != dev_type)
			continue;

		idx = 0;
		if (t->parms.link != link)
			idx |= 1;
		if (t->dev->type != dev_type)
			idx |= 2;
		if (idx == 0)
			return t;
		if (sel[idx] == NULL)
			sel[idx] = t;
Linus Torvalds's avatar
Linus Torvalds committed
222
	}
223

224
	for (t = ign->tunnels_l[h1]; t; t = t->next) {
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
		if ((local != t->parms.iph.saddr &&
		     (local != t->parms.iph.daddr ||
		      !ipv4_is_multicast(local))) ||
		    key != t->parms.i_key ||
		    !(t->dev->flags & IFF_UP))
			continue;

		if (t->dev->type != ARPHRD_IPGRE &&
		    t->dev->type != dev_type)
			continue;

		idx = 0;
		if (t->parms.link != link)
			idx |= 1;
		if (t->dev->type != dev_type)
			idx |= 2;
		if (idx == 0)
			return t;
		if (sel[idx] == NULL)
			sel[idx] = t;
Linus Torvalds's avatar
Linus Torvalds committed
245
	}
246

247
	for (t = ign->tunnels_wc[h1]; t; t = t->next) {
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
		if (t->parms.i_key != key ||
		    !(t->dev->flags & IFF_UP))
			continue;

		if (t->dev->type != ARPHRD_IPGRE &&
		    t->dev->type != dev_type)
			continue;

		idx = 0;
		if (t->parms.link != link)
			idx |= 1;
		if (t->dev->type != dev_type)
			idx |= 2;
		if (idx == 0)
			return t;
		if (sel[idx] == NULL)
			sel[idx] = t;
Linus Torvalds's avatar
Linus Torvalds committed
265
266
	}

267
268
269
	for (idx = 1; idx < ARRAY_SIZE(sel); idx++)
		if (sel[idx] != NULL)
			return sel[idx];
270

271
	if (ign->fb_tunnel_dev->flags & IFF_UP)
272
		return netdev_priv(ign->fb_tunnel_dev);
273

Linus Torvalds's avatar
Linus Torvalds committed
274
275
276
	return NULL;
}

277
278
static struct ip_tunnel **__ipgre_bucket(struct ipgre_net *ign,
		struct ip_tunnel_parm *parms)
Linus Torvalds's avatar
Linus Torvalds committed
279
{
280
281
282
	__be32 remote = parms->iph.daddr;
	__be32 local = parms->iph.saddr;
	__be32 key = parms->i_key;
Linus Torvalds's avatar
Linus Torvalds committed
283
284
285
286
287
	unsigned h = HASH(key);
	int prio = 0;

	if (local)
		prio |= 1;
288
	if (remote && !ipv4_is_multicast(remote)) {
Linus Torvalds's avatar
Linus Torvalds committed
289
290
291
292
		prio |= 2;
		h ^= HASH(remote);
	}

293
	return &ign->tunnels[prio][h];
Linus Torvalds's avatar
Linus Torvalds committed
294
295
}

296
297
static inline struct ip_tunnel **ipgre_bucket(struct ipgre_net *ign,
		struct ip_tunnel *t)
298
{
299
	return __ipgre_bucket(ign, &t->parms);
300
301
}

302
static void ipgre_tunnel_link(struct ipgre_net *ign, struct ip_tunnel *t)
Linus Torvalds's avatar
Linus Torvalds committed
303
{
304
	struct ip_tunnel **tp = ipgre_bucket(ign, t);
Linus Torvalds's avatar
Linus Torvalds committed
305
306
307
308
309
310
311

	t->next = *tp;
	write_lock_bh(&ipgre_lock);
	*tp = t;
	write_unlock_bh(&ipgre_lock);
}

312
static void ipgre_tunnel_unlink(struct ipgre_net *ign, struct ip_tunnel *t)
Linus Torvalds's avatar
Linus Torvalds committed
313
314
315
{
	struct ip_tunnel **tp;

316
	for (tp = ipgre_bucket(ign, t); *tp; tp = &(*tp)->next) {
Linus Torvalds's avatar
Linus Torvalds committed
317
318
319
320
321
322
323
324
325
		if (t == *tp) {
			write_lock_bh(&ipgre_lock);
			*tp = t->next;
			write_unlock_bh(&ipgre_lock);
			break;
		}
	}
}

326
327
328
static struct ip_tunnel *ipgre_tunnel_find(struct net *net,
					   struct ip_tunnel_parm *parms,
					   int type)
Linus Torvalds's avatar
Linus Torvalds committed
329
{
Al Viro's avatar
Al Viro committed
330
331
332
	__be32 remote = parms->iph.daddr;
	__be32 local = parms->iph.saddr;
	__be32 key = parms->i_key;
333
	int link = parms->link;
334
335
336
337
338
339
340
	struct ip_tunnel *t, **tp;
	struct ipgre_net *ign = net_generic(net, ipgre_net_id);

	for (tp = __ipgre_bucket(ign, parms); (t = *tp) != NULL; tp = &t->next)
		if (local == t->parms.iph.saddr &&
		    remote == t->parms.iph.daddr &&
		    key == t->parms.i_key &&
341
		    link == t->parms.link &&
342
343
344
345
346
347
348
349
350
351
		    type == t->dev->type)
			break;

	return t;
}

static struct ip_tunnel * ipgre_tunnel_locate(struct net *net,
		struct ip_tunnel_parm *parms, int create)
{
	struct ip_tunnel *t, *nt;
Linus Torvalds's avatar
Linus Torvalds committed
352
353
	struct net_device *dev;
	char name[IFNAMSIZ];
354
	struct ipgre_net *ign = net_generic(net, ipgre_net_id);
Linus Torvalds's avatar
Linus Torvalds committed
355

356
357
358
	t = ipgre_tunnel_find(net, parms, ARPHRD_IPGRE);
	if (t || !create)
		return t;
Linus Torvalds's avatar
Linus Torvalds committed
359
360
361

	if (parms->name[0])
		strlcpy(name, parms->name, IFNAMSIZ);
362
363
	else
		sprintf(name, "gre%%d");
Linus Torvalds's avatar
Linus Torvalds committed
364
365
366
367
368

	dev = alloc_netdev(sizeof(*t), name, ipgre_tunnel_setup);
	if (!dev)
	  return NULL;

369
370
	dev_net_set(dev, net);

371
372
373
374
375
	if (strchr(name, '%')) {
		if (dev_alloc_name(dev, name) < 0)
			goto failed_free;
	}

376
	nt = netdev_priv(dev);
Linus Torvalds's avatar
Linus Torvalds committed
377
	nt->parms = *parms;
Herbert Xu's avatar
Herbert Xu committed
378
	dev->rtnl_link_ops = &ipgre_link_ops;
Linus Torvalds's avatar
Linus Torvalds committed
379

380
381
	dev->mtu = ipgre_tunnel_bind_dev(dev);

382
383
	if (register_netdevice(dev) < 0)
		goto failed_free;
Linus Torvalds's avatar
Linus Torvalds committed
384
385

	dev_hold(dev);
386
	ipgre_tunnel_link(ign, nt);
Linus Torvalds's avatar
Linus Torvalds committed
387
388
	return nt;

389
390
failed_free:
	free_netdev(dev);
Linus Torvalds's avatar
Linus Torvalds committed
391
392
393
394
395
	return NULL;
}

static void ipgre_tunnel_uninit(struct net_device *dev)
{
396
397
398
399
	struct net *net = dev_net(dev);
	struct ipgre_net *ign = net_generic(net, ipgre_net_id);

	ipgre_tunnel_unlink(ign, netdev_priv(dev));
Linus Torvalds's avatar
Linus Torvalds committed
400
401
402
403
404
405
406
	dev_put(dev);
}


static void ipgre_err(struct sk_buff *skb, u32 info)
{

407
/* All the routers (except for Linux) return only
Linus Torvalds's avatar
Linus Torvalds committed
408
409
410
411
412
413
414
415
416
417
418
419
   8 bytes of packet payload. It means, that precise relaying of
   ICMP in the real Internet is absolutely infeasible.

   Moreover, Cisco "wise men" put GRE key to the third word
   in GRE header. It makes impossible maintaining even soft state for keyed
   GRE tunnels with enabled checksum. Tell them "thank you".

   Well, I wonder, rfc1812 was written by Cisco employee,
   what the hell these idiots break standrads established
   by themself???
 */

420
	struct iphdr *iph = (struct iphdr *)skb->data;
Al Viro's avatar
Al Viro committed
421
	__be16	     *p = (__be16*)(skb->data+(iph->ihl<<2));
Linus Torvalds's avatar
Linus Torvalds committed
422
	int grehlen = (iph->ihl<<2) + 4;
423
424
	const int type = icmp_hdr(skb)->type;
	const int code = icmp_hdr(skb)->code;
Linus Torvalds's avatar
Linus Torvalds committed
425
	struct ip_tunnel *t;
Al Viro's avatar
Al Viro committed
426
	__be16 flags;
Linus Torvalds's avatar
Linus Torvalds committed
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471

	flags = p[0];
	if (flags&(GRE_CSUM|GRE_KEY|GRE_SEQ|GRE_ROUTING|GRE_VERSION)) {
		if (flags&(GRE_VERSION|GRE_ROUTING))
			return;
		if (flags&GRE_KEY) {
			grehlen += 4;
			if (flags&GRE_CSUM)
				grehlen += 4;
		}
	}

	/* If only 8 bytes returned, keyed message will be dropped here */
	if (skb_headlen(skb) < grehlen)
		return;

	switch (type) {
	default:
	case ICMP_PARAMETERPROB:
		return;

	case ICMP_DEST_UNREACH:
		switch (code) {
		case ICMP_SR_FAILED:
		case ICMP_PORT_UNREACH:
			/* Impossible event. */
			return;
		case ICMP_FRAG_NEEDED:
			/* Soft state for pmtu is maintained by IP core. */
			return;
		default:
			/* All others are translated to HOST_UNREACH.
			   rfc2003 contains "deep thoughts" about NET_UNREACH,
			   I believe they are just ether pollution. --ANK
			 */
			break;
		}
		break;
	case ICMP_TIME_EXCEEDED:
		if (code != ICMP_EXC_TTL)
			return;
		break;
	}

	read_lock(&ipgre_lock);
472
	t = ipgre_tunnel_lookup(skb->dev, iph->daddr, iph->saddr,
473
474
475
				flags & GRE_KEY ?
				*(((__be32 *)p) + (grehlen / 4) - 1) : 0,
				p[1]);
476
477
	if (t == NULL || t->parms.iph.daddr == 0 ||
	    ipv4_is_multicast(t->parms.iph.daddr))
Linus Torvalds's avatar
Linus Torvalds committed
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
		goto out;

	if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED)
		goto out;

	if (jiffies - t->err_time < IPTUNNEL_ERR_TIMEO)
		t->err_count++;
	else
		t->err_count = 1;
	t->err_time = jiffies;
out:
	read_unlock(&ipgre_lock);
	return;
}

static inline void ipgre_ecn_decapsulate(struct iphdr *iph, struct sk_buff *skb)
{
	if (INET_ECN_is_ce(iph->tos)) {
		if (skb->protocol == htons(ETH_P_IP)) {
497
			IP_ECN_set_ce(ip_hdr(skb));
Linus Torvalds's avatar
Linus Torvalds committed
498
		} else if (skb->protocol == htons(ETH_P_IPV6)) {
499
			IP6_ECN_set_ce(ipv6_hdr(skb));
Linus Torvalds's avatar
Linus Torvalds committed
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
		}
	}
}

static inline u8
ipgre_ecn_encapsulate(u8 tos, struct iphdr *old_iph, struct sk_buff *skb)
{
	u8 inner = 0;
	if (skb->protocol == htons(ETH_P_IP))
		inner = old_iph->tos;
	else if (skb->protocol == htons(ETH_P_IPV6))
		inner = ipv6_get_dsfield((struct ipv6hdr *)old_iph);
	return INET_ECN_encapsulate(tos, inner);
}

static int ipgre_rcv(struct sk_buff *skb)
{
	struct iphdr *iph;
	u8     *h;
Al Viro's avatar
Al Viro committed
519
	__be16    flags;
520
	__sum16   csum = 0;
Al Viro's avatar
Al Viro committed
521
	__be32 key = 0;
Linus Torvalds's avatar
Linus Torvalds committed
522
523
524
	u32    seqno = 0;
	struct ip_tunnel *tunnel;
	int    offset = 4;
525
	__be16 gre_proto;
526
	unsigned int len;
Linus Torvalds's avatar
Linus Torvalds committed
527
528
529
530

	if (!pskb_may_pull(skb, 16))
		goto drop_nolock;

531
	iph = ip_hdr(skb);
Linus Torvalds's avatar
Linus Torvalds committed
532
	h = skb->data;
Al Viro's avatar
Al Viro committed
533
	flags = *(__be16*)h;
Linus Torvalds's avatar
Linus Torvalds committed
534
535
536
537
538
539
540
541
542

	if (flags&(GRE_CSUM|GRE_KEY|GRE_ROUTING|GRE_SEQ|GRE_VERSION)) {
		/* - Version must be 0.
		   - We do not support routing headers.
		 */
		if (flags&(GRE_VERSION|GRE_ROUTING))
			goto drop_nolock;

		if (flags&GRE_CSUM) {
543
			switch (skb->ip_summed) {
544
			case CHECKSUM_COMPLETE:
545
				csum = csum_fold(skb->csum);
546
547
548
549
550
551
				if (!csum)
					break;
				/* fall through */
			case CHECKSUM_NONE:
				skb->csum = 0;
				csum = __skb_checksum_complete(skb);
552
				skb->ip_summed = CHECKSUM_COMPLETE;
Linus Torvalds's avatar
Linus Torvalds committed
553
554
555
556
			}
			offset += 4;
		}
		if (flags&GRE_KEY) {
Al Viro's avatar
Al Viro committed
557
			key = *(__be32*)(h + offset);
Linus Torvalds's avatar
Linus Torvalds committed
558
559
560
			offset += 4;
		}
		if (flags&GRE_SEQ) {
Al Viro's avatar
Al Viro committed
561
			seqno = ntohl(*(__be32*)(h + offset));
Linus Torvalds's avatar
Linus Torvalds committed
562
563
564
565
			offset += 4;
		}
	}

566
567
	gre_proto = *(__be16 *)(h + 2);

Linus Torvalds's avatar
Linus Torvalds committed
568
	read_lock(&ipgre_lock);
569
	if ((tunnel = ipgre_tunnel_lookup(skb->dev,
570
571
					  iph->saddr, iph->daddr, key,
					  gre_proto))) {
572
573
		struct net_device_stats *stats = &tunnel->dev->stats;

Linus Torvalds's avatar
Linus Torvalds committed
574
575
		secpath_reset(skb);

576
		skb->protocol = gre_proto;
Linus Torvalds's avatar
Linus Torvalds committed
577
578
579
580
		/* WCCP version 1 and 2 protocol decoding.
		 * - Change protocol to IP
		 * - When dealing with WCCPv2, Skip extra 4 bytes in GRE header
		 */
581
		if (flags == 0 && gre_proto == htons(ETH_P_WCCP)) {
582
			skb->protocol = htons(ETH_P_IP);
583
			if ((*(h + offset) & 0xF0) != 0x40)
Linus Torvalds's avatar
Linus Torvalds committed
584
585
586
				offset += 4;
		}

587
		skb->mac_header = skb->network_header;
588
		__pskb_pull(skb, offset);
589
		skb_postpull_rcsum(skb, skb_transport_header(skb), offset);
Linus Torvalds's avatar
Linus Torvalds committed
590
591
		skb->pkt_type = PACKET_HOST;
#ifdef CONFIG_NET_IPGRE_BROADCAST
592
		if (ipv4_is_multicast(iph->daddr)) {
Linus Torvalds's avatar
Linus Torvalds committed
593
			/* Looped back packet, drop it! */
594
			if (skb->rtable->fl.iif == 0)
Linus Torvalds's avatar
Linus Torvalds committed
595
				goto drop;
596
			stats->multicast++;
Linus Torvalds's avatar
Linus Torvalds committed
597
598
599
600
601
602
			skb->pkt_type = PACKET_BROADCAST;
		}
#endif

		if (((flags&GRE_CSUM) && csum) ||
		    (!(flags&GRE_CSUM) && tunnel->parms.i_flags&GRE_CSUM)) {
603
604
			stats->rx_crc_errors++;
			stats->rx_errors++;
Linus Torvalds's avatar
Linus Torvalds committed
605
606
607
608
609
			goto drop;
		}
		if (tunnel->parms.i_flags&GRE_SEQ) {
			if (!(flags&GRE_SEQ) ||
			    (tunnel->i_seqno && (s32)(seqno - tunnel->i_seqno) < 0)) {
610
611
				stats->rx_fifo_errors++;
				stats->rx_errors++;
Linus Torvalds's avatar
Linus Torvalds committed
612
613
614
615
				goto drop;
			}
			tunnel->i_seqno = seqno + 1;
		}
616

617
618
		len = skb->len;

619
620
621
622
623
624
625
626
627
628
629
630
631
		/* Warning: All skb pointers will be invalidated! */
		if (tunnel->dev->type == ARPHRD_ETHER) {
			if (!pskb_may_pull(skb, ETH_HLEN)) {
				stats->rx_length_errors++;
				stats->rx_errors++;
				goto drop;
			}

			iph = ip_hdr(skb);
			skb->protocol = eth_type_trans(skb, tunnel->dev);
			skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
		}

632
		stats->rx_packets++;
633
		stats->rx_bytes += len;
Linus Torvalds's avatar
Linus Torvalds committed
634
635
636
637
		skb->dev = tunnel->dev;
		dst_release(skb->dst);
		skb->dst = NULL;
		nf_reset(skb);
638
639

		skb_reset_network_header(skb);
Linus Torvalds's avatar
Linus Torvalds committed
640
		ipgre_ecn_decapsulate(iph, skb);
641

Linus Torvalds's avatar
Linus Torvalds committed
642
643
644
645
		netif_rx(skb);
		read_unlock(&ipgre_lock);
		return(0);
	}
646
	icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
Linus Torvalds's avatar
Linus Torvalds committed
647
648
649
650
651
652
653
654
655
656

drop:
	read_unlock(&ipgre_lock);
drop_nolock:
	kfree_skb(skb);
	return(0);
}

static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
{
657
	struct ip_tunnel *tunnel = netdev_priv(dev);
658
	struct net_device_stats *stats = &tunnel->dev->stats;
659
	struct iphdr  *old_iph = ip_hdr(skb);
Linus Torvalds's avatar
Linus Torvalds committed
660
661
	struct iphdr  *tiph;
	u8     tos;
Al Viro's avatar
Al Viro committed
662
	__be16 df;
Linus Torvalds's avatar
Linus Torvalds committed
663
664
665
	struct rtable *rt;     			/* Route to the other host */
	struct net_device *tdev;			/* Device to other host */
	struct iphdr  *iph;			/* Our new IP header */
666
	unsigned int max_headroom;		/* The extra header space needed */
Linus Torvalds's avatar
Linus Torvalds committed
667
	int    gre_hlen;
Al Viro's avatar
Al Viro committed
668
	__be32 dst;
Linus Torvalds's avatar
Linus Torvalds committed
669
670
671
	int    mtu;

	if (tunnel->recursion++) {
672
		stats->collisions++;
Linus Torvalds's avatar
Linus Torvalds committed
673
674
675
		goto tx_error;
	}

676
677
678
679
	if (dev->type == ARPHRD_ETHER)
		IPCB(skb)->flags = 0;

	if (dev->header_ops && dev->type == ARPHRD_IPGRE) {
Linus Torvalds's avatar
Linus Torvalds committed
680
		gre_hlen = 0;
681
		tiph = (struct iphdr *)skb->data;
Linus Torvalds's avatar
Linus Torvalds committed
682
683
684
685
686
687
688
689
690
	} else {
		gre_hlen = tunnel->hlen;
		tiph = &tunnel->parms.iph;
	}

	if ((dst = tiph->daddr) == 0) {
		/* NBMA tunnel */

		if (skb->dst == NULL) {
691
			stats->tx_fifo_errors++;
Linus Torvalds's avatar
Linus Torvalds committed
692
693
694
695
			goto tx_error;
		}

		if (skb->protocol == htons(ETH_P_IP)) {
696
			rt = skb->rtable;
Linus Torvalds's avatar
Linus Torvalds committed
697
698
699
700
701
702
703
704
705
706
707
708
			if ((dst = rt->rt_gateway) == 0)
				goto tx_error_icmp;
		}
#ifdef CONFIG_IPV6
		else if (skb->protocol == htons(ETH_P_IPV6)) {
			struct in6_addr *addr6;
			int addr_type;
			struct neighbour *neigh = skb->dst->neighbour;

			if (neigh == NULL)
				goto tx_error;

709
			addr6 = (struct in6_addr *)&neigh->primary_key;
Linus Torvalds's avatar
Linus Torvalds committed
710
711
712
			addr_type = ipv6_addr_type(addr6);

			if (addr_type == IPV6_ADDR_ANY) {
713
				addr6 = &ipv6_hdr(skb)->daddr;
Linus Torvalds's avatar
Linus Torvalds committed
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
				addr_type = ipv6_addr_type(addr6);
			}

			if ((addr_type & IPV6_ADDR_COMPATv4) == 0)
				goto tx_error_icmp;

			dst = addr6->s6_addr32[3];
		}
#endif
		else
			goto tx_error;
	}

	tos = tiph->tos;
	if (tos&1) {
		if (skb->protocol == htons(ETH_P_IP))
			tos = old_iph->tos;
		tos &= ~1;
	}

	{
		struct flowi fl = { .oif = tunnel->parms.link,
				    .nl_u = { .ip4_u =
					      { .daddr = dst,
						.saddr = tiph->saddr,
						.tos = RT_TOS(tos) } },
				    .proto = IPPROTO_GRE };
741
		if (ip_route_output_key(dev_net(dev), &rt, &fl)) {
742
			stats->tx_carrier_errors++;
Linus Torvalds's avatar
Linus Torvalds committed
743
744
745
746
747
748
749
			goto tx_error;
		}
	}
	tdev = rt->u.dst.dev;

	if (tdev == dev) {
		ip_rt_put(rt);
750
		stats->collisions++;
Linus Torvalds's avatar
Linus Torvalds committed
751
752
753
754
755
		goto tx_error;
	}

	df = tiph->frag_off;
	if (df)
Herbert Xu's avatar
Herbert Xu committed
756
		mtu = dst_mtu(&rt->u.dst) - dev->hard_header_len - tunnel->hlen;
Linus Torvalds's avatar
Linus Torvalds committed
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
	else
		mtu = skb->dst ? dst_mtu(skb->dst) : dev->mtu;

	if (skb->dst)
		skb->dst->ops->update_pmtu(skb->dst, mtu);

	if (skb->protocol == htons(ETH_P_IP)) {
		df |= (old_iph->frag_off&htons(IP_DF));

		if ((old_iph->frag_off&htons(IP_DF)) &&
		    mtu < ntohs(old_iph->tot_len)) {
			icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));
			ip_rt_put(rt);
			goto tx_error;
		}
	}
#ifdef CONFIG_IPV6
	else if (skb->protocol == htons(ETH_P_IPV6)) {
775
		struct rt6_info *rt6 = (struct rt6_info *)skb->dst;
Linus Torvalds's avatar
Linus Torvalds committed
776
777

		if (rt6 && mtu < dst_mtu(skb->dst) && mtu >= IPV6_MIN_MTU) {
778
779
			if ((tunnel->parms.iph.daddr &&
			     !ipv4_is_multicast(tunnel->parms.iph.daddr)) ||
Linus Torvalds's avatar
Linus Torvalds committed
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
			    rt6->rt6i_dst.plen == 128) {
				rt6->rt6i_flags |= RTF_MODIFIED;
				skb->dst->metrics[RTAX_MTU-1] = mtu;
			}
		}

		if (mtu >= IPV6_MIN_MTU && mtu < skb->len - tunnel->hlen + gre_hlen) {
			icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, dev);
			ip_rt_put(rt);
			goto tx_error;
		}
	}
#endif

	if (tunnel->err_count > 0) {
		if (jiffies - tunnel->err_time < IPTUNNEL_ERR_TIMEO) {
			tunnel->err_count--;

			dst_link_failure(skb);
		} else
			tunnel->err_count = 0;
	}

	max_headroom = LL_RESERVED_SPACE(tdev) + gre_hlen;

805
806
	if (skb_headroom(skb) < max_headroom || skb_shared(skb)||
	    (skb_cloned(skb) && !skb_clone_writable(skb, 0))) {
Linus Torvalds's avatar
Linus Torvalds committed
807
808
809
		struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
		if (!new_skb) {
			ip_rt_put(rt);
810
			stats->tx_dropped++;
Linus Torvalds's avatar
Linus Torvalds committed
811
812
813
814
815
816
817
818
			dev_kfree_skb(skb);
			tunnel->recursion--;
			return 0;
		}
		if (skb->sk)
			skb_set_owner_w(new_skb, skb->sk);
		dev_kfree_skb(skb);
		skb = new_skb;
819
		old_iph = ip_hdr(skb);
Linus Torvalds's avatar
Linus Torvalds committed
820
821
	}

822
	skb_reset_transport_header(skb);
823
824
	skb_push(skb, gre_hlen);
	skb_reset_network_header(skb);
Linus Torvalds's avatar
Linus Torvalds committed
825
	memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
826
827
	IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED |
			      IPSKB_REROUTED);
Linus Torvalds's avatar
Linus Torvalds committed
828
829
830
831
832
833
834
	dst_release(skb->dst);
	skb->dst = &rt->u.dst;

	/*
	 *	Push down and install the IPIP header.
	 */

835
	iph 			=	ip_hdr(skb);
Linus Torvalds's avatar
Linus Torvalds committed
836
837
838
839
840
841
842
843
844
845
846
847
848
	iph->version		=	4;
	iph->ihl		=	sizeof(struct iphdr) >> 2;
	iph->frag_off		=	df;
	iph->protocol		=	IPPROTO_GRE;
	iph->tos		=	ipgre_ecn_encapsulate(tos, old_iph, skb);
	iph->daddr		=	rt->rt_dst;
	iph->saddr		=	rt->rt_src;

	if ((iph->ttl = tiph->ttl) == 0) {
		if (skb->protocol == htons(ETH_P_IP))
			iph->ttl = old_iph->ttl;
#ifdef CONFIG_IPV6
		else if (skb->protocol == htons(ETH_P_IPV6))
849
			iph->ttl = ((struct ipv6hdr *)old_iph)->hop_limit;
Linus Torvalds's avatar
Linus Torvalds committed
850
851
852
853
854
#endif
		else
			iph->ttl = dst_metric(&rt->u.dst, RTAX_HOPLIMIT);
	}

855
856
857
	((__be16 *)(iph + 1))[0] = tunnel->parms.o_flags;
	((__be16 *)(iph + 1))[1] = (dev->type == ARPHRD_ETHER) ?
				   htons(ETH_P_TEB) : skb->protocol;
Linus Torvalds's avatar
Linus Torvalds committed
858
859

	if (tunnel->parms.o_flags&(GRE_KEY|GRE_CSUM|GRE_SEQ)) {
Al Viro's avatar
Al Viro committed
860
		__be32 *ptr = (__be32*)(((u8*)iph) + tunnel->hlen - 4);
Linus Torvalds's avatar
Linus Torvalds committed
861
862
863
864
865
866
867
868
869
870
871
872

		if (tunnel->parms.o_flags&GRE_SEQ) {
			++tunnel->o_seqno;
			*ptr = htonl(tunnel->o_seqno);
			ptr--;
		}
		if (tunnel->parms.o_flags&GRE_KEY) {
			*ptr = tunnel->parms.o_key;
			ptr--;
		}
		if (tunnel->parms.o_flags&GRE_CSUM) {
			*ptr = 0;
873
			*(__sum16*)ptr = ip_compute_csum((void*)(iph+1), skb->len - sizeof(struct iphdr));
Linus Torvalds's avatar
Linus Torvalds committed
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
		}
	}

	nf_reset(skb);

	IPTUNNEL_XMIT();
	tunnel->recursion--;
	return 0;

tx_error_icmp:
	dst_link_failure(skb);

tx_error:
	stats->tx_errors++;
	dev_kfree_skb(skb);
	tunnel->recursion--;
	return 0;
}

893
static int ipgre_tunnel_bind_dev(struct net_device *dev)
894
895
896
897
898
899
900
901
902
903
904
{
	struct net_device *tdev = NULL;
	struct ip_tunnel *tunnel;
	struct iphdr *iph;
	int hlen = LL_MAX_HEADER;
	int mtu = ETH_DATA_LEN;
	int addend = sizeof(struct iphdr) + 4;

	tunnel = netdev_priv(dev);
	iph = &tunnel->parms.iph;

Herbert Xu's avatar
Herbert Xu committed
905
	/* Guess output device to choose reasonable mtu and needed_headroom */
906
907
908
909
910
911
912
913
914

	if (iph->daddr) {
		struct flowi fl = { .oif = tunnel->parms.link,
				    .nl_u = { .ip4_u =
					      { .daddr = iph->daddr,
						.saddr = iph->saddr,
						.tos = RT_TOS(iph->tos) } },
				    .proto = IPPROTO_GRE };
		struct rtable *rt;
915
		if (!ip_route_output_key(dev_net(dev), &rt, &fl)) {
916
917
918
			tdev = rt->u.dst.dev;
			ip_rt_put(rt);
		}
919
920
921

		if (dev->type != ARPHRD_ETHER)
			dev->flags |= IFF_POINTOPOINT;
922
923
924
	}

	if (!tdev && tunnel->parms.link)
925
		tdev = __dev_get_by_index(dev_net(dev), tunnel->parms.link);
926
927

	if (tdev) {
Herbert Xu's avatar
Herbert Xu committed
928
		hlen = tdev->hard_header_len + tdev->needed_headroom;
929
930
931
932
933
934
935
936
937
938
939
940
941
		mtu = tdev->mtu;
	}
	dev->iflink = tunnel->parms.link;

	/* Precalculate GRE options length */
	if (tunnel->parms.o_flags&(GRE_CSUM|GRE_KEY|GRE_SEQ)) {
		if (tunnel->parms.o_flags&GRE_CSUM)
			addend += 4;
		if (tunnel->parms.o_flags&GRE_KEY)
			addend += 4;
		if (tunnel->parms.o_flags&GRE_SEQ)
			addend += 4;
	}
Herbert Xu's avatar
Herbert Xu committed
942
	dev->needed_headroom = addend + hlen;
943
944
945
946
947
	mtu -= dev->hard_header_len - addend;

	if (mtu < 68)
		mtu = 68;

948
949
	tunnel->hlen = addend;

950
	return mtu;
951
952
}

Linus Torvalds's avatar
Linus Torvalds committed
953
954
955
956
957
958
static int
ipgre_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
{
	int err = 0;
	struct ip_tunnel_parm p;
	struct ip_tunnel *t;
959
960
	struct net *net = dev_net(dev);
	struct ipgre_net *ign = net_generic(net, ipgre_net_id);
Linus Torvalds's avatar
Linus Torvalds committed
961
962
963
964

	switch (cmd) {
	case SIOCGETTUNNEL:
		t = NULL;
965
		if (dev == ign->fb_tunnel_dev) {
Linus Torvalds's avatar
Linus Torvalds committed
966
967
968
969
			if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) {
				err = -EFAULT;
				break;
			}
970
			t = ipgre_tunnel_locate(net, &p, 0);
Linus Torvalds's avatar
Linus Torvalds committed
971
972
		}
		if (t == NULL)
973
			t = netdev_priv(dev);
Linus Torvalds's avatar
Linus Torvalds committed
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
		memcpy(&p, &t->parms, sizeof(p));
		if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p)))
			err = -EFAULT;
		break;

	case SIOCADDTUNNEL:
	case SIOCCHGTUNNEL:
		err = -EPERM;
		if (!capable(CAP_NET_ADMIN))
			goto done;

		err = -EFAULT;
		if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p)))
			goto done;

		err = -EINVAL;
		if (p.iph.version != 4 || p.iph.protocol != IPPROTO_GRE ||
		    p.iph.ihl != 5 || (p.iph.frag_off&htons(~IP_DF)) ||
		    ((p.i_flags|p.o_flags)&(GRE_VERSION|GRE_ROUTING)))
			goto done;
		if (p.iph.ttl)
			p.iph.frag_off |= htons(IP_DF);

		if (!(p.i_flags&GRE_KEY))
			p.i_key = 0;
		if (!(p.o_flags&GRE_KEY))
			p.o_key = 0;