-diff -Nurp linux-2.6.22-592/include/linux/if_ether.h linux-2.6.22-593/include/linux/if_ether.h
---- linux-2.6.22-592/include/linux/if_ether.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-593/include/linux/if_ether.h 2008-02-11 14:01:45.000000000 -0500
-@@ -56,6 +56,7 @@
- #define ETH_P_DIAG 0x6005 /* DEC Diagnostics */
- #define ETH_P_CUST 0x6006 /* DEC Customer use */
- #define ETH_P_SCA 0x6007 /* DEC Systems Comms Arch */
-+#define ETH_P_ETH 0x6558 /* Ethernet encapsulation (GRE) */
- #define ETH_P_RARP 0x8035 /* Reverse Addr Res packet */
- #define ETH_P_ATALK 0x809B /* Appletalk DDP */
- #define ETH_P_AARP 0x80F3 /* Appletalk AARP */
-diff -Nurp linux-2.6.22-592/net/ethernet/gre.c linux-2.6.22-593/net/ethernet/gre.c
---- linux-2.6.22-592/net/ethernet/gre.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-593/net/ethernet/gre.c 2008-02-11 13:43:02.000000000 -0500
-@@ -0,0 +1,1638 @@
+diff -Nurb linux-2.6.22-592/drivers/net/gre.c linux-2.6.22-593/drivers/net/gre.c
+--- linux-2.6.22-592/drivers/net/gre.c 1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.22-593/drivers/net/gre.c 2008-02-13 19:40:19.000000000 -0500
+@@ -0,0 +1,1634 @@
+/*
+ * Linux NET3: GRE over IP protocol decoder.
+ *
+ will match fallback tunnel.
+ */
+
-+#define HASH_SIZE 16
-+#define HASH(addr) (((__force u32)addr^((__force u32)addr>>4))&0xF)
++#define HASH_SIZE 1024
++#define HASH(addr) (ntohl(addr)&1023)
+
+static struct ip_tunnel *tunnels[4][HASH_SIZE];
+
+
+static struct ip_tunnel * ipgre_tunnel_lookup(__be32 remote, __be32 local, __be32 key)
+{
-+ unsigned h0 = HASH(remote);
-+ unsigned h1 = HASH(key);
++ /* HACK */
++ unsigned hash_value = HASH(key);
+ struct ip_tunnel *t;
+
-+ for (t = tunnels_r_l[h0^h1]; t; t = t->next) {
-+ if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr) {
-+ if (t->parms.i_key == key && (t->dev->flags&IFF_UP))
-+ return t;
-+ }
++ t = tunnels_r_l[hash_value];
++
++ if (t && (t->parms.i_key == key) && (t->dev->flags&IFF_UP)) {
++ return t;
+ }
-+ for (t = tunnels_r[h0^h1]; t; t = t->next) {
-+ if (remote == t->parms.iph.daddr) {
-+ if (t->parms.i_key == key && (t->dev->flags&IFF_UP))
++
++ t = tunnels_r[hash_value];
++ if (t && (t->parms.i_key == key) && (t->dev->flags&IFF_UP))
+ return t;
-+ }
-+ }
-+ for (t = tunnels_l[h1]; t; t = t->next) {
-+ if (local == t->parms.iph.saddr ||
-+ (local == t->parms.iph.daddr && MULTICAST(local))) {
-+ if (t->parms.i_key == key && (t->dev->flags&IFF_UP))
++
++ t = tunnels_l[hash_value];
++ if (t && (t->parms.i_key == key) && (t->dev->flags&IFF_UP))
+ return t;
-+ }
-+ }
-+ for (t = tunnels_wc[h1]; t; t = t->next) {
-+ if (t->parms.i_key == key && (t->dev->flags&IFF_UP))
++ t = tunnels_wc[hash_value];
++ if (t && (t->parms.i_key == key) && (t->dev->flags&IFF_UP))
+ return t;
-+ }
-+
+ if (ipgre_fb_tunnel_dev->flags&IFF_UP)
+ return netdev_priv(ipgre_fb_tunnel_dev);
+ return NULL;
+ prio |= 1;
+ if (remote && !MULTICAST(remote)) {
+ prio |= 2;
-+ h ^= HASH(remote);
++ //h ^= HASH(remote);
+ }
+
+ return &tunnels[prio][h];
+ prio |= 1;
+ if (remote && !MULTICAST(remote)) {
+ prio |= 2;
-+ h ^= HASH(remote);
++ //h ^= HASH(remote);
+ }
+ for (tp = &tunnels[prio][h]; (t = *tp) != NULL; tp = &t->next) {
+ if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr) {
+ if (!create)
+ return NULL;
+
++ printk(KERN_CRIT "Adding tunnel %s with key %d\n", parms->name, ntohl(key));
++
+ if (parms->name[0])
+ strlcpy(name, parms->name, IFNAMSIZ);
+ else {
+ int i;
+ for (i=1; i<100; i++) {
+ sprintf(name, "gre%d", i);
-+ if (__dev_get_by_name(init_net(), name) == NULL)
++ if (__dev_get_by_name(&init_net, name) == NULL)
+ break;
+ }
+ if (i==100)
+ struct iphdr *iph = (struct iphdr*)skb->data;
+ __be16 *p = (__be16*)(skb->data+(iph->ihl<<2));
+ int grehlen = (iph->ihl<<2) + 4;
-+ int type = skb->h.icmph->type;
-+ int code = skb->h.icmph->code;
++ int type = icmp_hdr(skb)->type;
++ int code = icmp_hdr(skb)->code;
+ struct ip_tunnel *t;
+ __be16 flags;
+
+ struct flowi fl;
+ struct rtable *rt;
+
-+ if (!net_eq(skb->dev->nd_net, init_net()))
++ if (skb->dev->nd_net != &init_net)
+ return;
+
+ if (p[1] != htons(ETH_P_IP))
+ dst_release(skb2->dst);
+ skb2->dst = NULL;
+ skb_pull(skb2, skb->data - (u8*)eiph);
-+ skb2->nh.raw = skb2->data;
++ skb_reset_network_header(skb2);
+
+ /* Try to guess incoming interface */
+ memset(&fl, 0, sizeof(fl));
-+ fl.fl_net = init_net();
++ fl.fl_net = &init_net;
+ fl.fl4_dst = eiph->saddr;
+ fl.fl4_tos = RT_TOS(eiph->tos);
+ fl.proto = IPPROTO_GRE;
+{
+ if (INET_ECN_is_ce(iph->tos)) {
+ if (skb->protocol == htons(ETH_P_IP)) {
-+ IP_ECN_set_ce(skb->nh.iph);
++ IP_ECN_set_ce(ip_hdr(skb));
+ } else if (skb->protocol == htons(ETH_P_IPV6)) {
-+ IP6_ECN_set_ce(skb->nh.ipv6h);
++ IP6_ECN_set_ce(ipv6_hdr(skb));
+ }
+ }
+}
+ int offset = 4;
+ __be16 proto;
+
-+ if (!net_eq(skb->dev->nd_net, init_net())) {
++ if (skb->dev->nd_net != &init_net) {
+ kfree_skb(skb);
+ return 0;
+ }
+ if (!pskb_may_pull(skb, 16))
+ goto drop_nolock;
+
-+ iph = skb->nh.iph;
++ iph = ip_hdr(skb);
+ h = skb->data;
+ flags = *(__be16*)h;
+
+ offset += 4;
+ }
+
-+ skb->mac.raw = skb->nh.raw;
-+ skb->nh.raw = __pskb_pull(skb, offset);
-+ skb_postpull_rcsum(skb, skb->h.raw, offset);
++ //skb->mac.raw = skb->nh.raw;
++ skb_reset_mac_header(skb);
++ __pskb_pull(skb, offset);
++ skb_reset_network_header(skb);
++ skb_postpull_rcsum(skb, skb_transport_header(skb), offset);
+ if(proto == ETH_P_ETH)
+ {
+#ifdef GRE_DEBUG
+
+ /* XXX added these lines to make arp work? XXX */
+ /*skb->mac.raw = skb->data;*/
-+ skb->nh.raw = skb->nh.raw + ETH_HLEN;
++ skb->network_header = skb->network_header + ETH_HLEN;
+ /* XXX added these lines to make arp work? XXX */
+
+#ifdef GRE_DEBUG
+{
+ struct ip_tunnel *tunnel = netdev_priv(dev);
+ struct net_device_stats *stats = &tunnel->stat;
-+ struct iphdr *old_iph = skb->nh.iph;
++ struct iphdr *old_iph = ip_hdr(skb);
+ struct iphdr *tiph;
+ u8 tos;
+ __be16 df;
+ addr_type = ipv6_addr_type(addr6);
+
+ if (addr_type == IPV6_ADDR_ANY) {
-+ addr6 = &skb->nh.ipv6h->daddr;
++ addr6 = &ipv6_hdr(skb)->daddr;
+ addr_type = ipv6_addr_type(addr6);
+ }
+
+ if ((addr_type & IPV6_ADDR_COMPATv4) == 0)
+ goto tx_error_icmp;
+
-+ dst = addr6->s6_addr32[3];
+ }
+#endif
+ else
+ }
+
+ {
-+ struct flowi fl = { .fl_net = init_net(),
++ struct flowi fl = { .fl_net = &init_net,
+ .oif = tunnel->parms.link,
+ .nl_u = { .ip4_u =
+ { .daddr = dst,
+ skb_set_owner_w(new_skb, skb->sk);
+ dev_kfree_skb(skb);
+ skb = new_skb;
-+ old_iph = skb->nh.iph;
++ old_iph = ip_hdr(skb);
+ }
+
-+ skb->h.raw = skb->nh.raw;
-+ skb->nh.raw = skb_push(skb, gre_hlen);
++ skb->transport_header = skb->network_header;
++ skb_push(skb, gre_hlen);
+ memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
+ IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED |
+ IPSKB_REROUTED);
+ * Push down and install the IPIP header.
+ */
+
-+ iph = skb->nh.iph;
++ iph = ip_hdr(skb);
+ iph->version = 4;
+ iph->ihl = sizeof(struct iphdr) >> 2;
+ iph->frag_off = df;
+{
+ struct ip_tunnel *tunnel = netdev_priv(dev);
+ struct net_device_stats *stats = &tunnel->stat;
-+ struct iphdr *old_iph = skb->nh.iph;
++ struct iphdr *old_iph = ip_hdr(skb);
+ struct iphdr *tiph = &tunnel->parms.iph;
+ u8 tos;
+ __be16 df;
+
+
+ {
-+ struct flowi fl = { .fl_net = init_net(),
++ struct flowi fl = { .fl_net = &init_net,
+ .oif = tunnel->parms.link,
+ .nl_u = { .ip4_u =
+ { .daddr = tiph->daddr,
+ skb_set_owner_w(new_skb, skb->sk);
+ dev_kfree_skb(skb);
+ skb = new_skb;
-+ old_iph = skb->nh.iph;
++ old_iph = ip_hdr(skb);
+ }
+#ifdef GRE_DEBUG
+ printk(KERN_ALERT "gre.c:1094 Passed the headroom calculation\n");
+
+
+/* XXX skb->h.raw = skb->nh.raw; XXX */
-+ skb->h.raw = skb->mac.raw;
++// skb->h.raw = skb->mac.raw;
++ skb->transport_header = skb->mac_header; // Added by valas
+
-+ skb->nh.raw = skb_push(skb, gre_hlen);
++ skb_push(skb, gre_hlen);
+ memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
+ dst_release(skb->dst);
+ skb->dst = &rt->u.dst;
+ * Push down and install the etherip header.
+ */
+
-+ iph = skb->nh.iph;
++ iph = ip_hdr(skb);
+ iph->version = 4;
+ iph->ihl = sizeof(struct iphdr) >> 2;
+ iph->frag_off = df;
+ p.o_key = 0;
+
+ t = ipgre_tunnel_locate(&p, cmd == SIOCADDTUNNEL);
-+ printk(KERN_ALERT "1174 GRE: proto %s %d\n", p.name, p.proto_type);
++ if (t) printk(KERN_ALERT "1174 GRE: proto %s %d\n", p.name, p.proto_type);
+ if (dev != ipgre_fb_tunnel_dev && cmd == SIOCCHGTUNNEL) {
+ if (t != NULL) {
+ if (t->dev != dev) {
+ goto done;
+ dev = t->dev;
+ }
-+ err = unregister_netdevice(dev);
++ unregister_netdevice(dev); // added by Valas
+ break;
+
+ default:
+ struct ip_tunnel *t = netdev_priv(dev);
+
+ if (MULTICAST(t->parms.iph.daddr)) {
-+ struct flowi fl = { .fl_net = init_net(),
++ struct flowi fl = { .fl_net = &init_net,
+ .oif = t->parms.link,
+ .nl_u = { .ip4_u =
+ { .daddr = t->parms.iph.daddr,
+{
+ struct ip_tunnel *t = netdev_priv(dev);
+ if (MULTICAST(t->parms.iph.daddr) && t->mlink) {
-+ struct in_device *in_dev = inetdev_by_index(init_net(), t->mlink);
++ struct in_device *in_dev = inetdev_by_index(&init_net, t->mlink);
+ if (in_dev) {
+ ip_mc_dec_group(in_dev, t->parms.iph.daddr);
+ in_dev_put(in_dev);
+ /* Guess output device to choose reasonable mtu and hard_header_len */
+
+ if (iph->daddr) {
-+ struct flowi fl = { .fl_net = init_net(),
++ struct flowi fl = { .fl_net = &init_net,
+ .oif = tunnel->parms.link,
+ .nl_u = { .ip4_u =
+ { .daddr = iph->daddr,
+ }
+
+ if (!tdev && tunnel->parms.link)
-+ tdev = __dev_get_by_index(init_net(), tunnel->parms.link);
++ tdev = __dev_get_by_index(&init_net, tunnel->parms.link);
+
+ if (tdev) {
+ hlen = tdev->hard_header_len;
+module_init(ipgre_init);
+module_exit(ipgre_fini);
+MODULE_LICENSE("GPL");
-diff -Nurp linux-2.6.22-592/net/ethernet/Makefile linux-2.6.22-593/net/ethernet/Makefile
---- linux-2.6.22-592/net/ethernet/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-593/net/ethernet/Makefile 2008-02-11 13:58:47.000000000 -0500
-@@ -5,3 +5,5 @@
- obj-y += eth.o
- obj-$(subst m,y,$(CONFIG_IPX)) += pe2.o
- obj-$(subst m,y,$(CONFIG_ATALK)) += pe2.o
-+obj-m += gre.o
-+
+diff -Nurb linux-2.6.22-592/drivers/net/Makefile linux-2.6.22-593/drivers/net/Makefile
+--- linux-2.6.22-592/drivers/net/Makefile 2008-02-13 15:29:36.000000000 -0500
++++ linux-2.6.22-593/drivers/net/Makefile 2008-02-13 15:32:42.000000000 -0500
+@@ -2,6 +2,7 @@
+ # Makefile for the Linux network (ethercard) device drivers.
+ #
+
++obj-m +=gre.o
+ obj-y +=ztun.o shortbridge.o
+ obj-$(CONFIG_E1000) += e1000/
+ obj-$(CONFIG_E1000E) += e1000e/
+diff -Nurb linux-2.6.22-592/include/linux/if_ether.h linux-2.6.22-593/include/linux/if_ether.h
+--- linux-2.6.22-592/include/linux/if_ether.h 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-593/include/linux/if_ether.h 2008-02-13 15:36:53.000000000 -0500
+@@ -56,6 +56,7 @@
+ #define ETH_P_DIAG 0x6005 /* DEC Diagnostics */
+ #define ETH_P_CUST 0x6006 /* DEC Customer use */
+ #define ETH_P_SCA 0x6007 /* DEC Systems Comms Arch */
++#define ETH_P_ETH 0x6558 /* Ethernet in Ethernet */
+ #define ETH_P_RARP 0x8035 /* Reverse Addr Res packet */
+ #define ETH_P_ATALK 0x809B /* Appletalk DDP */
+ #define ETH_P_AARP 0x80F3 /* Appletalk AARP */
+diff -Nurb linux-2.6.22-592/include/linux/if_tunnel.h linux-2.6.22-593/include/linux/if_tunnel.h
+--- linux-2.6.22-592/include/linux/if_tunnel.h 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-593/include/linux/if_tunnel.h 2008-02-13 15:38:04.000000000 -0500
+@@ -25,6 +25,7 @@
+ __be16 o_flags;
+ __be32 i_key;
+ __be32 o_key;
++ __be16 proto_type; /*Added*/
+ struct iphdr iph;
+ };
+