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