aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/filter.h255
1 files changed, 205 insertions, 50 deletions
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 49ef7a298c92..f0c2ad43b4af 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -76,56 +76,211 @@ enum {
76/* BPF program can access up to 512 bytes of stack space. */ 76/* BPF program can access up to 512 bytes of stack space. */
77#define MAX_BPF_STACK 512 77#define MAX_BPF_STACK 512
78 78
79/* bpf_add|sub|...: a += x, bpf_mov: a = x */ 79/* Helper macros for filter block array initializers. */
80#define BPF_ALU64_REG(op, a, x) \ 80
81 ((struct sock_filter_int) {BPF_ALU64|BPF_OP(op)|BPF_X, a, x, 0, 0}) 81/* ALU ops on registers, bpf_add|sub|...: A += X */
82#define BPF_ALU32_REG(op, a, x) \ 82
83 ((struct sock_filter_int) {BPF_ALU|BPF_OP(op)|BPF_X, a, x, 0, 0}) 83#define BPF_ALU64_REG(OP, A, X) \
84 84 ((struct sock_filter_int) { \
85/* bpf_add|sub|...: a += imm, bpf_mov: a = imm */ 85 .code = BPF_ALU64 | BPF_OP(OP) | BPF_X, \
86#define BPF_ALU64_IMM(op, a, imm) \ 86 .a_reg = A, \
87 ((struct sock_filter_int) {BPF_ALU64|BPF_OP(op)|BPF_K, a, 0, 0, imm}) 87 .x_reg = X, \
88#define BPF_ALU32_IMM(op, a, imm) \ 88 .off = 0, \
89 ((struct sock_filter_int) {BPF_ALU|BPF_OP(op)|BPF_K, a, 0, 0, imm}) 89 .imm = 0 })
90 90
91/* R0 = *(uint *) (skb->data + off) */ 91#define BPF_ALU32_REG(OP, A, X) \
92#define BPF_LD_ABS(size, off) \ 92 ((struct sock_filter_int) { \
93 ((struct sock_filter_int) {BPF_LD|BPF_SIZE(size)|BPF_ABS, 0, 0, 0, off}) 93 .code = BPF_ALU | BPF_OP(OP) | BPF_X, \
94 94 .a_reg = A, \
95/* R0 = *(uint *) (skb->data + x + off) */ 95 .x_reg = X, \
96#define BPF_LD_IND(size, x, off) \ 96 .off = 0, \
97 ((struct sock_filter_int) {BPF_LD|BPF_SIZE(size)|BPF_IND, 0, x, 0, off}) 97 .imm = 0 })
98 98
99/* a = *(uint *) (x + off) */ 99/* ALU ops on immediates, bpf_add|sub|...: A += IMM */
100#define BPF_LDX_MEM(sz, a, x, off) \ 100
101 ((struct sock_filter_int) {BPF_LDX|BPF_SIZE(sz)|BPF_MEM, a, x, off, 0}) 101#define BPF_ALU64_IMM(OP, A, IMM) \
102 102 ((struct sock_filter_int) { \
103/* if (a 'op' x) goto pc+off */ 103 .code = BPF_ALU64 | BPF_OP(OP) | BPF_K, \
104#define BPF_JMP_REG(op, a, x, off) \ 104 .a_reg = A, \
105 ((struct sock_filter_int) {BPF_JMP|BPF_OP(op)|BPF_X, a, x, off, 0}) 105 .x_reg = 0, \
106 106 .off = 0, \
107/* if (a 'op' imm) goto pc+off */ 107 .imm = IMM })
108#define BPF_JMP_IMM(op, a, imm, off) \ 108
109 ((struct sock_filter_int) {BPF_JMP|BPF_OP(op)|BPF_K, a, 0, off, imm}) 109#define BPF_ALU32_IMM(OP, A, IMM) \
110 110 ((struct sock_filter_int) { \
111#define BPF_EXIT_INSN() \ 111 .code = BPF_ALU | BPF_OP(OP) | BPF_K, \
112 ((struct sock_filter_int) {BPF_JMP|BPF_EXIT, 0, 0, 0, 0}) 112 .a_reg = A, \
113 113 .x_reg = 0, \
114static inline int size_to_bpf(int size) 114 .off = 0, \
115{ 115 .imm = IMM })
116 switch (size) { 116
117 case 1: 117/* Endianess conversion, cpu_to_{l,b}e(), {l,b}e_to_cpu() */
118 return BPF_B; 118
119 case 2: 119#define BPF_ENDIAN(TYPE, A, LEN) \
120 return BPF_H; 120 ((struct sock_filter_int) { \
121 case 4: 121 .code = BPF_ALU | BPF_END | BPF_SRC(TYPE), \
122 return BPF_W; 122 .a_reg = A, \
123 case 8: 123 .x_reg = 0, \
124 return BPF_DW; 124 .off = 0, \
125 default: 125 .imm = LEN })
126 return -EINVAL; 126
127 } 127/* Short form of mov, A = X */
128} 128
129#define BPF_MOV64_REG(A, X) \
130 ((struct sock_filter_int) { \
131 .code = BPF_ALU64 | BPF_MOV | BPF_X, \
132 .a_reg = A, \
133 .x_reg = X, \
134 .off = 0, \
135 .imm = 0 })
136
137#define BPF_MOV32_REG(A, X) \
138 ((struct sock_filter_int) { \
139 .code = BPF_ALU | BPF_MOV | BPF_X, \
140 .a_reg = A, \
141 .x_reg = X, \
142 .off = 0, \
143 .imm = 0 })
144
145/* Short form of mov, A = IMM */
146
147#define BPF_MOV64_IMM(A, IMM) \
148 ((struct sock_filter_int) { \
149 .code = BPF_ALU64 | BPF_MOV | BPF_K, \
150 .a_reg = A, \
151 .x_reg = 0, \
152 .off = 0, \
153 .imm = IMM })
154
155#define BPF_MOV32_IMM(A, IMM) \
156 ((struct sock_filter_int) { \
157 .code = BPF_ALU | BPF_MOV | BPF_K, \
158 .a_reg = A, \
159 .x_reg = 0, \
160 .off = 0, \
161 .imm = IMM })
162
163/* Short form of mov based on type, BPF_X: A = X, BPF_K: A = IMM */
164
165#define BPF_MOV64_RAW(TYPE, A, X, IMM) \
166 ((struct sock_filter_int) { \
167 .code = BPF_ALU64 | BPF_MOV | BPF_SRC(TYPE), \
168 .a_reg = A, \
169 .x_reg = X, \
170 .off = 0, \
171 .imm = IMM })
172
173#define BPF_MOV32_RAW(TYPE, A, X, IMM) \
174 ((struct sock_filter_int) { \
175 .code = BPF_ALU | BPF_MOV | BPF_SRC(TYPE), \
176 .a_reg = A, \
177 .x_reg = X, \
178 .off = 0, \
179 .imm = IMM })
180
181/* Direct packet access, R0 = *(uint *) (skb->data + OFF) */
182
183#define BPF_LD_ABS(SIZE, OFF) \
184 ((struct sock_filter_int) { \
185 .code = BPF_LD | BPF_SIZE(SIZE) | BPF_ABS, \
186 .a_reg = 0, \
187 .x_reg = 0, \
188 .off = 0, \
189 .imm = OFF })
190
191/* Indirect packet access, R0 = *(uint *) (skb->data + X + OFF) */
192
193#define BPF_LD_IND(SIZE, X, OFF) \
194 ((struct sock_filter_int) { \
195 .code = BPF_LD | BPF_SIZE(SIZE) | BPF_IND, \
196 .a_reg = 0, \
197 .x_reg = X, \
198 .off = 0, \
199 .imm = OFF })
200
201/* Memory store, A = *(uint *) (X + OFF), and vice versa */
202
203#define BPF_LDX_MEM(SIZE, A, X, OFF) \
204 ((struct sock_filter_int) { \
205 .code = BPF_LDX | BPF_SIZE(SIZE) | BPF_MEM, \
206 .a_reg = A, \
207 .x_reg = X, \
208 .off = OFF, \
209 .imm = 0 })
210
211#define BPF_STX_MEM(SIZE, A, X, OFF) \
212 ((struct sock_filter_int) { \
213 .code = BPF_STX | BPF_SIZE(SIZE) | BPF_MEM, \
214 .a_reg = A, \
215 .x_reg = X, \
216 .off = OFF, \
217 .imm = 0 })
218
219/* Conditional jumps against registers, if (A 'op' X) goto pc + OFF */
220
221#define BPF_JMP_REG(OP, A, X, OFF) \
222 ((struct sock_filter_int) { \
223 .code = BPF_JMP | BPF_OP(OP) | BPF_X, \
224 .a_reg = A, \
225 .x_reg = X, \
226 .off = OFF, \
227 .imm = 0 })
228
229/* Conditional jumps against immediates, if (A 'op' IMM) goto pc + OFF */
230
231#define BPF_JMP_IMM(OP, A, IMM, OFF) \
232 ((struct sock_filter_int) { \
233 .code = BPF_JMP | BPF_OP(OP) | BPF_K, \
234 .a_reg = A, \
235 .x_reg = 0, \
236 .off = OFF, \
237 .imm = IMM })
238
239/* Function call */
240
241#define BPF_EMIT_CALL(FUNC) \
242 ((struct sock_filter_int) { \
243 .code = BPF_JMP | BPF_CALL, \
244 .a_reg = 0, \
245 .x_reg = 0, \
246 .off = 0, \
247 .imm = ((FUNC) - __bpf_call_base) })