bpf: Add bpf_skc_to_unix_sock() helper
authorHengqi Chen <hengqi.chen@gmail.com>
Thu, 21 Oct 2021 13:47:51 +0000 (21:47 +0800)
committerAlexei Starovoitov <ast@kernel.org>
Thu, 21 Oct 2021 22:11:06 +0000 (15:11 -0700)
The helper is used in tracing programs to cast a socket
pointer to a unix_sock pointer.
The return value could be NULL if the casting is illegal.

Suggested-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Hengqi Chen <hengqi.chen@gmail.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: Song Liu <songliubraving@fb.com>
Link: https://lore.kernel.org/bpf/20211021134752.1223426-2-hengqi.chen@gmail.com
include/linux/bpf.h
include/uapi/linux/bpf.h
kernel/trace/bpf_trace.c
net/core/filter.c
scripts/bpf_doc.py
tools/include/uapi/linux/bpf.h

index d604c82..be3102b 100644 (file)
@@ -2093,6 +2093,7 @@ extern const struct bpf_func_proto bpf_skc_to_tcp_sock_proto;
 extern const struct bpf_func_proto bpf_skc_to_tcp_timewait_sock_proto;
 extern const struct bpf_func_proto bpf_skc_to_tcp_request_sock_proto;
 extern const struct bpf_func_proto bpf_skc_to_udp6_sock_proto;
+extern const struct bpf_func_proto bpf_skc_to_unix_sock_proto;
 extern const struct bpf_func_proto bpf_copy_from_user_proto;
 extern const struct bpf_func_proto bpf_snprintf_btf_proto;
 extern const struct bpf_func_proto bpf_snprintf_proto;
index 6fc59d6..22e7a3f 100644 (file)
@@ -4909,6 +4909,12 @@ union bpf_attr {
  *     Return
  *             The number of bytes written to the buffer, or a negative error
  *             in case of failure.
+ *
+ * struct unix_sock *bpf_skc_to_unix_sock(void *sk)
+ *     Description
+ *             Dynamically cast a *sk* pointer to a *unix_sock* pointer.
+ *     Return
+ *             *sk* if casting is valid, or **NULL** otherwise.
  */
 #define __BPF_FUNC_MAPPER(FN)          \
        FN(unspec),                     \
@@ -5089,6 +5095,7 @@ union bpf_attr {
        FN(task_pt_regs),               \
        FN(get_branch_snapshot),        \
        FN(trace_vprintk),              \
+       FN(skc_to_unix_sock),           \
        /* */
 
 /* integer value in 'imm' field of BPF_CALL instruction selects which helper
index 6b31538..cbcd0d6 100644 (file)
@@ -1608,6 +1608,8 @@ tracing_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
                return &bpf_skc_to_tcp_request_sock_proto;
        case BPF_FUNC_skc_to_udp6_sock:
                return &bpf_skc_to_udp6_sock_proto;
+       case BPF_FUNC_skc_to_unix_sock:
+               return &bpf_skc_to_unix_sock_proto;
        case BPF_FUNC_sk_storage_get:
                return &bpf_sk_storage_get_tracing_proto;
        case BPF_FUNC_sk_storage_delete:
index 4bace37..8e8d3b4 100644 (file)
@@ -10723,6 +10723,26 @@ const struct bpf_func_proto bpf_skc_to_udp6_sock_proto = {
        .ret_btf_id             = &btf_sock_ids[BTF_SOCK_TYPE_UDP6],
 };
 
+BPF_CALL_1(bpf_skc_to_unix_sock, struct sock *, sk)
+{
+       /* unix_sock type is not generated in dwarf and hence btf,
+        * trigger an explicit type generation here.
+        */
+       BTF_TYPE_EMIT(struct unix_sock);
+       if (sk && sk_fullsock(sk) && sk->sk_family == AF_UNIX)
+               return (unsigned long)sk;
+
+       return (unsigned long)NULL;
+}
+
+const struct bpf_func_proto bpf_skc_to_unix_sock_proto = {
+       .func                   = bpf_skc_to_unix_sock,
+       .gpl_only               = false,
+       .ret_type               = RET_PTR_TO_BTF_ID_OR_NULL,
+       .arg1_type              = ARG_PTR_TO_BTF_ID_SOCK_COMMON,
+       .ret_btf_id             = &btf_sock_ids[BTF_SOCK_TYPE_UNIX],
+};
+
 BPF_CALL_1(bpf_sock_from_file, struct file *, file)
 {
        return (unsigned long)sock_from_file(file);
@@ -10762,6 +10782,9 @@ bpf_sk_base_func_proto(enum bpf_func_id func_id)
        case BPF_FUNC_skc_to_udp6_sock:
                func = &bpf_skc_to_udp6_sock_proto;
                break;
+       case BPF_FUNC_skc_to_unix_sock:
+               func = &bpf_skc_to_unix_sock_proto;
+               break;
        default:
                return bpf_base_func_proto(func_id);
        }
index 00ac7b7..a6403dd 100755 (executable)
@@ -537,6 +537,7 @@ class PrinterHelpers(Printer):
             'struct tcp_timewait_sock',
             'struct tcp_request_sock',
             'struct udp6_sock',
+            'struct unix_sock',
             'struct task_struct',
 
             'struct __sk_buff',
@@ -589,6 +590,7 @@ class PrinterHelpers(Printer):
             'struct tcp_timewait_sock',
             'struct tcp_request_sock',
             'struct udp6_sock',
+            'struct unix_sock',
             'struct task_struct',
             'struct path',
             'struct btf_ptr',
index 6fc59d6..22e7a3f 100644 (file)
@@ -4909,6 +4909,12 @@ union bpf_attr {
  *     Return
  *             The number of bytes written to the buffer, or a negative error
  *             in case of failure.
+ *
+ * struct unix_sock *bpf_skc_to_unix_sock(void *sk)
+ *     Description
+ *             Dynamically cast a *sk* pointer to a *unix_sock* pointer.
+ *     Return
+ *             *sk* if casting is valid, or **NULL** otherwise.
  */
 #define __BPF_FUNC_MAPPER(FN)          \
        FN(unspec),                     \
@@ -5089,6 +5095,7 @@ union bpf_attr {
        FN(task_pt_regs),               \
        FN(get_branch_snapshot),        \
        FN(trace_vprintk),              \
+       FN(skc_to_unix_sock),           \
        /* */
 
 /* integer value in 'imm' field of BPF_CALL instruction selects which helper