Setting tag linux-2.6-27-38
[linux-2.6.git] / linux-2.6-700-egre.patch
index 1cac19d..e1fb5c8 100644 (file)
@@ -1,7 +1,31 @@
-diff -Nurp 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-03-18 16:10:13.000000000 -0400
-@@ -0,0 +1,1632 @@
+diff -Nurb linux-2.6.27-660/drivers/net/Kconfig linux-2.6.27-700/drivers/net/Kconfig
+--- linux-2.6.27-660/drivers/net/Kconfig       2009-04-16 10:27:01.000000000 -0400
++++ linux-2.6.27-700/drivers/net/Kconfig       2009-04-16 10:27:39.000000000 -0400
+@@ -39,6 +39,9 @@
+         'ifb1' etc.
+         Look at the iproute2 documentation directory for usage etc
++config EGRE
++      tristate "EGRE module for Ethernet over GRE Tunnels"
++      
+ config DUMMY
+       tristate "Dummy net driver support"
+       ---help---
+diff -Nurb linux-2.6.27-660/drivers/net/Makefile linux-2.6.27-700/drivers/net/Makefile
+--- linux-2.6.27-660/drivers/net/Makefile      2008-10-09 18:13:53.000000000 -0400
++++ linux-2.6.27-700/drivers/net/Makefile      2009-04-16 10:27:39.000000000 -0400
+@@ -2,6 +2,7 @@
+ # Makefile for the Linux network (ethercard) device drivers.
+ #
++obj-$(CONFIG_EGRE) += gre.o
+ obj-$(CONFIG_E1000) += e1000/
+ obj-$(CONFIG_E1000E) += e1000e/
+ obj-$(CONFIG_IBM_NEW_EMAC) += ibm_newemac/
+diff -Nurb linux-2.6.27-660/drivers/net/gre.c linux-2.6.27-700/drivers/net/gre.c
+--- linux-2.6.27-660/drivers/net/gre.c 1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.27-700/drivers/net/gre.c 2009-04-16 12:48:33.000000000 -0400
+@@ -0,0 +1,1646 @@
 +/*
 + *    Linux NET3:     GRE over IP protocol decoder.
 + *
@@ -52,6 +76,8 @@ diff -Nurp linux-2.6.22-592/drivers/net/gre.c linux-2.6.22-593/drivers/net/gre.c
 +#include <net/ip6_route.h>
 +#endif
 +
++#define ipv4_is_multicast(x)    (((x) & htonl(0xf0000000)) == htonl(0xe0000000))
++
 +//#define GRE_DEBUG 1
 +
 +/*
@@ -202,7 +228,7 @@ diff -Nurp linux-2.6.22-592/drivers/net/gre.c linux-2.6.22-593/drivers/net/gre.c
 +
 +      if (local)
 +              prio |= 1;
-+      if (remote && !MULTICAST(remote)) {
++      if (remote && !ipv4_is_multicast(remote)) {
 +              prio |= 2;
 +              //h ^= HASH(remote);
 +      }
@@ -248,7 +274,7 @@ diff -Nurp linux-2.6.22-592/drivers/net/gre.c linux-2.6.22-593/drivers/net/gre.c
 +
 +      if (local)
 +              prio |= 1;
-+      if (remote && !MULTICAST(remote)) {
++      if (remote && !ipv4_is_multicast(remote)) {
 +              prio |= 2;
 +              //h ^= HASH(remote);
 +      }
@@ -387,7 +413,7 @@ diff -Nurp linux-2.6.22-592/drivers/net/gre.c linux-2.6.22-593/drivers/net/gre.c
 +
 +      read_lock(&ipgre_lock);
 +      t = ipgre_tunnel_lookup(iph->daddr, iph->saddr, (flags&GRE_KEY) ? *(((__be32*)p) + (grehlen>>2) - 1) : 0);
-+      if (t == NULL || t->parms.iph.daddr == 0 || MULTICAST(t->parms.iph.daddr))
++      if (t == NULL || t->parms.iph.daddr == 0 || ipv4_is_multicast(t->parms.iph.daddr))
 +              goto out;
 +
 +      if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED)
@@ -498,11 +524,11 @@ diff -Nurp linux-2.6.22-592/drivers/net/gre.c linux-2.6.22-593/drivers/net/gre.c
 +
 +      /* 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 (ip_route_output_key(&rt, &fl)) {
++      if (ip_route_output_key(dev_net(dev),&rt, &fl)) {
 +              kfree_skb(skb2);
 +              return;
 +      }
@@ -675,32 +701,32 @@ diff -Nurp linux-2.6.22-592/drivers/net/gre.c linux-2.6.22-593/drivers/net/gre.c
 +              else
 +                skb->pkt_type = PACKET_HOST;
 +#ifdef CONFIG_NET_IPGRE_BROADCAST
-+              if (MULTICAST(iph->daddr)) {
++              if (ipv4_is_multicast(iph->daddr)) {
 +                      /* Looped back packet, drop it! */
 +                      if (((struct rtable*)skb->dst)->fl.iif == 0)
 +                              goto drop;
-+                      tunnel->stat.multicast++;
++                      tunnel->dev->stats.multicast++;
 +                      skb->pkt_type = PACKET_BROADCAST;
 +              }
 +#endif
 +
 +              if (((flags&GRE_CSUM) && csum) ||
 +                  (!(flags&GRE_CSUM) && tunnel->parms.i_flags&GRE_CSUM)) {
-+                      tunnel->stat.rx_crc_errors++;
-+                      tunnel->stat.rx_errors++;
++                      tunnel->dev->stats.rx_crc_errors++;
++                      tunnel->dev->stats.rx_errors++;
 +                      goto drop;
 +              }
 +              if (tunnel->parms.i_flags&GRE_SEQ) {
 +                      if (!(flags&GRE_SEQ) ||
 +                          (tunnel->i_seqno && (s32)(seqno - tunnel->i_seqno) < 0)) {
-+                              tunnel->stat.rx_fifo_errors++;
-+                              tunnel->stat.rx_errors++;
++                              tunnel->dev->stats.rx_fifo_errors++;
++                              tunnel->dev->stats.rx_errors++;
 +                              goto drop;
 +                      }
 +                      tunnel->i_seqno = seqno + 1;
 +              }
-+              tunnel->stat.rx_packets++;
-+              tunnel->stat.rx_bytes += skb->len;
++              tunnel->dev->stats.rx_packets++;
++              tunnel->dev->stats.rx_bytes += skb->len;
 +              skb->dev = tunnel->dev;
 +              dst_release(skb->dst);
 +              skb->dst = NULL;
@@ -722,7 +748,7 @@ diff -Nurp linux-2.6.22-592/drivers/net/gre.c linux-2.6.22-593/drivers/net/gre.c
 +static int ipgre_ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
 +{
 +      struct ip_tunnel *tunnel = netdev_priv(dev);
-+      struct net_device_stats *stats = &tunnel->stat;
++      struct net_device_stats *stats = &tunnel->dev->stats;
 +      struct iphdr  *old_iph = ip_hdr(skb);
 +      struct iphdr  *tiph;
 +      u8     tos;
@@ -736,11 +762,11 @@ diff -Nurp linux-2.6.22-592/drivers/net/gre.c linux-2.6.22-593/drivers/net/gre.c
 +      int    mtu;
 +
 +      if (tunnel->recursion++) {
-+              tunnel->stat.collisions++;
++              tunnel->dev->stats.collisions++;
 +              goto tx_error;
 +      }
 +
-+      if (dev->hard_header) {
++      if (dev->header_ops) {
 +              gre_hlen = 0;
 +              tiph = (struct iphdr*)skb->data;
 +      } else {
@@ -752,7 +778,7 @@ diff -Nurp linux-2.6.22-592/drivers/net/gre.c linux-2.6.22-593/drivers/net/gre.c
 +              /* NBMA tunnel */
 +
 +              if (skb->dst == NULL) {
-+                      tunnel->stat.tx_fifo_errors++;
++                      tunnel->dev->stats.tx_fifo_errors++;
 +                      goto tx_error;
 +              }
 +
@@ -795,15 +821,15 @@ diff -Nurp linux-2.6.22-592/drivers/net/gre.c linux-2.6.22-593/drivers/net/gre.c
 +      }
 +
 +      {
-+              struct flowi fl = { .fl_net = &init_net,
++              struct flowi fl = { //.fl_net = &init_net,
 +                                  .oif = tunnel->parms.link,
 +                                  .nl_u = { .ip4_u =
 +                                            { .daddr = dst,
 +                                              .saddr = tiph->saddr,
 +                                              .tos = RT_TOS(tos) } },
 +                                  .proto = IPPROTO_GRE };
-+              if (ip_route_output_key(&rt, &fl)) {
-+                      tunnel->stat.tx_carrier_errors++;
++              if (ip_route_output_key(dev_net(dev),&rt, &fl)) {
++                      tunnel->dev->stats.tx_carrier_errors++;
 +                      goto tx_error;
 +              }
 +      }
@@ -812,7 +838,7 @@ diff -Nurp linux-2.6.22-592/drivers/net/gre.c linux-2.6.22-593/drivers/net/gre.c
 +
 +      if (tdev == dev) {
 +              ip_rt_put(rt);
-+              tunnel->stat.collisions++;
++              tunnel->dev->stats.collisions++;
 +              goto tx_error;
 +      }
 +
@@ -840,7 +866,7 @@ diff -Nurp linux-2.6.22-592/drivers/net/gre.c linux-2.6.22-593/drivers/net/gre.c
 +              struct rt6_info *rt6 = (struct rt6_info*)skb->dst;
 +
 +              if (rt6 && mtu < dst_mtu(skb->dst) && mtu >= IPV6_MIN_MTU) {
-+                      if ((tunnel->parms.iph.daddr && !MULTICAST(tunnel->parms.iph.daddr)) ||
++                      if ((tunnel->parms.iph.daddr && !ipv4_is_multicast(tunnel->parms.iph.daddr)) ||
 +                          rt6->rt6i_dst.plen == 128) {
 +                              rt6->rt6i_flags |= RTF_MODIFIED;
 +                              skb->dst->metrics[RTAX_MTU-1] = mtu;
@@ -954,7 +980,7 @@ diff -Nurp linux-2.6.22-592/drivers/net/gre.c linux-2.6.22-593/drivers/net/gre.c
 +static int ipgre_eth_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
 +{
 +      struct ip_tunnel *tunnel = netdev_priv(dev);
-+      struct net_device_stats *stats = &tunnel->stat;
++      struct net_device_stats *stats = &tunnel->dev->stats;
 +      struct iphdr *old_iph = ip_hdr(skb);
 +      struct iphdr *tiph = &tunnel->parms.iph;
 +      u8     tos;
@@ -976,8 +1002,8 @@ diff -Nurp linux-2.6.22-592/drivers/net/gre.c linux-2.6.22-593/drivers/net/gre.c
 +              goto tx_error;
 +      }
 +
-+      /* Need valid non-multicast daddr.  */
-+      if (tiph->daddr == 0 || MULTICAST(tiph->daddr))
++      /* Need valid non-ipv4_is_multicast daddr.  */
++      if (tiph->daddr == 0 || ipv4_is_multicast(tiph->daddr))
 +              goto tx_error;
 +
 +      tos = tiph->tos;
@@ -992,14 +1018,14 @@ diff -Nurp linux-2.6.22-592/drivers/net/gre.c linux-2.6.22-593/drivers/net/gre.c
 +
 +
 +      {
-+              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,
 +                                              .saddr = tiph->saddr,
 +                                              .tos = RT_TOS(tos) } },
 +                                  .proto = IPPROTO_GRE };
-+              if (ip_route_output_key(&rt, &fl)) {
++              if (ip_route_output_key(dev_net(dev),&rt, &fl)) {
 +                      stats->tx_carrier_errors++;
 +                      goto tx_error_icmp;
 +              }
@@ -1236,7 +1262,7 @@ diff -Nurp linux-2.6.22-592/drivers/net/gre.c linux-2.6.22-593/drivers/net/gre.c
 +
 +                              t = netdev_priv(dev);
 +
-+                              if (MULTICAST(p.iph.daddr))
++                              if (ipv4_is_multicast(p.iph.daddr))
 +                                      nflags = IFF_BROADCAST;
 +                              else if (p.iph.daddr)
 +                                      nflags = IFF_POINTOPOINT;
@@ -1311,7 +1337,7 @@ diff -Nurp linux-2.6.22-592/drivers/net/gre.c linux-2.6.22-593/drivers/net/gre.c
 +
 +static struct net_device_stats *ipgre_tunnel_get_stats(struct net_device *dev)
 +{
-+      return &(((struct ip_tunnel*)netdev_priv(dev))->stat);
++      return &(((struct ip_tunnel*)netdev_priv(dev))->dev->stats);
 +}
 +
 +static int ipgre_tunnel_change_mtu(struct net_device *dev, int new_mtu)
@@ -1326,7 +1352,7 @@ diff -Nurp linux-2.6.22-592/drivers/net/gre.c linux-2.6.22-593/drivers/net/gre.c
 +#ifdef CONFIG_NET_IPGRE_BROADCAST
 +/* Nice toy. Unfortunately, useless in real life :-)
 +   It allows to construct virtual multiprotocol broadcast "LAN"
-+   over the Internet, provided multicast routing is tuned.
++   over the Internet, provided ipv4_is_multicast routing is tuned.
 +
 +
 +   I have no idea was this bicycle invented before me,
@@ -1353,40 +1379,12 @@ diff -Nurp linux-2.6.22-592/drivers/net/gre.c linux-2.6.22-593/drivers/net/gre.c
 +
 + */
 +
-+static int ipgre_header(struct sk_buff *skb, struct net_device *dev, unsigned short type,
-+                      void *daddr, void *saddr, unsigned len)
-+{
-+      struct ip_tunnel *t = netdev_priv(dev);
-+      struct iphdr *iph = (struct iphdr *)skb_push(skb, t->hlen);
-+      __be16 *p = (__be16*)(iph+1);
-+
-+      memcpy(iph, &t->parms.iph, sizeof(struct iphdr));
-+      p[0]            = t->parms.o_flags;
-+      p[1]            = htons(type);
-+
-+      /*
-+       *      Set the source hardware address.
-+       */
-+
-+      if (saddr)
-+              memcpy(&iph->saddr, saddr, 4);
-+
-+      if (daddr) {
-+              memcpy(&iph->daddr, daddr, 4);
-+              return t->hlen;
-+      }
-+      if (iph->daddr && !MULTICAST(iph->daddr))
-+              return t->hlen;
-+
-+      return -t->hlen;
-+}
-+
 +static int ipgre_open(struct net_device *dev)
 +{
 +      struct ip_tunnel *t = netdev_priv(dev);
 +
-+      if (MULTICAST(t->parms.iph.daddr)) {
-+              struct flowi fl = { .fl_net = &init_net,
++      if (ipv4_is_multicast(t->parms.iph.daddr)) {
++              struct flowi fl = { //.fl_net = &init_net,
 +                                  .oif = t->parms.link,
 +                                  .nl_u = { .ip4_u =
 +                                            { .daddr = t->parms.iph.daddr,
@@ -1394,7 +1392,7 @@ diff -Nurp linux-2.6.22-592/drivers/net/gre.c linux-2.6.22-593/drivers/net/gre.c
 +                                              .tos = RT_TOS(t->parms.iph.tos) } },
 +                                  .proto = IPPROTO_GRE };
 +              struct rtable *rt;
-+              if (ip_route_output_key(&rt, &fl))
++              if (ip_route_output_key(dev_net(dev),&rt, &fl))
 +                      return -EADDRNOTAVAIL;
 +              dev = rt->u.dst.dev;
 +              ip_rt_put(rt);
@@ -1409,7 +1407,7 @@ diff -Nurp linux-2.6.22-592/drivers/net/gre.c linux-2.6.22-593/drivers/net/gre.c
 +static int ipgre_close(struct net_device *dev)
 +{
 +      struct ip_tunnel *t = netdev_priv(dev);
-+      if (MULTICAST(t->parms.iph.daddr) && t->mlink) {
++      if (ipv4_is_multicast(t->parms.iph.daddr) && 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);
@@ -1423,7 +1421,7 @@ diff -Nurp linux-2.6.22-592/drivers/net/gre.c linux-2.6.22-593/drivers/net/gre.c
 +
 +static void ipgre_ip_tunnel_setup(struct net_device *dev)
 +{
-+      SET_MODULE_OWNER(dev);
++      //SET_MODULE_OWNER(dev);
 +      dev->uninit             = ipgre_tunnel_uninit;
 +      dev->destructor         = free_netdev;
 +      dev->hard_start_xmit    = ipgre_ip_tunnel_xmit;
@@ -1442,7 +1440,7 @@ diff -Nurp linux-2.6.22-592/drivers/net/gre.c linux-2.6.22-593/drivers/net/gre.c
 +/* Tunnel setup for ipgre_eth */
 +static void ipgre_eth_tunnel_setup(struct net_device *dev)
 +{
-+      SET_MODULE_OWNER(dev);
++      //SET_MODULE_OWNER(dev);
 +      ether_setup(dev);
 +
 +      dev->uninit             = ipgre_tunnel_uninit;
@@ -1464,6 +1462,46 @@ diff -Nurp linux-2.6.22-592/drivers/net/gre.c linux-2.6.22-593/drivers/net/gre.c
 +      dev->iflink             = 0;
 +}
 +
++static int ipgre_header(struct sk_buff *skb, struct net_device *dev,
++            unsigned short type,
++            const void *daddr, const void *saddr, unsigned len)
++{
++    struct ip_tunnel *t = netdev_priv(dev);
++    struct iphdr *iph = (struct iphdr *)skb_push(skb, t->hlen);
++    __be16 *p = (__be16*)(iph+1);
++
++    memcpy(iph, &t->parms.iph, sizeof(struct iphdr));
++    p[0]        = t->parms.o_flags;
++    p[1]        = htons(type);
++
++    /*
++     *  Set the source hardware address.
++     */
++
++    if (saddr)
++        memcpy(&iph->saddr, saddr, 4);
++
++    if (daddr) {
++        memcpy(&iph->daddr, daddr, 4);
++        return t->hlen;
++    }
++    if (iph->daddr && !ipv4_is_multicast(iph->daddr))
++        return t->hlen;
++
++    return -t->hlen;
++}
++
++static int ipgre_header_parse(const struct sk_buff *skb, unsigned char *haddr)
++{
++    struct iphdr *iph = (struct iphdr*) skb_mac_header(skb);
++    memcpy(haddr, &iph->saddr, 4);
++    return 4;
++}
++
++static const struct header_ops ipgre_header_ops = {
++    .create = ipgre_header,
++    .parse  = ipgre_header_parse,
++};
 +
 +static int ipgre_tunnel_init(struct net_device *dev)
 +{
@@ -1489,7 +1527,7 @@ diff -Nurp linux-2.6.22-592/drivers/net/gre.c linux-2.6.22-593/drivers/net/gre.c
 +      /* 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,
@@ -1497,7 +1535,7 @@ diff -Nurp linux-2.6.22-592/drivers/net/gre.c linux-2.6.22-593/drivers/net/gre.c
 +                                              .tos = RT_TOS(iph->tos) } },
 +                                  .proto = IPPROTO_GRE };
 +              struct rtable *rt;
-+              if (!ip_route_output_key(&rt, &fl)) {
++              if (!ip_route_output_key(dev_net(dev), &rt, &fl)) {
 +                      tdev = rt->u.dst.dev;
 +                      ip_rt_put(rt);
 +              }
@@ -1512,11 +1550,11 @@ diff -Nurp linux-2.6.22-592/drivers/net/gre.c linux-2.6.22-593/drivers/net/gre.c
 +              }
 +
 +#ifdef CONFIG_NET_IPGRE_BROADCAST
-+              if (MULTICAST(iph->daddr)) {
++              if (ipv4_is_multicast(iph->daddr)) {
 +                      if (!iph->saddr)
 +                              return -EINVAL;
 +                      dev->flags = IFF_BROADCAST;
-+                      dev->hard_header = ipgre_header;
++                      dev->header_ops = &ipgre_header_ops;
 +                      dev->open = ipgre_open;
 +                      dev->stop = ipgre_close;
 +              }
@@ -1634,20 +1672,9 @@ diff -Nurp linux-2.6.22-592/drivers/net/gre.c linux-2.6.22-593/drivers/net/gre.c
 +module_init(ipgre_init);
 +module_exit(ipgre_fini);
 +MODULE_LICENSE("GPL");
-diff -Nurp 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-03-18 16:10:09.000000000 -0400
-+++ linux-2.6.22-593/drivers/net/Makefile      2008-03-18 16:10:13.000000000 -0400
-@@ -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 -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-03-18 16:10:13.000000000 -0400
+diff -Nurb linux-2.6.27-660/include/linux/if_ether.h linux-2.6.27-700/include/linux/if_ether.h
+--- linux-2.6.27-660/include/linux/if_ether.h  2008-10-09 18:13:53.000000000 -0400
++++ linux-2.6.27-700/include/linux/if_ether.h  2009-04-16 10:27:39.000000000 -0400
 @@ -56,6 +56,7 @@
  #define ETH_P_DIAG      0x6005          /* DEC Diagnostics              */
  #define ETH_P_CUST      0x6006          /* DEC Customer use             */
@@ -1656,10 +1683,10 @@ diff -Nurp linux-2.6.22-592/include/linux/if_ether.h linux-2.6.22-593/include/li
  #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/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-03-18 16:10:13.000000000 -0400
-@@ -25,6 +25,7 @@ struct ip_tunnel_parm
+diff -Nurb linux-2.6.27-660/include/linux/if_tunnel.h linux-2.6.27-700/include/linux/if_tunnel.h
+--- linux-2.6.27-660/include/linux/if_tunnel.h 2008-10-09 18:13:53.000000000 -0400
++++ linux-2.6.27-700/include/linux/if_tunnel.h 2009-04-16 10:27:39.000000000 -0400
+@@ -29,6 +29,7 @@
        __be16                  o_flags;
        __be32                  i_key;
        __be32                  o_key;
@@ -1667,9 +1694,9 @@ diff -Nurp linux-2.6.22-592/include/linux/if_tunnel.h linux-2.6.22-593/include/l
        struct iphdr            iph;
  };
  
-diff -Nurp linux-2.6.22-592/net/ipv4/ip_gre.c linux-2.6.22-593/net/ipv4/ip_gre.c
---- linux-2.6.22-592/net/ipv4/ip_gre.c 2008-03-18 16:10:02.000000000 -0400
-+++ linux-2.6.22-593/net/ipv4/ip_gre.c 2008-03-18 16:12:02.000000000 -0400
+diff -Nurb linux-2.6.27-660/net/ipv4/ip_gre.c linux-2.6.27-700/net/ipv4/ip_gre.c
+--- linux-2.6.27-660/net/ipv4/ip_gre.c 2008-10-09 18:13:53.000000000 -0400
++++ linux-2.6.27-700/net/ipv4/ip_gre.c 2009-04-16 12:48:33.000000000 -0400
 @@ -25,6 +25,7 @@
  #include <linux/init.h>
  #include <linux/in6.h>
@@ -1678,16 +1705,18 @@ diff -Nurp linux-2.6.22-592/net/ipv4/ip_gre.c linux-2.6.22-593/net/ipv4/ip_gre.c
  #include <linux/igmp.h>
  #include <linux/netfilter_ipv4.h>
  #include <linux/if_ether.h>
-@@ -46,6 +47,8 @@
+@@ -48,6 +49,10 @@
  #include <net/ip6_route.h>
  #endif
  
++#define MULTICAST(x)    (((x) & htonl(0xf0000000)) == htonl(0xe0000000))
++
 +//#define GRE_DEBUG 1
 +
  /*
     Problems & solutions
     --------------------
-@@ -116,7 +119,8 @@
+@@ -118,7 +123,8 @@
   */
  
  static int ipgre_tunnel_init(struct net_device *dev);
@@ -1697,7 +1726,7 @@ diff -Nurp linux-2.6.22-592/net/ipv4/ip_gre.c linux-2.6.22-593/net/ipv4/ip_gre.c
  
  /* Fallback tunnel: no source, no destination, no key, no options */
  
-@@ -243,6 +247,7 @@ static struct ip_tunnel * ipgre_tunnel_l
+@@ -255,6 +261,7 @@
        __be32 remote = parms->iph.daddr;
        __be32 local = parms->iph.saddr;
        __be32 key = parms->i_key;
@@ -1705,7 +1734,7 @@ diff -Nurp linux-2.6.22-592/net/ipv4/ip_gre.c linux-2.6.22-593/net/ipv4/ip_gre.c
        struct ip_tunnel *t, **tp, *nt;
        struct net_device *dev;
        char name[IFNAMSIZ];
-@@ -256,6 +261,8 @@ static struct ip_tunnel * ipgre_tunnel_l
+@@ -269,12 +276,28 @@
        if (!create)
                return NULL;
  
@@ -1713,39 +1742,37 @@ diff -Nurp linux-2.6.22-592/net/ipv4/ip_gre.c linux-2.6.22-593/net/ipv4/ip_gre.c
 +
        if (parms->name[0])
                strlcpy(name, parms->name, IFNAMSIZ);
-       else {
-@@ -268,8 +275,21 @@ static struct ip_tunnel * ipgre_tunnel_l
-               if (i==100)
-                       goto failed;
-       }
-+      
-+      /* Tunnel creation: check payload type and call appropriate
-+       * function */
-+      switch (proto)
-+      {
-+          case ETH_P_IP:
-+              dev = alloc_netdev(sizeof(*t), name, ipgre_ip_tunnel_setup);
-+              break;
-+          case ETH_P_ETH:
-+              dev = alloc_netdev(sizeof(*t), name, ipgre_eth_tunnel_setup);
-+              break;
-+          default:
-+              return NULL;
-+      }
+       else
+               sprintf(name, "gre%%d");
  
 -      dev = alloc_netdev(sizeof(*t), name, ipgre_tunnel_setup);
++
++      /* Tunnel creation: check payload type and call appropriate
++       * function */
++      switch (proto)
++      {
++          case ETH_P_IP:
++              dev = alloc_netdev(sizeof(*t), name, ipgre_ip_tunnel_setup);
++              break;
++          case ETH_P_ETH:
++              dev = alloc_netdev(sizeof(*t), name, ipgre_eth_tunnel_setup);
++              break;
++          default:
++              return NULL;
++      }
++
        if (!dev)
          return NULL;
  
-@@ -562,6 +582,7 @@ static int ipgre_rcv(struct sk_buff *skb
+@@ -431,6 +454,7 @@
        u32    seqno = 0;
        struct ip_tunnel *tunnel;
        int    offset = 4;
-+      __be16 proto;
++    __be16 proto;
  
-       if (skb->dev->nd_net != &init_net) {
-               kfree_skb(skb);
-@@ -574,6 +595,11 @@ static int ipgre_rcv(struct sk_buff *skb
+       if (!pskb_may_pull(skb, 16))
+               goto drop_nolock;
+@@ -439,6 +463,11 @@
        h = skb->data;
        flags = *(__be16*)h;
  
@@ -1757,37 +1784,37 @@ diff -Nurp linux-2.6.22-592/net/ipv4/ip_gre.c linux-2.6.22-593/net/ipv4/ip_gre.c
        if (flags&(GRE_CSUM|GRE_KEY|GRE_ROUTING|GRE_SEQ|GRE_VERSION)) {
                /* - Version must be 0.
                   - We do not support routing headers.
-@@ -625,7 +651,28 @@ static int ipgre_rcv(struct sk_buff *skb
+@@ -493,7 +522,29 @@
                __pskb_pull(skb, offset);
                skb_reset_network_header(skb);
                skb_postpull_rcsum(skb, skb_transport_header(skb), offset);
--              skb->pkt_type = PACKET_HOST;
-+              if(proto == ETH_P_ETH)
-+                {
-+#ifdef GRE_DEBUG
-+                  unsigned char* tmp_hdr = skb->data;
-+                  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);
-+#endif                    
-+                  skb->protocol = eth_type_trans(skb, tunnel->dev);
-+
-+                  /* XXX added these lines to make arp work? XXX */
-+                  /*skb->mac.raw = skb->data;*/
-+                  skb->network_header = skb->network_header + ETH_HLEN;
-+                  /* XXX added these lines to make arp work? XXX */
++              if(proto == ETH_P_ETH)
++                {
++ #ifdef GRE_DEBUG
++                  unsigned char* tmp_hdr = skb->data;
++                  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);
++ #endif                   
++                  skb->protocol = eth_type_trans(skb, tunnel->dev);
++ 
++                  /* XXX added these lines to make arp work? XXX */
++                  /*skb->mac.raw = skb->data;*/
++                  skb->network_header = skb->network_header + ETH_HLEN;
++                  /* XXX added these lines to make arp work? XXX */
++ 
++ #ifdef GRE_DEBUG
++                  tmp_hdr = skb->data;
++                  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);
++                  printk(KERN_ALERT "gre.c [671] received ethernet on gre %x\n",skb->protocol); 
++ #endif
++                  memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
++                }
++              else
+               skb->pkt_type = PACKET_HOST;
 +
-+#ifdef GRE_DEBUG
-+                  tmp_hdr = skb->data;
-+                  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);
-+                  printk(KERN_ALERT "gre.c [671] received ethernet on gre %x\n",skb->protocol); 
-+#endif
-+                  memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
-+                }
-+              else
-+                skb->pkt_type = PACKET_HOST;
  #ifdef CONFIG_NET_IPGRE_BROADCAST
-               if (MULTICAST(iph->daddr)) {
+               if (ipv4_is_multicast(iph->daddr)) {
                        /* Looped back packet, drop it! */
-@@ -671,7 +718,7 @@ drop_nolock:
+@@ -539,7 +590,7 @@
        return(0);
  }
  
@@ -1795,15 +1822,39 @@ diff -Nurp linux-2.6.22-592/net/ipv4/ip_gre.c linux-2.6.22-593/net/ipv4/ip_gre.c
 +static int ipgre_ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
  {
        struct ip_tunnel *tunnel = netdev_priv(dev);
-       struct net_device_stats *stats = &tunnel->stat;
-@@ -904,6 +951,228 @@ tx_error:
-       return 0;
+       struct net_device_stats *stats = &tunnel->dev->stats;
+@@ -799,9 +850,17 @@
+                       tdev = rt->u.dst.dev;
+                       ip_rt_put(rt);
+               }
++              if (tunnel->parms.proto_type == ETH_P_ETH)
++              {
++                  dev->flags |= IFF_BROADCAST;
++              }
++              else
++              {
+               dev->flags |= IFF_POINTOPOINT;
+       }
++      }
++
+       if (!tdev && tunnel->parms.link)
+               tdev = __dev_get_by_index(dev_net(dev), tunnel->parms.link);
+@@ -822,10 +881,234 @@
+       }
+       dev->hard_header_len = hlen + addend;
+       dev->mtu = mtu - addend;
++      if (tunnel->parms.proto_type == ETH_P_ETH)
++              dev->mtu -= ETH_HLEN;
+       tunnel->hlen = addend;
  }
  
 +static int ipgre_eth_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
 +{
 +      struct ip_tunnel *tunnel = netdev_priv(dev);
-+      struct net_device_stats *stats = &tunnel->stat;
++      struct net_device_stats *stats = &tunnel->dev->stats;
 +      struct iphdr *old_iph = ip_hdr(skb);
 +      struct iphdr *tiph = &tunnel->parms.iph;
 +      u8     tos;
@@ -1841,14 +1892,14 @@ diff -Nurp linux-2.6.22-592/net/ipv4/ip_gre.c linux-2.6.22-593/net/ipv4/ip_gre.c
 +
 +
 +      {
-+              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,
 +                                              .saddr = tiph->saddr,
 +                                              .tos = RT_TOS(tos) } },
 +                                  .proto = IPPROTO_GRE };
-+              if (ip_route_output_key(&rt, &fl)) {
++              if (ip_route_output_key(dev_net(dev),&rt, &fl)) {
 +                      stats->tx_carrier_errors++;
 +                      goto tx_error_icmp;
 +              }
@@ -2025,75 +2076,65 @@ diff -Nurp linux-2.6.22-592/net/ipv4/ip_gre.c linux-2.6.22-593/net/ipv4/ip_gre.c
  static int
  ipgre_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
  {
-@@ -911,6 +1180,8 @@ ipgre_tunnel_ioctl (struct net_device *d
-       struct ip_tunnel_parm p;
-       struct ip_tunnel *t;
-+        printk(KERN_ALERT "1174 GRE: entering gre ioctl. command is: %d\n", cmd);
-+
-       switch (cmd) {
-       case SIOCGETTUNNEL:
-               t = NULL;
-@@ -952,7 +1223,7 @@ ipgre_tunnel_ioctl (struct net_device *d
+@@ -876,6 +1159,7 @@
                        p.o_key = 0;
  
-               t = ipgre_tunnel_locate(&p, cmd == SIOCADDTUNNEL);
--
-+              if (t) printk(KERN_ALERT "1174 GRE: proto %s %x\n", p.name, p.proto_type);
-               if (dev != ipgre_fb_tunnel_dev && cmd == SIOCCHGTUNNEL) {
+               t = ipgre_tunnel_locate(net, &p, cmd == SIOCADDTUNNEL);
++              if (t) printk(KERN_ALERT "1174 GRE: proto %s %x\n", p.name, p.proto_type);
+               if (dev != ign->fb_tunnel_dev && cmd == SIOCCHGTUNNEL) {
                        if (t != NULL) {
-                               if (t->dev != dev) {
-@@ -968,6 +1239,12 @@ ipgre_tunnel_ioctl (struct net_device *d
-                                       nflags = IFF_BROADCAST;
+@@ -893,6 +1177,12 @@
                                else if (p.iph.daddr)
                                        nflags = IFF_POINTOPOINT;
-+                              
 +                              /* XXX:Set back IFF_BROADCAST if
 +                               * transporting ethernet */
 +                              printk(KERN_ALERT "1193 GRE: proto %s %d\n", p.name, p.proto_type);
 +                              if (p.proto_type == ETH_P_ETH)
 +                                      nflags = IFF_BROADCAST;
++
                                if ((dev->flags^nflags)&(IFF_POINTOPOINT|IFF_BROADCAST)) {
                                        err = -EINVAL;
-@@ -978,8 +1255,12 @@ ipgre_tunnel_ioctl (struct net_device *d
+                                       break;
+@@ -902,8 +1192,13 @@
                                t->parms.iph.daddr = p.iph.daddr;
                                t->parms.i_key = p.i_key;
                                t->parms.o_key = p.o_key;
--                              memcpy(dev->dev_addr, &p.iph.saddr, 4);
--                              memcpy(dev->broadcast, &p.iph.daddr, 4);
-+                              /* XXX:Copy in the protocol field */
-+                              t->parms.proto_type = p.proto_type;
-+                              if (t->parms.proto_type != ETH_P_ETH) {
-+                                      memcpy(dev->dev_addr, &p.iph.saddr, 4);
-+                                      memcpy(dev->broadcast, &p.iph.daddr, 4);
-+                              }
-                               ipgre_tunnel_link(t);
++                              /* XXX:Copy in the protocol field */
++                              t->parms.proto_type = p.proto_type;
++                              if (t->parms.proto_type != ETH_P_ETH) {
+                               memcpy(dev->dev_addr, &p.iph.saddr, 4);
+                               memcpy(dev->broadcast, &p.iph.daddr, 4);
++                              }
++
+                               ipgre_tunnel_link(ign, t);
                                netdev_state_change(dev);
                        }
-@@ -1139,12 +1420,12 @@ static int ipgre_close(struct net_device
+@@ -1076,13 +1371,13 @@
  
  #endif
  
 -static void ipgre_tunnel_setup(struct net_device *dev)
 +static void ipgre_ip_tunnel_setup(struct net_device *dev)
  {
-       SET_MODULE_OWNER(dev);
        dev->uninit             = ipgre_tunnel_uninit;
        dev->destructor         = free_netdev;
 -      dev->hard_start_xmit    = ipgre_tunnel_xmit;
-+      dev->hard_start_xmit    = ipgre_ip_tunnel_xmit;
-       dev->get_stats          = ipgre_tunnel_get_stats;
        dev->do_ioctl           = ipgre_tunnel_ioctl;
        dev->change_mtu         = ipgre_tunnel_change_mtu;
-@@ -1157,6 +1438,35 @@ static void ipgre_tunnel_setup(struct ne
-       dev->addr_len           = 4;
++      dev->hard_start_xmit    = ipgre_ip_tunnel_xmit;
+       dev->type               = ARPHRD_IPGRE;
+       dev->hard_header_len    = LL_MAX_HEADER + sizeof(struct iphdr) + 4;
+@@ -1093,6 +1388,36 @@
+       dev->features           |= NETIF_F_NETNS_LOCAL;
  }
  
 +/* Tunnel setup for ipgre_eth */
 +static void ipgre_eth_tunnel_setup(struct net_device *dev)
 +{
-+      SET_MODULE_OWNER(dev);
++      //SET_MODULE_OWNER(dev);
 +
 +       // Set default values for Ethernet device
 +      ether_setup(dev);
@@ -2101,7 +2142,7 @@ diff -Nurp linux-2.6.22-592/net/ipv4/ip_gre.c linux-2.6.22-593/net/ipv4/ip_gre.c
 +      dev->uninit             = ipgre_tunnel_uninit;
 +      dev->destructor         = free_netdev;
 +      dev->hard_start_xmit    = ipgre_eth_tunnel_xmit;
-+      dev->get_stats          = ipgre_tunnel_get_stats;
++      //dev->get_stats                = ipgre_tunnel_get_stats;
 +      dev->do_ioctl           = ipgre_tunnel_ioctl;
 +      dev->change_mtu         = ipgre_tunnel_change_mtu;
 +
@@ -2109,6 +2150,7 @@ diff -Nurp linux-2.6.22-592/net/ipv4/ip_gre.c linux-2.6.22-593/net/ipv4/ip_gre.c
 +      dev->mtu                = ETH_DATA_LEN - ETH_HLEN - sizeof(struct iphdr) - 4;
 +      dev->tx_queue_len       = 0;
 +      dev->iflink             = 0;
++      dev->features           |= NETIF_F_NETNS_LOCAL;
 +
 +      random_ether_addr(dev->dev_addr);
 +
@@ -2121,51 +2163,24 @@ diff -Nurp linux-2.6.22-592/net/ipv4/ip_gre.c linux-2.6.22-593/net/ipv4/ip_gre.c
 +
  static int ipgre_tunnel_init(struct net_device *dev)
  {
-       struct net_device *tdev = NULL;
-@@ -1172,8 +1482,10 @@ static int ipgre_tunnel_init(struct net_
+       struct ip_tunnel *tunnel;
+@@ -1104,8 +1429,10 @@
        tunnel->dev = dev;
        strcpy(tunnel->parms.name, dev->name);
  
--      memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4);
--      memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4);
 +      if (tunnel->parms.proto_type != ETH_P_ETH) {
-+              memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4);
-+              memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4);
-+      } 
+       memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4);
+       memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4);
++      } 
  
-       /* Guess output device to choose reasonable mtu and hard_header_len */
+       ipgre_tunnel_bind_dev(dev);
  
-@@ -1191,7 +1503,14 @@ static int ipgre_tunnel_init(struct net_
-                       ip_rt_put(rt);
-               }
--              dev->flags |= IFF_POINTOPOINT;
-+              if (tunnel->parms.proto_type == ETH_P_ETH)
-+              {
-+                  dev->flags |= IFF_BROADCAST;
-+              }
-+              else
-+              {
-+                      dev->flags |= IFF_POINTOPOINT;
-+              }
- #ifdef CONFIG_NET_IPGRE_BROADCAST
-               if (MULTICAST(iph->daddr)) {
-@@ -1225,6 +1544,8 @@ static int ipgre_tunnel_init(struct net_
-       }
-       dev->hard_header_len = hlen + addend;
-       dev->mtu = mtu - addend;
-+      if (tunnel->parms.proto_type == ETH_P_ETH)
-+              dev->mtu -= ETH_HLEN;
-       tunnel->hlen = addend;
-       return 0;
- }
-@@ -1270,7 +1591,7 @@ static int __init ipgre_init(void)
-       }
+@@ -1181,7 +1508,7 @@
+               goto err_assign;
  
-       ipgre_fb_tunnel_dev = alloc_netdev(sizeof(struct ip_tunnel), "gre0",
+       ign->fb_tunnel_dev = alloc_netdev(sizeof(struct ip_tunnel), "gre0",
 -                                         ipgre_tunnel_setup);
 +                                         ipgre_ip_tunnel_setup);
-       if (!ipgre_fb_tunnel_dev) {
+       if (!ign->fb_tunnel_dev) {
                err = -ENOMEM;
-               goto err1;
+               goto err_alloc_dev;