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