udp: pass udp_offload struct to UDP gro callbacks
authorTom Herbert <therbert@google.com>
Tue, 13 Jan 2015 01:00:37 +0000 (17:00 -0800)
committerDavid S. Miller <davem@davemloft.net>
Wed, 14 Jan 2015 20:20:04 +0000 (15:20 -0500)
This patch introduces udp_offload_callbacks which has the same
GRO functions (but not a GSO function) as offload_callbacks,
except there is an argument to a udp_offload struct passed to
gro_receive and gro_complete functions. This additional argument
can be used to retrieve the per port structure of the encapsulation
for use in gro processing (mostly by doing container_of on the
structure).

Signed-off-by: Tom Herbert <therbert@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/vxlan.c
include/linux/netdevice.h
net/ipv4/fou.c
net/ipv4/geneve.c
net/ipv4/udp_offload.c

index 985359d..5c56a3f 100644 (file)
@@ -539,7 +539,9 @@ static int vxlan_fdb_append(struct vxlan_fdb *f,
        return 1;
 }
 
-static struct sk_buff **vxlan_gro_receive(struct sk_buff **head, struct sk_buff *skb)
+static struct sk_buff **vxlan_gro_receive(struct sk_buff **head,
+                                         struct sk_buff *skb,
+                                         struct udp_offload *uoff)
 {
        struct sk_buff *p, **pp = NULL;
        struct vxlanhdr *vh, *vh2;
@@ -578,7 +580,8 @@ out:
        return pp;
 }
 
-static int vxlan_gro_complete(struct sk_buff *skb, int nhoff)
+static int vxlan_gro_complete(struct sk_buff *skb, int nhoff,
+                             struct udp_offload *uoff)
 {
        udp_tunnel_gro_complete(skb, nhoff);
 
index 679e6e9..47921c2 100644 (file)
@@ -1969,7 +1969,7 @@ struct offload_callbacks {
        struct sk_buff          *(*gso_segment)(struct sk_buff *skb,
                                                netdev_features_t features);
        struct sk_buff          **(*gro_receive)(struct sk_buff **head,
-                                              struct sk_buff *skb);
+                                                struct sk_buff *skb);
        int                     (*gro_complete)(struct sk_buff *skb, int nhoff);
 };
 
@@ -1979,10 +1979,21 @@ struct packet_offload {
        struct list_head         list;
 };
 
+struct udp_offload;
+
+struct udp_offload_callbacks {
+       struct sk_buff          **(*gro_receive)(struct sk_buff **head,
+                                                struct sk_buff *skb,
+                                                struct udp_offload *uoff);
+       int                     (*gro_complete)(struct sk_buff *skb,
+                                               int nhoff,
+                                               struct udp_offload *uoff);
+};
+
 struct udp_offload {
        __be16                   port;
        u8                       ipproto;
-       struct offload_callbacks callbacks;
+       struct udp_offload_callbacks callbacks;
 };
 
 /* often modified stats are per cpu, other are shared (netdev->stats) */
index 2197c36..3bc0cf0 100644 (file)
@@ -174,7 +174,8 @@ drop:
 }
 
 static struct sk_buff **fou_gro_receive(struct sk_buff **head,
-                                       struct sk_buff *skb)
+                                       struct sk_buff *skb,
+                                       struct udp_offload *uoff)
 {
        const struct net_offload *ops;
        struct sk_buff **pp = NULL;
@@ -195,7 +196,8 @@ out_unlock:
        return pp;
 }
 
-static int fou_gro_complete(struct sk_buff *skb, int nhoff)
+static int fou_gro_complete(struct sk_buff *skb, int nhoff,
+                           struct udp_offload *uoff)
 {
        const struct net_offload *ops;
        u8 proto = NAPI_GRO_CB(skb)->proto;
@@ -254,7 +256,8 @@ static struct guehdr *gue_gro_remcsum(struct sk_buff *skb, unsigned int off,
 }
 
 static struct sk_buff **gue_gro_receive(struct sk_buff **head,
-                                       struct sk_buff *skb)
+                                       struct sk_buff *skb,
+                                       struct udp_offload *uoff)
 {
        const struct net_offload **offloads;
        const struct net_offload *ops;
@@ -360,7 +363,8 @@ out:
        return pp;
 }
 
-static int gue_gro_complete(struct sk_buff *skb, int nhoff)
+static int gue_gro_complete(struct sk_buff *skb, int nhoff,
+                           struct udp_offload *uoff)
 {
        const struct net_offload **offloads;
        struct guehdr *guehdr = (struct guehdr *)(skb->data + nhoff);
index 23744c7..9568594 100644 (file)
@@ -147,7 +147,8 @@ static int geneve_hlen(struct genevehdr *gh)
 }
 
 static struct sk_buff **geneve_gro_receive(struct sk_buff **head,
-                                          struct sk_buff *skb)
+                                          struct sk_buff *skb,
+                                          struct udp_offload *uoff)
 {
        struct sk_buff *p, **pp = NULL;
        struct genevehdr *gh, *gh2;
@@ -211,7 +212,8 @@ out:
        return pp;
 }
 
-static int geneve_gro_complete(struct sk_buff *skb, int nhoff)
+static int geneve_gro_complete(struct sk_buff *skb, int nhoff,
+                              struct udp_offload *uoff)
 {
        struct genevehdr *gh;
        struct packet_offload *ptype;
index d3e537e..d10f6f4 100644 (file)
@@ -339,7 +339,8 @@ unflush:
        skb_gro_pull(skb, sizeof(struct udphdr)); /* pull encapsulating udp header */
        skb_gro_postpull_rcsum(skb, uh, sizeof(struct udphdr));
        NAPI_GRO_CB(skb)->proto = uo_priv->offload->ipproto;
-       pp = uo_priv->offload->callbacks.gro_receive(head, skb);
+       pp = uo_priv->offload->callbacks.gro_receive(head, skb,
+                                                    uo_priv->offload);
 
 out_unlock:
        rcu_read_unlock();
@@ -395,7 +396,9 @@ int udp_gro_complete(struct sk_buff *skb, int nhoff)
 
        if (uo_priv != NULL) {
                NAPI_GRO_CB(skb)->proto = uo_priv->offload->ipproto;
-               err = uo_priv->offload->callbacks.gro_complete(skb, nhoff + sizeof(struct udphdr));
+               err = uo_priv->offload->callbacks.gro_complete(skb,
+                               nhoff + sizeof(struct udphdr),
+                               uo_priv->offload);
        }
 
        rcu_read_unlock();