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