aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorDaniel Borkmann <dborkman@redhat.com>2014-05-29 04:22:50 -0400
committerDavid S. Miller <davem@davemloft.net>2014-06-02 01:16:58 -0400
commit3480593131e0b781287dae0139bf7ccee7cba7ff (patch)
tree6e259a45b3767bd80b789814e4d484ee0ac069bf /include/linux
parentd50bc1575096250aa37f17299c86ea548156efe8 (diff)
net: filter: get rid of BPF_S_* enum
This patch finally allows us to get rid of the BPF_S_* enum. Currently, the code performs unnecessary encode and decode workarounds in seccomp and filter migration itself when a filter is being attached in order to overcome BPF_S_* encoding which is not used anymore by the new interpreter resp. JIT compilers. Keeping it around would mean that also in future we would need to extend and maintain this enum and related encoders/decoders. We can get rid of all that and save us these operations during filter attaching. Naturally, also JIT compilers need to be updated by this. Before JIT conversion is being done, each compiler checks if A is being loaded at startup to obtain information if it needs to emit instructions to clear A first. Since BPF extensions are a subset of BPF_LD | BPF_{W,H,B} | BPF_ABS variants, case statements for extensions can be removed at that point. To ease and minimalize code changes in the classic JITs, we have introduced bpf_anc_helper(). Tested with test_bpf on x86_64 (JIT, int), s390x (JIT, int), arm (JIT, int), i368 (int), ppc64 (JIT, int); for sparc we unfortunately didn't have access, but changes are analogous to the rest. Joint work with Alexei Starovoitov. Signed-off-by: Daniel Borkmann <dborkman@redhat.com> Signed-off-by: Alexei Starovoitov <ast@plumgrid.com> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Martin Schwidefsky <schwidefsky@de.ibm.com> Cc: Mircea Gherzan <mgherzan@gmail.com> Cc: Kees Cook <keescook@chromium.org> Acked-by: Chema Gonzalez <chemag@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/filter.h108
1 files changed, 38 insertions, 70 deletions
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 625f4de9bdf2..49ef7a298c92 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -197,7 +197,6 @@ int sk_detach_filter(struct sock *sk);
197int sk_chk_filter(struct sock_filter *filter, unsigned int flen); 197int sk_chk_filter(struct sock_filter *filter, unsigned int flen);
198int sk_get_filter(struct sock *sk, struct sock_filter __user *filter, 198int sk_get_filter(struct sock *sk, struct sock_filter __user *filter,
199 unsigned int len); 199 unsigned int len);
200void sk_decode_filter(struct sock_filter *filt, struct sock_filter *to);
201 200
202void sk_filter_charge(struct sock *sk, struct sk_filter *fp); 201void sk_filter_charge(struct sock *sk, struct sk_filter *fp);
203void sk_filter_uncharge(struct sock *sk, struct sk_filter *fp); 202void sk_filter_uncharge(struct sock *sk, struct sk_filter *fp);
@@ -205,6 +204,41 @@ void sk_filter_uncharge(struct sock *sk, struct sk_filter *fp);
205u64 __bpf_call_base(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5); 204u64 __bpf_call_base(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5);
206void bpf_int_jit_compile(struct sk_filter *fp); 205void bpf_int_jit_compile(struct sk_filter *fp);
207 206
207#define BPF_ANC BIT(15)
208
209static inline u16 bpf_anc_helper(const struct sock_filter *ftest)
210{
211 BUG_ON(ftest->code & BPF_ANC);
212
213 switch (ftest->code) {
214 case BPF_LD | BPF_W | BPF_ABS:
215 case BPF_LD | BPF_H | BPF_ABS:
216 case BPF_LD | BPF_B | BPF_ABS:
217#define BPF_ANCILLARY(CODE) case SKF_AD_OFF + SKF_AD_##CODE: \
218 return BPF_ANC | SKF_AD_##CODE
219 switch (ftest->k) {
220 BPF_ANCILLARY(PROTOCOL);
221 BPF_ANCILLARY(PKTTYPE);
222 BPF_ANCILLARY(IFINDEX);
223 BPF_ANCILLARY(NLATTR);
224 BPF_ANCILLARY(NLATTR_NEST);
225 BPF_ANCILLARY(MARK);
226 BPF_ANCILLARY(QUEUE);
227 BPF_ANCILLARY(HATYPE);
228 BPF_ANCILLARY(RXHASH);
229 BPF_ANCILLARY(CPU);
230 BPF_ANCILLARY(ALU_XOR_X);
231 BPF_ANCILLARY(VLAN_TAG);
232 BPF_ANCILLARY(VLAN_TAG_PRESENT);
233 BPF_ANCILLARY(PAY_OFFSET);
234 BPF_ANCILLARY(RANDOM);
235 }
236 /* Fallthrough. */
237 default:
238 return ftest->code;
239 }
240}
241
208#ifdef CONFIG_BPF_JIT 242#ifdef CONFIG_BPF_JIT
209#include <stdarg.h> 243#include <stdarg.h>
210#include <linux/linkage.h> 244#include <linux/linkage.h>
@@ -224,86 +258,20 @@ static inline void bpf_jit_dump(unsigned int flen, unsigned int proglen,
224} 258}
225#else 259#else
226#include <linux/slab.h> 260#include <linux/slab.h>
261
227static inline void bpf_jit_compile(struct sk_filter *fp) 262static inline void bpf_jit_compile(struct sk_filter *fp)
228{ 263{
229} 264}
265
230static inline void bpf_jit_free(struct sk_filter *fp) 266static inline void bpf_jit_free(struct sk_filter *fp)
231{ 267{
232 kfree(fp); 268 kfree(fp);
233} 269}
234#endif 270#endif /* CONFIG_BPF_JIT */
235 271
236static inline int bpf_tell_extensions(void) 272static inline int bpf_tell_extensions(void)
237{ 273{
238 return SKF_AD_MAX; 274 return SKF_AD_MAX;
239} 275}
240 276
241enum {
242 BPF_S_RET_K = 1,
243 BPF_S_RET_A,
244 BPF_S_ALU_ADD_K,
245 BPF_S_ALU_ADD_X,
246 BPF_S_ALU_SUB_K,
247 BPF_S_ALU_SUB_X,
248 BPF_S_ALU_MUL_K,
249 BPF_S_ALU_MUL_X,
250 BPF_S_ALU_DIV_X,
251 BPF_S_ALU_MOD_K,
252 BPF_S_ALU_MOD_X,
253 BPF_S_ALU_AND_K,
254 BPF_S_ALU_AND_X,
255 BPF_S_ALU_OR_K,
256 BPF_S_ALU_OR_X,
257 BPF_S_ALU_XOR_K,
258 BPF_S_ALU_XOR_X,
259 BPF_S_ALU_LSH_K,
260 BPF_S_ALU_LSH_X,
261 BPF_S_ALU_RSH_K,
262 BPF_S_ALU_RSH_X,
263 BPF_S_ALU_NEG,
264 BPF_S_LD_W_ABS,
265 BPF_S_LD_H_ABS,
266 BPF_S_LD_B_ABS,
267 BPF_S_LD_W_LEN,
268 BPF_S_LD_W_IND,
269 BPF_S_LD_H_IND,
270 BPF_S_LD_B_IND,
271 BPF_S_LD_IMM,
272 BPF_S_LDX_W_LEN,
273 BPF_S_LDX_B_MSH,
274 BPF_S_LDX_IMM,
275 BPF_S_MISC_TAX,
276 BPF_S_MISC_TXA,
277 BPF_S_ALU_DIV_K,
278 BPF_S_LD_MEM,
279 BPF_S_LDX_MEM,
280 BPF_S_ST,
281 BPF_S_STX,
282 BPF_S_JMP_JA,
283 BPF_S_JMP_JEQ_K,
284 BPF_S_JMP_JEQ_X,
285 BPF_S_JMP_JGE_K,
286 BPF_S_JMP_JGE_X,
287 BPF_S_JMP_JGT_K,
288 BPF_S_JMP_JGT_X,
289 BPF_S_JMP_JSET_K,
290 BPF_S_JMP_JSET_X,
291 /* Ancillary data */
292 BPF_S_ANC_PROTOCOL,
293 BPF_S_ANC_PKTTYPE,
294 BPF_S_ANC_IFINDEX,
295 BPF_S_ANC_NLATTR,
296 BPF_S_ANC_NLATTR_NEST,
297 BPF_S_ANC_MARK,
298 BPF_S_ANC_QUEUE,
299 BPF_S_ANC_HATYPE,
300 BPF_S_ANC_RXHASH,
301 BPF_S_ANC_CPU,
302 BPF_S_ANC_ALU_XOR_X,
303 BPF_S_ANC_VLAN_TAG,
304 BPF_S_ANC_VLAN_TAG_PRESENT,
305 BPF_S_ANC_PAY_OFFSET,
306 BPF_S_ANC_RANDOM,
307};
308
309#endif /* __LINUX_FILTER_H__ */ 277#endif /* __LINUX_FILTER_H__ */