|
@@ -857,7 +857,9 @@ b_epilogue:
|
|
|
emit(ARM_LDR_I(r_A, r_scratch, off), ctx);
|
|
|
break;
|
|
|
case BPF_ANC | SKF_AD_IFINDEX:
|
|
|
+ case BPF_ANC | SKF_AD_HATYPE:
|
|
|
/* A = skb->dev->ifindex */
|
|
|
+ /* A = skb->dev->type */
|
|
|
ctx->seen |= SEEN_SKB;
|
|
|
off = offsetof(struct sk_buff, dev);
|
|
|
emit(ARM_LDR_I(r_scratch, r_skb, off), ctx);
|
|
@@ -867,8 +869,24 @@ b_epilogue:
|
|
|
|
|
|
BUILD_BUG_ON(FIELD_SIZEOF(struct net_device,
|
|
|
ifindex) != 4);
|
|
|
- off = offsetof(struct net_device, ifindex);
|
|
|
- emit(ARM_LDR_I(r_A, r_scratch, off), ctx);
|
|
|
+ BUILD_BUG_ON(FIELD_SIZEOF(struct net_device,
|
|
|
+ type) != 2);
|
|
|
+
|
|
|
+ if (code == (BPF_ANC | SKF_AD_IFINDEX)) {
|
|
|
+ off = offsetof(struct net_device, ifindex);
|
|
|
+ emit(ARM_LDR_I(r_A, r_scratch, off), ctx);
|
|
|
+ } else {
|
|
|
+ /*
|
|
|
+ * offset of field "type" in "struct
|
|
|
+ * net_device" is above what can be
|
|
|
+ * used in the ldrh rd, [rn, #imm]
|
|
|
+ * instruction, so load the offset in
|
|
|
+ * a register and use ldrh rd, [rn, rm]
|
|
|
+ */
|
|
|
+ off = offsetof(struct net_device, type);
|
|
|
+ emit_mov_i(ARM_R3, off, ctx);
|
|
|
+ emit(ARM_LDRH_R(r_A, r_scratch, ARM_R3), ctx);
|
|
|
+ }
|
|
|
break;
|
|
|
case BPF_ANC | SKF_AD_MARK:
|
|
|
ctx->seen |= SEEN_SKB;
|