Received: by 2002:a05:6a10:17d3:0:0:0:0 with SMTP id hz19csp2056561pxb; Mon, 12 Apr 2021 13:10:16 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzh5isF7zvE9Kknac4+kD2hKNCNrmKv+eHCbBAR8ebJ2q734tVS73Tnj4hg95nDJVpFsqmZ X-Received: by 2002:aa7:8c06:0:b029:242:3a8c:9f10 with SMTP id c6-20020aa78c060000b02902423a8c9f10mr26587478pfd.43.1618258216261; Mon, 12 Apr 2021 13:10:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1618258216; cv=none; d=google.com; s=arc-20160816; b=ul+Inle1QAxqxlDlYobxCBDUL1bjxi+vzqJcl7XoxUBPwhwbl4xNzizOzdGWZF7Cbf x85U3F9YNyRrhCK01hjaCRdb4d7yOfKvJFuytgpYcl0HNi5NZIwT/iR4RfA0xSeIqiCP QP7YoY/nz7+FjRK4xBp5t8kPgTTbduYcWgO5SVrxkJmTJE6kIhiwqLfmP7V8JleUQ7Bz 4NJ2zJK5DOW4ixnY1kHjUD4UsbpXfPWL3g4sUZeuE0vTy5S700MXbsBgEK/mSQbERaBP RfU7i796QLmUg5OOyADOUN/d8ye5u87mYMP2/koKKJm3cyU9UGFxe8Elpw6xMTBFvMOC Ht2w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=kyzsvHgwxTm+unE52ogrv9ZaEaoGxqeOnFJJyMcqp8o=; b=OAy67tGODxPVts1nbNTk+1j6VTIcCSgvO2lSB4OYw9M1+YV6AMgSTEi7149LFvCxli bT0uMbwsWQFj7t+okhUWSr8Z6ipdkNwAiyQsaPWrhLQ9ykUpB2XDftpvVO29MJiQ6jAm Zzmdqd+UUDmREfkHKFTmOMj6WUkPtVv7tQSngDc6cn4gdgrUdV1mISYsBjrqlhRDTsrj rdQMnwBBNCXRn8xIa4F2Yio8AIhFIogcNdzsOE8JaKGTdI9XoIKVod4maQTBJafxvZQO TilXw3/oWv92/6BFHgIuTrgf7wVsE6pAwikyX9djrmZO8qQ4wGbAeALcvsaYI6wYk4Mq RdvQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=eAIqaYtE; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id p16si14320624plw.176.2021.04.12.13.10.04; Mon, 12 Apr 2021 13:10:16 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=eAIqaYtE; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238547AbhDLIuE (ORCPT + 99 others); Mon, 12 Apr 2021 04:50:04 -0400 Received: from mail.kernel.org ([198.145.29.99]:39972 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237996AbhDLIrF (ORCPT ); Mon, 12 Apr 2021 04:47:05 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 4601261221; Mon, 12 Apr 2021 08:46:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1618217206; bh=t7XBKXfhQ8LYhu6wfrJX+sDRVHvyuCdsNJBYfV5jCiE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=eAIqaYtEfHXRQmic6B8kkvtnfAn/NXP65MjK1DbcJkxHW0hAZqL2Kb0TOVTQ8/CxJ HYJXSr3EIUcg10UUbOCW1ZsNZvDilaUwf6ApnL6A0ZnqEog3fVRvLMN4w3tzivdLRB QSQAw98LB2CqiYRIth6hD154Mw/9yTizRyjktHsc= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Yuya Kusakabe , Daniel Borkmann , Jason Wang , "Michael S. Tsirkin" , Sasha Levin Subject: [PATCH 5.4 041/111] virtio_net: Add XDP meta data support Date: Mon, 12 Apr 2021 10:40:19 +0200 Message-Id: <20210412084005.618418867@linuxfoundation.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210412084004.200986670@linuxfoundation.org> References: <20210412084004.200986670@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Yuya Kusakabe [ Upstream commit 503d539a6e417b018616bf3060e0b5814fafce47 ] Implement support for transferring XDP meta data into skb for virtio_net driver; before calling into the program, xdp.data_meta points to xdp.data, where on program return with pass verdict, we call into skb_metadata_set(). Tested with the script at https://github.com/higebu/virtio_net-xdp-metadata-test. Signed-off-by: Yuya Kusakabe Signed-off-by: Daniel Borkmann Acked-by: Jason Wang Acked-by: Michael S. Tsirkin Link: https://lore.kernel.org/bpf/20200225033212.437563-2-yuya.kusakabe@gmail.com Signed-off-by: Sasha Levin --- drivers/net/virtio_net.c | 52 ++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 0ef85819665c..b67460864b3c 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -376,7 +376,7 @@ 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, - bool hdr_valid) + bool hdr_valid, unsigned int metasize) { struct sk_buff *skb; struct virtio_net_hdr_mrg_rxbuf *hdr; @@ -398,6 +398,7 @@ static struct sk_buff *page_to_skb(struct virtnet_info *vi, else hdr_padded_len = sizeof(struct padded_vnet_hdr); + /* hdr_valid means no XDP, so we can copy the vnet header */ if (hdr_valid) memcpy(hdr, p, hdr_len); @@ -410,6 +411,11 @@ static struct sk_buff *page_to_skb(struct virtnet_info *vi, copy = skb_tailroom(skb); skb_put_data(skb, p, copy); + if (metasize) { + __skb_pull(skb, metasize); + skb_metadata_set(skb, metasize); + } + len -= copy; offset += copy; @@ -455,10 +461,6 @@ static int __virtnet_xdp_xmit_one(struct virtnet_info *vi, struct virtio_net_hdr_mrg_rxbuf *hdr; int err; - /* virtqueue want to use data area in-front of packet */ - if (unlikely(xdpf->metasize > 0)) - return -EOPNOTSUPP; - if (unlikely(xdpf->headroom < vi->hdr_len)) return -EOVERFLOW; @@ -649,6 +651,7 @@ static struct sk_buff *receive_small(struct net_device *dev, unsigned int delta = 0; struct page *xdp_page; int err; + unsigned int metasize = 0; len -= vi->hdr_len; stats->bytes += len; @@ -688,8 +691,8 @@ static struct sk_buff *receive_small(struct net_device *dev, xdp.data_hard_start = buf + VIRTNET_RX_PAD + vi->hdr_len; xdp.data = xdp.data_hard_start + xdp_headroom; - xdp_set_data_meta_invalid(&xdp); xdp.data_end = xdp.data + len; + xdp.data_meta = xdp.data; xdp.rxq = &rq->xdp_rxq; orig_data = xdp.data; act = bpf_prog_run_xdp(xdp_prog, &xdp); @@ -700,6 +703,7 @@ static struct sk_buff *receive_small(struct net_device *dev, /* Recalculate length in case bpf program changed it */ delta = orig_data - xdp.data; len = xdp.data_end - xdp.data; + metasize = xdp.data - xdp.data_meta; break; case XDP_TX: stats->xdp_tx++; @@ -745,6 +749,9 @@ static struct sk_buff *receive_small(struct net_device *dev, memcpy(skb_vnet_hdr(skb), buf, vi->hdr_len); } /* keep zeroed vnet hdr since packet was changed by bpf */ + if (metasize) + skb_metadata_set(skb, metasize); + err: return skb; @@ -765,8 +772,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, true); + struct sk_buff *skb = + page_to_skb(vi, rq, page, 0, len, PAGE_SIZE, true, 0); stats->bytes += len - vi->hdr_len; if (unlikely(!skb)) @@ -798,6 +805,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev, unsigned int truesize; unsigned int headroom = mergeable_ctx_to_headroom(ctx); int err; + unsigned int metasize = 0; head_skb = NULL; stats->bytes += len - vi->hdr_len; @@ -844,8 +852,8 @@ static struct sk_buff *receive_mergeable(struct net_device *dev, data = page_address(xdp_page) + offset; xdp.data_hard_start = data - VIRTIO_XDP_HEADROOM + vi->hdr_len; xdp.data = data + vi->hdr_len; - xdp_set_data_meta_invalid(&xdp); xdp.data_end = xdp.data + (len - vi->hdr_len); + xdp.data_meta = xdp.data; xdp.rxq = &rq->xdp_rxq; act = bpf_prog_run_xdp(xdp_prog, &xdp); @@ -853,24 +861,27 @@ static struct sk_buff *receive_mergeable(struct net_device *dev, switch (act) { case XDP_PASS: + metasize = xdp.data - xdp.data_meta; + /* recalculate offset to account for any header - * adjustments. Note other cases do not build an - * skb and avoid using offset + * adjustments and minus the metasize to copy the + * metadata in page_to_skb(). Note other cases do not + * build an skb and avoid using offset */ - offset = xdp.data - - page_address(xdp_page) - vi->hdr_len; + offset = xdp.data - page_address(xdp_page) - + vi->hdr_len - metasize; - /* recalculate len if xdp.data or xdp.data_end were - * adjusted + /* recalculate len if xdp.data, xdp.data_end or + * xdp.data_meta were adjusted */ - len = xdp.data_end - xdp.data + vi->hdr_len; + len = xdp.data_end - xdp.data + vi->hdr_len + metasize; /* We can only create skb based on xdp_page. */ if (unlikely(xdp_page != page)) { rcu_read_unlock(); put_page(page); - head_skb = page_to_skb(vi, rq, xdp_page, - offset, len, - PAGE_SIZE, false); + head_skb = page_to_skb(vi, rq, xdp_page, offset, + len, PAGE_SIZE, false, + metasize); return head_skb; } break; @@ -926,7 +937,8 @@ static struct sk_buff *receive_mergeable(struct net_device *dev, goto err_skb; } - head_skb = page_to_skb(vi, rq, page, offset, len, truesize, !xdp_prog); + head_skb = page_to_skb(vi, rq, page, offset, len, truesize, !xdp_prog, + metasize); curr_skb = head_skb; if (unlikely(!curr_skb)) -- 2.30.2