Commit 1e7cbb41 authored by Jason Wang's avatar Jason Wang Committed by Greg Kroah-Hartman

virtio-net: restore VIRTIO_HDR_F_DATA_VALID on receiving

[ Upstream commit 6391a448 ]

Commit 501db511 ("virtio: don't set VIRTIO_NET_HDR_F_DATA_VALID on
xmit") in fact disables VIRTIO_HDR_F_DATA_VALID on receiving path too,
fixing this by adding a hint (has_data_valid) and set it only on the
receiving path.

Cc: Rolf Neugebauer <rolf.neugebauer@docker.com>
Signed-off-by: default avatarJason Wang <jasowang@redhat.com>
Acked-by: default avatarRolf Neugebauer <rolf.neugebauer@docker.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 3eab5dd0
...@@ -827,7 +827,7 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q, ...@@ -827,7 +827,7 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q,
return -EINVAL; return -EINVAL;
ret = virtio_net_hdr_from_skb(skb, &vnet_hdr, ret = virtio_net_hdr_from_skb(skb, &vnet_hdr,
macvtap_is_little_endian(q)); macvtap_is_little_endian(q), true);
if (ret) if (ret)
BUG(); BUG();
......
...@@ -1374,7 +1374,7 @@ static ssize_t tun_put_user(struct tun_struct *tun, ...@@ -1374,7 +1374,7 @@ static ssize_t tun_put_user(struct tun_struct *tun,
return -EINVAL; return -EINVAL;
ret = virtio_net_hdr_from_skb(skb, &gso, ret = virtio_net_hdr_from_skb(skb, &gso,
tun_is_little_endian(tun)); tun_is_little_endian(tun), true);
if (ret) { if (ret) {
struct skb_shared_info *sinfo = skb_shinfo(skb); struct skb_shared_info *sinfo = skb_shinfo(skb);
pr_err("unexpected GSO type: " pr_err("unexpected GSO type: "
......
...@@ -840,7 +840,7 @@ static int xmit_skb(struct send_queue *sq, struct sk_buff *skb) ...@@ -840,7 +840,7 @@ static int xmit_skb(struct send_queue *sq, struct sk_buff *skb)
hdr = skb_vnet_hdr(skb); hdr = skb_vnet_hdr(skb);
if (virtio_net_hdr_from_skb(skb, &hdr->hdr, if (virtio_net_hdr_from_skb(skb, &hdr->hdr,
virtio_is_little_endian(vi->vdev))) virtio_is_little_endian(vi->vdev), false))
BUG(); BUG();
if (vi->mergeable_rx_bufs) if (vi->mergeable_rx_bufs)
......
...@@ -56,7 +56,8 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb, ...@@ -56,7 +56,8 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb,
static inline int virtio_net_hdr_from_skb(const struct sk_buff *skb, static inline int virtio_net_hdr_from_skb(const struct sk_buff *skb,
struct virtio_net_hdr *hdr, struct virtio_net_hdr *hdr,
bool little_endian) bool little_endian,
bool has_data_valid)
{ {
memset(hdr, 0, sizeof(*hdr)); memset(hdr, 0, sizeof(*hdr));
...@@ -91,6 +92,9 @@ static inline int virtio_net_hdr_from_skb(const struct sk_buff *skb, ...@@ -91,6 +92,9 @@ static inline int virtio_net_hdr_from_skb(const struct sk_buff *skb,
skb_checksum_start_offset(skb)); skb_checksum_start_offset(skb));
hdr->csum_offset = __cpu_to_virtio16(little_endian, hdr->csum_offset = __cpu_to_virtio16(little_endian,
skb->csum_offset); skb->csum_offset);
} else if (has_data_valid &&
skb->ip_summed == CHECKSUM_UNNECESSARY) {
hdr->flags = VIRTIO_NET_HDR_F_DATA_VALID;
} /* else everything is zero */ } /* else everything is zero */
return 0; return 0;
......
...@@ -1972,7 +1972,7 @@ static int __packet_rcv_vnet(const struct sk_buff *skb, ...@@ -1972,7 +1972,7 @@ static int __packet_rcv_vnet(const struct sk_buff *skb,
{ {
*vnet_hdr = (const struct virtio_net_hdr) { 0 }; *vnet_hdr = (const struct virtio_net_hdr) { 0 };
if (virtio_net_hdr_from_skb(skb, vnet_hdr, vio_le())) if (virtio_net_hdr_from_skb(skb, vnet_hdr, vio_le(), true))
BUG(); BUG();
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment