]>
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 | ||
f20ff2f1 JK |
59 | enum bpf_mode { |
60 | CBPF_BYTECODE, | |
61 | CBPF_FILE, | |
62 | EBPF_OBJECT, | |
63 | EBPF_PINNED, | |
64 | BPF_MODE_MAX, | |
65 | }; | |
66 | ||
e4225669 DB |
67 | struct bpf_cfg_in { |
68 | const char *object; | |
69 | const char *section; | |
70 | const char *uds; | |
658cfebc | 71 | enum bpf_prog_type type; |
f20ff2f1 | 72 | enum bpf_mode mode; |
65fdae3d | 73 | __u32 ifindex; |
3f0b9e62 | 74 | bool verbose; |
e4225669 DB |
75 | int argc; |
76 | char **argv; | |
51be7546 | 77 | struct sock_filter opcodes[BPF_MAXINSNS]; |
3f0b9e62 JK |
78 | union { |
79 | int n_opcodes; | |
80 | int prog_fd; | |
81 | }; | |
e4225669 DB |
82 | }; |
83 | ||
10e51a76 DA |
84 | /* ALU ops on registers, bpf_add|sub|...: dst_reg += src_reg */ |
85 | ||
86 | #define BPF_ALU64_REG(OP, DST, SRC) \ | |
87 | ((struct bpf_insn) { \ | |
88 | .code = BPF_ALU64 | BPF_OP(OP) | BPF_X, \ | |
89 | .dst_reg = DST, \ | |
90 | .src_reg = SRC, \ | |
91 | .off = 0, \ | |
92 | .imm = 0 }) | |
93 | ||
94 | #define BPF_ALU32_REG(OP, DST, SRC) \ | |
95 | ((struct bpf_insn) { \ | |
96 | .code = BPF_ALU | BPF_OP(OP) | BPF_X, \ | |
97 | .dst_reg = DST, \ | |
98 | .src_reg = SRC, \ | |
99 | .off = 0, \ | |
100 | .imm = 0 }) | |
101 | ||
102 | /* ALU ops on immediates, bpf_add|sub|...: dst_reg += imm32 */ | |
103 | ||
104 | #define BPF_ALU64_IMM(OP, DST, IMM) \ | |
105 | ((struct bpf_insn) { \ | |
106 | .code = BPF_ALU64 | BPF_OP(OP) | BPF_K, \ | |
107 | .dst_reg = DST, \ | |
108 | .src_reg = 0, \ | |
109 | .off = 0, \ | |
110 | .imm = IMM }) | |
111 | ||
112 | #define BPF_ALU32_IMM(OP, DST, IMM) \ | |
113 | ((struct bpf_insn) { \ | |
114 | .code = BPF_ALU | BPF_OP(OP) | BPF_K, \ | |
115 | .dst_reg = DST, \ | |
116 | .src_reg = 0, \ | |
117 | .off = 0, \ | |
118 | .imm = IMM }) | |
119 | ||
120 | /* Short form of mov, dst_reg = src_reg */ | |
121 | ||
122 | #define BPF_MOV64_REG(DST, SRC) \ | |
123 | ((struct bpf_insn) { \ | |
124 | .code = BPF_ALU64 | BPF_MOV | BPF_X, \ | |
125 | .dst_reg = DST, \ | |
126 | .src_reg = SRC, \ | |
127 | .off = 0, \ | |
128 | .imm = 0 }) | |
129 | ||
130 | #define BPF_MOV32_REG(DST, SRC) \ | |
131 | ((struct bpf_insn) { \ | |
132 | .code = BPF_ALU | BPF_MOV | BPF_X, \ | |
133 | .dst_reg = DST, \ | |
134 | .src_reg = SRC, \ | |
135 | .off = 0, \ | |
136 | .imm = 0 }) | |
137 | ||
138 | /* Short form of mov, dst_reg = imm32 */ | |
139 | ||
140 | #define BPF_MOV64_IMM(DST, IMM) \ | |
141 | ((struct bpf_insn) { \ | |
142 | .code = BPF_ALU64 | BPF_MOV | BPF_K, \ | |
143 | .dst_reg = DST, \ | |
144 | .src_reg = 0, \ | |
145 | .off = 0, \ | |
146 | .imm = IMM }) | |
147 | ||
148 | #define BPF_MOV32_IMM(DST, IMM) \ | |
149 | ((struct bpf_insn) { \ | |
150 | .code = BPF_ALU | BPF_MOV | BPF_K, \ | |
151 | .dst_reg = DST, \ | |
152 | .src_reg = 0, \ | |
153 | .off = 0, \ | |
154 | .imm = IMM }) | |
155 | ||
156 | /* BPF_LD_IMM64 macro encodes single 'load 64-bit immediate' insn */ | |
157 | #define BPF_LD_IMM64(DST, IMM) \ | |
158 | BPF_LD_IMM64_RAW(DST, 0, IMM) | |
159 | ||
160 | #define BPF_LD_IMM64_RAW(DST, SRC, IMM) \ | |
161 | ((struct bpf_insn) { \ | |
162 | .code = BPF_LD | BPF_DW | BPF_IMM, \ | |
163 | .dst_reg = DST, \ | |
164 | .src_reg = SRC, \ | |
165 | .off = 0, \ | |
166 | .imm = (__u32) (IMM) }), \ | |
167 | ((struct bpf_insn) { \ | |
168 | .code = 0, /* zero is reserved opcode */ \ | |
169 | .dst_reg = 0, \ | |
170 | .src_reg = 0, \ | |
171 | .off = 0, \ | |
172 | .imm = ((__u64) (IMM)) >> 32 }) | |
173 | ||
174 | #ifndef BPF_PSEUDO_MAP_FD | |
175 | # define BPF_PSEUDO_MAP_FD 1 | |
176 | #endif | |
177 | ||
178 | /* pseudo BPF_LD_IMM64 insn used to refer to process-local map_fd */ | |
179 | #define BPF_LD_MAP_FD(DST, MAP_FD) \ | |
180 | BPF_LD_IMM64_RAW(DST, BPF_PSEUDO_MAP_FD, MAP_FD) | |
181 | ||
182 | ||
183 | /* Direct packet access, R0 = *(uint *) (skb->data + imm32) */ | |
184 | ||
185 | #define BPF_LD_ABS(SIZE, IMM) \ | |
186 | ((struct bpf_insn) { \ | |
187 | .code = BPF_LD | BPF_SIZE(SIZE) | BPF_ABS, \ | |
188 | .dst_reg = 0, \ | |
189 | .src_reg = 0, \ | |
190 | .off = 0, \ | |
191 | .imm = IMM }) | |
192 | ||
193 | /* Memory load, dst_reg = *(uint *) (src_reg + off16) */ | |
194 | ||
195 | #define BPF_LDX_MEM(SIZE, DST, SRC, OFF) \ | |
196 | ((struct bpf_insn) { \ | |
197 | .code = BPF_LDX | BPF_SIZE(SIZE) | BPF_MEM, \ | |
198 | .dst_reg = DST, \ | |
199 | .src_reg = SRC, \ | |
200 | .off = OFF, \ | |
201 | .imm = 0 }) | |
202 | ||
203 | /* Memory store, *(uint *) (dst_reg + off16) = src_reg */ | |
204 | ||
205 | #define BPF_STX_MEM(SIZE, DST, SRC, OFF) \ | |
206 | ((struct bpf_insn) { \ | |
207 | .code = BPF_STX | BPF_SIZE(SIZE) | BPF_MEM, \ | |
208 | .dst_reg = DST, \ | |
209 | .src_reg = SRC, \ | |
210 | .off = OFF, \ | |
211 | .imm = 0 }) | |
212 | ||
213 | /* Memory store, *(uint *) (dst_reg + off16) = imm32 */ | |
214 | ||
215 | #define BPF_ST_MEM(SIZE, DST, OFF, IMM) \ | |
216 | ((struct bpf_insn) { \ | |
217 | .code = BPF_ST | BPF_SIZE(SIZE) | BPF_MEM, \ | |
218 | .dst_reg = DST, \ | |
219 | .src_reg = 0, \ | |
220 | .off = OFF, \ | |
221 | .imm = IMM }) | |
222 | ||
223 | /* Conditional jumps against registers, if (dst_reg 'op' src_reg) goto pc + off16 */ | |
224 | ||
225 | #define BPF_JMP_REG(OP, DST, SRC, OFF) \ | |
226 | ((struct bpf_insn) { \ | |
227 | .code = BPF_JMP | BPF_OP(OP) | BPF_X, \ | |
228 | .dst_reg = DST, \ | |
229 | .src_reg = SRC, \ | |
230 | .off = OFF, \ | |
231 | .imm = 0 }) | |
232 | ||
233 | /* Conditional jumps against immediates, if (dst_reg 'op' imm32) goto pc + off16 */ | |
234 | ||
235 | #define BPF_JMP_IMM(OP, DST, IMM, OFF) \ | |
236 | ((struct bpf_insn) { \ | |
237 | .code = BPF_JMP | BPF_OP(OP) | BPF_K, \ | |
238 | .dst_reg = DST, \ | |
239 | .src_reg = 0, \ | |
240 | .off = OFF, \ | |
241 | .imm = IMM }) | |
242 | ||
243 | /* Raw code statement block */ | |
244 | ||
245 | #define BPF_RAW_INSN(CODE, DST, SRC, OFF, IMM) \ | |
246 | ((struct bpf_insn) { \ | |
247 | .code = CODE, \ | |
248 | .dst_reg = DST, \ | |
249 | .src_reg = SRC, \ | |
250 | .off = OFF, \ | |
251 | .imm = IMM }) | |
252 | ||
253 | /* Program exit */ | |
254 | ||
255 | #define BPF_EXIT_INSN() \ | |
256 | ((struct bpf_insn) { \ | |
257 | .code = BPF_JMP | BPF_EXIT, \ | |
258 | .dst_reg = 0, \ | |
259 | .src_reg = 0, \ | |
260 | .off = 0, \ | |
261 | .imm = 0 }) | |
262 | ||
4a847fcb JK |
263 | int bpf_parse_common(struct bpf_cfg_in *cfg, const struct bpf_cfg_ops *ops); |
264 | int bpf_load_common(struct bpf_cfg_in *cfg, const struct bpf_cfg_ops *ops, | |
265 | void *nl); | |
399db839 JK |
266 | int bpf_parse_and_load_common(struct bpf_cfg_in *cfg, |
267 | const struct bpf_cfg_ops *ops, void *nl); | |
e4225669 DB |
268 | |
269 | const char *bpf_prog_to_default_section(enum bpf_prog_type type); | |
6256f8c9 | 270 | |
91d88eeb | 271 | int bpf_graft_map(const char *map_path, uint32_t *key, int argc, char **argv); |
e4225669 | 272 | int bpf_trace_pipe(void); |
4bd62446 | 273 | |
32e93fb7 DB |
274 | void bpf_print_ops(FILE *f, struct rtattr *bpf_ops, __u16 len); |
275 | ||
869d889e DA |
276 | int bpf_prog_load(enum bpf_prog_type type, const struct bpf_insn *insns, |
277 | size_t size_insns, const char *license, char *log, | |
278 | size_t size_log); | |
279 | ||
fc4ccce0 DA |
280 | int bpf_prog_attach_fd(int prog_fd, int target_fd, enum bpf_attach_type type); |
281 | int bpf_prog_detach_fd(int target_fd, enum bpf_attach_type type); | |
282 | ||
a0b5b7cf | 283 | int bpf_dump_prog_info(FILE *f, uint32_t id); |
779525cd | 284 | |
32e93fb7 | 285 | #ifdef HAVE_ELF |
4bd62446 DB |
286 | int bpf_send_map_fds(const char *path, const char *obj); |
287 | int bpf_recv_map_fds(const char *path, int *fds, struct bpf_map_aux *aux, | |
288 | unsigned int entries); | |
11c39b5e | 289 | #else |
4bd62446 | 290 | static inline int bpf_send_map_fds(const char *path, const char *obj) |
6256f8c9 DB |
291 | { |
292 | return 0; | |
293 | } | |
4bd62446 DB |
294 | |
295 | static inline int bpf_recv_map_fds(const char *path, int *fds, | |
296 | struct bpf_map_aux *aux, | |
297 | unsigned int entries) | |
298 | { | |
299 | return -1; | |
300 | } | |
11c39b5e | 301 | #endif /* HAVE_ELF */ |
e4225669 | 302 | #endif /* __BPF_UTIL__ */ |