Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * Linux Socket Filter Data Structures
0004  */
0005 #ifndef __TOOLS_LINUX_FILTER_H
0006 #define __TOOLS_LINUX_FILTER_H
0007 
0008 #include <linux/bpf.h>
0009 
0010 /* ArgX, context and stack frame pointer register positions. Note,
0011  * Arg1, Arg2, Arg3, etc are used as argument mappings of function
0012  * calls in BPF_CALL instruction.
0013  */
0014 #define BPF_REG_ARG1    BPF_REG_1
0015 #define BPF_REG_ARG2    BPF_REG_2
0016 #define BPF_REG_ARG3    BPF_REG_3
0017 #define BPF_REG_ARG4    BPF_REG_4
0018 #define BPF_REG_ARG5    BPF_REG_5
0019 #define BPF_REG_CTX BPF_REG_6
0020 #define BPF_REG_FP  BPF_REG_10
0021 
0022 /* Additional register mappings for converted user programs. */
0023 #define BPF_REG_A   BPF_REG_0
0024 #define BPF_REG_X   BPF_REG_7
0025 #define BPF_REG_TMP BPF_REG_8
0026 
0027 /* BPF program can access up to 512 bytes of stack space. */
0028 #define MAX_BPF_STACK   512
0029 
0030 /* Helper macros for filter block array initializers. */
0031 
0032 /* ALU ops on registers, bpf_add|sub|...: dst_reg += src_reg */
0033 
0034 #define BPF_ALU64_REG(OP, DST, SRC)             \
0035     ((struct bpf_insn) {                    \
0036         .code  = BPF_ALU64 | BPF_OP(OP) | BPF_X,    \
0037         .dst_reg = DST,                 \
0038         .src_reg = SRC,                 \
0039         .off   = 0,                 \
0040         .imm   = 0 })
0041 
0042 #define BPF_ALU32_REG(OP, DST, SRC)             \
0043     ((struct bpf_insn) {                    \
0044         .code  = BPF_ALU | BPF_OP(OP) | BPF_X,      \
0045         .dst_reg = DST,                 \
0046         .src_reg = SRC,                 \
0047         .off   = 0,                 \
0048         .imm   = 0 })
0049 
0050 /* ALU ops on immediates, bpf_add|sub|...: dst_reg += imm32 */
0051 
0052 #define BPF_ALU64_IMM(OP, DST, IMM)             \
0053     ((struct bpf_insn) {                    \
0054         .code  = BPF_ALU64 | BPF_OP(OP) | BPF_K,    \
0055         .dst_reg = DST,                 \
0056         .src_reg = 0,                   \
0057         .off   = 0,                 \
0058         .imm   = IMM })
0059 
0060 #define BPF_ALU32_IMM(OP, DST, IMM)             \
0061     ((struct bpf_insn) {                    \
0062         .code  = BPF_ALU | BPF_OP(OP) | BPF_K,      \
0063         .dst_reg = DST,                 \
0064         .src_reg = 0,                   \
0065         .off   = 0,                 \
0066         .imm   = IMM })
0067 
0068 /* Endianess conversion, cpu_to_{l,b}e(), {l,b}e_to_cpu() */
0069 
0070 #define BPF_ENDIAN(TYPE, DST, LEN)              \
0071     ((struct bpf_insn) {                    \
0072         .code  = BPF_ALU | BPF_END | BPF_SRC(TYPE), \
0073         .dst_reg = DST,                 \
0074         .src_reg = 0,                   \
0075         .off   = 0,                 \
0076         .imm   = LEN })
0077 
0078 /* Short form of mov, dst_reg = src_reg */
0079 
0080 #define BPF_MOV64_REG(DST, SRC)                 \
0081     ((struct bpf_insn) {                    \
0082         .code  = BPF_ALU64 | BPF_MOV | BPF_X,       \
0083         .dst_reg = DST,                 \
0084         .src_reg = SRC,                 \
0085         .off   = 0,                 \
0086         .imm   = 0 })
0087 
0088 #define BPF_MOV32_REG(DST, SRC)                 \
0089     ((struct bpf_insn) {                    \
0090         .code  = BPF_ALU | BPF_MOV | BPF_X,     \
0091         .dst_reg = DST,                 \
0092         .src_reg = SRC,                 \
0093         .off   = 0,                 \
0094         .imm   = 0 })
0095 
0096 /* Short form of mov, dst_reg = imm32 */
0097 
0098 #define BPF_MOV64_IMM(DST, IMM)                 \
0099     ((struct bpf_insn) {                    \
0100         .code  = BPF_ALU64 | BPF_MOV | BPF_K,       \
0101         .dst_reg = DST,                 \
0102         .src_reg = 0,                   \
0103         .off   = 0,                 \
0104         .imm   = IMM })
0105 
0106 #define BPF_MOV32_IMM(DST, IMM)                 \
0107     ((struct bpf_insn) {                    \
0108         .code  = BPF_ALU | BPF_MOV | BPF_K,     \
0109         .dst_reg = DST,                 \
0110         .src_reg = 0,                   \
0111         .off   = 0,                 \
0112         .imm   = IMM })
0113 
0114 /* Short form of mov based on type,  BPF_X: dst_reg = src_reg, BPF_K: dst_reg = imm32 */
0115 
0116 #define BPF_MOV64_RAW(TYPE, DST, SRC, IMM)          \
0117     ((struct bpf_insn) {                    \
0118         .code  = BPF_ALU64 | BPF_MOV | BPF_SRC(TYPE),   \
0119         .dst_reg = DST,                 \
0120         .src_reg = SRC,                 \
0121         .off   = 0,                 \
0122         .imm   = IMM })
0123 
0124 #define BPF_MOV32_RAW(TYPE, DST, SRC, IMM)          \
0125     ((struct bpf_insn) {                    \
0126         .code  = BPF_ALU | BPF_MOV | BPF_SRC(TYPE), \
0127         .dst_reg = DST,                 \
0128         .src_reg = SRC,                 \
0129         .off   = 0,                 \
0130         .imm   = IMM })
0131 
0132 /* Direct packet access, R0 = *(uint *) (skb->data + imm32) */
0133 
0134 #define BPF_LD_ABS(SIZE, IMM)                   \
0135     ((struct bpf_insn) {                    \
0136         .code  = BPF_LD | BPF_SIZE(SIZE) | BPF_ABS, \
0137         .dst_reg = 0,                   \
0138         .src_reg = 0,                   \
0139         .off   = 0,                 \
0140         .imm   = IMM })
0141 
0142 /* Indirect packet access, R0 = *(uint *) (skb->data + src_reg + imm32) */
0143 
0144 #define BPF_LD_IND(SIZE, SRC, IMM)              \
0145     ((struct bpf_insn) {                    \
0146         .code  = BPF_LD | BPF_SIZE(SIZE) | BPF_IND, \
0147         .dst_reg = 0,                   \
0148         .src_reg = SRC,                 \
0149         .off   = 0,                 \
0150         .imm   = IMM })
0151 
0152 /* Memory load, dst_reg = *(uint *) (src_reg + off16) */
0153 
0154 #define BPF_LDX_MEM(SIZE, DST, SRC, OFF)            \
0155     ((struct bpf_insn) {                    \
0156         .code  = BPF_LDX | BPF_SIZE(SIZE) | BPF_MEM,    \
0157         .dst_reg = DST,                 \
0158         .src_reg = SRC,                 \
0159         .off   = OFF,                   \
0160         .imm   = 0 })
0161 
0162 /* Memory store, *(uint *) (dst_reg + off16) = src_reg */
0163 
0164 #define BPF_STX_MEM(SIZE, DST, SRC, OFF)            \
0165     ((struct bpf_insn) {                    \
0166         .code  = BPF_STX | BPF_SIZE(SIZE) | BPF_MEM,    \
0167         .dst_reg = DST,                 \
0168         .src_reg = SRC,                 \
0169         .off   = OFF,                   \
0170         .imm   = 0 })
0171 
0172 /*
0173  * Atomic operations:
0174  *
0175  *   BPF_ADD                  *(uint *) (dst_reg + off16) += src_reg
0176  *   BPF_AND                  *(uint *) (dst_reg + off16) &= src_reg
0177  *   BPF_OR                   *(uint *) (dst_reg + off16) |= src_reg
0178  *   BPF_XOR                  *(uint *) (dst_reg + off16) ^= src_reg
0179  *   BPF_ADD | BPF_FETCH      src_reg = atomic_fetch_add(dst_reg + off16, src_reg);
0180  *   BPF_AND | BPF_FETCH      src_reg = atomic_fetch_and(dst_reg + off16, src_reg);
0181  *   BPF_OR | BPF_FETCH       src_reg = atomic_fetch_or(dst_reg + off16, src_reg);
0182  *   BPF_XOR | BPF_FETCH      src_reg = atomic_fetch_xor(dst_reg + off16, src_reg);
0183  *   BPF_XCHG                 src_reg = atomic_xchg(dst_reg + off16, src_reg)
0184  *   BPF_CMPXCHG              r0 = atomic_cmpxchg(dst_reg + off16, r0, src_reg)
0185  */
0186 
0187 #define BPF_ATOMIC_OP(SIZE, OP, DST, SRC, OFF)          \
0188     ((struct bpf_insn) {                    \
0189         .code  = BPF_STX | BPF_SIZE(SIZE) | BPF_ATOMIC, \
0190         .dst_reg = DST,                 \
0191         .src_reg = SRC,                 \
0192         .off   = OFF,                   \
0193         .imm   = OP })
0194 
0195 /* Legacy alias */
0196 #define BPF_STX_XADD(SIZE, DST, SRC, OFF) BPF_ATOMIC_OP(SIZE, BPF_ADD, DST, SRC, OFF)
0197 
0198 /* Memory store, *(uint *) (dst_reg + off16) = imm32 */
0199 
0200 #define BPF_ST_MEM(SIZE, DST, OFF, IMM)             \
0201     ((struct bpf_insn) {                    \
0202         .code  = BPF_ST | BPF_SIZE(SIZE) | BPF_MEM, \
0203         .dst_reg = DST,                 \
0204         .src_reg = 0,                   \
0205         .off   = OFF,                   \
0206         .imm   = IMM })
0207 
0208 /* Conditional jumps against registers, if (dst_reg 'op' src_reg) goto pc + off16 */
0209 
0210 #define BPF_JMP_REG(OP, DST, SRC, OFF)              \
0211     ((struct bpf_insn) {                    \
0212         .code  = BPF_JMP | BPF_OP(OP) | BPF_X,      \
0213         .dst_reg = DST,                 \
0214         .src_reg = SRC,                 \
0215         .off   = OFF,                   \
0216         .imm   = 0 })
0217 
0218 /* Like BPF_JMP_REG, but with 32-bit wide operands for comparison. */
0219 
0220 #define BPF_JMP32_REG(OP, DST, SRC, OFF)            \
0221     ((struct bpf_insn) {                    \
0222         .code  = BPF_JMP32 | BPF_OP(OP) | BPF_X,    \
0223         .dst_reg = DST,                 \
0224         .src_reg = SRC,                 \
0225         .off   = OFF,                   \
0226         .imm   = 0 })
0227 
0228 /* Conditional jumps against immediates, if (dst_reg 'op' imm32) goto pc + off16 */
0229 
0230 #define BPF_JMP_IMM(OP, DST, IMM, OFF)              \
0231     ((struct bpf_insn) {                    \
0232         .code  = BPF_JMP | BPF_OP(OP) | BPF_K,      \
0233         .dst_reg = DST,                 \
0234         .src_reg = 0,                   \
0235         .off   = OFF,                   \
0236         .imm   = IMM })
0237 
0238 /* Like BPF_JMP_IMM, but with 32-bit wide operands for comparison. */
0239 
0240 #define BPF_JMP32_IMM(OP, DST, IMM, OFF)            \
0241     ((struct bpf_insn) {                    \
0242         .code  = BPF_JMP32 | BPF_OP(OP) | BPF_K,    \
0243         .dst_reg = DST,                 \
0244         .src_reg = 0,                   \
0245         .off   = OFF,                   \
0246         .imm   = IMM })
0247 
0248 /* Unconditional jumps, goto pc + off16 */
0249 
0250 #define BPF_JMP_A(OFF)                      \
0251     ((struct bpf_insn) {                    \
0252         .code  = BPF_JMP | BPF_JA,          \
0253         .dst_reg = 0,                   \
0254         .src_reg = 0,                   \
0255         .off   = OFF,                   \
0256         .imm   = 0 })
0257 
0258 /* Function call */
0259 
0260 #define BPF_EMIT_CALL(FUNC)                 \
0261     ((struct bpf_insn) {                    \
0262         .code  = BPF_JMP | BPF_CALL,            \
0263         .dst_reg = 0,                   \
0264         .src_reg = 0,                   \
0265         .off   = 0,                 \
0266         .imm   = ((FUNC) - BPF_FUNC_unspec) })
0267 
0268 /* Raw code statement block */
0269 
0270 #define BPF_RAW_INSN(CODE, DST, SRC, OFF, IMM)          \
0271     ((struct bpf_insn) {                    \
0272         .code  = CODE,                  \
0273         .dst_reg = DST,                 \
0274         .src_reg = SRC,                 \
0275         .off   = OFF,                   \
0276         .imm   = IMM })
0277 
0278 /* BPF_LD_IMM64 macro encodes single 'load 64-bit immediate' insn */
0279 
0280 #define BPF_LD_IMM64(DST, IMM)                  \
0281     BPF_LD_IMM64_RAW(DST, 0, IMM)
0282 
0283 #define BPF_LD_IMM64_RAW(DST, SRC, IMM)             \
0284     ((struct bpf_insn) {                    \
0285         .code  = BPF_LD | BPF_DW | BPF_IMM,     \
0286         .dst_reg = DST,                 \
0287         .src_reg = SRC,                 \
0288         .off   = 0,                 \
0289         .imm   = (__u32) (IMM) }),          \
0290     ((struct bpf_insn) {                    \
0291         .code  = 0, /* zero is reserved opcode */   \
0292         .dst_reg = 0,                   \
0293         .src_reg = 0,                   \
0294         .off   = 0,                 \
0295         .imm   = ((__u64) (IMM)) >> 32 })
0296 
0297 #define BPF_LD_IMM64_RAW_FULL(DST, SRC, OFF1, OFF2, IMM1, IMM2) \
0298     ((struct bpf_insn) {                    \
0299         .code  = BPF_LD | BPF_DW | BPF_IMM,     \
0300         .dst_reg = DST,                 \
0301         .src_reg = SRC,                 \
0302         .off   = OFF1,                  \
0303         .imm   = IMM1 }),               \
0304     ((struct bpf_insn) {                    \
0305         .code  = 0, /* zero is reserved opcode */   \
0306         .dst_reg = 0,                   \
0307         .src_reg = 0,                   \
0308         .off   = OFF2,                  \
0309         .imm   = IMM2 })
0310 
0311 /* pseudo BPF_LD_IMM64 insn used to refer to process-local map_fd */
0312 
0313 #define BPF_LD_MAP_FD(DST, MAP_FD)              \
0314     BPF_LD_IMM64_RAW_FULL(DST, BPF_PSEUDO_MAP_FD, 0, 0, \
0315                   MAP_FD, 0)
0316 
0317 #define BPF_LD_MAP_VALUE(DST, MAP_FD, VALUE_OFF)        \
0318     BPF_LD_IMM64_RAW_FULL(DST, BPF_PSEUDO_MAP_VALUE, 0, 0,  \
0319                   MAP_FD, VALUE_OFF)
0320 
0321 /* Relative call */
0322 
0323 #define BPF_CALL_REL(TGT)                   \
0324     ((struct bpf_insn) {                    \
0325         .code  = BPF_JMP | BPF_CALL,            \
0326         .dst_reg = 0,                   \
0327         .src_reg = BPF_PSEUDO_CALL,         \
0328         .off   = 0,                 \
0329         .imm   = TGT })
0330 
0331 /* Program exit */
0332 
0333 #define BPF_EXIT_INSN()                     \
0334     ((struct bpf_insn) {                    \
0335         .code  = BPF_JMP | BPF_EXIT,            \
0336         .dst_reg = 0,                   \
0337         .src_reg = 0,                   \
0338         .off   = 0,                 \
0339         .imm   = 0 })
0340 
0341 #endif /* __TOOLS_LINUX_FILTER_H */