|
@@ -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;
|
|
@@ -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;
|
|
@@ -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))
|
|
@@ -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;
|
|
@@ -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))
|