18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci/* Multipath TCP 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Copyright (c) 2017 - 2019, Intel Corporation. 58c2ecf20Sopenharmony_ci */ 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#ifndef __MPTCP_PROTOCOL_H 88c2ecf20Sopenharmony_ci#define __MPTCP_PROTOCOL_H 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <linux/random.h> 118c2ecf20Sopenharmony_ci#include <net/tcp.h> 128c2ecf20Sopenharmony_ci#include <net/inet_connection_sock.h> 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci#define MPTCP_SUPPORTED_VERSION 1 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci/* MPTCP option bits */ 178c2ecf20Sopenharmony_ci#define OPTION_MPTCP_MPC_SYN BIT(0) 188c2ecf20Sopenharmony_ci#define OPTION_MPTCP_MPC_SYNACK BIT(1) 198c2ecf20Sopenharmony_ci#define OPTION_MPTCP_MPC_ACK BIT(2) 208c2ecf20Sopenharmony_ci#define OPTION_MPTCP_MPJ_SYN BIT(3) 218c2ecf20Sopenharmony_ci#define OPTION_MPTCP_MPJ_SYNACK BIT(4) 228c2ecf20Sopenharmony_ci#define OPTION_MPTCP_MPJ_ACK BIT(5) 238c2ecf20Sopenharmony_ci#define OPTION_MPTCP_ADD_ADDR BIT(6) 248c2ecf20Sopenharmony_ci#define OPTION_MPTCP_ADD_ADDR6 BIT(7) 258c2ecf20Sopenharmony_ci#define OPTION_MPTCP_RM_ADDR BIT(8) 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci/* MPTCP option subtypes */ 288c2ecf20Sopenharmony_ci#define MPTCPOPT_MP_CAPABLE 0 298c2ecf20Sopenharmony_ci#define MPTCPOPT_MP_JOIN 1 308c2ecf20Sopenharmony_ci#define MPTCPOPT_DSS 2 318c2ecf20Sopenharmony_ci#define MPTCPOPT_ADD_ADDR 3 328c2ecf20Sopenharmony_ci#define MPTCPOPT_RM_ADDR 4 338c2ecf20Sopenharmony_ci#define MPTCPOPT_MP_PRIO 5 348c2ecf20Sopenharmony_ci#define MPTCPOPT_MP_FAIL 6 358c2ecf20Sopenharmony_ci#define MPTCPOPT_MP_FASTCLOSE 7 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci/* MPTCP suboption lengths */ 388c2ecf20Sopenharmony_ci#define TCPOLEN_MPTCP_MPC_SYN 4 398c2ecf20Sopenharmony_ci#define TCPOLEN_MPTCP_MPC_SYNACK 12 408c2ecf20Sopenharmony_ci#define TCPOLEN_MPTCP_MPC_ACK 20 418c2ecf20Sopenharmony_ci#define TCPOLEN_MPTCP_MPC_ACK_DATA 22 428c2ecf20Sopenharmony_ci#define TCPOLEN_MPTCP_MPJ_SYN 12 438c2ecf20Sopenharmony_ci#define TCPOLEN_MPTCP_MPJ_SYNACK 16 448c2ecf20Sopenharmony_ci#define TCPOLEN_MPTCP_MPJ_ACK 24 458c2ecf20Sopenharmony_ci#define TCPOLEN_MPTCP_DSS_BASE 4 468c2ecf20Sopenharmony_ci#define TCPOLEN_MPTCP_DSS_ACK32 4 478c2ecf20Sopenharmony_ci#define TCPOLEN_MPTCP_DSS_ACK64 8 488c2ecf20Sopenharmony_ci#define TCPOLEN_MPTCP_DSS_MAP32 10 498c2ecf20Sopenharmony_ci#define TCPOLEN_MPTCP_DSS_MAP64 14 508c2ecf20Sopenharmony_ci#define TCPOLEN_MPTCP_DSS_CHECKSUM 2 518c2ecf20Sopenharmony_ci#define TCPOLEN_MPTCP_ADD_ADDR 16 528c2ecf20Sopenharmony_ci#define TCPOLEN_MPTCP_ADD_ADDR_PORT 18 538c2ecf20Sopenharmony_ci#define TCPOLEN_MPTCP_ADD_ADDR_BASE 8 548c2ecf20Sopenharmony_ci#define TCPOLEN_MPTCP_ADD_ADDR_BASE_PORT 10 558c2ecf20Sopenharmony_ci#define TCPOLEN_MPTCP_ADD_ADDR6 28 568c2ecf20Sopenharmony_ci#define TCPOLEN_MPTCP_ADD_ADDR6_PORT 30 578c2ecf20Sopenharmony_ci#define TCPOLEN_MPTCP_ADD_ADDR6_BASE 20 588c2ecf20Sopenharmony_ci#define TCPOLEN_MPTCP_ADD_ADDR6_BASE_PORT 22 598c2ecf20Sopenharmony_ci#define TCPOLEN_MPTCP_PORT_LEN 2 608c2ecf20Sopenharmony_ci#define TCPOLEN_MPTCP_RM_ADDR_BASE 4 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci/* MPTCP MP_JOIN flags */ 638c2ecf20Sopenharmony_ci#define MPTCPOPT_BACKUP BIT(0) 648c2ecf20Sopenharmony_ci#define MPTCPOPT_HMAC_LEN 20 658c2ecf20Sopenharmony_ci#define MPTCPOPT_THMAC_LEN 8 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci/* MPTCP MP_CAPABLE flags */ 688c2ecf20Sopenharmony_ci#define MPTCP_VERSION_MASK (0x0F) 698c2ecf20Sopenharmony_ci#define MPTCP_CAP_CHECKSUM_REQD BIT(7) 708c2ecf20Sopenharmony_ci#define MPTCP_CAP_EXTENSIBILITY BIT(6) 718c2ecf20Sopenharmony_ci#define MPTCP_CAP_HMAC_SHA256 BIT(0) 728c2ecf20Sopenharmony_ci#define MPTCP_CAP_FLAG_MASK (0x3F) 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci/* MPTCP DSS flags */ 758c2ecf20Sopenharmony_ci#define MPTCP_DSS_DATA_FIN BIT(4) 768c2ecf20Sopenharmony_ci#define MPTCP_DSS_DSN64 BIT(3) 778c2ecf20Sopenharmony_ci#define MPTCP_DSS_HAS_MAP BIT(2) 788c2ecf20Sopenharmony_ci#define MPTCP_DSS_ACK64 BIT(1) 798c2ecf20Sopenharmony_ci#define MPTCP_DSS_HAS_ACK BIT(0) 808c2ecf20Sopenharmony_ci#define MPTCP_DSS_FLAG_MASK (0x1F) 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci/* MPTCP ADD_ADDR flags */ 838c2ecf20Sopenharmony_ci#define MPTCP_ADDR_ECHO BIT(0) 848c2ecf20Sopenharmony_ci#define MPTCP_ADDR_IPVERSION_4 4 858c2ecf20Sopenharmony_ci#define MPTCP_ADDR_IPVERSION_6 6 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci/* MPTCP socket flags */ 888c2ecf20Sopenharmony_ci#define MPTCP_DATA_READY 0 898c2ecf20Sopenharmony_ci#define MPTCP_SEND_SPACE 1 908c2ecf20Sopenharmony_ci#define MPTCP_WORK_RTX 2 918c2ecf20Sopenharmony_ci#define MPTCP_WORK_EOF 3 928c2ecf20Sopenharmony_ci#define MPTCP_FALLBACK_DONE 4 938c2ecf20Sopenharmony_ci#define MPTCP_WORK_CLOSE_SUBFLOW 5 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_cistruct mptcp_options_received { 968c2ecf20Sopenharmony_ci u64 sndr_key; 978c2ecf20Sopenharmony_ci u64 rcvr_key; 988c2ecf20Sopenharmony_ci u64 data_ack; 998c2ecf20Sopenharmony_ci u64 data_seq; 1008c2ecf20Sopenharmony_ci u32 subflow_seq; 1018c2ecf20Sopenharmony_ci u16 data_len; 1028c2ecf20Sopenharmony_ci u16 mp_capable : 1, 1038c2ecf20Sopenharmony_ci mp_join : 1, 1048c2ecf20Sopenharmony_ci dss : 1, 1058c2ecf20Sopenharmony_ci add_addr : 1, 1068c2ecf20Sopenharmony_ci rm_addr : 1, 1078c2ecf20Sopenharmony_ci family : 4, 1088c2ecf20Sopenharmony_ci echo : 1, 1098c2ecf20Sopenharmony_ci backup : 1; 1108c2ecf20Sopenharmony_ci u32 token; 1118c2ecf20Sopenharmony_ci u32 nonce; 1128c2ecf20Sopenharmony_ci u64 thmac; 1138c2ecf20Sopenharmony_ci u8 hmac[20]; 1148c2ecf20Sopenharmony_ci u8 join_id; 1158c2ecf20Sopenharmony_ci u8 use_map:1, 1168c2ecf20Sopenharmony_ci dsn64:1, 1178c2ecf20Sopenharmony_ci data_fin:1, 1188c2ecf20Sopenharmony_ci use_ack:1, 1198c2ecf20Sopenharmony_ci ack64:1, 1208c2ecf20Sopenharmony_ci mpc_map:1, 1218c2ecf20Sopenharmony_ci __unused:2; 1228c2ecf20Sopenharmony_ci u8 addr_id; 1238c2ecf20Sopenharmony_ci u8 rm_id; 1248c2ecf20Sopenharmony_ci union { 1258c2ecf20Sopenharmony_ci struct in_addr addr; 1268c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_MPTCP_IPV6) 1278c2ecf20Sopenharmony_ci struct in6_addr addr6; 1288c2ecf20Sopenharmony_ci#endif 1298c2ecf20Sopenharmony_ci }; 1308c2ecf20Sopenharmony_ci u64 ahmac; 1318c2ecf20Sopenharmony_ci u16 port; 1328c2ecf20Sopenharmony_ci}; 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_cistatic inline __be32 mptcp_option(u8 subopt, u8 len, u8 nib, u8 field) 1358c2ecf20Sopenharmony_ci{ 1368c2ecf20Sopenharmony_ci return htonl((TCPOPT_MPTCP << 24) | (len << 16) | (subopt << 12) | 1378c2ecf20Sopenharmony_ci ((nib & 0xF) << 8) | field); 1388c2ecf20Sopenharmony_ci} 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_cistruct mptcp_addr_info { 1418c2ecf20Sopenharmony_ci sa_family_t family; 1428c2ecf20Sopenharmony_ci __be16 port; 1438c2ecf20Sopenharmony_ci u8 id; 1448c2ecf20Sopenharmony_ci u8 flags; 1458c2ecf20Sopenharmony_ci int ifindex; 1468c2ecf20Sopenharmony_ci union { 1478c2ecf20Sopenharmony_ci struct in_addr addr; 1488c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_MPTCP_IPV6) 1498c2ecf20Sopenharmony_ci struct in6_addr addr6; 1508c2ecf20Sopenharmony_ci#endif 1518c2ecf20Sopenharmony_ci }; 1528c2ecf20Sopenharmony_ci}; 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_cienum mptcp_pm_status { 1558c2ecf20Sopenharmony_ci MPTCP_PM_ADD_ADDR_RECEIVED, 1568c2ecf20Sopenharmony_ci MPTCP_PM_RM_ADDR_RECEIVED, 1578c2ecf20Sopenharmony_ci MPTCP_PM_ESTABLISHED, 1588c2ecf20Sopenharmony_ci MPTCP_PM_SUBFLOW_ESTABLISHED, 1598c2ecf20Sopenharmony_ci}; 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_cistruct mptcp_pm_data { 1628c2ecf20Sopenharmony_ci struct mptcp_addr_info local; 1638c2ecf20Sopenharmony_ci struct mptcp_addr_info remote; 1648c2ecf20Sopenharmony_ci struct list_head anno_list; 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci spinlock_t lock; /*protects the whole PM data */ 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_ci bool add_addr_signal; 1698c2ecf20Sopenharmony_ci bool rm_addr_signal; 1708c2ecf20Sopenharmony_ci bool server_side; 1718c2ecf20Sopenharmony_ci bool work_pending; 1728c2ecf20Sopenharmony_ci bool accept_addr; 1738c2ecf20Sopenharmony_ci bool accept_subflow; 1748c2ecf20Sopenharmony_ci bool add_addr_echo; 1758c2ecf20Sopenharmony_ci u8 add_addr_signaled; 1768c2ecf20Sopenharmony_ci u8 add_addr_accepted; 1778c2ecf20Sopenharmony_ci u8 local_addr_used; 1788c2ecf20Sopenharmony_ci u8 subflows; 1798c2ecf20Sopenharmony_ci u8 add_addr_signal_max; 1808c2ecf20Sopenharmony_ci u8 add_addr_accept_max; 1818c2ecf20Sopenharmony_ci u8 local_addr_max; 1828c2ecf20Sopenharmony_ci u8 subflows_max; 1838c2ecf20Sopenharmony_ci u8 status; 1848c2ecf20Sopenharmony_ci u8 rm_id; 1858c2ecf20Sopenharmony_ci}; 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_cistruct mptcp_data_frag { 1888c2ecf20Sopenharmony_ci struct list_head list; 1898c2ecf20Sopenharmony_ci u64 data_seq; 1908c2ecf20Sopenharmony_ci int data_len; 1918c2ecf20Sopenharmony_ci int offset; 1928c2ecf20Sopenharmony_ci int overhead; 1938c2ecf20Sopenharmony_ci struct page *page; 1948c2ecf20Sopenharmony_ci}; 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_ci/* MPTCP connection sock */ 1978c2ecf20Sopenharmony_cistruct mptcp_sock { 1988c2ecf20Sopenharmony_ci /* inet_connection_sock must be the first member */ 1998c2ecf20Sopenharmony_ci struct inet_connection_sock sk; 2008c2ecf20Sopenharmony_ci u64 local_key; 2018c2ecf20Sopenharmony_ci u64 remote_key; 2028c2ecf20Sopenharmony_ci u64 write_seq; 2038c2ecf20Sopenharmony_ci u64 ack_seq; 2048c2ecf20Sopenharmony_ci u64 rcv_data_fin_seq; 2058c2ecf20Sopenharmony_ci struct sock *last_snd; 2068c2ecf20Sopenharmony_ci int snd_burst; 2078c2ecf20Sopenharmony_ci atomic64_t snd_una; 2088c2ecf20Sopenharmony_ci unsigned long timer_ival; 2098c2ecf20Sopenharmony_ci u32 token; 2108c2ecf20Sopenharmony_ci unsigned long flags; 2118c2ecf20Sopenharmony_ci bool can_ack; 2128c2ecf20Sopenharmony_ci bool fully_established; 2138c2ecf20Sopenharmony_ci bool rcv_data_fin; 2148c2ecf20Sopenharmony_ci bool snd_data_fin_enable; 2158c2ecf20Sopenharmony_ci bool use_64bit_ack; /* Set when we received a 64-bit DSN */ 2168c2ecf20Sopenharmony_ci spinlock_t join_list_lock; 2178c2ecf20Sopenharmony_ci struct work_struct work; 2188c2ecf20Sopenharmony_ci struct sk_buff *ooo_last_skb; 2198c2ecf20Sopenharmony_ci struct rb_root out_of_order_queue; 2208c2ecf20Sopenharmony_ci struct list_head conn_list; 2218c2ecf20Sopenharmony_ci struct list_head rtx_queue; 2228c2ecf20Sopenharmony_ci struct list_head join_list; 2238c2ecf20Sopenharmony_ci struct skb_ext *cached_ext; /* for the next sendmsg */ 2248c2ecf20Sopenharmony_ci struct socket *subflow; /* outgoing connect/listener/!mp_capable */ 2258c2ecf20Sopenharmony_ci struct sock *first; 2268c2ecf20Sopenharmony_ci struct mptcp_pm_data pm; 2278c2ecf20Sopenharmony_ci struct { 2288c2ecf20Sopenharmony_ci u32 space; /* bytes copied in last measurement window */ 2298c2ecf20Sopenharmony_ci u32 copied; /* bytes copied in this measurement window */ 2308c2ecf20Sopenharmony_ci u64 time; /* start time of measurement window */ 2318c2ecf20Sopenharmony_ci u64 rtt_us; /* last maximum rtt of subflows */ 2328c2ecf20Sopenharmony_ci } rcvq_space; 2338c2ecf20Sopenharmony_ci}; 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ci#define mptcp_for_each_subflow(__msk, __subflow) \ 2368c2ecf20Sopenharmony_ci list_for_each_entry(__subflow, &((__msk)->conn_list), node) 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_cistatic inline struct mptcp_sock *mptcp_sk(const struct sock *sk) 2398c2ecf20Sopenharmony_ci{ 2408c2ecf20Sopenharmony_ci return (struct mptcp_sock *)sk; 2418c2ecf20Sopenharmony_ci} 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_cistatic inline struct mptcp_data_frag *mptcp_rtx_tail(const struct sock *sk) 2448c2ecf20Sopenharmony_ci{ 2458c2ecf20Sopenharmony_ci struct mptcp_sock *msk = mptcp_sk(sk); 2468c2ecf20Sopenharmony_ci 2478c2ecf20Sopenharmony_ci if (list_empty(&msk->rtx_queue)) 2488c2ecf20Sopenharmony_ci return NULL; 2498c2ecf20Sopenharmony_ci 2508c2ecf20Sopenharmony_ci return list_last_entry(&msk->rtx_queue, struct mptcp_data_frag, list); 2518c2ecf20Sopenharmony_ci} 2528c2ecf20Sopenharmony_ci 2538c2ecf20Sopenharmony_cistatic inline struct mptcp_data_frag *mptcp_rtx_head(const struct sock *sk) 2548c2ecf20Sopenharmony_ci{ 2558c2ecf20Sopenharmony_ci struct mptcp_sock *msk = mptcp_sk(sk); 2568c2ecf20Sopenharmony_ci 2578c2ecf20Sopenharmony_ci return list_first_entry_or_null(&msk->rtx_queue, struct mptcp_data_frag, list); 2588c2ecf20Sopenharmony_ci} 2598c2ecf20Sopenharmony_ci 2608c2ecf20Sopenharmony_cistruct mptcp_subflow_request_sock { 2618c2ecf20Sopenharmony_ci struct tcp_request_sock sk; 2628c2ecf20Sopenharmony_ci u16 mp_capable : 1, 2638c2ecf20Sopenharmony_ci mp_join : 1, 2648c2ecf20Sopenharmony_ci backup : 1; 2658c2ecf20Sopenharmony_ci u8 local_id; 2668c2ecf20Sopenharmony_ci u8 remote_id; 2678c2ecf20Sopenharmony_ci u64 local_key; 2688c2ecf20Sopenharmony_ci u64 idsn; 2698c2ecf20Sopenharmony_ci u32 token; 2708c2ecf20Sopenharmony_ci u32 ssn_offset; 2718c2ecf20Sopenharmony_ci u64 thmac; 2728c2ecf20Sopenharmony_ci u32 local_nonce; 2738c2ecf20Sopenharmony_ci u32 remote_nonce; 2748c2ecf20Sopenharmony_ci struct mptcp_sock *msk; 2758c2ecf20Sopenharmony_ci struct hlist_nulls_node token_node; 2768c2ecf20Sopenharmony_ci}; 2778c2ecf20Sopenharmony_ci 2788c2ecf20Sopenharmony_cistatic inline struct mptcp_subflow_request_sock * 2798c2ecf20Sopenharmony_cimptcp_subflow_rsk(const struct request_sock *rsk) 2808c2ecf20Sopenharmony_ci{ 2818c2ecf20Sopenharmony_ci return (struct mptcp_subflow_request_sock *)rsk; 2828c2ecf20Sopenharmony_ci} 2838c2ecf20Sopenharmony_ci 2848c2ecf20Sopenharmony_cienum mptcp_data_avail { 2858c2ecf20Sopenharmony_ci MPTCP_SUBFLOW_NODATA, 2868c2ecf20Sopenharmony_ci MPTCP_SUBFLOW_DATA_AVAIL, 2878c2ecf20Sopenharmony_ci MPTCP_SUBFLOW_OOO_DATA 2888c2ecf20Sopenharmony_ci}; 2898c2ecf20Sopenharmony_ci 2908c2ecf20Sopenharmony_ci/* MPTCP subflow context */ 2918c2ecf20Sopenharmony_cistruct mptcp_subflow_context { 2928c2ecf20Sopenharmony_ci struct list_head node;/* conn_list of subflows */ 2938c2ecf20Sopenharmony_ci u64 local_key; 2948c2ecf20Sopenharmony_ci u64 remote_key; 2958c2ecf20Sopenharmony_ci u64 idsn; 2968c2ecf20Sopenharmony_ci u64 map_seq; 2978c2ecf20Sopenharmony_ci u32 snd_isn; 2988c2ecf20Sopenharmony_ci u32 token; 2998c2ecf20Sopenharmony_ci u32 rel_write_seq; 3008c2ecf20Sopenharmony_ci u32 map_subflow_seq; 3018c2ecf20Sopenharmony_ci u32 ssn_offset; 3028c2ecf20Sopenharmony_ci u32 map_data_len; 3038c2ecf20Sopenharmony_ci u32 request_mptcp : 1, /* send MP_CAPABLE */ 3048c2ecf20Sopenharmony_ci request_join : 1, /* send MP_JOIN */ 3058c2ecf20Sopenharmony_ci request_bkup : 1, 3068c2ecf20Sopenharmony_ci mp_capable : 1, /* remote is MPTCP capable */ 3078c2ecf20Sopenharmony_ci mp_join : 1, /* remote is JOINing */ 3088c2ecf20Sopenharmony_ci fully_established : 1, /* path validated */ 3098c2ecf20Sopenharmony_ci pm_notified : 1, /* PM hook called for established status */ 3108c2ecf20Sopenharmony_ci conn_finished : 1, 3118c2ecf20Sopenharmony_ci map_valid : 1, 3128c2ecf20Sopenharmony_ci mpc_map : 1, 3138c2ecf20Sopenharmony_ci backup : 1, 3148c2ecf20Sopenharmony_ci rx_eof : 1, 3158c2ecf20Sopenharmony_ci can_ack : 1; /* only after processing the remote a key */ 3168c2ecf20Sopenharmony_ci enum mptcp_data_avail data_avail; 3178c2ecf20Sopenharmony_ci u32 remote_nonce; 3188c2ecf20Sopenharmony_ci u64 thmac; 3198c2ecf20Sopenharmony_ci u32 local_nonce; 3208c2ecf20Sopenharmony_ci u32 remote_token; 3218c2ecf20Sopenharmony_ci u8 hmac[MPTCPOPT_HMAC_LEN]; 3228c2ecf20Sopenharmony_ci u8 local_id; 3238c2ecf20Sopenharmony_ci u8 remote_id; 3248c2ecf20Sopenharmony_ci 3258c2ecf20Sopenharmony_ci struct sock *tcp_sock; /* tcp sk backpointer */ 3268c2ecf20Sopenharmony_ci struct sock *conn; /* parent mptcp_sock */ 3278c2ecf20Sopenharmony_ci const struct inet_connection_sock_af_ops *icsk_af_ops; 3288c2ecf20Sopenharmony_ci void (*tcp_data_ready)(struct sock *sk); 3298c2ecf20Sopenharmony_ci void (*tcp_state_change)(struct sock *sk); 3308c2ecf20Sopenharmony_ci void (*tcp_write_space)(struct sock *sk); 3318c2ecf20Sopenharmony_ci 3328c2ecf20Sopenharmony_ci struct rcu_head rcu; 3338c2ecf20Sopenharmony_ci}; 3348c2ecf20Sopenharmony_ci 3358c2ecf20Sopenharmony_cistatic inline struct mptcp_subflow_context * 3368c2ecf20Sopenharmony_cimptcp_subflow_ctx(const struct sock *sk) 3378c2ecf20Sopenharmony_ci{ 3388c2ecf20Sopenharmony_ci struct inet_connection_sock *icsk = inet_csk(sk); 3398c2ecf20Sopenharmony_ci 3408c2ecf20Sopenharmony_ci /* Use RCU on icsk_ulp_data only for sock diag code */ 3418c2ecf20Sopenharmony_ci return (__force struct mptcp_subflow_context *)icsk->icsk_ulp_data; 3428c2ecf20Sopenharmony_ci} 3438c2ecf20Sopenharmony_ci 3448c2ecf20Sopenharmony_cistatic inline struct sock * 3458c2ecf20Sopenharmony_cimptcp_subflow_tcp_sock(const struct mptcp_subflow_context *subflow) 3468c2ecf20Sopenharmony_ci{ 3478c2ecf20Sopenharmony_ci return subflow->tcp_sock; 3488c2ecf20Sopenharmony_ci} 3498c2ecf20Sopenharmony_ci 3508c2ecf20Sopenharmony_cistatic inline u64 3518c2ecf20Sopenharmony_cimptcp_subflow_get_map_offset(const struct mptcp_subflow_context *subflow) 3528c2ecf20Sopenharmony_ci{ 3538c2ecf20Sopenharmony_ci return tcp_sk(mptcp_subflow_tcp_sock(subflow))->copied_seq - 3548c2ecf20Sopenharmony_ci subflow->ssn_offset - 3558c2ecf20Sopenharmony_ci subflow->map_subflow_seq; 3568c2ecf20Sopenharmony_ci} 3578c2ecf20Sopenharmony_ci 3588c2ecf20Sopenharmony_cistatic inline u64 3598c2ecf20Sopenharmony_cimptcp_subflow_get_mapped_dsn(const struct mptcp_subflow_context *subflow) 3608c2ecf20Sopenharmony_ci{ 3618c2ecf20Sopenharmony_ci return subflow->map_seq + mptcp_subflow_get_map_offset(subflow); 3628c2ecf20Sopenharmony_ci} 3638c2ecf20Sopenharmony_ci 3648c2ecf20Sopenharmony_ciint mptcp_is_enabled(struct net *net); 3658c2ecf20Sopenharmony_civoid mptcp_subflow_fully_established(struct mptcp_subflow_context *subflow, 3668c2ecf20Sopenharmony_ci struct mptcp_options_received *mp_opt); 3678c2ecf20Sopenharmony_cibool mptcp_subflow_data_available(struct sock *sk); 3688c2ecf20Sopenharmony_civoid __init mptcp_subflow_init(void); 3698c2ecf20Sopenharmony_civoid mptcp_subflow_shutdown(struct sock *sk, struct sock *ssk, int how); 3708c2ecf20Sopenharmony_civoid __mptcp_close_ssk(struct sock *sk, struct sock *ssk, 3718c2ecf20Sopenharmony_ci struct mptcp_subflow_context *subflow, 3728c2ecf20Sopenharmony_ci long timeout); 3738c2ecf20Sopenharmony_civoid mptcp_subflow_reset(struct sock *ssk); 3748c2ecf20Sopenharmony_ci 3758c2ecf20Sopenharmony_ci/* called with sk socket lock held */ 3768c2ecf20Sopenharmony_ciint __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc, 3778c2ecf20Sopenharmony_ci const struct mptcp_addr_info *remote); 3788c2ecf20Sopenharmony_ciint mptcp_subflow_create_socket(struct sock *sk, struct socket **new_sock); 3798c2ecf20Sopenharmony_ci 3808c2ecf20Sopenharmony_cistatic inline void mptcp_subflow_tcp_fallback(struct sock *sk, 3818c2ecf20Sopenharmony_ci struct mptcp_subflow_context *ctx) 3828c2ecf20Sopenharmony_ci{ 3838c2ecf20Sopenharmony_ci sk->sk_data_ready = ctx->tcp_data_ready; 3848c2ecf20Sopenharmony_ci sk->sk_state_change = ctx->tcp_state_change; 3858c2ecf20Sopenharmony_ci sk->sk_write_space = ctx->tcp_write_space; 3868c2ecf20Sopenharmony_ci 3878c2ecf20Sopenharmony_ci inet_csk(sk)->icsk_af_ops = ctx->icsk_af_ops; 3888c2ecf20Sopenharmony_ci} 3898c2ecf20Sopenharmony_ci 3908c2ecf20Sopenharmony_civoid __init mptcp_proto_init(void); 3918c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_MPTCP_IPV6) 3928c2ecf20Sopenharmony_ciint __init mptcp_proto_v6_init(void); 3938c2ecf20Sopenharmony_ci#endif 3948c2ecf20Sopenharmony_ci 3958c2ecf20Sopenharmony_cistruct sock *mptcp_sk_clone(const struct sock *sk, 3968c2ecf20Sopenharmony_ci const struct mptcp_options_received *mp_opt, 3978c2ecf20Sopenharmony_ci struct request_sock *req); 3988c2ecf20Sopenharmony_civoid mptcp_get_options(const struct sk_buff *skb, 3998c2ecf20Sopenharmony_ci struct mptcp_options_received *mp_opt); 4008c2ecf20Sopenharmony_ci 4018c2ecf20Sopenharmony_civoid mptcp_finish_connect(struct sock *sk); 4028c2ecf20Sopenharmony_cistatic inline bool mptcp_is_fully_established(struct sock *sk) 4038c2ecf20Sopenharmony_ci{ 4048c2ecf20Sopenharmony_ci return inet_sk_state_load(sk) == TCP_ESTABLISHED && 4058c2ecf20Sopenharmony_ci READ_ONCE(mptcp_sk(sk)->fully_established); 4068c2ecf20Sopenharmony_ci} 4078c2ecf20Sopenharmony_civoid mptcp_rcv_space_init(struct mptcp_sock *msk, const struct sock *ssk); 4088c2ecf20Sopenharmony_civoid mptcp_data_ready(struct sock *sk, struct sock *ssk); 4098c2ecf20Sopenharmony_cibool mptcp_finish_join(struct sock *sk); 4108c2ecf20Sopenharmony_civoid mptcp_data_acked(struct sock *sk); 4118c2ecf20Sopenharmony_civoid mptcp_subflow_eof(struct sock *sk); 4128c2ecf20Sopenharmony_cibool mptcp_update_rcv_data_fin(struct mptcp_sock *msk, u64 data_fin_seq, bool use_64bit); 4138c2ecf20Sopenharmony_civoid mptcp_destroy_common(struct mptcp_sock *msk); 4148c2ecf20Sopenharmony_ci 4158c2ecf20Sopenharmony_civoid __init mptcp_token_init(void); 4168c2ecf20Sopenharmony_cistatic inline void mptcp_token_init_request(struct request_sock *req) 4178c2ecf20Sopenharmony_ci{ 4188c2ecf20Sopenharmony_ci mptcp_subflow_rsk(req)->token_node.pprev = NULL; 4198c2ecf20Sopenharmony_ci} 4208c2ecf20Sopenharmony_ci 4218c2ecf20Sopenharmony_ciint mptcp_token_new_request(struct request_sock *req); 4228c2ecf20Sopenharmony_civoid mptcp_token_destroy_request(struct request_sock *req); 4238c2ecf20Sopenharmony_ciint mptcp_token_new_connect(struct sock *sk); 4248c2ecf20Sopenharmony_civoid mptcp_token_accept(struct mptcp_subflow_request_sock *r, 4258c2ecf20Sopenharmony_ci struct mptcp_sock *msk); 4268c2ecf20Sopenharmony_cibool mptcp_token_exists(u32 token); 4278c2ecf20Sopenharmony_cistruct mptcp_sock *mptcp_token_get_sock(struct net *net, u32 token); 4288c2ecf20Sopenharmony_cistruct mptcp_sock *mptcp_token_iter_next(const struct net *net, long *s_slot, 4298c2ecf20Sopenharmony_ci long *s_num); 4308c2ecf20Sopenharmony_civoid mptcp_token_destroy(struct mptcp_sock *msk); 4318c2ecf20Sopenharmony_ci 4328c2ecf20Sopenharmony_civoid mptcp_crypto_key_sha(u64 key, u32 *token, u64 *idsn); 4338c2ecf20Sopenharmony_ci 4348c2ecf20Sopenharmony_civoid mptcp_crypto_hmac_sha(u64 key1, u64 key2, u8 *msg, int len, void *hmac); 4358c2ecf20Sopenharmony_ci 4368c2ecf20Sopenharmony_civoid __init mptcp_pm_init(void); 4378c2ecf20Sopenharmony_civoid mptcp_pm_data_init(struct mptcp_sock *msk); 4388c2ecf20Sopenharmony_civoid mptcp_pm_new_connection(struct mptcp_sock *msk, int server_side); 4398c2ecf20Sopenharmony_civoid mptcp_pm_fully_established(struct mptcp_sock *msk); 4408c2ecf20Sopenharmony_cibool mptcp_pm_allow_new_subflow(struct mptcp_sock *msk); 4418c2ecf20Sopenharmony_civoid mptcp_pm_connection_closed(struct mptcp_sock *msk); 4428c2ecf20Sopenharmony_civoid mptcp_pm_subflow_established(struct mptcp_sock *msk, 4438c2ecf20Sopenharmony_ci struct mptcp_subflow_context *subflow); 4448c2ecf20Sopenharmony_civoid mptcp_pm_subflow_closed(struct mptcp_sock *msk, u8 id); 4458c2ecf20Sopenharmony_civoid mptcp_pm_add_addr_received(struct mptcp_sock *msk, 4468c2ecf20Sopenharmony_ci const struct mptcp_addr_info *addr); 4478c2ecf20Sopenharmony_civoid mptcp_pm_rm_addr_received(struct mptcp_sock *msk, u8 rm_id); 4488c2ecf20Sopenharmony_civoid mptcp_pm_free_anno_list(struct mptcp_sock *msk); 4498c2ecf20Sopenharmony_cistruct mptcp_pm_add_entry * 4508c2ecf20Sopenharmony_cimptcp_pm_del_add_timer(struct mptcp_sock *msk, 4518c2ecf20Sopenharmony_ci struct mptcp_addr_info *addr); 4528c2ecf20Sopenharmony_ci 4538c2ecf20Sopenharmony_ciint mptcp_pm_announce_addr(struct mptcp_sock *msk, 4548c2ecf20Sopenharmony_ci const struct mptcp_addr_info *addr, 4558c2ecf20Sopenharmony_ci bool echo); 4568c2ecf20Sopenharmony_ciint mptcp_pm_remove_addr(struct mptcp_sock *msk, u8 local_id); 4578c2ecf20Sopenharmony_ciint mptcp_pm_remove_subflow(struct mptcp_sock *msk, u8 local_id); 4588c2ecf20Sopenharmony_ci 4598c2ecf20Sopenharmony_cistatic inline bool mptcp_pm_should_add_signal(struct mptcp_sock *msk) 4608c2ecf20Sopenharmony_ci{ 4618c2ecf20Sopenharmony_ci return READ_ONCE(msk->pm.add_addr_signal); 4628c2ecf20Sopenharmony_ci} 4638c2ecf20Sopenharmony_ci 4648c2ecf20Sopenharmony_cistatic inline bool mptcp_pm_should_rm_signal(struct mptcp_sock *msk) 4658c2ecf20Sopenharmony_ci{ 4668c2ecf20Sopenharmony_ci return READ_ONCE(msk->pm.rm_addr_signal); 4678c2ecf20Sopenharmony_ci} 4688c2ecf20Sopenharmony_ci 4698c2ecf20Sopenharmony_cistatic inline unsigned int mptcp_add_addr_len(int family, bool echo) 4708c2ecf20Sopenharmony_ci{ 4718c2ecf20Sopenharmony_ci if (family == AF_INET) 4728c2ecf20Sopenharmony_ci return echo ? TCPOLEN_MPTCP_ADD_ADDR_BASE 4738c2ecf20Sopenharmony_ci : TCPOLEN_MPTCP_ADD_ADDR; 4748c2ecf20Sopenharmony_ci return echo ? TCPOLEN_MPTCP_ADD_ADDR6_BASE : TCPOLEN_MPTCP_ADD_ADDR6; 4758c2ecf20Sopenharmony_ci} 4768c2ecf20Sopenharmony_ci 4778c2ecf20Sopenharmony_cibool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining, 4788c2ecf20Sopenharmony_ci struct mptcp_addr_info *saddr, bool *echo); 4798c2ecf20Sopenharmony_cibool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining, 4808c2ecf20Sopenharmony_ci u8 *rm_id); 4818c2ecf20Sopenharmony_ciint mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc); 4828c2ecf20Sopenharmony_ci 4838c2ecf20Sopenharmony_civoid __init mptcp_pm_nl_init(void); 4848c2ecf20Sopenharmony_civoid mptcp_pm_nl_data_init(struct mptcp_sock *msk); 4858c2ecf20Sopenharmony_civoid mptcp_pm_nl_fully_established(struct mptcp_sock *msk); 4868c2ecf20Sopenharmony_civoid mptcp_pm_nl_subflow_established(struct mptcp_sock *msk); 4878c2ecf20Sopenharmony_civoid mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk); 4888c2ecf20Sopenharmony_civoid mptcp_pm_nl_rm_addr_received(struct mptcp_sock *msk); 4898c2ecf20Sopenharmony_civoid mptcp_pm_nl_rm_subflow_received(struct mptcp_sock *msk, u8 rm_id); 4908c2ecf20Sopenharmony_ciint mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct sock_common *skc); 4918c2ecf20Sopenharmony_ci 4928c2ecf20Sopenharmony_cistatic inline struct mptcp_ext *mptcp_get_ext(struct sk_buff *skb) 4938c2ecf20Sopenharmony_ci{ 4948c2ecf20Sopenharmony_ci return (struct mptcp_ext *)skb_ext_find(skb, SKB_EXT_MPTCP); 4958c2ecf20Sopenharmony_ci} 4968c2ecf20Sopenharmony_ci 4978c2ecf20Sopenharmony_cistatic inline bool before64(__u64 seq1, __u64 seq2) 4988c2ecf20Sopenharmony_ci{ 4998c2ecf20Sopenharmony_ci return (__s64)(seq1 - seq2) < 0; 5008c2ecf20Sopenharmony_ci} 5018c2ecf20Sopenharmony_ci 5028c2ecf20Sopenharmony_ci#define after64(seq2, seq1) before64(seq1, seq2) 5038c2ecf20Sopenharmony_ci 5048c2ecf20Sopenharmony_civoid mptcp_diag_subflow_init(struct tcp_ulp_ops *ops); 5058c2ecf20Sopenharmony_ci 5068c2ecf20Sopenharmony_cistatic inline bool __mptcp_check_fallback(const struct mptcp_sock *msk) 5078c2ecf20Sopenharmony_ci{ 5088c2ecf20Sopenharmony_ci return test_bit(MPTCP_FALLBACK_DONE, &msk->flags); 5098c2ecf20Sopenharmony_ci} 5108c2ecf20Sopenharmony_ci 5118c2ecf20Sopenharmony_cistatic inline bool mptcp_check_fallback(const struct sock *sk) 5128c2ecf20Sopenharmony_ci{ 5138c2ecf20Sopenharmony_ci struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk); 5148c2ecf20Sopenharmony_ci struct mptcp_sock *msk = mptcp_sk(subflow->conn); 5158c2ecf20Sopenharmony_ci 5168c2ecf20Sopenharmony_ci return __mptcp_check_fallback(msk); 5178c2ecf20Sopenharmony_ci} 5188c2ecf20Sopenharmony_ci 5198c2ecf20Sopenharmony_cistatic inline void __mptcp_do_fallback(struct mptcp_sock *msk) 5208c2ecf20Sopenharmony_ci{ 5218c2ecf20Sopenharmony_ci if (test_bit(MPTCP_FALLBACK_DONE, &msk->flags)) { 5228c2ecf20Sopenharmony_ci pr_debug("TCP fallback already done (msk=%p)", msk); 5238c2ecf20Sopenharmony_ci return; 5248c2ecf20Sopenharmony_ci } 5258c2ecf20Sopenharmony_ci set_bit(MPTCP_FALLBACK_DONE, &msk->flags); 5268c2ecf20Sopenharmony_ci} 5278c2ecf20Sopenharmony_ci 5288c2ecf20Sopenharmony_cistatic inline void mptcp_do_fallback(struct sock *sk) 5298c2ecf20Sopenharmony_ci{ 5308c2ecf20Sopenharmony_ci struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk); 5318c2ecf20Sopenharmony_ci struct mptcp_sock *msk = mptcp_sk(subflow->conn); 5328c2ecf20Sopenharmony_ci 5338c2ecf20Sopenharmony_ci __mptcp_do_fallback(msk); 5348c2ecf20Sopenharmony_ci} 5358c2ecf20Sopenharmony_ci 5368c2ecf20Sopenharmony_ci#define pr_fallback(a) pr_debug("%s:fallback to TCP (msk=%p)", __func__, a) 5378c2ecf20Sopenharmony_ci 5388c2ecf20Sopenharmony_cistatic inline bool subflow_simultaneous_connect(struct sock *sk) 5398c2ecf20Sopenharmony_ci{ 5408c2ecf20Sopenharmony_ci struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk); 5418c2ecf20Sopenharmony_ci struct sock *parent = subflow->conn; 5428c2ecf20Sopenharmony_ci 5438c2ecf20Sopenharmony_ci return sk->sk_state == TCP_ESTABLISHED && 5448c2ecf20Sopenharmony_ci !mptcp_sk(parent)->pm.server_side && 5458c2ecf20Sopenharmony_ci !subflow->conn_finished; 5468c2ecf20Sopenharmony_ci} 5478c2ecf20Sopenharmony_ci 5488c2ecf20Sopenharmony_ci#ifdef CONFIG_SYN_COOKIES 5498c2ecf20Sopenharmony_civoid subflow_init_req_cookie_join_save(const struct mptcp_subflow_request_sock *subflow_req, 5508c2ecf20Sopenharmony_ci struct sk_buff *skb); 5518c2ecf20Sopenharmony_cibool mptcp_token_join_cookie_init_state(struct mptcp_subflow_request_sock *subflow_req, 5528c2ecf20Sopenharmony_ci struct sk_buff *skb); 5538c2ecf20Sopenharmony_civoid __init mptcp_join_cookie_init(void); 5548c2ecf20Sopenharmony_ci#else 5558c2ecf20Sopenharmony_cistatic inline void 5568c2ecf20Sopenharmony_cisubflow_init_req_cookie_join_save(const struct mptcp_subflow_request_sock *subflow_req, 5578c2ecf20Sopenharmony_ci struct sk_buff *skb) {} 5588c2ecf20Sopenharmony_cistatic inline bool 5598c2ecf20Sopenharmony_cimptcp_token_join_cookie_init_state(struct mptcp_subflow_request_sock *subflow_req, 5608c2ecf20Sopenharmony_ci struct sk_buff *skb) 5618c2ecf20Sopenharmony_ci{ 5628c2ecf20Sopenharmony_ci return false; 5638c2ecf20Sopenharmony_ci} 5648c2ecf20Sopenharmony_ci 5658c2ecf20Sopenharmony_cistatic inline void mptcp_join_cookie_init(void) {} 5668c2ecf20Sopenharmony_ci#endif 5678c2ecf20Sopenharmony_ci 5688c2ecf20Sopenharmony_ci#endif /* __MPTCP_PROTOCOL_H */ 569