blob: 384ec4804198d21bc23fbfb344a092532dab8dc4 [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
Peter Krystadeda7acd2020-01-21 16:56:16 -080014#define MPTCP_SUPPORTED_VERSION 0
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 12
33#define TCPOLEN_MPTCP_MPC_SYNACK 12
34#define TCPOLEN_MPTCP_MPC_ACK 20
Mat Martineau6d0060f2020-01-21 16:56:23 -080035#define TCPOLEN_MPTCP_DSS_BASE 4
36#define TCPOLEN_MPTCP_DSS_ACK64 8
37#define TCPOLEN_MPTCP_DSS_MAP64 14
38#define TCPOLEN_MPTCP_DSS_CHECKSUM 2
Peter Krystadeda7acd2020-01-21 16:56:16 -080039
40/* MPTCP MP_CAPABLE flags */
41#define MPTCP_VERSION_MASK (0x0F)
42#define MPTCP_CAP_CHECKSUM_REQD BIT(7)
43#define MPTCP_CAP_EXTENSIBILITY BIT(6)
44#define MPTCP_CAP_HMAC_SHA1 BIT(0)
45#define MPTCP_CAP_FLAG_MASK (0x3F)
46
Mat Martineau6d0060f2020-01-21 16:56:23 -080047/* MPTCP DSS flags */
48#define MPTCP_DSS_DATA_FIN BIT(4)
49#define MPTCP_DSS_DSN64 BIT(3)
50#define MPTCP_DSS_HAS_MAP BIT(2)
51#define MPTCP_DSS_ACK64 BIT(1)
52#define MPTCP_DSS_HAS_ACK BIT(0)
53
Mat Martineauf870fa02020-01-21 16:56:15 -080054/* MPTCP connection sock */
55struct mptcp_sock {
56 /* inet_connection_sock must be the first member */
57 struct inet_connection_sock sk;
Peter Krystadcec37a62020-01-21 16:56:18 -080058 u64 local_key;
59 u64 remote_key;
Mat Martineau6d0060f2020-01-21 16:56:23 -080060 u64 write_seq;
61 u64 ack_seq;
Peter Krystad79c09492020-01-21 16:56:20 -080062 u32 token;
Peter Krystadcec37a62020-01-21 16:56:18 -080063 struct list_head conn_list;
Mat Martineau6d0060f2020-01-21 16:56:23 -080064 struct skb_ext *cached_ext; /* for the next sendmsg */
Mat Martineauf870fa02020-01-21 16:56:15 -080065 struct socket *subflow; /* outgoing connect/listener/!mp_capable */
66};
67
Peter Krystadcec37a62020-01-21 16:56:18 -080068#define mptcp_for_each_subflow(__msk, __subflow) \
69 list_for_each_entry(__subflow, &((__msk)->conn_list), node)
70
Mat Martineauf870fa02020-01-21 16:56:15 -080071static inline struct mptcp_sock *mptcp_sk(const struct sock *sk)
72{
73 return (struct mptcp_sock *)sk;
74}
75
Peter Krystadcec37a62020-01-21 16:56:18 -080076struct mptcp_subflow_request_sock {
77 struct tcp_request_sock sk;
78 u8 mp_capable : 1,
79 mp_join : 1,
80 backup : 1;
81 u64 local_key;
82 u64 remote_key;
Peter Krystad79c09492020-01-21 16:56:20 -080083 u64 idsn;
84 u32 token;
Peter Krystadcec37a62020-01-21 16:56:18 -080085};
86
87static inline struct mptcp_subflow_request_sock *
88mptcp_subflow_rsk(const struct request_sock *rsk)
89{
90 return (struct mptcp_subflow_request_sock *)rsk;
91}
92
Peter Krystad2303f992020-01-21 16:56:17 -080093/* MPTCP subflow context */
94struct mptcp_subflow_context {
Peter Krystadcec37a62020-01-21 16:56:18 -080095 struct list_head node;/* conn_list of subflows */
96 u64 local_key;
97 u64 remote_key;
Peter Krystad79c09492020-01-21 16:56:20 -080098 u64 idsn;
99 u32 token;
Mat Martineau6d0060f2020-01-21 16:56:23 -0800100 u32 rel_write_seq;
Peter Krystadcec37a62020-01-21 16:56:18 -0800101 u32 request_mptcp : 1, /* send MP_CAPABLE */
102 mp_capable : 1, /* remote is MPTCP capable */
103 fourth_ack : 1, /* send initial DSS */
104 conn_finished : 1;
Peter Krystad2303f992020-01-21 16:56:17 -0800105 struct sock *tcp_sock; /* tcp sk backpointer */
106 struct sock *conn; /* parent mptcp_sock */
Peter Krystadcec37a62020-01-21 16:56:18 -0800107 const struct inet_connection_sock_af_ops *icsk_af_ops;
Peter Krystad2303f992020-01-21 16:56:17 -0800108 struct rcu_head rcu;
109};
110
111static inline struct mptcp_subflow_context *
112mptcp_subflow_ctx(const struct sock *sk)
113{
114 struct inet_connection_sock *icsk = inet_csk(sk);
115
116 /* Use RCU on icsk_ulp_data only for sock diag code */
117 return (__force struct mptcp_subflow_context *)icsk->icsk_ulp_data;
118}
119
120static inline struct sock *
121mptcp_subflow_tcp_sock(const struct mptcp_subflow_context *subflow)
122{
123 return subflow->tcp_sock;
124}
125
126void mptcp_subflow_init(void);
127int mptcp_subflow_create_socket(struct sock *sk, struct socket **new_sock);
128
Peter Krystadcec37a62020-01-21 16:56:18 -0800129extern const struct inet_connection_sock_af_ops ipv4_specific;
130#if IS_ENABLED(CONFIG_MPTCP_IPV6)
131extern const struct inet_connection_sock_af_ops ipv6_specific;
132#endif
133
134void mptcp_get_options(const struct sk_buff *skb,
135 struct tcp_options_received *opt_rx);
136
137void mptcp_finish_connect(struct sock *sk);
138
Peter Krystad79c09492020-01-21 16:56:20 -0800139int mptcp_token_new_request(struct request_sock *req);
140void mptcp_token_destroy_request(u32 token);
141int mptcp_token_new_connect(struct sock *sk);
142int mptcp_token_new_accept(u32 token);
143void mptcp_token_update_accept(struct sock *sk, struct sock *conn);
144void mptcp_token_destroy(u32 token);
145
146void mptcp_crypto_key_sha(u64 key, u32 *token, u64 *idsn);
147static inline void mptcp_crypto_key_gen_sha(u64 *key, u32 *token, u64 *idsn)
148{
149 /* we might consider a faster version that computes the key as a
150 * hash of some information available in the MPTCP socket. Use
151 * random data at the moment, as it's probably the safest option
152 * in case multiple sockets are opened in different namespaces at
153 * the same time.
154 */
155 get_random_bytes(key, sizeof(u64));
156 mptcp_crypto_key_sha(*key, token, idsn);
157}
158
159void mptcp_crypto_hmac_sha(u64 key1, u64 key2, u32 nonce1, u32 nonce2,
160 u32 *hash_out);
161
Mat Martineau6d0060f2020-01-21 16:56:23 -0800162static inline struct mptcp_ext *mptcp_get_ext(struct sk_buff *skb)
163{
164 return (struct mptcp_ext *)skb_ext_find(skb, SKB_EXT_MPTCP);
165}
166
Mat Martineauf870fa02020-01-21 16:56:15 -0800167#endif /* __MPTCP_PROTOCOL_H */