1/* 2 * Linux Socket Filter Data Structures 3 */ 4#ifndef __TOOLS_LINUX_FILTER_H 5#define __TOOLS_LINUX_FILTER_H 6 7#include <linux/bpf.h> 8 9/* ArgX, context and stack frame pointer register positions. Note, 10 * Arg1, Arg2, Arg3, etc are used as argument mappings of function 11 * calls in BPF_CALL instruction. 12 */ 13#define BPF_REG_ARG1 BPF_REG_1 14#define BPF_REG_ARG2 BPF_REG_2 15#define BPF_REG_ARG3 BPF_REG_3 16#define BPF_REG_ARG4 BPF_REG_4 17#define BPF_REG_ARG5 BPF_REG_5 18#define BPF_REG_CTX BPF_REG_6 19#define BPF_REG_FP BPF_REG_10 20 21/* Additional register mappings for converted user programs. */ 22#define BPF_REG_A BPF_REG_0 23#define BPF_REG_X BPF_REG_7 24#define BPF_REG_TMP BPF_REG_8 25 26/* BPF program can access up to 512 bytes of stack space. */ 27#define MAX_BPF_STACK 512 28 29/* Helper macros for filter block array initializers. */ 30 31/* ALU ops on registers, bpf_add|sub|...: dst_reg += src_reg */ 32 33#define BPF_ALU64_REG(OP, DST, SRC) \ 34 ((struct bpf_insn) { \ 35 .code = BPF_ALU64 | BPF_OP(OP) | BPF_X, \ 36 .dst_reg = DST, \ 37 .src_reg = SRC, \ 38 .off = 0, \ 39 .imm = 0 }) 40 41#define BPF_ALU32_REG(OP, DST, SRC) \ 42 ((struct bpf_insn) { \ 43 .code = BPF_ALU | BPF_OP(OP) | BPF_X, \ 44 .dst_reg = DST, \ 45 .src_reg = SRC, \ 46 .off = 0, \ 47 .imm = 0 }) 48 49/* ALU ops on immediates, bpf_add|sub|...: dst_reg += imm32 */ 50 51#define BPF_ALU64_IMM(OP, DST, IMM) \ 52 ((struct bpf_insn) { \ 53 .code = BPF_ALU64 | BPF_OP(OP) | BPF_K, \ 54 .dst_reg = DST, \ 55 .src_reg = 0, \ 56 .off = 0, \ 57 .imm = IMM }) 58 59#define BPF_ALU32_IMM(OP, DST, IMM) \ 60 ((struct bpf_insn) { \ 61 .code = BPF_ALU | BPF_OP(OP) | BPF_K, \ 62 .dst_reg = DST, \ 63 .src_reg = 0, \ 64 .off = 0, \ 65 .imm = IMM }) 66 67/* Endianess conversion, cpu_to_{l,b}e(), {l,b}e_to_cpu() */ 68 69#define BPF_ENDIAN(TYPE, DST, LEN) \ 70 ((struct bpf_insn) { \ 71 .code = BPF_ALU | BPF_END | BPF_SRC(TYPE), \ 72 .dst_reg = DST, \ 73 .src_reg = 0, \ 74 .off = 0, \ 75 .imm = LEN }) 76 77/* Short form of mov, dst_reg = src_reg */ 78 79#define BPF_MOV64_REG(DST, SRC) \ 80 ((struct bpf_insn) { \ 81 .code = BPF_ALU64 | BPF_MOV | BPF_X, \ 82 .dst_reg = DST, \ 83 .src_reg = SRC, \ 84 .off = 0, \ 85 .imm = 0 }) 86 87#define BPF_MOV32_REG(DST, SRC) \ 88 ((struct bpf_insn) { \ 89 .code = BPF_ALU | BPF_MOV | BPF_X, \ 90 .dst_reg = DST, \ 91 .src_reg = SRC, \ 92 .off = 0, \ 93 .imm = 0 }) 94 95/* Short form of mov, dst_reg = imm32 */ 96 97#define BPF_MOV64_IMM(DST, IMM) \ 98 ((struct bpf_insn) { \ 99 .code = BPF_ALU64 | BPF_MOV | BPF_K, \ 100 .dst_reg = DST, \ 101 .src_reg = 0, \ 102 .off = 0, \ 103 .imm = IMM }) 104 105#define BPF_MOV32_IMM(DST, IMM) \ 106 ((struct bpf_insn) { \ 107 .code = BPF_ALU | BPF_MOV | BPF_K, \ 108 .dst_reg = DST, \ 109 .src_reg = 0, \ 110 .off = 0, \ 111 .imm = IMM }) 112 113/* Short form of mov based on type, BPF_X: dst_reg = src_reg, BPF_K: dst_reg = imm32 */ 114 115#define BPF_MOV64_RAW(TYPE, DST, SRC, IMM) \ 116 ((struct bpf_insn) { \ 117 .code = BPF_ALU64 | BPF_MOV | BPF_SRC(TYPE), \ 118 .dst_reg = DST, \ 119 .src_reg = SRC, \ 120 .off = 0, \ 121 .imm = IMM }) 122 123#define BPF_MOV32_RAW(TYPE, DST, SRC, IMM) \ 124 ((struct bpf_insn) { \ 125 .code = BPF_ALU | BPF_MOV | BPF_SRC(TYPE), \ 126 .dst_reg = DST, \ 127 .src_reg = SRC, \ 128 .off = 0, \ 129 .imm = IMM }) 130 131/* Direct packet access, R0 = *(uint *) (skb->data + imm32) */ 132 133#define BPF_LD_ABS(SIZE, IMM) \ 134 ((struct bpf_insn) { \ 135 .code = BPF_LD | BPF_SIZE(SIZE) | BPF_ABS, \ 136 .dst_reg = 0, \ 137 .src_reg = 0, \ 138 .off = 0, \ 139 .imm = IMM }) 140 141/* Indirect packet access, R0 = *(uint *) (skb->data + src_reg + imm32) */ 142 143#define BPF_LD_IND(SIZE, SRC, IMM) \ 144 ((struct bpf_insn) { \ 145 .code = BPF_LD | BPF_SIZE(SIZE) | BPF_IND, \ 146 .dst_reg = 0, \ 147 .src_reg = SRC, \ 148 .off = 0, \ 149 .imm = IMM }) 150 151/* Memory load, dst_reg = *(uint *) (src_reg + off16) */ 152 153#define BPF_LDX_MEM(SIZE, DST, SRC, OFF) \ 154 ((struct bpf_insn) { \ 155 .code = BPF_LDX | BPF_SIZE(SIZE) | BPF_MEM, \ 156 .dst_reg = DST, \ 157 .src_reg = SRC, \ 158 .off = OFF, \ 159 .imm = 0 }) 160 161/* Memory store, *(uint *) (dst_reg + off16) = src_reg */ 162 163#define BPF_STX_MEM(SIZE, DST, SRC, OFF) \ 164 ((struct bpf_insn) { \ 165 .code = BPF_STX | BPF_SIZE(SIZE) | BPF_MEM, \ 166 .dst_reg = DST, \ 167 .src_reg = SRC, \ 168 .off = OFF, \ 169 .imm = 0 }) 170 171/* Memory store, *(uint *) (dst_reg + off16) = imm32 */ 172 173#define BPF_ST_MEM(SIZE, DST, OFF, IMM) \ 174 ((struct bpf_insn) { \ 175 .code = BPF_ST | BPF_SIZE(SIZE) | BPF_MEM, \ 176 .dst_reg = DST, \ 177 .src_reg = 0, \ 178 .off = OFF, \ 179 .imm = IMM }) 180 181/* Conditional jumps against registers, if (dst_reg 'op' src_reg) goto pc + off16 */ 182 183#define BPF_JMP_REG(OP, DST, SRC, OFF) \ 184 ((struct bpf_insn) { \ 185 .code = BPF_JMP | BPF_OP(OP) | BPF_X, \ 186 .dst_reg = DST, \ 187 .src_reg = SRC, \ 188 .off = OFF, \ 189 .imm = 0 }) 190 191/* Conditional jumps against immediates, if (dst_reg 'op' imm32) goto pc + off16 */ 192 193#define BPF_JMP_IMM(OP, DST, IMM, OFF) \ 194 ((struct bpf_insn) { \ 195 .code = BPF_JMP | BPF_OP(OP) | BPF_K, \ 196 .dst_reg = DST, \ 197 .src_reg = 0, \ 198 .off = OFF, \ 199 .imm = IMM }) 200 201/* Function call */ 202 203#define BPF_EMIT_CALL(FUNC) \ 204 ((struct bpf_insn) { \ 205 .code = BPF_JMP | BPF_CALL, \ 206 .dst_reg = 0, \ 207 .src_reg = 0, \ 208 .off = 0, \ 209 .imm = ((FUNC) - BPF_FUNC_unspec) }) 210 211/* Raw code statement block */ 212 213#define BPF_RAW_INSN(CODE, DST, SRC, OFF, IMM) \ 214 ((struct bpf_insn) { \ 215 .code = CODE, \ 216 .dst_reg = DST, \ 217 .src_reg = SRC, \ 218 .off = OFF, \ 219 .imm = IMM }) 220 221/* Program exit */ 222 223#define BPF_EXIT_INSN() \ 224 ((struct bpf_insn) { \ 225 .code = BPF_JMP | BPF_EXIT, \ 226 .dst_reg = 0, \ 227 .src_reg = 0, \ 228 .off = 0, \ 229 .imm = 0 }) 230 231#endif /* __TOOLS_LINUX_FILTER_H */ 232