xfrm: remove gso_segment indirection from xfrm_mode
authorFlorian Westphal <fw@strlen.de>
Fri, 29 Mar 2019 20:16:27 +0000 (21:16 +0100)
committerSteffen Klassert <steffen.klassert@secunet.com>
Mon, 8 Apr 2019 07:14:47 +0000 (09:14 +0200)
These functions are small and we only have versions for tunnel
and transport mode for ipv4 and ipv6 respectively.

Just place the 'transport or tunnel' conditional in the protocol
specific function instead of using an indirection.

Before:
    3226       12       0     3238   net/ipv4/esp4_offload.o
    7004      492       0     7496   net/ipv4/ip_vti.o
    3339       12       0     3351   net/ipv6/esp6_offload.o
   11294      460       0    11754   net/ipv6/ip6_vti.o
    1180       72       0     1252   net/ipv4/xfrm4_mode_beet.o
     428       48       0      476   net/ipv4/xfrm4_mode_transport.o
    1271       48       0     1319   net/ipv4/xfrm4_mode_tunnel.o
    1083       60       0     1143   net/ipv6/xfrm6_mode_beet.o
     172       48       0      220   net/ipv6/xfrm6_mode_ro.o
     429       48       0      477   net/ipv6/xfrm6_mode_transport.o
    1164       48       0     1212   net/ipv6/xfrm6_mode_tunnel.o
15730428  6937008 4046908 26714344   vmlinux

After:
    3461       12       0     3473   net/ipv4/esp4_offload.o
    7000      492       0     7492   net/ipv4/ip_vti.o
    3574       12       0     3586   net/ipv6/esp6_offload.o
   11295      460       0    11755   net/ipv6/ip6_vti.o
    1180       64       0     1244   net/ipv4/xfrm4_mode_beet.o
     171       40       0      211   net/ipv4/xfrm4_mode_transport.o
    1163       40       0     1203   net/ipv4/xfrm4_mode_tunnel.o
    1083       52       0     1135   net/ipv6/xfrm6_mode_beet.o
     172       40       0      212   net/ipv6/xfrm6_mode_ro.o
     172       40       0      212   net/ipv6/xfrm6_mode_transport.o
    1056       40       0     1096   net/ipv6/xfrm6_mode_tunnel.o
15730424  6937008 4046908 26714340   vmlinux

Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
include/net/xfrm.h
net/ipv4/esp4_offload.c
net/ipv4/xfrm4_mode_transport.c
net/ipv4/xfrm4_mode_tunnel.c
net/ipv6/esp6_offload.c
net/ipv6/xfrm6_mode_transport.c
net/ipv6/xfrm6_mode_tunnel.c

index 07966a2..de103a6 100644 (file)
@@ -449,11 +449,6 @@ struct xfrm_mode {
         */
        int (*output2)(struct xfrm_state *x,struct sk_buff *skb);
 
-       /*
-        * Adjust pointers into the packet and do GSO segmentation.
-        */
-       struct sk_buff *(*gso_segment)(struct xfrm_state *x, struct sk_buff *skb, netdev_features_t features);
-
        struct xfrm_state_afinfo *afinfo;
        struct module *owner;
        u8 encap;
index c6c84f2..74d59e0 100644 (file)
@@ -107,6 +107,44 @@ static void esp4_gso_encap(struct xfrm_state *x, struct sk_buff *skb)
        xo->proto = proto;
 }
 
+static struct sk_buff *xfrm4_tunnel_gso_segment(struct xfrm_state *x,
+                                               struct sk_buff *skb,
+                                               netdev_features_t features)
+{
+       __skb_push(skb, skb->mac_len);
+       return skb_mac_gso_segment(skb, features);
+}
+
+static struct sk_buff *xfrm4_transport_gso_segment(struct xfrm_state *x,
+                                                  struct sk_buff *skb,
+                                                  netdev_features_t features)
+{
+       const struct net_offload *ops;
+       struct sk_buff *segs = ERR_PTR(-EINVAL);
+       struct xfrm_offload *xo = xfrm_offload(skb);
+
+       skb->transport_header += x->props.header_len;
+       ops = rcu_dereference(inet_offloads[xo->proto]);
+       if (likely(ops && ops->callbacks.gso_segment))
+               segs = ops->callbacks.gso_segment(skb, features);
+
+       return segs;
+}
+
+static struct sk_buff *xfrm4_outer_mode_gso_segment(struct xfrm_state *x,
+                                                   struct sk_buff *skb,
+                                                   netdev_features_t features)
+{
+       switch (x->outer_mode->encap) {
+       case XFRM_MODE_TUNNEL:
+               return xfrm4_tunnel_gso_segment(x, skb, features);
+       case XFRM_MODE_TRANSPORT:
+               return xfrm4_transport_gso_segment(x, skb, features);
+       }
+
+       return ERR_PTR(-EOPNOTSUPP);
+}
+
 static struct sk_buff *esp4_gso_segment(struct sk_buff *skb,
                                        netdev_features_t features)
 {
@@ -147,7 +185,7 @@ static struct sk_buff *esp4_gso_segment(struct sk_buff *skb,
 
        xo->flags |= XFRM_GSO_SEGMENT;
 
-       return x->outer_mode->gso_segment(x, skb, esp_features);
+       return xfrm4_outer_mode_gso_segment(x, skb, esp_features);
 }
 
 static int esp_input_tail(struct xfrm_state *x, struct sk_buff *skb)
index d4b34bb..397863e 100644 (file)
 #include <net/xfrm.h>
 #include <net/protocol.h>
 
-static struct sk_buff *xfrm4_transport_gso_segment(struct xfrm_state *x,
-                                                  struct sk_buff *skb,
-                                                  netdev_features_t features)
-{
-       const struct net_offload *ops;
-       struct sk_buff *segs = ERR_PTR(-EINVAL);
-       struct xfrm_offload *xo = xfrm_offload(skb);
-
-       skb->transport_header += x->props.header_len;
-       ops = rcu_dereference(inet_offloads[xo->proto]);
-       if (likely(ops && ops->callbacks.gso_segment))
-               segs = ops->callbacks.gso_segment(skb, features);
-
-       return segs;
-}
-
 static struct xfrm_mode xfrm4_transport_mode = {
-       .gso_segment = xfrm4_transport_gso_segment,
        .owner = THIS_MODULE,
        .encap = XFRM_MODE_TRANSPORT,
        .family = AF_INET,
index 8bd5112..b5d4ba4 100644 (file)
@@ -101,18 +101,9 @@ out:
        return err;
 }
 
-static struct sk_buff *xfrm4_mode_tunnel_gso_segment(struct xfrm_state *x,
-                                                    struct sk_buff *skb,
-                                                    netdev_features_t features)
-{
-       __skb_push(skb, skb->mac_len);
-       return skb_mac_gso_segment(skb, features);
-}
-
 static struct xfrm_mode xfrm4_tunnel_mode = {
        .input2 = xfrm4_mode_tunnel_input,
        .output2 = xfrm4_mode_tunnel_output,
-       .gso_segment = xfrm4_mode_tunnel_gso_segment,
        .owner = THIS_MODULE,
        .encap = XFRM_MODE_TUNNEL,
        .flags = XFRM_MODE_FLAG_TUNNEL,
index d46b4eb..c793a2a 100644 (file)
@@ -134,6 +134,44 @@ static void esp6_gso_encap(struct xfrm_state *x, struct sk_buff *skb)
        xo->proto = proto;
 }
 
+static struct sk_buff *xfrm6_tunnel_gso_segment(struct xfrm_state *x,
+                                               struct sk_buff *skb,
+                                               netdev_features_t features)
+{
+       __skb_push(skb, skb->mac_len);
+       return skb_mac_gso_segment(skb, features);
+}
+
+static struct sk_buff *xfrm6_transport_gso_segment(struct xfrm_state *x,
+                                                  struct sk_buff *skb,
+                                                  netdev_features_t features)
+{
+       const struct net_offload *ops;
+       struct sk_buff *segs = ERR_PTR(-EINVAL);
+       struct xfrm_offload *xo = xfrm_offload(skb);
+
+       skb->transport_header += x->props.header_len;
+       ops = rcu_dereference(inet6_offloads[xo->proto]);
+       if (likely(ops && ops->callbacks.gso_segment))
+               segs = ops->callbacks.gso_segment(skb, features);
+
+       return segs;
+}
+
+static struct sk_buff *xfrm6_outer_mode_gso_segment(struct xfrm_state *x,
+                                                   struct sk_buff *skb,
+                                                   netdev_features_t features)
+{
+       switch (x->outer_mode->encap) {
+       case XFRM_MODE_TUNNEL:
+               return xfrm6_tunnel_gso_segment(x, skb, features);
+       case XFRM_MODE_TRANSPORT:
+               return xfrm6_transport_gso_segment(x, skb, features);
+       }
+
+       return ERR_PTR(-EOPNOTSUPP);
+}
+
 static struct sk_buff *esp6_gso_segment(struct sk_buff *skb,
                                        netdev_features_t features)
 {
@@ -172,7 +210,7 @@ static struct sk_buff *esp6_gso_segment(struct sk_buff *skb,
 
        xo->flags |= XFRM_GSO_SEGMENT;
 
-       return x->outer_mode->gso_segment(x, skb, esp_features);
+       return xfrm6_outer_mode_gso_segment(x, skb, esp_features);
 }
 
 static int esp6_input_tail(struct xfrm_state *x, struct sk_buff *skb)
index 6a72ff3..d90c934 100644 (file)
 #include <net/xfrm.h>
 #include <net/protocol.h>
 
-static struct sk_buff *xfrm4_transport_gso_segment(struct xfrm_state *x,
-                                                  struct sk_buff *skb,
-                                                  netdev_features_t features)
-{
-       const struct net_offload *ops;
-       struct sk_buff *segs = ERR_PTR(-EINVAL);
-       struct xfrm_offload *xo = xfrm_offload(skb);
-
-       skb->transport_header += x->props.header_len;
-       ops = rcu_dereference(inet6_offloads[xo->proto]);
-       if (likely(ops && ops->callbacks.gso_segment))
-               segs = ops->callbacks.gso_segment(skb, features);
-
-       return segs;
-}
-
 static struct xfrm_mode xfrm6_transport_mode = {
-       .gso_segment = xfrm4_transport_gso_segment,
        .owner = THIS_MODULE,
        .encap = XFRM_MODE_TRANSPORT,
        .family = AF_INET6,
index 7450dd8..8e23a2f 100644 (file)
@@ -101,18 +101,10 @@ out:
        return err;
 }
 
-static struct sk_buff *xfrm6_mode_tunnel_gso_segment(struct xfrm_state *x,
-                                                    struct sk_buff *skb,
-                                                    netdev_features_t features)
-{
-       __skb_push(skb, skb->mac_len);
-       return skb_mac_gso_segment(skb, features);
-}
 
 static struct xfrm_mode xfrm6_tunnel_mode = {
        .input2 = xfrm6_mode_tunnel_input,
        .output2 = xfrm6_mode_tunnel_output,
-       .gso_segment = xfrm6_mode_tunnel_gso_segment,
        .owner = THIS_MODULE,
        .encap = XFRM_MODE_TUNNEL,
        .flags = XFRM_MODE_FLAG_TUNNEL,