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>
This commit is contained in:
parent
ad2805dc79
commit
aa4c1037a3
|
@ -389,6 +389,21 @@ struct sock {
|
||||||
* Because of non atomicity rules, all
|
* Because of non atomicity rules, all
|
||||||
* changes are protected by socket lock.
|
* changes are protected by socket lock.
|
||||||
*/
|
*/
|
||||||
|
unsigned int __sk_flags_offset[0];
|
||||||
|
#ifdef __BIG_ENDIAN_BITFIELD
|
||||||
|
#define SK_FL_PROTO_SHIFT 16
|
||||||
|
#define SK_FL_PROTO_MASK 0x00ff0000
|
||||||
|
|
||||||
|
#define SK_FL_TYPE_SHIFT 0
|
||||||
|
#define SK_FL_TYPE_MASK 0x0000ffff
|
||||||
|
#else
|
||||||
|
#define SK_FL_PROTO_SHIFT 8
|
||||||
|
#define SK_FL_PROTO_MASK 0x0000ff00
|
||||||
|
|
||||||
|
#define SK_FL_TYPE_SHIFT 16
|
||||||
|
#define SK_FL_TYPE_MASK 0xffff0000
|
||||||
|
#endif
|
||||||
|
|
||||||
kmemcheck_bitfield_begin(flags);
|
kmemcheck_bitfield_begin(flags);
|
||||||
unsigned int sk_padding : 2,
|
unsigned int sk_padding : 2,
|
||||||
sk_no_check_tx : 1,
|
sk_no_check_tx : 1,
|
||||||
|
|
|
@ -571,6 +571,9 @@ enum bpf_ret_code {
|
||||||
|
|
||||||
struct bpf_sock {
|
struct bpf_sock {
|
||||||
__u32 bound_dev_if;
|
__u32 bound_dev_if;
|
||||||
|
__u32 family;
|
||||||
|
__u32 type;
|
||||||
|
__u32 protocol;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* User return codes for XDP prog type.
|
/* User return codes for XDP prog type.
|
||||||
|
|
|
@ -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,
|
*insn++ = BPF_LDX_MEM(BPF_W, dst_reg, src_reg,
|
||||||
offsetof(struct sock, sk_bound_dev_if));
|
offsetof(struct sock, sk_bound_dev_if));
|
||||||
break;
|
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;
|
return insn - insn_buf;
|
||||||
|
|
Loading…
Reference in New Issue