diff options
author | Michal Sekletar <msekleta@redhat.com> | 2015-03-24 09:48:41 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-03-24 15:25:15 -0400 |
commit | 27cd5452476978283decb19e429e81fc6c71e74b (patch) | |
tree | a147d4576190e18580589e6faaf08e1b7050ef2d /net/core | |
parent | f6bb76cd4d8552bada1e454c291419f893e1af7b (diff) |
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: Michal Sekletar <msekleta@redhat.com>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@plumgrid.com>
Reviewed-by: Jiri Pirko <jiri@resnulli.us>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/filter.c | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/net/core/filter.c b/net/core/filter.c index 084eacc4d1d4..32f43c59908c 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
@@ -272,6 +272,16 @@ static bool convert_bpf_extensions(struct sock_filter *fp, | |||
272 | insn += cnt - 1; | 272 | insn += cnt - 1; |
273 | break; | 273 | break; |
274 | 274 | ||
275 | case SKF_AD_OFF + SKF_AD_VLAN_TPID: | ||
276 | BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, vlan_proto) != 2); | ||
277 | |||
278 | /* A = *(u16 *) (CTX + offsetof(vlan_proto)) */ | ||
279 | *insn++ = BPF_LDX_MEM(BPF_H, BPF_REG_A, BPF_REG_CTX, | ||
280 | offsetof(struct sk_buff, vlan_proto)); | ||
281 | /* A = ntohs(A) [emitting a nop or swap16] */ | ||
282 | *insn = BPF_ENDIAN(BPF_FROM_BE, BPF_REG_A, 16); | ||
283 | break; | ||
284 | |||
275 | case SKF_AD_OFF + SKF_AD_PAY_OFFSET: | 285 | case SKF_AD_OFF + SKF_AD_PAY_OFFSET: |
276 | case SKF_AD_OFF + SKF_AD_NLATTR: | 286 | case SKF_AD_OFF + SKF_AD_NLATTR: |
277 | case SKF_AD_OFF + SKF_AD_NLATTR_NEST: | 287 | 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, | |||
1226 | offsetof(struct sk_buff, protocol)); | 1236 | offsetof(struct sk_buff, protocol)); |
1227 | break; | 1237 | break; |
1228 | 1238 | ||
1239 | case offsetof(struct __sk_buff, vlan_proto): | ||
1240 | BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, vlan_proto) != 2); | ||
1241 | |||
1242 | *insn++ = BPF_LDX_MEM(BPF_H, dst_reg, src_reg, | ||
1243 | offsetof(struct sk_buff, vlan_proto)); | ||
1244 | break; | ||
1245 | |||
1229 | case offsetof(struct __sk_buff, mark): | 1246 | case offsetof(struct __sk_buff, mark): |
1230 | return convert_skb_access(SKF_AD_MARK, dst_reg, src_reg, insn); | 1247 | return convert_skb_access(SKF_AD_MARK, dst_reg, src_reg, insn); |
1231 | 1248 | ||