bpf: export bpf_sock for BPF_PROG_TYPE_CGROUP_SOCK_ADDR prog type
authorStanislav Fomichev <sdf@google.com>
Wed, 12 Jun 2019 17:30:37 +0000 (10:30 -0700)
committerDaniel Borkmann <daniel@iogearbox.net>
Fri, 14 Jun 2019 23:21:56 +0000 (01:21 +0200)
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>
include/uapi/linux/bpf.h
net/core/filter.c

index ae0907d8c03ad0b9a53a50fa34ac85e1b8e4bcdc..8815fc418cdefd5a7289fe41d6ca42e37ade19f3 100644 (file)
@@ -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
index a5e4ac7fcbe5a1e23e080d76360fffcbf655caeb..37c4a2fd559b8f1686e86c58cba4697dd1fe4da3 100644 (file)
@@ -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;