xref: /linux/include/net/mptcp.h (revision cec37a6e)
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 
153ee17bc7SMat Martineau /* MPTCP sk_buff extension data */
163ee17bc7SMat Martineau struct mptcp_ext {
173ee17bc7SMat Martineau 	u64		data_ack;
183ee17bc7SMat Martineau 	u64		data_seq;
193ee17bc7SMat Martineau 	u32		subflow_seq;
203ee17bc7SMat Martineau 	u16		data_len;
213ee17bc7SMat Martineau 	u8		use_map:1,
223ee17bc7SMat Martineau 			dsn64:1,
233ee17bc7SMat Martineau 			data_fin:1,
243ee17bc7SMat Martineau 			use_ack:1,
253ee17bc7SMat Martineau 			ack64:1,
263ee17bc7SMat Martineau 			__unused:3;
273ee17bc7SMat Martineau 	/* one byte hole */
283ee17bc7SMat Martineau };
293ee17bc7SMat Martineau 
30eda7acddSPeter Krystad struct mptcp_out_options {
31eda7acddSPeter Krystad #if IS_ENABLED(CONFIG_MPTCP)
32eda7acddSPeter Krystad 	u16 suboptions;
33eda7acddSPeter Krystad 	u64 sndr_key;
34eda7acddSPeter Krystad 	u64 rcvr_key;
35eda7acddSPeter Krystad #endif
36eda7acddSPeter Krystad };
37eda7acddSPeter Krystad 
3885712484SMat Martineau #ifdef CONFIG_MPTCP
3985712484SMat Martineau 
40f870fa0bSMat Martineau void mptcp_init(void);
41f870fa0bSMat Martineau 
42*cec37a6eSPeter Krystad static inline bool sk_is_mptcp(const struct sock *sk)
43*cec37a6eSPeter Krystad {
44*cec37a6eSPeter Krystad 	return tcp_sk(sk)->is_mptcp;
45*cec37a6eSPeter Krystad }
46*cec37a6eSPeter Krystad 
47*cec37a6eSPeter Krystad static inline bool rsk_is_mptcp(const struct request_sock *req)
48*cec37a6eSPeter Krystad {
49*cec37a6eSPeter Krystad 	return tcp_rsk(req)->is_mptcp;
50*cec37a6eSPeter Krystad }
51*cec37a6eSPeter Krystad 
52eda7acddSPeter Krystad void mptcp_parse_option(const unsigned char *ptr, int opsize,
53eda7acddSPeter Krystad 			struct tcp_options_received *opt_rx);
54*cec37a6eSPeter Krystad bool mptcp_syn_options(struct sock *sk, unsigned int *size,
55*cec37a6eSPeter Krystad 		       struct mptcp_out_options *opts);
56*cec37a6eSPeter Krystad void mptcp_rcv_synsent(struct sock *sk);
57*cec37a6eSPeter Krystad bool mptcp_synack_options(const struct request_sock *req, unsigned int *size,
58*cec37a6eSPeter Krystad 			  struct mptcp_out_options *opts);
59*cec37a6eSPeter Krystad bool mptcp_established_options(struct sock *sk, struct sk_buff *skb,
60*cec37a6eSPeter Krystad 			       unsigned int *size, unsigned int remaining,
61*cec37a6eSPeter Krystad 			       struct mptcp_out_options *opts);
62*cec37a6eSPeter Krystad 
63eda7acddSPeter Krystad void mptcp_write_options(__be32 *ptr, struct mptcp_out_options *opts);
64eda7acddSPeter Krystad 
6585712484SMat Martineau /* move the skb extension owership, with the assumption that 'to' is
6685712484SMat Martineau  * newly allocated
6785712484SMat Martineau  */
6885712484SMat Martineau static inline void mptcp_skb_ext_move(struct sk_buff *to,
6985712484SMat Martineau 				      struct sk_buff *from)
7085712484SMat Martineau {
7185712484SMat Martineau 	if (!skb_ext_exist(from, SKB_EXT_MPTCP))
7285712484SMat Martineau 		return;
7385712484SMat Martineau 
7485712484SMat Martineau 	if (WARN_ON_ONCE(to->active_extensions))
7585712484SMat Martineau 		skb_ext_put(to);
7685712484SMat Martineau 
7785712484SMat Martineau 	to->active_extensions = from->active_extensions;
7885712484SMat Martineau 	to->extensions = from->extensions;
7985712484SMat Martineau 	from->active_extensions = 0;
8085712484SMat Martineau }
8185712484SMat Martineau 
8285712484SMat Martineau static inline bool mptcp_ext_matches(const struct mptcp_ext *to_ext,
8385712484SMat Martineau 				     const struct mptcp_ext *from_ext)
8485712484SMat Martineau {
8585712484SMat Martineau 	/* MPTCP always clears the ext when adding it to the skb, so
8685712484SMat Martineau 	 * holes do not bother us here
8785712484SMat Martineau 	 */
8885712484SMat Martineau 	return !from_ext ||
8985712484SMat Martineau 	       (to_ext && from_ext &&
9085712484SMat Martineau 	        !memcmp(from_ext, to_ext, sizeof(struct mptcp_ext)));
9185712484SMat Martineau }
9285712484SMat Martineau 
9385712484SMat Martineau /* check if skbs can be collapsed.
9485712484SMat Martineau  * MPTCP collapse is allowed if neither @to or @from carry an mptcp data
9585712484SMat Martineau  * mapping, or if the extension of @to is the same as @from.
9685712484SMat Martineau  * Collapsing is not possible if @to lacks an extension, but @from carries one.
9785712484SMat Martineau  */
9885712484SMat Martineau static inline bool mptcp_skb_can_collapse(const struct sk_buff *to,
9985712484SMat Martineau 					  const struct sk_buff *from)
10085712484SMat Martineau {
10185712484SMat Martineau 	return mptcp_ext_matches(skb_ext_find(to, SKB_EXT_MPTCP),
10285712484SMat Martineau 				 skb_ext_find(from, SKB_EXT_MPTCP));
10385712484SMat Martineau }
10485712484SMat Martineau 
10585712484SMat Martineau #else
10685712484SMat Martineau 
107f870fa0bSMat Martineau static inline void mptcp_init(void)
108f870fa0bSMat Martineau {
109f870fa0bSMat Martineau }
110f870fa0bSMat Martineau 
111*cec37a6eSPeter Krystad static inline bool sk_is_mptcp(const struct sock *sk)
112*cec37a6eSPeter Krystad {
113*cec37a6eSPeter Krystad 	return false;
114*cec37a6eSPeter Krystad }
115*cec37a6eSPeter Krystad 
116*cec37a6eSPeter Krystad static inline bool rsk_is_mptcp(const struct request_sock *req)
117*cec37a6eSPeter Krystad {
118*cec37a6eSPeter Krystad 	return false;
119*cec37a6eSPeter Krystad }
120*cec37a6eSPeter Krystad 
121eda7acddSPeter Krystad static inline void mptcp_parse_option(const unsigned char *ptr, int opsize,
122eda7acddSPeter Krystad 				      struct tcp_options_received *opt_rx)
123eda7acddSPeter Krystad {
124eda7acddSPeter Krystad }
125eda7acddSPeter Krystad 
126*cec37a6eSPeter Krystad static inline bool mptcp_syn_options(struct sock *sk, unsigned int *size,
127*cec37a6eSPeter Krystad 				     struct mptcp_out_options *opts)
128*cec37a6eSPeter Krystad {
129*cec37a6eSPeter Krystad 	return false;
130*cec37a6eSPeter Krystad }
131*cec37a6eSPeter Krystad 
132*cec37a6eSPeter Krystad static inline void mptcp_rcv_synsent(struct sock *sk)
133*cec37a6eSPeter Krystad {
134*cec37a6eSPeter Krystad }
135*cec37a6eSPeter Krystad 
136*cec37a6eSPeter Krystad static inline bool mptcp_synack_options(const struct request_sock *req,
137*cec37a6eSPeter Krystad 					unsigned int *size,
138*cec37a6eSPeter Krystad 					struct mptcp_out_options *opts)
139*cec37a6eSPeter Krystad {
140*cec37a6eSPeter Krystad 	return false;
141*cec37a6eSPeter Krystad }
142*cec37a6eSPeter Krystad 
143*cec37a6eSPeter Krystad static inline bool mptcp_established_options(struct sock *sk,
144*cec37a6eSPeter Krystad 					     struct sk_buff *skb,
145*cec37a6eSPeter Krystad 					     unsigned int *size,
146*cec37a6eSPeter Krystad 					     unsigned int remaining,
147*cec37a6eSPeter Krystad 					     struct mptcp_out_options *opts)
148*cec37a6eSPeter Krystad {
149*cec37a6eSPeter Krystad 	return false;
150*cec37a6eSPeter Krystad }
151*cec37a6eSPeter Krystad 
15285712484SMat Martineau static inline void mptcp_skb_ext_move(struct sk_buff *to,
15385712484SMat Martineau 				      const struct sk_buff *from)
15485712484SMat Martineau {
15585712484SMat Martineau }
15685712484SMat Martineau 
15785712484SMat Martineau static inline bool mptcp_skb_can_collapse(const struct sk_buff *to,
15885712484SMat Martineau 					  const struct sk_buff *from)
15985712484SMat Martineau {
16085712484SMat Martineau 	return true;
16185712484SMat Martineau }
16285712484SMat Martineau 
16385712484SMat Martineau #endif /* CONFIG_MPTCP */
164f870fa0bSMat Martineau 
165*cec37a6eSPeter Krystad void mptcp_handle_ipv6_mapped(struct sock *sk, bool mapped);
166*cec37a6eSPeter Krystad 
167f870fa0bSMat Martineau #if IS_ENABLED(CONFIG_MPTCP_IPV6)
168f870fa0bSMat Martineau int mptcpv6_init(void);
169f870fa0bSMat Martineau #elif IS_ENABLED(CONFIG_IPV6)
170f870fa0bSMat Martineau static inline int mptcpv6_init(void)
171f870fa0bSMat Martineau {
172f870fa0bSMat Martineau 	return 0;
173f870fa0bSMat Martineau }
174f870fa0bSMat Martineau #endif
175f870fa0bSMat Martineau 
1763ee17bc7SMat Martineau #endif /* __NET_MPTCP_H */
177