blob: eb3f65264a40e9bf3a3bd20adecdd0723ccf2975 [file] [log] [blame]
Mat Martineauf870fa02020-01-21 16:56:15 -08001/* SPDX-License-Identifier: GPL-2.0 */
2/* Multipath TCP
3 *
4 * Copyright (c) 2017 - 2019, Intel Corporation.
5 */
6
7#ifndef __MPTCP_PROTOCOL_H
8#define __MPTCP_PROTOCOL_H
9
Peter Krystad79c09492020-01-21 16:56:20 -080010#include <linux/random.h>
11#include <net/tcp.h>
12#include <net/inet_connection_sock.h>
13
Christoph Paaschcc7972e2020-01-21 16:56:31 -080014#define MPTCP_SUPPORTED_VERSION 1
Peter Krystadeda7acd2020-01-21 16:56:16 -080015
16/* MPTCP option bits */
17#define OPTION_MPTCP_MPC_SYN BIT(0)
18#define OPTION_MPTCP_MPC_SYNACK BIT(1)
19#define OPTION_MPTCP_MPC_ACK BIT(2)
20
21/* MPTCP option subtypes */
22#define MPTCPOPT_MP_CAPABLE 0
23#define MPTCPOPT_MP_JOIN 1
24#define MPTCPOPT_DSS 2
25#define MPTCPOPT_ADD_ADDR 3
26#define MPTCPOPT_RM_ADDR 4
27#define MPTCPOPT_MP_PRIO 5
28#define MPTCPOPT_MP_FAIL 6
29#define MPTCPOPT_MP_FASTCLOSE 7
30
31/* MPTCP suboption lengths */
Christoph Paaschcc7972e2020-01-21 16:56:31 -080032#define TCPOLEN_MPTCP_MPC_SYN 4
Peter Krystadeda7acd2020-01-21 16:56:16 -080033#define TCPOLEN_MPTCP_MPC_SYNACK 12
34#define TCPOLEN_MPTCP_MPC_ACK 20
Christoph Paaschcc7972e2020-01-21 16:56:31 -080035#define TCPOLEN_MPTCP_MPC_ACK_DATA 22
Mat Martineau6d0060f2020-01-21 16:56:23 -080036#define TCPOLEN_MPTCP_DSS_BASE 4
Mat Martineau648ef4b2020-01-21 16:56:24 -080037#define TCPOLEN_MPTCP_DSS_ACK32 4
Mat Martineau6d0060f2020-01-21 16:56:23 -080038#define TCPOLEN_MPTCP_DSS_ACK64 8
Mat Martineau648ef4b2020-01-21 16:56:24 -080039#define TCPOLEN_MPTCP_DSS_MAP32 10
Mat Martineau6d0060f2020-01-21 16:56:23 -080040#define TCPOLEN_MPTCP_DSS_MAP64 14
41#define TCPOLEN_MPTCP_DSS_CHECKSUM 2
Peter Krystadeda7acd2020-01-21 16:56:16 -080042
43/* MPTCP MP_CAPABLE flags */
44#define MPTCP_VERSION_MASK (0x0F)
45#define MPTCP_CAP_CHECKSUM_REQD BIT(7)
46#define MPTCP_CAP_EXTENSIBILITY BIT(6)
Paolo Abeni65492c52020-01-21 16:56:30 -080047#define MPTCP_CAP_HMAC_SHA256 BIT(0)
Peter Krystadeda7acd2020-01-21 16:56:16 -080048#define MPTCP_CAP_FLAG_MASK (0x3F)
49
Mat Martineau6d0060f2020-01-21 16:56:23 -080050/* MPTCP DSS flags */
51#define MPTCP_DSS_DATA_FIN BIT(4)
52#define MPTCP_DSS_DSN64 BIT(3)
53#define MPTCP_DSS_HAS_MAP BIT(2)
54#define MPTCP_DSS_ACK64 BIT(1)
55#define MPTCP_DSS_HAS_ACK BIT(0)
Mat Martineau648ef4b2020-01-21 16:56:24 -080056#define MPTCP_DSS_FLAG_MASK (0x1F)
57
58/* MPTCP socket flags */
Florian Westphald99bfed2020-02-17 16:54:38 +010059#define MPTCP_DATA_READY 0
60#define MPTCP_SEND_SPACE 1
Mat Martineau6d0060f2020-01-21 16:56:23 -080061
Mat Martineauf870fa02020-01-21 16:56:15 -080062/* MPTCP connection sock */
63struct mptcp_sock {
64 /* inet_connection_sock must be the first member */
65 struct inet_connection_sock sk;
Peter Krystadcec37a62020-01-21 16:56:18 -080066 u64 local_key;
67 u64 remote_key;
Mat Martineau6d0060f2020-01-21 16:56:23 -080068 u64 write_seq;
69 u64 ack_seq;
Peter Krystad79c09492020-01-21 16:56:20 -080070 u32 token;
Mat Martineau648ef4b2020-01-21 16:56:24 -080071 unsigned long flags;
Christoph Paaschd22f4982020-01-21 16:56:32 -080072 bool can_ack;
Paolo Abeni80992012020-02-26 10:14:47 +010073 struct work_struct work;
Peter Krystadcec37a62020-01-21 16:56:18 -080074 struct list_head conn_list;
Mat Martineau6d0060f2020-01-21 16:56:23 -080075 struct skb_ext *cached_ext; /* for the next sendmsg */
Mat Martineauf870fa02020-01-21 16:56:15 -080076 struct socket *subflow; /* outgoing connect/listener/!mp_capable */
Paolo Abeni8ab183d2020-01-21 16:56:33 -080077 struct sock *first;
Mat Martineauf870fa02020-01-21 16:56:15 -080078};
79
Peter Krystadcec37a62020-01-21 16:56:18 -080080#define mptcp_for_each_subflow(__msk, __subflow) \
81 list_for_each_entry(__subflow, &((__msk)->conn_list), node)
82
Mat Martineauf870fa02020-01-21 16:56:15 -080083static inline struct mptcp_sock *mptcp_sk(const struct sock *sk)
84{
85 return (struct mptcp_sock *)sk;
86}
87
Peter Krystadcec37a62020-01-21 16:56:18 -080088struct mptcp_subflow_request_sock {
89 struct tcp_request_sock sk;
Christoph Paaschd22f4982020-01-21 16:56:32 -080090 u16 mp_capable : 1,
Peter Krystadcec37a62020-01-21 16:56:18 -080091 mp_join : 1,
Christoph Paaschd22f4982020-01-21 16:56:32 -080092 backup : 1,
93 remote_key_valid : 1;
Peter Krystadcec37a62020-01-21 16:56:18 -080094 u64 local_key;
95 u64 remote_key;
Peter Krystad79c09492020-01-21 16:56:20 -080096 u64 idsn;
97 u32 token;
Mat Martineau648ef4b2020-01-21 16:56:24 -080098 u32 ssn_offset;
Peter Krystadcec37a62020-01-21 16:56:18 -080099};
100
101static inline struct mptcp_subflow_request_sock *
102mptcp_subflow_rsk(const struct request_sock *rsk)
103{
104 return (struct mptcp_subflow_request_sock *)rsk;
105}
106
Peter Krystad2303f992020-01-21 16:56:17 -0800107/* MPTCP subflow context */
108struct mptcp_subflow_context {
Peter Krystadcec37a62020-01-21 16:56:18 -0800109 struct list_head node;/* conn_list of subflows */
110 u64 local_key;
111 u64 remote_key;
Peter Krystad79c09492020-01-21 16:56:20 -0800112 u64 idsn;
Mat Martineau648ef4b2020-01-21 16:56:24 -0800113 u64 map_seq;
Christoph Paaschcc7972e2020-01-21 16:56:31 -0800114 u32 snd_isn;
Peter Krystad79c09492020-01-21 16:56:20 -0800115 u32 token;
Mat Martineau6d0060f2020-01-21 16:56:23 -0800116 u32 rel_write_seq;
Mat Martineau648ef4b2020-01-21 16:56:24 -0800117 u32 map_subflow_seq;
118 u32 ssn_offset;
119 u32 map_data_len;
Peter Krystadcec37a62020-01-21 16:56:18 -0800120 u32 request_mptcp : 1, /* send MP_CAPABLE */
121 mp_capable : 1, /* remote is MPTCP capable */
Paolo Abeni0be534f2020-03-19 11:06:30 +0100122 fully_established : 1, /* path validated */
Mat Martineau648ef4b2020-01-21 16:56:24 -0800123 conn_finished : 1,
124 map_valid : 1,
Christoph Paaschd22f4982020-01-21 16:56:32 -0800125 mpc_map : 1,
Mat Martineau648ef4b2020-01-21 16:56:24 -0800126 data_avail : 1,
Christoph Paaschd22f4982020-01-21 16:56:32 -0800127 rx_eof : 1,
Mat Martineau76c42a22020-02-28 15:47:40 -0800128 data_fin_tx_enable : 1,
Christoph Paaschd22f4982020-01-21 16:56:32 -0800129 can_ack : 1; /* only after processing the remote a key */
Mat Martineau76c42a22020-02-28 15:47:40 -0800130 u64 data_fin_tx_seq;
Mat Martineau648ef4b2020-01-21 16:56:24 -0800131
Peter Krystad2303f992020-01-21 16:56:17 -0800132 struct sock *tcp_sock; /* tcp sk backpointer */
133 struct sock *conn; /* parent mptcp_sock */
Peter Krystadcec37a62020-01-21 16:56:18 -0800134 const struct inet_connection_sock_af_ops *icsk_af_ops;
Mat Martineau648ef4b2020-01-21 16:56:24 -0800135 void (*tcp_data_ready)(struct sock *sk);
136 void (*tcp_state_change)(struct sock *sk);
137 void (*tcp_write_space)(struct sock *sk);
138
Peter Krystad2303f992020-01-21 16:56:17 -0800139 struct rcu_head rcu;
140};
141
142static inline struct mptcp_subflow_context *
143mptcp_subflow_ctx(const struct sock *sk)
144{
145 struct inet_connection_sock *icsk = inet_csk(sk);
146
147 /* Use RCU on icsk_ulp_data only for sock diag code */
148 return (__force struct mptcp_subflow_context *)icsk->icsk_ulp_data;
149}
150
151static inline struct sock *
152mptcp_subflow_tcp_sock(const struct mptcp_subflow_context *subflow)
153{
154 return subflow->tcp_sock;
155}
156
Mat Martineau648ef4b2020-01-21 16:56:24 -0800157static inline u64
158mptcp_subflow_get_map_offset(const struct mptcp_subflow_context *subflow)
159{
160 return tcp_sk(mptcp_subflow_tcp_sock(subflow))->copied_seq -
161 subflow->ssn_offset -
162 subflow->map_subflow_seq;
163}
164
165static inline u64
166mptcp_subflow_get_mapped_dsn(const struct mptcp_subflow_context *subflow)
167{
168 return subflow->map_seq + mptcp_subflow_get_map_offset(subflow);
169}
170
171int mptcp_is_enabled(struct net *net);
172bool mptcp_subflow_data_available(struct sock *sk);
Peter Krystad2303f992020-01-21 16:56:17 -0800173void mptcp_subflow_init(void);
174int mptcp_subflow_create_socket(struct sock *sk, struct socket **new_sock);
175
Mat Martineau648ef4b2020-01-21 16:56:24 -0800176static inline void mptcp_subflow_tcp_fallback(struct sock *sk,
177 struct mptcp_subflow_context *ctx)
178{
179 sk->sk_data_ready = ctx->tcp_data_ready;
180 sk->sk_state_change = ctx->tcp_state_change;
181 sk->sk_write_space = ctx->tcp_write_space;
182
183 inet_csk(sk)->icsk_af_ops = ctx->icsk_af_ops;
184}
185
Peter Krystadcec37a62020-01-21 16:56:18 -0800186extern const struct inet_connection_sock_af_ops ipv4_specific;
187#if IS_ENABLED(CONFIG_MPTCP_IPV6)
188extern const struct inet_connection_sock_af_ops ipv6_specific;
189#endif
190
Mat Martineau648ef4b2020-01-21 16:56:24 -0800191void mptcp_proto_init(void);
Matthieu Baerts784325e2020-01-21 16:56:28 -0800192#if IS_ENABLED(CONFIG_MPTCP_IPV6)
193int mptcp_proto_v6_init(void);
194#endif
Mat Martineau648ef4b2020-01-21 16:56:24 -0800195
Paolo Abeni58b09912020-03-13 16:52:41 +0100196struct sock *mptcp_sk_clone(const struct sock *sk, struct request_sock *req);
Peter Krystadcec37a62020-01-21 16:56:18 -0800197void mptcp_get_options(const struct sk_buff *skb,
198 struct tcp_options_received *opt_rx);
199
200void mptcp_finish_connect(struct sock *sk);
Florian Westphal2e522132020-02-26 10:14:51 +0100201void mptcp_data_ready(struct sock *sk, struct sock *ssk);
Peter Krystadcec37a62020-01-21 16:56:18 -0800202
Peter Krystad79c09492020-01-21 16:56:20 -0800203int mptcp_token_new_request(struct request_sock *req);
204void mptcp_token_destroy_request(u32 token);
205int mptcp_token_new_connect(struct sock *sk);
Paolo Abeni58b09912020-03-13 16:52:41 +0100206int mptcp_token_new_accept(u32 token, struct sock *conn);
Peter Krystad79c09492020-01-21 16:56:20 -0800207void mptcp_token_destroy(u32 token);
208
209void mptcp_crypto_key_sha(u64 key, u32 *token, u64 *idsn);
210static inline void mptcp_crypto_key_gen_sha(u64 *key, u32 *token, u64 *idsn)
211{
212 /* we might consider a faster version that computes the key as a
213 * hash of some information available in the MPTCP socket. Use
214 * random data at the moment, as it's probably the safest option
215 * in case multiple sockets are opened in different namespaces at
216 * the same time.
217 */
218 get_random_bytes(key, sizeof(u64));
219 mptcp_crypto_key_sha(*key, token, idsn);
220}
221
222void mptcp_crypto_hmac_sha(u64 key1, u64 key2, u32 nonce1, u32 nonce2,
Paolo Abeni65492c52020-01-21 16:56:30 -0800223 void *hash_out);
Peter Krystad79c09492020-01-21 16:56:20 -0800224
Mat Martineau6d0060f2020-01-21 16:56:23 -0800225static inline struct mptcp_ext *mptcp_get_ext(struct sk_buff *skb)
226{
227 return (struct mptcp_ext *)skb_ext_find(skb, SKB_EXT_MPTCP);
228}
229
Mat Martineau648ef4b2020-01-21 16:56:24 -0800230static inline bool before64(__u64 seq1, __u64 seq2)
231{
232 return (__s64)(seq1 - seq2) < 0;
233}
234
235#define after64(seq2, seq1) before64(seq1, seq2)
236
Mat Martineauf870fa02020-01-21 16:56:15 -0800237#endif /* __MPTCP_PROTOCOL_H */