xref: /openbmc/linux/include/net/mptcp.h (revision 648ef4b88673dadb8463bf0d4b10fbf33d55def8)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Multipath TCP
4  *
5  * Copyright (c) 2017 - 2019, Intel Corporation.
6  */
7 
8 #ifndef __NET_MPTCP_H
9 #define __NET_MPTCP_H
10 
11 #include <linux/skbuff.h>
12 #include <linux/tcp.h>
13 #include <linux/types.h>
14 
15 /* MPTCP sk_buff extension data */
16 struct mptcp_ext {
17 	u64		data_ack;
18 	u64		data_seq;
19 	u32		subflow_seq;
20 	u16		data_len;
21 	u8		use_map:1,
22 			dsn64:1,
23 			data_fin:1,
24 			use_ack:1,
25 			ack64:1,
26 			__unused:3;
27 	/* one byte hole */
28 };
29 
30 struct mptcp_out_options {
31 #if IS_ENABLED(CONFIG_MPTCP)
32 	u16 suboptions;
33 	u64 sndr_key;
34 	u64 rcvr_key;
35 	struct mptcp_ext ext_copy;
36 #endif
37 };
38 
39 #ifdef CONFIG_MPTCP
40 
41 void mptcp_init(void);
42 
43 static inline bool sk_is_mptcp(const struct sock *sk)
44 {
45 	return tcp_sk(sk)->is_mptcp;
46 }
47 
48 static inline bool rsk_is_mptcp(const struct request_sock *req)
49 {
50 	return tcp_rsk(req)->is_mptcp;
51 }
52 
53 void mptcp_parse_option(const unsigned char *ptr, int opsize,
54 			struct tcp_options_received *opt_rx);
55 bool mptcp_syn_options(struct sock *sk, unsigned int *size,
56 		       struct mptcp_out_options *opts);
57 void mptcp_rcv_synsent(struct sock *sk);
58 bool mptcp_synack_options(const struct request_sock *req, unsigned int *size,
59 			  struct mptcp_out_options *opts);
60 bool mptcp_established_options(struct sock *sk, struct sk_buff *skb,
61 			       unsigned int *size, unsigned int remaining,
62 			       struct mptcp_out_options *opts);
63 void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb,
64 			    struct tcp_options_received *opt_rx);
65 
66 void mptcp_write_options(__be32 *ptr, struct mptcp_out_options *opts);
67 
68 /* move the skb extension owership, with the assumption that 'to' is
69  * newly allocated
70  */
71 static inline void mptcp_skb_ext_move(struct sk_buff *to,
72 				      struct sk_buff *from)
73 {
74 	if (!skb_ext_exist(from, SKB_EXT_MPTCP))
75 		return;
76 
77 	if (WARN_ON_ONCE(to->active_extensions))
78 		skb_ext_put(to);
79 
80 	to->active_extensions = from->active_extensions;
81 	to->extensions = from->extensions;
82 	from->active_extensions = 0;
83 }
84 
85 static inline bool mptcp_ext_matches(const struct mptcp_ext *to_ext,
86 				     const struct mptcp_ext *from_ext)
87 {
88 	/* MPTCP always clears the ext when adding it to the skb, so
89 	 * holes do not bother us here
90 	 */
91 	return !from_ext ||
92 	       (to_ext && from_ext &&
93 	        !memcmp(from_ext, to_ext, sizeof(struct mptcp_ext)));
94 }
95 
96 /* check if skbs can be collapsed.
97  * MPTCP collapse is allowed if neither @to or @from carry an mptcp data
98  * mapping, or if the extension of @to is the same as @from.
99  * Collapsing is not possible if @to lacks an extension, but @from carries one.
100  */
101 static inline bool mptcp_skb_can_collapse(const struct sk_buff *to,
102 					  const struct sk_buff *from)
103 {
104 	return mptcp_ext_matches(skb_ext_find(to, SKB_EXT_MPTCP),
105 				 skb_ext_find(from, SKB_EXT_MPTCP));
106 }
107 
108 #else
109 
110 static inline void mptcp_init(void)
111 {
112 }
113 
114 static inline bool sk_is_mptcp(const struct sock *sk)
115 {
116 	return false;
117 }
118 
119 static inline bool rsk_is_mptcp(const struct request_sock *req)
120 {
121 	return false;
122 }
123 
124 static inline void mptcp_parse_option(const unsigned char *ptr, int opsize,
125 				      struct tcp_options_received *opt_rx)
126 {
127 }
128 
129 static inline bool mptcp_syn_options(struct sock *sk, unsigned int *size,
130 				     struct mptcp_out_options *opts)
131 {
132 	return false;
133 }
134 
135 static inline void mptcp_rcv_synsent(struct sock *sk)
136 {
137 }
138 
139 static inline bool mptcp_synack_options(const struct request_sock *req,
140 					unsigned int *size,
141 					struct mptcp_out_options *opts)
142 {
143 	return false;
144 }
145 
146 static inline bool mptcp_established_options(struct sock *sk,
147 					     struct sk_buff *skb,
148 					     unsigned int *size,
149 					     unsigned int remaining,
150 					     struct mptcp_out_options *opts)
151 {
152 	return false;
153 }
154 
155 static inline void mptcp_incoming_options(struct sock *sk,
156 					  struct sk_buff *skb,
157 					  struct tcp_options_received *opt_rx)
158 {
159 }
160 
161 static inline void mptcp_skb_ext_move(struct sk_buff *to,
162 				      const struct sk_buff *from)
163 {
164 }
165 
166 static inline bool mptcp_skb_can_collapse(const struct sk_buff *to,
167 					  const struct sk_buff *from)
168 {
169 	return true;
170 }
171 
172 #endif /* CONFIG_MPTCP */
173 
174 void mptcp_handle_ipv6_mapped(struct sock *sk, bool mapped);
175 
176 #if IS_ENABLED(CONFIG_MPTCP_IPV6)
177 int mptcpv6_init(void);
178 #elif IS_ENABLED(CONFIG_IPV6)
179 static inline int mptcpv6_init(void)
180 {
181 	return 0;
182 }
183 #endif
184 
185 #endif /* __NET_MPTCP_H */
186