mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-22 15:02:32 +00:00
d5bf46bbe8
OpenWRT's developer guide prefers having actual patches so they an be sent upstream more easily. However, in this case, Adding proper fields also allows for `git am` to properly function. Some of these patches are quite old, and lack much traceable history. This commit tries to rectify that, by digging in the history to find where and how it was first added. It is by no means perfect and also shows some patches that should have been long gone. Signed-off-by: Olliver Schinagl <oliver@schinagl.nl>
68 lines
2.4 KiB
Diff
68 lines
2.4 KiB
Diff
From 5142239a22219921a7863cf00c9ab853c00689d8 Mon Sep 17 00:00:00 2001
|
|
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
|
Date: Fri, 11 Mar 2022 10:14:18 +0100
|
|
Subject: [PATCH] net: veth: Account total xdp_frame len running ndo_xdp_xmit
|
|
|
|
Even if this is a theoretical issue since it is not possible to perform
|
|
XDP_REDIRECT on a non-linear xdp_frame, veth driver does not account
|
|
paged area in ndo_xdp_xmit function pointer.
|
|
Introduce xdp_get_frame_len utility routine to get the xdp_frame full
|
|
length and account total frame size running XDP_REDIRECT of a
|
|
non-linear xdp frame into a veth device.
|
|
|
|
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
|
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
|
|
Acked-by: Toke Hoiland-Jorgensen <toke@redhat.com>
|
|
Acked-by: John Fastabend <john.fastabend@gmail.com>
|
|
Link: https://lore.kernel.org/bpf/54f9fd3bb65d190daf2c0bbae2f852ff16cfbaa0.1646989407.git.lorenzo@kernel.org
|
|
---
|
|
drivers/net/veth.c | 4 ++--
|
|
include/net/xdp.h | 14 ++++++++++++++
|
|
2 files changed, 16 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
|
|
index 58b20ea171dd..b77ce3fdcfe8 100644
|
|
--- a/drivers/net/veth.c
|
|
+++ b/drivers/net/veth.c
|
|
@@ -501,7 +501,7 @@ static int veth_xdp_xmit(struct net_devi
|
|
struct xdp_frame *frame = frames[i];
|
|
void *ptr = veth_xdp_to_ptr(frame);
|
|
|
|
- if (unlikely(frame->len > max_len ||
|
|
+ if (unlikely(xdp_get_frame_len(frame) > max_len ||
|
|
__ptr_ring_produce(&rq->xdp_ring, ptr)))
|
|
break;
|
|
nxmit++;
|
|
@@ -862,7 +862,7 @@ static int veth_xdp_rcv(struct veth_rq *
|
|
/* ndo_xdp_xmit */
|
|
struct xdp_frame *frame = veth_ptr_to_xdp(ptr);
|
|
|
|
- stats->xdp_bytes += frame->len;
|
|
+ stats->xdp_bytes += xdp_get_frame_len(frame);
|
|
frame = veth_xdp_rcv_one(rq, frame, bq, stats);
|
|
if (frame) {
|
|
/* XDP_PASS */
|
|
--- a/include/net/xdp.h
|
|
+++ b/include/net/xdp.h
|
|
@@ -295,6 +295,20 @@ out:
|
|
__xdp_release_frame(xdpf->data, mem);
|
|
}
|
|
|
|
+static __always_inline unsigned int xdp_get_frame_len(struct xdp_frame *xdpf)
|
|
+{
|
|
+ struct skb_shared_info *sinfo;
|
|
+ unsigned int len = xdpf->len;
|
|
+
|
|
+ if (likely(!xdp_frame_has_frags(xdpf)))
|
|
+ goto out;
|
|
+
|
|
+ sinfo = xdp_get_shared_info_from_frame(xdpf);
|
|
+ len += sinfo->xdp_frags_size;
|
|
+out:
|
|
+ return len;
|
|
+}
|
|
+
|
|
int xdp_rxq_info_reg(struct xdp_rxq_info *xdp_rxq,
|
|
struct net_device *dev, u32 queue_index, unsigned int napi_id);
|
|
void xdp_rxq_info_unreg(struct xdp_rxq_info *xdp_rxq);
|