[PATCH 1/2] bpf: preserve rx_queue_index across XDP redirects
From: Siddharth_Cibi <hidden>
Date: 2026-06-19 19:58:23
Also in:
bpf, lkml
Subsystem:
bpf [general] (safe dynamic programs and tools), networking [general], the rest, xdp (express data path) · Maintainers:
Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds, David S. Miller, Jesper Dangaard Brouer, John Fastabend
From: Siddharth C <redacted>
Store rx_queue_index in struct xdp_frame during xdp_buff to
xdp_frame conversion and restore it when rebuilding xdp_rxq_info
for cpumap and devmap execution paths.
This preserves ingress RX queue information for XDP programs
executed after redirect, allowing access to the original
rx_queue_index instead of losing queue context.
Also propagate rx_queue_index for zero-copy XDP frame conversion.
Signed-off-by: Siddharth_Cibi <redacted>
---
include/net/xdp.h | 2 ++
kernel/bpf/cpumap.c | 2 +-
kernel/bpf/devmap.c | 5 ++++-
net/core/xdp.c | 1 +
4 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/include/net/xdp.h b/include/net/xdp.h
index aa742f413c35..90318b2b76dc 100644
--- a/include/net/xdp.h
+++ b/include/net/xdp.h
@@ -301,6 +301,7 @@ struct xdp_frame {
*/
enum xdp_mem_type mem_type:32;
struct net_device *dev_rx; /* used by cpumap */
+ u32 rx_queue_index;
u32 frame_sz;
u32 flags; /* supported values defined in xdp_buff_flags */
};@@ -441,6 +442,7 @@ struct xdp_frame *xdp_convert_buff_to_frame(struct xdp_buff *xdp)
/* rxq only valid until napi_schedule ends, convert to xdp_mem_type */
xdp_frame->mem_type = xdp->rxq->mem.type;
+ xdp_frame->rx_queue_index = xdp->rxq->queue_index;
return xdp_frame;
}
diff --git a/kernel/bpf/cpumap.c b/kernel/bpf/cpumap.c
index 5e59ab896f05..8f2d7013620f 100644
--- a/kernel/bpf/cpumap.c
+++ b/kernel/bpf/cpumap.c
@@ -197,7 +197,7 @@ static int cpu_map_bpf_prog_run_xdp(struct bpf_cpu_map_entry *rcpu,
rxq.dev = xdpf->dev_rx;
rxq.mem.type = xdpf->mem_type;
- /* TODO: report queue_index to xdp_rxq_info */
+ rxq.queue_index = xdpf->rx_queue_index;
xdp_convert_frame_to_buff(xdpf, &xdp);
diff --git a/kernel/bpf/devmap.c b/kernel/bpf/devmap.c
index dc7b859e8bbf..f419fa0e53e5 100644
--- a/kernel/bpf/devmap.c
+++ b/kernel/bpf/devmap.c
@@ -339,7 +339,7 @@ static int dev_map_bpf_prog_run(struct bpf_prog *xdp_prog,
struct net_device *rx_dev)
{
struct xdp_txq_info txq = { .dev = tx_dev };
- struct xdp_rxq_info rxq = { .dev = rx_dev };
+ struct xdp_rxq_info rxq = { };
struct xdp_buff xdp;
int i, nframes = 0;
@@ -349,6 +349,9 @@ static int dev_map_bpf_prog_run(struct bpf_prog *xdp_prog,
int err;
xdp_convert_frame_to_buff(xdpf, &xdp);
+ rxq.dev = rx_dev;
+ rxq.mem.type = xdpf->mem_type;
+ rxq.queue_index = xdpf->rx_queue_index;
xdp.txq = &txq;
xdp.rxq = &rxq;
diff --git a/net/core/xdp.c b/net/core/xdp.c
index 9890a30584ba..9691d8dfadf3 100644
--- a/net/core/xdp.c
+++ b/net/core/xdp.c
@@ -606,6 +606,7 @@ struct xdp_frame *xdp_convert_zc_to_xdp_frame(struct xdp_buff *xdp)
xdpf->metasize = metasize;
xdpf->frame_sz = PAGE_SIZE;
xdpf->mem_type = MEM_TYPE_PAGE_ORDER0;
+ xdpf->rx_queue_index = xdp->rxq->queue_index;
xsk_buff_free(xdp);
return xdpf;
--
2.53.0