diff options
author | Denis Kirjanov <kda@linux-powerpc.org> | 2014-11-10 00:59:43 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-11-11 13:39:47 -0500 |
commit | 5b61c4db49e2530ed10631321d4c73f49d560a93 (patch) | |
tree | 1dbc2c4c557a54aa81a161f65b8bffb61ed5bfd6 | |
parent | 4083c8056deebc01e658d6a2ba060cca4e733fb8 (diff) |
PPC: bpf_jit_comp: add SKF_AD_HATYPE instruction
Add BPF extension SKF_AD_HATYPE to ppc JIT to check
the hw type of the interface
Before:
[ 57.723666] test_bpf: #20 LD_HATYPE
[ 57.723675] BPF filter opcode 0020 (@0) unsupported
[ 57.724168] 48 48 PASS
After:
[ 103.053184] test_bpf: #20 LD_HATYPE 7 6 PASS
CC: Alexei Starovoitov<alexei.starovoitov@gmail.com>
CC: Daniel Borkmann<dborkman@redhat.com>
CC: Philippe Bergheaud<felix@linux.vnet.ibm.com>
Signed-off-by: Denis Kirjanov <kda@linux-powerpc.org>
v2: address Alexei's comments
Acked-by: Alexei Starovoitov <ast@plumgrid.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | arch/powerpc/net/bpf_jit_comp.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c index d110e288d7ac..d3fa80d04e6b 100644 --- a/arch/powerpc/net/bpf_jit_comp.c +++ b/arch/powerpc/net/bpf_jit_comp.c | |||
@@ -361,6 +361,11 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, | |||
361 | protocol)); | 361 | protocol)); |
362 | break; | 362 | break; |
363 | case BPF_ANC | SKF_AD_IFINDEX: | 363 | case BPF_ANC | SKF_AD_IFINDEX: |
364 | case BPF_ANC | SKF_AD_HATYPE: | ||
365 | BUILD_BUG_ON(FIELD_SIZEOF(struct net_device, | ||
366 | ifindex) != 4); | ||
367 | BUILD_BUG_ON(FIELD_SIZEOF(struct net_device, | ||
368 | type) != 2); | ||
364 | PPC_LD_OFFS(r_scratch1, r_skb, offsetof(struct sk_buff, | 369 | PPC_LD_OFFS(r_scratch1, r_skb, offsetof(struct sk_buff, |
365 | dev)); | 370 | dev)); |
366 | PPC_CMPDI(r_scratch1, 0); | 371 | PPC_CMPDI(r_scratch1, 0); |
@@ -368,14 +373,18 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, | |||
368 | PPC_BCC(COND_EQ, addrs[ctx->pc_ret0]); | 373 | PPC_BCC(COND_EQ, addrs[ctx->pc_ret0]); |
369 | } else { | 374 | } else { |
370 | /* Exit, returning 0; first pass hits here. */ | 375 | /* Exit, returning 0; first pass hits here. */ |
371 | PPC_BCC_SHORT(COND_NE, (ctx->idx*4)+12); | 376 | PPC_BCC_SHORT(COND_NE, ctx->idx * 4 + 12); |
372 | PPC_LI(r_ret, 0); | 377 | PPC_LI(r_ret, 0); |
373 | PPC_JMP(exit_addr); | 378 | PPC_JMP(exit_addr); |
374 | } | 379 | } |
375 | BUILD_BUG_ON(FIELD_SIZEOF(struct net_device, | 380 | if (code == (BPF_ANC | SKF_AD_IFINDEX)) { |
376 | ifindex) != 4); | 381 | PPC_LWZ_OFFS(r_A, r_scratch1, |
377 | PPC_LWZ_OFFS(r_A, r_scratch1, | ||
378 | offsetof(struct net_device, ifindex)); | 382 | offsetof(struct net_device, ifindex)); |
383 | } else { | ||
384 | PPC_LHZ_OFFS(r_A, r_scratch1, | ||
385 | offsetof(struct net_device, type)); | ||
386 | } | ||
387 | |||
379 | break; | 388 | break; |
380 | case BPF_ANC | SKF_AD_MARK: | 389 | case BPF_ANC | SKF_AD_MARK: |
381 | BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, mark) != 4); | 390 | BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, mark) != 4); |