xref: /linux/tools/testing/selftests/bpf/progs/ksock_wq.c (revision 5a8cd539ac19f7a68e68e1d25ef9ca2ff55b8500)
1*c93cbdb1SMahe Tardy // SPDX-License-Identifier: GPL-2.0
2*c93cbdb1SMahe Tardy /* Copyright (c) 2026 Isovalent */
3*c93cbdb1SMahe Tardy 
4*c93cbdb1SMahe Tardy #include "vmlinux.h"
5*c93cbdb1SMahe Tardy #include <bpf/bpf_helpers.h>
6*c93cbdb1SMahe Tardy #include "bpf_experimental.h"
7*c93cbdb1SMahe Tardy #include "bpf_tracing_net.h"
8*c93cbdb1SMahe Tardy #include "errno.h"
9*c93cbdb1SMahe Tardy #include "ksock_common.h"
10*c93cbdb1SMahe Tardy 
11*c93cbdb1SMahe Tardy struct ksock_wq_value {
12*c93cbdb1SMahe Tardy 	struct bpf_wq work;
13*c93cbdb1SMahe Tardy };
14*c93cbdb1SMahe Tardy 
15*c93cbdb1SMahe Tardy struct {
16*c93cbdb1SMahe Tardy 	__uint(type, BPF_MAP_TYPE_ARRAY);
17*c93cbdb1SMahe Tardy 	__uint(max_entries, 1);
18*c93cbdb1SMahe Tardy 	__type(key, u32);
19*c93cbdb1SMahe Tardy 	__type(value, struct ksock_wq_value);
20*c93cbdb1SMahe Tardy } work_map SEC(".maps");
21*c93cbdb1SMahe Tardy 
22*c93cbdb1SMahe Tardy int create_err;
23*c93cbdb1SMahe Tardy u32 callback_done;
24*c93cbdb1SMahe Tardy 
ksock_wq_callback(void * map,int * key,void * value)25*c93cbdb1SMahe Tardy static int ksock_wq_callback(void *map, int *key, void *value)
26*c93cbdb1SMahe Tardy {
27*c93cbdb1SMahe Tardy 	struct bpf_ksock_create_opts opts = {
28*c93cbdb1SMahe Tardy 		.family = AF_INET,
29*c93cbdb1SMahe Tardy 		.type = SOCK_DGRAM,
30*c93cbdb1SMahe Tardy 		.protocol = IPPROTO_UDP,
31*c93cbdb1SMahe Tardy 	};
32*c93cbdb1SMahe Tardy 	struct bpf_ksock *ks;
33*c93cbdb1SMahe Tardy 	int err = 0;
34*c93cbdb1SMahe Tardy 
35*c93cbdb1SMahe Tardy 	ks = bpf_ksock_create(&opts, sizeof(opts), &err);
36*c93cbdb1SMahe Tardy 	if (ks)
37*c93cbdb1SMahe Tardy 		bpf_ksock_release(ks);
38*c93cbdb1SMahe Tardy 	create_err = err;
39*c93cbdb1SMahe Tardy 	__sync_fetch_and_add(&callback_done, 1);
40*c93cbdb1SMahe Tardy 	return 0;
41*c93cbdb1SMahe Tardy }
42*c93cbdb1SMahe Tardy 
43*c93cbdb1SMahe Tardy SEC("syscall")
ksock_wq_start(void * ctx)44*c93cbdb1SMahe Tardy int ksock_wq_start(void *ctx)
45*c93cbdb1SMahe Tardy {
46*c93cbdb1SMahe Tardy 	struct ksock_wq_value *value;
47*c93cbdb1SMahe Tardy 	u32 key = 0;
48*c93cbdb1SMahe Tardy 	int err;
49*c93cbdb1SMahe Tardy 
50*c93cbdb1SMahe Tardy 	value = bpf_map_lookup_elem(&work_map, &key);
51*c93cbdb1SMahe Tardy 	if (!value)
52*c93cbdb1SMahe Tardy 		return -ENOENT;
53*c93cbdb1SMahe Tardy 	err = bpf_wq_init(&value->work, &work_map, 0);
54*c93cbdb1SMahe Tardy 	if (err)
55*c93cbdb1SMahe Tardy 		return err;
56*c93cbdb1SMahe Tardy 	err = bpf_wq_set_callback(&value->work, ksock_wq_callback, 0);
57*c93cbdb1SMahe Tardy 	if (err)
58*c93cbdb1SMahe Tardy 		return err;
59*c93cbdb1SMahe Tardy 	return bpf_wq_start(&value->work, 0);
60*c93cbdb1SMahe Tardy }
61*c93cbdb1SMahe Tardy 
62*c93cbdb1SMahe Tardy char __license[] SEC("license") = "GPL";
63