162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/* Multipath TCP
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * Copyright (c) 2017 - 2019, Intel Corporation.
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#ifndef __MPTCP_PROTOCOL_H
862306a36Sopenharmony_ci#define __MPTCP_PROTOCOL_H
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include <linux/random.h>
1162306a36Sopenharmony_ci#include <net/tcp.h>
1262306a36Sopenharmony_ci#include <net/inet_connection_sock.h>
1362306a36Sopenharmony_ci#include <uapi/linux/mptcp.h>
1462306a36Sopenharmony_ci#include <net/genetlink.h>
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci#define MPTCP_SUPPORTED_VERSION	1
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci/* MPTCP option bits */
1962306a36Sopenharmony_ci#define OPTION_MPTCP_MPC_SYN	BIT(0)
2062306a36Sopenharmony_ci#define OPTION_MPTCP_MPC_SYNACK	BIT(1)
2162306a36Sopenharmony_ci#define OPTION_MPTCP_MPC_ACK	BIT(2)
2262306a36Sopenharmony_ci#define OPTION_MPTCP_MPJ_SYN	BIT(3)
2362306a36Sopenharmony_ci#define OPTION_MPTCP_MPJ_SYNACK	BIT(4)
2462306a36Sopenharmony_ci#define OPTION_MPTCP_MPJ_ACK	BIT(5)
2562306a36Sopenharmony_ci#define OPTION_MPTCP_ADD_ADDR	BIT(6)
2662306a36Sopenharmony_ci#define OPTION_MPTCP_RM_ADDR	BIT(7)
2762306a36Sopenharmony_ci#define OPTION_MPTCP_FASTCLOSE	BIT(8)
2862306a36Sopenharmony_ci#define OPTION_MPTCP_PRIO	BIT(9)
2962306a36Sopenharmony_ci#define OPTION_MPTCP_RST	BIT(10)
3062306a36Sopenharmony_ci#define OPTION_MPTCP_DSS	BIT(11)
3162306a36Sopenharmony_ci#define OPTION_MPTCP_FAIL	BIT(12)
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci#define OPTION_MPTCP_CSUMREQD	BIT(13)
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci#define OPTIONS_MPTCP_MPC	(OPTION_MPTCP_MPC_SYN | OPTION_MPTCP_MPC_SYNACK | \
3662306a36Sopenharmony_ci				 OPTION_MPTCP_MPC_ACK)
3762306a36Sopenharmony_ci#define OPTIONS_MPTCP_MPJ	(OPTION_MPTCP_MPJ_SYN | OPTION_MPTCP_MPJ_SYNACK | \
3862306a36Sopenharmony_ci				 OPTION_MPTCP_MPJ_ACK)
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci/* MPTCP option subtypes */
4162306a36Sopenharmony_ci#define MPTCPOPT_MP_CAPABLE	0
4262306a36Sopenharmony_ci#define MPTCPOPT_MP_JOIN	1
4362306a36Sopenharmony_ci#define MPTCPOPT_DSS		2
4462306a36Sopenharmony_ci#define MPTCPOPT_ADD_ADDR	3
4562306a36Sopenharmony_ci#define MPTCPOPT_RM_ADDR	4
4662306a36Sopenharmony_ci#define MPTCPOPT_MP_PRIO	5
4762306a36Sopenharmony_ci#define MPTCPOPT_MP_FAIL	6
4862306a36Sopenharmony_ci#define MPTCPOPT_MP_FASTCLOSE	7
4962306a36Sopenharmony_ci#define MPTCPOPT_RST		8
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci/* MPTCP suboption lengths */
5262306a36Sopenharmony_ci#define TCPOLEN_MPTCP_MPC_SYN		4
5362306a36Sopenharmony_ci#define TCPOLEN_MPTCP_MPC_SYNACK	12
5462306a36Sopenharmony_ci#define TCPOLEN_MPTCP_MPC_ACK		20
5562306a36Sopenharmony_ci#define TCPOLEN_MPTCP_MPC_ACK_DATA	22
5662306a36Sopenharmony_ci#define TCPOLEN_MPTCP_MPJ_SYN		12
5762306a36Sopenharmony_ci#define TCPOLEN_MPTCP_MPJ_SYNACK	16
5862306a36Sopenharmony_ci#define TCPOLEN_MPTCP_MPJ_ACK		24
5962306a36Sopenharmony_ci#define TCPOLEN_MPTCP_DSS_BASE		4
6062306a36Sopenharmony_ci#define TCPOLEN_MPTCP_DSS_ACK32		4
6162306a36Sopenharmony_ci#define TCPOLEN_MPTCP_DSS_ACK64		8
6262306a36Sopenharmony_ci#define TCPOLEN_MPTCP_DSS_MAP32		10
6362306a36Sopenharmony_ci#define TCPOLEN_MPTCP_DSS_MAP64		14
6462306a36Sopenharmony_ci#define TCPOLEN_MPTCP_DSS_CHECKSUM	2
6562306a36Sopenharmony_ci#define TCPOLEN_MPTCP_ADD_ADDR		16
6662306a36Sopenharmony_ci#define TCPOLEN_MPTCP_ADD_ADDR_PORT	18
6762306a36Sopenharmony_ci#define TCPOLEN_MPTCP_ADD_ADDR_BASE	8
6862306a36Sopenharmony_ci#define TCPOLEN_MPTCP_ADD_ADDR_BASE_PORT	10
6962306a36Sopenharmony_ci#define TCPOLEN_MPTCP_ADD_ADDR6		28
7062306a36Sopenharmony_ci#define TCPOLEN_MPTCP_ADD_ADDR6_PORT	30
7162306a36Sopenharmony_ci#define TCPOLEN_MPTCP_ADD_ADDR6_BASE	20
7262306a36Sopenharmony_ci#define TCPOLEN_MPTCP_ADD_ADDR6_BASE_PORT	22
7362306a36Sopenharmony_ci#define TCPOLEN_MPTCP_PORT_LEN		2
7462306a36Sopenharmony_ci#define TCPOLEN_MPTCP_PORT_ALIGN	2
7562306a36Sopenharmony_ci#define TCPOLEN_MPTCP_RM_ADDR_BASE	3
7662306a36Sopenharmony_ci#define TCPOLEN_MPTCP_PRIO		3
7762306a36Sopenharmony_ci#define TCPOLEN_MPTCP_PRIO_ALIGN	4
7862306a36Sopenharmony_ci#define TCPOLEN_MPTCP_FASTCLOSE		12
7962306a36Sopenharmony_ci#define TCPOLEN_MPTCP_RST		4
8062306a36Sopenharmony_ci#define TCPOLEN_MPTCP_FAIL		12
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ci#define TCPOLEN_MPTCP_MPC_ACK_DATA_CSUM	(TCPOLEN_MPTCP_DSS_CHECKSUM + TCPOLEN_MPTCP_MPC_ACK_DATA)
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci/* MPTCP MP_JOIN flags */
8562306a36Sopenharmony_ci#define MPTCPOPT_BACKUP		BIT(0)
8662306a36Sopenharmony_ci#define MPTCPOPT_THMAC_LEN	8
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci/* MPTCP MP_CAPABLE flags */
8962306a36Sopenharmony_ci#define MPTCP_VERSION_MASK	(0x0F)
9062306a36Sopenharmony_ci#define MPTCP_CAP_CHECKSUM_REQD	BIT(7)
9162306a36Sopenharmony_ci#define MPTCP_CAP_EXTENSIBILITY	BIT(6)
9262306a36Sopenharmony_ci#define MPTCP_CAP_DENY_JOIN_ID0	BIT(5)
9362306a36Sopenharmony_ci#define MPTCP_CAP_HMAC_SHA256	BIT(0)
9462306a36Sopenharmony_ci#define MPTCP_CAP_FLAG_MASK	(0x1F)
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci/* MPTCP DSS flags */
9762306a36Sopenharmony_ci#define MPTCP_DSS_DATA_FIN	BIT(4)
9862306a36Sopenharmony_ci#define MPTCP_DSS_DSN64		BIT(3)
9962306a36Sopenharmony_ci#define MPTCP_DSS_HAS_MAP	BIT(2)
10062306a36Sopenharmony_ci#define MPTCP_DSS_ACK64		BIT(1)
10162306a36Sopenharmony_ci#define MPTCP_DSS_HAS_ACK	BIT(0)
10262306a36Sopenharmony_ci#define MPTCP_DSS_FLAG_MASK	(0x1F)
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci/* MPTCP ADD_ADDR flags */
10562306a36Sopenharmony_ci#define MPTCP_ADDR_ECHO		BIT(0)
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci/* MPTCP MP_PRIO flags */
10862306a36Sopenharmony_ci#define MPTCP_PRIO_BKUP		BIT(0)
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci/* MPTCP TCPRST flags */
11162306a36Sopenharmony_ci#define MPTCP_RST_TRANSIENT	BIT(0)
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci/* MPTCP socket atomic flags */
11462306a36Sopenharmony_ci#define MPTCP_NOSPACE		1
11562306a36Sopenharmony_ci#define MPTCP_WORK_RTX		2
11662306a36Sopenharmony_ci#define MPTCP_FALLBACK_DONE	4
11762306a36Sopenharmony_ci#define MPTCP_WORK_CLOSE_SUBFLOW 5
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci/* MPTCP socket release cb flags */
12062306a36Sopenharmony_ci#define MPTCP_PUSH_PENDING	1
12162306a36Sopenharmony_ci#define MPTCP_CLEAN_UNA		2
12262306a36Sopenharmony_ci#define MPTCP_ERROR_REPORT	3
12362306a36Sopenharmony_ci#define MPTCP_RETRANSMIT	4
12462306a36Sopenharmony_ci#define MPTCP_FLUSH_JOIN_LIST	5
12562306a36Sopenharmony_ci#define MPTCP_SYNC_STATE	6
12662306a36Sopenharmony_ci#define MPTCP_SYNC_SNDBUF	7
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_cistruct mptcp_skb_cb {
12962306a36Sopenharmony_ci	u64 map_seq;
13062306a36Sopenharmony_ci	u64 end_seq;
13162306a36Sopenharmony_ci	u32 offset;
13262306a36Sopenharmony_ci	u8  has_rxtstamp:1;
13362306a36Sopenharmony_ci};
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ci#define MPTCP_SKB_CB(__skb)	((struct mptcp_skb_cb *)&((__skb)->cb[0]))
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_cistatic inline bool before64(__u64 seq1, __u64 seq2)
13862306a36Sopenharmony_ci{
13962306a36Sopenharmony_ci	return (__s64)(seq1 - seq2) < 0;
14062306a36Sopenharmony_ci}
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci#define after64(seq2, seq1)	before64(seq1, seq2)
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_cistruct mptcp_options_received {
14562306a36Sopenharmony_ci	u64	sndr_key;
14662306a36Sopenharmony_ci	u64	rcvr_key;
14762306a36Sopenharmony_ci	u64	data_ack;
14862306a36Sopenharmony_ci	u64	data_seq;
14962306a36Sopenharmony_ci	u32	subflow_seq;
15062306a36Sopenharmony_ci	u16	data_len;
15162306a36Sopenharmony_ci	__sum16	csum;
15262306a36Sopenharmony_ci	u16	suboptions;
15362306a36Sopenharmony_ci	u32	token;
15462306a36Sopenharmony_ci	u32	nonce;
15562306a36Sopenharmony_ci	u16	use_map:1,
15662306a36Sopenharmony_ci		dsn64:1,
15762306a36Sopenharmony_ci		data_fin:1,
15862306a36Sopenharmony_ci		use_ack:1,
15962306a36Sopenharmony_ci		ack64:1,
16062306a36Sopenharmony_ci		mpc_map:1,
16162306a36Sopenharmony_ci		reset_reason:4,
16262306a36Sopenharmony_ci		reset_transient:1,
16362306a36Sopenharmony_ci		echo:1,
16462306a36Sopenharmony_ci		backup:1,
16562306a36Sopenharmony_ci		deny_join_id0:1,
16662306a36Sopenharmony_ci		__unused:2;
16762306a36Sopenharmony_ci	u8	join_id;
16862306a36Sopenharmony_ci	u64	thmac;
16962306a36Sopenharmony_ci	u8	hmac[MPTCPOPT_HMAC_LEN];
17062306a36Sopenharmony_ci	struct mptcp_addr_info addr;
17162306a36Sopenharmony_ci	struct mptcp_rm_list rm_list;
17262306a36Sopenharmony_ci	u64	ahmac;
17362306a36Sopenharmony_ci	u64	fail_seq;
17462306a36Sopenharmony_ci};
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_cistatic inline __be32 mptcp_option(u8 subopt, u8 len, u8 nib, u8 field)
17762306a36Sopenharmony_ci{
17862306a36Sopenharmony_ci	return htonl((TCPOPT_MPTCP << 24) | (len << 16) | (subopt << 12) |
17962306a36Sopenharmony_ci		     ((nib & 0xF) << 8) | field);
18062306a36Sopenharmony_ci}
18162306a36Sopenharmony_ci
18262306a36Sopenharmony_cienum mptcp_pm_status {
18362306a36Sopenharmony_ci	MPTCP_PM_ADD_ADDR_RECEIVED,
18462306a36Sopenharmony_ci	MPTCP_PM_ADD_ADDR_SEND_ACK,
18562306a36Sopenharmony_ci	MPTCP_PM_RM_ADDR_RECEIVED,
18662306a36Sopenharmony_ci	MPTCP_PM_ESTABLISHED,
18762306a36Sopenharmony_ci	MPTCP_PM_SUBFLOW_ESTABLISHED,
18862306a36Sopenharmony_ci	MPTCP_PM_ALREADY_ESTABLISHED,	/* persistent status, set after ESTABLISHED event */
18962306a36Sopenharmony_ci	MPTCP_PM_MPC_ENDPOINT_ACCOUNTED /* persistent status, set after MPC local address is
19062306a36Sopenharmony_ci					 * accounted int id_avail_bitmap
19162306a36Sopenharmony_ci					 */
19262306a36Sopenharmony_ci};
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_cienum mptcp_pm_type {
19562306a36Sopenharmony_ci	MPTCP_PM_TYPE_KERNEL = 0,
19662306a36Sopenharmony_ci	MPTCP_PM_TYPE_USERSPACE,
19762306a36Sopenharmony_ci
19862306a36Sopenharmony_ci	__MPTCP_PM_TYPE_NR,
19962306a36Sopenharmony_ci	__MPTCP_PM_TYPE_MAX = __MPTCP_PM_TYPE_NR - 1,
20062306a36Sopenharmony_ci};
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_ci/* Status bits below MPTCP_PM_ALREADY_ESTABLISHED need pm worker actions */
20362306a36Sopenharmony_ci#define MPTCP_PM_WORK_MASK ((1 << MPTCP_PM_ALREADY_ESTABLISHED) - 1)
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_cienum mptcp_addr_signal_status {
20662306a36Sopenharmony_ci	MPTCP_ADD_ADDR_SIGNAL,
20762306a36Sopenharmony_ci	MPTCP_ADD_ADDR_ECHO,
20862306a36Sopenharmony_ci	MPTCP_RM_ADDR_SIGNAL,
20962306a36Sopenharmony_ci};
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_ci/* max value of mptcp_addr_info.id */
21262306a36Sopenharmony_ci#define MPTCP_PM_MAX_ADDR_ID		U8_MAX
21362306a36Sopenharmony_ci
21462306a36Sopenharmony_cistruct mptcp_pm_data {
21562306a36Sopenharmony_ci	struct mptcp_addr_info local;
21662306a36Sopenharmony_ci	struct mptcp_addr_info remote;
21762306a36Sopenharmony_ci	struct list_head anno_list;
21862306a36Sopenharmony_ci	struct list_head userspace_pm_local_addr_list;
21962306a36Sopenharmony_ci
22062306a36Sopenharmony_ci	spinlock_t	lock;		/*protects the whole PM data */
22162306a36Sopenharmony_ci
22262306a36Sopenharmony_ci	u8		addr_signal;
22362306a36Sopenharmony_ci	bool		server_side;
22462306a36Sopenharmony_ci	bool		work_pending;
22562306a36Sopenharmony_ci	bool		accept_addr;
22662306a36Sopenharmony_ci	bool		accept_subflow;
22762306a36Sopenharmony_ci	bool		remote_deny_join_id0;
22862306a36Sopenharmony_ci	u8		add_addr_signaled;
22962306a36Sopenharmony_ci	u8		add_addr_accepted;
23062306a36Sopenharmony_ci	u8		local_addr_used;
23162306a36Sopenharmony_ci	u8		pm_type;
23262306a36Sopenharmony_ci	u8		subflows;
23362306a36Sopenharmony_ci	u8		status;
23462306a36Sopenharmony_ci	DECLARE_BITMAP(id_avail_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
23562306a36Sopenharmony_ci	struct mptcp_rm_list rm_list_tx;
23662306a36Sopenharmony_ci	struct mptcp_rm_list rm_list_rx;
23762306a36Sopenharmony_ci};
23862306a36Sopenharmony_ci
23962306a36Sopenharmony_cistruct mptcp_pm_addr_entry {
24062306a36Sopenharmony_ci	struct list_head	list;
24162306a36Sopenharmony_ci	struct mptcp_addr_info	addr;
24262306a36Sopenharmony_ci	u8			flags;
24362306a36Sopenharmony_ci	int			ifindex;
24462306a36Sopenharmony_ci	struct socket		*lsk;
24562306a36Sopenharmony_ci};
24662306a36Sopenharmony_ci
24762306a36Sopenharmony_cistruct mptcp_data_frag {
24862306a36Sopenharmony_ci	struct list_head list;
24962306a36Sopenharmony_ci	u64 data_seq;
25062306a36Sopenharmony_ci	u16 data_len;
25162306a36Sopenharmony_ci	u16 offset;
25262306a36Sopenharmony_ci	u16 overhead;
25362306a36Sopenharmony_ci	u16 already_sent;
25462306a36Sopenharmony_ci	struct page *page;
25562306a36Sopenharmony_ci};
25662306a36Sopenharmony_ci
25762306a36Sopenharmony_ci/* MPTCP connection sock */
25862306a36Sopenharmony_cistruct mptcp_sock {
25962306a36Sopenharmony_ci	/* inet_connection_sock must be the first member */
26062306a36Sopenharmony_ci	struct inet_connection_sock sk;
26162306a36Sopenharmony_ci	u64		local_key;
26262306a36Sopenharmony_ci	u64		remote_key;
26362306a36Sopenharmony_ci	u64		write_seq;
26462306a36Sopenharmony_ci	u64		bytes_sent;
26562306a36Sopenharmony_ci	u64		snd_nxt;
26662306a36Sopenharmony_ci	u64		bytes_received;
26762306a36Sopenharmony_ci	u64		ack_seq;
26862306a36Sopenharmony_ci	atomic64_t	rcv_wnd_sent;
26962306a36Sopenharmony_ci	u64		rcv_data_fin_seq;
27062306a36Sopenharmony_ci	u64		bytes_retrans;
27162306a36Sopenharmony_ci	int		rmem_fwd_alloc;
27262306a36Sopenharmony_ci	int		snd_burst;
27362306a36Sopenharmony_ci	int		old_wspace;
27462306a36Sopenharmony_ci	u64		recovery_snd_nxt;	/* in recovery mode accept up to this seq;
27562306a36Sopenharmony_ci						 * recovery related fields are under data_lock
27662306a36Sopenharmony_ci						 * protection
27762306a36Sopenharmony_ci						 */
27862306a36Sopenharmony_ci	u64		bytes_acked;
27962306a36Sopenharmony_ci	u64		snd_una;
28062306a36Sopenharmony_ci	u64		wnd_end;
28162306a36Sopenharmony_ci	unsigned long	timer_ival;
28262306a36Sopenharmony_ci	u32		token;
28362306a36Sopenharmony_ci	int		rmem_released;
28462306a36Sopenharmony_ci	unsigned long	flags;
28562306a36Sopenharmony_ci	unsigned long	cb_flags;
28662306a36Sopenharmony_ci	bool		recovery;		/* closing subflow write queue reinjected */
28762306a36Sopenharmony_ci	bool		can_ack;
28862306a36Sopenharmony_ci	bool		fully_established;
28962306a36Sopenharmony_ci	bool		rcv_data_fin;
29062306a36Sopenharmony_ci	bool		snd_data_fin_enable;
29162306a36Sopenharmony_ci	bool		rcv_fastclose;
29262306a36Sopenharmony_ci	bool		use_64bit_ack; /* Set when we received a 64-bit DSN */
29362306a36Sopenharmony_ci	bool		csum_enabled;
29462306a36Sopenharmony_ci	bool		allow_infinite_fallback;
29562306a36Sopenharmony_ci	u8		pending_state; /* A subflow asked to set this sk_state,
29662306a36Sopenharmony_ci					* protected by the msk data lock
29762306a36Sopenharmony_ci					*/
29862306a36Sopenharmony_ci	u8		mpc_endpoint_id;
29962306a36Sopenharmony_ci	u8		recvmsg_inq:1,
30062306a36Sopenharmony_ci			cork:1,
30162306a36Sopenharmony_ci			nodelay:1,
30262306a36Sopenharmony_ci			fastopening:1,
30362306a36Sopenharmony_ci			in_accept_queue:1,
30462306a36Sopenharmony_ci			free_first:1,
30562306a36Sopenharmony_ci			rcvspace_init:1;
30662306a36Sopenharmony_ci	struct work_struct work;
30762306a36Sopenharmony_ci	struct sk_buff  *ooo_last_skb;
30862306a36Sopenharmony_ci	struct rb_root  out_of_order_queue;
30962306a36Sopenharmony_ci	struct sk_buff_head receive_queue;
31062306a36Sopenharmony_ci	struct list_head conn_list;
31162306a36Sopenharmony_ci	struct list_head rtx_queue;
31262306a36Sopenharmony_ci	struct mptcp_data_frag *first_pending;
31362306a36Sopenharmony_ci	struct list_head join_list;
31462306a36Sopenharmony_ci	struct sock	*first; /* The mptcp ops can safely dereference, using suitable
31562306a36Sopenharmony_ci				 * ONCE annotation, the subflow outside the socket
31662306a36Sopenharmony_ci				 * lock as such sock is freed after close().
31762306a36Sopenharmony_ci				 */
31862306a36Sopenharmony_ci	struct mptcp_pm_data	pm;
31962306a36Sopenharmony_ci	struct mptcp_sched_ops	*sched;
32062306a36Sopenharmony_ci	struct {
32162306a36Sopenharmony_ci		u32	space;	/* bytes copied in last measurement window */
32262306a36Sopenharmony_ci		u32	copied; /* bytes copied in this measurement window */
32362306a36Sopenharmony_ci		u64	time;	/* start time of measurement window */
32462306a36Sopenharmony_ci		u64	rtt_us; /* last maximum rtt of subflows */
32562306a36Sopenharmony_ci	} rcvq_space;
32662306a36Sopenharmony_ci	u8		scaling_ratio;
32762306a36Sopenharmony_ci
32862306a36Sopenharmony_ci	u32		subflow_id;
32962306a36Sopenharmony_ci	u32		setsockopt_seq;
33062306a36Sopenharmony_ci	char		ca_name[TCP_CA_NAME_MAX];
33162306a36Sopenharmony_ci};
33262306a36Sopenharmony_ci
33362306a36Sopenharmony_ci#define mptcp_data_lock(sk) spin_lock_bh(&(sk)->sk_lock.slock)
33462306a36Sopenharmony_ci#define mptcp_data_unlock(sk) spin_unlock_bh(&(sk)->sk_lock.slock)
33562306a36Sopenharmony_ci
33662306a36Sopenharmony_ci#define mptcp_for_each_subflow(__msk, __subflow)			\
33762306a36Sopenharmony_ci	list_for_each_entry(__subflow, &((__msk)->conn_list), node)
33862306a36Sopenharmony_ci#define mptcp_for_each_subflow_safe(__msk, __subflow, __tmp)			\
33962306a36Sopenharmony_ci	list_for_each_entry_safe(__subflow, __tmp, &((__msk)->conn_list), node)
34062306a36Sopenharmony_ci
34162306a36Sopenharmony_cistatic inline void msk_owned_by_me(const struct mptcp_sock *msk)
34262306a36Sopenharmony_ci{
34362306a36Sopenharmony_ci	sock_owned_by_me((const struct sock *)msk);
34462306a36Sopenharmony_ci}
34562306a36Sopenharmony_ci
34662306a36Sopenharmony_ci#define mptcp_sk(ptr) container_of_const(ptr, struct mptcp_sock, sk.icsk_inet.sk)
34762306a36Sopenharmony_ci
34862306a36Sopenharmony_ci/* the msk socket don't use the backlog, also account for the bulk
34962306a36Sopenharmony_ci * free memory
35062306a36Sopenharmony_ci */
35162306a36Sopenharmony_cistatic inline int __mptcp_rmem(const struct sock *sk)
35262306a36Sopenharmony_ci{
35362306a36Sopenharmony_ci	return atomic_read(&sk->sk_rmem_alloc) - READ_ONCE(mptcp_sk(sk)->rmem_released);
35462306a36Sopenharmony_ci}
35562306a36Sopenharmony_ci
35662306a36Sopenharmony_cistatic inline int mptcp_win_from_space(const struct sock *sk, int space)
35762306a36Sopenharmony_ci{
35862306a36Sopenharmony_ci	return __tcp_win_from_space(mptcp_sk(sk)->scaling_ratio, space);
35962306a36Sopenharmony_ci}
36062306a36Sopenharmony_ci
36162306a36Sopenharmony_cistatic inline int __mptcp_space(const struct sock *sk)
36262306a36Sopenharmony_ci{
36362306a36Sopenharmony_ci	return mptcp_win_from_space(sk, READ_ONCE(sk->sk_rcvbuf) - __mptcp_rmem(sk));
36462306a36Sopenharmony_ci}
36562306a36Sopenharmony_ci
36662306a36Sopenharmony_cistatic inline struct mptcp_data_frag *mptcp_send_head(const struct sock *sk)
36762306a36Sopenharmony_ci{
36862306a36Sopenharmony_ci	const struct mptcp_sock *msk = mptcp_sk(sk);
36962306a36Sopenharmony_ci
37062306a36Sopenharmony_ci	return READ_ONCE(msk->first_pending);
37162306a36Sopenharmony_ci}
37262306a36Sopenharmony_ci
37362306a36Sopenharmony_cistatic inline struct mptcp_data_frag *mptcp_send_next(struct sock *sk)
37462306a36Sopenharmony_ci{
37562306a36Sopenharmony_ci	struct mptcp_sock *msk = mptcp_sk(sk);
37662306a36Sopenharmony_ci	struct mptcp_data_frag *cur;
37762306a36Sopenharmony_ci
37862306a36Sopenharmony_ci	cur = msk->first_pending;
37962306a36Sopenharmony_ci	return list_is_last(&cur->list, &msk->rtx_queue) ? NULL :
38062306a36Sopenharmony_ci						     list_next_entry(cur, list);
38162306a36Sopenharmony_ci}
38262306a36Sopenharmony_ci
38362306a36Sopenharmony_cistatic inline struct mptcp_data_frag *mptcp_pending_tail(const struct sock *sk)
38462306a36Sopenharmony_ci{
38562306a36Sopenharmony_ci	const struct mptcp_sock *msk = mptcp_sk(sk);
38662306a36Sopenharmony_ci
38762306a36Sopenharmony_ci	if (!msk->first_pending)
38862306a36Sopenharmony_ci		return NULL;
38962306a36Sopenharmony_ci
39062306a36Sopenharmony_ci	if (WARN_ON_ONCE(list_empty(&msk->rtx_queue)))
39162306a36Sopenharmony_ci		return NULL;
39262306a36Sopenharmony_ci
39362306a36Sopenharmony_ci	return list_last_entry(&msk->rtx_queue, struct mptcp_data_frag, list);
39462306a36Sopenharmony_ci}
39562306a36Sopenharmony_ci
39662306a36Sopenharmony_cistatic inline struct mptcp_data_frag *mptcp_rtx_head(struct sock *sk)
39762306a36Sopenharmony_ci{
39862306a36Sopenharmony_ci	struct mptcp_sock *msk = mptcp_sk(sk);
39962306a36Sopenharmony_ci
40062306a36Sopenharmony_ci	if (msk->snd_una == READ_ONCE(msk->snd_nxt))
40162306a36Sopenharmony_ci		return NULL;
40262306a36Sopenharmony_ci
40362306a36Sopenharmony_ci	return list_first_entry_or_null(&msk->rtx_queue, struct mptcp_data_frag, list);
40462306a36Sopenharmony_ci}
40562306a36Sopenharmony_ci
40662306a36Sopenharmony_cistruct csum_pseudo_header {
40762306a36Sopenharmony_ci	__be64 data_seq;
40862306a36Sopenharmony_ci	__be32 subflow_seq;
40962306a36Sopenharmony_ci	__be16 data_len;
41062306a36Sopenharmony_ci	__sum16 csum;
41162306a36Sopenharmony_ci};
41262306a36Sopenharmony_ci
41362306a36Sopenharmony_cistruct mptcp_subflow_request_sock {
41462306a36Sopenharmony_ci	struct	tcp_request_sock sk;
41562306a36Sopenharmony_ci	u16	mp_capable : 1,
41662306a36Sopenharmony_ci		mp_join : 1,
41762306a36Sopenharmony_ci		backup : 1,
41862306a36Sopenharmony_ci		csum_reqd : 1,
41962306a36Sopenharmony_ci		allow_join_id0 : 1;
42062306a36Sopenharmony_ci	u8	local_id;
42162306a36Sopenharmony_ci	u8	remote_id;
42262306a36Sopenharmony_ci	u64	local_key;
42362306a36Sopenharmony_ci	u64	idsn;
42462306a36Sopenharmony_ci	u32	token;
42562306a36Sopenharmony_ci	u32	ssn_offset;
42662306a36Sopenharmony_ci	u64	thmac;
42762306a36Sopenharmony_ci	u32	local_nonce;
42862306a36Sopenharmony_ci	u32	remote_nonce;
42962306a36Sopenharmony_ci	struct mptcp_sock	*msk;
43062306a36Sopenharmony_ci	struct hlist_nulls_node token_node;
43162306a36Sopenharmony_ci};
43262306a36Sopenharmony_ci
43362306a36Sopenharmony_cistatic inline struct mptcp_subflow_request_sock *
43462306a36Sopenharmony_cimptcp_subflow_rsk(const struct request_sock *rsk)
43562306a36Sopenharmony_ci{
43662306a36Sopenharmony_ci	return (struct mptcp_subflow_request_sock *)rsk;
43762306a36Sopenharmony_ci}
43862306a36Sopenharmony_ci
43962306a36Sopenharmony_cienum mptcp_data_avail {
44062306a36Sopenharmony_ci	MPTCP_SUBFLOW_NODATA,
44162306a36Sopenharmony_ci	MPTCP_SUBFLOW_DATA_AVAIL,
44262306a36Sopenharmony_ci};
44362306a36Sopenharmony_ci
44462306a36Sopenharmony_cistruct mptcp_delegated_action {
44562306a36Sopenharmony_ci	struct napi_struct napi;
44662306a36Sopenharmony_ci	struct list_head head;
44762306a36Sopenharmony_ci};
44862306a36Sopenharmony_ci
44962306a36Sopenharmony_ciDECLARE_PER_CPU(struct mptcp_delegated_action, mptcp_delegated_actions);
45062306a36Sopenharmony_ci
45162306a36Sopenharmony_ci#define MPTCP_DELEGATE_SCHEDULED	0
45262306a36Sopenharmony_ci#define MPTCP_DELEGATE_SEND		1
45362306a36Sopenharmony_ci#define MPTCP_DELEGATE_ACK		2
45462306a36Sopenharmony_ci#define MPTCP_DELEGATE_SNDBUF		3
45562306a36Sopenharmony_ci
45662306a36Sopenharmony_ci#define MPTCP_DELEGATE_ACTIONS_MASK	(~BIT(MPTCP_DELEGATE_SCHEDULED))
45762306a36Sopenharmony_ci/* MPTCP subflow context */
45862306a36Sopenharmony_cistruct mptcp_subflow_context {
45962306a36Sopenharmony_ci	struct	list_head node;/* conn_list of subflows */
46062306a36Sopenharmony_ci
46162306a36Sopenharmony_ci	struct_group(reset,
46262306a36Sopenharmony_ci
46362306a36Sopenharmony_ci	unsigned long avg_pacing_rate; /* protected by msk socket lock */
46462306a36Sopenharmony_ci	u64	local_key;
46562306a36Sopenharmony_ci	u64	remote_key;
46662306a36Sopenharmony_ci	u64	idsn;
46762306a36Sopenharmony_ci	u64	map_seq;
46862306a36Sopenharmony_ci	u32	snd_isn;
46962306a36Sopenharmony_ci	u32	token;
47062306a36Sopenharmony_ci	u32	rel_write_seq;
47162306a36Sopenharmony_ci	u32	map_subflow_seq;
47262306a36Sopenharmony_ci	u32	ssn_offset;
47362306a36Sopenharmony_ci	u32	map_data_len;
47462306a36Sopenharmony_ci	__wsum	map_data_csum;
47562306a36Sopenharmony_ci	u32	map_csum_len;
47662306a36Sopenharmony_ci	u32	request_mptcp : 1,  /* send MP_CAPABLE */
47762306a36Sopenharmony_ci		request_join : 1,   /* send MP_JOIN */
47862306a36Sopenharmony_ci		request_bkup : 1,
47962306a36Sopenharmony_ci		mp_capable : 1,	    /* remote is MPTCP capable */
48062306a36Sopenharmony_ci		mp_join : 1,	    /* remote is JOINing */
48162306a36Sopenharmony_ci		fully_established : 1,	    /* path validated */
48262306a36Sopenharmony_ci		pm_notified : 1,    /* PM hook called for established status */
48362306a36Sopenharmony_ci		conn_finished : 1,
48462306a36Sopenharmony_ci		map_valid : 1,
48562306a36Sopenharmony_ci		map_csum_reqd : 1,
48662306a36Sopenharmony_ci		map_data_fin : 1,
48762306a36Sopenharmony_ci		mpc_map : 1,
48862306a36Sopenharmony_ci		backup : 1,
48962306a36Sopenharmony_ci		send_mp_prio : 1,
49062306a36Sopenharmony_ci		send_mp_fail : 1,
49162306a36Sopenharmony_ci		send_fastclose : 1,
49262306a36Sopenharmony_ci		send_infinite_map : 1,
49362306a36Sopenharmony_ci		remote_key_valid : 1,        /* received the peer key from */
49462306a36Sopenharmony_ci		disposable : 1,	    /* ctx can be free at ulp release time */
49562306a36Sopenharmony_ci		stale : 1,	    /* unable to snd/rcv data, do not use for xmit */
49662306a36Sopenharmony_ci		valid_csum_seen : 1,        /* at least one csum validated */
49762306a36Sopenharmony_ci		is_mptfo : 1,	    /* subflow is doing TFO */
49862306a36Sopenharmony_ci		__unused : 10;
49962306a36Sopenharmony_ci	enum mptcp_data_avail data_avail;
50062306a36Sopenharmony_ci	bool	scheduled;
50162306a36Sopenharmony_ci	u32	remote_nonce;
50262306a36Sopenharmony_ci	u64	thmac;
50362306a36Sopenharmony_ci	u32	local_nonce;
50462306a36Sopenharmony_ci	u32	remote_token;
50562306a36Sopenharmony_ci	union {
50662306a36Sopenharmony_ci		u8	hmac[MPTCPOPT_HMAC_LEN]; /* MPJ subflow only */
50762306a36Sopenharmony_ci		u64	iasn;	    /* initial ack sequence number, MPC subflows only */
50862306a36Sopenharmony_ci	};
50962306a36Sopenharmony_ci	s16	local_id;	    /* if negative not initialized yet */
51062306a36Sopenharmony_ci	u8	remote_id;
51162306a36Sopenharmony_ci	u8	reset_seen:1;
51262306a36Sopenharmony_ci	u8	reset_transient:1;
51362306a36Sopenharmony_ci	u8	reset_reason:4;
51462306a36Sopenharmony_ci	u8	stale_count;
51562306a36Sopenharmony_ci
51662306a36Sopenharmony_ci	u32	subflow_id;
51762306a36Sopenharmony_ci
51862306a36Sopenharmony_ci	long	delegated_status;
51962306a36Sopenharmony_ci	unsigned long	fail_tout;
52062306a36Sopenharmony_ci
52162306a36Sopenharmony_ci	);
52262306a36Sopenharmony_ci
52362306a36Sopenharmony_ci	struct	list_head delegated_node;   /* link into delegated_action, protected by local BH */
52462306a36Sopenharmony_ci
52562306a36Sopenharmony_ci	u32	setsockopt_seq;
52662306a36Sopenharmony_ci	u32	stale_rcv_tstamp;
52762306a36Sopenharmony_ci	int     cached_sndbuf;	    /* sndbuf size when last synced with the msk sndbuf,
52862306a36Sopenharmony_ci				     * protected by the msk socket lock
52962306a36Sopenharmony_ci				     */
53062306a36Sopenharmony_ci
53162306a36Sopenharmony_ci	struct	sock *tcp_sock;	    /* tcp sk backpointer */
53262306a36Sopenharmony_ci	struct	sock *conn;	    /* parent mptcp_sock */
53362306a36Sopenharmony_ci	const	struct inet_connection_sock_af_ops *icsk_af_ops;
53462306a36Sopenharmony_ci	void	(*tcp_state_change)(struct sock *sk);
53562306a36Sopenharmony_ci	void	(*tcp_error_report)(struct sock *sk);
53662306a36Sopenharmony_ci
53762306a36Sopenharmony_ci	struct	rcu_head rcu;
53862306a36Sopenharmony_ci};
53962306a36Sopenharmony_ci
54062306a36Sopenharmony_cistatic inline struct mptcp_subflow_context *
54162306a36Sopenharmony_cimptcp_subflow_ctx(const struct sock *sk)
54262306a36Sopenharmony_ci{
54362306a36Sopenharmony_ci	struct inet_connection_sock *icsk = inet_csk(sk);
54462306a36Sopenharmony_ci
54562306a36Sopenharmony_ci	/* Use RCU on icsk_ulp_data only for sock diag code */
54662306a36Sopenharmony_ci	return (__force struct mptcp_subflow_context *)icsk->icsk_ulp_data;
54762306a36Sopenharmony_ci}
54862306a36Sopenharmony_ci
54962306a36Sopenharmony_cistatic inline struct sock *
55062306a36Sopenharmony_cimptcp_subflow_tcp_sock(const struct mptcp_subflow_context *subflow)
55162306a36Sopenharmony_ci{
55262306a36Sopenharmony_ci	return subflow->tcp_sock;
55362306a36Sopenharmony_ci}
55462306a36Sopenharmony_ci
55562306a36Sopenharmony_cistatic inline void
55662306a36Sopenharmony_cimptcp_subflow_ctx_reset(struct mptcp_subflow_context *subflow)
55762306a36Sopenharmony_ci{
55862306a36Sopenharmony_ci	memset(&subflow->reset, 0, sizeof(subflow->reset));
55962306a36Sopenharmony_ci	subflow->request_mptcp = 1;
56062306a36Sopenharmony_ci	WRITE_ONCE(subflow->local_id, -1);
56162306a36Sopenharmony_ci}
56262306a36Sopenharmony_ci
56362306a36Sopenharmony_cistatic inline u64
56462306a36Sopenharmony_cimptcp_subflow_get_map_offset(const struct mptcp_subflow_context *subflow)
56562306a36Sopenharmony_ci{
56662306a36Sopenharmony_ci	return tcp_sk(mptcp_subflow_tcp_sock(subflow))->copied_seq -
56762306a36Sopenharmony_ci		      subflow->ssn_offset -
56862306a36Sopenharmony_ci		      subflow->map_subflow_seq;
56962306a36Sopenharmony_ci}
57062306a36Sopenharmony_ci
57162306a36Sopenharmony_cistatic inline u64
57262306a36Sopenharmony_cimptcp_subflow_get_mapped_dsn(const struct mptcp_subflow_context *subflow)
57362306a36Sopenharmony_ci{
57462306a36Sopenharmony_ci	return subflow->map_seq + mptcp_subflow_get_map_offset(subflow);
57562306a36Sopenharmony_ci}
57662306a36Sopenharmony_ci
57762306a36Sopenharmony_civoid mptcp_subflow_process_delegated(struct sock *ssk, long actions);
57862306a36Sopenharmony_ci
57962306a36Sopenharmony_cistatic inline void mptcp_subflow_delegate(struct mptcp_subflow_context *subflow, int action)
58062306a36Sopenharmony_ci{
58162306a36Sopenharmony_ci	long old, set_bits = BIT(MPTCP_DELEGATE_SCHEDULED) | BIT(action);
58262306a36Sopenharmony_ci	struct mptcp_delegated_action *delegated;
58362306a36Sopenharmony_ci	bool schedule;
58462306a36Sopenharmony_ci
58562306a36Sopenharmony_ci	/* the caller held the subflow bh socket lock */
58662306a36Sopenharmony_ci	lockdep_assert_in_softirq();
58762306a36Sopenharmony_ci
58862306a36Sopenharmony_ci	/* The implied barrier pairs with tcp_release_cb_override()
58962306a36Sopenharmony_ci	 * mptcp_napi_poll(), and ensures the below list check sees list
59062306a36Sopenharmony_ci	 * updates done prior to delegated status bits changes
59162306a36Sopenharmony_ci	 */
59262306a36Sopenharmony_ci	old = set_mask_bits(&subflow->delegated_status, 0, set_bits);
59362306a36Sopenharmony_ci	if (!(old & BIT(MPTCP_DELEGATE_SCHEDULED))) {
59462306a36Sopenharmony_ci		if (WARN_ON_ONCE(!list_empty(&subflow->delegated_node)))
59562306a36Sopenharmony_ci			return;
59662306a36Sopenharmony_ci
59762306a36Sopenharmony_ci		delegated = this_cpu_ptr(&mptcp_delegated_actions);
59862306a36Sopenharmony_ci		schedule = list_empty(&delegated->head);
59962306a36Sopenharmony_ci		list_add_tail(&subflow->delegated_node, &delegated->head);
60062306a36Sopenharmony_ci		sock_hold(mptcp_subflow_tcp_sock(subflow));
60162306a36Sopenharmony_ci		if (schedule)
60262306a36Sopenharmony_ci			napi_schedule(&delegated->napi);
60362306a36Sopenharmony_ci	}
60462306a36Sopenharmony_ci}
60562306a36Sopenharmony_ci
60662306a36Sopenharmony_cistatic inline struct mptcp_subflow_context *
60762306a36Sopenharmony_cimptcp_subflow_delegated_next(struct mptcp_delegated_action *delegated)
60862306a36Sopenharmony_ci{
60962306a36Sopenharmony_ci	struct mptcp_subflow_context *ret;
61062306a36Sopenharmony_ci
61162306a36Sopenharmony_ci	if (list_empty(&delegated->head))
61262306a36Sopenharmony_ci		return NULL;
61362306a36Sopenharmony_ci
61462306a36Sopenharmony_ci	ret = list_first_entry(&delegated->head, struct mptcp_subflow_context, delegated_node);
61562306a36Sopenharmony_ci	list_del_init(&ret->delegated_node);
61662306a36Sopenharmony_ci	return ret;
61762306a36Sopenharmony_ci}
61862306a36Sopenharmony_ci
61962306a36Sopenharmony_ciint mptcp_is_enabled(const struct net *net);
62062306a36Sopenharmony_ciunsigned int mptcp_get_add_addr_timeout(const struct net *net);
62162306a36Sopenharmony_ciint mptcp_is_checksum_enabled(const struct net *net);
62262306a36Sopenharmony_ciint mptcp_allow_join_id0(const struct net *net);
62362306a36Sopenharmony_ciunsigned int mptcp_stale_loss_cnt(const struct net *net);
62462306a36Sopenharmony_ciint mptcp_get_pm_type(const struct net *net);
62562306a36Sopenharmony_ciconst char *mptcp_get_scheduler(const struct net *net);
62662306a36Sopenharmony_civoid __mptcp_subflow_fully_established(struct mptcp_sock *msk,
62762306a36Sopenharmony_ci				       struct mptcp_subflow_context *subflow,
62862306a36Sopenharmony_ci				       const struct mptcp_options_received *mp_opt);
62962306a36Sopenharmony_cibool __mptcp_retransmit_pending_data(struct sock *sk);
63062306a36Sopenharmony_civoid mptcp_check_and_set_pending(struct sock *sk);
63162306a36Sopenharmony_civoid __mptcp_push_pending(struct sock *sk, unsigned int flags);
63262306a36Sopenharmony_cibool mptcp_subflow_data_available(struct sock *sk);
63362306a36Sopenharmony_civoid __init mptcp_subflow_init(void);
63462306a36Sopenharmony_civoid mptcp_subflow_shutdown(struct sock *sk, struct sock *ssk, int how);
63562306a36Sopenharmony_civoid mptcp_close_ssk(struct sock *sk, struct sock *ssk,
63662306a36Sopenharmony_ci		     struct mptcp_subflow_context *subflow);
63762306a36Sopenharmony_civoid __mptcp_subflow_send_ack(struct sock *ssk);
63862306a36Sopenharmony_civoid mptcp_subflow_reset(struct sock *ssk);
63962306a36Sopenharmony_civoid mptcp_subflow_queue_clean(struct sock *sk, struct sock *ssk);
64062306a36Sopenharmony_civoid mptcp_sock_graft(struct sock *sk, struct socket *parent);
64162306a36Sopenharmony_cistruct sock *__mptcp_nmpc_sk(struct mptcp_sock *msk);
64262306a36Sopenharmony_cibool __mptcp_close(struct sock *sk, long timeout);
64362306a36Sopenharmony_civoid mptcp_cancel_work(struct sock *sk);
64462306a36Sopenharmony_civoid __mptcp_unaccepted_force_close(struct sock *sk);
64562306a36Sopenharmony_civoid mptcp_set_owner_r(struct sk_buff *skb, struct sock *sk);
64662306a36Sopenharmony_civoid mptcp_set_state(struct sock *sk, int state);
64762306a36Sopenharmony_ci
64862306a36Sopenharmony_cibool mptcp_addresses_equal(const struct mptcp_addr_info *a,
64962306a36Sopenharmony_ci			   const struct mptcp_addr_info *b, bool use_port);
65062306a36Sopenharmony_civoid mptcp_local_address(const struct sock_common *skc, struct mptcp_addr_info *addr);
65162306a36Sopenharmony_ci
65262306a36Sopenharmony_ci/* called with sk socket lock held */
65362306a36Sopenharmony_ciint __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc,
65462306a36Sopenharmony_ci			    const struct mptcp_addr_info *remote);
65562306a36Sopenharmony_ciint mptcp_subflow_create_socket(struct sock *sk, unsigned short family,
65662306a36Sopenharmony_ci				struct socket **new_sock);
65762306a36Sopenharmony_civoid mptcp_info2sockaddr(const struct mptcp_addr_info *info,
65862306a36Sopenharmony_ci			 struct sockaddr_storage *addr,
65962306a36Sopenharmony_ci			 unsigned short family);
66062306a36Sopenharmony_cistruct mptcp_sched_ops *mptcp_sched_find(const char *name);
66162306a36Sopenharmony_ciint mptcp_register_scheduler(struct mptcp_sched_ops *sched);
66262306a36Sopenharmony_civoid mptcp_unregister_scheduler(struct mptcp_sched_ops *sched);
66362306a36Sopenharmony_civoid mptcp_sched_init(void);
66462306a36Sopenharmony_ciint mptcp_init_sched(struct mptcp_sock *msk,
66562306a36Sopenharmony_ci		     struct mptcp_sched_ops *sched);
66662306a36Sopenharmony_civoid mptcp_release_sched(struct mptcp_sock *msk);
66762306a36Sopenharmony_civoid mptcp_subflow_set_scheduled(struct mptcp_subflow_context *subflow,
66862306a36Sopenharmony_ci				 bool scheduled);
66962306a36Sopenharmony_cistruct sock *mptcp_subflow_get_send(struct mptcp_sock *msk);
67062306a36Sopenharmony_cistruct sock *mptcp_subflow_get_retrans(struct mptcp_sock *msk);
67162306a36Sopenharmony_ciint mptcp_sched_get_send(struct mptcp_sock *msk);
67262306a36Sopenharmony_ciint mptcp_sched_get_retrans(struct mptcp_sock *msk);
67362306a36Sopenharmony_ci
67462306a36Sopenharmony_cistatic inline bool __tcp_can_send(const struct sock *ssk)
67562306a36Sopenharmony_ci{
67662306a36Sopenharmony_ci	/* only send if our side has not closed yet */
67762306a36Sopenharmony_ci	return ((1 << inet_sk_state_load(ssk)) & (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT));
67862306a36Sopenharmony_ci}
67962306a36Sopenharmony_ci
68062306a36Sopenharmony_cistatic inline bool __mptcp_subflow_active(struct mptcp_subflow_context *subflow)
68162306a36Sopenharmony_ci{
68262306a36Sopenharmony_ci	/* can't send if JOIN hasn't completed yet (i.e. is usable for mptcp) */
68362306a36Sopenharmony_ci	if (subflow->request_join && !subflow->fully_established)
68462306a36Sopenharmony_ci		return false;
68562306a36Sopenharmony_ci
68662306a36Sopenharmony_ci	return __tcp_can_send(mptcp_subflow_tcp_sock(subflow));
68762306a36Sopenharmony_ci}
68862306a36Sopenharmony_ci
68962306a36Sopenharmony_civoid mptcp_subflow_set_active(struct mptcp_subflow_context *subflow);
69062306a36Sopenharmony_ci
69162306a36Sopenharmony_cibool mptcp_subflow_active(struct mptcp_subflow_context *subflow);
69262306a36Sopenharmony_ci
69362306a36Sopenharmony_civoid mptcp_subflow_drop_ctx(struct sock *ssk);
69462306a36Sopenharmony_ci
69562306a36Sopenharmony_cistatic inline void mptcp_subflow_tcp_fallback(struct sock *sk,
69662306a36Sopenharmony_ci					      struct mptcp_subflow_context *ctx)
69762306a36Sopenharmony_ci{
69862306a36Sopenharmony_ci	sk->sk_data_ready = sock_def_readable;
69962306a36Sopenharmony_ci	sk->sk_state_change = ctx->tcp_state_change;
70062306a36Sopenharmony_ci	sk->sk_write_space = sk_stream_write_space;
70162306a36Sopenharmony_ci	sk->sk_error_report = ctx->tcp_error_report;
70262306a36Sopenharmony_ci
70362306a36Sopenharmony_ci	inet_csk(sk)->icsk_af_ops = ctx->icsk_af_ops;
70462306a36Sopenharmony_ci}
70562306a36Sopenharmony_ci
70662306a36Sopenharmony_civoid __init mptcp_proto_init(void);
70762306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_MPTCP_IPV6)
70862306a36Sopenharmony_ciint __init mptcp_proto_v6_init(void);
70962306a36Sopenharmony_ci#endif
71062306a36Sopenharmony_ci
71162306a36Sopenharmony_cistruct sock *mptcp_sk_clone_init(const struct sock *sk,
71262306a36Sopenharmony_ci				 const struct mptcp_options_received *mp_opt,
71362306a36Sopenharmony_ci				 struct sock *ssk,
71462306a36Sopenharmony_ci				 struct request_sock *req);
71562306a36Sopenharmony_civoid mptcp_get_options(const struct sk_buff *skb,
71662306a36Sopenharmony_ci		       struct mptcp_options_received *mp_opt);
71762306a36Sopenharmony_ci
71862306a36Sopenharmony_civoid mptcp_finish_connect(struct sock *sk);
71962306a36Sopenharmony_civoid __mptcp_sync_state(struct sock *sk, int state);
72062306a36Sopenharmony_civoid mptcp_reset_tout_timer(struct mptcp_sock *msk, unsigned long fail_tout);
72162306a36Sopenharmony_ci
72262306a36Sopenharmony_cistatic inline void mptcp_stop_tout_timer(struct sock *sk)
72362306a36Sopenharmony_ci{
72462306a36Sopenharmony_ci	if (!inet_csk(sk)->icsk_mtup.probe_timestamp)
72562306a36Sopenharmony_ci		return;
72662306a36Sopenharmony_ci
72762306a36Sopenharmony_ci	sk_stop_timer(sk, &sk->sk_timer);
72862306a36Sopenharmony_ci	inet_csk(sk)->icsk_mtup.probe_timestamp = 0;
72962306a36Sopenharmony_ci}
73062306a36Sopenharmony_ci
73162306a36Sopenharmony_cistatic inline void mptcp_set_close_tout(struct sock *sk, unsigned long tout)
73262306a36Sopenharmony_ci{
73362306a36Sopenharmony_ci	/* avoid 0 timestamp, as that means no close timeout */
73462306a36Sopenharmony_ci	inet_csk(sk)->icsk_mtup.probe_timestamp = tout ? : 1;
73562306a36Sopenharmony_ci}
73662306a36Sopenharmony_ci
73762306a36Sopenharmony_cistatic inline void mptcp_start_tout_timer(struct sock *sk)
73862306a36Sopenharmony_ci{
73962306a36Sopenharmony_ci	mptcp_set_close_tout(sk, tcp_jiffies32);
74062306a36Sopenharmony_ci	mptcp_reset_tout_timer(mptcp_sk(sk), 0);
74162306a36Sopenharmony_ci}
74262306a36Sopenharmony_ci
74362306a36Sopenharmony_cistatic inline bool mptcp_is_fully_established(struct sock *sk)
74462306a36Sopenharmony_ci{
74562306a36Sopenharmony_ci	return inet_sk_state_load(sk) == TCP_ESTABLISHED &&
74662306a36Sopenharmony_ci	       READ_ONCE(mptcp_sk(sk)->fully_established);
74762306a36Sopenharmony_ci}
74862306a36Sopenharmony_civoid mptcp_rcv_space_init(struct mptcp_sock *msk, const struct sock *ssk);
74962306a36Sopenharmony_civoid mptcp_data_ready(struct sock *sk, struct sock *ssk);
75062306a36Sopenharmony_cibool mptcp_finish_join(struct sock *sk);
75162306a36Sopenharmony_cibool mptcp_schedule_work(struct sock *sk);
75262306a36Sopenharmony_ciint mptcp_setsockopt(struct sock *sk, int level, int optname,
75362306a36Sopenharmony_ci		     sockptr_t optval, unsigned int optlen);
75462306a36Sopenharmony_ciint mptcp_getsockopt(struct sock *sk, int level, int optname,
75562306a36Sopenharmony_ci		     char __user *optval, int __user *option);
75662306a36Sopenharmony_ci
75762306a36Sopenharmony_ciu64 __mptcp_expand_seq(u64 old_seq, u64 cur_seq);
75862306a36Sopenharmony_cistatic inline u64 mptcp_expand_seq(u64 old_seq, u64 cur_seq, bool use_64bit)
75962306a36Sopenharmony_ci{
76062306a36Sopenharmony_ci	if (use_64bit)
76162306a36Sopenharmony_ci		return cur_seq;
76262306a36Sopenharmony_ci
76362306a36Sopenharmony_ci	return __mptcp_expand_seq(old_seq, cur_seq);
76462306a36Sopenharmony_ci}
76562306a36Sopenharmony_civoid __mptcp_check_push(struct sock *sk, struct sock *ssk);
76662306a36Sopenharmony_civoid __mptcp_data_acked(struct sock *sk);
76762306a36Sopenharmony_civoid __mptcp_error_report(struct sock *sk);
76862306a36Sopenharmony_cibool mptcp_update_rcv_data_fin(struct mptcp_sock *msk, u64 data_fin_seq, bool use_64bit);
76962306a36Sopenharmony_cistatic inline bool mptcp_data_fin_enabled(const struct mptcp_sock *msk)
77062306a36Sopenharmony_ci{
77162306a36Sopenharmony_ci	return READ_ONCE(msk->snd_data_fin_enable) &&
77262306a36Sopenharmony_ci	       READ_ONCE(msk->write_seq) == READ_ONCE(msk->snd_nxt);
77362306a36Sopenharmony_ci}
77462306a36Sopenharmony_ci
77562306a36Sopenharmony_cistatic inline void mptcp_write_space(struct sock *sk)
77662306a36Sopenharmony_ci{
77762306a36Sopenharmony_ci	if (sk_stream_is_writeable(sk)) {
77862306a36Sopenharmony_ci		/* pairs with memory barrier in mptcp_poll */
77962306a36Sopenharmony_ci		smp_mb();
78062306a36Sopenharmony_ci		if (test_and_clear_bit(MPTCP_NOSPACE, &mptcp_sk(sk)->flags))
78162306a36Sopenharmony_ci			sk_stream_write_space(sk);
78262306a36Sopenharmony_ci	}
78362306a36Sopenharmony_ci}
78462306a36Sopenharmony_ci
78562306a36Sopenharmony_cistatic inline void __mptcp_sync_sndbuf(struct sock *sk)
78662306a36Sopenharmony_ci{
78762306a36Sopenharmony_ci	struct mptcp_subflow_context *subflow;
78862306a36Sopenharmony_ci	int ssk_sndbuf, new_sndbuf;
78962306a36Sopenharmony_ci
79062306a36Sopenharmony_ci	if (sk->sk_userlocks & SOCK_SNDBUF_LOCK)
79162306a36Sopenharmony_ci		return;
79262306a36Sopenharmony_ci
79362306a36Sopenharmony_ci	new_sndbuf = sock_net(sk)->ipv4.sysctl_tcp_wmem[0];
79462306a36Sopenharmony_ci	mptcp_for_each_subflow(mptcp_sk(sk), subflow) {
79562306a36Sopenharmony_ci		ssk_sndbuf =  READ_ONCE(mptcp_subflow_tcp_sock(subflow)->sk_sndbuf);
79662306a36Sopenharmony_ci
79762306a36Sopenharmony_ci		subflow->cached_sndbuf = ssk_sndbuf;
79862306a36Sopenharmony_ci		new_sndbuf += ssk_sndbuf;
79962306a36Sopenharmony_ci	}
80062306a36Sopenharmony_ci
80162306a36Sopenharmony_ci	/* the msk max wmem limit is <nr_subflows> * tcp wmem[2] */
80262306a36Sopenharmony_ci	WRITE_ONCE(sk->sk_sndbuf, new_sndbuf);
80362306a36Sopenharmony_ci	mptcp_write_space(sk);
80462306a36Sopenharmony_ci}
80562306a36Sopenharmony_ci
80662306a36Sopenharmony_ci/* The called held both the msk socket and the subflow socket locks,
80762306a36Sopenharmony_ci * possibly under BH
80862306a36Sopenharmony_ci */
80962306a36Sopenharmony_cistatic inline void __mptcp_propagate_sndbuf(struct sock *sk, struct sock *ssk)
81062306a36Sopenharmony_ci{
81162306a36Sopenharmony_ci	struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk);
81262306a36Sopenharmony_ci
81362306a36Sopenharmony_ci	if (READ_ONCE(ssk->sk_sndbuf) != subflow->cached_sndbuf)
81462306a36Sopenharmony_ci		__mptcp_sync_sndbuf(sk);
81562306a36Sopenharmony_ci}
81662306a36Sopenharmony_ci
81762306a36Sopenharmony_ci/* the caller held only the subflow socket lock, either in process or
81862306a36Sopenharmony_ci * BH context. Additionally this can be called under the msk data lock,
81962306a36Sopenharmony_ci * so we can't acquire such lock here: let the delegate action acquires
82062306a36Sopenharmony_ci * the needed locks in suitable order.
82162306a36Sopenharmony_ci */
82262306a36Sopenharmony_cistatic inline void mptcp_propagate_sndbuf(struct sock *sk, struct sock *ssk)
82362306a36Sopenharmony_ci{
82462306a36Sopenharmony_ci	struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk);
82562306a36Sopenharmony_ci
82662306a36Sopenharmony_ci	if (likely(READ_ONCE(ssk->sk_sndbuf) == subflow->cached_sndbuf))
82762306a36Sopenharmony_ci		return;
82862306a36Sopenharmony_ci
82962306a36Sopenharmony_ci	local_bh_disable();
83062306a36Sopenharmony_ci	mptcp_subflow_delegate(subflow, MPTCP_DELEGATE_SNDBUF);
83162306a36Sopenharmony_ci	local_bh_enable();
83262306a36Sopenharmony_ci}
83362306a36Sopenharmony_ci
83462306a36Sopenharmony_civoid mptcp_destroy_common(struct mptcp_sock *msk, unsigned int flags);
83562306a36Sopenharmony_ci
83662306a36Sopenharmony_ci#define MPTCP_TOKEN_MAX_RETRIES	4
83762306a36Sopenharmony_ci
83862306a36Sopenharmony_civoid __init mptcp_token_init(void);
83962306a36Sopenharmony_cistatic inline void mptcp_token_init_request(struct request_sock *req)
84062306a36Sopenharmony_ci{
84162306a36Sopenharmony_ci	mptcp_subflow_rsk(req)->token_node.pprev = NULL;
84262306a36Sopenharmony_ci}
84362306a36Sopenharmony_ci
84462306a36Sopenharmony_ciint mptcp_token_new_request(struct request_sock *req);
84562306a36Sopenharmony_civoid mptcp_token_destroy_request(struct request_sock *req);
84662306a36Sopenharmony_ciint mptcp_token_new_connect(struct sock *ssk);
84762306a36Sopenharmony_civoid mptcp_token_accept(struct mptcp_subflow_request_sock *r,
84862306a36Sopenharmony_ci			struct mptcp_sock *msk);
84962306a36Sopenharmony_cibool mptcp_token_exists(u32 token);
85062306a36Sopenharmony_cistruct mptcp_sock *mptcp_token_get_sock(struct net *net, u32 token);
85162306a36Sopenharmony_cistruct mptcp_sock *mptcp_token_iter_next(const struct net *net, long *s_slot,
85262306a36Sopenharmony_ci					 long *s_num);
85362306a36Sopenharmony_civoid mptcp_token_destroy(struct mptcp_sock *msk);
85462306a36Sopenharmony_ci
85562306a36Sopenharmony_civoid mptcp_crypto_key_sha(u64 key, u32 *token, u64 *idsn);
85662306a36Sopenharmony_ci
85762306a36Sopenharmony_civoid mptcp_crypto_hmac_sha(u64 key1, u64 key2, u8 *msg, int len, void *hmac);
85862306a36Sopenharmony_ci__sum16 __mptcp_make_csum(u64 data_seq, u32 subflow_seq, u16 data_len, __wsum sum);
85962306a36Sopenharmony_ci
86062306a36Sopenharmony_civoid __init mptcp_pm_init(void);
86162306a36Sopenharmony_civoid mptcp_pm_data_init(struct mptcp_sock *msk);
86262306a36Sopenharmony_civoid mptcp_pm_data_reset(struct mptcp_sock *msk);
86362306a36Sopenharmony_ciint mptcp_pm_parse_addr(struct nlattr *attr, struct genl_info *info,
86462306a36Sopenharmony_ci			struct mptcp_addr_info *addr);
86562306a36Sopenharmony_ciint mptcp_pm_parse_entry(struct nlattr *attr, struct genl_info *info,
86662306a36Sopenharmony_ci			 bool require_family,
86762306a36Sopenharmony_ci			 struct mptcp_pm_addr_entry *entry);
86862306a36Sopenharmony_cibool mptcp_pm_addr_families_match(const struct sock *sk,
86962306a36Sopenharmony_ci				  const struct mptcp_addr_info *loc,
87062306a36Sopenharmony_ci				  const struct mptcp_addr_info *rem);
87162306a36Sopenharmony_civoid mptcp_pm_subflow_chk_stale(const struct mptcp_sock *msk, struct sock *ssk);
87262306a36Sopenharmony_civoid mptcp_pm_nl_subflow_chk_stale(const struct mptcp_sock *msk, struct sock *ssk);
87362306a36Sopenharmony_civoid mptcp_pm_new_connection(struct mptcp_sock *msk, const struct sock *ssk, int server_side);
87462306a36Sopenharmony_civoid mptcp_pm_fully_established(struct mptcp_sock *msk, const struct sock *ssk);
87562306a36Sopenharmony_cibool mptcp_pm_allow_new_subflow(struct mptcp_sock *msk);
87662306a36Sopenharmony_civoid mptcp_pm_connection_closed(struct mptcp_sock *msk);
87762306a36Sopenharmony_civoid mptcp_pm_subflow_established(struct mptcp_sock *msk);
87862306a36Sopenharmony_cibool mptcp_pm_nl_check_work_pending(struct mptcp_sock *msk);
87962306a36Sopenharmony_civoid mptcp_pm_subflow_check_next(struct mptcp_sock *msk, const struct sock *ssk,
88062306a36Sopenharmony_ci				 const struct mptcp_subflow_context *subflow);
88162306a36Sopenharmony_civoid mptcp_pm_add_addr_received(const struct sock *ssk,
88262306a36Sopenharmony_ci				const struct mptcp_addr_info *addr);
88362306a36Sopenharmony_civoid mptcp_pm_add_addr_echoed(struct mptcp_sock *msk,
88462306a36Sopenharmony_ci			      const struct mptcp_addr_info *addr);
88562306a36Sopenharmony_civoid mptcp_pm_add_addr_send_ack(struct mptcp_sock *msk);
88662306a36Sopenharmony_civoid mptcp_pm_nl_addr_send_ack(struct mptcp_sock *msk);
88762306a36Sopenharmony_civoid mptcp_pm_rm_addr_received(struct mptcp_sock *msk,
88862306a36Sopenharmony_ci			       const struct mptcp_rm_list *rm_list);
88962306a36Sopenharmony_civoid mptcp_pm_mp_prio_received(struct sock *sk, u8 bkup);
89062306a36Sopenharmony_civoid mptcp_pm_mp_fail_received(struct sock *sk, u64 fail_seq);
89162306a36Sopenharmony_ciint mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
89262306a36Sopenharmony_ci				 struct mptcp_addr_info *addr,
89362306a36Sopenharmony_ci				 struct mptcp_addr_info *rem,
89462306a36Sopenharmony_ci				 u8 bkup);
89562306a36Sopenharmony_cibool mptcp_pm_alloc_anno_list(struct mptcp_sock *msk,
89662306a36Sopenharmony_ci			      const struct mptcp_addr_info *addr);
89762306a36Sopenharmony_civoid mptcp_pm_free_anno_list(struct mptcp_sock *msk);
89862306a36Sopenharmony_cibool mptcp_pm_sport_in_anno_list(struct mptcp_sock *msk, const struct sock *sk);
89962306a36Sopenharmony_cistruct mptcp_pm_add_entry *
90062306a36Sopenharmony_cimptcp_pm_del_add_timer(struct mptcp_sock *msk,
90162306a36Sopenharmony_ci		       const struct mptcp_addr_info *addr, bool check_id);
90262306a36Sopenharmony_cistruct mptcp_pm_add_entry *
90362306a36Sopenharmony_cimptcp_lookup_anno_list_by_saddr(const struct mptcp_sock *msk,
90462306a36Sopenharmony_ci				const struct mptcp_addr_info *addr);
90562306a36Sopenharmony_ciint mptcp_pm_get_flags_and_ifindex_by_id(struct mptcp_sock *msk,
90662306a36Sopenharmony_ci					 unsigned int id,
90762306a36Sopenharmony_ci					 u8 *flags, int *ifindex);
90862306a36Sopenharmony_ciint mptcp_pm_nl_get_flags_and_ifindex_by_id(struct mptcp_sock *msk, unsigned int id,
90962306a36Sopenharmony_ci					    u8 *flags, int *ifindex);
91062306a36Sopenharmony_ciint mptcp_userspace_pm_get_flags_and_ifindex_by_id(struct mptcp_sock *msk,
91162306a36Sopenharmony_ci						   unsigned int id,
91262306a36Sopenharmony_ci						   u8 *flags, int *ifindex);
91362306a36Sopenharmony_ciint mptcp_pm_set_flags(struct net *net, struct nlattr *token,
91462306a36Sopenharmony_ci		       struct mptcp_pm_addr_entry *loc,
91562306a36Sopenharmony_ci		       struct mptcp_pm_addr_entry *rem, u8 bkup);
91662306a36Sopenharmony_ciint mptcp_pm_nl_set_flags(struct net *net, struct mptcp_pm_addr_entry *addr, u8 bkup);
91762306a36Sopenharmony_ciint mptcp_userspace_pm_set_flags(struct net *net, struct nlattr *token,
91862306a36Sopenharmony_ci				 struct mptcp_pm_addr_entry *loc,
91962306a36Sopenharmony_ci				 struct mptcp_pm_addr_entry *rem, u8 bkup);
92062306a36Sopenharmony_ciint mptcp_pm_announce_addr(struct mptcp_sock *msk,
92162306a36Sopenharmony_ci			   const struct mptcp_addr_info *addr,
92262306a36Sopenharmony_ci			   bool echo);
92362306a36Sopenharmony_ciint mptcp_pm_remove_addr(struct mptcp_sock *msk, const struct mptcp_rm_list *rm_list);
92462306a36Sopenharmony_ciint mptcp_pm_remove_subflow(struct mptcp_sock *msk, const struct mptcp_rm_list *rm_list);
92562306a36Sopenharmony_civoid mptcp_pm_remove_addrs(struct mptcp_sock *msk, struct list_head *rm_list);
92662306a36Sopenharmony_civoid mptcp_pm_remove_addrs_and_subflows(struct mptcp_sock *msk,
92762306a36Sopenharmony_ci					struct list_head *rm_list);
92862306a36Sopenharmony_ci
92962306a36Sopenharmony_civoid mptcp_free_local_addr_list(struct mptcp_sock *msk);
93062306a36Sopenharmony_ciint mptcp_nl_cmd_announce(struct sk_buff *skb, struct genl_info *info);
93162306a36Sopenharmony_ciint mptcp_nl_cmd_remove(struct sk_buff *skb, struct genl_info *info);
93262306a36Sopenharmony_ciint mptcp_nl_cmd_sf_create(struct sk_buff *skb, struct genl_info *info);
93362306a36Sopenharmony_ciint mptcp_nl_cmd_sf_destroy(struct sk_buff *skb, struct genl_info *info);
93462306a36Sopenharmony_ci
93562306a36Sopenharmony_civoid mptcp_event(enum mptcp_event_type type, const struct mptcp_sock *msk,
93662306a36Sopenharmony_ci		 const struct sock *ssk, gfp_t gfp);
93762306a36Sopenharmony_civoid mptcp_event_addr_announced(const struct sock *ssk, const struct mptcp_addr_info *info);
93862306a36Sopenharmony_civoid mptcp_event_addr_removed(const struct mptcp_sock *msk, u8 id);
93962306a36Sopenharmony_civoid mptcp_event_pm_listener(const struct sock *ssk,
94062306a36Sopenharmony_ci			     enum mptcp_event_type event);
94162306a36Sopenharmony_cibool mptcp_userspace_pm_active(const struct mptcp_sock *msk);
94262306a36Sopenharmony_ci
94362306a36Sopenharmony_civoid __mptcp_fastopen_gen_msk_ackseq(struct mptcp_sock *msk, struct mptcp_subflow_context *subflow,
94462306a36Sopenharmony_ci				     const struct mptcp_options_received *mp_opt);
94562306a36Sopenharmony_civoid mptcp_fastopen_subflow_synack_set_params(struct mptcp_subflow_context *subflow,
94662306a36Sopenharmony_ci					      struct request_sock *req);
94762306a36Sopenharmony_ci
94862306a36Sopenharmony_cistatic inline bool mptcp_pm_should_add_signal(struct mptcp_sock *msk)
94962306a36Sopenharmony_ci{
95062306a36Sopenharmony_ci	return READ_ONCE(msk->pm.addr_signal) &
95162306a36Sopenharmony_ci		(BIT(MPTCP_ADD_ADDR_SIGNAL) | BIT(MPTCP_ADD_ADDR_ECHO));
95262306a36Sopenharmony_ci}
95362306a36Sopenharmony_ci
95462306a36Sopenharmony_cistatic inline bool mptcp_pm_should_add_signal_addr(struct mptcp_sock *msk)
95562306a36Sopenharmony_ci{
95662306a36Sopenharmony_ci	return READ_ONCE(msk->pm.addr_signal) & BIT(MPTCP_ADD_ADDR_SIGNAL);
95762306a36Sopenharmony_ci}
95862306a36Sopenharmony_ci
95962306a36Sopenharmony_cistatic inline bool mptcp_pm_should_add_signal_echo(struct mptcp_sock *msk)
96062306a36Sopenharmony_ci{
96162306a36Sopenharmony_ci	return READ_ONCE(msk->pm.addr_signal) & BIT(MPTCP_ADD_ADDR_ECHO);
96262306a36Sopenharmony_ci}
96362306a36Sopenharmony_ci
96462306a36Sopenharmony_cistatic inline bool mptcp_pm_should_rm_signal(struct mptcp_sock *msk)
96562306a36Sopenharmony_ci{
96662306a36Sopenharmony_ci	return READ_ONCE(msk->pm.addr_signal) & BIT(MPTCP_RM_ADDR_SIGNAL);
96762306a36Sopenharmony_ci}
96862306a36Sopenharmony_ci
96962306a36Sopenharmony_cistatic inline bool mptcp_pm_is_userspace(const struct mptcp_sock *msk)
97062306a36Sopenharmony_ci{
97162306a36Sopenharmony_ci	return READ_ONCE(msk->pm.pm_type) == MPTCP_PM_TYPE_USERSPACE;
97262306a36Sopenharmony_ci}
97362306a36Sopenharmony_ci
97462306a36Sopenharmony_cistatic inline bool mptcp_pm_is_kernel(const struct mptcp_sock *msk)
97562306a36Sopenharmony_ci{
97662306a36Sopenharmony_ci	return READ_ONCE(msk->pm.pm_type) == MPTCP_PM_TYPE_KERNEL;
97762306a36Sopenharmony_ci}
97862306a36Sopenharmony_ci
97962306a36Sopenharmony_cistatic inline unsigned int mptcp_add_addr_len(int family, bool echo, bool port)
98062306a36Sopenharmony_ci{
98162306a36Sopenharmony_ci	u8 len = TCPOLEN_MPTCP_ADD_ADDR_BASE;
98262306a36Sopenharmony_ci
98362306a36Sopenharmony_ci	if (family == AF_INET6)
98462306a36Sopenharmony_ci		len = TCPOLEN_MPTCP_ADD_ADDR6_BASE;
98562306a36Sopenharmony_ci	if (!echo)
98662306a36Sopenharmony_ci		len += MPTCPOPT_THMAC_LEN;
98762306a36Sopenharmony_ci	/* account for 2 trailing 'nop' options */
98862306a36Sopenharmony_ci	if (port)
98962306a36Sopenharmony_ci		len += TCPOLEN_MPTCP_PORT_LEN + TCPOLEN_MPTCP_PORT_ALIGN;
99062306a36Sopenharmony_ci
99162306a36Sopenharmony_ci	return len;
99262306a36Sopenharmony_ci}
99362306a36Sopenharmony_ci
99462306a36Sopenharmony_cistatic inline int mptcp_rm_addr_len(const struct mptcp_rm_list *rm_list)
99562306a36Sopenharmony_ci{
99662306a36Sopenharmony_ci	if (rm_list->nr == 0 || rm_list->nr > MPTCP_RM_IDS_MAX)
99762306a36Sopenharmony_ci		return -EINVAL;
99862306a36Sopenharmony_ci
99962306a36Sopenharmony_ci	return TCPOLEN_MPTCP_RM_ADDR_BASE + roundup(rm_list->nr - 1, 4) + 1;
100062306a36Sopenharmony_ci}
100162306a36Sopenharmony_ci
100262306a36Sopenharmony_cibool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, const struct sk_buff *skb,
100362306a36Sopenharmony_ci			      unsigned int opt_size, unsigned int remaining,
100462306a36Sopenharmony_ci			      struct mptcp_addr_info *addr, bool *echo,
100562306a36Sopenharmony_ci			      bool *drop_other_suboptions);
100662306a36Sopenharmony_cibool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
100762306a36Sopenharmony_ci			     struct mptcp_rm_list *rm_list);
100862306a36Sopenharmony_ciint mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc);
100962306a36Sopenharmony_ciint mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
101062306a36Sopenharmony_ciint mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
101162306a36Sopenharmony_ci
101262306a36Sopenharmony_cistatic inline u8 subflow_get_local_id(const struct mptcp_subflow_context *subflow)
101362306a36Sopenharmony_ci{
101462306a36Sopenharmony_ci	int local_id = READ_ONCE(subflow->local_id);
101562306a36Sopenharmony_ci
101662306a36Sopenharmony_ci	if (local_id < 0)
101762306a36Sopenharmony_ci		return 0;
101862306a36Sopenharmony_ci	return local_id;
101962306a36Sopenharmony_ci}
102062306a36Sopenharmony_ci
102162306a36Sopenharmony_civoid __init mptcp_pm_nl_init(void);
102262306a36Sopenharmony_civoid mptcp_pm_nl_work(struct mptcp_sock *msk);
102362306a36Sopenharmony_civoid mptcp_pm_nl_rm_subflow_received(struct mptcp_sock *msk,
102462306a36Sopenharmony_ci				     const struct mptcp_rm_list *rm_list);
102562306a36Sopenharmony_ciunsigned int mptcp_pm_get_add_addr_signal_max(const struct mptcp_sock *msk);
102662306a36Sopenharmony_ciunsigned int mptcp_pm_get_add_addr_accept_max(const struct mptcp_sock *msk);
102762306a36Sopenharmony_ciunsigned int mptcp_pm_get_subflows_max(const struct mptcp_sock *msk);
102862306a36Sopenharmony_ciunsigned int mptcp_pm_get_local_addr_max(const struct mptcp_sock *msk);
102962306a36Sopenharmony_ci
103062306a36Sopenharmony_ci/* called under PM lock */
103162306a36Sopenharmony_cistatic inline void __mptcp_pm_close_subflow(struct mptcp_sock *msk)
103262306a36Sopenharmony_ci{
103362306a36Sopenharmony_ci	if (--msk->pm.subflows < mptcp_pm_get_subflows_max(msk))
103462306a36Sopenharmony_ci		WRITE_ONCE(msk->pm.accept_subflow, true);
103562306a36Sopenharmony_ci}
103662306a36Sopenharmony_ci
103762306a36Sopenharmony_cistatic inline void mptcp_pm_close_subflow(struct mptcp_sock *msk)
103862306a36Sopenharmony_ci{
103962306a36Sopenharmony_ci	spin_lock_bh(&msk->pm.lock);
104062306a36Sopenharmony_ci	__mptcp_pm_close_subflow(msk);
104162306a36Sopenharmony_ci	spin_unlock_bh(&msk->pm.lock);
104262306a36Sopenharmony_ci}
104362306a36Sopenharmony_ci
104462306a36Sopenharmony_civoid mptcp_sockopt_sync(struct mptcp_sock *msk, struct sock *ssk);
104562306a36Sopenharmony_civoid mptcp_sockopt_sync_locked(struct mptcp_sock *msk, struct sock *ssk);
104662306a36Sopenharmony_ci
104762306a36Sopenharmony_cistatic inline struct mptcp_ext *mptcp_get_ext(const struct sk_buff *skb)
104862306a36Sopenharmony_ci{
104962306a36Sopenharmony_ci	return (struct mptcp_ext *)skb_ext_find(skb, SKB_EXT_MPTCP);
105062306a36Sopenharmony_ci}
105162306a36Sopenharmony_ci
105262306a36Sopenharmony_civoid mptcp_diag_subflow_init(struct tcp_ulp_ops *ops);
105362306a36Sopenharmony_ci
105462306a36Sopenharmony_cistatic inline bool __mptcp_check_fallback(const struct mptcp_sock *msk)
105562306a36Sopenharmony_ci{
105662306a36Sopenharmony_ci	return test_bit(MPTCP_FALLBACK_DONE, &msk->flags);
105762306a36Sopenharmony_ci}
105862306a36Sopenharmony_ci
105962306a36Sopenharmony_cistatic inline bool mptcp_check_fallback(const struct sock *sk)
106062306a36Sopenharmony_ci{
106162306a36Sopenharmony_ci	struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
106262306a36Sopenharmony_ci	struct mptcp_sock *msk = mptcp_sk(subflow->conn);
106362306a36Sopenharmony_ci
106462306a36Sopenharmony_ci	return __mptcp_check_fallback(msk);
106562306a36Sopenharmony_ci}
106662306a36Sopenharmony_ci
106762306a36Sopenharmony_cistatic inline void __mptcp_do_fallback(struct mptcp_sock *msk)
106862306a36Sopenharmony_ci{
106962306a36Sopenharmony_ci	if (test_bit(MPTCP_FALLBACK_DONE, &msk->flags)) {
107062306a36Sopenharmony_ci		pr_debug("TCP fallback already done (msk=%p)", msk);
107162306a36Sopenharmony_ci		return;
107262306a36Sopenharmony_ci	}
107362306a36Sopenharmony_ci	set_bit(MPTCP_FALLBACK_DONE, &msk->flags);
107462306a36Sopenharmony_ci}
107562306a36Sopenharmony_ci
107662306a36Sopenharmony_cistatic inline void mptcp_do_fallback(struct sock *ssk)
107762306a36Sopenharmony_ci{
107862306a36Sopenharmony_ci	struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk);
107962306a36Sopenharmony_ci	struct sock *sk = subflow->conn;
108062306a36Sopenharmony_ci	struct mptcp_sock *msk;
108162306a36Sopenharmony_ci
108262306a36Sopenharmony_ci	msk = mptcp_sk(sk);
108362306a36Sopenharmony_ci	__mptcp_do_fallback(msk);
108462306a36Sopenharmony_ci	if (READ_ONCE(msk->snd_data_fin_enable) && !(ssk->sk_shutdown & SEND_SHUTDOWN)) {
108562306a36Sopenharmony_ci		gfp_t saved_allocation = ssk->sk_allocation;
108662306a36Sopenharmony_ci
108762306a36Sopenharmony_ci		/* we are in a atomic (BH) scope, override ssk default for data
108862306a36Sopenharmony_ci		 * fin allocation
108962306a36Sopenharmony_ci		 */
109062306a36Sopenharmony_ci		ssk->sk_allocation = GFP_ATOMIC;
109162306a36Sopenharmony_ci		ssk->sk_shutdown |= SEND_SHUTDOWN;
109262306a36Sopenharmony_ci		tcp_shutdown(ssk, SEND_SHUTDOWN);
109362306a36Sopenharmony_ci		ssk->sk_allocation = saved_allocation;
109462306a36Sopenharmony_ci	}
109562306a36Sopenharmony_ci}
109662306a36Sopenharmony_ci
109762306a36Sopenharmony_ci#define pr_fallback(a) pr_debug("%s:fallback to TCP (msk=%p)", __func__, a)
109862306a36Sopenharmony_ci
109962306a36Sopenharmony_cistatic inline bool mptcp_check_infinite_map(struct sk_buff *skb)
110062306a36Sopenharmony_ci{
110162306a36Sopenharmony_ci	struct mptcp_ext *mpext;
110262306a36Sopenharmony_ci
110362306a36Sopenharmony_ci	mpext = skb ? mptcp_get_ext(skb) : NULL;
110462306a36Sopenharmony_ci	if (mpext && mpext->infinite_map)
110562306a36Sopenharmony_ci		return true;
110662306a36Sopenharmony_ci
110762306a36Sopenharmony_ci	return false;
110862306a36Sopenharmony_ci}
110962306a36Sopenharmony_ci
111062306a36Sopenharmony_cistatic inline bool is_active_ssk(struct mptcp_subflow_context *subflow)
111162306a36Sopenharmony_ci{
111262306a36Sopenharmony_ci	return (subflow->request_mptcp || subflow->request_join);
111362306a36Sopenharmony_ci}
111462306a36Sopenharmony_ci
111562306a36Sopenharmony_cistatic inline bool subflow_simultaneous_connect(struct sock *sk)
111662306a36Sopenharmony_ci{
111762306a36Sopenharmony_ci	struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
111862306a36Sopenharmony_ci
111962306a36Sopenharmony_ci	return (1 << sk->sk_state) &
112062306a36Sopenharmony_ci	       (TCPF_ESTABLISHED | TCPF_FIN_WAIT1 | TCPF_FIN_WAIT2 | TCPF_CLOSING) &&
112162306a36Sopenharmony_ci	       is_active_ssk(subflow) &&
112262306a36Sopenharmony_ci	       !subflow->conn_finished;
112362306a36Sopenharmony_ci}
112462306a36Sopenharmony_ci
112562306a36Sopenharmony_ci#ifdef CONFIG_SYN_COOKIES
112662306a36Sopenharmony_civoid subflow_init_req_cookie_join_save(const struct mptcp_subflow_request_sock *subflow_req,
112762306a36Sopenharmony_ci				       struct sk_buff *skb);
112862306a36Sopenharmony_cibool mptcp_token_join_cookie_init_state(struct mptcp_subflow_request_sock *subflow_req,
112962306a36Sopenharmony_ci					struct sk_buff *skb);
113062306a36Sopenharmony_civoid __init mptcp_join_cookie_init(void);
113162306a36Sopenharmony_ci#else
113262306a36Sopenharmony_cistatic inline void
113362306a36Sopenharmony_cisubflow_init_req_cookie_join_save(const struct mptcp_subflow_request_sock *subflow_req,
113462306a36Sopenharmony_ci				  struct sk_buff *skb) {}
113562306a36Sopenharmony_cistatic inline bool
113662306a36Sopenharmony_cimptcp_token_join_cookie_init_state(struct mptcp_subflow_request_sock *subflow_req,
113762306a36Sopenharmony_ci				   struct sk_buff *skb)
113862306a36Sopenharmony_ci{
113962306a36Sopenharmony_ci	return false;
114062306a36Sopenharmony_ci}
114162306a36Sopenharmony_ci
114262306a36Sopenharmony_cistatic inline void mptcp_join_cookie_init(void) {}
114362306a36Sopenharmony_ci#endif
114462306a36Sopenharmony_ci
114562306a36Sopenharmony_ci#endif /* __MPTCP_PROTOCOL_H */
1146