Skip to content

Commit ac06587

Browse files
anakryikoAlexei Starovoitov
authored and
Alexei Starovoitov
committed
selftests/bpf: Add BPF_PROG, BPF_KPROBE, and BPF_KRETPROBE macros
Streamline BPF_TRACE_x macro by moving out return type and section attribute definition out of macro itself. That makes those function look in source code similar to other BPF programs. Additionally, simplify its usage by determining number of arguments automatically (so just single BPF_TRACE vs a family of BPF_TRACE_1, BPF_TRACE_2, etc). Also, allow more natural function argument syntax without commas inbetween argument type and name. Given this helper is useful not only for tracing tp_btf/fenty/fexit programs, but could be used for LSM programs and others following the same pattern, rename BPF_TRACE macro into more generic BPF_PROG. Existing BPF_TRACE_x usages in selftests are converted to new BPF_PROG macro. Following the same pattern, define BPF_KPROBE and BPF_KRETPROBE macros for nicer usage of kprobe/kretprobe arguments, respectively. BPF_KRETPROBE, adopts same convention used by fexit programs, that last defined argument is probed function's return result. v4->v5: - fix test_overhead test (__set_task_comm is void) (Alexei); v3->v4: - rebased and fixed one more BPF_TRACE_x occurence (Alexei); v2->v3: - rename to shorter and as generic BPF_PROG (Alexei); v1->v2: - verified GCC handles pragmas as expected; - added descriptions to macros; - converted new STRUCT_OPS selftest to BPF_HANDLER (worked as expected); - added original context as 'ctx' parameter, for cases where it has to be passed into BPF helpers. This might cause an accidental naming collision, unfortunately, but at least it's easy to work around. Fortunately, this situation produces quite legible compilation error: progs/bpf_dctcp.c:46:6: error: redefinition of 'ctx' with a different type: 'int' vs 'unsigned long long *' int ctx = 123; ^ progs/bpf_dctcp.c:42:6: note: previous definition is here void BPF_HANDLER(dctcp_init, struct sock *sk) ^ ./bpf_trace_helpers.h:58:32: note: expanded from macro 'BPF_HANDLER' ____##name(unsigned long long *ctx, ##args) Signed-off-by: Andrii Nakryiko <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]> Acked-by: Martin KaFai Lau <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent 1d1a3bc commit ac06587

11 files changed

+193
-121
lines changed

tools/testing/selftests/bpf/bpf_tcp_helpers.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,6 @@
66
#include <linux/types.h>
77
#include <bpf_helpers.h>
88
#include <bpf_core_read.h>
9-
#include "bpf_trace_helpers.h"
10-
11-
/* "struct_ops/" is only a convention. not a requirement. */
12-
#define BPF_TCP_OPS_0(fname, ret_type, ...) BPF_TRACE_x(0, "struct_ops/"#fname, fname, ret_type, __VA_ARGS__)
13-
#define BPF_TCP_OPS_1(fname, ret_type, ...) BPF_TRACE_x(1, "struct_ops/"#fname, fname, ret_type, __VA_ARGS__)
14-
#define BPF_TCP_OPS_2(fname, ret_type, ...) BPF_TRACE_x(2, "struct_ops/"#fname, fname, ret_type, __VA_ARGS__)
15-
#define BPF_TCP_OPS_3(fname, ret_type, ...) BPF_TRACE_x(3, "struct_ops/"#fname, fname, ret_type, __VA_ARGS__)
16-
#define BPF_TCP_OPS_4(fname, ret_type, ...) BPF_TRACE_x(4, "struct_ops/"#fname, fname, ret_type, __VA_ARGS__)
17-
#define BPF_TCP_OPS_5(fname, ret_type, ...) BPF_TRACE_x(5, "struct_ops/"#fname, fname, ret_type, __VA_ARGS__)
189

1910
struct sock_common {
2011
unsigned char skc_state;
Lines changed: 114 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,120 @@
1-
/* SPDX-License-Identifier: GPL-2.0 */
1+
/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
22
#ifndef __BPF_TRACE_HELPERS_H
33
#define __BPF_TRACE_HELPERS_H
44

5-
#include "bpf_helpers.h"
6-
7-
#define __BPF_MAP_0(i, m, v, ...) v
8-
#define __BPF_MAP_1(i, m, v, t, a, ...) m(t, a, ctx[i])
9-
#define __BPF_MAP_2(i, m, v, t, a, ...) m(t, a, ctx[i]), __BPF_MAP_1(i+1, m, v, __VA_ARGS__)
10-
#define __BPF_MAP_3(i, m, v, t, a, ...) m(t, a, ctx[i]), __BPF_MAP_2(i+1, m, v, __VA_ARGS__)
11-
#define __BPF_MAP_4(i, m, v, t, a, ...) m(t, a, ctx[i]), __BPF_MAP_3(i+1, m, v, __VA_ARGS__)
12-
#define __BPF_MAP_5(i, m, v, t, a, ...) m(t, a, ctx[i]), __BPF_MAP_4(i+1, m, v, __VA_ARGS__)
13-
#define __BPF_MAP_6(i, m, v, t, a, ...) m(t, a, ctx[i]), __BPF_MAP_5(i+1, m, v, __VA_ARGS__)
14-
#define __BPF_MAP_7(i, m, v, t, a, ...) m(t, a, ctx[i]), __BPF_MAP_6(i+1, m, v, __VA_ARGS__)
15-
#define __BPF_MAP_8(i, m, v, t, a, ...) m(t, a, ctx[i]), __BPF_MAP_7(i+1, m, v, __VA_ARGS__)
16-
#define __BPF_MAP_9(i, m, v, t, a, ...) m(t, a, ctx[i]), __BPF_MAP_8(i+1, m, v, __VA_ARGS__)
17-
#define __BPF_MAP_10(i, m, v, t, a, ...) m(t, a, ctx[i]), __BPF_MAP_9(i+1, m, v, __VA_ARGS__)
18-
#define __BPF_MAP_11(i, m, v, t, a, ...) m(t, a, ctx[i]), __BPF_MAP_10(i+1, m, v, __VA_ARGS__)
19-
#define __BPF_MAP_12(i, m, v, t, a, ...) m(t, a, ctx[i]), __BPF_MAP_11(i+1, m, v, __VA_ARGS__)
20-
#define __BPF_MAP(n, ...) __BPF_MAP_##n(0, __VA_ARGS__)
21-
22-
/* BPF sizeof(void *) is always 8, so no need to cast to long first
23-
* for ptr to avoid compiler warning.
5+
#include <bpf_helpers.h>
6+
7+
#define ___bpf_concat(a, b) a ## b
8+
#define ___bpf_apply(fn, n) ___bpf_concat(fn, n)
9+
#define ___bpf_nth(_, _1, _2, _3, _4, _5, _6, _7, _8, _9, _a, _b, _c, N, ...) N
10+
#define ___bpf_narg(...) \
11+
___bpf_nth(_, ##__VA_ARGS__, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
12+
#define ___bpf_empty(...) \
13+
___bpf_nth(_, ##__VA_ARGS__, N, N, N, N, N, N, N, N, N, N, 0)
14+
15+
#define ___bpf_ctx_cast0() ctx
16+
#define ___bpf_ctx_cast1(x) ___bpf_ctx_cast0(), (void *)ctx[0]
17+
#define ___bpf_ctx_cast2(x, args...) ___bpf_ctx_cast1(args), (void *)ctx[1]
18+
#define ___bpf_ctx_cast3(x, args...) ___bpf_ctx_cast2(args), (void *)ctx[2]
19+
#define ___bpf_ctx_cast4(x, args...) ___bpf_ctx_cast3(args), (void *)ctx[3]
20+
#define ___bpf_ctx_cast5(x, args...) ___bpf_ctx_cast4(args), (void *)ctx[4]
21+
#define ___bpf_ctx_cast6(x, args...) ___bpf_ctx_cast5(args), (void *)ctx[5]
22+
#define ___bpf_ctx_cast7(x, args...) ___bpf_ctx_cast6(args), (void *)ctx[6]
23+
#define ___bpf_ctx_cast8(x, args...) ___bpf_ctx_cast7(args), (void *)ctx[7]
24+
#define ___bpf_ctx_cast9(x, args...) ___bpf_ctx_cast8(args), (void *)ctx[8]
25+
#define ___bpf_ctx_cast10(x, args...) ___bpf_ctx_cast9(args), (void *)ctx[9]
26+
#define ___bpf_ctx_cast11(x, args...) ___bpf_ctx_cast10(args), (void *)ctx[10]
27+
#define ___bpf_ctx_cast12(x, args...) ___bpf_ctx_cast11(args), (void *)ctx[11]
28+
#define ___bpf_ctx_cast(args...) \
29+
___bpf_apply(___bpf_ctx_cast, ___bpf_narg(args))(args)
30+
31+
/*
32+
* BPF_PROG is a convenience wrapper for generic tp_btf/fentry/fexit and
33+
* similar kinds of BPF programs, that accept input arguments as a single
34+
* pointer to untyped u64 array, where each u64 can actually be a typed
35+
* pointer or integer of different size. Instead of requring user to write
36+
* manual casts and work with array elements by index, BPF_PROG macro
37+
* allows user to declare a list of named and typed input arguments in the
38+
* same syntax as for normal C function. All the casting is hidden and
39+
* performed transparently, while user code can just assume working with
40+
* function arguments of specified type and name.
41+
*
42+
* Original raw context argument is preserved as well as 'ctx' argument.
43+
* This is useful when using BPF helpers that expect original context
44+
* as one of the parameters (e.g., for bpf_perf_event_output()).
2445
*/
25-
#define __BPF_CAST(t, a, ctx) (t) ctx
26-
#define __BPF_V void
27-
#define __BPF_N
28-
29-
#define __BPF_DECL_ARGS(t, a, ctx) t a
30-
31-
#define BPF_TRACE_x(x, sec_name, fname, ret_type, ...) \
32-
static __always_inline ret_type \
33-
____##fname(__BPF_MAP(x, __BPF_DECL_ARGS, __BPF_V, __VA_ARGS__)); \
34-
\
35-
SEC(sec_name) \
36-
ret_type fname(__u64 *ctx) \
37-
{ \
38-
return ____##fname(__BPF_MAP(x, __BPF_CAST, __BPF_N, __VA_ARGS__));\
39-
} \
40-
\
41-
static __always_inline \
42-
ret_type ____##fname(__BPF_MAP(x, __BPF_DECL_ARGS, __BPF_V, __VA_ARGS__))
43-
44-
#define BPF_TRACE_0(sec, fname, ...) BPF_TRACE_x(0, sec, fname, int, __VA_ARGS__)
45-
#define BPF_TRACE_1(sec, fname, ...) BPF_TRACE_x(1, sec, fname, int, __VA_ARGS__)
46-
#define BPF_TRACE_2(sec, fname, ...) BPF_TRACE_x(2, sec, fname, int, __VA_ARGS__)
47-
#define BPF_TRACE_3(sec, fname, ...) BPF_TRACE_x(3, sec, fname, int, __VA_ARGS__)
48-
#define BPF_TRACE_4(sec, fname, ...) BPF_TRACE_x(4, sec, fname, int, __VA_ARGS__)
49-
#define BPF_TRACE_5(sec, fname, ...) BPF_TRACE_x(5, sec, fname, int, __VA_ARGS__)
50-
#define BPF_TRACE_6(sec, fname, ...) BPF_TRACE_x(6, sec, fname, int, __VA_ARGS__)
51-
#define BPF_TRACE_7(sec, fname, ...) BPF_TRACE_x(7, sec, fname, int, __VA_ARGS__)
52-
#define BPF_TRACE_8(sec, fname, ...) BPF_TRACE_x(8, sec, fname, int, __VA_ARGS__)
53-
#define BPF_TRACE_9(sec, fname, ...) BPF_TRACE_x(9, sec, fname, int, __VA_ARGS__)
54-
#define BPF_TRACE_10(sec, fname, ...) BPF_TRACE_x(10, sec, fname, int, __VA_ARGS__)
55-
#define BPF_TRACE_11(sec, fname, ...) BPF_TRACE_x(11, sec, fname, int, __VA_ARGS__)
56-
#define BPF_TRACE_12(sec, fname, ...) BPF_TRACE_x(12, sec, fname, int, __VA_ARGS__)
46+
#define BPF_PROG(name, args...) \
47+
name(unsigned long long *ctx); \
48+
static __always_inline typeof(name(0)) \
49+
____##name(unsigned long long *ctx, ##args); \
50+
typeof(name(0)) name(unsigned long long *ctx) \
51+
{ \
52+
_Pragma("GCC diagnostic push") \
53+
_Pragma("GCC diagnostic ignored \"-Wint-conversion\"") \
54+
return ____##name(___bpf_ctx_cast(args)); \
55+
_Pragma("GCC diagnostic pop") \
56+
} \
57+
static __always_inline typeof(name(0)) \
58+
____##name(unsigned long long *ctx, ##args)
59+
60+
struct pt_regs;
61+
62+
#define ___bpf_kprobe_args0() ctx
63+
#define ___bpf_kprobe_args1(x) \
64+
___bpf_kprobe_args0(), (void *)PT_REGS_PARM1(ctx)
65+
#define ___bpf_kprobe_args2(x, args...) \
66+
___bpf_kprobe_args1(args), (void *)PT_REGS_PARM2(ctx)
67+
#define ___bpf_kprobe_args3(x, args...) \
68+
___bpf_kprobe_args2(args), (void *)PT_REGS_PARM3(ctx)
69+
#define ___bpf_kprobe_args4(x, args...) \
70+
___bpf_kprobe_args3(args), (void *)PT_REGS_PARM4(ctx)
71+
#define ___bpf_kprobe_args5(x, args...) \
72+
___bpf_kprobe_args4(args), (void *)PT_REGS_PARM5(ctx)
73+
#define ___bpf_kprobe_args(args...) \
74+
___bpf_apply(___bpf_kprobe_args, ___bpf_narg(args))(args)
5775

76+
/*
77+
* BPF_KPROBE serves the same purpose for kprobes as BPF_PROG for
78+
* tp_btf/fentry/fexit BPF programs. It hides the underlying platform-specific
79+
* low-level way of getting kprobe input arguments from struct pt_regs, and
80+
* provides a familiar typed and named function arguments syntax and
81+
* semantics of accessing kprobe input paremeters.
82+
*
83+
* Original struct pt_regs* context is preserved as 'ctx' argument. This might
84+
* be necessary when using BPF helpers like bpf_perf_event_output().
85+
*/
86+
#define BPF_KPROBE(name, args...) \
87+
name(struct pt_regs *ctx); \
88+
static __always_inline typeof(name(0)) ____##name(struct pt_regs *ctx, ##args);\
89+
typeof(name(0)) name(struct pt_regs *ctx) \
90+
{ \
91+
_Pragma("GCC diagnostic push") \
92+
_Pragma("GCC diagnostic ignored \"-Wint-conversion\"") \
93+
return ____##name(___bpf_kprobe_args(args)); \
94+
_Pragma("GCC diagnostic pop") \
95+
} \
96+
static __always_inline typeof(name(0)) ____##name(struct pt_regs *ctx, ##args)
97+
98+
#define ___bpf_kretprobe_args0() ctx
99+
#define ___bpf_kretprobe_argsN(x, args...) \
100+
___bpf_kprobe_args(args), (void *)PT_REGS_RET(ctx)
101+
#define ___bpf_kretprobe_args(args...) \
102+
___bpf_apply(___bpf_kretprobe_args, ___bpf_empty(args))(args)
103+
104+
/*
105+
* BPF_KRETPROBE is similar to BPF_KPROBE, except, in addition to listing all
106+
* input kprobe arguments, one last extra argument has to be specified, which
107+
* captures kprobe return value.
108+
*/
109+
#define BPF_KRETPROBE(name, args...) \
110+
name(struct pt_regs *ctx); \
111+
static __always_inline typeof(name(0)) ____##name(struct pt_regs *ctx, ##args);\
112+
typeof(name(0)) name(struct pt_regs *ctx) \
113+
{ \
114+
_Pragma("GCC diagnostic push") \
115+
_Pragma("GCC diagnostic ignored \"-Wint-conversion\"") \
116+
return ____##name(___bpf_kretprobe_args(args)); \
117+
_Pragma("GCC diagnostic pop") \
118+
} \
119+
static __always_inline typeof(name(0)) ____##name(struct pt_regs *ctx, ##args)
58120
#endif

tools/testing/selftests/bpf/progs/bpf_dctcp.c

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
#include <linux/bpf.h>
1010
#include <linux/types.h>
11+
#include <bpf_helpers.h>
12+
#include <bpf_trace_helpers.h>
1113
#include "bpf_tcp_helpers.h"
1214

1315
char _license[] SEC("license") = "GPL";
@@ -36,7 +38,8 @@ static __always_inline void dctcp_reset(const struct tcp_sock *tp,
3638
ca->old_delivered_ce = tp->delivered_ce;
3739
}
3840

39-
BPF_TCP_OPS_1(dctcp_init, void, struct sock *, sk)
41+
SEC("struct_ops/dctcp_init")
42+
void BPF_PROG(dctcp_init, struct sock *sk)
4043
{
4144
const struct tcp_sock *tp = tcp_sk(sk);
4245
struct dctcp *ca = inet_csk_ca(sk);
@@ -49,7 +52,8 @@ BPF_TCP_OPS_1(dctcp_init, void, struct sock *, sk)
4952
dctcp_reset(tp, ca);
5053
}
5154

52-
BPF_TCP_OPS_1(dctcp_ssthresh, __u32, struct sock *, sk)
55+
SEC("struct_ops/dctcp_ssthresh")
56+
__u32 BPF_PROG(dctcp_ssthresh, struct sock *sk)
5357
{
5458
struct dctcp *ca = inet_csk_ca(sk);
5559
struct tcp_sock *tp = tcp_sk(sk);
@@ -58,8 +62,8 @@ BPF_TCP_OPS_1(dctcp_ssthresh, __u32, struct sock *, sk)
5862
return max(tp->snd_cwnd - ((tp->snd_cwnd * ca->dctcp_alpha) >> 11U), 2U);
5963
}
6064

61-
BPF_TCP_OPS_2(dctcp_update_alpha, void,
62-
struct sock *, sk, __u32, flags)
65+
SEC("struct_ops/dctcp_update_alpha")
66+
void BPF_PROG(dctcp_update_alpha, struct sock *sk, __u32 flags)
6367
{
6468
const struct tcp_sock *tp = tcp_sk(sk);
6569
struct dctcp *ca = inet_csk_ca(sk);
@@ -97,7 +101,8 @@ static __always_inline void dctcp_react_to_loss(struct sock *sk)
97101
tp->snd_ssthresh = max(tp->snd_cwnd >> 1U, 2U);
98102
}
99103

100-
BPF_TCP_OPS_2(dctcp_state, void, struct sock *, sk, __u8, new_state)
104+
SEC("struct_ops/dctcp_state")
105+
void BPF_PROG(dctcp_state, struct sock *sk, __u8 new_state)
101106
{
102107
if (new_state == TCP_CA_Recovery &&
103108
new_state != BPF_CORE_READ_BITFIELD(inet_csk(sk), icsk_ca_state))
@@ -144,8 +149,8 @@ void dctcp_ece_ack_update(struct sock *sk, enum tcp_ca_event evt,
144149
dctcp_ece_ack_cwr(sk, new_ce_state);
145150
}
146151

147-
BPF_TCP_OPS_2(dctcp_cwnd_event, void,
148-
struct sock *, sk, enum tcp_ca_event, ev)
152+
SEC("struct_ops/dctcp_cwnd_event")
153+
void BPF_PROG(dctcp_cwnd_event, struct sock *sk, enum tcp_ca_event ev)
149154
{
150155
struct dctcp *ca = inet_csk_ca(sk);
151156

@@ -163,15 +168,16 @@ BPF_TCP_OPS_2(dctcp_cwnd_event, void,
163168
}
164169
}
165170

166-
BPF_TCP_OPS_1(dctcp_cwnd_undo, __u32, struct sock *, sk)
171+
SEC("struct_ops/dctcp_cwnd_undo")
172+
__u32 BPF_PROG(dctcp_cwnd_undo, struct sock *sk)
167173
{
168174
const struct dctcp *ca = inet_csk_ca(sk);
169175

170176
return max(tcp_sk(sk)->snd_cwnd, ca->loss_cwnd);
171177
}
172178

173-
BPF_TCP_OPS_3(tcp_reno_cong_avoid, void,
174-
struct sock *, sk, __u32, ack, __u32, acked)
179+
SEC("struct_ops/tcp_reno_cong_avoid")
180+
void BPF_PROG(tcp_reno_cong_avoid, struct sock *sk, __u32 ack, __u32 acked)
175181
{
176182
struct tcp_sock *tp = tcp_sk(sk);
177183

tools/testing/selftests/bpf/progs/fentry_test.c

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,46 +7,49 @@
77
char _license[] SEC("license") = "GPL";
88

99
__u64 test1_result = 0;
10-
BPF_TRACE_1("fentry/bpf_fentry_test1", test1, int, a)
10+
SEC("fentry/bpf_fentry_test1")
11+
int BPF_PROG(test1, int a)
1112
{
1213
test1_result = a == 1;
1314
return 0;
1415
}
1516

1617
__u64 test2_result = 0;
17-
BPF_TRACE_2("fentry/bpf_fentry_test2", test2, int, a, __u64, b)
18+
SEC("fentry/bpf_fentry_test2")
19+
int BPF_PROG(test2, int a, __u64 b)
1820
{
1921
test2_result = a == 2 && b == 3;
2022
return 0;
2123
}
2224

2325
__u64 test3_result = 0;
24-
BPF_TRACE_3("fentry/bpf_fentry_test3", test3, char, a, int, b, __u64, c)
26+
SEC("fentry/bpf_fentry_test3")
27+
int BPF_PROG(test3, char a, int b, __u64 c)
2528
{
2629
test3_result = a == 4 && b == 5 && c == 6;
2730
return 0;
2831
}
2932

3033
__u64 test4_result = 0;
31-
BPF_TRACE_4("fentry/bpf_fentry_test4", test4,
32-
void *, a, char, b, int, c, __u64, d)
34+
SEC("fentry/bpf_fentry_test4")
35+
int BPF_PROG(test4, void *a, char b, int c, __u64 d)
3336
{
3437
test4_result = a == (void *)7 && b == 8 && c == 9 && d == 10;
3538
return 0;
3639
}
3740

3841
__u64 test5_result = 0;
39-
BPF_TRACE_5("fentry/bpf_fentry_test5", test5,
40-
__u64, a, void *, b, short, c, int, d, __u64, e)
42+
SEC("fentry/bpf_fentry_test5")
43+
int BPF_PROG(test5, __u64 a, void *b, short c, int d, __u64 e)
4144
{
4245
test5_result = a == 11 && b == (void *)12 && c == 13 && d == 14 &&
4346
e == 15;
4447
return 0;
4548
}
4649

4750
__u64 test6_result = 0;
48-
BPF_TRACE_6("fentry/bpf_fentry_test6", test6,
49-
__u64, a, void *, b, short, c, int, d, void *, e, __u64, f)
51+
SEC("fentry/bpf_fentry_test6")
52+
int BPF_PROG(test6, __u64 a, void *b, short c, int d, void * e, __u64 f)
5053
{
5154
test6_result = a == 16 && b == (void *)17 && c == 18 && d == 19 &&
5255
e == (void *)20 && f == 21;

tools/testing/selftests/bpf/progs/fexit_bpf2bpf.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ struct sk_buff {
99
};
1010

1111
__u64 test_result = 0;
12-
BPF_TRACE_2("fexit/test_pkt_access", test_main,
13-
struct sk_buff *, skb, int, ret)
12+
SEC("fexit/test_pkt_access")
13+
int BPF_PROG(test_main, struct sk_buff *skb, int ret)
1414
{
1515
int len;
1616

@@ -24,8 +24,8 @@ BPF_TRACE_2("fexit/test_pkt_access", test_main,
2424
}
2525

2626
__u64 test_result_subprog1 = 0;
27-
BPF_TRACE_2("fexit/test_pkt_access_subprog1", test_subprog1,
28-
struct sk_buff *, skb, int, ret)
27+
SEC("fexit/test_pkt_access_subprog1")
28+
int BPF_PROG(test_subprog1, struct sk_buff *skb, int ret)
2929
{
3030
int len;
3131

@@ -81,8 +81,8 @@ int test_subprog2(struct args_subprog2 *ctx)
8181
}
8282

8383
__u64 test_result_subprog3 = 0;
84-
BPF_TRACE_3("fexit/test_pkt_access_subprog3", test_subprog3,
85-
int, val, struct sk_buff *, skb, int, ret)
84+
SEC("fexit/test_pkt_access_subprog3")
85+
int BPF_PROG(test_subprog3, int val, struct sk_buff *skb, int ret)
8686
{
8787
int len;
8888

tools/testing/selftests/bpf/progs/fexit_bpf2bpf_simple.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@ struct sk_buff {
99
};
1010

1111
__u64 test_result = 0;
12-
BPF_TRACE_2("fexit/test_pkt_md_access", test_main2,
13-
struct sk_buff *, skb, int, ret)
12+
13+
SEC("fexit/test_pkt_md_access")
14+
int BPF_PROG(test_main2, struct sk_buff *skb, int ret)
1415
{
1516
int len;
1617

0 commit comments

Comments
 (0)