X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=linux-2.6-700-egre.patch;h=e1fb5c88438ca17482288aa1e9c585effeb3d343;hb=refs%2Fheads%2F27;hp=1cac19d722978f47204e208d4286389bc5ae7d47;hpb=2ec0617d8f9b81119dd3b31d8da50c3c61483a4c;p=linux-2.6.git diff --git a/linux-2.6-700-egre.patch b/linux-2.6-700-egre.patch index 1cac19d72..e1fb5c884 100644 --- a/linux-2.6-700-egre.patch +++ b/linux-2.6-700-egre.patch @@ -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 +#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 #include @@ -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 #include #include -@@ -46,6 +47,8 @@ +@@ -48,6 +49,10 @@ #include #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;