1/*
2 * Copyright (c) 2012-2017 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29#ifndef _NETINET_MPTCP_H_
30#define _NETINET_MPTCP_H_
31
32#ifdef BSD_KERNEL_PRIVATE
33
34#include <machine/endian.h>
35
36#include <libkern/crypto/sha1.h>
37
38#if BYTE_ORDER == BIG_ENDIAN
39#define mptcp_hton64(x) (x)
40#define mptcp_ntoh64(x) (x)
41#else /* LITTLE_ENDIAN */
42#define mptcp_hton64(x) __DARWIN_OSSwapInt64(x)
43#define mptcp_ntoh64(x) __DARWIN_OSSwapInt64(x)
44#endif
45
46/*
47 * MPTCP Option Subtype Field values
48 */
49#define MPO_CAPABLE 0x0
50#define MPO_JOIN 0x1
51#define MPO_DSS 0x2
52#define MPO_ADD_ADDR 0x3
53#define MPO_REMOVE_ADDR 0x4
54#define MPO_PRIO 0x5
55#define MPO_FAIL 0x6
56#define MPO_FASTCLOSE 0x7
57
58/* MPTCP Protocol version */
59#define MPTCP_STD_VERSION_0 0x0
60
61/*
62 * MPTCP MP_CAPABLE TCP Option definitions
63 *
64 * Used to establish an MPTCP connection and first subflow.
65 */
66struct mptcp_mpcapable_opt_common {
67 u_int8_t mmco_kind;
68 u_int8_t mmco_len;
69#if BYTE_ORDER == LITTLE_ENDIAN
70 u_int8_t mmco_version:4,
71 mmco_subtype:4;
72#else /* BIG_ENDIAN */
73 u_int8_t mmco_subtype:4,
74 mmco_version:4;
75#endif
76#define MPCAP_PROPOSAL_SBIT 0x01 /* SHA1 Algorithm */
77#define MPCAP_HBIT 0x01 /* alias of MPCAP_PROPOSAL_SBIT */
78#define MPCAP_GBIT 0x02 /* must be 0 */
79#define MPCAP_FBIT 0x04 /* must be 0 */
80#define MPCAP_EBIT 0x08 /* must be 0 */
81#define MPCAP_DBIT 0x10 /* must be 0 */
82#define MPCAP_CBIT 0x20 /* must be 0 */
83#define MPCAP_BBIT 0x40 /* Extensibility bit, must be 0 */
84#define MPCAP_ABIT 0x80 /* alias of MPCAP_CHECKSUM_CBIT */
85#define MPCAP_CHECKSUM_CBIT 0x80 /* DSS Checksum bit */
86 u_int8_t mmco_flags;
87} __attribute__((__packed__));
88
89struct mptcp_mpcapable_opt_rsp {
90 struct mptcp_mpcapable_opt_common mmc_common;
91 mptcp_key_t mmc_localkey;
92} __attribute__((__packed__));
93
94struct mptcp_mpcapable_opt_rsp1 {
95 struct mptcp_mpcapable_opt_common mmc_common;
96 mptcp_key_t mmc_localkey;
97 mptcp_key_t mmc_remotekey;
98} __attribute__((__packed__));
99
100/*
101 * MPTCP MP_JOIN TCP Option definitions
102 *
103 * Used to add subflows to an existing MP_CAPABLE connection.
104 */
105
106/* MP_JOIN Option for SYN */
107struct mptcp_mpjoin_opt_req {
108 u_int8_t mmjo_kind;
109 u_int8_t mmjo_len;
110#define MPTCP_BACKUP 0x1
111 u_int8_t mmjo_subtype_bkp;
112 u_int8_t mmjo_addr_id;
113 u_int32_t mmjo_peer_token;
114 u_int32_t mmjo_rand;
115} __attribute__((__packed__));
116
117/* MP_JOIN Option for SYN/ACK */
118struct mptcp_mpjoin_opt_rsp {
119 u_int8_t mmjo_kind;
120 u_int8_t mmjo_len;
121#define MPTCP_BACKUP 0x1
122 u_int8_t mmjo_subtype_bkp;
123 u_int8_t mmjo_addr_id;
124 u_int64_t mmjo_mac; /* Truncated message auth code */
125 u_int32_t mmjo_rand;
126} __attribute__((__packed__));
127
128/* MP_Join Option for ACK */
129struct mptcp_mpjoin_opt_rsp2 {
130 u_int8_t mmjo_kind;
131 u_int8_t mmjo_len;
132#if BYTE_ORDER == LITTLE_ENDIAN
133 u_int8_t mmjo_reserved1:4,
134 mmjo_subtype:4;
135#else /* BIG_ENDIAN */
136 u_int8_t mmjo_subtype:4,
137 mmjo_reserved1:4;
138#endif
139 u_int8_t mmjo_reserved2;
140 u_int8_t mmjo_mac[SHA1_RESULTLEN]; /* This is 160 bits HMAC SHA-1 per RFC */
141} __attribute__((__packed__));
142
143
144/*
145 * MPTCP ADD_ADDR and REMOVE_ADDR TCP Options
146 *
147 * ADD_ADDR option shall be ignored by this implementation
148 * REMOVE_ADDR option shall be sent to help flush dead subflows
149 */
150
151/* Add Address Option */
152struct mptcp_addaddr_opt {
153 u_int8_t ma_kind;
154 u_int8_t ma_len;
155#if BYTE_ORDER == LITTLE_ENDIAN
156 u_int8_t ma_ipver:4,
157 ma_subtype:4;
158#else /* BIG_ENDIAN */
159 u_int8_t ma_subtype:4,
160 ma_ipver:4;
161#endif
162#define MA_IPVer_V4 4 /* IPv4 Address tagged to the option */
163#define MA_IPVer_V6 6 /* IPv6 Address tagged to the option */
164 u_int8_t ma_addr_id;
165} __attribute__((__packed__));
166
167/* Address sent in the ADD_ADDR option */
168struct mptcp_addr_family_val {
169 union {
170 struct in_addr ma_v4_addr;
171 struct in6_addr ma_v6_addr;
172 } ma_addr;
173 /* u_int16_t ma_ports; */ /* optional field */
174} __attribute__((__packed__));
175
176/* Remove Address Option */
177struct mptcp_remaddr_opt {
178 u_int8_t mr_kind;
179 u_int8_t mr_len;
180#if BYTE_ORDER == LITTLE_ENDIAN
181 u_int8_t mr_rest:4,
182 mr_subtype:4;
183#else /* BIG_ENDIAN */
184 u_int8_t mr_subtype:4,
185 mr_rest:4;
186#endif
187 u_int8_t mr_addr_id;
188} __attribute__((__packed__));
189
190/*
191 * MPTCP Data Sequence Signal (DSS) TCP Options
192 *
193 * Used to map subflow sequence space to MPTCP data sequence space.
194 * Used to send Data ACKs
195 */
196
197/*
198 * DSS Option variants coded as flags in the DSS option flags field
199 */
200#define MDSS_A 0x01 /* Data ACK present if set */
201#define MDSS_a 0x02 /* 64-bit Data ACK present if set */
202#define MDSS_M 0x04 /* Data Sequence Number present if set */
203#define MDSS_m 0x08 /* 64-bit Data Sequence Number present if set */
204#define MDSS_F 0x10 /* Data FIN present */
205
206/* DSS fields common to all DSS option variants */
207struct mptcp_dss_copt {
208 u_int8_t mdss_kind;
209 u_int8_t mdss_len;
210#if BYTE_ORDER == LITTLE_ENDIAN
211 u_int8_t mdss_reserved1:4,
212 mdss_subtype:4;
213#else /* BIG_ENDIAN */
214 u_int8_t mdss_subtype:4,
215 mdss_reserved1:4;
216#endif
217 u_int8_t mdss_flags;
218}__attribute__((__packed__));
219
220/* 32-bit DSS option */
221struct mptcp_dsn_opt {
222 struct mptcp_dss_copt mdss_copt;
223 u_int32_t mdss_dsn; /* Data Sequence Number */
224 u_int32_t mdss_subflow_seqn; /* Relative Subflow Seq Num */
225 u_int16_t mdss_data_len; /* Data Length */
226 /* u_int16_t mdss_xsum; */ /* Data checksum - optional */
227
228}__attribute__((__packed__));
229
230/* 64-bit DSS option */
231struct mptcp_dsn64_opt {
232 struct mptcp_dss_copt mdss_copt;
233 u_int64_t mdss_dsn; /* Data Sequence Number */
234 u_int32_t mdss_subflow_seqn; /* Relative Subflow Seq Num */
235 u_int16_t mdss_data_len; /* Data Length */
236 /* u_int16_t mdss_xsum; */ /* Data checksum - optional */
237}__attribute__((__packed__));
238
239/* 32-bit DSS Data ACK option */
240struct mptcp_data_ack_opt {
241 struct mptcp_dss_copt mdss_copt;
242 u_int32_t mdss_ack;
243}__attribute__((__packed__));
244
245/* 64-bit DSS Data ACK option */
246struct mptcp_data_ack64_opt {
247 struct mptcp_dss_copt mdss_copt;
248 u_int64_t mdss_ack;
249}__attribute__((__packed__));
250
251/* 32-bit DSS+Data ACK option */
252struct mptcp_dss_ack_opt {
253 struct mptcp_dss_copt mdss_copt;
254 u_int32_t mdss_ack; /* Data ACK */
255 u_int32_t mdss_dsn; /* Data Sequence Number */
256 u_int32_t mdss_subflow_seqn; /* Relative Subflow Seq Num */
257 u_int16_t mdss_data_len; /* Data Length */
258 /* u_int16_t mdss_xsum; */ /* Data checksum - optional */
259}__attribute__((__packed__));
260
261/* 64-bit DSS+Data ACK option */
262struct mptcp_dss64_ack64_opt {
263 struct mptcp_dss_copt mdss_copt;
264 u_int64_t mdss_ack; /* Data ACK */
265 u_int64_t mdss_dsn; /* Data Sequence Number */
266 u_int32_t mdss_subflow_seqn; /* Relative Subflow Seq Num */
267 u_int16_t mdss_data_len; /* Data Length */
268 /* u_int16_t mdss_xsum; */ /* Data checksum - optional */
269}__attribute__((__packed__));
270
271/* DSS+Data ACK mixed option variants */
272struct mptcp_dss32_ack64_opt {
273 struct mptcp_dss_copt mdss_copt;
274 u_int64_t mdss_ack; /* Data ACK */
275 u_int32_t mdss_dsn; /* Data Sequence Number */
276 u_int32_t mdss_subflow_seqn; /* Relative Subflow Seq Num */
277 u_int16_t mdss_data_len; /* Data Length */
278 /* u_int16_t mdss_xsum; */ /* Data checksum - optional */
279}__attribute__((__packed__));
280
281struct mptcp_dss64_ack32_opt {
282 struct mptcp_dss_copt mdss_copt;
283 u_int32_t mdss_ack; /* Data ACK */
284 u_int64_t mdss_dsn; /* Data Sequence Number */
285 u_int32_t mdss_subflow_seqn; /* Relative Subflow Seq Num */
286 u_int16_t mdss_data_len; /* Data Length */
287 /* u_int16_t mdss_xsum; */ /* Data checksum - optional */
288}__attribute__((__packed__));
289
290
291/*
292 * MPTCP Fast Close Option
293 *
294 * MPTCP connection is aborted if the FastClose option is received.
295 * In future, we may send this option if a MPTCP socket level abort
296 * API is supported.
297 */
298struct mptcp_fastclose_opt {
299 u_int8_t mfast_kind;
300 u_int8_t mfast_len;
301#if BYTE_ORDER == LITTLE_ENDIAN
302 u_int8_t mfast_reserved:4,
303 mfast_subtype:4;
304#else /* BIG_ENDIAN */
305 u_int8_t mfast_subtype:4,
306 mfast_reserved:4;
307#endif
308 u_int8_t mfast_reserved1;
309 u_int64_t mfast_key; /* Option receiver's key */
310}__attribute__((__packed__));
311
312/*
313 * MPTCP MP_FAIL Option
314 *
315 * When DSS checksum is ON, and checksum fails, remote peer may send
316 * this option to indicate the failure. Likewise, we may send this
317 * option.
318 */
319struct mptcp_mpfail_opt {
320 u_int8_t mfail_kind;
321 u_int8_t mfail_len;
322#if BYTE_ORDER == LITTLE_ENDIAN
323 u_int8_t mfail_reserved:4,
324 mfail_subtype:4;
325#else /* BIG_ENDIAN */
326 u_int8_t mfail_subtype:4,
327 mfail_reserved:4;
328#endif
329 u_int8_t mfail_reserved1:8;
330 u_int64_t mfail_dsn;
331}__attribute__((__packed__));
332
333
334/*
335 * MPTCP MP_PRIO Option
336 *
337 * When a subflow becomes unusable (due to bad radio coverage) or
338 * it is the costlier path or it is not the preferred path, the receiver may
339 * use this option to let the sender know of its path preference.
340 */
341
342/* Option to change priority of self */
343struct mptcp_mpprio_opt {
344 u_int8_t mpprio_kind;
345 u_int8_t mpprio_len;
346#define MPTCP_MPPRIO_BKP 0x1
347#if BYTE_ORDER == LITTLE_ENDIAN
348 u_int8_t mpprio_flags:4,
349 mpprio_subtype:4;
350#else /* BIG_ENDIAN */
351 u_int8_t mpprio_subtype:4,
352 mpprio_flags:4;
353#endif
354}__attribute__((__packed__));
355
356/* Option to change priority of some other subflow(s) using addr_id */
357struct mptcp_mpprio_addr_opt {
358 u_int8_t mpprio_kind;
359 u_int8_t mpprio_len;
360#define MPTCP_MPPRIO_BKP 0x1
361#if BYTE_ORDER == LITTLE_ENDIAN
362 u_int8_t mpprio_flags:4,
363 mpprio_subtype:4;
364#else /* BIG_ENDIAN */
365 u_int8_t mpprio_subtype:4,
366 mpprio_flags:4;
367#endif
368 u_int8_t mpprio_addrid;
369}__attribute__((__packed__));
370
371/*
372 * MPTCP Checksum Psuedo Header
373 *
374 */
375struct mptcp_pseudohdr {
376 u_int64_t mphdr_dsn; /* Data Sequence Number */
377 u_int32_t mphdr_ssn; /* Subflow Sequence Number */
378 u_int16_t mphdr_len; /* Data-Level Length */
379 u_int16_t mphdr_xsum; /* MPTCP Level Checksum */
380}__attribute__((__packed__));
381
382#endif /* BSD_KERNEL_PRIVATE */
383
384#endif /* _NETINET_MPTCP_H_ */
385