Line data Source code
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 : struct seq_file;
16 :
17 : /* MPTCP sk_buff extension data */
18 : struct mptcp_ext {
19 : union {
20 : u64 data_ack;
21 : u32 data_ack32;
22 : };
23 : u64 data_seq;
24 : u32 subflow_seq;
25 : u16 data_len;
26 : u8 use_map:1,
27 : dsn64:1,
28 : data_fin:1,
29 : use_ack:1,
30 : ack64:1,
31 : mpc_map:1,
32 : frozen:1,
33 : __unused:1;
34 : /* one byte hole */
35 : };
36 :
37 : struct mptcp_out_options {
38 : #if IS_ENABLED(CONFIG_MPTCP)
39 : u16 suboptions;
40 : u64 sndr_key;
41 : u64 rcvr_key;
42 : union {
43 : struct in_addr addr;
44 : #if IS_ENABLED(CONFIG_MPTCP_IPV6)
45 : struct in6_addr addr6;
46 : #endif
47 : };
48 : u8 addr_id;
49 : u16 port;
50 : u64 ahmac;
51 : u8 rm_id;
52 : u8 join_id;
53 : u8 backup;
54 : u32 nonce;
55 : u64 thmac;
56 : u32 token;
57 : u8 hmac[20];
58 : struct mptcp_ext ext_copy;
59 : #endif
60 : };
61 :
62 : #ifdef CONFIG_MPTCP
63 : extern struct request_sock_ops mptcp_subflow_request_sock_ops;
64 :
65 : void mptcp_init(void);
66 :
67 : static inline bool sk_is_mptcp(const struct sock *sk)
68 : {
69 : return tcp_sk(sk)->is_mptcp;
70 : }
71 :
72 : static inline bool rsk_is_mptcp(const struct request_sock *req)
73 : {
74 : return tcp_rsk(req)->is_mptcp;
75 : }
76 :
77 : static inline bool rsk_drop_req(const struct request_sock *req)
78 : {
79 : return tcp_rsk(req)->is_mptcp && tcp_rsk(req)->drop_req;
80 : }
81 :
82 : void mptcp_space(const struct sock *ssk, int *space, int *full_space);
83 : bool mptcp_syn_options(struct sock *sk, const struct sk_buff *skb,
84 : unsigned int *size, struct mptcp_out_options *opts);
85 : bool mptcp_synack_options(const struct request_sock *req, unsigned int *size,
86 : struct mptcp_out_options *opts);
87 : bool mptcp_established_options(struct sock *sk, struct sk_buff *skb,
88 : unsigned int *size, unsigned int remaining,
89 : struct mptcp_out_options *opts);
90 : void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb);
91 :
92 : void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
93 : struct mptcp_out_options *opts);
94 :
95 : /* move the skb extension owership, with the assumption that 'to' is
96 : * newly allocated
97 : */
98 : static inline void mptcp_skb_ext_move(struct sk_buff *to,
99 : struct sk_buff *from)
100 : {
101 : if (!skb_ext_exist(from, SKB_EXT_MPTCP))
102 : return;
103 :
104 : if (WARN_ON_ONCE(to->active_extensions))
105 : skb_ext_put(to);
106 :
107 : to->active_extensions = from->active_extensions;
108 : to->extensions = from->extensions;
109 : from->active_extensions = 0;
110 : }
111 :
112 : static inline void mptcp_skb_ext_copy(struct sk_buff *to,
113 : struct sk_buff *from)
114 : {
115 : struct mptcp_ext *from_ext;
116 :
117 : from_ext = skb_ext_find(from, SKB_EXT_MPTCP);
118 : if (!from_ext)
119 : return;
120 :
121 : from_ext->frozen = 1;
122 : skb_ext_copy(to, from);
123 : }
124 :
125 : static inline bool mptcp_ext_matches(const struct mptcp_ext *to_ext,
126 : const struct mptcp_ext *from_ext)
127 : {
128 : /* MPTCP always clears the ext when adding it to the skb, so
129 : * holes do not bother us here
130 : */
131 : return !from_ext ||
132 : (to_ext && from_ext &&
133 : !memcmp(from_ext, to_ext, sizeof(struct mptcp_ext)));
134 : }
135 :
136 : /* check if skbs can be collapsed.
137 : * MPTCP collapse is allowed if neither @to or @from carry an mptcp data
138 : * mapping, or if the extension of @to is the same as @from.
139 : * Collapsing is not possible if @to lacks an extension, but @from carries one.
140 : */
141 : static inline bool mptcp_skb_can_collapse(const struct sk_buff *to,
142 : const struct sk_buff *from)
143 : {
144 : return mptcp_ext_matches(skb_ext_find(to, SKB_EXT_MPTCP),
145 : skb_ext_find(from, SKB_EXT_MPTCP));
146 : }
147 :
148 : void mptcp_seq_show(struct seq_file *seq);
149 : int mptcp_subflow_init_cookie_req(struct request_sock *req,
150 : const struct sock *sk_listener,
151 : struct sk_buff *skb);
152 : #else
153 :
154 1 : static inline void mptcp_init(void)
155 : {
156 1 : }
157 :
158 1405 : static inline bool sk_is_mptcp(const struct sock *sk)
159 : {
160 1405 : return false;
161 : }
162 :
163 4 : static inline bool rsk_is_mptcp(const struct request_sock *req)
164 : {
165 4 : return false;
166 : }
167 :
168 : static inline bool rsk_drop_req(const struct request_sock *req)
169 : {
170 : return false;
171 : }
172 :
173 : static inline void mptcp_parse_option(const struct sk_buff *skb,
174 : const unsigned char *ptr, int opsize,
175 : struct tcp_options_received *opt_rx)
176 : {
177 : }
178 :
179 : static inline bool mptcp_syn_options(struct sock *sk, const struct sk_buff *skb,
180 : unsigned int *size,
181 : struct mptcp_out_options *opts)
182 : {
183 : return false;
184 : }
185 :
186 : static inline bool mptcp_synack_options(const struct request_sock *req,
187 : unsigned int *size,
188 : struct mptcp_out_options *opts)
189 : {
190 : return false;
191 : }
192 :
193 : static inline bool mptcp_established_options(struct sock *sk,
194 : struct sk_buff *skb,
195 : unsigned int *size,
196 : unsigned int remaining,
197 : struct mptcp_out_options *opts)
198 : {
199 : return false;
200 : }
201 :
202 : static inline void mptcp_incoming_options(struct sock *sk,
203 : struct sk_buff *skb)
204 : {
205 : }
206 :
207 0 : static inline void mptcp_skb_ext_move(struct sk_buff *to,
208 : const struct sk_buff *from)
209 : {
210 0 : }
211 :
212 0 : static inline void mptcp_skb_ext_copy(struct sk_buff *to,
213 : struct sk_buff *from)
214 : {
215 0 : }
216 :
217 16 : static inline bool mptcp_skb_can_collapse(const struct sk_buff *to,
218 : const struct sk_buff *from)
219 : {
220 16 : return true;
221 : }
222 :
223 : static inline void mptcp_space(const struct sock *ssk, int *s, int *fs) { }
224 0 : static inline void mptcp_seq_show(struct seq_file *seq) { }
225 :
226 : static inline int mptcp_subflow_init_cookie_req(struct request_sock *req,
227 : const struct sock *sk_listener,
228 : struct sk_buff *skb)
229 : {
230 : return 0; /* TCP fallback */
231 : }
232 : #endif /* CONFIG_MPTCP */
233 :
234 : #if IS_ENABLED(CONFIG_MPTCP_IPV6)
235 : int mptcpv6_init(void);
236 : void mptcpv6_handle_mapped(struct sock *sk, bool mapped);
237 : #elif IS_ENABLED(CONFIG_IPV6)
238 : static inline int mptcpv6_init(void) { return 0; }
239 : static inline void mptcpv6_handle_mapped(struct sock *sk, bool mapped) { }
240 : #endif
241 :
242 : #endif /* __NET_MPTCP_H */
|