Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

xfrm: Set transport header to fix UDP GRO handling

The referenced commit replaced a call to __xfrm4|6_udp_encap_rcv() with
a custom check for non-ESP markers. But what the called function also
did was setting the transport header to the ESP header. The function
that follows, esp4|6_gro_receive(), relies on that being set when it calls
xfrm_parse_spi(). We have to set the full offset as the skb's head was
not moved yet so adding just the UDP header length won't work.

Fixes: e3fd05777685 ("xfrm: Fix UDP GRO handling for some corner cases")
Signed-off-by: Tobias Brunner <tobias@strongswan.org>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>

authored by

Tobias Brunner and committed by
Steffen Klassert
3ac9e292 c0f21029

+6
+3
net/ipv4/xfrm4_input.c
··· 202 202 if (len <= sizeof(struct ip_esp_hdr) || udpdata32[0] == 0) 203 203 goto out; 204 204 205 + /* set the transport header to ESP */ 206 + skb_set_transport_header(skb, offset); 207 + 205 208 NAPI_GRO_CB(skb)->proto = IPPROTO_UDP; 206 209 207 210 pp = call_gro_receive(ops->callbacks.gro_receive, head, skb);
+3
net/ipv6/xfrm6_input.c
··· 202 202 if (len <= sizeof(struct ip_esp_hdr) || udpdata32[0] == 0) 203 203 goto out; 204 204 205 + /* set the transport header to ESP */ 206 + skb_set_transport_header(skb, offset); 207 + 205 208 NAPI_GRO_CB(skb)->proto = IPPROTO_UDP; 206 209 207 210 pp = call_gro_receive(ops->callbacks.gro_receive, head, skb);