Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 27cd5452 authored by Michal Sekletar's avatar Michal Sekletar Committed by David S. Miller
Browse files

filter: introduce SKF_AD_VLAN_TPID BPF extension



If vlan offloading takes place then vlan header is removed from frame
and its contents, both vlan_tci and vlan_proto, is available to user
space via TPACKET interface. However, only vlan_tci can be used in BPF
filters.

This commit introduces a new BPF extension. It makes possible to load
the value of vlan_proto (vlan TPID) to register A. Support for classic
BPF and eBPF is being added, analogous to skb->protocol.

Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Alexei Starovoitov <ast@plumgrid.com>
Cc: Jiri Pirko <jpirko@redhat.com>

Signed-off-by: default avatarMichal Sekletar <msekleta@redhat.com>
Acked-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Acked-by: default avatarAlexei Starovoitov <ast@plumgrid.com>
Reviewed-by: default avatarJiri Pirko <jiri@resnulli.us>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f6bb76cd
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -280,7 +280,8 @@ Possible BPF extensions are shown in the following table:
  rxhash                                skb->hash
  cpu                                   raw_smp_processor_id()
  vlan_tci                              skb_vlan_tag_get(skb)
  vlan_pr                               skb_vlan_tag_present(skb)
  vlan_avail                            skb_vlan_tag_present(skb)
  vlan_tpid                             skb->vlan_proto
  rand                                  prandom_u32()

These extensions can also be prefixed with '#'.
+1 −0
Original line number Diff line number Diff line
@@ -454,6 +454,7 @@ static inline u16 bpf_anc_helper(const struct sock_filter *ftest)
		BPF_ANCILLARY(VLAN_TAG_PRESENT);
		BPF_ANCILLARY(PAY_OFFSET);
		BPF_ANCILLARY(RANDOM);
		BPF_ANCILLARY(VLAN_TPID);
		}
		/* Fallthrough. */
	default:
+1 −0
Original line number Diff line number Diff line
@@ -182,6 +182,7 @@ struct __sk_buff {
	__u32 protocol;
	__u32 vlan_present;
	__u32 vlan_tci;
	__u32 vlan_proto;
};

#endif /* _UAPI__LINUX_BPF_H__ */
+2 −1
Original line number Diff line number Diff line
@@ -77,7 +77,8 @@ struct sock_fprog { /* Required for SO_ATTACH_FILTER. */
#define SKF_AD_VLAN_TAG_PRESENT 48
#define SKF_AD_PAY_OFFSET	52
#define SKF_AD_RANDOM	56
#define SKF_AD_MAX	60
#define SKF_AD_VLAN_TPID	60
#define SKF_AD_MAX	64
#define SKF_NET_OFF   (-0x100000)
#define SKF_LL_OFF    (-0x200000)

+17 −0
Original line number Diff line number Diff line
@@ -272,6 +272,16 @@ static bool convert_bpf_extensions(struct sock_filter *fp,
		insn += cnt - 1;
		break;

	case SKF_AD_OFF + SKF_AD_VLAN_TPID:
		BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, vlan_proto) != 2);

		/* A = *(u16 *) (CTX + offsetof(vlan_proto)) */
		*insn++ = BPF_LDX_MEM(BPF_H, BPF_REG_A, BPF_REG_CTX,
				      offsetof(struct sk_buff, vlan_proto));
		/* A = ntohs(A) [emitting a nop or swap16] */
		*insn = BPF_ENDIAN(BPF_FROM_BE, BPF_REG_A, 16);
		break;

	case SKF_AD_OFF + SKF_AD_PAY_OFFSET:
	case SKF_AD_OFF + SKF_AD_NLATTR:
	case SKF_AD_OFF + SKF_AD_NLATTR_NEST:
@@ -1226,6 +1236,13 @@ static u32 sk_filter_convert_ctx_access(int dst_reg, int src_reg, int ctx_off,
				      offsetof(struct sk_buff, protocol));
		break;

	case offsetof(struct __sk_buff, vlan_proto):
		BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, vlan_proto) != 2);

		*insn++ = BPF_LDX_MEM(BPF_H, dst_reg, src_reg,
				      offsetof(struct sk_buff, vlan_proto));
		break;

	case offsetof(struct __sk_buff, mark):
		return convert_skb_access(SKF_AD_MARK, dst_reg, src_reg, insn);

Loading