qede: Fix race between rdma destroy workqueue and link change event
[linux-2.6-block.git] / net / mptcp / protocol.h
CommitLineData
f870fa0b
MM
1/* 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
79c0949e
PK
10#include <linux/random.h>
11#include <net/tcp.h>
12#include <net/inet_connection_sock.h>
13
cc7972ea 14#define MPTCP_SUPPORTED_VERSION 1
eda7acdd
PK
15
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 */
cc7972ea 32#define TCPOLEN_MPTCP_MPC_SYN 4
eda7acdd
PK
33#define TCPOLEN_MPTCP_MPC_SYNACK 12
34#define TCPOLEN_MPTCP_MPC_ACK 20
cc7972ea 35#define TCPOLEN_MPTCP_MPC_ACK_DATA 22
6d0060f6 36#define TCPOLEN_MPTCP_DSS_BASE 4
648ef4b8 37#define TCPOLEN_MPTCP_DSS_ACK32 4
6d0060f6 38#define TCPOLEN_MPTCP_DSS_ACK64 8
648ef4b8 39#define TCPOLEN_MPTCP_DSS_MAP32 10
6d0060f6
MM
40#define TCPOLEN_MPTCP_DSS_MAP64 14
41#define TCPOLEN_MPTCP_DSS_CHECKSUM 2
eda7acdd
PK
42
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)
65492c5a 47#define MPTCP_CAP_HMAC_SHA256 BIT(0)
eda7acdd
PK
48#define MPTCP_CAP_FLAG_MASK (0x3F)
49
6d0060f6
MM
50/* 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)
648ef4b8
MM
56#define MPTCP_DSS_FLAG_MASK (0x1F)
57
58/* MPTCP socket flags */
59#define MPTCP_DATA_READY BIT(0)
1891c4a0 60#define MPTCP_SEND_SPACE BIT(1)
6d0060f6 61
f870fa0b
MM
62/* MPTCP connection sock */
63struct mptcp_sock {
64 /* inet_connection_sock must be the first member */
65 struct inet_connection_sock sk;
cec37a6e
PK
66 u64 local_key;
67 u64 remote_key;
6d0060f6
MM
68 u64 write_seq;
69 u64 ack_seq;
79c0949e 70 u32 token;
648ef4b8 71 unsigned long flags;
d22f4988 72 bool can_ack;
cec37a6e 73 struct list_head conn_list;
6d0060f6 74 struct skb_ext *cached_ext; /* for the next sendmsg */
f870fa0b 75 struct socket *subflow; /* outgoing connect/listener/!mp_capable */
8ab183de 76 struct sock *first;
f870fa0b
MM
77};
78
cec37a6e
PK
79#define mptcp_for_each_subflow(__msk, __subflow) \
80 list_for_each_entry(__subflow, &((__msk)->conn_list), node)
81
f870fa0b
MM
82static inline struct mptcp_sock *mptcp_sk(const struct sock *sk)
83{
84 return (struct mptcp_sock *)sk;
85}
86
cec37a6e
PK
87struct mptcp_subflow_request_sock {
88 struct tcp_request_sock sk;
d22f4988 89 u16 mp_capable : 1,
cec37a6e 90 mp_join : 1,
d22f4988
CP
91 backup : 1,
92 remote_key_valid : 1;
cec37a6e
PK
93 u64 local_key;
94 u64 remote_key;
79c0949e
PK
95 u64 idsn;
96 u32 token;
648ef4b8 97 u32 ssn_offset;
cec37a6e
PK
98};
99
100static inline struct mptcp_subflow_request_sock *
101mptcp_subflow_rsk(const struct request_sock *rsk)
102{
103 return (struct mptcp_subflow_request_sock *)rsk;
104}
105
2303f994
PK
106/* MPTCP subflow context */
107struct mptcp_subflow_context {
cec37a6e
PK
108 struct list_head node;/* conn_list of subflows */
109 u64 local_key;
110 u64 remote_key;
79c0949e 111 u64 idsn;
648ef4b8 112 u64 map_seq;
cc7972ea 113 u32 snd_isn;
79c0949e 114 u32 token;
6d0060f6 115 u32 rel_write_seq;
648ef4b8
MM
116 u32 map_subflow_seq;
117 u32 ssn_offset;
118 u32 map_data_len;
cec37a6e
PK
119 u32 request_mptcp : 1, /* send MP_CAPABLE */
120 mp_capable : 1, /* remote is MPTCP capable */
121 fourth_ack : 1, /* send initial DSS */
648ef4b8
MM
122 conn_finished : 1,
123 map_valid : 1,
d22f4988 124 mpc_map : 1,
648ef4b8 125 data_avail : 1,
d22f4988
CP
126 rx_eof : 1,
127 can_ack : 1; /* only after processing the remote a key */
648ef4b8 128
2303f994
PK
129 struct sock *tcp_sock; /* tcp sk backpointer */
130 struct sock *conn; /* parent mptcp_sock */
cec37a6e 131 const struct inet_connection_sock_af_ops *icsk_af_ops;
648ef4b8
MM
132 void (*tcp_data_ready)(struct sock *sk);
133 void (*tcp_state_change)(struct sock *sk);
134 void (*tcp_write_space)(struct sock *sk);
135
2303f994
PK
136 struct rcu_head rcu;
137};
138
139static inline struct mptcp_subflow_context *
140mptcp_subflow_ctx(const struct sock *sk)
141{
142 struct inet_connection_sock *icsk = inet_csk(sk);
143
144 /* Use RCU on icsk_ulp_data only for sock diag code */
145 return (__force struct mptcp_subflow_context *)icsk->icsk_ulp_data;
146}
147
148static inline struct sock *
149mptcp_subflow_tcp_sock(const struct mptcp_subflow_context *subflow)
150{
151 return subflow->tcp_sock;
152}
153
648ef4b8
MM
154static inline u64
155mptcp_subflow_get_map_offset(const struct mptcp_subflow_context *subflow)
156{
157 return tcp_sk(mptcp_subflow_tcp_sock(subflow))->copied_seq -
158 subflow->ssn_offset -
159 subflow->map_subflow_seq;
160}
161
162static inline u64
163mptcp_subflow_get_mapped_dsn(const struct mptcp_subflow_context *subflow)
164{
165 return subflow->map_seq + mptcp_subflow_get_map_offset(subflow);
166}
167
168int mptcp_is_enabled(struct net *net);
169bool mptcp_subflow_data_available(struct sock *sk);
2303f994
PK
170void mptcp_subflow_init(void);
171int mptcp_subflow_create_socket(struct sock *sk, struct socket **new_sock);
172
648ef4b8
MM
173static inline void mptcp_subflow_tcp_fallback(struct sock *sk,
174 struct mptcp_subflow_context *ctx)
175{
176 sk->sk_data_ready = ctx->tcp_data_ready;
177 sk->sk_state_change = ctx->tcp_state_change;
178 sk->sk_write_space = ctx->tcp_write_space;
179
180 inet_csk(sk)->icsk_af_ops = ctx->icsk_af_ops;
181}
182
cec37a6e
PK
183extern const struct inet_connection_sock_af_ops ipv4_specific;
184#if IS_ENABLED(CONFIG_MPTCP_IPV6)
185extern const struct inet_connection_sock_af_ops ipv6_specific;
186#endif
187
648ef4b8 188void mptcp_proto_init(void);
784325e9
MB
189#if IS_ENABLED(CONFIG_MPTCP_IPV6)
190int mptcp_proto_v6_init(void);
191#endif
648ef4b8
MM
192
193struct mptcp_read_arg {
194 struct msghdr *msg;
195};
196
197int mptcp_read_actor(read_descriptor_t *desc, struct sk_buff *skb,
198 unsigned int offset, size_t len);
199
cec37a6e
PK
200void mptcp_get_options(const struct sk_buff *skb,
201 struct tcp_options_received *opt_rx);
202
203void mptcp_finish_connect(struct sock *sk);
204
79c0949e
PK
205int mptcp_token_new_request(struct request_sock *req);
206void mptcp_token_destroy_request(u32 token);
207int mptcp_token_new_connect(struct sock *sk);
208int mptcp_token_new_accept(u32 token);
209void mptcp_token_update_accept(struct sock *sk, struct sock *conn);
210void mptcp_token_destroy(u32 token);
211
212void mptcp_crypto_key_sha(u64 key, u32 *token, u64 *idsn);
213static inline void mptcp_crypto_key_gen_sha(u64 *key, u32 *token, u64 *idsn)
214{
215 /* we might consider a faster version that computes the key as a
216 * hash of some information available in the MPTCP socket. Use
217 * random data at the moment, as it's probably the safest option
218 * in case multiple sockets are opened in different namespaces at
219 * the same time.
220 */
221 get_random_bytes(key, sizeof(u64));
222 mptcp_crypto_key_sha(*key, token, idsn);
223}
224
225void mptcp_crypto_hmac_sha(u64 key1, u64 key2, u32 nonce1, u32 nonce2,
65492c5a 226 void *hash_out);
79c0949e 227
6d0060f6
MM
228static inline struct mptcp_ext *mptcp_get_ext(struct sk_buff *skb)
229{
230 return (struct mptcp_ext *)skb_ext_find(skb, SKB_EXT_MPTCP);
231}
232
648ef4b8
MM
233static inline bool before64(__u64 seq1, __u64 seq2)
234{
235 return (__s64)(seq1 - seq2) < 0;
236}
237
238#define after64(seq2, seq1) before64(seq1, seq2)
239
f870fa0b 240#endif /* __MPTCP_PROTOCOL_H */