1 /* 2 * Linux Socket Filter Data Structures 3 */ 4 #ifndef __LINUX_FILTER_H__ 5 #define __LINUX_FILTER_H__ 6 7 #include <linux/atomic.h> 8 #include <linux/compat.h> 9 #include <linux/workqueue.h> 10 #include <uapi/linux/filter.h> 11 12 /* Internally used and optimized filter representation with extended 13 * instruction set based on top of classic BPF. 14 */ 15 16 /* instruction classes */ 17 #define BPF_ALU64 0x07 /* alu mode in double word width */ 18 19 /* ld/ldx fields */ 20 #define BPF_DW 0x18 /* double word */ 21 #define BPF_XADD 0xc0 /* exclusive add */ 22 23 /* alu/jmp fields */ 24 #define BPF_MOV 0xb0 /* mov reg to reg */ 25 #define BPF_ARSH 0xc0 /* sign extending arithmetic shift right */ 26 27 /* change endianness of a register */ 28 #define BPF_END 0xd0 /* flags for endianness conversion: */ 29 #define BPF_TO_LE 0x00 /* convert to little-endian */ 30 #define BPF_TO_BE 0x08 /* convert to big-endian */ 31 #define BPF_FROM_LE BPF_TO_LE 32 #define BPF_FROM_BE BPF_TO_BE 33 34 #define BPF_JNE 0x50 /* jump != */ 35 #define BPF_JSGT 0x60 /* SGT is signed '>', GT in x86 */ 36 #define BPF_JSGE 0x70 /* SGE is signed '>=', GE in x86 */ 37 #define BPF_CALL 0x80 /* function call */ 38 #define BPF_EXIT 0x90 /* function return */ 39 40 /* BPF has 10 general purpose 64-bit registers and stack frame. */ 41 #define MAX_BPF_REG 11 42 43 /* BPF program can access up to 512 bytes of stack space. */ 44 #define MAX_BPF_STACK 512 45 46 /* Arg1, context and stack frame pointer register positions. */ 47 #define ARG1_REG 1 48 #define CTX_REG 6 49 #define FP_REG 10 50 51 struct sock_filter_int { 52 __u8 code; /* opcode */ 53 __u8 a_reg:4; /* dest register */ 54 __u8 x_reg:4; /* source register */ 55 __s16 off; /* signed offset */ 56 __s32 imm; /* signed immediate constant */ 57 }; 58 59 #ifdef CONFIG_COMPAT 60 /* A struct sock_filter is architecture independent. */ 61 struct compat_sock_fprog { 62 u16 len; 63 compat_uptr_t filter; /* struct sock_filter * */ 64 }; 65 #endif 66 67 struct sock_fprog_kern { 68 u16 len; 69 struct sock_filter *filter; 70 }; 71 72 struct sk_buff; 73 struct sock; 74 struct seccomp_data; 75 76 struct sk_filter { 77 atomic_t refcnt; 78 u32 jited:1, /* Is our filter JIT'ed? */ 79 len:31; /* Number of filter blocks */ 80 struct sock_fprog_kern *orig_prog; /* Original BPF program */ 81 struct rcu_head rcu; 82 unsigned int (*bpf_func)(const struct sk_buff *skb, 83 const struct sock_filter_int *filter); 84 union { 85 struct sock_filter insns[0]; 86 struct sock_filter_int insnsi[0]; 87 struct work_struct work; 88 }; 89 }; 90 91 static inline unsigned int sk_filter_size(unsigned int proglen) 92 { 93 return max(sizeof(struct sk_filter), 94 offsetof(struct sk_filter, insns[proglen])); 95 } 96 97 #define sk_filter_proglen(fprog) \ 98 (fprog->len * sizeof(fprog->filter[0])) 99 100 #define SK_RUN_FILTER(filter, ctx) \ 101 (*filter->bpf_func)(ctx, filter->insnsi) 102 103 int sk_filter(struct sock *sk, struct sk_buff *skb); 104 105 u32 sk_run_filter_int_seccomp(const struct seccomp_data *ctx, 106 const struct sock_filter_int *insni); 107 u32 sk_run_filter_int_skb(const struct sk_buff *ctx, 108 const struct sock_filter_int *insni); 109 110 int sk_convert_filter(struct sock_filter *prog, int len, 111 struct sock_filter_int *new_prog, int *new_len); 112 113 int sk_unattached_filter_create(struct sk_filter **pfp, 114 struct sock_fprog *fprog); 115 void sk_unattached_filter_destroy(struct sk_filter *fp); 116 117 int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk); 118 int sk_detach_filter(struct sock *sk); 119 120 int sk_chk_filter(struct sock_filter *filter, unsigned int flen); 121 int sk_get_filter(struct sock *sk, struct sock_filter __user *filter, 122 unsigned int len); 123 void sk_decode_filter(struct sock_filter *filt, struct sock_filter *to); 124 125 void sk_filter_charge(struct sock *sk, struct sk_filter *fp); 126 void sk_filter_uncharge(struct sock *sk, struct sk_filter *fp); 127 128 #ifdef CONFIG_BPF_JIT 129 #include <stdarg.h> 130 #include <linux/linkage.h> 131 #include <linux/printk.h> 132 133 void bpf_jit_compile(struct sk_filter *fp); 134 void bpf_jit_free(struct sk_filter *fp); 135 136 static inline void bpf_jit_dump(unsigned int flen, unsigned int proglen, 137 u32 pass, void *image) 138 { 139 pr_err("flen=%u proglen=%u pass=%u image=%pK\n", 140 flen, proglen, pass, image); 141 if (image) 142 print_hex_dump(KERN_ERR, "JIT code: ", DUMP_PREFIX_OFFSET, 143 16, 1, image, proglen, false); 144 } 145 #else 146 #include <linux/slab.h> 147 static inline void bpf_jit_compile(struct sk_filter *fp) 148 { 149 } 150 static inline void bpf_jit_free(struct sk_filter *fp) 151 { 152 kfree(fp); 153 } 154 #endif 155 156 static inline int bpf_tell_extensions(void) 157 { 158 return SKF_AD_MAX; 159 } 160 161 enum { 162 BPF_S_RET_K = 1, 163 BPF_S_RET_A, 164 BPF_S_ALU_ADD_K, 165 BPF_S_ALU_ADD_X, 166 BPF_S_ALU_SUB_K, 167 BPF_S_ALU_SUB_X, 168 BPF_S_ALU_MUL_K, 169 BPF_S_ALU_MUL_X, 170 BPF_S_ALU_DIV_X, 171 BPF_S_ALU_MOD_K, 172 BPF_S_ALU_MOD_X, 173 BPF_S_ALU_AND_K, 174 BPF_S_ALU_AND_X, 175 BPF_S_ALU_OR_K, 176 BPF_S_ALU_OR_X, 177 BPF_S_ALU_XOR_K, 178 BPF_S_ALU_XOR_X, 179 BPF_S_ALU_LSH_K, 180 BPF_S_ALU_LSH_X, 181 BPF_S_ALU_RSH_K, 182 BPF_S_ALU_RSH_X, 183 BPF_S_ALU_NEG, 184 BPF_S_LD_W_ABS, 185 BPF_S_LD_H_ABS, 186 BPF_S_LD_B_ABS, 187 BPF_S_LD_W_LEN, 188 BPF_S_LD_W_IND, 189 BPF_S_LD_H_IND, 190 BPF_S_LD_B_IND, 191 BPF_S_LD_IMM, 192 BPF_S_LDX_W_LEN, 193 BPF_S_LDX_B_MSH, 194 BPF_S_LDX_IMM, 195 BPF_S_MISC_TAX, 196 BPF_S_MISC_TXA, 197 BPF_S_ALU_DIV_K, 198 BPF_S_LD_MEM, 199 BPF_S_LDX_MEM, 200 BPF_S_ST, 201 BPF_S_STX, 202 BPF_S_JMP_JA, 203 BPF_S_JMP_JEQ_K, 204 BPF_S_JMP_JEQ_X, 205 BPF_S_JMP_JGE_K, 206 BPF_S_JMP_JGE_X, 207 BPF_S_JMP_JGT_K, 208 BPF_S_JMP_JGT_X, 209 BPF_S_JMP_JSET_K, 210 BPF_S_JMP_JSET_X, 211 /* Ancillary data */ 212 BPF_S_ANC_PROTOCOL, 213 BPF_S_ANC_PKTTYPE, 214 BPF_S_ANC_IFINDEX, 215 BPF_S_ANC_NLATTR, 216 BPF_S_ANC_NLATTR_NEST, 217 BPF_S_ANC_MARK, 218 BPF_S_ANC_QUEUE, 219 BPF_S_ANC_HATYPE, 220 BPF_S_ANC_RXHASH, 221 BPF_S_ANC_CPU, 222 BPF_S_ANC_ALU_XOR_X, 223 BPF_S_ANC_VLAN_TAG, 224 BPF_S_ANC_VLAN_TAG_PRESENT, 225 BPF_S_ANC_PAY_OFFSET, 226 }; 227 228 #endif /* __LINUX_FILTER_H__ */ 229