Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * Linux Socket Filter Data Structures | |
3 | */ | |
1da177e4 LT |
4 | #ifndef __LINUX_FILTER_H__ |
5 | #define __LINUX_FILTER_H__ | |
6 | ||
60063497 | 7 | #include <linux/atomic.h> |
0c5fe1b4 | 8 | #include <linux/compat.h> |
d45ed4a4 | 9 | #include <linux/workqueue.h> |
607ca46e | 10 | #include <uapi/linux/filter.h> |
792d4b5c | 11 | |
0c5fe1b4 WD |
12 | #ifdef CONFIG_COMPAT |
13 | /* | |
14 | * A struct sock_filter is architecture independent. | |
15 | */ | |
16 | struct compat_sock_fprog { | |
17 | u16 len; | |
18 | compat_uptr_t filter; /* struct sock_filter * */ | |
19 | }; | |
20 | #endif | |
21 | ||
a3ea269b DB |
22 | struct sock_fprog_kern { |
23 | u16 len; | |
24 | struct sock_filter *filter; | |
25 | }; | |
26 | ||
792d4b5c HC |
27 | struct sk_buff; |
28 | struct sock; | |
29 | ||
a3ea269b | 30 | struct sk_filter { |
b715631f | 31 | atomic_t refcnt; |
f8bbbfc3 DB |
32 | u32 jited:1, /* Is our filter JIT'ed? */ |
33 | len:31; /* Number of filter blocks */ | |
a3ea269b | 34 | struct sock_fprog_kern *orig_prog; /* Original BPF program */ |
d45ed4a4 | 35 | struct rcu_head rcu; |
0a14842f ED |
36 | unsigned int (*bpf_func)(const struct sk_buff *skb, |
37 | const struct sock_filter *filter); | |
d45ed4a4 AS |
38 | union { |
39 | struct sock_filter insns[0]; | |
40 | struct work_struct work; | |
41 | }; | |
b715631f SH |
42 | }; |
43 | ||
d45ed4a4 | 44 | static inline unsigned int sk_filter_size(unsigned int proglen) |
b715631f | 45 | { |
d45ed4a4 AS |
46 | return max(sizeof(struct sk_filter), |
47 | offsetof(struct sk_filter, insns[proglen])); | |
b715631f SH |
48 | } |
49 | ||
a3ea269b DB |
50 | #define sk_filter_proglen(fprog) \ |
51 | (fprog->len * sizeof(fprog->filter[0])) | |
52 | ||
43db6d65 | 53 | extern int sk_filter(struct sock *sk, struct sk_buff *skb); |
62ab0812 | 54 | extern unsigned int sk_run_filter(const struct sk_buff *skb, |
93aaae2e | 55 | const struct sock_filter *filter); |
a3ea269b | 56 | |
302d6637 JP |
57 | extern int sk_unattached_filter_create(struct sk_filter **pfp, |
58 | struct sock_fprog *fprog); | |
59 | extern void sk_unattached_filter_destroy(struct sk_filter *fp); | |
a3ea269b | 60 | |
1da177e4 | 61 | extern int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk); |
55b33325 | 62 | extern int sk_detach_filter(struct sock *sk); |
a3ea269b | 63 | |
4f25af27 | 64 | extern int sk_chk_filter(struct sock_filter *filter, unsigned int flen); |
a8fc9277 | 65 | extern int sk_get_filter(struct sock *sk, struct sock_filter __user *filter, unsigned len); |
ed13998c | 66 | extern void sk_decode_filter(struct sock_filter *filt, struct sock_filter *to); |
0a14842f ED |
67 | |
68 | #ifdef CONFIG_BPF_JIT | |
20074f35 | 69 | #include <stdarg.h> |
a691ce7f CG |
70 | #include <linux/linkage.h> |
71 | #include <linux/printk.h> | |
72 | ||
0a14842f ED |
73 | extern void bpf_jit_compile(struct sk_filter *fp); |
74 | extern void bpf_jit_free(struct sk_filter *fp); | |
79617801 DB |
75 | |
76 | static inline void bpf_jit_dump(unsigned int flen, unsigned int proglen, | |
77 | u32 pass, void *image) | |
78 | { | |
16495445 | 79 | pr_err("flen=%u proglen=%u pass=%u image=%pK\n", |
79617801 DB |
80 | flen, proglen, pass, image); |
81 | if (image) | |
16495445 | 82 | print_hex_dump(KERN_ERR, "JIT code: ", DUMP_PREFIX_OFFSET, |
79617801 DB |
83 | 16, 1, image, proglen, false); |
84 | } | |
0a14842f ED |
85 | #define SK_RUN_FILTER(FILTER, SKB) (*FILTER->bpf_func)(SKB, FILTER->insns) |
86 | #else | |
d45ed4a4 | 87 | #include <linux/slab.h> |
0a14842f ED |
88 | static inline void bpf_jit_compile(struct sk_filter *fp) |
89 | { | |
90 | } | |
91 | static inline void bpf_jit_free(struct sk_filter *fp) | |
92 | { | |
d45ed4a4 | 93 | kfree(fp); |
0a14842f ED |
94 | } |
95 | #define SK_RUN_FILTER(FILTER, SKB) sk_run_filter(SKB, FILTER->insns) | |
96 | #endif | |
97 | ||
ea02f941 MS |
98 | static inline int bpf_tell_extensions(void) |
99 | { | |
37692299 | 100 | return SKF_AD_MAX; |
ea02f941 MS |
101 | } |
102 | ||
0a14842f ED |
103 | enum { |
104 | BPF_S_RET_K = 1, | |
105 | BPF_S_RET_A, | |
106 | BPF_S_ALU_ADD_K, | |
107 | BPF_S_ALU_ADD_X, | |
108 | BPF_S_ALU_SUB_K, | |
109 | BPF_S_ALU_SUB_X, | |
110 | BPF_S_ALU_MUL_K, | |
111 | BPF_S_ALU_MUL_X, | |
112 | BPF_S_ALU_DIV_X, | |
b6069a95 ED |
113 | BPF_S_ALU_MOD_K, |
114 | BPF_S_ALU_MOD_X, | |
0a14842f ED |
115 | BPF_S_ALU_AND_K, |
116 | BPF_S_ALU_AND_X, | |
117 | BPF_S_ALU_OR_K, | |
118 | BPF_S_ALU_OR_X, | |
9e49e889 DB |
119 | BPF_S_ALU_XOR_K, |
120 | BPF_S_ALU_XOR_X, | |
0a14842f ED |
121 | BPF_S_ALU_LSH_K, |
122 | BPF_S_ALU_LSH_X, | |
123 | BPF_S_ALU_RSH_K, | |
124 | BPF_S_ALU_RSH_X, | |
125 | BPF_S_ALU_NEG, | |
126 | BPF_S_LD_W_ABS, | |
127 | BPF_S_LD_H_ABS, | |
128 | BPF_S_LD_B_ABS, | |
129 | BPF_S_LD_W_LEN, | |
130 | BPF_S_LD_W_IND, | |
131 | BPF_S_LD_H_IND, | |
132 | BPF_S_LD_B_IND, | |
133 | BPF_S_LD_IMM, | |
134 | BPF_S_LDX_W_LEN, | |
135 | BPF_S_LDX_B_MSH, | |
136 | BPF_S_LDX_IMM, | |
137 | BPF_S_MISC_TAX, | |
138 | BPF_S_MISC_TXA, | |
139 | BPF_S_ALU_DIV_K, | |
140 | BPF_S_LD_MEM, | |
141 | BPF_S_LDX_MEM, | |
142 | BPF_S_ST, | |
143 | BPF_S_STX, | |
144 | BPF_S_JMP_JA, | |
145 | BPF_S_JMP_JEQ_K, | |
146 | BPF_S_JMP_JEQ_X, | |
147 | BPF_S_JMP_JGE_K, | |
148 | BPF_S_JMP_JGE_X, | |
149 | BPF_S_JMP_JGT_K, | |
150 | BPF_S_JMP_JGT_X, | |
151 | BPF_S_JMP_JSET_K, | |
152 | BPF_S_JMP_JSET_X, | |
153 | /* Ancillary data */ | |
154 | BPF_S_ANC_PROTOCOL, | |
155 | BPF_S_ANC_PKTTYPE, | |
156 | BPF_S_ANC_IFINDEX, | |
157 | BPF_S_ANC_NLATTR, | |
158 | BPF_S_ANC_NLATTR_NEST, | |
159 | BPF_S_ANC_MARK, | |
160 | BPF_S_ANC_QUEUE, | |
161 | BPF_S_ANC_HATYPE, | |
162 | BPF_S_ANC_RXHASH, | |
163 | BPF_S_ANC_CPU, | |
ffe06c17 | 164 | BPF_S_ANC_ALU_XOR_X, |
46b325c7 | 165 | BPF_S_ANC_SECCOMP_LD_W, |
f3335031 ED |
166 | BPF_S_ANC_VLAN_TAG, |
167 | BPF_S_ANC_VLAN_TAG_PRESENT, | |
3e5289d5 | 168 | BPF_S_ANC_PAY_OFFSET, |
0a14842f ED |
169 | }; |
170 | ||
1da177e4 | 171 | #endif /* __LINUX_FILTER_H__ */ |