Skip to content

Commit

Permalink
virtio-net: keep vnet header zeroed after processing XDP
Browse files Browse the repository at this point in the history
We copy vnet header unconditionally in page_to_skb() this is wrong
since XDP may modify the packet data. So let's keep a zeroed vnet
header for not confusing the conversion between vnet header and skb
metadata.

In the future, we should able to detect whether or not the packet was
modified and keep using the vnet header when packet was not touched.

Fixes: f600b69 ("virtio_net: Add XDP support")
Reported-by: Pavel Popa <pashinho1990@gmail.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Jason Wang authored and David S. Miller committed Dec 1, 2018
1 parent 9b2156f commit 436c945
Showing 1 changed file with 9 additions and 5 deletions.
14 changes: 9 additions & 5 deletions drivers/net/virtio_net.c
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,8 @@ static unsigned int mergeable_ctx_to_truesize(void *mrg_ctx)
static struct sk_buff *page_to_skb(struct virtnet_info *vi,
struct receive_queue *rq,
struct page *page, unsigned int offset,
unsigned int len, unsigned int truesize)
unsigned int len, unsigned int truesize,
bool hdr_valid)
{
struct sk_buff *skb;
struct virtio_net_hdr_mrg_rxbuf *hdr;
Expand All @@ -387,7 +388,8 @@ static struct sk_buff *page_to_skb(struct virtnet_info *vi,
else
hdr_padded_len = sizeof(struct padded_vnet_hdr);

memcpy(hdr, p, hdr_len);
if (hdr_valid)
memcpy(hdr, p, hdr_len);

len -= hdr_len;
offset += hdr_padded_len;
Expand Down Expand Up @@ -739,7 +741,8 @@ static struct sk_buff *receive_big(struct net_device *dev,
struct virtnet_rq_stats *stats)
{
struct page *page = buf;
struct sk_buff *skb = page_to_skb(vi, rq, page, 0, len, PAGE_SIZE);
struct sk_buff *skb = page_to_skb(vi, rq, page, 0, len,
PAGE_SIZE, true);

stats->bytes += len - vi->hdr_len;
if (unlikely(!skb))
Expand Down Expand Up @@ -842,7 +845,8 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
rcu_read_unlock();
put_page(page);
head_skb = page_to_skb(vi, rq, xdp_page,
offset, len, PAGE_SIZE);
offset, len,
PAGE_SIZE, false);
return head_skb;
}
break;
Expand Down Expand Up @@ -898,7 +902,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
goto err_skb;
}

head_skb = page_to_skb(vi, rq, page, offset, len, truesize);
head_skb = page_to_skb(vi, rq, page, offset, len, truesize, !xdp_prog);
curr_skb = head_skb;

if (unlikely(!curr_skb))
Expand Down

0 comments on commit 436c945

Please sign in to comment.