xref: /linux/include/net/mptcp.h (revision c83a47e5)
13ee17bc7SMat Martineau /* SPDX-License-Identifier: GPL-2.0 */
23ee17bc7SMat Martineau /*
33ee17bc7SMat Martineau  * Multipath TCP
43ee17bc7SMat Martineau  *
53ee17bc7SMat Martineau  * Copyright (c) 2017 - 2019, Intel Corporation.
63ee17bc7SMat Martineau  */
73ee17bc7SMat Martineau 
83ee17bc7SMat Martineau #ifndef __NET_MPTCP_H
93ee17bc7SMat Martineau #define __NET_MPTCP_H
103ee17bc7SMat Martineau 
1185712484SMat Martineau #include <linux/skbuff.h>
12eda7acddSPeter Krystad #include <linux/tcp.h>
133ee17bc7SMat Martineau #include <linux/types.h>
143ee17bc7SMat Martineau 
15fc518953SFlorian Westphal struct seq_file;
16fc518953SFlorian Westphal 
173ee17bc7SMat Martineau /* MPTCP sk_buff extension data */
183ee17bc7SMat Martineau struct mptcp_ext {
19a0c1d0eaSChristoph Paasch 	union {
203ee17bc7SMat Martineau 		u64	data_ack;
21a0c1d0eaSChristoph Paasch 		u32	data_ack32;
22a0c1d0eaSChristoph Paasch 	};
233ee17bc7SMat Martineau 	u64		data_seq;
243ee17bc7SMat Martineau 	u32		subflow_seq;
253ee17bc7SMat Martineau 	u16		data_len;
263ee17bc7SMat Martineau 	u8		use_map:1,
273ee17bc7SMat Martineau 			dsn64:1,
283ee17bc7SMat Martineau 			data_fin:1,
293ee17bc7SMat Martineau 			use_ack:1,
303ee17bc7SMat Martineau 			ack64:1,
31cc7972eaSChristoph Paasch 			mpc_map:1,
32cc7972eaSChristoph Paasch 			__unused:2;
333ee17bc7SMat Martineau 	/* one byte hole */
343ee17bc7SMat Martineau };
353ee17bc7SMat Martineau 
36eda7acddSPeter Krystad struct mptcp_out_options {
37eda7acddSPeter Krystad #if IS_ENABLED(CONFIG_MPTCP)
38eda7acddSPeter Krystad 	u16 suboptions;
39eda7acddSPeter Krystad 	u64 sndr_key;
40eda7acddSPeter Krystad 	u64 rcvr_key;
413df523abSPeter Krystad 	union {
423df523abSPeter Krystad 		struct in_addr addr;
433df523abSPeter Krystad #if IS_ENABLED(CONFIG_MPTCP_IPV6)
443df523abSPeter Krystad 		struct in6_addr addr6;
453df523abSPeter Krystad #endif
463df523abSPeter Krystad 	};
473df523abSPeter Krystad 	u8 addr_id;
483df523abSPeter Krystad 	u64 ahmac;
493df523abSPeter Krystad 	u8 rm_id;
50f296234cSPeter Krystad 	u8 join_id;
51f296234cSPeter Krystad 	u8 backup;
52f296234cSPeter Krystad 	u32 nonce;
53f296234cSPeter Krystad 	u64 thmac;
54ec3edaa7SPeter Krystad 	u32 token;
55ec3edaa7SPeter Krystad 	u8 hmac[20];
566d0060f6SMat Martineau 	struct mptcp_ext ext_copy;
57eda7acddSPeter Krystad #endif
58eda7acddSPeter Krystad };
59eda7acddSPeter Krystad 
6085712484SMat Martineau #ifdef CONFIG_MPTCP
6108b8d080SFlorian Westphal extern struct request_sock_ops mptcp_subflow_request_sock_ops;
6285712484SMat Martineau 
63f870fa0bSMat Martineau void mptcp_init(void);
64f870fa0bSMat Martineau 
65cec37a6eSPeter Krystad static inline bool sk_is_mptcp(const struct sock *sk)
66cec37a6eSPeter Krystad {
67cec37a6eSPeter Krystad 	return tcp_sk(sk)->is_mptcp;
68cec37a6eSPeter Krystad }
69cec37a6eSPeter Krystad 
70cec37a6eSPeter Krystad static inline bool rsk_is_mptcp(const struct request_sock *req)
71cec37a6eSPeter Krystad {
72cec37a6eSPeter Krystad 	return tcp_rsk(req)->is_mptcp;
73cec37a6eSPeter Krystad }
74cec37a6eSPeter Krystad 
7590bf4513SPaolo Abeni static inline bool rsk_drop_req(const struct request_sock *req)
7690bf4513SPaolo Abeni {
7790bf4513SPaolo Abeni 	return tcp_rsk(req)->is_mptcp && tcp_rsk(req)->drop_req;
7890bf4513SPaolo Abeni }
7990bf4513SPaolo Abeni 
80071c8ed6SFlorian Westphal void mptcp_space(const struct sock *ssk, int *space, int *full_space);
81cc7972eaSChristoph Paasch bool mptcp_syn_options(struct sock *sk, const struct sk_buff *skb,
82cc7972eaSChristoph Paasch 		       unsigned int *size, struct mptcp_out_options *opts);
83cec37a6eSPeter Krystad bool mptcp_synack_options(const struct request_sock *req, unsigned int *size,
84cec37a6eSPeter Krystad 			  struct mptcp_out_options *opts);
85cec37a6eSPeter Krystad bool mptcp_established_options(struct sock *sk, struct sk_buff *skb,
86cec37a6eSPeter Krystad 			       unsigned int *size, unsigned int remaining,
87cec37a6eSPeter Krystad 			       struct mptcp_out_options *opts);
88648ef4b8SMat Martineau void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb,
89648ef4b8SMat Martineau 			    struct tcp_options_received *opt_rx);
90cec37a6eSPeter Krystad 
91eda7acddSPeter Krystad void mptcp_write_options(__be32 *ptr, struct mptcp_out_options *opts);
92eda7acddSPeter Krystad 
9385712484SMat Martineau /* move the skb extension owership, with the assumption that 'to' is
9485712484SMat Martineau  * newly allocated
9585712484SMat Martineau  */
9685712484SMat Martineau static inline void mptcp_skb_ext_move(struct sk_buff *to,
9785712484SMat Martineau 				      struct sk_buff *from)
9885712484SMat Martineau {
9985712484SMat Martineau 	if (!skb_ext_exist(from, SKB_EXT_MPTCP))
10085712484SMat Martineau 		return;
10185712484SMat Martineau 
10285712484SMat Martineau 	if (WARN_ON_ONCE(to->active_extensions))
10385712484SMat Martineau 		skb_ext_put(to);
10485712484SMat Martineau 
10585712484SMat Martineau 	to->active_extensions = from->active_extensions;
10685712484SMat Martineau 	to->extensions = from->extensions;
10785712484SMat Martineau 	from->active_extensions = 0;
10885712484SMat Martineau }
10985712484SMat Martineau 
11085712484SMat Martineau static inline bool mptcp_ext_matches(const struct mptcp_ext *to_ext,
11185712484SMat Martineau 				     const struct mptcp_ext *from_ext)
11285712484SMat Martineau {
11385712484SMat Martineau 	/* MPTCP always clears the ext when adding it to the skb, so
11485712484SMat Martineau 	 * holes do not bother us here
11585712484SMat Martineau 	 */
11685712484SMat Martineau 	return !from_ext ||
11785712484SMat Martineau 	       (to_ext && from_ext &&
11885712484SMat Martineau 	        !memcmp(from_ext, to_ext, sizeof(struct mptcp_ext)));
11985712484SMat Martineau }
12085712484SMat Martineau 
12185712484SMat Martineau /* check if skbs can be collapsed.
12285712484SMat Martineau  * MPTCP collapse is allowed if neither @to or @from carry an mptcp data
12385712484SMat Martineau  * mapping, or if the extension of @to is the same as @from.
12485712484SMat Martineau  * Collapsing is not possible if @to lacks an extension, but @from carries one.
12585712484SMat Martineau  */
12685712484SMat Martineau static inline bool mptcp_skb_can_collapse(const struct sk_buff *to,
12785712484SMat Martineau 					  const struct sk_buff *from)
12885712484SMat Martineau {
12985712484SMat Martineau 	return mptcp_ext_matches(skb_ext_find(to, SKB_EXT_MPTCP),
13085712484SMat Martineau 				 skb_ext_find(from, SKB_EXT_MPTCP));
13185712484SMat Martineau }
13285712484SMat Martineau 
133fc518953SFlorian Westphal void mptcp_seq_show(struct seq_file *seq);
134*c83a47e5SFlorian Westphal int mptcp_subflow_init_cookie_req(struct request_sock *req,
135*c83a47e5SFlorian Westphal 				  const struct sock *sk_listener,
136*c83a47e5SFlorian Westphal 				  struct sk_buff *skb);
13785712484SMat Martineau #else
13885712484SMat Martineau 
139f870fa0bSMat Martineau static inline void mptcp_init(void)
140f870fa0bSMat Martineau {
141f870fa0bSMat Martineau }
142f870fa0bSMat Martineau 
143cec37a6eSPeter Krystad static inline bool sk_is_mptcp(const struct sock *sk)
144cec37a6eSPeter Krystad {
145cec37a6eSPeter Krystad 	return false;
146cec37a6eSPeter Krystad }
147cec37a6eSPeter Krystad 
148cec37a6eSPeter Krystad static inline bool rsk_is_mptcp(const struct request_sock *req)
149cec37a6eSPeter Krystad {
150cec37a6eSPeter Krystad 	return false;
151cec37a6eSPeter Krystad }
152cec37a6eSPeter Krystad 
15390bf4513SPaolo Abeni static inline bool rsk_drop_req(const struct request_sock *req)
15490bf4513SPaolo Abeni {
15590bf4513SPaolo Abeni 	return false;
15690bf4513SPaolo Abeni }
15790bf4513SPaolo Abeni 
158cc7972eaSChristoph Paasch static inline void mptcp_parse_option(const struct sk_buff *skb,
159cc7972eaSChristoph Paasch 				      const unsigned char *ptr, int opsize,
160eda7acddSPeter Krystad 				      struct tcp_options_received *opt_rx)
161eda7acddSPeter Krystad {
162eda7acddSPeter Krystad }
163eda7acddSPeter Krystad 
164cc7972eaSChristoph Paasch static inline bool mptcp_syn_options(struct sock *sk, const struct sk_buff *skb,
165cc7972eaSChristoph Paasch 				     unsigned int *size,
166cec37a6eSPeter Krystad 				     struct mptcp_out_options *opts)
167cec37a6eSPeter Krystad {
168cec37a6eSPeter Krystad 	return false;
169cec37a6eSPeter Krystad }
170cec37a6eSPeter Krystad 
171cec37a6eSPeter Krystad static inline bool mptcp_synack_options(const struct request_sock *req,
172cec37a6eSPeter Krystad 					unsigned int *size,
173cec37a6eSPeter Krystad 					struct mptcp_out_options *opts)
174cec37a6eSPeter Krystad {
175cec37a6eSPeter Krystad 	return false;
176cec37a6eSPeter Krystad }
177cec37a6eSPeter Krystad 
178cec37a6eSPeter Krystad static inline bool mptcp_established_options(struct sock *sk,
179cec37a6eSPeter Krystad 					     struct sk_buff *skb,
180cec37a6eSPeter Krystad 					     unsigned int *size,
181cec37a6eSPeter Krystad 					     unsigned int remaining,
182cec37a6eSPeter Krystad 					     struct mptcp_out_options *opts)
183cec37a6eSPeter Krystad {
184cec37a6eSPeter Krystad 	return false;
185cec37a6eSPeter Krystad }
186cec37a6eSPeter Krystad 
187648ef4b8SMat Martineau static inline void mptcp_incoming_options(struct sock *sk,
188648ef4b8SMat Martineau 					  struct sk_buff *skb,
189648ef4b8SMat Martineau 					  struct tcp_options_received *opt_rx)
190648ef4b8SMat Martineau {
191648ef4b8SMat Martineau }
192648ef4b8SMat Martineau 
19385712484SMat Martineau static inline void mptcp_skb_ext_move(struct sk_buff *to,
19485712484SMat Martineau 				      const struct sk_buff *from)
19585712484SMat Martineau {
19685712484SMat Martineau }
19785712484SMat Martineau 
19885712484SMat Martineau static inline bool mptcp_skb_can_collapse(const struct sk_buff *to,
19985712484SMat Martineau 					  const struct sk_buff *from)
20085712484SMat Martineau {
20185712484SMat Martineau 	return true;
20285712484SMat Martineau }
20385712484SMat Martineau 
204071c8ed6SFlorian Westphal static inline void mptcp_space(const struct sock *ssk, int *s, int *fs) { }
205fc518953SFlorian Westphal static inline void mptcp_seq_show(struct seq_file *seq) { }
206*c83a47e5SFlorian Westphal 
207*c83a47e5SFlorian Westphal static inline int mptcp_subflow_init_cookie_req(struct request_sock *req,
208*c83a47e5SFlorian Westphal 						const struct sock *sk_listener,
209*c83a47e5SFlorian Westphal 						struct sk_buff *skb)
210*c83a47e5SFlorian Westphal {
211*c83a47e5SFlorian Westphal 	return 0; /* TCP fallback */
212*c83a47e5SFlorian Westphal }
21385712484SMat Martineau #endif /* CONFIG_MPTCP */
214f870fa0bSMat Martineau 
215f870fa0bSMat Martineau #if IS_ENABLED(CONFIG_MPTCP_IPV6)
216f870fa0bSMat Martineau int mptcpv6_init(void);
21731484d56SGeert Uytterhoeven void mptcpv6_handle_mapped(struct sock *sk, bool mapped);
218f870fa0bSMat Martineau #elif IS_ENABLED(CONFIG_IPV6)
21931484d56SGeert Uytterhoeven static inline int mptcpv6_init(void) { return 0; }
22031484d56SGeert Uytterhoeven static inline void mptcpv6_handle_mapped(struct sock *sk, bool mapped) { }
221f870fa0bSMat Martineau #endif
222f870fa0bSMat Martineau 
2233ee17bc7SMat Martineau #endif /* __NET_MPTCP_H */
224