]>
Commit | Line | Data |
---|---|---|
1d129d19 | 1 | /* |
e4225669 | 2 | * bpf_util.h BPF common code |
1d129d19 JP |
3 | * |
4 | * This program is free software; you can distribute it and/or | |
5 | * modify it under the terms of the GNU General Public License | |
6 | * as published by the Free Software Foundation; either version | |
7 | * 2 of the License, or (at your option) any later version. | |
8 | * | |
e4225669 | 9 | * Authors: Daniel Borkmann <daniel@iogearbox.net> |
1d129d19 JP |
10 | * Jiri Pirko <jiri@resnulli.us> |
11 | */ | |
12 | ||
e4225669 DB |
13 | #ifndef __BPF_UTIL__ |
14 | #define __BPF_UTIL__ | |
1d129d19 | 15 | |
11c39b5e | 16 | #include <linux/bpf.h> |
e4225669 | 17 | #include <linux/filter.h> |
32e93fb7 | 18 | #include <linux/magic.h> |
e4225669 DB |
19 | #include <linux/elf-em.h> |
20 | #include <linux/if_alg.h> | |
11c39b5e DB |
21 | |
22 | #include "utils.h" | |
4bd62446 | 23 | #include "bpf_scm.h" |
11c39b5e | 24 | |
88eea539 | 25 | #define BPF_ENV_UDS "TC_BPF_UDS" |
32e93fb7 | 26 | #define BPF_ENV_MNT "TC_BPF_MNT" |
88eea539 | 27 | |
afc1a200 DB |
28 | #ifndef BPF_MAX_LOG |
29 | # define BPF_MAX_LOG 4096 | |
30 | #endif | |
31 | ||
e4225669 DB |
32 | #define BPF_DIR_GLOBALS "globals" |
33 | ||
32e93fb7 DB |
34 | #ifndef BPF_FS_MAGIC |
35 | # define BPF_FS_MAGIC 0xcafe4a11 | |
36 | #endif | |
1d129d19 | 37 | |
32e93fb7 DB |
38 | #define BPF_DIR_MNT "/sys/fs/bpf" |
39 | ||
32e93fb7 DB |
40 | #ifndef TRACEFS_MAGIC |
41 | # define TRACEFS_MAGIC 0x74726163 | |
42 | #endif | |
43 | ||
44 | #define TRACE_DIR_MNT "/sys/kernel/tracing" | |
45 | ||
e4225669 DB |
46 | #ifndef AF_ALG |
47 | # define AF_ALG 38 | |
48 | #endif | |
49 | ||
50 | #ifndef EM_BPF | |
51 | # define EM_BPF 247 | |
52 | #endif | |
53 | ||
54 | struct bpf_cfg_ops { | |
55 | void (*cbpf_cb)(void *nl, const struct sock_filter *ops, int ops_len); | |
56 | void (*ebpf_cb)(void *nl, int fd, const char *annotation); | |
57 | }; | |
58 | ||
59 | struct bpf_cfg_in { | |
60 | const char *object; | |
61 | const char *section; | |
62 | const char *uds; | |
63 | int argc; | |
64 | char **argv; | |
65 | struct sock_filter *ops; | |
66 | }; | |
67 | ||
10e51a76 DA |
68 | /* ALU ops on registers, bpf_add|sub|...: dst_reg += src_reg */ |
69 | ||
70 | #define BPF_ALU64_REG(OP, DST, SRC) \ | |
71 | ((struct bpf_insn) { \ | |
72 | .code = BPF_ALU64 | BPF_OP(OP) | BPF_X, \ | |
73 | .dst_reg = DST, \ | |
74 | .src_reg = SRC, \ | |
75 | .off = 0, \ | |
76 | .imm = 0 }) | |
77 | ||
78 | #define BPF_ALU32_REG(OP, DST, SRC) \ | |
79 | ((struct bpf_insn) { \ | |
80 | .code = BPF_ALU | BPF_OP(OP) | BPF_X, \ | |
81 | .dst_reg = DST, \ | |
82 | .src_reg = SRC, \ | |
83 | .off = 0, \ | |
84 | .imm = 0 }) | |
85 | ||
86 | /* ALU ops on immediates, bpf_add|sub|...: dst_reg += imm32 */ | |
87 | ||
88 | #define BPF_ALU64_IMM(OP, DST, IMM) \ | |
89 | ((struct bpf_insn) { \ | |
90 | .code = BPF_ALU64 | BPF_OP(OP) | BPF_K, \ | |
91 | .dst_reg = DST, \ | |
92 | .src_reg = 0, \ | |
93 | .off = 0, \ | |
94 | .imm = IMM }) | |
95 | ||
96 | #define BPF_ALU32_IMM(OP, DST, IMM) \ | |
97 | ((struct bpf_insn) { \ | |
98 | .code = BPF_ALU | BPF_OP(OP) | BPF_K, \ | |
99 | .dst_reg = DST, \ | |
100 | .src_reg = 0, \ | |
101 | .off = 0, \ | |
102 | .imm = IMM }) | |
103 | ||
104 | /* Short form of mov, dst_reg = src_reg */ | |
105 | ||
106 | #define BPF_MOV64_REG(DST, SRC) \ | |
107 | ((struct bpf_insn) { \ | |
108 | .code = BPF_ALU64 | BPF_MOV | BPF_X, \ | |
109 | .dst_reg = DST, \ | |
110 | .src_reg = SRC, \ | |
111 | .off = 0, \ | |
112 | .imm = 0 }) | |
113 | ||
114 | #define BPF_MOV32_REG(DST, SRC) \ | |
115 | ((struct bpf_insn) { \ | |
116 | .code = BPF_ALU | BPF_MOV | BPF_X, \ | |
117 | .dst_reg = DST, \ | |
118 | .src_reg = SRC, \ | |
119 | .off = 0, \ | |
120 | .imm = 0 }) | |
121 | ||
122 | /* Short form of mov, dst_reg = imm32 */ | |
123 | ||
124 | #define BPF_MOV64_IMM(DST, IMM) \ | |
125 | ((struct bpf_insn) { \ | |
126 | .code = BPF_ALU64 | BPF_MOV | BPF_K, \ | |
127 | .dst_reg = DST, \ | |
128 | .src_reg = 0, \ | |
129 | .off = 0, \ | |
130 | .imm = IMM }) | |
131 | ||
132 | #define BPF_MOV32_IMM(DST, IMM) \ | |
133 | ((struct bpf_insn) { \ | |
134 | .code = BPF_ALU | BPF_MOV | BPF_K, \ | |
135 | .dst_reg = DST, \ | |
136 | .src_reg = 0, \ | |
137 | .off = 0, \ | |
138 | .imm = IMM }) | |
139 | ||
140 | /* BPF_LD_IMM64 macro encodes single 'load 64-bit immediate' insn */ | |
141 | #define BPF_LD_IMM64(DST, IMM) \ | |
142 | BPF_LD_IMM64_RAW(DST, 0, IMM) | |
143 | ||
144 | #define BPF_LD_IMM64_RAW(DST, SRC, IMM) \ | |
145 | ((struct bpf_insn) { \ | |
146 | .code = BPF_LD | BPF_DW | BPF_IMM, \ | |
147 | .dst_reg = DST, \ | |
148 | .src_reg = SRC, \ | |
149 | .off = 0, \ | |
150 | .imm = (__u32) (IMM) }), \ | |
151 | ((struct bpf_insn) { \ | |
152 | .code = 0, /* zero is reserved opcode */ \ | |
153 | .dst_reg = 0, \ | |
154 | .src_reg = 0, \ | |
155 | .off = 0, \ | |
156 | .imm = ((__u64) (IMM)) >> 32 }) | |
157 | ||
158 | #ifndef BPF_PSEUDO_MAP_FD | |
159 | # define BPF_PSEUDO_MAP_FD 1 | |
160 | #endif | |
161 | ||
162 | /* pseudo BPF_LD_IMM64 insn used to refer to process-local map_fd */ | |
163 | #define BPF_LD_MAP_FD(DST, MAP_FD) \ | |
164 | BPF_LD_IMM64_RAW(DST, BPF_PSEUDO_MAP_FD, MAP_FD) | |
165 | ||
166 | ||
167 | /* Direct packet access, R0 = *(uint *) (skb->data + imm32) */ | |
168 | ||
169 | #define BPF_LD_ABS(SIZE, IMM) \ | |
170 | ((struct bpf_insn) { \ | |
171 | .code = BPF_LD | BPF_SIZE(SIZE) | BPF_ABS, \ | |
172 | .dst_reg = 0, \ | |
173 | .src_reg = 0, \ | |
174 | .off = 0, \ | |
175 | .imm = IMM }) | |
176 | ||
177 | /* Memory load, dst_reg = *(uint *) (src_reg + off16) */ | |
178 | ||
179 | #define BPF_LDX_MEM(SIZE, DST, SRC, OFF) \ | |
180 | ((struct bpf_insn) { \ | |
181 | .code = BPF_LDX | BPF_SIZE(SIZE) | BPF_MEM, \ | |
182 | .dst_reg = DST, \ | |
183 | .src_reg = SRC, \ | |
184 | .off = OFF, \ | |
185 | .imm = 0 }) | |
186 | ||
187 | /* Memory store, *(uint *) (dst_reg + off16) = src_reg */ | |
188 | ||
189 | #define BPF_STX_MEM(SIZE, DST, SRC, OFF) \ | |
190 | ((struct bpf_insn) { \ | |
191 | .code = BPF_STX | BPF_SIZE(SIZE) | BPF_MEM, \ | |
192 | .dst_reg = DST, \ | |
193 | .src_reg = SRC, \ | |
194 | .off = OFF, \ | |
195 | .imm = 0 }) | |
196 | ||
197 | /* Memory store, *(uint *) (dst_reg + off16) = imm32 */ | |
198 | ||
199 | #define BPF_ST_MEM(SIZE, DST, OFF, IMM) \ | |
200 | ((struct bpf_insn) { \ | |
201 | .code = BPF_ST | BPF_SIZE(SIZE) | BPF_MEM, \ | |
202 | .dst_reg = DST, \ | |
203 | .src_reg = 0, \ | |
204 | .off = OFF, \ | |
205 | .imm = IMM }) | |
206 | ||
207 | /* Conditional jumps against registers, if (dst_reg 'op' src_reg) goto pc + off16 */ | |
208 | ||
209 | #define BPF_JMP_REG(OP, DST, SRC, OFF) \ | |
210 | ((struct bpf_insn) { \ | |
211 | .code = BPF_JMP | BPF_OP(OP) | BPF_X, \ | |
212 | .dst_reg = DST, \ | |
213 | .src_reg = SRC, \ | |
214 | .off = OFF, \ | |
215 | .imm = 0 }) | |
216 | ||
217 | /* Conditional jumps against immediates, if (dst_reg 'op' imm32) goto pc + off16 */ | |
218 | ||
219 | #define BPF_JMP_IMM(OP, DST, IMM, OFF) \ | |
220 | ((struct bpf_insn) { \ | |
221 | .code = BPF_JMP | BPF_OP(OP) | BPF_K, \ | |
222 | .dst_reg = DST, \ | |
223 | .src_reg = 0, \ | |
224 | .off = OFF, \ | |
225 | .imm = IMM }) | |
226 | ||
227 | /* Raw code statement block */ | |
228 | ||
229 | #define BPF_RAW_INSN(CODE, DST, SRC, OFF, IMM) \ | |
230 | ((struct bpf_insn) { \ | |
231 | .code = CODE, \ | |
232 | .dst_reg = DST, \ | |
233 | .src_reg = SRC, \ | |
234 | .off = OFF, \ | |
235 | .imm = IMM }) | |
236 | ||
237 | /* Program exit */ | |
238 | ||
239 | #define BPF_EXIT_INSN() \ | |
240 | ((struct bpf_insn) { \ | |
241 | .code = BPF_JMP | BPF_EXIT, \ | |
242 | .dst_reg = 0, \ | |
243 | .src_reg = 0, \ | |
244 | .off = 0, \ | |
245 | .imm = 0 }) | |
246 | ||
e4225669 DB |
247 | int bpf_parse_common(enum bpf_prog_type type, struct bpf_cfg_in *cfg, |
248 | const struct bpf_cfg_ops *ops, void *nl); | |
249 | ||
250 | const char *bpf_prog_to_default_section(enum bpf_prog_type type); | |
6256f8c9 | 251 | |
91d88eeb | 252 | int bpf_graft_map(const char *map_path, uint32_t *key, int argc, char **argv); |
e4225669 | 253 | int bpf_trace_pipe(void); |
4bd62446 | 254 | |
32e93fb7 DB |
255 | void bpf_print_ops(FILE *f, struct rtattr *bpf_ops, __u16 len); |
256 | ||
869d889e DA |
257 | int bpf_prog_load(enum bpf_prog_type type, const struct bpf_insn *insns, |
258 | size_t size_insns, const char *license, char *log, | |
259 | size_t size_log); | |
260 | ||
fc4ccce0 DA |
261 | int bpf_prog_attach_fd(int prog_fd, int target_fd, enum bpf_attach_type type); |
262 | int bpf_prog_detach_fd(int target_fd, enum bpf_attach_type type); | |
263 | ||
32e93fb7 | 264 | #ifdef HAVE_ELF |
4bd62446 DB |
265 | int bpf_send_map_fds(const char *path, const char *obj); |
266 | int bpf_recv_map_fds(const char *path, int *fds, struct bpf_map_aux *aux, | |
267 | unsigned int entries); | |
11c39b5e | 268 | #else |
4bd62446 | 269 | static inline int bpf_send_map_fds(const char *path, const char *obj) |
6256f8c9 DB |
270 | { |
271 | return 0; | |
272 | } | |
4bd62446 DB |
273 | |
274 | static inline int bpf_recv_map_fds(const char *path, int *fds, | |
275 | struct bpf_map_aux *aux, | |
276 | unsigned int entries) | |
277 | { | |
278 | return -1; | |
279 | } | |
11c39b5e | 280 | #endif /* HAVE_ELF */ |
e4225669 | 281 | #endif /* __BPF_UTIL__ */ |