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