Juergen Gross c8c159
Patch-mainline: v5.16-rc7
Juergen Gross c8c159
Git-commit: 7e5cced9ca84df52d874aca6b632f930b3dc5bc6
Juergen Gross c8c159
References: git-fixes
Juergen Gross c8c159
From: Willem de Bruijn <willemb@google.com>
Juergen Gross c8c159
Date: Mon, 20 Dec 2021 09:49:01 -0500
Juergen Gross c8c159
Subject: [PATCH] net: accept UFOv6 packages in virtio_net_hdr_to_skb
Juergen Gross c8c159
Juergen Gross c8c159
Skb with skb->protocol 0 at the time of virtio_net_hdr_to_skb may have
Juergen Gross c8c159
a protocol inferred from virtio_net_hdr with virtio_net_hdr_set_proto.
Juergen Gross c8c159
Juergen Gross c8c159
Unlike TCP, UDP does not have separate types for IPv4 and IPv6. Type
Juergen Gross c8c159
VIRTIO_NET_HDR_GSO_UDP is guessed to be IPv4/UDP. As of the below
Juergen Gross c8c159
commit, UFOv6 packets are dropped due to not matching the protocol as
Juergen Gross c8c159
obtained from dev_parse_header_protocol.
Juergen Gross c8c159
Juergen Gross c8c159
Invert the test to take that L2 protocol field as starting point and
Juergen Gross c8c159
pass both UFOv4 and UFOv6 for VIRTIO_NET_HDR_GSO_UDP.
Juergen Gross c8c159
Juergen Gross c8c159
Fixes: 924a9bc362a5 ("net: check if protocol extracted by virtio_net_hdr_set_proto is correct")
Juergen Gross c8c159
Link: https://lore.kernel.org/netdev/CABcq3pG9GRCYqFDBAJ48H1vpnnX=41u+MhQnayF1ztLH4WX0Fw@mail.gmail.com/
Juergen Gross c8c159
Reported-by: Andrew Melnichenko <andrew@daynix.com>
Juergen Gross c8c159
Signed-off-by: Willem de Bruijn <willemb@google.com>
Juergen Gross c8c159
Link: https://lore.kernel.org/r/20211220144901.2784030-1-willemdebruijn.kernel@gmail.com
Juergen Gross c8c159
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Juergen Gross c8c159
Signed-off-by: Juergen Gross <jgross@suse.com>
Juergen Gross c8c159
---
Juergen Gross c8c159
 include/linux/virtio_net.h | 22 ++++++++++++++++++++--
Juergen Gross c8c159
 1 file changed, 20 insertions(+), 2 deletions(-)
Juergen Gross c8c159
Juergen Gross c8c159
diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h
Juergen Gross c8c159
index 04e87f4b9417..22dd48c82560 100644
Juergen Gross c8c159
--- a/include/linux/virtio_net.h
Juergen Gross c8c159
+++ b/include/linux/virtio_net.h
Juergen Gross c8c159
@@ -7,6 +7,21 @@
Juergen Gross c8c159
 #include <uapi/linux/udp.h>
Juergen Gross c8c159
 #include <uapi/linux/virtio_net.h>
Juergen Gross c8c159
 
Juergen Gross c8c159
+static inline bool virtio_net_hdr_match_proto(__be16 protocol, __u8 gso_type)
Juergen Gross c8c159
+{
Juergen Gross c8c159
+	switch (gso_type & ~VIRTIO_NET_HDR_GSO_ECN) {
Juergen Gross c8c159
+	case VIRTIO_NET_HDR_GSO_TCPV4:
Juergen Gross c8c159
+		return protocol == cpu_to_be16(ETH_P_IP);
Juergen Gross c8c159
+	case VIRTIO_NET_HDR_GSO_TCPV6:
Juergen Gross c8c159
+		return protocol == cpu_to_be16(ETH_P_IPV6);
Juergen Gross c8c159
+	case VIRTIO_NET_HDR_GSO_UDP:
Juergen Gross c8c159
+		return protocol == cpu_to_be16(ETH_P_IP) ||
Juergen Gross c8c159
+		       protocol == cpu_to_be16(ETH_P_IPV6);
Juergen Gross c8c159
+	default:
Juergen Gross c8c159
+		return false;
Juergen Gross c8c159
+	}
Juergen Gross c8c159
+}
Juergen Gross c8c159
+
Juergen Gross c8c159
 static inline int virtio_net_hdr_set_proto(struct sk_buff *skb,
Juergen Gross c8c159
 					   const struct virtio_net_hdr *hdr)
Juergen Gross c8c159
 {
Juergen Gross c8c159
@@ -88,9 +103,12 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb,
Juergen Gross c8c159
 			if (!skb->protocol) {
Juergen Gross c8c159
 				__be16 protocol = dev_parse_header_protocol(skb);
Juergen Gross c8c159
 
Juergen Gross c8c159
-				virtio_net_hdr_set_proto(skb, hdr);
Juergen Gross c8c159
-				if (protocol && protocol != skb->protocol)
Juergen Gross c8c159
+				if (!protocol)
Juergen Gross c8c159
+					virtio_net_hdr_set_proto(skb, hdr);
Juergen Gross c8c159
+				else if (!virtio_net_hdr_match_proto(protocol, hdr->gso_type))
Juergen Gross c8c159
 					return -EINVAL;
Juergen Gross c8c159
+				else
Juergen Gross c8c159
+					skb->protocol = protocol;
Juergen Gross c8c159
 			}
Juergen Gross c8c159
 retry:
Juergen Gross c8c159
 			if (!skb_flow_dissect_flow_keys_basic(NULL, skb, &keys,
Juergen Gross c8c159
-- 
Juergen Gross c8c159
2.35.3
Juergen Gross c8c159