mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-14 15:54:15 +08:00
xfrm: reset transport header back to network header after all input transforms ahave been applied
[ Upstream commitbfc0698beb
] 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:7785bba299
("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> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
2a55e64d5c
commit
a95d9004fb
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user