提交 bfc0698b 编写于 作者: S Sowmini Varadhan 提交者: Steffen Klassert

xfrm: reset transport header back to network header after all input transforms ahave been applied

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: 7785bba2 ("esp: Add a software GRO codepath")
Suggested-by: NSteffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: NSowmini Varadhan <sowmini.varadhan@oracle.com>
Signed-off-by: NSteffen Klassert <steffen.klassert@secunet.com>
上级 215ab0f0
...@@ -67,6 +67,7 @@ int xfrm4_transport_finish(struct sk_buff *skb, int async) ...@@ -67,6 +67,7 @@ int xfrm4_transport_finish(struct sk_buff *skb, int async)
if (xo && (xo->flags & XFRM_GRO)) { if (xo && (xo->flags & XFRM_GRO)) {
skb_mac_header_rebuild(skb); skb_mac_header_rebuild(skb);
skb_reset_transport_header(skb);
return 0; return 0;
} }
......
...@@ -46,7 +46,6 @@ static int xfrm4_transport_output(struct xfrm_state *x, struct sk_buff *skb) ...@@ -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) static int xfrm4_transport_input(struct xfrm_state *x, struct sk_buff *skb)
{ {
int ihl = skb->data - skb_transport_header(skb); int ihl = skb->data - skb_transport_header(skb);
struct xfrm_offload *xo = xfrm_offload(skb);
if (skb->transport_header != skb->network_header) { if (skb->transport_header != skb->network_header) {
memmove(skb_transport_header(skb), memmove(skb_transport_header(skb),
...@@ -54,8 +53,7 @@ static int xfrm4_transport_input(struct xfrm_state *x, struct sk_buff *skb) ...@@ -54,8 +53,7 @@ static int xfrm4_transport_input(struct xfrm_state *x, struct sk_buff *skb)
skb->network_header = skb->transport_header; skb->network_header = skb->transport_header;
} }
ip_hdr(skb)->tot_len = htons(skb->len + ihl); 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; return 0;
} }
......
...@@ -59,6 +59,7 @@ int xfrm6_transport_finish(struct sk_buff *skb, int async) ...@@ -59,6 +59,7 @@ int xfrm6_transport_finish(struct sk_buff *skb, int async)
if (xo && (xo->flags & XFRM_GRO)) { if (xo && (xo->flags & XFRM_GRO)) {
skb_mac_header_rebuild(skb); skb_mac_header_rebuild(skb);
skb_reset_transport_header(skb);
return -1; return -1;
} }
......
...@@ -51,7 +51,6 @@ static int xfrm6_transport_output(struct xfrm_state *x, struct sk_buff *skb) ...@@ -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) static int xfrm6_transport_input(struct xfrm_state *x, struct sk_buff *skb)
{ {
int ihl = skb->data - skb_transport_header(skb); int ihl = skb->data - skb_transport_header(skb);
struct xfrm_offload *xo = xfrm_offload(skb);
if (skb->transport_header != skb->network_header) { if (skb->transport_header != skb->network_header) {
memmove(skb_transport_header(skb), memmove(skb_transport_header(skb),
...@@ -60,8 +59,7 @@ static int xfrm6_transport_input(struct xfrm_state *x, struct sk_buff *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 - ipv6_hdr(skb)->payload_len = htons(skb->len + ihl -
sizeof(struct ipv6hdr)); sizeof(struct ipv6hdr));
if (!xo || !(xo->flags & XFRM_GRO)) skb_reset_transport_header(skb);
skb_reset_transport_header(skb);
return 0; return 0;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册