Skip to content

Commit 7aa5d31

Browse files
josh8551021vijay-suman
authored andcommitted
gve: ignore nonrelevant GSO type bits when processing TSO headers
[ Upstream commit 1b9f756 ] TSO currently fails when the skb's gso_type field has more than one bit set. TSO packets can be passed from userspace using PF_PACKET, TUNTAP and a few others, using virtio_net_hdr (e.g., PACKET_VNET_HDR). This includes virtualization, such as QEMU, a real use-case. The gso_type and gso_size fields as passed from userspace in virtio_net_hdr are not trusted blindly by the kernel. It adds gso_type |= SKB_GSO_DODGY to force the packet to enter the software GSO stack for verification. This issue might similarly come up when the CWR bit is set in the TCP header for congestion control, causing the SKB_GSO_TCP_ECN gso_type bit to be set. Fixes: a57e5de ("gve: DQO: Add TX path") Signed-off-by: Joshua Washington <[email protected]> Reviewed-by: Praveen Kaligineedi <[email protected]> Reviewed-by: Harshitha Ramamurthy <[email protected]> Reviewed-by: Willem de Bruijn <[email protected]> Suggested-by: Eric Dumazet <[email protected]> Acked-by: Andrei Vagin <[email protected]> v2 - Remove unnecessary comments, remove line break between fixes tag and signoffs. v3 - Add back unrelated empty line removal. Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]> Signed-off-by: Sasha Levin <[email protected]> (cherry picked from commit c495ebe90b5b7804f016f9e40a8c2fd8f5307d12) Orabug: 37356729 Signed-off-by: Yifei Liu <[email protected]> Reviewed-by: Saeed Mirzamohammadi <[email protected]> Signed-off-by: Saeed Mirzamohammadi <[email protected]> Signed-off-by: Vijayendra Suman <[email protected]>
1 parent 4017fb9 commit 7aa5d31

File tree

1 file changed

+5
-15
lines changed

1 file changed

+5
-15
lines changed

drivers/net/ethernet/google/gve/gve_tx_dqo.c

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -501,28 +501,18 @@ static int gve_prep_tso(struct sk_buff *skb)
501501
if (unlikely(skb_shinfo(skb)->gso_size < GVE_TX_MIN_TSO_MSS_DQO))
502502
return -1;
503503

504+
if (!(skb_shinfo(skb)->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)))
505+
return -EINVAL;
506+
504507
/* Needed because we will modify header. */
505508
err = skb_cow_head(skb, 0);
506509
if (err < 0)
507510
return err;
508511

509512
tcp = tcp_hdr(skb);
510-
511-
/* Remove payload length from checksum. */
512513
paylen = skb->len - skb_transport_offset(skb);
513-
514-
switch (skb_shinfo(skb)->gso_type) {
515-
case SKB_GSO_TCPV4:
516-
case SKB_GSO_TCPV6:
517-
csum_replace_by_diff(&tcp->check,
518-
(__force __wsum)htonl(paylen));
519-
520-
/* Compute length of segmentation header. */
521-
header_len = skb_tcp_all_headers(skb);
522-
break;
523-
default:
524-
return -EINVAL;
525-
}
514+
csum_replace_by_diff(&tcp->check, (__force __wsum)htonl(paylen));
515+
header_len = skb_tcp_all_headers(skb);
526516

527517
if (unlikely(header_len > GVE_TX_MAX_HDR_SIZE_DQO))
528518
return -EINVAL;

0 commit comments

Comments
 (0)