summaryrefslogtreecommitdiff
path: root/net/bpf/test_run.c
diff options
context:
space:
mode:
authorMartin KaFai Lau <martin.lau@kernel.org>2025-09-23 13:35:13 -0700
committerMartin KaFai Lau <martin.lau@kernel.org>2025-09-23 15:21:41 -0700
commit5000380e3204fa19a049c6ad5549ff3412124abd (patch)
tree55c7a5032dc4336896636bbbffb8cfd9545420e0 /net/bpf/test_run.c
parent54728bd535fb3899ad51489dc1e05eb5bb53cb95 (diff)
parentefec2e55bdefb889639a6e7fe1f1f2431cdddc6a (diff)
Merge branch 'add-kfunc-bpf_xdp_pull_data'
Amery Hung says: ==================== Add kfunc bpf_xdp_pull_data v7 -> v6 patch 5 (new patch) - Rename variables in bpf_prog_test_run_xdp() patch 6 - Fix bugs (Martin) v6 -> v5 patch 6 - v5 selftest failed on S390 when changing how tailroom occupied by skb_shared_info is calculated. Revert selftest to v4, where we get SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) by running an XDP program Link: https://lore.kernel.org/bpf/20250919230952.3628709-1-ameryhung@gmail.com/ v5 -> v4 patch 1 - Add a new patch clearing pfmemalloc bit in xdp->frags when all frags are freed in bpf_xdp_adjust_tail() (Maciej) patch 2 - Refactor bpf_xdp_shrink_data() (Maciej) patch 3 - Clear pfmemalloc when all frags are freed in bpf_xdp_pull_data() (Maciej) patch 6 - Use BTF to get sizes of skb_shared_info and xdp_frame (Maciej) Link: https://lore.kernel.org/bpf/20250919182100.1925352-1-ameryhung@gmail.com/ v3 -> v4 patch 2 - Improve comments (Jakub) - Drop new_end and len_free to simplify code (Jakub) patch 4 - Instead of adding is_xdp to bpf_test_init, move lower-bound check of user_size to callers (Martin) - Simplify linear data size calculation (Martin) patch 5 - Add static function identifier (Martin) - Free calloc-ed buf (Martin) Link: https://lore.kernel.org/bpf/20250917225513.3388199-1-ameryhung@gmail.com/ v2 -> v3 Separate mlx5 fixes from the patchset patch 2 - Use headroom for pulling data by shifting metadata and data down (Jakub) - Drop the flags argument (Martin) patch 4 - Support empty linear xdp data for BPF_PROG_TEST_RUN Link: https://lore.kernel.org/bpf/20250915224801.2961360-1-ameryhung@gmail.com/ v1 -> v2 Rebase onto bpf-next Try to build on top of the mlx5 patchset that avoids copying payload to linear part by Christoph but got a kernel panic. Will rebase on that patchset if it got merged first, or separate the mlx5 fix from this set. patch 1 - Remove the unnecessary head frag search (Dragos) - Rewind the end frag pointer to simplify the change (Dragos) - Rewind the end frag pointer and recalculate truesize only when the number of frags changed (Dragos) patch 3 - Fix len == zero behavior. To mirror bpf_skb_pull_data() correctly, the kfunc should do nothing (Stanislav) - Fix a pointer wrap around bug (Jakub) - Use memmove() when moving sinfo->frags (Jakub) Link: https://lore.kernel.org/bpf/20250905173352.3759457-1-ameryhung@gmail.com/ ==================== Link: https://patch.msgid.link/20250922233356.3356453-1-ameryhung@gmail.com Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
Diffstat (limited to 'net/bpf/test_run.c')
-rw-r--r--net/bpf/test_run.c37
1 files changed, 23 insertions, 14 deletions
diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c
index 9728dbd4c66c..3df3fe46beb3 100644
--- a/net/bpf/test_run.c
+++ b/net/bpf/test_run.c
@@ -665,7 +665,7 @@ static void *bpf_test_init(const union bpf_attr *kattr, u32 user_size,
void __user *data_in = u64_to_user_ptr(kattr->test.data_in);
void *data;
- if (user_size < ETH_HLEN || user_size > PAGE_SIZE - headroom - tailroom)
+ if (user_size > PAGE_SIZE - headroom - tailroom)
return ERR_PTR(-EINVAL);
size = SKB_DATA_ALIGN(size);
@@ -1001,6 +1001,9 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr,
kattr->test.cpu || kattr->test.batch_size)
return -EINVAL;
+ if (size < ETH_HLEN)
+ return -EINVAL;
+
data = bpf_test_init(kattr, kattr->test.data_size_in,
size, NET_SKB_PAD + NET_IP_ALIGN,
SKB_DATA_ALIGN(sizeof(struct skb_shared_info)));
@@ -1207,9 +1210,9 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr,
{
bool do_live = (kattr->test.flags & BPF_F_TEST_XDP_LIVE_FRAMES);
u32 tailroom = SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
+ u32 retval = 0, meta_sz = 0, duration, max_linear_sz, size;
+ u32 linear_sz = kattr->test.data_size_in;
u32 batch_size = kattr->test.batch_size;
- u32 retval = 0, duration, max_data_sz;
- u32 size = kattr->test.data_size_in;
u32 headroom = XDP_PACKET_HEADROOM;
u32 repeat = kattr->test.repeat;
struct netdev_rx_queue *rxqueue;
@@ -1246,39 +1249,45 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr,
if (ctx) {
/* There can't be user provided data before the meta data */
- if (ctx->data_meta || ctx->data_end != size ||
+ if (ctx->data_meta || ctx->data_end > kattr->test.data_size_in ||
ctx->data > ctx->data_end ||
unlikely(xdp_metalen_invalid(ctx->data)) ||
(do_live && (kattr->test.data_out || kattr->test.ctx_out)))
goto free_ctx;
/* Meta data is allocated from the headroom */
headroom -= ctx->data;
- }
- max_data_sz = PAGE_SIZE - headroom - tailroom;
- if (size > max_data_sz) {
- /* disallow live data mode for jumbo frames */
- if (do_live)
- goto free_ctx;
- size = max_data_sz;
+ meta_sz = ctx->data;
+ linear_sz = ctx->data_end;
}
- data = bpf_test_init(kattr, size, max_data_sz, headroom, tailroom);
+ max_linear_sz = PAGE_SIZE - headroom - tailroom;
+ linear_sz = min_t(u32, linear_sz, max_linear_sz);
+
+ /* disallow live data mode for jumbo frames */
+ if (do_live && kattr->test.data_size_in > linear_sz)
+ goto free_ctx;
+
+ if (kattr->test.data_size_in - meta_sz < ETH_HLEN)
+ return -EINVAL;
+
+ data = bpf_test_init(kattr, linear_sz, max_linear_sz, headroom, tailroom);
if (IS_ERR(data)) {
ret = PTR_ERR(data);
goto free_ctx;
}
rxqueue = __netif_get_rx_queue(current->nsproxy->net_ns->loopback_dev, 0);
- rxqueue->xdp_rxq.frag_size = headroom + max_data_sz + tailroom;
+ rxqueue->xdp_rxq.frag_size = PAGE_SIZE;
xdp_init_buff(&xdp, rxqueue->xdp_rxq.frag_size, &rxqueue->xdp_rxq);
- xdp_prepare_buff(&xdp, data, headroom, size, true);
+ xdp_prepare_buff(&xdp, data, headroom, linear_sz, true);
sinfo = xdp_get_shared_info_from_buff(&xdp);
ret = xdp_convert_md_to_buff(ctx, &xdp);
if (ret)
goto free_data;
+ size = linear_sz;
if (unlikely(kattr->test.data_size_in > size)) {
void __user *data_in = u64_to_user_ptr(kattr->test.data_in);