Debugged EGRE module
authorSapan Bhatia <sapanb@cs.princeton.edu>
Thu, 16 Apr 2009 16:43:07 +0000 (16:43 +0000)
committerSapan Bhatia <sapanb@cs.princeton.edu>
Thu, 16 Apr 2009 16:43:07 +0000 (16:43 +0000)
linux-2.6-700-egre.patch

index 43e75b3..1ce71c4 100644 (file)
@@ -1,6 +1,6 @@
 diff -Nurb linux-2.6.27-660/Makefile linux-2.6.27-700/Makefile
---- linux-2.6.27-660/Makefile  2009-04-10 18:27:45.000000000 -0400
-+++ linux-2.6.27-700/Makefile  2009-04-10 18:28:43.000000000 -0400
+--- linux-2.6.27-660/Makefile  2009-04-16 10:27:07.000000000 -0400
++++ linux-2.6.27-700/Makefile  2009-04-16 10:27:39.000000000 -0400
 @@ -1,7 +1,7 @@
  VERSION = 2
  PATCHLEVEL = 6
@@ -11,8 +11,8 @@ diff -Nurb linux-2.6.27-660/Makefile linux-2.6.27-700/Makefile
  
  # *DOCUMENTATION*
 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-10 18:27:44.000000000 -0400
-+++ linux-2.6.27-700/drivers/net/Kconfig       2009-04-10 18:32:52.000000000 -0400
+--- 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
@@ -25,7 +25,7 @@ diff -Nurb linux-2.6.27-660/drivers/net/Kconfig linux-2.6.27-700/drivers/net/Kco
        ---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-10 18:28:43.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.
  #
@@ -36,8 +36,8 @@ diff -Nurb linux-2.6.27-660/drivers/net/Makefile linux-2.6.27-700/drivers/net/Ma
  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-10 18:28:43.000000000 -0400
-@@ -0,0 +1,1632 @@
++++ 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.
 + *
@@ -88,6 +88,8 @@ diff -Nurb linux-2.6.27-660/drivers/net/gre.c linux-2.6.27-700/drivers/net/gre.c
 +#include <net/ip6_route.h>
 +#endif
 +
++#define ipv4_is_multicast(x)    (((x) & htonl(0xf0000000)) == htonl(0xe0000000))
++
 +//#define GRE_DEBUG 1
 +
 +/*
@@ -238,7 +240,7 @@ diff -Nurb linux-2.6.27-660/drivers/net/gre.c linux-2.6.27-700/drivers/net/gre.c
 +
 +      if (local)
 +              prio |= 1;
-+      if (remote && !MULTICAST(remote)) {
++      if (remote && !ipv4_is_multicast(remote)) {
 +              prio |= 2;
 +              //h ^= HASH(remote);
 +      }
@@ -284,7 +286,7 @@ diff -Nurb linux-2.6.27-660/drivers/net/gre.c linux-2.6.27-700/drivers/net/gre.c
 +
 +      if (local)
 +              prio |= 1;
-+      if (remote && !MULTICAST(remote)) {
++      if (remote && !ipv4_is_multicast(remote)) {
 +              prio |= 2;
 +              //h ^= HASH(remote);
 +      }
@@ -423,7 +425,7 @@ diff -Nurb linux-2.6.27-660/drivers/net/gre.c linux-2.6.27-700/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)
@@ -534,11 +536,11 @@ diff -Nurb linux-2.6.27-660/drivers/net/gre.c linux-2.6.27-700/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;
 +      }
@@ -711,32 +713,32 @@ diff -Nurb linux-2.6.27-660/drivers/net/gre.c linux-2.6.27-700/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;
@@ -758,7 +760,7 @@ diff -Nurb linux-2.6.27-660/drivers/net/gre.c linux-2.6.27-700/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;
@@ -772,11 +774,11 @@ diff -Nurb linux-2.6.27-660/drivers/net/gre.c linux-2.6.27-700/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 {
@@ -788,7 +790,7 @@ diff -Nurb linux-2.6.27-660/drivers/net/gre.c linux-2.6.27-700/drivers/net/gre.c
 +              /* NBMA tunnel */
 +
 +              if (skb->dst == NULL) {
-+                      tunnel->stat.tx_fifo_errors++;
++                      tunnel->dev->stats.tx_fifo_errors++;
 +                      goto tx_error;
 +              }
 +
@@ -831,15 +833,15 @@ diff -Nurb linux-2.6.27-660/drivers/net/gre.c linux-2.6.27-700/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;
 +              }
 +      }
@@ -848,7 +850,7 @@ diff -Nurb linux-2.6.27-660/drivers/net/gre.c linux-2.6.27-700/drivers/net/gre.c
 +
 +      if (tdev == dev) {
 +              ip_rt_put(rt);
-+              tunnel->stat.collisions++;
++              tunnel->dev->stats.collisions++;
 +              goto tx_error;
 +      }
 +
@@ -876,7 +878,7 @@ diff -Nurb linux-2.6.27-660/drivers/net/gre.c linux-2.6.27-700/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;
@@ -990,7 +992,7 @@ diff -Nurb linux-2.6.27-660/drivers/net/gre.c linux-2.6.27-700/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;
@@ -1012,8 +1014,8 @@ diff -Nurb linux-2.6.27-660/drivers/net/gre.c linux-2.6.27-700/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;
@@ -1028,14 +1030,14 @@ diff -Nurb linux-2.6.27-660/drivers/net/gre.c linux-2.6.27-700/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;
 +              }
@@ -1272,7 +1274,7 @@ diff -Nurb linux-2.6.27-660/drivers/net/gre.c linux-2.6.27-700/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;
@@ -1347,7 +1349,7 @@ diff -Nurb linux-2.6.27-660/drivers/net/gre.c linux-2.6.27-700/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)
@@ -1362,7 +1364,7 @@ diff -Nurb linux-2.6.27-660/drivers/net/gre.c linux-2.6.27-700/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,
@@ -1389,40 +1391,12 @@ diff -Nurb linux-2.6.27-660/drivers/net/gre.c linux-2.6.27-700/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,
@@ -1430,7 +1404,7 @@ diff -Nurb linux-2.6.27-660/drivers/net/gre.c linux-2.6.27-700/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);
@@ -1445,7 +1419,7 @@ diff -Nurb linux-2.6.27-660/drivers/net/gre.c linux-2.6.27-700/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);
@@ -1459,7 +1433,7 @@ diff -Nurb linux-2.6.27-660/drivers/net/gre.c linux-2.6.27-700/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;
@@ -1478,7 +1452,7 @@ diff -Nurb linux-2.6.27-660/drivers/net/gre.c linux-2.6.27-700/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;
@@ -1500,6 +1474,46 @@ diff -Nurb linux-2.6.27-660/drivers/net/gre.c linux-2.6.27-700/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)
 +{
@@ -1525,7 +1539,7 @@ diff -Nurb linux-2.6.27-660/drivers/net/gre.c linux-2.6.27-700/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,
@@ -1533,7 +1547,7 @@ diff -Nurb linux-2.6.27-660/drivers/net/gre.c linux-2.6.27-700/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);
 +              }
@@ -1548,11 +1562,11 @@ diff -Nurb linux-2.6.27-660/drivers/net/gre.c linux-2.6.27-700/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;
 +              }
@@ -1672,7 +1686,7 @@ diff -Nurb linux-2.6.27-660/drivers/net/gre.c linux-2.6.27-700/drivers/net/gre.c
 +MODULE_LICENSE("GPL");
 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-10 18:28:43.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             */
@@ -1683,7 +1697,7 @@ diff -Nurb linux-2.6.27-660/include/linux/if_ether.h linux-2.6.27-700/include/li
  #define ETH_P_AARP    0x80F3          /* Appletalk AARP               */
 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-10 18:28:43.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;
@@ -1694,7 +1708,7 @@ diff -Nurb linux-2.6.27-660/include/linux/if_tunnel.h linux-2.6.27-700/include/l
  
 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-10 18:28:43.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>
@@ -1703,16 +1717,18 @@ diff -Nurb linux-2.6.27-660/net/ipv4/ip_gre.c linux-2.6.27-700/net/ipv4/ip_gre.c
  #include <linux/igmp.h>
  #include <linux/netfilter_ipv4.h>
  #include <linux/if_ether.h>
-@@ -48,6 +49,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
     --------------------
-@@ -118,7 +121,8 @@
+@@ -118,7 +123,8 @@
   */
  
  static int ipgre_tunnel_init(struct net_device *dev);
@@ -1722,7 +1738,7 @@ diff -Nurb linux-2.6.27-660/net/ipv4/ip_gre.c linux-2.6.27-700/net/ipv4/ip_gre.c
  
  /* Fallback tunnel: no source, no destination, no key, no options */
  
-@@ -255,6 +259,7 @@
+@@ -255,6 +261,7 @@
        __be32 remote = parms->iph.daddr;
        __be32 local = parms->iph.saddr;
        __be32 key = parms->i_key;
@@ -1730,7 +1746,7 @@ diff -Nurb linux-2.6.27-660/net/ipv4/ip_gre.c linux-2.6.27-700/net/ipv4/ip_gre.c
        struct ip_tunnel *t, **tp, *nt;
        struct net_device *dev;
        char name[IFNAMSIZ];
-@@ -269,12 +274,28 @@
+@@ -269,12 +276,28 @@
        if (!create)
                return NULL;
  
@@ -1760,7 +1776,7 @@ diff -Nurb linux-2.6.27-660/net/ipv4/ip_gre.c linux-2.6.27-700/net/ipv4/ip_gre.c
        if (!dev)
          return NULL;
  
-@@ -431,6 +452,7 @@
+@@ -431,6 +454,7 @@
        u32    seqno = 0;
        struct ip_tunnel *tunnel;
        int    offset = 4;
@@ -1768,7 +1784,7 @@ diff -Nurb linux-2.6.27-660/net/ipv4/ip_gre.c linux-2.6.27-700/net/ipv4/ip_gre.c
  
        if (!pskb_may_pull(skb, 16))
                goto drop_nolock;
-@@ -439,6 +461,11 @@
+@@ -439,6 +463,11 @@
        h = skb->data;
        flags = *(__be16*)h;
  
@@ -1780,7 +1796,7 @@ diff -Nurb linux-2.6.27-660/net/ipv4/ip_gre.c linux-2.6.27-700/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.
-@@ -493,7 +520,29 @@
+@@ -493,7 +522,29 @@
                __pskb_pull(skb, offset);
                skb_reset_network_header(skb);
                skb_postpull_rcsum(skb, skb_transport_header(skb), offset);
@@ -1810,7 +1826,7 @@ diff -Nurb linux-2.6.27-660/net/ipv4/ip_gre.c linux-2.6.27-700/net/ipv4/ip_gre.c
  #ifdef CONFIG_NET_IPGRE_BROADCAST
                if (ipv4_is_multicast(iph->daddr)) {
                        /* Looped back packet, drop it! */
-@@ -539,7 +588,7 @@
+@@ -539,7 +590,7 @@
        return(0);
  }
  
@@ -1819,7 +1835,7 @@ diff -Nurb linux-2.6.27-660/net/ipv4/ip_gre.c linux-2.6.27-700/net/ipv4/ip_gre.c
  {
        struct ip_tunnel *tunnel = netdev_priv(dev);
        struct net_device_stats *stats = &tunnel->dev->stats;
-@@ -799,9 +848,17 @@
+@@ -799,9 +850,17 @@
                        tdev = rt->u.dst.dev;
                        ip_rt_put(rt);
                }
@@ -1837,7 +1853,7 @@ diff -Nurb linux-2.6.27-660/net/ipv4/ip_gre.c linux-2.6.27-700/net/ipv4/ip_gre.c
        if (!tdev && tunnel->parms.link)
                tdev = __dev_get_by_index(dev_net(dev), tunnel->parms.link);
  
-@@ -822,10 +879,234 @@
+@@ -822,10 +881,234 @@
        }
        dev->hard_header_len = hlen + addend;
        dev->mtu = mtu - addend;
@@ -1850,7 +1866,7 @@ diff -Nurb linux-2.6.27-660/net/ipv4/ip_gre.c linux-2.6.27-700/net/ipv4/ip_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;
@@ -1888,14 +1904,14 @@ diff -Nurb linux-2.6.27-660/net/ipv4/ip_gre.c linux-2.6.27-700/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;
 +              }
@@ -2072,7 +2088,7 @@ diff -Nurb linux-2.6.27-660/net/ipv4/ip_gre.c linux-2.6.27-700/net/ipv4/ip_gre.c
  static int
  ipgre_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
  {
-@@ -876,6 +1157,7 @@
+@@ -876,6 +1159,7 @@
                        p.o_key = 0;
  
                t = ipgre_tunnel_locate(net, &p, cmd == SIOCADDTUNNEL);
@@ -2080,7 +2096,7 @@ diff -Nurb linux-2.6.27-660/net/ipv4/ip_gre.c linux-2.6.27-700/net/ipv4/ip_gre.c
  
                if (dev != ign->fb_tunnel_dev && cmd == SIOCCHGTUNNEL) {
                        if (t != NULL) {
-@@ -893,6 +1175,12 @@
+@@ -893,6 +1177,12 @@
                                else if (p.iph.daddr)
                                        nflags = IFF_POINTOPOINT;
  
@@ -2093,7 +2109,7 @@ diff -Nurb linux-2.6.27-660/net/ipv4/ip_gre.c linux-2.6.27-700/net/ipv4/ip_gre.c
                                if ((dev->flags^nflags)&(IFF_POINTOPOINT|IFF_BROADCAST)) {
                                        err = -EINVAL;
                                        break;
-@@ -902,8 +1190,13 @@
+@@ -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;
@@ -2107,7 +2123,7 @@ diff -Nurb linux-2.6.27-660/net/ipv4/ip_gre.c linux-2.6.27-700/net/ipv4/ip_gre.c
                                ipgre_tunnel_link(ign, t);
                                netdev_state_change(dev);
                        }
-@@ -1076,13 +1369,13 @@
+@@ -1076,13 +1371,13 @@
  
  #endif
  
@@ -2123,14 +2139,14 @@ diff -Nurb linux-2.6.27-660/net/ipv4/ip_gre.c linux-2.6.27-700/net/ipv4/ip_gre.c
  
        dev->type               = ARPHRD_IPGRE;
        dev->hard_header_len    = LL_MAX_HEADER + sizeof(struct iphdr) + 4;
-@@ -1093,6 +1386,35 @@
+@@ -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);
@@ -2138,7 +2154,7 @@ diff -Nurb linux-2.6.27-660/net/ipv4/ip_gre.c linux-2.6.27-700/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;
 +
@@ -2146,6 +2162,7 @@ diff -Nurb linux-2.6.27-660/net/ipv4/ip_gre.c linux-2.6.27-700/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);
 +
@@ -2159,7 +2176,7 @@ diff -Nurb linux-2.6.27-660/net/ipv4/ip_gre.c linux-2.6.27-700/net/ipv4/ip_gre.c
  static int ipgre_tunnel_init(struct net_device *dev)
  {
        struct ip_tunnel *tunnel;
-@@ -1104,8 +1426,10 @@
+@@ -1104,8 +1429,10 @@
        tunnel->dev = dev;
        strcpy(tunnel->parms.name, dev->name);
  
@@ -2170,7 +2187,7 @@ diff -Nurb linux-2.6.27-660/net/ipv4/ip_gre.c linux-2.6.27-700/net/ipv4/ip_gre.c
  
        ipgre_tunnel_bind_dev(dev);
  
-@@ -1181,7 +1505,7 @@
+@@ -1181,7 +1508,7 @@
                goto err_assign;
  
        ign->fb_tunnel_dev = alloc_netdev(sizeof(struct ip_tunnel), "gre0",