Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.8.
  1// SPDX-License-Identifier: GPL-2.0
  2
  3#include <linux/bpf.h>
  4#include <bpf/bpf_helpers.h>
  5#include <bpf/bpf_tracing.h>
  6
  7#include "bpf_misc.h"
  8
  9#define __always_unused __attribute__((unused))
 10
 11char _license[] SEC("license") = "GPL";
 12
 13struct sock {
 14} __attribute__((preserve_access_index));
 15
 16struct bpf_iter__sockmap {
 17	union {
 18		struct sock *sk;
 19	};
 20} __attribute__((preserve_access_index));
 21
 22struct {
 23	__uint(type, BPF_MAP_TYPE_SOCKHASH);
 24	__uint(max_entries, 1);
 25	__type(key, int);
 26	__type(value, int);
 27} sockhash SEC(".maps");
 28
 29struct {
 30	__uint(type, BPF_MAP_TYPE_SOCKMAP);
 31	__uint(max_entries, 1);
 32	__type(key, int);
 33	__type(value, int);
 34} sockmap SEC(".maps");
 35
 36enum { CG_OK = 1 };
 37
 38int zero = 0;
 39
 40static __always_inline void test_sockmap_delete(void)
 41{
 42	bpf_map_delete_elem(&sockmap, &zero);
 43	bpf_map_delete_elem(&sockhash, &zero);
 44}
 45
 46static __always_inline void test_sockmap_update(void *sk)
 47{
 48	if (sk) {
 49		bpf_map_update_elem(&sockmap, &zero, sk, BPF_ANY);
 50		bpf_map_update_elem(&sockhash, &zero, sk, BPF_ANY);
 51	}
 52}
 53
 54static __always_inline void test_sockmap_lookup_and_update(void)
 55{
 56	struct bpf_sock *sk = bpf_map_lookup_elem(&sockmap, &zero);
 57
 58	if (sk) {
 59		test_sockmap_update(sk);
 60		bpf_sk_release(sk);
 61	}
 62}
 63
 64static __always_inline void test_sockmap_mutate(void *sk)
 65{
 66	test_sockmap_delete();
 67	test_sockmap_update(sk);
 68}
 69
 70static __always_inline void test_sockmap_lookup_and_mutate(void)
 71{
 72	test_sockmap_delete();
 73	test_sockmap_lookup_and_update();
 74}
 75
 76SEC("action")
 77__success
 78int test_sched_act(struct __sk_buff *skb)
 79{
 80	test_sockmap_mutate(skb->sk);
 81	return 0;
 82}
 83
 84SEC("classifier")
 85__success
 86int test_sched_cls(struct __sk_buff *skb)
 87{
 88	test_sockmap_mutate(skb->sk);
 89	return 0;
 90}
 91
 92SEC("flow_dissector")
 93__success
 94int test_flow_dissector_delete(struct __sk_buff *skb __always_unused)
 95{
 96	test_sockmap_delete();
 97	return 0;
 98}
 99
100SEC("flow_dissector")
101__failure __msg("program of this type cannot use helper bpf_sk_release")
102int test_flow_dissector_update(struct __sk_buff *skb __always_unused)
103{
104	test_sockmap_lookup_and_update(); /* no access to skb->sk */
105	return 0;
106}
107
108SEC("iter/sockmap")
109__success
110int test_trace_iter(struct bpf_iter__sockmap *ctx)
111{
112	test_sockmap_mutate(ctx->sk);
113	return 0;
114}
115
116SEC("raw_tp/kfree")
117__failure __msg("cannot update sockmap in this context")
118int test_raw_tp_delete(const void *ctx __always_unused)
119{
120	test_sockmap_delete();
121	return 0;
122}
123
124SEC("raw_tp/kfree")
125__failure __msg("cannot update sockmap in this context")
126int test_raw_tp_update(const void *ctx __always_unused)
127{
128	test_sockmap_lookup_and_update();
129	return 0;
130}
131
132SEC("sk_lookup")
133__success
134int test_sk_lookup(struct bpf_sk_lookup *ctx)
135{
136	test_sockmap_mutate(ctx->sk);
137	return 0;
138}
139
140SEC("sk_reuseport")
141__success
142int test_sk_reuseport(struct sk_reuseport_md *ctx)
143{
144	test_sockmap_mutate(ctx->sk);
145	return 0;
146}
147
148SEC("socket")
149__success
150int test_socket_filter(struct __sk_buff *skb)
151{
152	test_sockmap_mutate(skb->sk);
153	return 0;
154}
155
156SEC("sockops")
157__success
158int test_sockops_delete(struct bpf_sock_ops *ctx __always_unused)
159{
160	test_sockmap_delete();
161	return CG_OK;
162}
163
164SEC("sockops")
165__failure __msg("cannot update sockmap in this context")
166int test_sockops_update(struct bpf_sock_ops *ctx)
167{
168	test_sockmap_update(ctx->sk);
169	return CG_OK;
170}
171
172SEC("sockops")
173__success
174int test_sockops_update_dedicated(struct bpf_sock_ops *ctx)
175{
176	bpf_sock_map_update(ctx, &sockmap, &zero, BPF_ANY);
177	bpf_sock_hash_update(ctx, &sockhash, &zero, BPF_ANY);
178	return CG_OK;
179}
180
181SEC("xdp")
182__success
183int test_xdp(struct xdp_md *ctx __always_unused)
184{
185	test_sockmap_lookup_and_mutate();
186	return XDP_PASS;
187}