bpf: Add bpf_skc_to_mptcp_sock_proto
authorGeliang Tang <geliang.tang@suse.com>
Thu, 19 May 2022 23:30:10 +0000 (16:30 -0700)
committerAndrii Nakryiko <andrii@kernel.org>
Fri, 20 May 2022 22:29:00 +0000 (15:29 -0700)
This patch implements a new struct bpf_func_proto, named
bpf_skc_to_mptcp_sock_proto. Define a new bpf_id BTF_SOCK_TYPE_MPTCP,
and a new helper bpf_skc_to_mptcp_sock(), which invokes another new
helper bpf_mptcp_sock_from_subflow() in net/mptcp/bpf.c to get struct
mptcp_sock from a given subflow socket.

v2: Emit BTF type, add func_id checks in verifier.c and bpf_trace.c,
remove build check for CONFIG_BPF_JIT
v5: Drop EXPORT_SYMBOL (Martin)

Co-developed-by: Nicolas Rybowski <nicolas.rybowski@tessares.net>
Co-developed-by: Matthieu Baerts <matthieu.baerts@tessares.net>
Signed-off-by: Nicolas Rybowski <nicolas.rybowski@tessares.net>
Signed-off-by: Matthieu Baerts <matthieu.baerts@tessares.net>
Signed-off-by: Geliang Tang <geliang.tang@suse.com>
Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20220519233016.105670-2-mathew.j.martineau@linux.intel.com
include/linux/bpf.h
include/linux/btf_ids.h
include/net/mptcp.h
include/uapi/linux/bpf.h
kernel/bpf/verifier.c
kernel/trace/bpf_trace.c
net/core/filter.c
net/mptcp/Makefile
net/mptcp/bpf.c [new file with mode: 0644]
scripts/bpf_doc.py
tools/include/uapi/linux/bpf.h

index c107392..a3ef078 100644 (file)
@@ -2231,6 +2231,7 @@ 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_skc_to_mptcp_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 bc5d9cc..335a190 100644 (file)
@@ -178,7 +178,8 @@ extern struct btf_id_set name;
        BTF_SOCK_TYPE(BTF_SOCK_TYPE_TCP6, tcp6_sock)                    \
        BTF_SOCK_TYPE(BTF_SOCK_TYPE_UDP, udp_sock)                      \
        BTF_SOCK_TYPE(BTF_SOCK_TYPE_UDP6, udp6_sock)                    \
-       BTF_SOCK_TYPE(BTF_SOCK_TYPE_UNIX, unix_sock)
+       BTF_SOCK_TYPE(BTF_SOCK_TYPE_UNIX, unix_sock)                    \
+       BTF_SOCK_TYPE(BTF_SOCK_TYPE_MPTCP, mptcp_sock)
 
 enum {
 #define BTF_SOCK_TYPE(name, str) name,
index 8b1afd6..2ba09de 100644 (file)
@@ -284,4 +284,10 @@ static inline int mptcpv6_init(void) { return 0; }
 static inline void mptcpv6_handle_mapped(struct sock *sk, bool mapped) { }
 #endif
 
+#if defined(CONFIG_MPTCP) && defined(CONFIG_BPF_SYSCALL)
+struct mptcp_sock *bpf_mptcp_sock_from_subflow(struct sock *sk);
+#else
+static inline struct mptcp_sock *bpf_mptcp_sock_from_subflow(struct sock *sk) { return NULL; }
+#endif
+
 #endif /* __NET_MPTCP_H */
index 0210f85..56688be 100644 (file)
@@ -5172,6 +5172,12 @@ union bpf_attr {
  *     Return
  *             Map value associated to *key* on *cpu*, or **NULL** if no entry
  *             was found or *cpu* is invalid.
+ *
+ * struct mptcp_sock *bpf_skc_to_mptcp_sock(void *sk)
+ *     Description
+ *             Dynamically cast a *sk* pointer to a *mptcp_sock* pointer.
+ *     Return
+ *             *sk* if casting is valid, or **NULL** otherwise.
  */
 #define __BPF_FUNC_MAPPER(FN)          \
        FN(unspec),                     \
@@ -5370,6 +5376,7 @@ union bpf_attr {
        FN(ima_file_hash),              \
        FN(kptr_xchg),                  \
        FN(map_lookup_percpu_elem),     \
+       FN(skc_to_mptcp_sock),          \
        /* */
 
 /* integer value in 'imm' field of BPF_CALL instruction selects which helper
index 9b59581..14e8c17 100644 (file)
@@ -509,6 +509,7 @@ static bool is_ptr_cast_function(enum bpf_func_id func_id)
                func_id == BPF_FUNC_skc_to_tcp_sock ||
                func_id == BPF_FUNC_skc_to_tcp6_sock ||
                func_id == BPF_FUNC_skc_to_udp6_sock ||
+               func_id == BPF_FUNC_skc_to_mptcp_sock ||
                func_id == BPF_FUNC_skc_to_tcp_timewait_sock ||
                func_id == BPF_FUNC_skc_to_tcp_request_sock;
 }
index 7141ca8..10b157a 100644 (file)
@@ -1705,6 +1705,8 @@ tracing_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
                return &bpf_skc_to_udp6_sock_proto;
        case BPF_FUNC_skc_to_unix_sock:
                return &bpf_skc_to_unix_sock_proto;
+       case BPF_FUNC_skc_to_mptcp_sock:
+               return &bpf_skc_to_mptcp_sock_proto;
        case BPF_FUNC_sk_storage_get:
                return &bpf_sk_storage_get_tracing_proto;
        case BPF_FUNC_sk_storage_delete:
index fe0da52..5af58eb 100644 (file)
@@ -78,6 +78,7 @@
 #include <linux/btf_ids.h>
 #include <net/tls.h>
 #include <net/xdp.h>
+#include <net/mptcp.h>
 
 static const struct bpf_func_proto *
 bpf_sk_base_func_proto(enum bpf_func_id func_id);
@@ -11281,6 +11282,20 @@ const struct bpf_func_proto bpf_skc_to_unix_sock_proto = {
        .ret_btf_id             = &btf_sock_ids[BTF_SOCK_TYPE_UNIX],
 };
 
+BPF_CALL_1(bpf_skc_to_mptcp_sock, struct sock *, sk)
+{
+       BTF_TYPE_EMIT(struct mptcp_sock);
+       return (unsigned long)bpf_mptcp_sock_from_subflow(sk);
+}
+
+const struct bpf_func_proto bpf_skc_to_mptcp_sock_proto = {
+       .func           = bpf_skc_to_mptcp_sock,
+       .gpl_only       = false,
+       .ret_type       = RET_PTR_TO_BTF_ID_OR_NULL,
+       .arg1_type      = ARG_PTR_TO_SOCK_COMMON,
+       .ret_btf_id     = &btf_sock_ids[BTF_SOCK_TYPE_MPTCP],
+};
+
 BPF_CALL_1(bpf_sock_from_file, struct file *, file)
 {
        return (unsigned long)sock_from_file(file);
@@ -11323,6 +11338,9 @@ bpf_sk_base_func_proto(enum bpf_func_id func_id)
        case BPF_FUNC_skc_to_unix_sock:
                func = &bpf_skc_to_unix_sock_proto;
                break;
+       case BPF_FUNC_skc_to_mptcp_sock:
+               func = &bpf_skc_to_mptcp_sock_proto;
+               break;
        case BPF_FUNC_ktime_get_coarse_ns:
                return &bpf_ktime_get_coarse_ns_proto;
        default:
index e54dace..99dddf0 100644 (file)
@@ -10,3 +10,5 @@ obj-$(CONFIG_INET_MPTCP_DIAG) += mptcp_diag.o
 mptcp_crypto_test-objs := crypto_test.o
 mptcp_token_test-objs := token_test.o
 obj-$(CONFIG_MPTCP_KUNIT_TEST) += mptcp_crypto_test.o mptcp_token_test.o
+
+obj-$(CONFIG_BPF_SYSCALL) += bpf.o
diff --git a/net/mptcp/bpf.c b/net/mptcp/bpf.c
new file mode 100644 (file)
index 0000000..5a0a84a
--- /dev/null
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Multipath TCP
+ *
+ * Copyright (c) 2020, Tessares SA.
+ * Copyright (c) 2022, SUSE.
+ *
+ * Author: Nicolas Rybowski <nicolas.rybowski@tessares.net>
+ */
+
+#define pr_fmt(fmt) "MPTCP: " fmt
+
+#include <linux/bpf.h>
+#include "protocol.h"
+
+struct mptcp_sock *bpf_mptcp_sock_from_subflow(struct sock *sk)
+{
+       if (sk && sk_fullsock(sk) && sk->sk_protocol == IPPROTO_TCP && sk_is_mptcp(sk))
+               return mptcp_sk(mptcp_subflow_ctx(sk)->conn);
+
+       return NULL;
+}
index 0966252..d5452f7 100755 (executable)
@@ -633,6 +633,7 @@ class PrinterHelpers(Printer):
             'struct socket',
             'struct file',
             'struct bpf_timer',
+            'struct mptcp_sock',
     ]
     known_types = {
             '...',
@@ -682,6 +683,7 @@ class PrinterHelpers(Printer):
             'struct socket',
             'struct file',
             'struct bpf_timer',
+            'struct mptcp_sock',
     }
     mapped_types = {
             'u8': '__u8',
index 0210f85..56688be 100644 (file)
@@ -5172,6 +5172,12 @@ union bpf_attr {
  *     Return
  *             Map value associated to *key* on *cpu*, or **NULL** if no entry
  *             was found or *cpu* is invalid.
+ *
+ * struct mptcp_sock *bpf_skc_to_mptcp_sock(void *sk)
+ *     Description
+ *             Dynamically cast a *sk* pointer to a *mptcp_sock* pointer.
+ *     Return
+ *             *sk* if casting is valid, or **NULL** otherwise.
  */
 #define __BPF_FUNC_MAPPER(FN)          \
        FN(unspec),                     \
@@ -5370,6 +5376,7 @@ union bpf_attr {
        FN(ima_file_hash),              \
        FN(kptr_xchg),                  \
        FN(map_lookup_percpu_elem),     \
+       FN(skc_to_mptcp_sock),          \
        /* */
 
 /* integer value in 'imm' field of BPF_CALL instruction selects which helper