diff options
author | Eric Dumazet <edumazet@google.com> | 2012-09-27 02:48:50 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-10-01 17:01:57 -0400 |
commit | 60769a5dcd8755715c7143b4571d5c44f01796f1 (patch) | |
tree | 913951cd23fa8aaaac5de4585484becaaead41ff | |
parent | c9e6bc644e557338221e75c242ab12c275a67d1b (diff) |
ipv4: gre: add GRO capability
Add GRO capability to IPv4 GRE tunnels, using the gro_cells
infrastructure.
Tested using IPv4 and IPv6 TCP traffic inside this tunnel, and
checking GRO is building large packets.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/net/ipip.h | 3 | ||||
-rw-r--r-- | net/ipv4/ip_gre.c | 13 |
2 files changed, 14 insertions, 2 deletions
diff --git a/include/net/ipip.h b/include/net/ipip.h index a93cf6d7e94b..ddc077c51f32 100644 --- a/include/net/ipip.h +++ b/include/net/ipip.h @@ -2,6 +2,7 @@ #define __NET_IPIP_H 1 #include <linux/if_tunnel.h> +#include <net/gro_cells.h> #include <net/ip.h> /* Keep error state on tunnel for 30 sec */ @@ -36,6 +37,8 @@ struct ip_tunnel { #endif struct ip_tunnel_prl_entry __rcu *prl; /* potential router list */ unsigned int prl_count; /* # of entries in PRL */ + + struct gro_cells gro_cells; }; struct ip_tunnel_prl_entry { diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index ef0b861ce044..b1871d993d22 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -740,8 +740,7 @@ static int ipgre_rcv(struct sk_buff *skb) tstats->rx_bytes += skb->len; u64_stats_update_end(&tstats->syncp); - netif_rx(skb); - + gro_cells_receive(&tunnel->gro_cells, skb); return 0; } icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); @@ -1319,6 +1318,9 @@ static const struct net_device_ops ipgre_netdev_ops = { static void ipgre_dev_free(struct net_device *dev) { + struct ip_tunnel *tunnel = netdev_priv(dev); + + gro_cells_destroy(&tunnel->gro_cells); free_percpu(dev->tstats); free_netdev(dev); } @@ -1350,6 +1352,7 @@ static int ipgre_tunnel_init(struct net_device *dev) { struct ip_tunnel *tunnel; struct iphdr *iph; + int err; tunnel = netdev_priv(dev); iph = &tunnel->parms.iph; @@ -1376,6 +1379,12 @@ static int ipgre_tunnel_init(struct net_device *dev) if (!dev->tstats) return -ENOMEM; + err = gro_cells_init(&tunnel->gro_cells, dev); + if (err) { + free_percpu(dev->tstats); + return err; + } + return 0; } |