diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c index 8be702de34f98b44592fe2640d50cb5bf3ea9991..9af9a690dbda4fbf75a98b024253e416d4e2cc56 100644 --- a/arch/arm/net/bpf_jit_32.c +++ b/arch/arm/net/bpf_jit_32.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -168,6 +169,8 @@ static inline bool is_load_to_a(u16 inst) case BPF_S_ANC_MARK: case BPF_S_ANC_PROTOCOL: case BPF_S_ANC_RXHASH: + case BPF_S_ANC_VLAN_TAG: + case BPF_S_ANC_VLAN_TAG_PRESENT: case BPF_S_ANC_QUEUE: return true; default: @@ -815,6 +818,17 @@ static int build_body(struct jit_ctx *ctx) off = offsetof(struct sk_buff, rxhash); emit(ARM_LDR_I(r_A, r_skb, off), ctx); break; + case BPF_S_ANC_VLAN_TAG: + case BPF_S_ANC_VLAN_TAG_PRESENT: + ctx->seen |= SEEN_SKB; + BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, vlan_tci) != 2); + off = offsetof(struct sk_buff, vlan_tci); + emit(ARM_LDRH_I(r_A, r_skb, off), ctx); + if (inst->code == BPF_S_ANC_VLAN_TAG) + OP_IMM3(ARM_AND, r_A, r_A, VLAN_VID_MASK, ctx); + else + OP_IMM3(ARM_AND, r_A, r_A, VLAN_TAG_PRESENT, ctx); + break; case BPF_S_ANC_QUEUE: ctx->seen |= SEEN_SKB; BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff,