]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
xfrm: reset transport header back to network header after all input transforms ahave...
authorSowmini Varadhan <sowmini.varadhan@oracle.com>
Mon, 3 Sep 2018 11:36:52 +0000 (04:36 -0700)
committerSteffen Klassert <steffen.klassert@secunet.com>
Tue, 4 Sep 2018 08:26:30 +0000 (10:26 +0200)
A policy may have been set up with multiple transforms (e.g., ESP
and ipcomp). In this situation, the ingress IPsec processing
iterates in xfrm_input() and applies each transform in turn,
processing the nexthdr to find any additional xfrm that may apply.

This patch resets the transport header back to network header
only after the last transformation so that subsequent xfrms
can find the correct transport header.

Fixes: 7785bba299a8 ("esp: Add a software GRO codepath")
Suggested-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Sowmini Varadhan <sowmini.varadhan@oracle.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
net/ipv4/xfrm4_input.c
net/ipv4/xfrm4_mode_transport.c
net/ipv6/xfrm6_input.c
net/ipv6/xfrm6_mode_transport.c

index bcfc00e88756dabb1f491d3d41137ccbc7ab1cbc..f8de2482a52923709ed58c401785a6ac60771932 100644 (file)
@@ -67,6 +67,7 @@ int xfrm4_transport_finish(struct sk_buff *skb, int async)
 
        if (xo && (xo->flags & XFRM_GRO)) {
                skb_mac_header_rebuild(skb);
+               skb_reset_transport_header(skb);
                return 0;
        }
 
index 3d36644890bb6d3b0a755c811c60e920ad5cd8b8..1ad2c2c4e250f84b1ad73020c727ea8b68b3e0d3 100644 (file)
@@ -46,7 +46,6 @@ static int xfrm4_transport_output(struct xfrm_state *x, struct sk_buff *skb)
 static int xfrm4_transport_input(struct xfrm_state *x, struct sk_buff *skb)
 {
        int ihl = skb->data - skb_transport_header(skb);
-       struct xfrm_offload *xo = xfrm_offload(skb);
 
        if (skb->transport_header != skb->network_header) {
                memmove(skb_transport_header(skb),
@@ -54,8 +53,7 @@ static int xfrm4_transport_input(struct xfrm_state *x, struct sk_buff *skb)
                skb->network_header = skb->transport_header;
        }
        ip_hdr(skb)->tot_len = htons(skb->len + ihl);
-       if (!xo || !(xo->flags & XFRM_GRO))
-               skb_reset_transport_header(skb);
+       skb_reset_transport_header(skb);
        return 0;
 }
 
index 841f4a07438e83502eadd6ec6c16a16d1de6aa55..9ef490dddcea23b82bd703217bfdde49dce41069 100644 (file)
@@ -59,6 +59,7 @@ int xfrm6_transport_finish(struct sk_buff *skb, int async)
 
        if (xo && (xo->flags & XFRM_GRO)) {
                skb_mac_header_rebuild(skb);
+               skb_reset_transport_header(skb);
                return -1;
        }
 
index 9ad07a91708ef7a1008d469766ab39b9b882883f..3c29da5defe6c357ff04ca4adead1a9fee208f08 100644 (file)
@@ -51,7 +51,6 @@ static int xfrm6_transport_output(struct xfrm_state *x, struct sk_buff *skb)
 static int xfrm6_transport_input(struct xfrm_state *x, struct sk_buff *skb)
 {
        int ihl = skb->data - skb_transport_header(skb);
-       struct xfrm_offload *xo = xfrm_offload(skb);
 
        if (skb->transport_header != skb->network_header) {
                memmove(skb_transport_header(skb),
@@ -60,8 +59,7 @@ static int xfrm6_transport_input(struct xfrm_state *x, struct sk_buff *skb)
        }
        ipv6_hdr(skb)->payload_len = htons(skb->len + ihl -
                                           sizeof(struct ipv6hdr));
-       if (!xo || !(xo->flags & XFRM_GRO))
-               skb_reset_transport_header(skb);
+       skb_reset_transport_header(skb);
        return 0;
 }