4.9-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Jason Wang <jasow...@redhat.com>


[ Upstream commit 6391a4481ba0796805d6581e42f9f0418c099e34 ]

Commit 501db511397f ("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.neugeba...@docker.com>
Signed-off-by: Jason Wang <jasow...@redhat.com>
Acked-by: Rolf Neugebauer <rolf.neugeba...@docker.com>
Signed-off-by: David S. Miller <da...@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
 drivers/net/macvtap.c      |    2 +-
 drivers/net/tun.c          |    2 +-
 drivers/net/virtio_net.c   |    2 +-
 include/linux/virtio_net.h |    6 +++++-
 net/packet/af_packet.c     |    2 +-
 5 files changed, 9 insertions(+), 5 deletions(-)

--- a/drivers/net/macvtap.c
+++ b/drivers/net/macvtap.c
@@ -827,7 +827,7 @@ static ssize_t macvtap_put_user(struct m
                        return -EINVAL;
 
                ret = virtio_net_hdr_from_skb(skb, &vnet_hdr,
-                                             macvtap_is_little_endian(q));
+                                             macvtap_is_little_endian(q), 
true);
                if (ret)
                        BUG();
 
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -1374,7 +1374,7 @@ static ssize_t tun_put_user(struct tun_s
                        return -EINVAL;
 
                ret = virtio_net_hdr_from_skb(skb, &gso,
-                                             tun_is_little_endian(tun));
+                                             tun_is_little_endian(tun), true);
                if (ret) {
                        struct skb_shared_info *sinfo = skb_shinfo(skb);
                        pr_err("unexpected GSO type: "
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -840,7 +840,7 @@ static int xmit_skb(struct send_queue *s
                hdr = skb_vnet_hdr(skb);
 
        if (virtio_net_hdr_from_skb(skb, &hdr->hdr,
-                                   virtio_is_little_endian(vi->vdev)))
+                                   virtio_is_little_endian(vi->vdev), false))
                BUG();
 
        if (vi->mergeable_rx_bufs)
--- a/include/linux/virtio_net.h
+++ b/include/linux/virtio_net.h
@@ -56,7 +56,8 @@ static inline int virtio_net_hdr_to_skb(
 
 static inline int virtio_net_hdr_from_skb(const struct sk_buff *skb,
                                          struct virtio_net_hdr *hdr,
-                                         bool little_endian)
+                                         bool little_endian,
+                                         bool has_data_valid)
 {
        memset(hdr, 0, sizeof(*hdr));
 
@@ -91,6 +92,9 @@ static inline int virtio_net_hdr_from_sk
                                skb_checksum_start_offset(skb));
                hdr->csum_offset = __cpu_to_virtio16(little_endian,
                                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 */
 
        return 0;
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1972,7 +1972,7 @@ static int __packet_rcv_vnet(const struc
 {
        *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();
 
        return 0;


Reply via email to