Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

bpf: Add bpf_skc_to_mptcp_sock_proto

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

authored by

Geliang Tang and committed by
Andrii Nakryiko
3bc253c2 7aa424e0

+69 -1
+1
include/linux/bpf.h
··· 2231 2231 extern const struct bpf_func_proto bpf_skc_to_tcp_request_sock_proto; 2232 2232 extern const struct bpf_func_proto bpf_skc_to_udp6_sock_proto; 2233 2233 extern const struct bpf_func_proto bpf_skc_to_unix_sock_proto; 2234 + extern const struct bpf_func_proto bpf_skc_to_mptcp_sock_proto; 2234 2235 extern const struct bpf_func_proto bpf_copy_from_user_proto; 2235 2236 extern const struct bpf_func_proto bpf_snprintf_btf_proto; 2236 2237 extern const struct bpf_func_proto bpf_snprintf_proto;
+2 -1
include/linux/btf_ids.h
··· 178 178 BTF_SOCK_TYPE(BTF_SOCK_TYPE_TCP6, tcp6_sock) \ 179 179 BTF_SOCK_TYPE(BTF_SOCK_TYPE_UDP, udp_sock) \ 180 180 BTF_SOCK_TYPE(BTF_SOCK_TYPE_UDP6, udp6_sock) \ 181 - BTF_SOCK_TYPE(BTF_SOCK_TYPE_UNIX, unix_sock) 181 + BTF_SOCK_TYPE(BTF_SOCK_TYPE_UNIX, unix_sock) \ 182 + BTF_SOCK_TYPE(BTF_SOCK_TYPE_MPTCP, mptcp_sock) 182 183 183 184 enum { 184 185 #define BTF_SOCK_TYPE(name, str) name,
+6
include/net/mptcp.h
··· 284 284 static inline void mptcpv6_handle_mapped(struct sock *sk, bool mapped) { } 285 285 #endif 286 286 287 + #if defined(CONFIG_MPTCP) && defined(CONFIG_BPF_SYSCALL) 288 + struct mptcp_sock *bpf_mptcp_sock_from_subflow(struct sock *sk); 289 + #else 290 + static inline struct mptcp_sock *bpf_mptcp_sock_from_subflow(struct sock *sk) { return NULL; } 291 + #endif 292 + 287 293 #endif /* __NET_MPTCP_H */
+7
include/uapi/linux/bpf.h
··· 5172 5172 * Return 5173 5173 * Map value associated to *key* on *cpu*, or **NULL** if no entry 5174 5174 * was found or *cpu* is invalid. 5175 + * 5176 + * struct mptcp_sock *bpf_skc_to_mptcp_sock(void *sk) 5177 + * Description 5178 + * Dynamically cast a *sk* pointer to a *mptcp_sock* pointer. 5179 + * Return 5180 + * *sk* if casting is valid, or **NULL** otherwise. 5175 5181 */ 5176 5182 #define __BPF_FUNC_MAPPER(FN) \ 5177 5183 FN(unspec), \ ··· 5376 5370 FN(ima_file_hash), \ 5377 5371 FN(kptr_xchg), \ 5378 5372 FN(map_lookup_percpu_elem), \ 5373 + FN(skc_to_mptcp_sock), \ 5379 5374 /* */ 5380 5375 5381 5376 /* integer value in 'imm' field of BPF_CALL instruction selects which helper
+1
kernel/bpf/verifier.c
··· 509 509 func_id == BPF_FUNC_skc_to_tcp_sock || 510 510 func_id == BPF_FUNC_skc_to_tcp6_sock || 511 511 func_id == BPF_FUNC_skc_to_udp6_sock || 512 + func_id == BPF_FUNC_skc_to_mptcp_sock || 512 513 func_id == BPF_FUNC_skc_to_tcp_timewait_sock || 513 514 func_id == BPF_FUNC_skc_to_tcp_request_sock; 514 515 }
+2
kernel/trace/bpf_trace.c
··· 1705 1705 return &bpf_skc_to_udp6_sock_proto; 1706 1706 case BPF_FUNC_skc_to_unix_sock: 1707 1707 return &bpf_skc_to_unix_sock_proto; 1708 + case BPF_FUNC_skc_to_mptcp_sock: 1709 + return &bpf_skc_to_mptcp_sock_proto; 1708 1710 case BPF_FUNC_sk_storage_get: 1709 1711 return &bpf_sk_storage_get_tracing_proto; 1710 1712 case BPF_FUNC_sk_storage_delete:
+18
net/core/filter.c
··· 78 78 #include <linux/btf_ids.h> 79 79 #include <net/tls.h> 80 80 #include <net/xdp.h> 81 + #include <net/mptcp.h> 81 82 82 83 static const struct bpf_func_proto * 83 84 bpf_sk_base_func_proto(enum bpf_func_id func_id); ··· 11282 11281 .ret_btf_id = &btf_sock_ids[BTF_SOCK_TYPE_UNIX], 11283 11282 }; 11284 11283 11284 + BPF_CALL_1(bpf_skc_to_mptcp_sock, struct sock *, sk) 11285 + { 11286 + BTF_TYPE_EMIT(struct mptcp_sock); 11287 + return (unsigned long)bpf_mptcp_sock_from_subflow(sk); 11288 + } 11289 + 11290 + const struct bpf_func_proto bpf_skc_to_mptcp_sock_proto = { 11291 + .func = bpf_skc_to_mptcp_sock, 11292 + .gpl_only = false, 11293 + .ret_type = RET_PTR_TO_BTF_ID_OR_NULL, 11294 + .arg1_type = ARG_PTR_TO_SOCK_COMMON, 11295 + .ret_btf_id = &btf_sock_ids[BTF_SOCK_TYPE_MPTCP], 11296 + }; 11297 + 11285 11298 BPF_CALL_1(bpf_sock_from_file, struct file *, file) 11286 11299 { 11287 11300 return (unsigned long)sock_from_file(file); ··· 11337 11322 break; 11338 11323 case BPF_FUNC_skc_to_unix_sock: 11339 11324 func = &bpf_skc_to_unix_sock_proto; 11325 + break; 11326 + case BPF_FUNC_skc_to_mptcp_sock: 11327 + func = &bpf_skc_to_mptcp_sock_proto; 11340 11328 break; 11341 11329 case BPF_FUNC_ktime_get_coarse_ns: 11342 11330 return &bpf_ktime_get_coarse_ns_proto;
+2
net/mptcp/Makefile
··· 10 10 mptcp_crypto_test-objs := crypto_test.o 11 11 mptcp_token_test-objs := token_test.o 12 12 obj-$(CONFIG_MPTCP_KUNIT_TEST) += mptcp_crypto_test.o mptcp_token_test.o 13 + 14 + obj-$(CONFIG_BPF_SYSCALL) += bpf.o
+21
net/mptcp/bpf.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Multipath TCP 3 + * 4 + * Copyright (c) 2020, Tessares SA. 5 + * Copyright (c) 2022, SUSE. 6 + * 7 + * Author: Nicolas Rybowski <nicolas.rybowski@tessares.net> 8 + */ 9 + 10 + #define pr_fmt(fmt) "MPTCP: " fmt 11 + 12 + #include <linux/bpf.h> 13 + #include "protocol.h" 14 + 15 + struct mptcp_sock *bpf_mptcp_sock_from_subflow(struct sock *sk) 16 + { 17 + if (sk && sk_fullsock(sk) && sk->sk_protocol == IPPROTO_TCP && sk_is_mptcp(sk)) 18 + return mptcp_sk(mptcp_subflow_ctx(sk)->conn); 19 + 20 + return NULL; 21 + }
+2
scripts/bpf_doc.py
··· 633 633 'struct socket', 634 634 'struct file', 635 635 'struct bpf_timer', 636 + 'struct mptcp_sock', 636 637 ] 637 638 known_types = { 638 639 '...', ··· 683 682 'struct socket', 684 683 'struct file', 685 684 'struct bpf_timer', 685 + 'struct mptcp_sock', 686 686 } 687 687 mapped_types = { 688 688 'u8': '__u8',
+7
tools/include/uapi/linux/bpf.h
··· 5172 5172 * Return 5173 5173 * Map value associated to *key* on *cpu*, or **NULL** if no entry 5174 5174 * was found or *cpu* is invalid. 5175 + * 5176 + * struct mptcp_sock *bpf_skc_to_mptcp_sock(void *sk) 5177 + * Description 5178 + * Dynamically cast a *sk* pointer to a *mptcp_sock* pointer. 5179 + * Return 5180 + * *sk* if casting is valid, or **NULL** otherwise. 5175 5181 */ 5176 5182 #define __BPF_FUNC_MAPPER(FN) \ 5177 5183 FN(unspec), \ ··· 5376 5370 FN(ima_file_hash), \ 5377 5371 FN(kptr_xchg), \ 5378 5372 FN(map_lookup_percpu_elem), \ 5373 + FN(skc_to_mptcp_sock), \ 5379 5374 /* */ 5380 5375 5381 5376 /* integer value in 'imm' field of BPF_CALL instruction selects which helper