Fix build.
[linux-2.6.git] / linux-2.6-700-egre.patch
1 diff -Nurb linux-2.6.27-660/Makefile linux-2.6.27-700/Makefile
2 --- linux-2.6.27-660/Makefile   2009-04-10 18:27:45.000000000 -0400
3 +++ linux-2.6.27-700/Makefile   2009-04-10 18:28:43.000000000 -0400
4 @@ -1,7 +1,7 @@
5  VERSION = 2
6  PATCHLEVEL = 6
7  SUBLEVEL = 27
8 -EXTRAVERSION = .14-vs2.3.0.36.4
9 +EXTRAVERSION = -prep
10  NAME = Trembling Tortoise
11  
12  # *DOCUMENTATION*
13 diff -Nurb linux-2.6.27-660/drivers/net/Kconfig linux-2.6.27-700/drivers/net/Kconfig
14 --- linux-2.6.27-660/drivers/net/Kconfig        2009-04-10 18:27:44.000000000 -0400
15 +++ linux-2.6.27-700/drivers/net/Kconfig        2009-04-10 18:32:52.000000000 -0400
16 @@ -39,6 +39,9 @@
17           'ifb1' etc.
18           Look at the iproute2 documentation directory for usage etc
19  
20 +config EGRE
21 +       tristate "EGRE module for Ethernet over GRE Tunnels"
22 +      
23  config DUMMY
24         tristate "Dummy net driver support"
25         ---help---
26 diff -Nurb linux-2.6.27-660/drivers/net/Makefile linux-2.6.27-700/drivers/net/Makefile
27 --- linux-2.6.27-660/drivers/net/Makefile       2008-10-09 18:13:53.000000000 -0400
28 +++ linux-2.6.27-700/drivers/net/Makefile       2009-04-10 18:28:43.000000000 -0400
29 @@ -2,6 +2,7 @@
30  # Makefile for the Linux network (ethercard) device drivers.
31  #
32  
33 +obj-$(CONFIG_EGRE) += gre.o
34  obj-$(CONFIG_E1000) += e1000/
35  obj-$(CONFIG_E1000E) += e1000e/
36  obj-$(CONFIG_IBM_NEW_EMAC) += ibm_newemac/
37 diff -Nurb linux-2.6.27-660/drivers/net/gre.c linux-2.6.27-700/drivers/net/gre.c
38 --- linux-2.6.27-660/drivers/net/gre.c  1969-12-31 19:00:00.000000000 -0500
39 +++ linux-2.6.27-700/drivers/net/gre.c  2009-04-10 18:28:43.000000000 -0400
40 @@ -0,0 +1,1632 @@
41 +/*
42 + *     Linux NET3:     GRE over IP protocol decoder.
43 + *
44 + *     Authors: Alexey Kuznetsov (kuznet@ms2.inr.ac.ru)
45 + *
46 + *     This program is free software; you can redistribute it and/or
47 + *     modify it under the terms of the GNU General Public License
48 + *     as published by the Free Software Foundation; either version
49 + *     2 of the License, or (at your option) any later version.
50 + *
51 + */
52 +
53 +#include <linux/capability.h>
54 +#include <linux/module.h>
55 +#include <linux/types.h>
56 +#include <linux/sched.h>
57 +#include <linux/kernel.h>
58 +#include <asm/uaccess.h>
59 +#include <linux/skbuff.h>
60 +#include <linux/netdevice.h>
61 +#include <linux/in.h>
62 +#include <linux/tcp.h>
63 +#include <linux/udp.h>
64 +#include <linux/if_arp.h>
65 +#include <linux/mroute.h>
66 +#include <linux/init.h>
67 +#include <linux/in6.h>
68 +#include <linux/inetdevice.h>
69 +#include <linux/etherdevice.h>   /**XXX added XXX */
70 +#include <linux/igmp.h>
71 +#include <linux/netfilter_ipv4.h>
72 +#include <linux/if_ether.h>
73 +
74 +#include <net/sock.h>
75 +#include <net/ip.h>
76 +#include <net/icmp.h>
77 +#include <net/protocol.h>
78 +#include <net/ipip.h>
79 +#include <net/arp.h>
80 +#include <net/checksum.h>
81 +#include <net/dsfield.h>
82 +#include <net/inet_ecn.h>
83 +#include <net/xfrm.h>
84 +
85 +#ifdef CONFIG_IPV6
86 +#include <net/ipv6.h>
87 +#include <net/ip6_fib.h>
88 +#include <net/ip6_route.h>
89 +#endif
90 +
91 +//#define GRE_DEBUG 1
92 +
93 +/*
94 +   Problems & solutions
95 +   --------------------
96 +
97 +   1. The most important issue is detecting local dead loops.
98 +   They would cause complete host lockup in transmit, which
99 +   would be "resolved" by stack overflow or, if queueing is enabled,
100 +   with infinite looping in net_bh.
101 +
102 +   We cannot track such dead loops during route installation,
103 +   it is infeasible task. The most general solutions would be
104 +   to keep skb->encapsulation counter (sort of local ttl),
105 +   and silently drop packet when it expires. It is the best
106 +   solution, but it supposes maintaing new variable in ALL
107 +   skb, even if no tunneling is used.
108 +
109 +   Current solution: t->recursion lock breaks dead loops. It looks
110 +   like dev->tbusy flag, but I preferred new variable, because
111 +   the semantics is different. One day, when hard_start_xmit
112 +   will be multithreaded we will have to use skb->encapsulation.
113 +
114 +
115 +
116 +   2. Networking dead loops would not kill routers, but would really
117 +   kill network. IP hop limit plays role of "t->recursion" in this case,
118 +   if we copy it from packet being encapsulated to upper header.
119 +   It is very good solution, but it introduces two problems:
120 +
121 +   - Routing protocols, using packets with ttl=1 (OSPF, RIP2),
122 +     do not work over tunnels.
123 +   - traceroute does not work. I planned to relay ICMP from tunnel,
124 +     so that this problem would be solved and traceroute output
125 +     would even more informative. This idea appeared to be wrong:
126 +     only Linux complies to rfc1812 now (yes, guys, Linux is the only
127 +     true router now :-)), all routers (at least, in neighbourhood of mine)
128 +     return only 8 bytes of payload. It is the end.
129 +
130 +   Hence, if we want that OSPF worked or traceroute said something reasonable,
131 +   we should search for another solution.
132 +
133 +   One of them is to parse packet trying to detect inner encapsulation
134 +   made by our node. It is difficult or even impossible, especially,
135 +   taking into account fragmentation. TO be short, tt is not solution at all.
136 +
137 +   Current solution: The solution was UNEXPECTEDLY SIMPLE.
138 +   We force DF flag on tunnels with preconfigured hop limit,
139 +   that is ALL. :-) Well, it does not remove the problem completely,
140 +   but exponential growth of network traffic is changed to linear
141 +   (branches, that exceed pmtu are pruned) and tunnel mtu
142 +   fastly degrades to value <68, where looping stops.
143 +   Yes, it is not good if there exists a router in the loop,
144 +   which does not force DF, even when encapsulating packets have DF set.
145 +   But it is not our problem! Nobody could accuse us, we made
146 +   all that we could make. Even if it is your gated who injected
147 +   fatal route to network, even if it were you who configured
148 +   fatal static route: you are innocent. :-)
149 +
150 +
151 +
152 +   3. Really, ipv4/ipip.c, ipv4/ip_gre.c and ipv6/sit.c contain
153 +   practically identical code. It would be good to glue them
154 +   together, but it is not very evident, how to make them modular.
155 +   sit is integral part of IPv6, ipip and gre are naturally modular.
156 +   We could extract common parts (hash table, ioctl etc)
157 +   to a separate module (ip_tunnel.c).
158 +
159 +   Alexey Kuznetsov.
160 + */
161 +
162 +static int ipgre_tunnel_init(struct net_device *dev);
163 +static void ipgre_ip_tunnel_setup(struct net_device *dev);
164 +static void ipgre_eth_tunnel_setup(struct net_device *dev);
165 +
166 +/* Fallback tunnel: no source, no destination, no key, no options */
167 +
168 +static int ipgre_fb_tunnel_init(struct net_device *dev);
169 +
170 +static struct net_device *ipgre_fb_tunnel_dev;
171 +
172 +/* Tunnel hash table */
173 +
174 +/*
175 +   4 hash tables:
176 +
177 +   3: (remote,local)
178 +   2: (remote,*)
179 +   1: (*,local)
180 +   0: (*,*)
181 +
182 +   We require exact key match i.e. if a key is present in packet
183 +   it will match only tunnel with the same key; if it is not present,
184 +   it will match only keyless tunnel.
185 +
186 +   All keysless packets, if not matched configured keyless tunnels
187 +   will match fallback tunnel.
188 + */
189 +
190 +#define HASH_SIZE  1024
191 +#define HASH(addr) (ntohl(addr)&1023)
192 +
193 +static struct ip_tunnel *tunnels[4][HASH_SIZE];
194 +
195 +#define tunnels_r_l    (tunnels[3])
196 +#define tunnels_r      (tunnels[2])
197 +#define tunnels_l      (tunnels[1])
198 +#define tunnels_wc     (tunnels[0])
199 +
200 +static DEFINE_RWLOCK(ipgre_lock);
201 +
202 +/* Given src, dst and key, find appropriate for input tunnel. */
203 +
204 +static struct ip_tunnel * ipgre_tunnel_lookup(__be32 remote, __be32 local, __be32 key)
205 +{
206 +       /* HACK */
207 +       unsigned hash_value = HASH(key);
208 +       struct ip_tunnel *t;
209 +
210 +       t = tunnels_r_l[hash_value];
211 +
212 +       if (t && (t->parms.i_key == key) && (t->dev->flags&IFF_UP)) {
213 +               return t;
214 +       }
215 +
216 +       t = tunnels_r[hash_value];
217 +                       if (t && (t->parms.i_key == key) && (t->dev->flags&IFF_UP))
218 +                               return t;
219 +
220 +       t = tunnels_l[hash_value];
221 +                       if (t && (t->parms.i_key == key) && (t->dev->flags&IFF_UP))
222 +                               return t;
223 +       t = tunnels_wc[hash_value];
224 +               if (t && (t->parms.i_key == key) && (t->dev->flags&IFF_UP))
225 +                       return t;
226 +       if (ipgre_fb_tunnel_dev->flags&IFF_UP)
227 +               return netdev_priv(ipgre_fb_tunnel_dev);
228 +       return NULL;
229 +}
230 +
231 +static struct ip_tunnel **ipgre_bucket(struct ip_tunnel *t)
232 +{
233 +       __be32 remote = t->parms.iph.daddr;
234 +       __be32 local = t->parms.iph.saddr;
235 +       __be32 key = t->parms.i_key;
236 +       unsigned h = HASH(key);
237 +       int prio = 0;
238 +
239 +       if (local)
240 +               prio |= 1;
241 +       if (remote && !MULTICAST(remote)) {
242 +               prio |= 2;
243 +               //h ^= HASH(remote);
244 +       }
245 +
246 +       return &tunnels[prio][h];
247 +}
248 +
249 +static void ipgre_tunnel_link(struct ip_tunnel *t)
250 +{
251 +       struct ip_tunnel **tp = ipgre_bucket(t);
252 +
253 +       t->next = *tp;
254 +       write_lock_bh(&ipgre_lock);
255 +       *tp = t;
256 +       write_unlock_bh(&ipgre_lock);
257 +}
258 +
259 +static void ipgre_tunnel_unlink(struct ip_tunnel *t)
260 +{
261 +       struct ip_tunnel **tp;
262 +
263 +       for (tp = ipgre_bucket(t); *tp; tp = &(*tp)->next) {
264 +               if (t == *tp) {
265 +                       write_lock_bh(&ipgre_lock);
266 +                       *tp = t->next;
267 +                       write_unlock_bh(&ipgre_lock);
268 +                       break;
269 +               }
270 +       }
271 +}
272 +
273 +static struct ip_tunnel * ipgre_tunnel_locate(struct ip_tunnel_parm *parms, int create)
274 +{
275 +       __be32 remote = parms->iph.daddr;
276 +       __be32 local = parms->iph.saddr;
277 +       __be32 key = parms->i_key;
278 +       __be16 proto = parms->proto_type;
279 +       struct ip_tunnel *t, **tp, *nt;
280 +       struct net_device *dev;
281 +       unsigned h = HASH(key);
282 +       int prio = 0;
283 +       char name[IFNAMSIZ];
284 +
285 +       if (local)
286 +               prio |= 1;
287 +       if (remote && !MULTICAST(remote)) {
288 +               prio |= 2;
289 +               //h ^= HASH(remote);
290 +       }
291 +       for (tp = &tunnels[prio][h]; (t = *tp) != NULL; tp = &t->next) {
292 +               if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr) {
293 +                       if (key == t->parms.i_key)
294 +                               return t;
295 +               }
296 +       }
297 +       if (!create)
298 +               return NULL;
299 +
300 +       printk(KERN_CRIT "Adding tunnel %s with key %d\n", parms->name, ntohl(key));
301 +
302 +       if (parms->name[0])
303 +               strlcpy(name, parms->name, IFNAMSIZ);
304 +       else {
305 +               int i;
306 +               for (i=1; i<100; i++) {
307 +                       sprintf(name, "gre%d", i);
308 +                       if (__dev_get_by_name(&init_net, name) == NULL)
309 +                               break;
310 +               }
311 +               if (i==100)
312 +                       goto failed;
313 +       }
314 +       
315 +       /* Tunnel creation: check payload type and call appropriate
316 +        * function */
317 +       switch (proto)
318 +       {
319 +           case ETH_P_IP:
320 +               dev = alloc_netdev(sizeof(*t), name, ipgre_ip_tunnel_setup);
321 +               break;
322 +           case ETH_P_ETH:
323 +               dev = alloc_netdev(sizeof(*t), name, ipgre_eth_tunnel_setup);
324 +               break;
325 +           default:
326 +               return NULL;
327 +       }
328 +
329 +       if (!dev)
330 +         return NULL;
331 +
332 +       dev->init = ipgre_tunnel_init;
333 +       nt = netdev_priv(dev);
334 +       nt->parms = *parms;
335 +
336 +       if (register_netdevice(dev) < 0) {
337 +               free_netdev(dev);
338 +               goto failed;
339 +       }
340 +
341 +       dev_hold(dev);
342 +       ipgre_tunnel_link(nt);
343 +       return nt;
344 +
345 +failed:
346 +       return NULL;
347 +}
348 +
349 +static void ipgre_tunnel_uninit(struct net_device *dev)
350 +{
351 +       ipgre_tunnel_unlink(netdev_priv(dev));
352 +       dev_put(dev);
353 +}
354 +
355 +
356 +static void ipgre_err(struct sk_buff *skb, u32 info)
357 +{
358 +#ifndef I_WISH_WORLD_WERE_PERFECT
359 +
360 +/* It is not :-( All the routers (except for Linux) return only
361 +   8 bytes of packet payload. It means, that precise relaying of
362 +   ICMP in the real Internet is absolutely infeasible.
363 +
364 +   Moreover, Cisco "wise men" put GRE key to the third word
365 +   in GRE header. It makes impossible maintaining even soft state for keyed
366 +   GRE tunnels with enabled checksum. Tell them "thank you".
367 +
368 +   Well, I wonder, rfc1812 was written by Cisco employee,
369 +   what the hell these idiots break standrads established
370 +   by themself???
371 + */
372 +
373 +       struct iphdr *iph = (struct iphdr*)skb->data;
374 +       __be16       *p = (__be16*)(skb->data+(iph->ihl<<2));
375 +       int grehlen = (iph->ihl<<2) + 4;
376 +       int type = icmp_hdr(skb)->type;
377 +       int code = icmp_hdr(skb)->code;
378 +       struct ip_tunnel *t;
379 +       __be16 flags;
380 +
381 +       flags = p[0];
382 +       if (flags&(GRE_CSUM|GRE_KEY|GRE_SEQ|GRE_ROUTING|GRE_VERSION)) {
383 +               if (flags&(GRE_VERSION|GRE_ROUTING))
384 +                       return;
385 +               if (flags&GRE_KEY) {
386 +                       grehlen += 4;
387 +                       if (flags&GRE_CSUM)
388 +                               grehlen += 4;
389 +               }
390 +       }
391 +
392 +       /* If only 8 bytes returned, keyed message will be dropped here */
393 +       if (skb_headlen(skb) < grehlen)
394 +               return;
395 +
396 +       switch (type) {
397 +       default:
398 +       case ICMP_PARAMETERPROB:
399 +               return;
400 +
401 +       case ICMP_DEST_UNREACH:
402 +               switch (code) {
403 +               case ICMP_SR_FAILED:
404 +               case ICMP_PORT_UNREACH:
405 +                       /* Impossible event. */
406 +                       return;
407 +               case ICMP_FRAG_NEEDED:
408 +                       /* Soft state for pmtu is maintained by IP core. */
409 +                       return;
410 +               default:
411 +                       /* All others are translated to HOST_UNREACH.
412 +                          rfc2003 contains "deep thoughts" about NET_UNREACH,
413 +                          I believe they are just ether pollution. --ANK
414 +                        */
415 +                       break;
416 +               }
417 +               break;
418 +       case ICMP_TIME_EXCEEDED:
419 +               if (code != ICMP_EXC_TTL)
420 +                       return;
421 +               break;
422 +       }
423 +
424 +       read_lock(&ipgre_lock);
425 +       t = ipgre_tunnel_lookup(iph->daddr, iph->saddr, (flags&GRE_KEY) ? *(((__be32*)p) + (grehlen>>2) - 1) : 0);
426 +       if (t == NULL || t->parms.iph.daddr == 0 || MULTICAST(t->parms.iph.daddr))
427 +               goto out;
428 +
429 +       if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED)
430 +               goto out;
431 +
432 +       if (jiffies - t->err_time < IPTUNNEL_ERR_TIMEO)
433 +               t->err_count++;
434 +       else
435 +               t->err_count = 1;
436 +       t->err_time = jiffies;
437 +out:
438 +       read_unlock(&ipgre_lock);
439 +       return;
440 +#else
441 +       struct iphdr *iph = (struct iphdr*)dp;
442 +       struct iphdr *eiph;
443 +       __be16       *p = (__be16*)(dp+(iph->ihl<<2));
444 +       int type = skb->h.icmph->type;
445 +       int code = skb->h.icmph->code;
446 +       int rel_type = 0;
447 +       int rel_code = 0;
448 +       __be32 rel_info = 0;
449 +       __u32 n = 0;
450 +       __be16 flags;
451 +       int grehlen = (iph->ihl<<2) + 4;
452 +       struct sk_buff *skb2;
453 +       struct flowi fl;
454 +       struct rtable *rt;
455 +
456 +       if (skb->dev->nd_net != &init_net)
457 +               return;
458 +
459 +       if (p[1] != htons(ETH_P_IP))
460 +               return;
461 +
462 +       flags = p[0];
463 +       if (flags&(GRE_CSUM|GRE_KEY|GRE_SEQ|GRE_ROUTING|GRE_VERSION)) {
464 +               if (flags&(GRE_VERSION|GRE_ROUTING))
465 +                       return;
466 +               if (flags&GRE_CSUM)
467 +                       grehlen += 4;
468 +               if (flags&GRE_KEY)
469 +                       grehlen += 4;
470 +               if (flags&GRE_SEQ)
471 +                       grehlen += 4;
472 +       }
473 +       if (len < grehlen + sizeof(struct iphdr))
474 +               return;
475 +       eiph = (struct iphdr*)(dp + grehlen);
476 +
477 +       switch (type) {
478 +       default:
479 +               return;
480 +       case ICMP_PARAMETERPROB:
481 +               n = ntohl(skb->h.icmph->un.gateway) >> 24;
482 +               if (n < (iph->ihl<<2))
483 +                       return;
484 +
485 +               /* So... This guy found something strange INSIDE encapsulated
486 +                  packet. Well, he is fool, but what can we do ?
487 +                */
488 +               rel_type = ICMP_PARAMETERPROB;
489 +               n -= grehlen;
490 +               rel_info = htonl(n << 24);
491 +               break;
492 +
493 +       case ICMP_DEST_UNREACH:
494 +               switch (code) {
495 +               case ICMP_SR_FAILED:
496 +               case ICMP_PORT_UNREACH:
497 +                       /* Impossible event. */
498 +                       return;
499 +               case ICMP_FRAG_NEEDED:
500 +                       /* And it is the only really necessary thing :-) */
501 +                       n = ntohs(skb->h.icmph->un.frag.mtu);
502 +                       if (n < grehlen+68)
503 +                               return;
504 +                       n -= grehlen;
505 +                       /* BSD 4.2 MORE DOES NOT EXIST IN NATURE. */
506 +                       if (n > ntohs(eiph->tot_len))
507 +                               return;
508 +                       rel_info = htonl(n);
509 +                       break;
510 +               default:
511 +                       /* All others are translated to HOST_UNREACH.
512 +                          rfc2003 contains "deep thoughts" about NET_UNREACH,
513 +                          I believe, it is just ether pollution. --ANK
514 +                        */
515 +                       rel_type = ICMP_DEST_UNREACH;
516 +                       rel_code = ICMP_HOST_UNREACH;
517 +                       break;
518 +               }
519 +               break;
520 +       case ICMP_TIME_EXCEEDED:
521 +               if (code != ICMP_EXC_TTL)
522 +                       return;
523 +               break;
524 +       }
525 +
526 +       /* Prepare fake skb to feed it to icmp_send */
527 +       skb2 = skb_clone(skb, GFP_ATOMIC);
528 +       if (skb2 == NULL)
529 +               return;
530 +       dst_release(skb2->dst);
531 +       skb2->dst = NULL;
532 +       skb_pull(skb2, skb->data - (u8*)eiph);
533 +       skb_reset_network_header(skb2);
534 +
535 +       /* Try to guess incoming interface */
536 +       memset(&fl, 0, sizeof(fl));
537 +       fl.fl_net = &init_net;
538 +       fl.fl4_dst = eiph->saddr;
539 +       fl.fl4_tos = RT_TOS(eiph->tos);
540 +       fl.proto = IPPROTO_GRE;
541 +       if (ip_route_output_key(&rt, &fl)) {
542 +               kfree_skb(skb2);
543 +               return;
544 +       }
545 +       skb2->dev = rt->u.dst.dev;
546 +
547 +       /* route "incoming" packet */
548 +       if (rt->rt_flags&RTCF_LOCAL) {
549 +               ip_rt_put(rt);
550 +               rt = NULL;
551 +               fl.fl4_dst = eiph->daddr;
552 +               fl.fl4_src = eiph->saddr;
553 +               fl.fl4_tos = eiph->tos;
554 +               if (ip_route_output_key(&rt, &fl) ||
555 +                   rt->u.dst.dev->type != ARPHRD_IPGRE) {
556 +                       ip_rt_put(rt);
557 +                       kfree_skb(skb2);
558 +                       return;
559 +               }
560 +       } else {
561 +               ip_rt_put(rt);
562 +               if (ip_route_input(skb2, eiph->daddr, eiph->saddr, eiph->tos, skb2->dev) ||
563 +                   skb2->dst->dev->type != ARPHRD_IPGRE) {
564 +                       kfree_skb(skb2);
565 +                       return;
566 +               }
567 +       }
568 +
569 +       /* change mtu on this route */
570 +       if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) {
571 +               if (n > dst_mtu(skb2->dst)) {
572 +                       kfree_skb(skb2);
573 +                       return;
574 +               }
575 +               skb2->dst->ops->update_pmtu(skb2->dst, n);
576 +       } else if (type == ICMP_TIME_EXCEEDED) {
577 +               struct ip_tunnel *t = netdev_priv(skb2->dev);
578 +               if (t->parms.iph.ttl) {
579 +                       rel_type = ICMP_DEST_UNREACH;
580 +                       rel_code = ICMP_HOST_UNREACH;
581 +               }
582 +       }
583 +
584 +       icmp_send(skb2, rel_type, rel_code, rel_info);
585 +       kfree_skb(skb2);
586 +#endif
587 +}
588 +
589 +static inline void ipgre_ecn_decapsulate(struct iphdr *iph, struct sk_buff *skb)
590 +{
591 +       if (INET_ECN_is_ce(iph->tos)) {
592 +               if (skb->protocol == htons(ETH_P_IP)) {
593 +                       IP_ECN_set_ce(ip_hdr(skb));
594 +               } else if (skb->protocol == htons(ETH_P_IPV6)) {
595 +                       IP6_ECN_set_ce(ipv6_hdr(skb));
596 +               }
597 +       }
598 +}
599 +
600 +static inline u8
601 +ipgre_ecn_encapsulate(u8 tos, struct iphdr *old_iph, struct sk_buff *skb)
602 +{
603 +       u8 inner = 0;
604 +       if (skb->protocol == htons(ETH_P_IP))
605 +               inner = old_iph->tos;
606 +       else if (skb->protocol == htons(ETH_P_IPV6))
607 +               inner = ipv6_get_dsfield((struct ipv6hdr *)old_iph);
608 +       return INET_ECN_encapsulate(tos, inner);
609 +}
610 +
611 +static int ipgre_rcv(struct sk_buff *skb)
612 +{
613 +       struct iphdr *iph;
614 +       u8     *h;
615 +       __be16    flags;
616 +       __sum16   csum = 0;
617 +       __be32 key = 0;
618 +       u32    seqno = 0;
619 +       struct ip_tunnel *tunnel;
620 +       int    offset = 4;
621 +       __be16 proto;
622 +
623 +       if (skb->dev->nd_net != &init_net) {
624 +               kfree_skb(skb);
625 +               return 0;
626 +       }
627 +       if (!pskb_may_pull(skb, 16))
628 +               goto drop_nolock;
629 +
630 +       iph = ip_hdr(skb);
631 +       h = skb->data;
632 +       flags = *(__be16*)h;
633 +
634 +#ifdef GRE_DEBUG
635 +       printk(KERN_DEBUG "gre.c [601] src:%x dst:%x  proto:%d %x", iph->saddr, iph->daddr, iph->protocol, skb->data);
636 +#endif 
637 +       proto = ntohs(*(__be16*)(h+2)); /* XXX added XXX */
638 +       
639 +       if (flags&(GRE_CSUM|GRE_KEY|GRE_ROUTING|GRE_SEQ|GRE_VERSION)) {
640 +               /* - Version must be 0.
641 +                  - We do not support routing headers.
642 +                */
643 +               if (flags&(GRE_VERSION|GRE_ROUTING))
644 +                       goto drop_nolock;
645 +
646 +               if (flags&GRE_CSUM) {
647 +                       switch (skb->ip_summed) {
648 +                       case CHECKSUM_COMPLETE:
649 +                               csum = csum_fold(skb->csum);
650 +                               if (!csum)
651 +                                       break;
652 +                               /* fall through */
653 +                       case CHECKSUM_NONE:
654 +                               skb->csum = 0;
655 +                               csum = __skb_checksum_complete(skb);
656 +                               skb->ip_summed = CHECKSUM_COMPLETE;
657 +                       }
658 +                       offset += 4;
659 +               }
660 +               if (flags&GRE_KEY) {
661 +                       key = *(__be32*)(h + offset);
662 +                       offset += 4;
663 +               }
664 +               if (flags&GRE_SEQ) {
665 +                       seqno = ntohl(*(__be32*)(h + offset));
666 +                       offset += 4;
667 +               }
668 +       }
669 +
670 +       read_lock(&ipgre_lock);
671 +       if ((tunnel = ipgre_tunnel_lookup(iph->saddr, iph->daddr, key)) != NULL) {
672 +               secpath_reset(skb);
673 +
674 +               skb->protocol = *(__be16*)(h + 2);
675 +               /* WCCP version 1 and 2 protocol decoding.
676 +                * - Change protocol to IP
677 +                * - When dealing with WCCPv2, Skip extra 4 bytes in GRE header
678 +                */
679 +               if (flags == 0 &&
680 +                   skb->protocol == htons(ETH_P_WCCP)) {
681 +                       skb->protocol = htons(ETH_P_IP);
682 +                       if ((*(h + offset) & 0xF0) != 0x40)
683 +                               offset += 4;
684 +               }
685 +
686 +               //skb->mac.raw = skb->nh.raw;
687 +               skb_reset_mac_header(skb);
688 +               __pskb_pull(skb, offset);
689 +               skb_reset_network_header(skb);
690 +               skb_postpull_rcsum(skb, skb_transport_header(skb), offset);
691 +               if(proto == ETH_P_ETH)
692 +                 {
693 +#ifdef GRE_DEBUG
694 +                   unsigned char* tmp_hdr = skb->data;
695 +                   printk(KERN_DEBUG "gre.c [658] %x %x %x %x %x %x\tskb %x\n", tmp_hdr[0], tmp_hdr[1], tmp_hdr[2], tmp_hdr[3], tmp_hdr[4], tmp_hdr[5], skb->data);
696 +#endif             
697 +                   skb->protocol = eth_type_trans(skb, tunnel->dev);
698 +
699 +                   /* XXX added these lines to make arp work? XXX */
700 +                   /*skb->mac.raw = skb->data;*/
701 +                   skb->network_header = skb->network_header + ETH_HLEN;
702 +                   /* XXX added these lines to make arp work? XXX */
703 +
704 +#ifdef GRE_DEBUG
705 +                   tmp_hdr = skb->data;
706 +                   printk(KERN_DEBUG "gre.c [669] %x %x %x %x %x %x\tskb %x\n", tmp_hdr[0], tmp_hdr[1], tmp_hdr[2], tmp_hdr[3], tmp_hdr[4], tmp_hdr[5], skb->data);
707 +                   printk(KERN_ALERT "gre.c [671] received ethernet on gre %x %x\n",skb->protocol, ((skb->nh).iph)->protocol); 
708 +#endif
709 +                   memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
710 +                 }
711 +               else
712 +                 skb->pkt_type = PACKET_HOST;
713 +#ifdef CONFIG_NET_IPGRE_BROADCAST
714 +               if (MULTICAST(iph->daddr)) {
715 +                       /* Looped back packet, drop it! */
716 +                       if (((struct rtable*)skb->dst)->fl.iif == 0)
717 +                               goto drop;
718 +                       tunnel->stat.multicast++;
719 +                       skb->pkt_type = PACKET_BROADCAST;
720 +               }
721 +#endif
722 +
723 +               if (((flags&GRE_CSUM) && csum) ||
724 +                   (!(flags&GRE_CSUM) && tunnel->parms.i_flags&GRE_CSUM)) {
725 +                       tunnel->stat.rx_crc_errors++;
726 +                       tunnel->stat.rx_errors++;
727 +                       goto drop;
728 +               }
729 +               if (tunnel->parms.i_flags&GRE_SEQ) {
730 +                       if (!(flags&GRE_SEQ) ||
731 +                           (tunnel->i_seqno && (s32)(seqno - tunnel->i_seqno) < 0)) {
732 +                               tunnel->stat.rx_fifo_errors++;
733 +                               tunnel->stat.rx_errors++;
734 +                               goto drop;
735 +                       }
736 +                       tunnel->i_seqno = seqno + 1;
737 +               }
738 +               tunnel->stat.rx_packets++;
739 +               tunnel->stat.rx_bytes += skb->len;
740 +               skb->dev = tunnel->dev;
741 +               dst_release(skb->dst);
742 +               skb->dst = NULL;
743 +               nf_reset(skb);
744 +               ipgre_ecn_decapsulate(iph, skb);
745 +               netif_rx(skb);
746 +               read_unlock(&ipgre_lock);
747 +               return(0);
748 +       }
749 +       icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
750 +
751 +drop:
752 +       read_unlock(&ipgre_lock);
753 +drop_nolock:
754 +       kfree_skb(skb);
755 +       return(0);
756 +}
757 +
758 +static int ipgre_ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
759 +{
760 +       struct ip_tunnel *tunnel = netdev_priv(dev);
761 +       struct net_device_stats *stats = &tunnel->stat;
762 +       struct iphdr  *old_iph = ip_hdr(skb);
763 +       struct iphdr  *tiph;
764 +       u8     tos;
765 +       __be16 df;
766 +       struct rtable *rt;                      /* Route to the other host */
767 +       struct net_device *tdev;                        /* Device to other host */
768 +       struct iphdr  *iph;                     /* Our new IP header */
769 +       int    max_headroom;                    /* The extra header space needed */
770 +       int    gre_hlen;
771 +       __be32 dst;
772 +       int    mtu;
773 +
774 +       if (tunnel->recursion++) {
775 +               tunnel->stat.collisions++;
776 +               goto tx_error;
777 +       }
778 +
779 +       if (dev->hard_header) {
780 +               gre_hlen = 0;
781 +               tiph = (struct iphdr*)skb->data;
782 +       } else {
783 +               gre_hlen = tunnel->hlen;
784 +               tiph = &tunnel->parms.iph;
785 +       }
786 +
787 +       if ((dst = tiph->daddr) == 0) {
788 +               /* NBMA tunnel */
789 +
790 +               if (skb->dst == NULL) {
791 +                       tunnel->stat.tx_fifo_errors++;
792 +                       goto tx_error;
793 +               }
794 +
795 +               if (skb->protocol == htons(ETH_P_IP)) {
796 +                       rt = (struct rtable*)skb->dst;
797 +                       if ((dst = rt->rt_gateway) == 0)
798 +                               goto tx_error_icmp;
799 +               }
800 +#ifdef CONFIG_IPV6
801 +               else if (skb->protocol == htons(ETH_P_IPV6)) {
802 +                       struct in6_addr *addr6;
803 +                       int addr_type;
804 +                       struct neighbour *neigh = skb->dst->neighbour;
805 +
806 +                       if (neigh == NULL)
807 +                               goto tx_error;
808 +
809 +                       addr6 = (struct in6_addr*)&neigh->primary_key;
810 +                       addr_type = ipv6_addr_type(addr6);
811 +
812 +                       if (addr_type == IPV6_ADDR_ANY) {
813 +                               addr6 = &ipv6_hdr(skb)->daddr;
814 +                               addr_type = ipv6_addr_type(addr6);
815 +                       }
816 +
817 +                       if ((addr_type & IPV6_ADDR_COMPATv4) == 0)
818 +                               goto tx_error_icmp;
819 +
820 +               }
821 +#endif
822 +               else
823 +                       goto tx_error;
824 +       }
825 +
826 +       tos = tiph->tos;
827 +       if (tos&1) {
828 +               if (skb->protocol == htons(ETH_P_IP))
829 +                       tos = old_iph->tos;
830 +               tos &= ~1;
831 +       }
832 +
833 +       {
834 +               struct flowi fl = { .fl_net = &init_net,
835 +                                   .oif = tunnel->parms.link,
836 +                                   .nl_u = { .ip4_u =
837 +                                             { .daddr = dst,
838 +                                               .saddr = tiph->saddr,
839 +                                               .tos = RT_TOS(tos) } },
840 +                                   .proto = IPPROTO_GRE };
841 +               if (ip_route_output_key(&rt, &fl)) {
842 +                       tunnel->stat.tx_carrier_errors++;
843 +                       goto tx_error;
844 +               }
845 +       }
846 +       tdev = rt->u.dst.dev;
847 +
848 +
849 +       if (tdev == dev) {
850 +               ip_rt_put(rt);
851 +               tunnel->stat.collisions++;
852 +               goto tx_error;
853 +       }
854 +
855 +       df = tiph->frag_off;
856 +       if (df)
857 +               mtu = dst_mtu(&rt->u.dst) - tunnel->hlen;
858 +       else
859 +               mtu = skb->dst ? dst_mtu(skb->dst) : dev->mtu;
860 +
861 +       if (skb->dst)
862 +               skb->dst->ops->update_pmtu(skb->dst, mtu);
863 +
864 +       if (skb->protocol == htons(ETH_P_IP)) {
865 +               df |= (old_iph->frag_off&htons(IP_DF));
866 +
867 +               if ((old_iph->frag_off&htons(IP_DF)) &&
868 +                   mtu < ntohs(old_iph->tot_len)) {
869 +                       icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));
870 +                       ip_rt_put(rt);
871 +                       goto tx_error;
872 +               }
873 +       }
874 +#ifdef CONFIG_IPV6
875 +       else if (skb->protocol == htons(ETH_P_IPV6)) {
876 +               struct rt6_info *rt6 = (struct rt6_info*)skb->dst;
877 +
878 +               if (rt6 && mtu < dst_mtu(skb->dst) && mtu >= IPV6_MIN_MTU) {
879 +                       if ((tunnel->parms.iph.daddr && !MULTICAST(tunnel->parms.iph.daddr)) ||
880 +                           rt6->rt6i_dst.plen == 128) {
881 +                               rt6->rt6i_flags |= RTF_MODIFIED;
882 +                               skb->dst->metrics[RTAX_MTU-1] = mtu;
883 +                       }
884 +               }
885 +
886 +               if (mtu >= IPV6_MIN_MTU && mtu < skb->len - tunnel->hlen + gre_hlen) {
887 +                       icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, dev);
888 +                       ip_rt_put(rt);
889 +                       goto tx_error;
890 +               }
891 +       }
892 +#endif
893 +
894 +       if (tunnel->err_count > 0) {
895 +               if (jiffies - tunnel->err_time < IPTUNNEL_ERR_TIMEO) {
896 +                       tunnel->err_count--;
897 +
898 +                       dst_link_failure(skb);
899 +               } else
900 +                       tunnel->err_count = 0;
901 +       }
902 +
903 +       max_headroom = LL_RESERVED_SPACE(tdev) + gre_hlen;
904 +
905 +       if (skb_headroom(skb) < max_headroom || skb_cloned(skb) || skb_shared(skb)) {
906 +               struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
907 +               if (!new_skb) {
908 +                       ip_rt_put(rt);
909 +                       stats->tx_dropped++;
910 +                       dev_kfree_skb(skb);
911 +                       tunnel->recursion--;
912 +                       return 0;
913 +               }
914 +               if (skb->sk)
915 +                       skb_set_owner_w(new_skb, skb->sk);
916 +               dev_kfree_skb(skb);
917 +               skb = new_skb;
918 +               old_iph = ip_hdr(skb);
919 +       }
920 +
921 +       skb->transport_header = skb->network_header;
922 +       skb_push(skb, gre_hlen);
923 +       memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
924 +       IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED |
925 +                             IPSKB_REROUTED);
926 +       dst_release(skb->dst);
927 +       skb->dst = &rt->u.dst;
928 +
929 +       /*
930 +        *      Push down and install the IPIP header.
931 +        */
932 +
933 +       iph                     =       ip_hdr(skb);
934 +       iph->version            =       4;
935 +       iph->ihl                =       sizeof(struct iphdr) >> 2;
936 +       iph->frag_off           =       df;
937 +       iph->protocol           =       IPPROTO_GRE;
938 +       iph->tos                =       ipgre_ecn_encapsulate(tos, old_iph, skb);
939 +       iph->daddr              =       rt->rt_dst;
940 +       iph->saddr              =       rt->rt_src;
941 +
942 +       if ((iph->ttl = tiph->ttl) == 0) {
943 +               if (skb->protocol == htons(ETH_P_IP))
944 +                       iph->ttl = old_iph->ttl;
945 +#ifdef CONFIG_IPV6
946 +               else if (skb->protocol == htons(ETH_P_IPV6))
947 +                       iph->ttl = ((struct ipv6hdr*)old_iph)->hop_limit;
948 +#endif
949 +               else
950 +                       iph->ttl = dst_metric(&rt->u.dst, RTAX_HOPLIMIT);
951 +       }
952 +
953 +       ((__be16*)(iph+1))[0] = tunnel->parms.o_flags;
954 +       ((__be16*)(iph+1))[1] = skb->protocol;
955 +
956 +       if (tunnel->parms.o_flags&(GRE_KEY|GRE_CSUM|GRE_SEQ)) {
957 +               __be32 *ptr = (__be32*)(((u8*)iph) + tunnel->hlen - 4);
958 +
959 +               if (tunnel->parms.o_flags&GRE_SEQ) {
960 +                       ++tunnel->o_seqno;
961 +                       *ptr = htonl(tunnel->o_seqno);
962 +                       ptr--;
963 +               }
964 +               if (tunnel->parms.o_flags&GRE_KEY) {
965 +                       *ptr = tunnel->parms.o_key;
966 +                       ptr--;
967 +               }
968 +               if (tunnel->parms.o_flags&GRE_CSUM) {
969 +                       *ptr = 0;
970 +                       *(__sum16*)ptr = ip_compute_csum((void*)(iph+1), skb->len - sizeof(struct iphdr));
971 +               }
972 +       }
973 +
974 +       nf_reset(skb);
975 +
976 +       IPTUNNEL_XMIT();
977 +       tunnel->recursion--;
978 +       return 0;
979 +
980 +tx_error_icmp:
981 +       dst_link_failure(skb);
982 +
983 +tx_error:
984 +       stats->tx_errors++;
985 +       dev_kfree_skb(skb);
986 +       tunnel->recursion--;
987 +       return 0;
988 +}
989 +
990 +static int ipgre_eth_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
991 +{
992 +       struct ip_tunnel *tunnel = netdev_priv(dev);
993 +       struct net_device_stats *stats = &tunnel->stat;
994 +       struct iphdr *old_iph = ip_hdr(skb);
995 +       struct iphdr *tiph = &tunnel->parms.iph;
996 +       u8     tos;
997 +       __be16 df;
998 +       struct rtable *rt;              /* Route to the other host */
999 +       struct net_device *tdev;        /* Device to other host */
1000 +       int    gre_hlen = tunnel->hlen; /* XXX changed XXX*/
1001 +       //struct etheriphdr  *ethiph;
1002 +       struct iphdr  *iph;             /* Our new IP header */
1003 +       int    max_headroom;            /* The extra header space needed */
1004 +       int    mtu;
1005 +
1006 +#ifdef GRE_DEBUG
1007 +       printk(KERN_ALERT "gre.c:972 Starting xmit\n");
1008 +#endif
1009 +
1010 +       if (tunnel->recursion++) {
1011 +               stats->collisions++;
1012 +               goto tx_error;
1013 +       }
1014 +
1015 +       /* Need valid non-multicast daddr.  */
1016 +       if (tiph->daddr == 0 || MULTICAST(tiph->daddr))
1017 +               goto tx_error;
1018 +
1019 +       tos = tiph->tos;
1020 +       if (tos&1) {
1021 +               if (skb->protocol == htons(ETH_P_IP))
1022 +                       tos = old_iph->tos;
1023 +               tos &= ~1;
1024 +       }
1025 +#ifdef GRE_DEBUG
1026 +       printk(KERN_ALERT "gre.c:991 Passed tos assignment.\n");
1027 +#endif
1028 +
1029 +
1030 +       {
1031 +               struct flowi fl = { .fl_net = &init_net,
1032 +                                   .oif = tunnel->parms.link,
1033 +                                   .nl_u = { .ip4_u =
1034 +                                             { .daddr = tiph->daddr,
1035 +                                               .saddr = tiph->saddr,
1036 +                                               .tos = RT_TOS(tos) } },
1037 +                                   .proto = IPPROTO_GRE };
1038 +               if (ip_route_output_key(&rt, &fl)) {
1039 +                       stats->tx_carrier_errors++;
1040 +                       goto tx_error_icmp;
1041 +               }
1042 +       }
1043 +       tdev = rt->u.dst.dev;
1044 +#ifdef GRE_DEBUG
1045 +       printk(KERN_ALERT "gre.c:1006 Passed the route retrieval\n");
1046 +#endif
1047 +       if (tdev == dev) {
1048 +               ip_rt_put(rt);
1049 +               stats->collisions++;
1050 +               goto tx_error;
1051 +       }
1052 +#ifdef GRE_DEBUG
1053 +       printk(KERN_ALERT "gre.c:1018 Passed tdev collision check.\n");
1054 +#endif
1055 +
1056 +       /* Check MTU stuff if kernel panic */
1057 +       df = tiph->frag_off;
1058 +       if (df)
1059 +               mtu = dst_mtu(&rt->u.dst) - tunnel->hlen;
1060 +       else
1061 +               mtu = skb->dst ? dst_mtu(skb->dst) : dev->mtu;
1062 +/*
1063 +       if (skb->dst)
1064 +               skb->dst->ops->update_pmtu(skb->dst, mtu);
1065 +        XXX */
1066 +#ifdef GRE_DEBUG
1067 +       printk(KERN_ALERT "gre.c:1032 Passed the pmtu setting.\n");
1068 +#endif
1069 +
1070 +       if (skb->protocol == htons(ETH_P_IP)) {
1071 +               df |= (old_iph->frag_off&htons(IP_DF));
1072 +
1073 +               if ((old_iph->frag_off & htons(IP_DF)) &&
1074 +                   mtu < ntohs(old_iph->tot_len)) {
1075 +                       icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));
1076 +                       ip_rt_put(rt);
1077 +                       goto tx_error;
1078 +               }
1079 +       }
1080 +#ifdef CONFIG_IPV6
1081 +       else if (skb->protocol == htons(ETH_P_IPV6)) {
1082 +               struct rt6_info *rt6 = (struct rt6_info*)skb->dst;
1083 +
1084 +               if (rt6 && mtu < dst_mtu(skb->dst) && mtu >= IPV6_MIN_MTU) {
1085 +                       if (tiph->daddr || rt6->rt6i_dst.plen == 128) {
1086 +                               rt6->rt6i_flags |= RTF_MODIFIED;
1087 +                               skb->dst->metrics[RTAX_MTU-1] = mtu;
1088 +                       }
1089 +               }
1090 +
1091 +               /* @@@ Is this correct?  */
1092 +               if (mtu >= IPV6_MIN_MTU && mtu < skb->len - tunnel->hlen + gre_hlen) {
1093 +                       icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, dev);
1094 +                       ip_rt_put(rt);
1095 +                       goto tx_error;
1096 +               }
1097 +       }
1098 +#endif
1099 +#ifdef GRE_DEBUG
1100 +       printk(KERN_ALERT "gre.c:1065 Passed the fragmentation check.\n");
1101 +#endif
1102 +
1103 +       if (tunnel->err_count > 0) {
1104 +               if (jiffies - tunnel->err_time < IPTUNNEL_ERR_TIMEO) {
1105 +                       tunnel->err_count--;
1106 +                       dst_link_failure(skb);
1107 +               } else
1108 +                       tunnel->err_count = 0;
1109 +       }
1110 +
1111 +       max_headroom = LL_RESERVED_SPACE(tdev) + gre_hlen;
1112 +
1113 +       if (skb_headroom(skb) < max_headroom || skb_cloned(skb) || skb_shared(skb)) {
1114 +               struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
1115 +               if (!new_skb) {
1116 +                       ip_rt_put(rt);
1117 +                       stats->tx_dropped++;
1118 +                       dev_kfree_skb(skb);
1119 +                       tunnel->recursion--;
1120 +                       return 0;
1121 +               }
1122 +               if (skb->sk)
1123 +                       skb_set_owner_w(new_skb, skb->sk);
1124 +               dev_kfree_skb(skb);
1125 +               skb = new_skb;
1126 +               old_iph = ip_hdr(skb);
1127 +       }
1128 +#ifdef GRE_DEBUG
1129 +       printk(KERN_ALERT "gre.c:1094 Passed the headroom calculation\n");
1130 +#endif
1131 +
1132 +
1133 +       skb->transport_header = skb->mac_header; // Added by valas
1134 +       skb_push(skb, gre_hlen);
1135 +       skb_reset_network_header(skb);
1136 +       memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
1137 +       dst_release(skb->dst);
1138 +       skb->dst = &rt->u.dst;
1139 +
1140 +       /*
1141 +        *      Push down and install the etherip header.
1142 +        */
1143 +
1144 +       iph                     =       ip_hdr(skb);
1145 +       iph->version            =       4;
1146 +       iph->ihl                =       sizeof(struct iphdr) >> 2;
1147 +       iph->frag_off           =       df;
1148 +       iph->protocol           =       IPPROTO_GRE;
1149 +       iph->tos                =       ipgre_ecn_encapsulate(tos, old_iph, skb);
1150 +       iph->daddr              =       rt->rt_dst;
1151 +       iph->saddr              =       rt->rt_src;
1152 +
1153 +/*     ethiph->version         =       htons(ETHERIP_VERSION); */
1154 +#ifdef GRE_DEBUG
1155 +       printk(KERN_ALERT "gre.c:1121 Passed outer IP header construction.\n");
1156 +#endif
1157 +
1158 +       if ((iph->ttl = tiph->ttl) == 0) {
1159 +               if (skb->protocol == htons(ETH_P_IP))
1160 +                       iph->ttl = old_iph->ttl;
1161 +#ifdef CONFIG_IPV6
1162 +               else if (skb->protocol == htons(ETH_P_IPV6))
1163 +                       iph->ttl = ((struct ipv6hdr*)old_iph)->hop_limit;
1164 +#endif
1165 +               else
1166 +                       iph->ttl = dst_metric(&rt->u.dst, RTAX_HOPLIMIT);
1167 +       }
1168 +#ifdef GRE_DEBUG
1169 +       printk(KERN_ALERT "gre.c:1006 Passed the TTL check.\n");
1170 +#endif
1171 +
1172 +       ((__be16*)(iph+1))[0] = tunnel->parms.o_flags;
1173 +       ((__be16*)(iph+1))[1] = htons(tunnel->parms.proto_type);
1174 +
1175 +       if (tunnel->parms.o_flags&(GRE_KEY|GRE_CSUM|GRE_SEQ)) {
1176 +               __be32 *ptr = (__be32*)(((u8*)iph) + tunnel->hlen - 4);
1177 +
1178 +               if (tunnel->parms.o_flags&GRE_SEQ) {
1179 +                       ++tunnel->o_seqno;
1180 +                       *ptr = htonl(tunnel->o_seqno);
1181 +                       ptr--;
1182 +               }
1183 +               if (tunnel->parms.o_flags&GRE_KEY) {
1184 +                       *ptr = tunnel->parms.o_key;
1185 +                       ptr--;
1186 +               }
1187 +               if (tunnel->parms.o_flags&GRE_CSUM) {
1188 +                       *ptr = 0;
1189 +                       *(__sum16*)ptr = ip_compute_csum((void*)(iph+1), skb->len - sizeof(struct iphdr));
1190 +               }
1191 +       }
1192 +#ifdef GRE_DEBUG
1193 +       printk(KERN_ALERT "gre.c:1006 Passed the tunnel transmit.\n");
1194 +#endif
1195 +
1196 +       nf_reset(skb);
1197 +
1198 +       IPTUNNEL_XMIT();
1199 +       tunnel->recursion--;
1200 +       return 0;
1201 +
1202 +tx_error_icmp:
1203 +       dst_link_failure(skb);
1204 +
1205 +tx_error:
1206 +       stats->tx_errors++;
1207 +       dev_kfree_skb(skb);
1208 +       tunnel->recursion--;
1209 +       return 0;
1210 +}
1211 +
1212 +
1213 +static int
1214 +ipgre_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
1215 +{
1216 +       int err = 0;
1217 +       struct ip_tunnel_parm p;
1218 +       struct ip_tunnel *t;
1219 +
1220 +        printk(KERN_ALERT "1174 GRE: entering gre ioctl. command is: %d\n", cmd);
1221 +
1222 +       switch (cmd) {
1223 +       case SIOCGETTUNNEL:
1224 +               t = NULL;
1225 +               if (dev == ipgre_fb_tunnel_dev) {
1226 +                       if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) {
1227 +                               err = -EFAULT;
1228 +                               break;
1229 +                       }
1230 +                       t = ipgre_tunnel_locate(&p, 0);
1231 +               }
1232 +               if (t == NULL)
1233 +                       t = netdev_priv(dev);
1234 +               memcpy(&p, &t->parms, sizeof(p));
1235 +               if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p)))
1236 +                       err = -EFAULT;
1237 +               break;
1238 +
1239 +       case SIOCADDTUNNEL:
1240 +       case SIOCCHGTUNNEL:
1241 +               err = -EPERM;
1242 +               if (!capable(CAP_NET_ADMIN))
1243 +                       goto done;
1244 +
1245 +               err = -EFAULT;
1246 +               if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p)))
1247 +                       goto done;
1248 +
1249 +               err = -EINVAL;
1250 +               if (p.iph.version != 4 || p.iph.protocol != IPPROTO_GRE ||
1251 +                   p.iph.ihl != 5 || (p.iph.frag_off&htons(~IP_DF)) ||
1252 +                   ((p.i_flags|p.o_flags)&(GRE_VERSION|GRE_ROUTING)))
1253 +                       goto done;
1254 +               if (p.iph.ttl)
1255 +                       p.iph.frag_off |= htons(IP_DF);
1256 +
1257 +               if (!(p.i_flags&GRE_KEY))
1258 +                       p.i_key = 0;
1259 +               if (!(p.o_flags&GRE_KEY))
1260 +                       p.o_key = 0;
1261 +
1262 +               t = ipgre_tunnel_locate(&p, cmd == SIOCADDTUNNEL);
1263 +               if (t) printk(KERN_ALERT "1174 GRE: proto %s %d\n", p.name, p.proto_type);
1264 +               if (dev != ipgre_fb_tunnel_dev && cmd == SIOCCHGTUNNEL) {
1265 +                       if (t != NULL) {
1266 +                               if (t->dev != dev) {
1267 +                                       err = -EEXIST;
1268 +                                       break;
1269 +                               }
1270 +                       } else {
1271 +                               unsigned nflags=0;
1272 +
1273 +                               t = netdev_priv(dev);
1274 +
1275 +                               if (MULTICAST(p.iph.daddr))
1276 +                                       nflags = IFF_BROADCAST;
1277 +                               else if (p.iph.daddr)
1278 +                                       nflags = IFF_POINTOPOINT;
1279 +                               
1280 +                               /* XXX:Set back IFF_BROADCAST if
1281 +                                * transporting ethernet */
1282 +                               printk(KERN_ALERT "1193 GRE: proto %s %d\n", p.name, p.proto_type);
1283 +                               if (p.proto_type == ETH_P_ETH)
1284 +                                       nflags = IFF_BROADCAST;
1285 +
1286 +                               if ((dev->flags^nflags)&(IFF_POINTOPOINT|IFF_BROADCAST)) {
1287 +                                       err = -EINVAL;
1288 +                                       break;
1289 +                               }
1290 +                               ipgre_tunnel_unlink(t);
1291 +                               t->parms.iph.saddr = p.iph.saddr;
1292 +                               t->parms.iph.daddr = p.iph.daddr;
1293 +                               t->parms.i_key = p.i_key;
1294 +                               t->parms.o_key = p.o_key;
1295 +                               /* XXX:Copy in the protocol field */
1296 +                               t->parms.proto_type = p.proto_type;
1297 +                               if (t->parms.proto_type != ETH_P_ETH)
1298 +                               {
1299 +                                       memcpy(dev->dev_addr, &p.iph.saddr, 4);
1300 +                                       memcpy(dev->broadcast, &p.iph.daddr, 4);
1301 +                               }
1302 +                               ipgre_tunnel_link(t);
1303 +                               netdev_state_change(dev);
1304 +                       }
1305 +               }
1306 +
1307 +               if (t) {
1308 +                       err = 0;
1309 +                       if (cmd == SIOCCHGTUNNEL) {
1310 +                               t->parms.iph.ttl = p.iph.ttl;
1311 +                               t->parms.iph.tos = p.iph.tos;
1312 +                               t->parms.iph.frag_off = p.iph.frag_off;
1313 +                       }
1314 +                       if (copy_to_user(ifr->ifr_ifru.ifru_data, &t->parms, sizeof(p)))
1315 +                               err = -EFAULT;
1316 +               } else
1317 +                       err = (cmd == SIOCADDTUNNEL ? -ENOBUFS : -ENOENT);
1318 +               break;
1319 +
1320 +       case SIOCDELTUNNEL:
1321 +               err = -EPERM;
1322 +               if (!capable(CAP_NET_ADMIN))
1323 +                       goto done;
1324 +
1325 +               if (dev == ipgre_fb_tunnel_dev) {
1326 +                       err = -EFAULT;
1327 +                       if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p)))
1328 +                               goto done;
1329 +                       err = -ENOENT;
1330 +                       if ((t = ipgre_tunnel_locate(&p, 0)) == NULL)
1331 +                               goto done;
1332 +                       err = -EPERM;
1333 +                       if (t == netdev_priv(ipgre_fb_tunnel_dev))
1334 +                               goto done;
1335 +                       dev = t->dev;
1336 +               }
1337 +               unregister_netdevice(dev); // added by Valas
1338 +               break;
1339 +
1340 +       default:
1341 +               err = -EINVAL;
1342 +       }
1343 +
1344 +done:
1345 +       return err;
1346 +}
1347 +
1348 +static struct net_device_stats *ipgre_tunnel_get_stats(struct net_device *dev)
1349 +{
1350 +       return &(((struct ip_tunnel*)netdev_priv(dev))->stat);
1351 +}
1352 +
1353 +static int ipgre_tunnel_change_mtu(struct net_device *dev, int new_mtu)
1354 +{
1355 +       struct ip_tunnel *tunnel = netdev_priv(dev);
1356 +       if (new_mtu < 68 || new_mtu > 0xFFF8 - tunnel->hlen)
1357 +               return -EINVAL;
1358 +       dev->mtu = new_mtu;
1359 +       return 0;
1360 +}
1361 +
1362 +#ifdef CONFIG_NET_IPGRE_BROADCAST
1363 +/* Nice toy. Unfortunately, useless in real life :-)
1364 +   It allows to construct virtual multiprotocol broadcast "LAN"
1365 +   over the Internet, provided multicast routing is tuned.
1366 +
1367 +
1368 +   I have no idea was this bicycle invented before me,
1369 +   so that I had to set ARPHRD_IPGRE to a random value.
1370 +   I have an impression, that Cisco could make something similar,
1371 +   but this feature is apparently missing in IOS<=11.2(8).
1372 +
1373 +   I set up 10.66.66/24 and fec0:6666:6666::0/96 as virtual networks
1374 +   with broadcast 224.66.66.66. If you have access to mbone, play with me :-)
1375 +
1376 +   ping -t 255 224.66.66.66
1377 +
1378 +   If nobody answers, mbone does not work.
1379 +
1380 +   ip tunnel add Universe mode gre remote 224.66.66.66 local <Your_real_addr> ttl 255
1381 +   ip addr add 10.66.66.<somewhat>/24 dev Universe
1382 +   ifconfig Universe up
1383 +   ifconfig Universe add fe80::<Your_real_addr>/10
1384 +   ifconfig Universe add fec0:6666:6666::<Your_real_addr>/96
1385 +   ftp 10.66.66.66
1386 +   ...
1387 +   ftp fec0:6666:6666::193.233.7.65
1388 +   ...
1389 +
1390 + */
1391 +
1392 +static int ipgre_header(struct sk_buff *skb, struct net_device *dev, unsigned short type,
1393 +                       void *daddr, void *saddr, unsigned len)
1394 +{
1395 +       struct ip_tunnel *t = netdev_priv(dev);
1396 +       struct iphdr *iph = (struct iphdr *)skb_push(skb, t->hlen);
1397 +       __be16 *p = (__be16*)(iph+1);
1398 +
1399 +       memcpy(iph, &t->parms.iph, sizeof(struct iphdr));
1400 +       p[0]            = t->parms.o_flags;
1401 +       p[1]            = htons(type);
1402 +
1403 +       /*
1404 +        *      Set the source hardware address.
1405 +        */
1406 +
1407 +       if (saddr)
1408 +               memcpy(&iph->saddr, saddr, 4);
1409 +
1410 +       if (daddr) {
1411 +               memcpy(&iph->daddr, daddr, 4);
1412 +               return t->hlen;
1413 +       }
1414 +       if (iph->daddr && !MULTICAST(iph->daddr))
1415 +               return t->hlen;
1416 +
1417 +       return -t->hlen;
1418 +}
1419 +
1420 +static int ipgre_open(struct net_device *dev)
1421 +{
1422 +       struct ip_tunnel *t = netdev_priv(dev);
1423 +
1424 +       if (MULTICAST(t->parms.iph.daddr)) {
1425 +               struct flowi fl = { .fl_net = &init_net,
1426 +                                   .oif = t->parms.link,
1427 +                                   .nl_u = { .ip4_u =
1428 +                                             { .daddr = t->parms.iph.daddr,
1429 +                                               .saddr = t->parms.iph.saddr,
1430 +                                               .tos = RT_TOS(t->parms.iph.tos) } },
1431 +                                   .proto = IPPROTO_GRE };
1432 +               struct rtable *rt;
1433 +               if (ip_route_output_key(&rt, &fl))
1434 +                       return -EADDRNOTAVAIL;
1435 +               dev = rt->u.dst.dev;
1436 +               ip_rt_put(rt);
1437 +               if (__in_dev_get_rtnl(dev) == NULL)
1438 +                       return -EADDRNOTAVAIL;
1439 +               t->mlink = dev->ifindex;
1440 +               ip_mc_inc_group(__in_dev_get_rtnl(dev), t->parms.iph.daddr);
1441 +       }
1442 +       return 0;
1443 +}
1444 +
1445 +static int ipgre_close(struct net_device *dev)
1446 +{
1447 +       struct ip_tunnel *t = netdev_priv(dev);
1448 +       if (MULTICAST(t->parms.iph.daddr) && t->mlink) {
1449 +               struct in_device *in_dev = inetdev_by_index(&init_net, t->mlink);
1450 +               if (in_dev) {
1451 +                       ip_mc_dec_group(in_dev, t->parms.iph.daddr);
1452 +                       in_dev_put(in_dev);
1453 +               }
1454 +       }
1455 +       return 0;
1456 +}
1457 +
1458 +#endif
1459 +
1460 +static void ipgre_ip_tunnel_setup(struct net_device *dev)
1461 +{
1462 +       SET_MODULE_OWNER(dev);
1463 +       dev->uninit             = ipgre_tunnel_uninit;
1464 +       dev->destructor         = free_netdev;
1465 +       dev->hard_start_xmit    = ipgre_ip_tunnel_xmit;
1466 +       dev->get_stats          = ipgre_tunnel_get_stats;
1467 +       dev->do_ioctl           = ipgre_tunnel_ioctl;
1468 +       dev->change_mtu         = ipgre_tunnel_change_mtu;
1469 +
1470 +       dev->type               = ARPHRD_IPGRE;
1471 +       dev->hard_header_len    = LL_MAX_HEADER + sizeof(struct iphdr) + 4;
1472 +       dev->mtu                = ETH_DATA_LEN - sizeof(struct iphdr) - 4;
1473 +       dev->flags              = IFF_NOARP;
1474 +       dev->iflink             = 0;
1475 +       dev->addr_len           = 4;
1476 +}
1477 +
1478 +/* Tunnel setup for ipgre_eth */
1479 +static void ipgre_eth_tunnel_setup(struct net_device *dev)
1480 +{
1481 +       SET_MODULE_OWNER(dev);
1482 +       ether_setup(dev);
1483 +
1484 +       dev->uninit             = ipgre_tunnel_uninit;
1485 +       dev->destructor         = free_netdev;
1486 +       dev->hard_start_xmit    = ipgre_eth_tunnel_xmit;
1487 +       dev->get_stats          = ipgre_tunnel_get_stats;
1488 +       dev->do_ioctl           = ipgre_tunnel_ioctl;
1489 +       dev->change_mtu         = ipgre_tunnel_change_mtu;
1490 +
1491 +       dev->hard_header_len    = ETH_HLEN + sizeof(struct iphdr) + 4;
1492 +       dev->tx_queue_len       = 0;
1493 +       random_ether_addr(dev->dev_addr);
1494 +
1495 +#ifdef GRE_DEBUG
1496 +       unsigned char* d = dev->dev_addr;
1497 +       printk(KERN_ALERT "Here is the address we got:%x%x%x%x%x%x\n",d[0],d[1],d[2],d[3],d[4],d[5]);
1498 +#endif 
1499 +
1500 +       dev->iflink             = 0;
1501 +}
1502 +
1503 +
1504 +static int ipgre_tunnel_init(struct net_device *dev)
1505 +{
1506 +       struct net_device *tdev = NULL;
1507 +       struct ip_tunnel *tunnel;
1508 +       struct iphdr *iph;
1509 +       int hlen = LL_MAX_HEADER;
1510 +       int mtu = ETH_DATA_LEN;
1511 +       int addend = sizeof(struct iphdr) + 4;
1512 +
1513 +       tunnel = netdev_priv(dev);
1514 +       iph = &tunnel->parms.iph;
1515 +
1516 +       tunnel->dev = dev;
1517 +       strcpy(tunnel->parms.name, dev->name);
1518 +
1519 +       if (tunnel->parms.proto_type != ETH_P_ETH)
1520 +       {
1521 +               memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4);
1522 +               memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4);
1523 +       }
1524 +
1525 +       /* Guess output device to choose reasonable mtu and hard_header_len */
1526 +
1527 +       if (iph->daddr) {
1528 +               struct flowi fl = { .fl_net = &init_net,
1529 +                                   .oif = tunnel->parms.link,
1530 +                                   .nl_u = { .ip4_u =
1531 +                                             { .daddr = iph->daddr,
1532 +                                               .saddr = iph->saddr,
1533 +                                               .tos = RT_TOS(iph->tos) } },
1534 +                                   .proto = IPPROTO_GRE };
1535 +               struct rtable *rt;
1536 +               if (!ip_route_output_key(&rt, &fl)) {
1537 +                       tdev = rt->u.dst.dev;
1538 +                       ip_rt_put(rt);
1539 +               }
1540 +
1541 +               if (tunnel->parms.proto_type == ETH_P_ETH)
1542 +               {
1543 +                   dev->flags |= IFF_BROADCAST;
1544 +               }
1545 +               else
1546 +               {
1547 +                       dev->flags |= IFF_POINTOPOINT;
1548 +               }
1549 +
1550 +#ifdef CONFIG_NET_IPGRE_BROADCAST
1551 +               if (MULTICAST(iph->daddr)) {
1552 +                       if (!iph->saddr)
1553 +                               return -EINVAL;
1554 +                       dev->flags = IFF_BROADCAST;
1555 +                       dev->hard_header = ipgre_header;
1556 +                       dev->open = ipgre_open;
1557 +                       dev->stop = ipgre_close;
1558 +               }
1559 +#endif
1560 +       }
1561 +
1562 +       if (!tdev && tunnel->parms.link)
1563 +               tdev = __dev_get_by_index(&init_net, tunnel->parms.link);
1564 +
1565 +       if (tdev) {
1566 +               hlen = tdev->hard_header_len;
1567 +               mtu = tdev->mtu;
1568 +       }
1569 +       dev->iflink = tunnel->parms.link;
1570 +
1571 +       /* Precalculate GRE options length */
1572 +       if (tunnel->parms.o_flags&(GRE_CSUM|GRE_KEY|GRE_SEQ)) {
1573 +               if (tunnel->parms.o_flags&GRE_CSUM)
1574 +                       addend += 4;
1575 +               if (tunnel->parms.o_flags&GRE_KEY)
1576 +                       addend += 4;
1577 +               if (tunnel->parms.o_flags&GRE_SEQ)
1578 +                       addend += 4;
1579 +       }
1580 +       dev->hard_header_len = hlen + addend;
1581 +       dev->mtu = mtu - addend;
1582 +       tunnel->hlen = addend;
1583 +       return 0;
1584 +}
1585 +
1586 +static int __init ipgre_fb_tunnel_init(struct net_device *dev)
1587 +{
1588 +       struct ip_tunnel *tunnel = netdev_priv(dev);
1589 +       struct iphdr *iph = &tunnel->parms.iph;
1590 +
1591 +       tunnel->dev = dev;
1592 +       strcpy(tunnel->parms.name, dev->name);
1593 +
1594 +       iph->version            = 4;
1595 +       iph->protocol           = IPPROTO_GRE;
1596 +       iph->ihl                = 5;
1597 +       tunnel->hlen            = sizeof(struct iphdr) + 4;
1598 +
1599 +       dev_hold(dev);
1600 +       tunnels_wc[0]           = tunnel;
1601 +       return 0;
1602 +}
1603 +
1604 +
1605 +static struct net_protocol ipgre_protocol = {
1606 +       .handler        =       ipgre_rcv,
1607 +       .err_handler    =       ipgre_err,
1608 +};
1609 +
1610 +
1611 +/*
1612 + *     And now the modules code and kernel interface.
1613 + */
1614 +
1615 +static int __init ipgre_init(void)
1616 +{
1617 +       int err;
1618 +
1619 +       printk(KERN_INFO "GRE over IPv4 tunneling driver\n");
1620 +
1621 +       if (inet_add_protocol(&ipgre_protocol, IPPROTO_GRE) < 0) {
1622 +               printk(KERN_INFO "ipgre init: can't add protocol\n");
1623 +               return -EAGAIN;
1624 +       }
1625 +
1626 +       ipgre_fb_tunnel_dev = alloc_netdev(sizeof(struct ip_tunnel), "gre0",
1627 +                                          ipgre_ip_tunnel_setup);
1628 +       if (!ipgre_fb_tunnel_dev) {
1629 +               err = -ENOMEM;
1630 +               goto err1;
1631 +       }
1632 +
1633 +       ipgre_fb_tunnel_dev->init = ipgre_fb_tunnel_init;
1634 +
1635 +       if ((err = register_netdev(ipgre_fb_tunnel_dev)))
1636 +               goto err2;
1637 +out:
1638 +       return err;
1639 +err2:
1640 +       free_netdev(ipgre_fb_tunnel_dev);
1641 +err1:
1642 +       inet_del_protocol(&ipgre_protocol, IPPROTO_GRE);
1643 +       goto out;
1644 +}
1645 +
1646 +static void __exit ipgre_destroy_tunnels(void)
1647 +{
1648 +       int prio;
1649 +
1650 +       for (prio = 0; prio < 4; prio++) {
1651 +               int h;
1652 +               for (h = 0; h < HASH_SIZE; h++) {
1653 +                       struct ip_tunnel *t;
1654 +                       while ((t = tunnels[prio][h]) != NULL)
1655 +                               unregister_netdevice(t->dev);
1656 +               }
1657 +       }
1658 +}
1659 +
1660 +static void __exit ipgre_fini(void)
1661 +{
1662 +       if (inet_del_protocol(&ipgre_protocol, IPPROTO_GRE) < 0)
1663 +               printk(KERN_INFO "ipgre close: can't remove protocol\n");
1664 +
1665 +       rtnl_lock();
1666 +       ipgre_destroy_tunnels();
1667 +       rtnl_unlock();
1668 +}
1669 +
1670 +module_init(ipgre_init);
1671 +module_exit(ipgre_fini);
1672 +MODULE_LICENSE("GPL");
1673 diff -Nurb linux-2.6.27-660/include/linux/if_ether.h linux-2.6.27-700/include/linux/if_ether.h
1674 --- linux-2.6.27-660/include/linux/if_ether.h   2008-10-09 18:13:53.000000000 -0400
1675 +++ linux-2.6.27-700/include/linux/if_ether.h   2009-04-10 18:28:43.000000000 -0400
1676 @@ -56,6 +56,7 @@
1677  #define ETH_P_DIAG      0x6005          /* DEC Diagnostics              */
1678  #define ETH_P_CUST      0x6006          /* DEC Customer use             */
1679  #define ETH_P_SCA       0x6007          /* DEC Systems Comms Arch       */
1680 +#define ETH_P_ETH       0x6558          /* Ethernet in Ethernet         */
1681  #define ETH_P_RARP      0x8035         /* Reverse Addr Res packet      */
1682  #define ETH_P_ATALK    0x809B          /* Appletalk DDP                */
1683  #define ETH_P_AARP     0x80F3          /* Appletalk AARP               */
1684 diff -Nurb linux-2.6.27-660/include/linux/if_tunnel.h linux-2.6.27-700/include/linux/if_tunnel.h
1685 --- linux-2.6.27-660/include/linux/if_tunnel.h  2008-10-09 18:13:53.000000000 -0400
1686 +++ linux-2.6.27-700/include/linux/if_tunnel.h  2009-04-10 18:28:43.000000000 -0400
1687 @@ -29,6 +29,7 @@
1688         __be16                  o_flags;
1689         __be32                  i_key;
1690         __be32                  o_key;
1691 +        __be16                  proto_type;   /*Added*/
1692         struct iphdr            iph;
1693  };
1694  
1695 diff -Nurb linux-2.6.27-660/net/ipv4/ip_gre.c linux-2.6.27-700/net/ipv4/ip_gre.c
1696 --- linux-2.6.27-660/net/ipv4/ip_gre.c  2008-10-09 18:13:53.000000000 -0400
1697 +++ linux-2.6.27-700/net/ipv4/ip_gre.c  2009-04-10 18:28:43.000000000 -0400
1698 @@ -25,6 +25,7 @@
1699  #include <linux/init.h>
1700  #include <linux/in6.h>
1701  #include <linux/inetdevice.h>
1702 +#include <linux/etherdevice.h>   /**XXX added XXX */
1703  #include <linux/igmp.h>
1704  #include <linux/netfilter_ipv4.h>
1705  #include <linux/if_ether.h>
1706 @@ -48,6 +49,8 @@
1707  #include <net/ip6_route.h>
1708  #endif
1709  
1710 +//#define GRE_DEBUG 1
1711 +
1712  /*
1713     Problems & solutions
1714     --------------------
1715 @@ -118,7 +121,8 @@
1716   */
1717  
1718  static int ipgre_tunnel_init(struct net_device *dev);
1719 -static void ipgre_tunnel_setup(struct net_device *dev);
1720 +static void ipgre_ip_tunnel_setup(struct net_device *dev);
1721 +static void ipgre_eth_tunnel_setup(struct net_device *dev);
1722  
1723  /* Fallback tunnel: no source, no destination, no key, no options */
1724  
1725 @@ -255,6 +259,7 @@
1726         __be32 remote = parms->iph.daddr;
1727         __be32 local = parms->iph.saddr;
1728         __be32 key = parms->i_key;
1729 +       __be16 proto = parms->proto_type;
1730         struct ip_tunnel *t, **tp, *nt;
1731         struct net_device *dev;
1732         char name[IFNAMSIZ];
1733 @@ -269,12 +274,28 @@
1734         if (!create)
1735                 return NULL;
1736  
1737 +       printk(KERN_CRIT "Adding tunnel %s with key %d\n", parms->name, ntohl(key));
1738 +
1739         if (parms->name[0])
1740                 strlcpy(name, parms->name, IFNAMSIZ);
1741         else
1742                 sprintf(name, "gre%%d");
1743  
1744 -       dev = alloc_netdev(sizeof(*t), name, ipgre_tunnel_setup);
1745 +
1746 +       /* Tunnel creation: check payload type and call appropriate
1747 +        * function */
1748 +       switch (proto)
1749 +       {
1750 +           case ETH_P_IP:
1751 +               dev = alloc_netdev(sizeof(*t), name, ipgre_ip_tunnel_setup);
1752 +               break;
1753 +           case ETH_P_ETH:
1754 +               dev = alloc_netdev(sizeof(*t), name, ipgre_eth_tunnel_setup);
1755 +               break;
1756 +           default:
1757 +               return NULL;
1758 +       }
1759 +
1760         if (!dev)
1761           return NULL;
1762  
1763 @@ -431,6 +452,7 @@
1764         u32    seqno = 0;
1765         struct ip_tunnel *tunnel;
1766         int    offset = 4;
1767 +    __be16 proto;
1768  
1769         if (!pskb_may_pull(skb, 16))
1770                 goto drop_nolock;
1771 @@ -439,6 +461,11 @@
1772         h = skb->data;
1773         flags = *(__be16*)h;
1774  
1775 +#ifdef GRE_DEBUG
1776 +       printk(KERN_DEBUG "gre.c [601] src:%x dst:%x  proto:%d %p", iph->saddr, iph->daddr, iph->protocol, skb->data);
1777 +#endif 
1778 +       proto = ntohs(*(__be16*)(h+2)); /* XXX added XXX */
1779 +       
1780         if (flags&(GRE_CSUM|GRE_KEY|GRE_ROUTING|GRE_SEQ|GRE_VERSION)) {
1781                 /* - Version must be 0.
1782                    - We do not support routing headers.
1783 @@ -493,7 +520,29 @@
1784                 __pskb_pull(skb, offset);
1785                 skb_reset_network_header(skb);
1786                 skb_postpull_rcsum(skb, skb_transport_header(skb), offset);
1787 +               if(proto == ETH_P_ETH)
1788 +                 {
1789 + #ifdef GRE_DEBUG
1790 +                   unsigned char* tmp_hdr = skb->data;
1791 +                   printk(KERN_DEBUG "gre.c [658] %x %x %x %x %x %x\tskb %p\n", tmp_hdr[0], tmp_hdr[1], tmp_hdr[2], tmp_hdr[3], tmp_hdr[4], tmp_hdr[5], skb->data);
1792 + #endif                    
1793 +                   skb->protocol = eth_type_trans(skb, tunnel->dev);
1794
1795 +                   /* XXX added these lines to make arp work? XXX */
1796 +                   /*skb->mac.raw = skb->data;*/
1797 +                   skb->network_header = skb->network_header + ETH_HLEN;
1798 +                   /* XXX added these lines to make arp work? XXX */
1799
1800 + #ifdef GRE_DEBUG
1801 +                   tmp_hdr = skb->data;
1802 +                   printk(KERN_DEBUG "gre.c [669] %x %x %x %x %x %x\tskb %p\n", tmp_hdr[0], tmp_hdr[1], tmp_hdr[2], tmp_hdr[3], tmp_hdr[4], tmp_hdr[5], skb->data);
1803 +                   printk(KERN_ALERT "gre.c [671] received ethernet on gre %x\n",skb->protocol); 
1804 + #endif
1805 +                   memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
1806 +                 }
1807 +               else
1808                 skb->pkt_type = PACKET_HOST;
1809 +
1810  #ifdef CONFIG_NET_IPGRE_BROADCAST
1811                 if (ipv4_is_multicast(iph->daddr)) {
1812                         /* Looped back packet, drop it! */
1813 @@ -539,7 +588,7 @@
1814         return(0);
1815  }
1816  
1817 -static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
1818 +static int ipgre_ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
1819  {
1820         struct ip_tunnel *tunnel = netdev_priv(dev);
1821         struct net_device_stats *stats = &tunnel->dev->stats;
1822 @@ -799,9 +848,17 @@
1823                         tdev = rt->u.dst.dev;
1824                         ip_rt_put(rt);
1825                 }
1826 +               if (tunnel->parms.proto_type == ETH_P_ETH)
1827 +               {
1828 +                   dev->flags |= IFF_BROADCAST;
1829 +               }
1830 +               else
1831 +               {
1832                 dev->flags |= IFF_POINTOPOINT;
1833         }
1834  
1835 +       }
1836 +
1837         if (!tdev && tunnel->parms.link)
1838                 tdev = __dev_get_by_index(dev_net(dev), tunnel->parms.link);
1839  
1840 @@ -822,10 +879,234 @@
1841         }
1842         dev->hard_header_len = hlen + addend;
1843         dev->mtu = mtu - addend;
1844 +       if (tunnel->parms.proto_type == ETH_P_ETH)
1845 +               dev->mtu -= ETH_HLEN;
1846         tunnel->hlen = addend;
1847  
1848  }
1849  
1850 +static int ipgre_eth_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
1851 +{
1852 +       struct ip_tunnel *tunnel = netdev_priv(dev);
1853 +       struct net_device_stats *stats = &tunnel->stat;
1854 +       struct iphdr *old_iph = ip_hdr(skb);
1855 +       struct iphdr *tiph = &tunnel->parms.iph;
1856 +       u8     tos;
1857 +       __be16 df;
1858 +       struct rtable *rt;              /* Route to the other host */
1859 +       struct net_device *tdev;        /* Device to other host */
1860 +       int    gre_hlen = tunnel->hlen; /* XXX changed XXX*/
1861 +       //struct etheriphdr  *ethiph;
1862 +       struct iphdr  *iph;             /* Our new IP header */
1863 +       int    max_headroom;            /* The extra header space needed */
1864 +       int    mtu;
1865 +
1866 +#ifdef GRE_DEBUG
1867 +       printk(KERN_ALERT "gre.c:972 Starting xmit\n");
1868 +#endif
1869 +
1870 +       if (tunnel->recursion++) {
1871 +               stats->collisions++;
1872 +               goto tx_error;
1873 +       }
1874 +
1875 +       /* Need valid non-multicast daddr.  */
1876 +       if (tiph->daddr == 0 || MULTICAST(tiph->daddr))
1877 +               goto tx_error;
1878 +
1879 +       tos = tiph->tos;
1880 +       if (tos&1) {
1881 +               if (skb->protocol == htons(ETH_P_IP))
1882 +                       tos = old_iph->tos;
1883 +               tos &= ~1;
1884 +       }
1885 +#ifdef GRE_DEBUG
1886 +       printk(KERN_ALERT "gre.c:991 Passed tos assignment.\n");
1887 +#endif
1888 +
1889 +
1890 +       {
1891 +               struct flowi fl = { .fl_net = &init_net,
1892 +                                   .oif = tunnel->parms.link,
1893 +                                   .nl_u = { .ip4_u =
1894 +                                             { .daddr = tiph->daddr,
1895 +                                               .saddr = tiph->saddr,
1896 +                                               .tos = RT_TOS(tos) } },
1897 +                                   .proto = IPPROTO_GRE };
1898 +               if (ip_route_output_key(&rt, &fl)) {
1899 +                       stats->tx_carrier_errors++;
1900 +                       goto tx_error_icmp;
1901 +               }
1902 +       }
1903 +       tdev = rt->u.dst.dev;
1904 +#ifdef GRE_DEBUG
1905 +       printk(KERN_ALERT "gre.c:1006 Passed the route retrieval\n");
1906 +#endif
1907 +       if (tdev == dev) {
1908 +               ip_rt_put(rt);
1909 +               stats->collisions++;
1910 +               goto tx_error;
1911 +       }
1912 +#ifdef GRE_DEBUG
1913 +       printk(KERN_ALERT "gre.c:1018 Passed tdev collision check.\n");
1914 +#endif
1915 +
1916 +       /* Check MTU stuff if kernel panic */
1917 +       df = tiph->frag_off;
1918 +       if (df)
1919 +               mtu = dst_mtu(&rt->u.dst) - tunnel->hlen;
1920 +       else
1921 +               mtu = skb->dst ? dst_mtu(skb->dst) : dev->mtu;
1922 +/*
1923 +       if (skb->dst)
1924 +               skb->dst->ops->update_pmtu(skb->dst, mtu);
1925 +        XXX */
1926 +#ifdef GRE_DEBUG
1927 +       printk(KERN_ALERT "gre.c:1032 Passed the pmtu setting.\n");
1928 +#endif
1929 +
1930 +       if (skb->protocol == htons(ETH_P_IP)) {
1931 +               df |= (old_iph->frag_off&htons(IP_DF));
1932 +
1933 +               if ((old_iph->frag_off & htons(IP_DF)) &&
1934 +                   mtu < ntohs(old_iph->tot_len)) {
1935 +                       icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));
1936 +                       ip_rt_put(rt);
1937 +                       goto tx_error;
1938 +               }
1939 +       }
1940 +#ifdef CONFIG_IPV6
1941 +       else if (skb->protocol == htons(ETH_P_IPV6)) {
1942 +               struct rt6_info *rt6 = (struct rt6_info*)skb->dst;
1943 +
1944 +               if (rt6 && mtu < dst_mtu(skb->dst) && mtu >= IPV6_MIN_MTU) {
1945 +                       if (tiph->daddr || rt6->rt6i_dst.plen == 128) {
1946 +                               rt6->rt6i_flags |= RTF_MODIFIED;
1947 +                               skb->dst->metrics[RTAX_MTU-1] = mtu;
1948 +                       }
1949 +               }
1950 +
1951 +               /* @@@ Is this correct?  */
1952 +               if (mtu >= IPV6_MIN_MTU && mtu < skb->len - tunnel->hlen + gre_hlen) {
1953 +                       icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, dev);
1954 +                       ip_rt_put(rt);
1955 +                       goto tx_error;
1956 +               }
1957 +       }
1958 +#endif
1959 +#ifdef GRE_DEBUG
1960 +       printk(KERN_ALERT "gre.c:1065 Passed the fragmentation check.\n");
1961 +#endif
1962 +
1963 +       if (tunnel->err_count > 0) {
1964 +               if (jiffies - tunnel->err_time < IPTUNNEL_ERR_TIMEO) {
1965 +                       tunnel->err_count--;
1966 +                       dst_link_failure(skb);
1967 +               } else
1968 +                       tunnel->err_count = 0;
1969 +       }
1970 +
1971 +       max_headroom = LL_RESERVED_SPACE(tdev) + gre_hlen;
1972 +
1973 +       if (skb_headroom(skb) < max_headroom || skb_cloned(skb) || skb_shared(skb)) {
1974 +               struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
1975 +               if (!new_skb) {
1976 +                       ip_rt_put(rt);
1977 +                       stats->tx_dropped++;
1978 +                       dev_kfree_skb(skb);
1979 +                       tunnel->recursion--;
1980 +                       return 0;
1981 +               }
1982 +               if (skb->sk)
1983 +                       skb_set_owner_w(new_skb, skb->sk);
1984 +               dev_kfree_skb(skb);
1985 +               skb = new_skb;
1986 +               old_iph = ip_hdr(skb);
1987 +       }
1988 +#ifdef GRE_DEBUG
1989 +       printk(KERN_ALERT "gre.c:1094 Passed the headroom calculation\n");
1990 +#endif
1991 +
1992 +       skb->transport_header = skb->data;
1993 +       skb_push(skb, gre_hlen);
1994 +       skb_reset_network_header(skb);
1995 +       memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
1996 +       dst_release(skb->dst);
1997 +       skb->dst = &rt->u.dst;
1998 +
1999 +       /*
2000 +        *      Push down and install the etherip header.
2001 +        */
2002 +
2003 +       iph                     =       ip_hdr(skb);
2004 +       iph->version            =       4;
2005 +       iph->ihl                =       sizeof(struct iphdr) >> 2;
2006 +       iph->frag_off           =       df;
2007 +       iph->protocol           =       IPPROTO_GRE;
2008 +       iph->tos                =       ipgre_ecn_encapsulate(tos, old_iph, skb);
2009 +       iph->daddr              =       rt->rt_dst;
2010 +       iph->saddr              =       rt->rt_src;
2011 +
2012 +/*     ethiph->version         =       htons(ETHERIP_VERSION); */
2013 +#ifdef GRE_DEBUG
2014 +       printk(KERN_ALERT "gre.c:1121 Passed outer IP header construction.\n");
2015 +#endif
2016 +
2017 +       if ((iph->ttl = tiph->ttl) == 0) {
2018 +               if (skb->protocol == htons(ETH_P_IP))
2019 +                       iph->ttl = old_iph->ttl;
2020 +#ifdef CONFIG_IPV6
2021 +               else if (skb->protocol == htons(ETH_P_IPV6))
2022 +                       iph->ttl = ((struct ipv6hdr*)old_iph)->hop_limit;
2023 +#endif
2024 +               else
2025 +                       iph->ttl = dst_metric(&rt->u.dst, RTAX_HOPLIMIT);
2026 +       }
2027 +#ifdef GRE_DEBUG
2028 +       printk(KERN_ALERT "gre.c:1006 Passed the TTL check.\n");
2029 +#endif
2030 +
2031 +       ((__be16*)(iph+1))[0] = tunnel->parms.o_flags;
2032 +       ((__be16*)(iph+1))[1] = htons(tunnel->parms.proto_type);
2033 +
2034 +       if (tunnel->parms.o_flags&(GRE_KEY|GRE_CSUM|GRE_SEQ)) {
2035 +               __be32 *ptr = (__be32*)(((u8*)iph) + tunnel->hlen - 4);
2036 +
2037 +               if (tunnel->parms.o_flags&GRE_SEQ) {
2038 +                       ++tunnel->o_seqno;
2039 +                       *ptr = htonl(tunnel->o_seqno);
2040 +                       ptr--;
2041 +               }
2042 +               if (tunnel->parms.o_flags&GRE_KEY) {
2043 +                       *ptr = tunnel->parms.o_key;
2044 +                       ptr--;
2045 +               }
2046 +               if (tunnel->parms.o_flags&GRE_CSUM) {
2047 +                       *ptr = 0;
2048 +                       *(__sum16*)ptr = ip_compute_csum((void*)(iph+1), skb->len - sizeof(struct iphdr));
2049 +               }
2050 +       }
2051 +#ifdef GRE_DEBUG
2052 +       printk(KERN_ALERT "gre.c:1006 Passed the tunnel transmit.\n");
2053 +#endif
2054 +
2055 +       nf_reset(skb);
2056 +
2057 +       IPTUNNEL_XMIT();
2058 +       tunnel->recursion--;
2059 +       return 0;
2060 +
2061 +tx_error_icmp:
2062 +       dst_link_failure(skb);
2063 +
2064 +tx_error:
2065 +       stats->tx_errors++;
2066 +       dev_kfree_skb(skb);
2067 +       tunnel->recursion--;
2068 +       return 0;
2069 +}
2070 +
2071 +
2072  static int
2073  ipgre_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
2074  {
2075 @@ -876,6 +1157,7 @@
2076                         p.o_key = 0;
2077  
2078                 t = ipgre_tunnel_locate(net, &p, cmd == SIOCADDTUNNEL);
2079 +               if (t) printk(KERN_ALERT "1174 GRE: proto %s %x\n", p.name, p.proto_type);
2080  
2081                 if (dev != ign->fb_tunnel_dev && cmd == SIOCCHGTUNNEL) {
2082                         if (t != NULL) {
2083 @@ -893,6 +1175,12 @@
2084                                 else if (p.iph.daddr)
2085                                         nflags = IFF_POINTOPOINT;
2086  
2087 +                               /* XXX:Set back IFF_BROADCAST if
2088 +                                * transporting ethernet */
2089 +                               printk(KERN_ALERT "1193 GRE: proto %s %d\n", p.name, p.proto_type);
2090 +                               if (p.proto_type == ETH_P_ETH)
2091 +                                       nflags = IFF_BROADCAST;
2092 +
2093                                 if ((dev->flags^nflags)&(IFF_POINTOPOINT|IFF_BROADCAST)) {
2094                                         err = -EINVAL;
2095                                         break;
2096 @@ -902,8 +1190,13 @@
2097                                 t->parms.iph.daddr = p.iph.daddr;
2098                                 t->parms.i_key = p.i_key;
2099                                 t->parms.o_key = p.o_key;
2100 +                               /* XXX:Copy in the protocol field */
2101 +                               t->parms.proto_type = p.proto_type;
2102 +                               if (t->parms.proto_type != ETH_P_ETH) {
2103                                 memcpy(dev->dev_addr, &p.iph.saddr, 4);
2104                                 memcpy(dev->broadcast, &p.iph.daddr, 4);
2105 +                               }
2106 +
2107                                 ipgre_tunnel_link(ign, t);
2108                                 netdev_state_change(dev);
2109                         }
2110 @@ -1076,13 +1369,13 @@
2111  
2112  #endif
2113  
2114 -static void ipgre_tunnel_setup(struct net_device *dev)
2115 +static void ipgre_ip_tunnel_setup(struct net_device *dev)
2116  {
2117         dev->uninit             = ipgre_tunnel_uninit;
2118         dev->destructor         = free_netdev;
2119 -       dev->hard_start_xmit    = ipgre_tunnel_xmit;
2120         dev->do_ioctl           = ipgre_tunnel_ioctl;
2121         dev->change_mtu         = ipgre_tunnel_change_mtu;
2122 +       dev->hard_start_xmit    = ipgre_ip_tunnel_xmit;
2123  
2124         dev->type               = ARPHRD_IPGRE;
2125         dev->hard_header_len    = LL_MAX_HEADER + sizeof(struct iphdr) + 4;
2126 @@ -1093,6 +1386,35 @@
2127         dev->features           |= NETIF_F_NETNS_LOCAL;
2128  }
2129  
2130 +/* Tunnel setup for ipgre_eth */
2131 +static void ipgre_eth_tunnel_setup(struct net_device *dev)
2132 +{
2133 +       SET_MODULE_OWNER(dev);
2134 +
2135 +       // Set default values for Ethernet device
2136 +       ether_setup(dev);
2137 +
2138 +       dev->uninit             = ipgre_tunnel_uninit;
2139 +       dev->destructor         = free_netdev;
2140 +       dev->hard_start_xmit    = ipgre_eth_tunnel_xmit;
2141 +       dev->get_stats          = ipgre_tunnel_get_stats;
2142 +       dev->do_ioctl           = ipgre_tunnel_ioctl;
2143 +       dev->change_mtu         = ipgre_tunnel_change_mtu;
2144 +
2145 +       dev->hard_header_len    = LL_MAX_HEADER + ETH_HLEN + sizeof(struct iphdr) + 4;
2146 +       dev->mtu                = ETH_DATA_LEN - ETH_HLEN - sizeof(struct iphdr) - 4;
2147 +       dev->tx_queue_len       = 0;
2148 +       dev->iflink             = 0;
2149 +
2150 +       random_ether_addr(dev->dev_addr);
2151 +
2152 +#ifdef GRE_DEBUG
2153 +       { unsigned char* d = dev->dev_addr;
2154 +       printk(KERN_ALERT "Here is the address we got:%x%x%x%x%x%x\n",d[0],d[1],d[2],d[3],d[4],d[5]); }
2155 +#endif 
2156 +}
2157 +
2158 +
2159  static int ipgre_tunnel_init(struct net_device *dev)
2160  {
2161         struct ip_tunnel *tunnel;
2162 @@ -1104,8 +1426,10 @@
2163         tunnel->dev = dev;
2164         strcpy(tunnel->parms.name, dev->name);
2165  
2166 +       if (tunnel->parms.proto_type != ETH_P_ETH) {
2167         memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4);
2168         memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4);
2169 +       } 
2170  
2171         ipgre_tunnel_bind_dev(dev);
2172  
2173 @@ -1181,7 +1505,7 @@
2174                 goto err_assign;
2175  
2176         ign->fb_tunnel_dev = alloc_netdev(sizeof(struct ip_tunnel), "gre0",
2177 -                                          ipgre_tunnel_setup);
2178 +                                          ipgre_ip_tunnel_setup);
2179         if (!ign->fb_tunnel_dev) {
2180                 err = -ENOMEM;
2181                 goto err_alloc_dev;