xref: /linux/net/core/bpf_ksock.c (revision 5a8cd539ac19f7a68e68e1d25ef9ca2ff55b8500)
1*7ae4eb14SMahe Tardy // SPDX-License-Identifier: GPL-2.0-only
2*7ae4eb14SMahe Tardy /* Copyright (c) 2026 Isovalent */
3*7ae4eb14SMahe Tardy 
4*7ae4eb14SMahe Tardy #include <linux/bpf.h>
5*7ae4eb14SMahe Tardy #include <linux/bpf_ksock.h>
6*7ae4eb14SMahe Tardy #include <linux/btf.h>
7*7ae4eb14SMahe Tardy #include <linux/btf_ids.h>
8*7ae4eb14SMahe Tardy #include <linux/in.h>
9*7ae4eb14SMahe Tardy #include <linux/in6.h>
10*7ae4eb14SMahe Tardy #include <linux/net.h>
11*7ae4eb14SMahe Tardy #include <linux/refcount.h>
12*7ae4eb14SMahe Tardy #include <linux/sched.h>
13*7ae4eb14SMahe Tardy #include <linux/slab.h>
14*7ae4eb14SMahe Tardy #include <linux/socket.h>
15*7ae4eb14SMahe Tardy #include <linux/unaligned.h>
16*7ae4eb14SMahe Tardy #include <linux/workqueue.h>
17*7ae4eb14SMahe Tardy #include <net/sock.h>
18*7ae4eb14SMahe Tardy 
19*7ae4eb14SMahe Tardy /**
20*7ae4eb14SMahe Tardy  * struct bpf_ksock - refcounted BPF kernel socket context
21*7ae4eb14SMahe Tardy  * @sock:	The underlying kernel socket.
22*7ae4eb14SMahe Tardy  * @usage:	Reference counter.
23*7ae4eb14SMahe Tardy  * @rwork:	RCU work for deferred cleanup (sock_release may sleep).
24*7ae4eb14SMahe Tardy  */
25*7ae4eb14SMahe Tardy struct bpf_ksock {
26*7ae4eb14SMahe Tardy 	struct socket *sock;
27*7ae4eb14SMahe Tardy 	refcount_t usage;
28*7ae4eb14SMahe Tardy 	struct rcu_work rwork;
29*7ae4eb14SMahe Tardy };
30*7ae4eb14SMahe Tardy 
ksock_release_work_fn(struct work_struct * work)31*7ae4eb14SMahe Tardy static void ksock_release_work_fn(struct work_struct *work)
32*7ae4eb14SMahe Tardy {
33*7ae4eb14SMahe Tardy 	struct bpf_ksock *ks;
34*7ae4eb14SMahe Tardy 
35*7ae4eb14SMahe Tardy 	ks = container_of(to_rcu_work(work), struct bpf_ksock, rwork);
36*7ae4eb14SMahe Tardy 	sock_release(ks->sock);
37*7ae4eb14SMahe Tardy 	kfree(ks);
38*7ae4eb14SMahe Tardy }
39*7ae4eb14SMahe Tardy 
bpf_ksock_has_user_task_context(void)40*7ae4eb14SMahe Tardy static bool bpf_ksock_has_user_task_context(void)
41*7ae4eb14SMahe Tardy {
42*7ae4eb14SMahe Tardy 	/*
43*7ae4eb14SMahe Tardy 	 * Task work can run from do_exit() after exit_nsproxy_namespaces()
44*7ae4eb14SMahe Tardy 	 * cleared current->nsproxy, while current is still not a kthread.
45*7ae4eb14SMahe Tardy 	 */
46*7ae4eb14SMahe Tardy 	return !(current->flags & PF_KTHREAD) && current->nsproxy;
47*7ae4eb14SMahe Tardy }
48*7ae4eb14SMahe Tardy 
49*7ae4eb14SMahe Tardy __bpf_kfunc_start_defs();
50*7ae4eb14SMahe Tardy 
51*7ae4eb14SMahe Tardy /**
52*7ae4eb14SMahe Tardy  * bpf_ksock_create() - Create a BPF kernel socket.
53*7ae4eb14SMahe Tardy  *
54*7ae4eb14SMahe Tardy  * Allocates and creates a kernel socket.
55*7ae4eb14SMahe Tardy  *
56*7ae4eb14SMahe Tardy  * The returned context must either be stored in a map as a kptr, or
57*7ae4eb14SMahe Tardy  * freed with bpf_ksock_release().
58*7ae4eb14SMahe Tardy  *
59*7ae4eb14SMahe Tardy  * This function may sleep (sock_create), so it can only be used
60*7ae4eb14SMahe Tardy  * in sleepable BPF programs (SYSCALL).
61*7ae4eb14SMahe Tardy  * It cannot be called from a BPF workqueue callback because that callback
62*7ae4eb14SMahe Tardy  * does not retain the invoking task's namespace or security context.
63*7ae4eb14SMahe Tardy  *
64*7ae4eb14SMahe Tardy  * @opts:	Pointer to struct bpf_ksock_create_opts with socket parameters.
65*7ae4eb14SMahe Tardy  * @opts__sz:	Size of the opts struct.
66*7ae4eb14SMahe Tardy  * @err__uninit:	Integer to store error code when NULL is returned.
67*7ae4eb14SMahe Tardy  */
68*7ae4eb14SMahe Tardy __bpf_kfunc struct bpf_ksock *
bpf_ksock_create(const struct bpf_ksock_create_opts * opts,u32 opts__sz,int * err__uninit)69*7ae4eb14SMahe Tardy bpf_ksock_create(const struct bpf_ksock_create_opts *opts, u32 opts__sz,
70*7ae4eb14SMahe Tardy 		 int *err__uninit)
71*7ae4eb14SMahe Tardy {
72*7ae4eb14SMahe Tardy 	struct bpf_ksock_create_opts opts_copy;
73*7ae4eb14SMahe Tardy 	struct bpf_ksock *ks;
74*7ae4eb14SMahe Tardy 	int err;
75*7ae4eb14SMahe Tardy 
76*7ae4eb14SMahe Tardy 	/*
77*7ae4eb14SMahe Tardy 	 * sock_create() derives the network namespace, credentials, and cgroup
78*7ae4eb14SMahe Tardy 	 * from current. Kernel threads, including BPF workqueue callbacks, do
79*7ae4eb14SMahe Tardy 	 * not carry the context of the task that invoked the BPF program.
80*7ae4eb14SMahe Tardy 	 */
81*7ae4eb14SMahe Tardy 	if (!bpf_ksock_has_user_task_context()) {
82*7ae4eb14SMahe Tardy 		err = -EOPNOTSUPP;
83*7ae4eb14SMahe Tardy 		goto err_out;
84*7ae4eb14SMahe Tardy 	}
85*7ae4eb14SMahe Tardy 
86*7ae4eb14SMahe Tardy 	if (!opts || opts__sz != sizeof(struct bpf_ksock_create_opts)) {
87*7ae4eb14SMahe Tardy 		err = -EINVAL;
88*7ae4eb14SMahe Tardy 		goto err_out;
89*7ae4eb14SMahe Tardy 	}
90*7ae4eb14SMahe Tardy 
91*7ae4eb14SMahe Tardy 	opts_copy = (struct bpf_ksock_create_opts){
92*7ae4eb14SMahe Tardy 		.family = READ_ONCE(opts->family),
93*7ae4eb14SMahe Tardy 		.type = READ_ONCE(opts->type),
94*7ae4eb14SMahe Tardy 		.protocol = READ_ONCE(opts->protocol),
95*7ae4eb14SMahe Tardy 		.reserved = READ_ONCE(opts->reserved),
96*7ae4eb14SMahe Tardy 	};
97*7ae4eb14SMahe Tardy 
98*7ae4eb14SMahe Tardy 	if (opts_copy.reserved) {
99*7ae4eb14SMahe Tardy 		err = -EINVAL;
100*7ae4eb14SMahe Tardy 		goto err_out;
101*7ae4eb14SMahe Tardy 	}
102*7ae4eb14SMahe Tardy 
103*7ae4eb14SMahe Tardy 	if (opts_copy.family != AF_INET && opts_copy.family != AF_INET6) {
104*7ae4eb14SMahe Tardy 		err = -EAFNOSUPPORT;
105*7ae4eb14SMahe Tardy 		goto err_out;
106*7ae4eb14SMahe Tardy 	}
107*7ae4eb14SMahe Tardy 
108*7ae4eb14SMahe Tardy 	if (opts_copy.type != SOCK_DGRAM) {
109*7ae4eb14SMahe Tardy 		err = -EPROTONOSUPPORT;
110*7ae4eb14SMahe Tardy 		goto err_out;
111*7ae4eb14SMahe Tardy 	}
112*7ae4eb14SMahe Tardy 
113*7ae4eb14SMahe Tardy 	if (opts_copy.protocol != IPPROTO_UDP && opts_copy.protocol != 0) {
114*7ae4eb14SMahe Tardy 		err = -EPROTONOSUPPORT;
115*7ae4eb14SMahe Tardy 		goto err_out;
116*7ae4eb14SMahe Tardy 	}
117*7ae4eb14SMahe Tardy 
118*7ae4eb14SMahe Tardy 	ks = kzalloc_obj(*ks);
119*7ae4eb14SMahe Tardy 	if (!ks) {
120*7ae4eb14SMahe Tardy 		err = -ENOMEM;
121*7ae4eb14SMahe Tardy 		goto err_out;
122*7ae4eb14SMahe Tardy 	}
123*7ae4eb14SMahe Tardy 
124*7ae4eb14SMahe Tardy 	/*
125*7ae4eb14SMahe Tardy 	 * Use the normal current-task socket path so LSM/cgroup policy,
126*7ae4eb14SMahe Tardy 	 * socket labels, and the active netns reference match a socket(2)
127*7ae4eb14SMahe Tardy 	 * created by the BPF program's caller.
128*7ae4eb14SMahe Tardy 	 */
129*7ae4eb14SMahe Tardy 	err = sock_create(opts_copy.family, opts_copy.type, opts_copy.protocol,
130*7ae4eb14SMahe Tardy 			  &ks->sock);
131*7ae4eb14SMahe Tardy 	if (err)
132*7ae4eb14SMahe Tardy 		goto err_free;
133*7ae4eb14SMahe Tardy 
134*7ae4eb14SMahe Tardy 	ks->sock->sk->sk_rcvbuf = SOCK_MIN_RCVBUF;
135*7ae4eb14SMahe Tardy 	ks->sock->sk->sk_userlocks |= SOCK_RCVBUF_LOCK;
136*7ae4eb14SMahe Tardy 
137*7ae4eb14SMahe Tardy 	refcount_set(&ks->usage, 1);
138*7ae4eb14SMahe Tardy 	put_unaligned(0, err__uninit);
139*7ae4eb14SMahe Tardy 	return ks;
140*7ae4eb14SMahe Tardy 
141*7ae4eb14SMahe Tardy err_free:
142*7ae4eb14SMahe Tardy 	kfree(ks);
143*7ae4eb14SMahe Tardy err_out:
144*7ae4eb14SMahe Tardy 	put_unaligned(err, err__uninit);
145*7ae4eb14SMahe Tardy 	return NULL;
146*7ae4eb14SMahe Tardy }
147*7ae4eb14SMahe Tardy 
148*7ae4eb14SMahe Tardy /**
149*7ae4eb14SMahe Tardy  * bpf_ksock_connect() - Connect a BPF kernel socket to a remote address.
150*7ae4eb14SMahe Tardy  * @ks:		The BPF kernel socket context.
151*7ae4eb14SMahe Tardy  * @addr:	Pointer to an IPv4 or IPv6 socket address.
152*7ae4eb14SMahe Tardy  * @addr__sz:	Size of the address union.
153*7ae4eb14SMahe Tardy  *
154*7ae4eb14SMahe Tardy  * Connects the socket to the specified remote address and port.
155*7ae4eb14SMahe Tardy  *
156*7ae4eb14SMahe Tardy  * This function may sleep while connecting the socket, so it can only be used
157*7ae4eb14SMahe Tardy  * in sleepable BPF programs (SYSCALL).
158*7ae4eb14SMahe Tardy  *
159*7ae4eb14SMahe Tardy  * Return: 0 on success, negative errno on error.
160*7ae4eb14SMahe Tardy  */
bpf_ksock_connect(struct bpf_ksock * ks,const union bpf_ksock_addr * addr,u32 addr__sz)161*7ae4eb14SMahe Tardy __bpf_kfunc int bpf_ksock_connect(struct bpf_ksock *ks,
162*7ae4eb14SMahe Tardy 				  const union bpf_ksock_addr *addr,
163*7ae4eb14SMahe Tardy 				  u32 addr__sz)
164*7ae4eb14SMahe Tardy {
165*7ae4eb14SMahe Tardy 	struct sockaddr_storage sa;
166*7ae4eb14SMahe Tardy 	int addrlen;
167*7ae4eb14SMahe Tardy 
168*7ae4eb14SMahe Tardy 	if (!bpf_ksock_has_user_task_context())
169*7ae4eb14SMahe Tardy 		return -EOPNOTSUPP;
170*7ae4eb14SMahe Tardy 
171*7ae4eb14SMahe Tardy 	if (!addr || addr__sz != sizeof(*addr))
172*7ae4eb14SMahe Tardy 		return -EINVAL;
173*7ae4eb14SMahe Tardy 
174*7ae4eb14SMahe Tardy 	/* Kfunc memory arguments may be unaligned. */
175*7ae4eb14SMahe Tardy 	memcpy(&sa, addr, sizeof(*addr));
176*7ae4eb14SMahe Tardy 
177*7ae4eb14SMahe Tardy 	switch (sa.ss_family) {
178*7ae4eb14SMahe Tardy 	case AF_INET:
179*7ae4eb14SMahe Tardy 		addrlen = sizeof(struct sockaddr_in);
180*7ae4eb14SMahe Tardy 		break;
181*7ae4eb14SMahe Tardy 	case AF_INET6:
182*7ae4eb14SMahe Tardy 		addrlen = sizeof(struct sockaddr_in6);
183*7ae4eb14SMahe Tardy 		break;
184*7ae4eb14SMahe Tardy 	default:
185*7ae4eb14SMahe Tardy 		return -EAFNOSUPPORT;
186*7ae4eb14SMahe Tardy 	}
187*7ae4eb14SMahe Tardy 
188*7ae4eb14SMahe Tardy 	return connect_socket(ks->sock, &sa, addrlen, 0);
189*7ae4eb14SMahe Tardy }
190*7ae4eb14SMahe Tardy 
191*7ae4eb14SMahe Tardy /**
192*7ae4eb14SMahe Tardy  * bpf_ksock_acquire() - Acquire a reference to a BPF kernel socket.
193*7ae4eb14SMahe Tardy  * @ks:	The BPF kernel socket context to acquire. Must be a
194*7ae4eb14SMahe Tardy  *	trusted pointer (e.g. RCU-protected kptr from a map).
195*7ae4eb14SMahe Tardy  *
196*7ae4eb14SMahe Tardy  * The acquired context must either be stored in a map as a kptr, or
197*7ae4eb14SMahe Tardy  * freed with bpf_ksock_release().
198*7ae4eb14SMahe Tardy  */
bpf_ksock_acquire(struct bpf_ksock * ks)199*7ae4eb14SMahe Tardy __bpf_kfunc struct bpf_ksock *bpf_ksock_acquire(struct bpf_ksock *ks)
200*7ae4eb14SMahe Tardy {
201*7ae4eb14SMahe Tardy 	if (!refcount_inc_not_zero(&ks->usage))
202*7ae4eb14SMahe Tardy 		return NULL;
203*7ae4eb14SMahe Tardy 	return ks;
204*7ae4eb14SMahe Tardy }
205*7ae4eb14SMahe Tardy 
206*7ae4eb14SMahe Tardy /**
207*7ae4eb14SMahe Tardy  * bpf_ksock_release() - Release a BPF kernel socket.
208*7ae4eb14SMahe Tardy  * @ks:	The BPF kernel socket context to release.
209*7ae4eb14SMahe Tardy  *
210*7ae4eb14SMahe Tardy  * When the final reference is released, the socket is cleaned up via
211*7ae4eb14SMahe Tardy  * queue_rcu_work() (since sock_release may sleep).
212*7ae4eb14SMahe Tardy  */
bpf_ksock_release(struct bpf_ksock * ks)213*7ae4eb14SMahe Tardy __bpf_kfunc void bpf_ksock_release(struct bpf_ksock *ks)
214*7ae4eb14SMahe Tardy {
215*7ae4eb14SMahe Tardy 	if (refcount_dec_and_test(&ks->usage)) {
216*7ae4eb14SMahe Tardy 		INIT_RCU_WORK(&ks->rwork, ksock_release_work_fn);
217*7ae4eb14SMahe Tardy 		queue_rcu_work(system_dfl_wq, &ks->rwork);
218*7ae4eb14SMahe Tardy 	}
219*7ae4eb14SMahe Tardy }
220*7ae4eb14SMahe Tardy 
bpf_ksock_release_dtor(void * ks)221*7ae4eb14SMahe Tardy __bpf_kfunc void bpf_ksock_release_dtor(void *ks)
222*7ae4eb14SMahe Tardy {
223*7ae4eb14SMahe Tardy 	bpf_ksock_release(ks);
224*7ae4eb14SMahe Tardy }
225*7ae4eb14SMahe Tardy CFI_NOSEAL(bpf_ksock_release_dtor);
226*7ae4eb14SMahe Tardy 
227*7ae4eb14SMahe Tardy /**
228*7ae4eb14SMahe Tardy  * bpf_ksock_send() - Send data through a BPF kernel socket.
229*7ae4eb14SMahe Tardy  * @ks:		The BPF kernel socket context. Must be an acquired reference.
230*7ae4eb14SMahe Tardy  * @data:	Pointer to the data to send.
231*7ae4eb14SMahe Tardy  * @data__sz:	Size of the data to send.
232*7ae4eb14SMahe Tardy  *
233*7ae4eb14SMahe Tardy  * Sends data on a connected socket, best-effort and nonblocking. This may sleep
234*7ae4eb14SMahe Tardy  * (kernel_sendmsg), so it can only be called from sleepable BPF programs.
235*7ae4eb14SMahe Tardy  *
236*7ae4eb14SMahe Tardy  * Return: Number of bytes sent on success, negative errno on error.
237*7ae4eb14SMahe Tardy  */
bpf_ksock_send(struct bpf_ksock * ks,const void * data,u32 data__sz)238*7ae4eb14SMahe Tardy __bpf_kfunc int bpf_ksock_send(struct bpf_ksock *ks, const void *data,
239*7ae4eb14SMahe Tardy 			       u32 data__sz)
240*7ae4eb14SMahe Tardy {
241*7ae4eb14SMahe Tardy 	struct msghdr msg = {
242*7ae4eb14SMahe Tardy 		.msg_flags = MSG_DONTWAIT,
243*7ae4eb14SMahe Tardy 	};
244*7ae4eb14SMahe Tardy 	struct kvec iov = {
245*7ae4eb14SMahe Tardy 		.iov_base = (void *)data,
246*7ae4eb14SMahe Tardy 		.iov_len = data__sz,
247*7ae4eb14SMahe Tardy 	};
248*7ae4eb14SMahe Tardy 	int ret;
249*7ae4eb14SMahe Tardy 
250*7ae4eb14SMahe Tardy 	if (!bpf_ksock_has_user_task_context())
251*7ae4eb14SMahe Tardy 		return -EOPNOTSUPP;
252*7ae4eb14SMahe Tardy 
253*7ae4eb14SMahe Tardy 	ret = kernel_sendmsg(ks->sock, &msg, &iov, 1, data__sz);
254*7ae4eb14SMahe Tardy 
255*7ae4eb14SMahe Tardy 	return ret;
256*7ae4eb14SMahe Tardy }
257*7ae4eb14SMahe Tardy 
258*7ae4eb14SMahe Tardy __bpf_kfunc_end_defs();
259*7ae4eb14SMahe Tardy 
260*7ae4eb14SMahe Tardy BTF_KFUNCS_START(ksock_init_kfunc_btf_ids)
261*7ae4eb14SMahe Tardy BTF_ID_FLAGS(func, bpf_ksock_create, KF_ACQUIRE | KF_RET_NULL | KF_SLEEPABLE)
262*7ae4eb14SMahe Tardy BTF_ID_FLAGS(func, bpf_ksock_connect, KF_SLEEPABLE)
263*7ae4eb14SMahe Tardy BTF_KFUNCS_END(ksock_init_kfunc_btf_ids)
264*7ae4eb14SMahe Tardy 
265*7ae4eb14SMahe Tardy static const struct btf_kfunc_id_set ksock_init_kfunc_set = {
266*7ae4eb14SMahe Tardy 	.owner = THIS_MODULE,
267*7ae4eb14SMahe Tardy 	.set = &ksock_init_kfunc_btf_ids,
268*7ae4eb14SMahe Tardy };
269*7ae4eb14SMahe Tardy 
270*7ae4eb14SMahe Tardy BTF_KFUNCS_START(ksock_kfunc_btf_ids)
BTF_ID_FLAGS(func,bpf_ksock_release,KF_RELEASE)271*7ae4eb14SMahe Tardy BTF_ID_FLAGS(func, bpf_ksock_release, KF_RELEASE)
272*7ae4eb14SMahe Tardy BTF_ID_FLAGS(func, bpf_ksock_acquire, KF_ACQUIRE | KF_RCU | KF_RET_NULL)
273*7ae4eb14SMahe Tardy BTF_ID_FLAGS(func, bpf_ksock_send, KF_SLEEPABLE)
274*7ae4eb14SMahe Tardy BTF_KFUNCS_END(ksock_kfunc_btf_ids)
275*7ae4eb14SMahe Tardy 
276*7ae4eb14SMahe Tardy #ifdef CONFIG_BPF_LSM
277*7ae4eb14SMahe Tardy BTF_ID_LIST_SINGLE(bpf_lsm_socket_sendmsg_id, func, bpf_lsm_socket_sendmsg)
278*7ae4eb14SMahe Tardy #endif
279*7ae4eb14SMahe Tardy 
280*7ae4eb14SMahe Tardy static int bpf_ksock_kfunc_filter(const struct bpf_prog *prog, u32 kfunc_id)
281*7ae4eb14SMahe Tardy {
282*7ae4eb14SMahe Tardy 	if (!btf_id_set8_contains(&ksock_kfunc_btf_ids, kfunc_id))
283*7ae4eb14SMahe Tardy 		return 0;
284*7ae4eb14SMahe Tardy 
285*7ae4eb14SMahe Tardy 	if (prog->type == BPF_PROG_TYPE_SYSCALL)
286*7ae4eb14SMahe Tardy 		return 0;
287*7ae4eb14SMahe Tardy 
288*7ae4eb14SMahe Tardy #ifdef CONFIG_BPF_LSM
289*7ae4eb14SMahe Tardy 	if (prog->type == BPF_PROG_TYPE_LSM &&
290*7ae4eb14SMahe Tardy 	    prog->aux->attach_btf_id != bpf_lsm_socket_sendmsg_id[0])
291*7ae4eb14SMahe Tardy 		return 0;
292*7ae4eb14SMahe Tardy #endif
293*7ae4eb14SMahe Tardy 
294*7ae4eb14SMahe Tardy 	return -EACCES;
295*7ae4eb14SMahe Tardy }
296*7ae4eb14SMahe Tardy 
297*7ae4eb14SMahe Tardy static const struct btf_kfunc_id_set ksock_kfunc_set = {
298*7ae4eb14SMahe Tardy 	.owner = THIS_MODULE,
299*7ae4eb14SMahe Tardy 	.set = &ksock_kfunc_btf_ids,
300*7ae4eb14SMahe Tardy 	.filter = bpf_ksock_kfunc_filter,
301*7ae4eb14SMahe Tardy };
302*7ae4eb14SMahe Tardy 
303*7ae4eb14SMahe Tardy BTF_ID_LIST(bpf_ksock_dtor_ids)
BTF_ID(struct,bpf_ksock)304*7ae4eb14SMahe Tardy BTF_ID(struct, bpf_ksock)
305*7ae4eb14SMahe Tardy BTF_ID(func, bpf_ksock_release_dtor)
306*7ae4eb14SMahe Tardy 
307*7ae4eb14SMahe Tardy static int __init bpf_ksock_kfunc_init(void)
308*7ae4eb14SMahe Tardy {
309*7ae4eb14SMahe Tardy 	int ret;
310*7ae4eb14SMahe Tardy 	const struct btf_id_dtor_kfunc bpf_ksock_dtors[] = {
311*7ae4eb14SMahe Tardy 		{
312*7ae4eb14SMahe Tardy 			.btf_id = bpf_ksock_dtor_ids[0],
313*7ae4eb14SMahe Tardy 			.kfunc_btf_id = bpf_ksock_dtor_ids[1],
314*7ae4eb14SMahe Tardy 		},
315*7ae4eb14SMahe Tardy 	};
316*7ae4eb14SMahe Tardy 
317*7ae4eb14SMahe Tardy 	ret = register_btf_kfunc_id_set(BPF_PROG_TYPE_SYSCALL,
318*7ae4eb14SMahe Tardy 					&ksock_init_kfunc_set);
319*7ae4eb14SMahe Tardy 	ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_SYSCALL,
320*7ae4eb14SMahe Tardy 					       &ksock_kfunc_set);
321*7ae4eb14SMahe Tardy 	ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_LSM,
322*7ae4eb14SMahe Tardy 					       &ksock_kfunc_set);
323*7ae4eb14SMahe Tardy 	return ret ?: register_btf_id_dtor_kfuncs(bpf_ksock_dtors,
324*7ae4eb14SMahe Tardy 						  ARRAY_SIZE(bpf_ksock_dtors),
325*7ae4eb14SMahe Tardy 						  THIS_MODULE);
326*7ae4eb14SMahe Tardy }
327*7ae4eb14SMahe Tardy 
328*7ae4eb14SMahe Tardy late_initcall(bpf_ksock_kfunc_init);
329