xfrm: remove input indirection from xfrm_mode
authorFlorian Westphal <fw@strlen.de>
Fri, 29 Mar 2019 20:16:24 +0000 (21:16 +0100)
committerSteffen Klassert <steffen.klassert@secunet.com>
Mon, 8 Apr 2019 07:14:21 +0000 (09:14 +0200)
No need for any indirection or abstraction here, both functions
are pretty much the same and quite small, they also have no external
dependencies.

xfrm_prepare_input can then be made static.

With allmodconfig build, size increase of vmlinux is 25 byte:

Before:
   text   data     bss     dec      filename
15730207  6936924 4046908 26714039  vmlinux

After:
15730208  6936948 4046908 26714064 vmlinux

v2: Fix INET_XFRM_MODE_TRANSPORT name in is-enabled test (Sabrina Dubroca)
    change copied comment to refer to transport and network header,
    not skb->{h,nh}, which don't exist anymore. (Sabrina)
    make xfrm_prepare_input static (Eyal Birger)

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/xfrm4_mode_beet.c
net/ipv4/xfrm4_mode_transport.c
net/ipv4/xfrm4_mode_tunnel.c
net/ipv6/xfrm6_mode_beet.c
net/ipv6/xfrm6_mode_transport.c
net/ipv6/xfrm6_mode_tunnel.c
net/xfrm/xfrm_input.c

index 9a15506..2c5fc9c 100644 (file)
@@ -436,16 +436,6 @@ struct xfrm_mode {
         */
        int (*input2)(struct xfrm_state *x, struct sk_buff *skb);
 
-       /*
-        * This is the actual input entry point.
-        *
-        * For transport mode and equivalent this would be identical to
-        * input2 (which does not need to be set).  While tunnel mode
-        * and equivalent would set this to the tunnel encapsulation function
-        * xfrm4_prepare_input that would in turn call input2.
-        */
-       int (*input)(struct xfrm_state *x, struct sk_buff *skb);
-
        /*
         * Add encapsulation header.
         *
@@ -1606,7 +1596,6 @@ int xfrm_init_replay(struct xfrm_state *x);
 int xfrm_state_mtu(struct xfrm_state *x, int mtu);
 int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload);
 int xfrm_init_state(struct xfrm_state *x);
-int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb);
 int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type);
 int xfrm_input_resume(struct sk_buff *skb, int nexthdr);
 int xfrm_trans_queue(struct sk_buff *skb,
index a2e3b52..264c4c9 100644 (file)
@@ -128,7 +128,6 @@ out:
 
 static struct xfrm_mode xfrm4_beet_mode = {
        .input2 = xfrm4_beet_input,
-       .input = xfrm_prepare_input,
        .output2 = xfrm4_beet_output,
        .output = xfrm4_prepare_output,
        .owner = THIS_MODULE,
index 7c5443f..c943d71 100644 (file)
@@ -35,28 +35,6 @@ static int xfrm4_transport_output(struct xfrm_state *x, struct sk_buff *skb)
        return 0;
 }
 
-/* Remove encapsulation header.
- *
- * The IP header will be moved over the top of the encapsulation header.
- *
- * On entry, skb->h shall point to where the IP header should be and skb->nh
- * shall be set to where the IP header currently is.  skb->data shall point
- * to the start of the payload.
- */
-static int xfrm4_transport_input(struct xfrm_state *x, struct sk_buff *skb)
-{
-       int ihl = skb->data - skb_transport_header(skb);
-
-       if (skb->transport_header != skb->network_header) {
-               memmove(skb_transport_header(skb),
-                       skb_network_header(skb), ihl);
-               skb->network_header = skb->transport_header;
-       }
-       ip_hdr(skb)->tot_len = htons(skb->len + ihl);
-       skb_reset_transport_header(skb);
-       return 0;
-}
-
 static struct sk_buff *xfrm4_transport_gso_segment(struct xfrm_state *x,
                                                   struct sk_buff *skb,
                                                   netdev_features_t features)
@@ -87,7 +65,6 @@ static void xfrm4_transport_xmit(struct xfrm_state *x, struct sk_buff *skb)
 }
 
 static struct xfrm_mode xfrm4_transport_mode = {
-       .input = xfrm4_transport_input,
        .output = xfrm4_transport_output,
        .gso_segment = xfrm4_transport_gso_segment,
        .xmit = xfrm4_transport_xmit,
index cfc6b6d..678b917 100644 (file)
@@ -123,7 +123,6 @@ static void xfrm4_mode_tunnel_xmit(struct xfrm_state *x, struct sk_buff *skb)
 
 static struct xfrm_mode xfrm4_tunnel_mode = {
        .input2 = xfrm4_mode_tunnel_input,
-       .input = xfrm_prepare_input,
        .output2 = xfrm4_mode_tunnel_output,
        .output = xfrm4_prepare_output,
        .gso_segment = xfrm4_mode_tunnel_gso_segment,
index 0d440e3..eadacad 100644 (file)
@@ -104,7 +104,6 @@ out:
 
 static struct xfrm_mode xfrm6_beet_mode = {
        .input2 = xfrm6_beet_input,
-       .input = xfrm_prepare_input,
        .output2 = xfrm6_beet_output,
        .output = xfrm6_prepare_output,
        .owner = THIS_MODULE,
index 66ae792..4c306bb 100644 (file)
@@ -40,29 +40,6 @@ static int xfrm6_transport_output(struct xfrm_state *x, struct sk_buff *skb)
        return 0;
 }
 
-/* Remove encapsulation header.
- *
- * The IP header will be moved over the top of the encapsulation header.
- *
- * On entry, skb->h shall point to where the IP header should be and skb->nh
- * shall be set to where the IP header currently is.  skb->data shall point
- * to the start of the payload.
- */
-static int xfrm6_transport_input(struct xfrm_state *x, struct sk_buff *skb)
-{
-       int ihl = skb->data - skb_transport_header(skb);
-
-       if (skb->transport_header != skb->network_header) {
-               memmove(skb_transport_header(skb),
-                       skb_network_header(skb), ihl);
-               skb->network_header = skb->transport_header;
-       }
-       ipv6_hdr(skb)->payload_len = htons(skb->len + ihl -
-                                          sizeof(struct ipv6hdr));
-       skb_reset_transport_header(skb);
-       return 0;
-}
-
 static struct sk_buff *xfrm4_transport_gso_segment(struct xfrm_state *x,
                                                   struct sk_buff *skb,
                                                   netdev_features_t features)
@@ -92,9 +69,7 @@ static void xfrm6_transport_xmit(struct xfrm_state *x, struct sk_buff *skb)
        }
 }
 
-
 static struct xfrm_mode xfrm6_transport_mode = {
-       .input = xfrm6_transport_input,
        .output = xfrm6_transport_output,
        .gso_segment = xfrm4_transport_gso_segment,
        .xmit = xfrm6_transport_xmit,
index 6cf12e9..1e9677f 100644 (file)
@@ -122,7 +122,6 @@ static void xfrm6_mode_tunnel_xmit(struct xfrm_state *x, struct sk_buff *skb)
 
 static struct xfrm_mode xfrm6_tunnel_mode = {
        .input2 = xfrm6_mode_tunnel_input,
-       .input = xfrm_prepare_input,
        .output2 = xfrm6_mode_tunnel_output,
        .output = xfrm6_prepare_output,
        .gso_segment = xfrm6_mode_tunnel_gso_segment,
index ea5ac05..0edf3fb 100644 (file)
@@ -166,7 +166,7 @@ int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq)
 }
 EXPORT_SYMBOL(xfrm_parse_spi);
 
-int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb)
+static int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb)
 {
        struct xfrm_mode *inner_mode = x->inner_mode;
        int err;
@@ -184,7 +184,76 @@ int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb)
        skb->protocol = inner_mode->afinfo->eth_proto;
        return inner_mode->input2(x, skb);
 }
-EXPORT_SYMBOL(xfrm_prepare_input);
+
+/* Remove encapsulation header.
+ *
+ * The IP header will be moved over the top of the encapsulation header.
+ *
+ * On entry, skb_transport_header() shall point to where the IP header
+ * should be and skb_network_header() shall be set to where the IP header
+ * currently is.  skb->data shall point to the start of the payload.
+ */
+static int xfrm4_transport_input(struct xfrm_state *x, struct sk_buff *skb)
+{
+#if IS_ENABLED(CONFIG_INET_XFRM_MODE_TRANSPORT)
+       int ihl = skb->data - skb_transport_header(skb);
+
+       if (skb->transport_header != skb->network_header) {
+               memmove(skb_transport_header(skb),
+                       skb_network_header(skb), ihl);
+               skb->network_header = skb->transport_header;
+       }
+       ip_hdr(skb)->tot_len = htons(skb->len + ihl);
+       skb_reset_transport_header(skb);
+       return 0;
+#else
+       return -EOPNOTSUPP;
+#endif
+}
+
+static int xfrm6_transport_input(struct xfrm_state *x, struct sk_buff *skb)
+{
+#if IS_ENABLED(CONFIG_INET6_XFRM_MODE_TRANSPORT)
+       int ihl = skb->data - skb_transport_header(skb);
+
+       if (skb->transport_header != skb->network_header) {
+               memmove(skb_transport_header(skb),
+                       skb_network_header(skb), ihl);
+               skb->network_header = skb->transport_header;
+       }
+       ipv6_hdr(skb)->payload_len = htons(skb->len + ihl -
+                                          sizeof(struct ipv6hdr));
+       skb_reset_transport_header(skb);
+       return 0;
+#else
+       return -EOPNOTSUPP;
+#endif
+}
+
+static int xfrm_inner_mode_input(struct xfrm_state *x,
+                                const struct xfrm_mode *inner_mode,
+                                struct sk_buff *skb)
+{
+       switch (inner_mode->encap) {
+       case XFRM_MODE_BEET:
+       case XFRM_MODE_TUNNEL:
+               return xfrm_prepare_input(x, skb);
+       case XFRM_MODE_TRANSPORT:
+               if (inner_mode->family == AF_INET)
+                       return xfrm4_transport_input(x, skb);
+               if (inner_mode->family == AF_INET6)
+                       return xfrm6_transport_input(x, skb);
+               break;
+       case XFRM_MODE_ROUTEOPTIMIZATION:
+               WARN_ON_ONCE(1);
+               break;
+       default:
+               WARN_ON_ONCE(1);
+               break;
+       }
+
+       return -EOPNOTSUPP;
+}
 
 int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 {
@@ -410,7 +479,7 @@ resume:
                        }
                }
 
-               if (inner_mode->input(x, skb)) {
+               if (xfrm_inner_mode_input(x, inner_mode, skb)) {
                        XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEMODEERROR);
                        goto drop;
                }