diff options
Diffstat (limited to 'include/linux/virtio_net.h')
| -rw-r--r-- | include/linux/virtio_net.h | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h index cb462f9ab7dd..e0348cb0a1dd 100644 --- a/include/linux/virtio_net.h +++ b/include/linux/virtio_net.h | |||
| @@ -57,6 +57,25 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb, | |||
| 57 | 57 | ||
| 58 | if (!skb_partial_csum_set(skb, start, off)) | 58 | if (!skb_partial_csum_set(skb, start, off)) |
| 59 | return -EINVAL; | 59 | return -EINVAL; |
| 60 | } else { | ||
| 61 | /* gso packets without NEEDS_CSUM do not set transport_offset. | ||
| 62 | * probe and drop if does not match one of the above types. | ||
| 63 | */ | ||
| 64 | if (gso_type && skb->network_header) { | ||
| 65 | if (!skb->protocol) | ||
| 66 | virtio_net_hdr_set_proto(skb, hdr); | ||
| 67 | retry: | ||
| 68 | skb_probe_transport_header(skb, -1); | ||
| 69 | if (!skb_transport_header_was_set(skb)) { | ||
| 70 | /* UFO does not specify ipv4 or 6: try both */ | ||
| 71 | if (gso_type & SKB_GSO_UDP && | ||
| 72 | skb->protocol == htons(ETH_P_IP)) { | ||
| 73 | skb->protocol = htons(ETH_P_IPV6); | ||
| 74 | goto retry; | ||
| 75 | } | ||
| 76 | return -EINVAL; | ||
| 77 | } | ||
| 78 | } | ||
| 60 | } | 79 | } |
| 61 | 80 | ||
| 62 | if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) { | 81 | if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) { |
