1*c7838e3dSMahe Tardy /* SPDX-License-Identifier: GPL-2.0 */
2*c7838e3dSMahe Tardy /* Copyright (c) 2026 Isovalent */
3*c7838e3dSMahe Tardy
4*c7838e3dSMahe Tardy #ifndef _KSOCK_COMMON_H
5*c7838e3dSMahe Tardy #define _KSOCK_COMMON_H
6*c7838e3dSMahe Tardy
7*c7838e3dSMahe Tardy #include "errno.h"
8*c7838e3dSMahe Tardy
9*c7838e3dSMahe Tardy #define SOCK_DGRAM 2
10*c7838e3dSMahe Tardy #define IPPROTO_UDP 17
11*c7838e3dSMahe Tardy
12*c7838e3dSMahe Tardy struct bpf_ksock *bpf_ksock_create(const struct bpf_ksock_create_opts *opts,
13*c7838e3dSMahe Tardy u32 opts__sz, int *err__uninit) __ksym;
14*c7838e3dSMahe Tardy int bpf_ksock_connect(struct bpf_ksock *ks, const union bpf_ksock_addr *addr,
15*c7838e3dSMahe Tardy u32 addr__sz) __ksym;
16*c7838e3dSMahe Tardy struct bpf_ksock *bpf_ksock_acquire(struct bpf_ksock *ks) __ksym;
17*c7838e3dSMahe Tardy void bpf_ksock_release(struct bpf_ksock *ks) __ksym;
18*c7838e3dSMahe Tardy int bpf_ksock_send(struct bpf_ksock *ks, const void *data, u32 data__sz) __ksym;
19*c7838e3dSMahe Tardy void bpf_rcu_read_lock(void) __ksym;
20*c7838e3dSMahe Tardy void bpf_rcu_read_unlock(void) __ksym;
21*c7838e3dSMahe Tardy
22*c7838e3dSMahe Tardy struct __ksock_ctx_value {
23*c7838e3dSMahe Tardy struct bpf_ksock __kptr * ctx;
24*c7838e3dSMahe Tardy };
25*c7838e3dSMahe Tardy
26*c7838e3dSMahe Tardy struct {
27*c7838e3dSMahe Tardy __uint(type, BPF_MAP_TYPE_ARRAY);
28*c7838e3dSMahe Tardy __type(key, int);
29*c7838e3dSMahe Tardy __type(value, struct __ksock_ctx_value);
30*c7838e3dSMahe Tardy __uint(max_entries, 1);
31*c7838e3dSMahe Tardy } __ksock_ctx_map SEC(".maps");
32*c7838e3dSMahe Tardy
ksock_ctx_value_lookup(void)33*c7838e3dSMahe Tardy static inline struct __ksock_ctx_value *ksock_ctx_value_lookup(void)
34*c7838e3dSMahe Tardy {
35*c7838e3dSMahe Tardy u32 key = 0;
36*c7838e3dSMahe Tardy
37*c7838e3dSMahe Tardy return bpf_map_lookup_elem(&__ksock_ctx_map, &key);
38*c7838e3dSMahe Tardy }
39*c7838e3dSMahe Tardy
ksock_ctx_get(void)40*c7838e3dSMahe Tardy static inline struct bpf_ksock *ksock_ctx_get(void)
41*c7838e3dSMahe Tardy {
42*c7838e3dSMahe Tardy struct __ksock_ctx_value *v;
43*c7838e3dSMahe Tardy struct bpf_ksock *ks = NULL, *tmp;
44*c7838e3dSMahe Tardy
45*c7838e3dSMahe Tardy v = ksock_ctx_value_lookup();
46*c7838e3dSMahe Tardy if (!v)
47*c7838e3dSMahe Tardy return NULL;
48*c7838e3dSMahe Tardy
49*c7838e3dSMahe Tardy bpf_rcu_read_lock();
50*c7838e3dSMahe Tardy tmp = v->ctx;
51*c7838e3dSMahe Tardy if (tmp)
52*c7838e3dSMahe Tardy ks = bpf_ksock_acquire(tmp);
53*c7838e3dSMahe Tardy bpf_rcu_read_unlock();
54*c7838e3dSMahe Tardy
55*c7838e3dSMahe Tardy return ks;
56*c7838e3dSMahe Tardy }
57*c7838e3dSMahe Tardy
ksock_ctx_insert(struct bpf_ksock * ctx)58*c7838e3dSMahe Tardy static inline int ksock_ctx_insert(struct bpf_ksock *ctx)
59*c7838e3dSMahe Tardy {
60*c7838e3dSMahe Tardy struct __ksock_ctx_value *v;
61*c7838e3dSMahe Tardy struct bpf_ksock *old;
62*c7838e3dSMahe Tardy
63*c7838e3dSMahe Tardy v = ksock_ctx_value_lookup();
64*c7838e3dSMahe Tardy if (!v) {
65*c7838e3dSMahe Tardy bpf_ksock_release(ctx);
66*c7838e3dSMahe Tardy return -ENOENT;
67*c7838e3dSMahe Tardy }
68*c7838e3dSMahe Tardy
69*c7838e3dSMahe Tardy old = bpf_kptr_xchg(&v->ctx, ctx);
70*c7838e3dSMahe Tardy if (old) {
71*c7838e3dSMahe Tardy bpf_ksock_release(old);
72*c7838e3dSMahe Tardy return -EEXIST;
73*c7838e3dSMahe Tardy }
74*c7838e3dSMahe Tardy
75*c7838e3dSMahe Tardy return 0;
76*c7838e3dSMahe Tardy }
77*c7838e3dSMahe Tardy
78*c7838e3dSMahe Tardy #endif /* _KSOCK_COMMON_H */
79