diff options
author | Stanislav Fomichev <sdf@google.com> | 2019-06-12 10:30:37 -0700 |
---|---|---|
committer | Daniel Borkmann <daniel@iogearbox.net> | 2019-06-15 01:21:56 +0200 |
commit | fb85c4a730af221339c1dde1a434b73da0dfc3ed (patch) | |
tree | fce01722704a787ffdcfdeba1b5dc3d305359c84 | |
parent | d30bd78ce8ba1f093aa4877ed06601d0debd872b (diff) | |
download | linux-fb85c4a730af221339c1dde1a434b73da0dfc3ed.tar.gz linux-fb85c4a730af221339c1dde1a434b73da0dfc3ed.tar.bz2 linux-fb85c4a730af221339c1dde1a434b73da0dfc3ed.zip |
bpf: export bpf_sock for BPF_PROG_TYPE_CGROUP_SOCK_ADDR prog type
And let it use bpf_sk_storage_{get,delete} helpers to access socket
storage. Kernel context (struct bpf_sock_addr_kern) already has sk
member, so I just expose it to the BPF hooks. Using PTR_TO_SOCKET
instead of PTR_TO_SOCK_COMMON should be safe because the hook is
called on bind/connect.
Cc: Martin Lau <kafai@fb.com>
Signed-off-by: Stanislav Fomichev <sdf@google.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
-rw-r--r-- | include/uapi/linux/bpf.h | 1 | ||||
-rw-r--r-- | net/core/filter.c | 16 |
2 files changed, 17 insertions, 0 deletions
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index ae0907d8c03a..8815fc418cde 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -3247,6 +3247,7 @@ struct bpf_sock_addr { __u32 msg_src_ip6[4]; /* Allows 1,2,4-byte read an 4-byte write. * Stored in network byte order. */ + __bpf_md_ptr(struct bpf_sock *, sk); }; /* User bpf_sock_ops struct to access socket values and specify request ops diff --git a/net/core/filter.c b/net/core/filter.c index a5e4ac7fcbe5..37c4a2fd559b 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -5922,6 +5922,10 @@ sock_addr_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) case BPF_FUNC_skc_lookup_tcp: return &bpf_sock_addr_skc_lookup_tcp_proto; #endif /* CONFIG_INET */ + case BPF_FUNC_sk_storage_get: + return &bpf_sk_storage_get_proto; + case BPF_FUNC_sk_storage_delete: + return &bpf_sk_storage_delete_proto; default: return bpf_base_func_proto(func_id); } @@ -6828,6 +6832,13 @@ static bool sock_addr_is_valid_access(int off, int size, if (size != size_default) return false; break; + case offsetof(struct bpf_sock_addr, sk): + if (type != BPF_READ) + return false; + if (size != sizeof(__u64)) + return false; + info->reg_type = PTR_TO_SOCKET; + break; default: if (type == BPF_READ) { if (size != size_default) @@ -7778,6 +7789,11 @@ static u32 sock_addr_convert_ctx_access(enum bpf_access_type type, struct bpf_sock_addr_kern, struct in6_addr, t_ctx, s6_addr32[0], BPF_SIZE(si->code), off, tmp_reg); break; + case offsetof(struct bpf_sock_addr, sk): + *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct bpf_sock_addr_kern, sk), + si->dst_reg, si->src_reg, + offsetof(struct bpf_sock_addr_kern, sk)); + break; } return insn - insn_buf; |