diff options
author | David Ahern <dsa@cumulusnetworks.com> | 2016-12-01 19:48:06 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-12-02 21:46:09 +0300 |
commit | aa4c1037a30f4e88f444e83d42c2befbe0d5caf5 (patch) | |
tree | e2bb34c401d93df49f035a1d45c01fdff44b371d /net/core | |
parent | ad2805dc79e647ec2aee931a51924fda9d03b2fc (diff) | |
download | linux-aa4c1037a30f4e88f444e83d42c2befbe0d5caf5.tar.xz |
bpf: Add support for reading socket family, type, protocol
Add socket family, type and protocol to bpf_sock allowing bpf programs
read-only access.
Add __sk_flags_offset[0] to struct sock before the bitfield to
programmtically determine the offset of the unsigned int containing
protocol and type.
Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/filter.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/net/core/filter.c b/net/core/filter.c index 0ab252e462aa..56b43587d200 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -3121,6 +3121,27 @@ static u32 sock_filter_convert_ctx_access(enum bpf_access_type type, *insn++ = BPF_LDX_MEM(BPF_W, dst_reg, src_reg, offsetof(struct sock, sk_bound_dev_if)); break; + + case offsetof(struct bpf_sock, family): + BUILD_BUG_ON(FIELD_SIZEOF(struct sock, sk_family) != 2); + + *insn++ = BPF_LDX_MEM(BPF_H, dst_reg, src_reg, + offsetof(struct sock, sk_family)); + break; + + case offsetof(struct bpf_sock, type): + *insn++ = BPF_LDX_MEM(BPF_W, dst_reg, src_reg, + offsetof(struct sock, __sk_flags_offset)); + *insn++ = BPF_ALU32_IMM(BPF_AND, dst_reg, SK_FL_TYPE_MASK); + *insn++ = BPF_ALU32_IMM(BPF_RSH, dst_reg, SK_FL_TYPE_SHIFT); + break; + + case offsetof(struct bpf_sock, protocol): + *insn++ = BPF_LDX_MEM(BPF_W, dst_reg, src_reg, + offsetof(struct sock, __sk_flags_offset)); + *insn++ = BPF_ALU32_IMM(BPF_AND, dst_reg, SK_FL_PROTO_MASK); + *insn++ = BPF_ALU32_IMM(BPF_RSH, dst_reg, SK_FL_PROTO_SHIFT); + break; } return insn - insn_buf; |