hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/include/linux/virtio_net.h
....@@ -103,10 +103,18 @@
103103 if (gso_type && skb->network_header) {
104104 struct flow_keys_basic keys;
105105
106
- if (!skb->protocol)
107
- virtio_net_hdr_set_proto(skb, hdr);
106
+ if (!skb->protocol) {
107
+ __be16 protocol = dev_parse_header_protocol(skb);
108
+
109
+ if (!protocol)
110
+ virtio_net_hdr_set_proto(skb, hdr);
111
+ else if (!virtio_net_hdr_match_proto(protocol, hdr->gso_type))
112
+ return -EINVAL;
113
+ else
114
+ skb->protocol = protocol;
115
+ }
108116 retry:
109
- if (!skb_flow_dissect_flow_keys_basic(skb, &keys,
117
+ if (!skb_flow_dissect_flow_keys_basic(NULL, skb, &keys,
110118 NULL, 0, 0, 0,
111119 0)) {
112120 /* UFO does not specify ipv4 or 6: try both */
....@@ -140,6 +148,10 @@
140148 if (gso_type & SKB_GSO_UDP)
141149 nh_off -= thlen;
142150
151
+ /* Kernel has a special handling for GSO_BY_FRAGS. */
152
+ if (gso_size == GSO_BY_FRAGS)
153
+ return -EINVAL;
154
+
143155 /* Too small packets are not really GSO ones. */
144156 if (skb->len - nh_off > gso_size) {
145157 shinfo->gso_size = gso_size;