Merge branch 'r8152-autoresume'
[cascardo/linux.git] / drivers / net / geneve.c
index 3908a22..da3259c 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/etherdevice.h>
 #include <linux/hash.h>
 #include <net/dst_metadata.h>
+#include <net/gro_cells.h>
 #include <net/rtnetlink.h>
 #include <net/geneve.h>
 #include <net/protocol.h>
@@ -58,6 +59,7 @@ struct geneve_dev {
        struct list_head   next;        /* geneve's per namespace list */
        __be16             dst_port;
        bool               collect_md;
+       struct gro_cells   gro_cells;
 };
 
 struct geneve_sock {
@@ -141,7 +143,6 @@ static void geneve_rx(struct geneve_sock *gs, struct sk_buff *skb)
 
        if (ip_tunnel_collect_metadata() || gs->collect_md) {
                __be16 flags;
-               void *opts;
 
                flags = TUNNEL_KEY | TUNNEL_GENEVE_OPT |
                        (gnvh->oam ? TUNNEL_OAM : 0) |
@@ -152,11 +153,9 @@ static void geneve_rx(struct geneve_sock *gs, struct sk_buff *skb)
                                         gnvh->opt_len * 4);
                if (!tun_dst)
                        goto drop;
-
                /* Update tunnel dst according to Geneve options. */
-               opts = ip_tunnel_info_opts(&tun_dst->u.tun_info,
-                                          gnvh->opt_len * 4);
-               memcpy(opts, gnvh->options, gnvh->opt_len * 4);
+               ip_tunnel_info_opts_set(&tun_dst->u.tun_info,
+                                       gnvh->options, gnvh->opt_len * 4);
        } else {
                /* Drop packets w/ critical options,
                 * since we don't support any...
@@ -199,7 +198,7 @@ static void geneve_rx(struct geneve_sock *gs, struct sk_buff *skb)
        stats->rx_bytes += skb->len;
        u64_stats_update_end(&stats->syncp);
 
-       netif_rx(skb);
+       gro_cells_receive(&geneve->gro_cells, skb);
        return;
 drop:
        /* Consume bad packet */
@@ -209,14 +208,27 @@ drop:
 /* Setup stats when device is created */
 static int geneve_init(struct net_device *dev)
 {
+       struct geneve_dev *geneve = netdev_priv(dev);
+       int err;
+
        dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
        if (!dev->tstats)
                return -ENOMEM;
+
+       err = gro_cells_init(&geneve->gro_cells, dev);
+       if (err) {
+               free_percpu(dev->tstats);
+               return err;
+       }
+
        return 0;
 }
 
 static void geneve_uninit(struct net_device *dev)
 {
+       struct geneve_dev *geneve = netdev_priv(dev);
+
+       gro_cells_destroy(&geneve->gro_cells);
        free_percpu(dev->tstats);
 }
 
@@ -648,7 +660,7 @@ static netdev_tx_t geneve_xmit(struct sk_buff *skb, struct net_device *dev)
 
                tunnel_id_to_vni(key->tun_id, vni);
                if (key->tun_flags & TUNNEL_GENEVE_OPT)
-                       opts = ip_tunnel_info_opts(info, info->options_len);
+                       opts = ip_tunnel_info_opts(info);
 
                udp_csum = !!(key->tun_flags & TUNNEL_CSUM);
                err = geneve_build_skb(rt, skb, key->tun_flags, vni,