Home | History | Annotate | Download | only in include
      1 /*
      2  * bpf_util.h	BPF common code
      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  *
      9  * Authors:	Daniel Borkmann <daniel (at) iogearbox.net>
     10  *		Jiri Pirko <jiri (at) resnulli.us>
     11  */
     12 
     13 #ifndef __BPF_UTIL__
     14 #define __BPF_UTIL__
     15 
     16 #include <linux/bpf.h>
     17 #include <linux/filter.h>
     18 #include <linux/magic.h>
     19 #include <linux/elf-em.h>
     20 #include <linux/if_alg.h>
     21 
     22 #include "utils.h"
     23 #include "bpf_scm.h"
     24 
     25 #define BPF_ENV_UDS	"TC_BPF_UDS"
     26 #define BPF_ENV_MNT	"TC_BPF_MNT"
     27 
     28 #ifndef BPF_MAX_LOG
     29 # define BPF_MAX_LOG	4096
     30 #endif
     31 
     32 #define BPF_DIR_GLOBALS	"globals"
     33 
     34 #ifndef BPF_FS_MAGIC
     35 # define BPF_FS_MAGIC	0xcafe4a11
     36 #endif
     37 
     38 #define BPF_DIR_MNT	"/sys/fs/bpf"
     39 
     40 #ifndef TRACEFS_MAGIC
     41 # define TRACEFS_MAGIC	0x74726163
     42 #endif
     43 
     44 #define TRACE_DIR_MNT	"/sys/kernel/tracing"
     45 
     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 
     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 
    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);
    251 
    252 int bpf_graft_map(const char *map_path, uint32_t *key, int argc, char **argv);
    253 int bpf_trace_pipe(void);
    254 
    255 void bpf_print_ops(FILE *f, struct rtattr *bpf_ops, __u16 len);
    256 
    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 
    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 
    264 int bpf_dump_prog_info(FILE *f, uint32_t id);
    265 
    266 #ifdef HAVE_ELF
    267 int bpf_send_map_fds(const char *path, const char *obj);
    268 int bpf_recv_map_fds(const char *path, int *fds, struct bpf_map_aux *aux,
    269 		     unsigned int entries);
    270 #else
    271 static inline int bpf_send_map_fds(const char *path, const char *obj)
    272 {
    273 	return 0;
    274 }
    275 
    276 static inline int bpf_recv_map_fds(const char *path, int *fds,
    277 				   struct bpf_map_aux *aux,
    278 				   unsigned int entries)
    279 {
    280 	return -1;
    281 }
    282 #endif /* HAVE_ELF */
    283 #endif /* __BPF_UTIL__ */
    284