1
2
3
4
5
6
7
8
9#ifndef __BPF_UTIL__
10#define __BPF_UTIL__
11
12#include <linux/bpf.h>
13#include <linux/btf.h>
14#include <linux/filter.h>
15#include <linux/magic.h>
16#include <linux/elf-em.h>
17#include <linux/if_alg.h>
18
19#include "utils.h"
20#include "bpf_scm.h"
21
22#define BPF_ENV_UDS "TC_BPF_UDS"
23#define BPF_ENV_MNT "TC_BPF_MNT"
24
25#ifndef BPF_MAX_LOG
26# define BPF_MAX_LOG 4096
27#endif
28
29#define BPF_DIR_GLOBALS "globals"
30
31#ifndef BPF_FS_MAGIC
32# define BPF_FS_MAGIC 0xcafe4a11
33#endif
34
35#define BPF_DIR_MNT "/sys/fs/bpf"
36
37#ifndef TRACEFS_MAGIC
38# define TRACEFS_MAGIC 0x74726163
39#endif
40
41#define TRACE_DIR_MNT "/sys/kernel/tracing"
42
43#ifndef AF_ALG
44# define AF_ALG 38
45#endif
46
47#ifndef EM_BPF
48# define EM_BPF 247
49#endif
50
51struct bpf_cfg_ops {
52 void (*cbpf_cb)(void *nl, const struct sock_filter *ops, int ops_len);
53 void (*ebpf_cb)(void *nl, int fd, const char *annotation);
54};
55
56enum bpf_mode {
57 CBPF_BYTECODE,
58 CBPF_FILE,
59 EBPF_OBJECT,
60 EBPF_PINNED,
61 BPF_MODE_MAX,
62};
63
64struct bpf_cfg_in {
65 const char *object;
66 const char *section;
67 const char *prog_name;
68 const char *uds;
69 enum bpf_prog_type type;
70 enum bpf_mode mode;
71 __u32 ifindex;
72 bool verbose;
73 int argc;
74 char **argv;
75 struct sock_filter opcodes[BPF_MAXINSNS];
76 union {
77 int n_opcodes;
78 int prog_fd;
79 };
80};
81
82
83
84#define BPF_ALU64_REG(OP, DST, SRC) \
85 ((struct bpf_insn) { \
86 .code = BPF_ALU64 | BPF_OP(OP) | BPF_X, \
87 .dst_reg = DST, \
88 .src_reg = SRC, \
89 .off = 0, \
90 .imm = 0 })
91
92#define BPF_ALU32_REG(OP, DST, SRC) \
93 ((struct bpf_insn) { \
94 .code = BPF_ALU | BPF_OP(OP) | BPF_X, \
95 .dst_reg = DST, \
96 .src_reg = SRC, \
97 .off = 0, \
98 .imm = 0 })
99
100
101
102#define BPF_ALU64_IMM(OP, DST, IMM) \
103 ((struct bpf_insn) { \
104 .code = BPF_ALU64 | BPF_OP(OP) | BPF_K, \
105 .dst_reg = DST, \
106 .src_reg = 0, \
107 .off = 0, \
108 .imm = IMM })
109
110#define BPF_ALU32_IMM(OP, DST, IMM) \
111 ((struct bpf_insn) { \
112 .code = BPF_ALU | BPF_OP(OP) | BPF_K, \
113 .dst_reg = DST, \
114 .src_reg = 0, \
115 .off = 0, \
116 .imm = IMM })
117
118
119
120#define BPF_MOV64_REG(DST, SRC) \
121 ((struct bpf_insn) { \
122 .code = BPF_ALU64 | BPF_MOV | BPF_X, \
123 .dst_reg = DST, \
124 .src_reg = SRC, \
125 .off = 0, \
126 .imm = 0 })
127
128#define BPF_MOV32_REG(DST, SRC) \
129 ((struct bpf_insn) { \
130 .code = BPF_ALU | BPF_MOV | BPF_X, \
131 .dst_reg = DST, \
132 .src_reg = SRC, \
133 .off = 0, \
134 .imm = 0 })
135
136
137
138#define BPF_MOV64_IMM(DST, IMM) \
139 ((struct bpf_insn) { \
140 .code = BPF_ALU64 | BPF_MOV | BPF_K, \
141 .dst_reg = DST, \
142 .src_reg = 0, \
143 .off = 0, \
144 .imm = IMM })
145
146#define BPF_MOV32_IMM(DST, IMM) \
147 ((struct bpf_insn) { \
148 .code = BPF_ALU | BPF_MOV | BPF_K, \
149 .dst_reg = DST, \
150 .src_reg = 0, \
151 .off = 0, \
152 .imm = IMM })
153
154
155#define BPF_LD_IMM64(DST, IMM) \
156 BPF_LD_IMM64_RAW(DST, 0, IMM)
157
158#define BPF_LD_IMM64_RAW(DST, SRC, IMM) \
159 ((struct bpf_insn) { \
160 .code = BPF_LD | BPF_DW | BPF_IMM, \
161 .dst_reg = DST, \
162 .src_reg = SRC, \
163 .off = 0, \
164 .imm = (__u32) (IMM) }), \
165 ((struct bpf_insn) { \
166 .code = 0, \
167 .dst_reg = 0, \
168 .src_reg = 0, \
169 .off = 0, \
170 .imm = ((__u64) (IMM)) >> 32 })
171
172#ifndef BPF_PSEUDO_MAP_FD
173# define BPF_PSEUDO_MAP_FD 1
174#endif
175
176
177#define BPF_LD_MAP_FD(DST, MAP_FD) \
178 BPF_LD_IMM64_RAW(DST, BPF_PSEUDO_MAP_FD, MAP_FD)
179
180
181
182
183#define BPF_LD_ABS(SIZE, IMM) \
184 ((struct bpf_insn) { \
185 .code = BPF_LD | BPF_SIZE(SIZE) | BPF_ABS, \
186 .dst_reg = 0, \
187 .src_reg = 0, \
188 .off = 0, \
189 .imm = IMM })
190
191
192
193#define BPF_LDX_MEM(SIZE, DST, SRC, OFF) \
194 ((struct bpf_insn) { \
195 .code = BPF_LDX | BPF_SIZE(SIZE) | BPF_MEM, \
196 .dst_reg = DST, \
197 .src_reg = SRC, \
198 .off = OFF, \
199 .imm = 0 })
200
201
202
203#define BPF_STX_MEM(SIZE, DST, SRC, OFF) \
204 ((struct bpf_insn) { \
205 .code = BPF_STX | BPF_SIZE(SIZE) | BPF_MEM, \
206 .dst_reg = DST, \
207 .src_reg = SRC, \
208 .off = OFF, \
209 .imm = 0 })
210
211
212
213#define BPF_ST_MEM(SIZE, DST, OFF, IMM) \
214 ((struct bpf_insn) { \
215 .code = BPF_ST | BPF_SIZE(SIZE) | BPF_MEM, \
216 .dst_reg = DST, \
217 .src_reg = 0, \
218 .off = OFF, \
219 .imm = IMM })
220
221
222
223#define BPF_JMP_REG(OP, DST, SRC, OFF) \
224 ((struct bpf_insn) { \
225 .code = BPF_JMP | BPF_OP(OP) | BPF_X, \
226 .dst_reg = DST, \
227 .src_reg = SRC, \
228 .off = OFF, \
229 .imm = 0 })
230
231
232
233#define BPF_JMP_IMM(OP, DST, IMM, OFF) \
234 ((struct bpf_insn) { \
235 .code = BPF_JMP | BPF_OP(OP) | BPF_K, \
236 .dst_reg = DST, \
237 .src_reg = 0, \
238 .off = OFF, \
239 .imm = IMM })
240
241
242
243#define BPF_RAW_INSN(CODE, DST, SRC, OFF, IMM) \
244 ((struct bpf_insn) { \
245 .code = CODE, \
246 .dst_reg = DST, \
247 .src_reg = SRC, \
248 .off = OFF, \
249 .imm = IMM })
250
251
252
253#define BPF_EXIT_INSN() \
254 ((struct bpf_insn) { \
255 .code = BPF_JMP | BPF_EXIT, \
256 .dst_reg = 0, \
257 .src_reg = 0, \
258 .off = 0, \
259 .imm = 0 })
260
261int bpf_parse_common(struct bpf_cfg_in *cfg, const struct bpf_cfg_ops *ops);
262int bpf_load_common(struct bpf_cfg_in *cfg, const struct bpf_cfg_ops *ops,
263 void *nl);
264int bpf_parse_and_load_common(struct bpf_cfg_in *cfg,
265 const struct bpf_cfg_ops *ops, void *nl);
266
267const char *bpf_prog_to_default_section(enum bpf_prog_type type);
268
269int bpf_graft_map(const char *map_path, uint32_t *key, int argc, char **argv);
270int bpf_trace_pipe(void);
271
272void bpf_print_ops(struct rtattr *bpf_ops, __u16 len);
273
274int bpf_prog_load_dev(enum bpf_prog_type type, const struct bpf_insn *insns,
275 size_t size_insns, const char *license, __u32 ifindex,
276 char *log, size_t size_log, bool verbose);
277int bpf_program_load(enum bpf_prog_type type, const struct bpf_insn *insns,
278 size_t size_insns, const char *license, char *log,
279 size_t size_log, bool verbose);
280
281int bpf_prog_attach_fd(int prog_fd, int target_fd, enum bpf_attach_type type);
282int bpf_prog_detach_fd(int target_fd, enum bpf_attach_type type);
283int bpf_program_attach(int prog_fd, int target_fd, enum bpf_attach_type type);
284
285int bpf_dump_prog_info(FILE *f, uint32_t id);
286
287int bpf(int cmd, union bpf_attr *attr, unsigned int size);
288
289#ifdef HAVE_ELF
290int bpf_send_map_fds(const char *path, const char *obj);
291int bpf_recv_map_fds(const char *path, int *fds, struct bpf_map_aux *aux,
292 unsigned int entries);
293#ifdef HAVE_LIBBPF
294int iproute2_bpf_elf_ctx_init(struct bpf_cfg_in *cfg);
295int iproute2_bpf_fetch_ancillary(void);
296int iproute2_get_root_path(char *root_path, size_t len);
297bool iproute2_is_pin_map(const char *libbpf_map_name, char *pathname);
298bool iproute2_is_map_in_map(const char *libbpf_map_name, struct bpf_elf_map *imap,
299 struct bpf_elf_map *omap, char *omap_name);
300int iproute2_find_map_name_by_id(unsigned int map_id, char *name);
301int iproute2_load_libbpf(struct bpf_cfg_in *cfg);
302#endif
303#else
304static inline int bpf_send_map_fds(const char *path, const char *obj)
305{
306 return 0;
307}
308
309static inline int bpf_recv_map_fds(const char *path, int *fds,
310 struct bpf_map_aux *aux,
311 unsigned int entries)
312{
313 return -1;
314}
315#ifdef HAVE_LIBBPF
316static inline int iproute2_load_libbpf(struct bpf_cfg_in *cfg)
317{
318 fprintf(stderr, "No ELF library support compiled in.\n");
319 return -1;
320}
321#endif
322#endif
323
324const char *get_libbpf_version(void);
325
326#endif
327