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