]> git.saurik.com Git - apple/xnu.git/blame - bsd/netinet/mptcp_opt.c
xnu-4570.41.2.tar.gz
[apple/xnu.git] / bsd / netinet / mptcp_opt.c
CommitLineData
39236c6e 1/*
5ba3f43e 2 * Copyright (c) 2012-2017 Apple Inc. All rights reserved.
39236c6e
A
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#include <sys/param.h>
29#include <sys/systm.h>
30#include <netinet/in_systm.h>
31#include <sys/socket.h>
32#include <sys/socketvar.h>
3e170ce0 33#include <sys/syslog.h>
39236c6e
A
34#include <net/route.h>
35#include <netinet/in.h>
36#include <net/if.h>
37
38#include <netinet/ip.h>
39#include <netinet/ip_var.h>
40#include <netinet/in_var.h>
41#include <netinet/tcp.h>
39037602 42#include <netinet/tcp_cache.h>
39236c6e
A
43#include <netinet/tcp_seq.h>
44#include <netinet/tcpip.h>
45#include <netinet/tcp_fsm.h>
46#include <netinet/mptcp_var.h>
47#include <netinet/mptcp.h>
48#include <netinet/mptcp_opt.h>
49#include <netinet/mptcp_seq.h>
50
51#include <libkern/crypto/sha1.h>
52#include <netinet/mptcp_timer.h>
53
54#include <mach/sdt.h>
55
56static int mptcp_validate_join_hmac(struct tcpcb *, u_char*, int);
57static int mptcp_snd_mpprio(struct tcpcb *tp, u_char *cp, int optlen);
5ba3f43e 58static void mptcp_send_remaddr_opt(struct tcpcb *, struct mptcp_remaddr_opt *);
39236c6e
A
59
60/*
61 * MPTCP Options Output Processing
62 */
63
64static unsigned
5ba3f43e 65mptcp_setup_first_subflow_syn_opts(struct socket *so, u_char *opt, unsigned optlen)
39236c6e 66{
5ba3f43e 67 struct mptcp_mpcapable_opt_common mptcp_opt;
39236c6e 68 struct tcpcb *tp = sototcpcb(so);
5ba3f43e
A
69 struct mptcb *mp_tp = tptomptp(tp);
70
71 mpte_lock_assert_held(mp_tp->mpt_mpte);
39236c6e 72
39236c6e
A
73 /*
74 * Avoid retransmitting the MP_CAPABLE option.
75 */
39037602
A
76 if (tp->t_rxtshift > mptcp_mpcap_retries) {
77 if (!(mp_tp->mpt_flags & (MPTCPF_FALLBACK_HEURISTIC | MPTCPF_HEURISTIC_TRAC))) {
78 mp_tp->mpt_flags |= MPTCPF_HEURISTIC_TRAC;
79 tcp_heuristic_mptcp_loss(tp);
80 }
39236c6e 81 return (optlen);
39037602
A
82 }
83
84 if (!tcp_heuristic_do_mptcp(tp)) {
85 mp_tp->mpt_flags |= MPTCPF_FALLBACK_HEURISTIC;
86 return (optlen);
87 }
39236c6e 88
5ba3f43e 89 bzero(&mptcp_opt, sizeof (struct mptcp_mpcapable_opt_common));
39236c6e 90
5ba3f43e
A
91 mptcp_opt.mmco_kind = TCPOPT_MULTIPATH;
92 mptcp_opt.mmco_len =
93 sizeof (struct mptcp_mpcapable_opt_common) +
94 sizeof (mptcp_key_t);
95 mptcp_opt.mmco_subtype = MPO_CAPABLE;
96 mptcp_opt.mmco_version = mp_tp->mpt_version;
97 mptcp_opt.mmco_flags |= MPCAP_PROPOSAL_SBIT;
98 if (mp_tp->mpt_flags & MPTCPF_CHECKSUM)
99 mptcp_opt.mmco_flags |= MPCAP_CHECKSUM_CBIT;
100 memcpy(opt + optlen, &mptcp_opt, sizeof (struct mptcp_mpcapable_opt_common));
101 optlen += sizeof (struct mptcp_mpcapable_opt_common);
102 memcpy(opt + optlen, &mp_tp->mpt_localkey, sizeof (mptcp_key_t));
103 optlen += sizeof (mptcp_key_t);
39236c6e
A
104
105 return (optlen);
106}
107
108static unsigned
5ba3f43e 109mptcp_setup_join_subflow_syn_opts(struct socket *so, u_char *opt, unsigned optlen)
39236c6e 110{
5ba3f43e 111 struct mptcp_mpjoin_opt_req mpjoin_req;
39236c6e
A
112 struct inpcb *inp = sotoinpcb(so);
113 struct tcpcb *tp = NULL;
5ba3f43e 114 struct mptsub *mpts;
39236c6e
A
115
116 if (!inp)
117 return (optlen);
118
119 tp = intotcpcb(inp);
120 if (!tp)
121 return (optlen);
122
5ba3f43e 123 mpts = tp->t_mpsub;
39236c6e 124
5ba3f43e
A
125 VERIFY(tptomptp(tp));
126 mpte_lock_assert_held(tptomptp(tp)->mpt_mpte);
fe8ab488 127
5ba3f43e
A
128 bzero(&mpjoin_req, sizeof (mpjoin_req));
129 mpjoin_req.mmjo_kind = TCPOPT_MULTIPATH;
130 mpjoin_req.mmjo_len = sizeof (mpjoin_req);
131 mpjoin_req.mmjo_subtype_bkp = MPO_JOIN << 4;
fe8ab488 132
5ba3f43e
A
133 if (tp->t_mpflags & TMPF_BACKUP_PATH) {
134 mpjoin_req.mmjo_subtype_bkp |= MPTCP_BACKUP;
135 } else if (inp->inp_boundifp && IFNET_IS_CELLULAR(inp->inp_boundifp) &&
136 mpts->mpts_mpte->mpte_svctype != MPTCP_SVCTYPE_AGGREGATE) {
137 mpjoin_req.mmjo_subtype_bkp |= MPTCP_BACKUP;
138 tp->t_mpflags |= TMPF_BACKUP_PATH;
39236c6e 139 } else {
5ba3f43e
A
140 mpts->mpts_flags |= MPTSF_PREFERRED;
141 }
142
143 mpjoin_req.mmjo_addr_id = tp->t_local_aid;
144 mpjoin_req.mmjo_peer_token = tptomptp(tp)->mpt_remotetoken;
145 if (mpjoin_req.mmjo_peer_token == 0) {
146 mptcplog((LOG_DEBUG, "%s: peer token 0", __func__),
147 MPTCP_SOCKET_DBG, MPTCP_LOGLVL_ERR);
39236c6e 148 }
5ba3f43e
A
149 mptcp_get_rands(tp->t_local_aid, tptomptp(tp),
150 &mpjoin_req.mmjo_rand, NULL);
151 memcpy(opt + optlen, &mpjoin_req, mpjoin_req.mmjo_len);
152 optlen += mpjoin_req.mmjo_len;
153
39236c6e
A
154 return (optlen);
155}
156
157unsigned
158mptcp_setup_join_ack_opts(struct tcpcb *tp, u_char *opt, unsigned optlen)
159{
160 unsigned new_optlen;
161 struct mptcp_mpjoin_opt_rsp2 join_rsp2;
162
163 if ((MAX_TCPOPTLEN - optlen) < sizeof (struct mptcp_mpjoin_opt_rsp2)) {
164 printf("%s: no space left %d \n", __func__, optlen);
165 return (optlen);
166 }
167
168 bzero(&join_rsp2, sizeof (struct mptcp_mpjoin_opt_rsp2));
169 join_rsp2.mmjo_kind = TCPOPT_MULTIPATH;
170 join_rsp2.mmjo_len = sizeof (struct mptcp_mpjoin_opt_rsp2);
171 join_rsp2.mmjo_subtype = MPO_JOIN;
172 mptcp_get_hmac(tp->t_local_aid, tptomptp(tp),
5ba3f43e 173 (u_char*)&join_rsp2.mmjo_mac);
39236c6e
A
174 memcpy(opt + optlen, &join_rsp2, join_rsp2.mmjo_len);
175 new_optlen = optlen + join_rsp2.mmjo_len;
176 return (new_optlen);
177}
178
179unsigned
5ba3f43e 180mptcp_setup_syn_opts(struct socket *so, u_char *opt, unsigned optlen)
39236c6e
A
181{
182 unsigned new_optlen;
183
5ba3f43e
A
184 if (!(so->so_flags & SOF_MP_SEC_SUBFLOW))
185 new_optlen = mptcp_setup_first_subflow_syn_opts(so, opt, optlen);
186 else
187 new_optlen = mptcp_setup_join_subflow_syn_opts(so, opt, optlen);
188
39236c6e
A
189 return (new_optlen);
190}
191
192static int
193mptcp_send_mpfail(struct tcpcb *tp, u_char *opt, unsigned int optlen)
194{
195#pragma unused(tp, opt, optlen)
196
197 struct mptcb *mp_tp = NULL;
198 struct mptcp_mpfail_opt fail_opt;
199 uint64_t dsn;
200 int len = sizeof (struct mptcp_mpfail_opt);
201
202 mp_tp = tptomptp(tp);
203 if (mp_tp == NULL) {
204 tp->t_mpflags &= ~TMPF_SND_MPFAIL;
205 return (optlen);
206 }
207
5ba3f43e
A
208 mpte_lock_assert_held(mp_tp->mpt_mpte);
209
39236c6e
A
210 /* if option space low give up */
211 if ((MAX_TCPOPTLEN - optlen) < sizeof (struct mptcp_mpfail_opt)) {
212 tp->t_mpflags &= ~TMPF_SND_MPFAIL;
213 return (optlen);
39037602 214 }
39236c6e 215
39236c6e 216 dsn = mp_tp->mpt_rcvnxt;
39236c6e
A
217
218 bzero(&fail_opt, sizeof (fail_opt));
219 fail_opt.mfail_kind = TCPOPT_MULTIPATH;
220 fail_opt.mfail_len = len;
221 fail_opt.mfail_subtype = MPO_FAIL;
222 fail_opt.mfail_dsn = mptcp_hton64(dsn);
223 memcpy(opt + optlen, &fail_opt, len);
224 optlen += len;
225 tp->t_mpflags &= ~TMPF_SND_MPFAIL;
5ba3f43e 226 mptcplog((LOG_DEBUG, "%s: %d \n", __func__,
39037602 227 tp->t_local_aid), (MPTCP_SOCKET_DBG | MPTCP_SENDER_DBG),
3e170ce0 228 MPTCP_LOGLVL_LOG);
39236c6e
A
229 return (optlen);
230}
231
232static int
233mptcp_send_infinite_mapping(struct tcpcb *tp, u_char *opt, unsigned int optlen)
234{
235 struct mptcp_dsn_opt infin_opt;
236 struct mptcb *mp_tp = NULL;
237 size_t len = sizeof (struct mptcp_dsn_opt);
238 struct socket *so = tp->t_inpcb->inp_socket;
39236c6e
A
239 int csum_len = 0;
240
241 if (!so)
242 return (optlen);
243
244 mp_tp = tptomptp(tp);
245 if (mp_tp == NULL)
246 return (optlen);
247
5ba3f43e
A
248 mpte_lock_assert_held(mp_tp->mpt_mpte);
249
39236c6e
A
250 if (mp_tp->mpt_flags & MPTCPF_CHECKSUM)
251 csum_len = 2;
252
253 /* try later */
5ba3f43e 254 if ((MAX_TCPOPTLEN - optlen) < (len + csum_len))
39236c6e 255 return (optlen);
5ba3f43e 256
39236c6e
A
257 bzero(&infin_opt, sizeof (infin_opt));
258 infin_opt.mdss_copt.mdss_kind = TCPOPT_MULTIPATH;
259 infin_opt.mdss_copt.mdss_len = len + csum_len;
260 infin_opt.mdss_copt.mdss_subtype = MPO_DSS;
261 infin_opt.mdss_copt.mdss_flags |= MDSS_M;
262 if (mp_tp->mpt_flags & MPTCPF_RECVD_MPFAIL) {
263 infin_opt.mdss_dsn = (u_int32_t)
264 MPTCP_DATASEQ_LOW32(mp_tp->mpt_dsn_at_csum_fail);
fe8ab488 265 infin_opt.mdss_subflow_seqn = mp_tp->mpt_ssn_at_csum_fail;
39236c6e 266 } else {
490019cf
A
267 /*
268 * If MPTCP fallback happens, but TFO succeeds, the data on the
269 * SYN does not belong to the MPTCP data sequence space.
270 */
271 if ((tp->t_tfo_stats & TFO_S_SYN_DATA_ACKED) &&
272 ((mp_tp->mpt_local_idsn + 1) == mp_tp->mpt_snduna)) {
273 infin_opt.mdss_subflow_seqn = 1;
274
5ba3f43e
A
275 mptcplog((LOG_DEBUG, "%s: idsn %llu snduna %llu \n",
276 __func__, mp_tp->mpt_local_idsn,
490019cf
A
277 mp_tp->mpt_snduna),
278 (MPTCP_SOCKET_DBG | MPTCP_SENDER_DBG),
279 MPTCP_LOGLVL_LOG);
280 } else {
5ba3f43e 281 infin_opt.mdss_subflow_seqn = tp->snd_una - tp->t_mpsub->mpts_iss;
490019cf 282 }
39236c6e
A
283 infin_opt.mdss_dsn = (u_int32_t)
284 MPTCP_DATASEQ_LOW32(mp_tp->mpt_snduna);
39236c6e 285 }
5ba3f43e 286
39236c6e
A
287 if ((infin_opt.mdss_dsn == 0) || (infin_opt.mdss_subflow_seqn == 0)) {
288 return (optlen);
289 }
290 infin_opt.mdss_dsn = htonl(infin_opt.mdss_dsn);
291 infin_opt.mdss_subflow_seqn = htonl(infin_opt.mdss_subflow_seqn);
292 infin_opt.mdss_data_len = 0;
293
294 memcpy(opt + optlen, &infin_opt, len);
295 optlen += len;
296 if (csum_len != 0) {
297 /* The checksum field is set to 0 for infinite mapping */
298 uint16_t csum = 0;
299 memcpy(opt + optlen, &csum, csum_len);
300 optlen += csum_len;
301 }
302
5ba3f43e 303 mptcplog((LOG_DEBUG, "%s: dsn = %x, seq = %x len = %x\n", __func__,
3e170ce0
A
304 ntohl(infin_opt.mdss_dsn),
305 ntohl(infin_opt.mdss_subflow_seqn),
306 ntohs(infin_opt.mdss_data_len)),
307 (MPTCP_SOCKET_DBG | MPTCP_SENDER_DBG),
308 MPTCP_LOGLVL_LOG);
39236c6e 309
39236c6e
A
310 tp->t_mpflags |= TMPF_INFIN_SENT;
311 tcpstat.tcps_estab_fallback++;
312 return (optlen);
313}
314
315
316static int
317mptcp_ok_to_fin(struct tcpcb *tp, u_int64_t dsn, u_int32_t datalen)
318{
5ba3f43e
A
319 struct mptcb *mp_tp = tptomptp(tp);
320
321 mpte_lock_assert_held(mp_tp->mpt_mpte);
39236c6e 322
39236c6e 323 dsn = (mp_tp->mpt_sndmax & MPTCP_DATASEQ_LOW32_MASK) | dsn;
5ba3f43e 324 if ((dsn + datalen) == mp_tp->mpt_sndmax)
39236c6e 325 return (1);
5ba3f43e 326
39236c6e
A
327 return (0);
328}
329
39236c6e
A
330unsigned int
331mptcp_setup_opts(struct tcpcb *tp, int32_t off, u_char *opt,
5ba3f43e
A
332 unsigned int optlen, int flags, int len,
333 boolean_t *p_mptcp_acknow)
39236c6e
A
334{
335 struct inpcb *inp = (struct inpcb *)tp->t_inpcb;
336 struct socket *so = inp->inp_socket;
337 struct mptcb *mp_tp = tptomptp(tp);
338 boolean_t do_csum = FALSE;
339 boolean_t send_64bit_dsn = FALSE;
340 boolean_t send_64bit_ack = FALSE;
5ba3f43e 341 u_int32_t old_mpt_flags = tp->t_mpflags & TMPF_MPTCP_SIGNALS;
39236c6e 342
5ba3f43e 343 if (mptcp_enable == 0 || mp_tp == NULL || tp->t_state == TCPS_CLOSED) {
39236c6e 344 /* do nothing */
fe8ab488 345 goto ret_optlen;
39236c6e
A
346 }
347
5ba3f43e
A
348 mpte_lock_assert_held(mp_tp->mpt_mpte);
349
fe8ab488 350 if (mp_tp->mpt_flags & MPTCPF_CHECKSUM) {
39236c6e 351 do_csum = TRUE;
fe8ab488 352 }
39236c6e
A
353
354 /* tcp_output handles the SYN path separately */
fe8ab488
A
355 if (flags & TH_SYN) {
356 goto ret_optlen;
357 }
39236c6e
A
358
359 if ((MAX_TCPOPTLEN - optlen) <
360 sizeof (struct mptcp_mpcapable_opt_common)) {
5ba3f43e
A
361 mptcplog((LOG_ERR, "%s: no space left %d flags %x tp->t_mpflags %x len %d\n",
362 __func__, optlen, flags, tp->t_mpflags, len),
363 MPTCP_SOCKET_DBG, MPTCP_LOGLVL_ERR);
fe8ab488 364 goto ret_optlen;
39236c6e
A
365 }
366
39236c6e
A
367 if (tp->t_mpflags & TMPF_TCP_FALLBACK) {
368 if (tp->t_mpflags & TMPF_SND_MPFAIL)
369 optlen = mptcp_send_mpfail(tp, opt, optlen);
370 else if (!(tp->t_mpflags & TMPF_INFIN_SENT))
371 optlen = mptcp_send_infinite_mapping(tp, opt, optlen);
fe8ab488 372 goto ret_optlen;
39236c6e
A
373 }
374
5ba3f43e 375 if (tp->t_mpflags & TMPF_SND_KEYS) {
39236c6e
A
376 struct mptcp_mpcapable_opt_rsp1 mptcp_opt;
377 if ((MAX_TCPOPTLEN - optlen) <
378 sizeof (struct mptcp_mpcapable_opt_rsp1))
fe8ab488 379 goto ret_optlen;
39236c6e
A
380 bzero(&mptcp_opt, sizeof (struct mptcp_mpcapable_opt_rsp1));
381 mptcp_opt.mmc_common.mmco_kind = TCPOPT_MULTIPATH;
382 mptcp_opt.mmc_common.mmco_len =
383 sizeof (struct mptcp_mpcapable_opt_rsp1);
384 mptcp_opt.mmc_common.mmco_subtype = MPO_CAPABLE;
3e170ce0 385 mptcp_opt.mmc_common.mmco_version = mp_tp->mpt_version;
39236c6e
A
386 /* HMAC-SHA1 is the proposal */
387 mptcp_opt.mmc_common.mmco_flags |= MPCAP_PROPOSAL_SBIT;
39236c6e
A
388 if (mp_tp->mpt_flags & MPTCPF_CHECKSUM)
389 mptcp_opt.mmc_common.mmco_flags |= MPCAP_CHECKSUM_CBIT;
5ba3f43e
A
390 mptcp_opt.mmc_localkey = mp_tp->mpt_localkey;
391 mptcp_opt.mmc_remotekey = mp_tp->mpt_remotekey;
39236c6e
A
392 memcpy(opt + optlen, &mptcp_opt, mptcp_opt.mmc_common.mmco_len);
393 optlen += mptcp_opt.mmc_common.mmco_len;
5ba3f43e 394 tp->t_mpflags &= ~TMPF_SND_KEYS;
39236c6e
A
395
396 if (!tp->t_mpuna) {
397 tp->t_mpuna = tp->snd_una;
398 } else {
399 /* its a retransmission of the MP_CAPABLE ACK */
400 }
fe8ab488 401 goto ret_optlen;
39236c6e
A
402 }
403
5ba3f43e 404 if (tp->t_mpflags & TMPF_SND_JACK) {
39236c6e
A
405 /* Do the ACK part */
406 optlen = mptcp_setup_join_ack_opts(tp, opt, optlen);
407 if (!tp->t_mpuna) {
408 tp->t_mpuna = tp->snd_una;
409 }
410 /* Start a timer to retransmit the ACK */
411 tp->t_timer[TCPT_JACK_RXMT] =
412 OFFSET_FROM_START(tp, tcp_jack_rxmt);
5ba3f43e
A
413
414 tp->t_mpflags &= ~TMPF_SND_JACK;
fe8ab488 415 goto ret_optlen;
39236c6e
A
416 }
417
418 if (!(tp->t_mpflags & TMPF_MPTCP_TRUE))
fe8ab488 419 goto ret_optlen;
39037602
A
420 /*
421 * From here on, all options are sent only if MPTCP_TRUE
fe8ab488
A
422 * or when data is sent early on as in Fast Join
423 */
39236c6e 424
39037602
A
425 if ((tp->t_mpflags & TMPF_MPTCP_TRUE) &&
426 (tp->t_mpflags & TMPF_SND_REM_ADDR)) {
427 int rem_opt_len = sizeof (struct mptcp_remaddr_opt);
428 if ((optlen + rem_opt_len) <= MAX_TCPOPTLEN) {
429 mptcp_send_remaddr_opt(tp,
430 (struct mptcp_remaddr_opt *)(opt + optlen));
431 optlen += rem_opt_len;
432 } else {
433 tp->t_mpflags &= ~TMPF_SND_REM_ADDR;
434 }
435 }
436
437 if (tp->t_mpflags & TMPF_SND_MPPRIO) {
438 optlen = mptcp_snd_mpprio(tp, opt, optlen);
439 }
440
5ba3f43e 441 if (mp_tp->mpt_flags & MPTCPF_SND_64BITDSN) {
39236c6e
A
442 send_64bit_dsn = TRUE;
443 }
39037602 444 if (mp_tp->mpt_flags & MPTCPF_SND_64BITACK)
39236c6e 445 send_64bit_ack = TRUE;
39037602 446
5ba3f43e
A
447#define CHECK_OPTLEN { \
448 if ((MAX_TCPOPTLEN - optlen) < dssoptlen) { \
449 mptcplog((LOG_ERR, "%s: dssoptlen %d optlen %d \n", __func__, \
450 dssoptlen, optlen), \
451 MPTCP_SOCKET_DBG, MPTCP_LOGLVL_ERR); \
452 goto ret_optlen; \
453 } \
39236c6e
A
454}
455
456#define DO_FIN(dsn_opt) { \
457 int sndfin = 0; \
5ba3f43e 458 sndfin = mptcp_ok_to_fin(tp, dsn_opt.mdss_dsn, len); \
39236c6e
A
459 if (sndfin) { \
460 dsn_opt.mdss_copt.mdss_flags |= MDSS_F; \
39037602 461 dsn_opt.mdss_data_len += 1; \
39236c6e
A
462 } \
463}
464
465#define CHECK_DATALEN { \
466 /* MPTCP socket does not support IP options */ \
5ba3f43e
A
467 if ((len + optlen + dssoptlen) > tp->t_maxopd) { \
468 mptcplog((LOG_ERR, "%s: nosp %d len %d opt %d %d %d\n", \
469 __func__, len, dssoptlen, optlen, \
3e170ce0
A
470 tp->t_maxseg, tp->t_maxopd), \
471 MPTCP_SOCKET_DBG, MPTCP_LOGLVL_ERR); \
39236c6e 472 /* remove option length from payload len */ \
5ba3f43e 473 len = tp->t_maxopd - optlen - dssoptlen; \
39236c6e
A
474 } \
475}
476
477 if ((tp->t_mpflags & TMPF_SEND_DSN) &&
478 (send_64bit_dsn)) {
479 /*
480 * If there was the need to send 64-bit Data ACK along
481 * with 64-bit DSN, then 26 or 28 bytes would be used.
482 * With timestamps and NOOP padding that will cause
483 * overflow. Hence, in the rare event that both 64-bit
484 * DSN and 64-bit ACK have to be sent, delay the send of
485 * 64-bit ACK until our 64-bit DSN is acked with a 64-bit ack.
486 * XXX If this delay causes issue, remove the 2-byte padding.
487 */
488 struct mptcp_dss64_ack32_opt dsn_ack_opt;
5ba3f43e
A
489 unsigned int dssoptlen = sizeof (dsn_ack_opt);
490 uint16_t dss_csum;
39236c6e
A
491
492 if (do_csum) {
5ba3f43e 493 dssoptlen += 2;
39236c6e
A
494 }
495
496 CHECK_OPTLEN;
497
498 bzero(&dsn_ack_opt, sizeof (dsn_ack_opt));
499 dsn_ack_opt.mdss_copt.mdss_kind = TCPOPT_MULTIPATH;
500 dsn_ack_opt.mdss_copt.mdss_subtype = MPO_DSS;
5ba3f43e 501 dsn_ack_opt.mdss_copt.mdss_len = dssoptlen;
39236c6e
A
502 dsn_ack_opt.mdss_copt.mdss_flags |=
503 MDSS_M | MDSS_m | MDSS_A;
504
505 CHECK_DATALEN;
506
5ba3f43e
A
507 mptcp_output_getm_dsnmap64(so, off,
508 &dsn_ack_opt.mdss_dsn,
509 &dsn_ack_opt.mdss_subflow_seqn,
510 &dsn_ack_opt.mdss_data_len,
511 &dss_csum);
39236c6e
A
512
513 if ((dsn_ack_opt.mdss_data_len == 0) ||
514 (dsn_ack_opt.mdss_dsn == 0)) {
fe8ab488 515 goto ret_optlen;
39236c6e
A
516 }
517
518 if (tp->t_mpflags & TMPF_SEND_DFIN) {
519 DO_FIN(dsn_ack_opt);
520 }
521
39236c6e
A
522 dsn_ack_opt.mdss_ack =
523 htonl(MPTCP_DATAACK_LOW32(mp_tp->mpt_rcvnxt));
39236c6e
A
524
525 dsn_ack_opt.mdss_dsn = mptcp_hton64(dsn_ack_opt.mdss_dsn);
526 dsn_ack_opt.mdss_subflow_seqn = htonl(
527 dsn_ack_opt.mdss_subflow_seqn);
528 dsn_ack_opt.mdss_data_len = htons(
529 dsn_ack_opt.mdss_data_len);
39236c6e
A
530
531 memcpy(opt + optlen, &dsn_ack_opt, sizeof (dsn_ack_opt));
5ba3f43e
A
532 if (do_csum)
533 *((uint16_t *)(void *)(opt + optlen + sizeof (dsn_ack_opt))) = dss_csum;
39236c6e 534
5ba3f43e
A
535 optlen += dssoptlen;
536 mptcplog((LOG_DEBUG,"%s: long DSS = %llx ACK = %llx \n", __func__,
3e170ce0
A
537 mptcp_ntoh64(dsn_ack_opt.mdss_dsn),
538 mptcp_ntoh64(dsn_ack_opt.mdss_ack)),
539 MPTCP_SOCKET_DBG, MPTCP_LOGLVL_LOG);
39037602 540
39236c6e 541 tp->t_mpflags &= ~TMPF_MPTCP_ACKNOW;
fe8ab488 542 goto ret_optlen;
39236c6e
A
543 }
544
545 if ((tp->t_mpflags & TMPF_SEND_DSN) &&
546 (!send_64bit_dsn) &&
547 !(tp->t_mpflags & TMPF_MPTCP_ACKNOW)) {
548 struct mptcp_dsn_opt dsn_opt;
5ba3f43e
A
549 unsigned int dssoptlen = sizeof (struct mptcp_dsn_opt);
550 uint16_t dss_csum;
39236c6e
A
551
552 if (do_csum) {
5ba3f43e 553 dssoptlen += 2;
39236c6e
A
554 }
555
556 CHECK_OPTLEN;
557
558 bzero(&dsn_opt, sizeof (dsn_opt));
559 dsn_opt.mdss_copt.mdss_kind = TCPOPT_MULTIPATH;
560 dsn_opt.mdss_copt.mdss_subtype = MPO_DSS;
5ba3f43e 561 dsn_opt.mdss_copt.mdss_len = dssoptlen;
39236c6e
A
562 dsn_opt.mdss_copt.mdss_flags |= MDSS_M;
563
564 CHECK_DATALEN;
565
5ba3f43e
A
566 mptcp_output_getm_dsnmap32(so, off, &dsn_opt.mdss_dsn,
567 &dsn_opt.mdss_subflow_seqn,
568 &dsn_opt.mdss_data_len,
569 &dss_csum);
39236c6e
A
570
571 if ((dsn_opt.mdss_data_len == 0) ||
572 (dsn_opt.mdss_dsn == 0)) {
fe8ab488 573 goto ret_optlen;
39236c6e
A
574 }
575
576 if (tp->t_mpflags & TMPF_SEND_DFIN) {
577 DO_FIN(dsn_opt);
578 }
579
580 dsn_opt.mdss_dsn = htonl(dsn_opt.mdss_dsn);
581 dsn_opt.mdss_subflow_seqn = htonl(dsn_opt.mdss_subflow_seqn);
582 dsn_opt.mdss_data_len = htons(dsn_opt.mdss_data_len);
39236c6e 583 memcpy(opt + optlen, &dsn_opt, sizeof (dsn_opt));
5ba3f43e
A
584 if (do_csum)
585 *((uint16_t *)(void *)(opt + optlen + sizeof (dsn_opt))) = dss_csum;
586
587 optlen += dssoptlen;
39236c6e 588 tp->t_mpflags &= ~TMPF_MPTCP_ACKNOW;
fe8ab488 589 goto ret_optlen;
39236c6e
A
590 }
591
592 /* 32-bit Data ACK option */
593 if ((tp->t_mpflags & TMPF_MPTCP_ACKNOW) &&
594 (!send_64bit_ack) &&
595 !(tp->t_mpflags & TMPF_SEND_DSN) &&
596 !(tp->t_mpflags & TMPF_SEND_DFIN)) {
597
598 struct mptcp_data_ack_opt dack_opt;
5ba3f43e 599 unsigned int dssoptlen = 0;
39236c6e 600do_ack32_only:
5ba3f43e 601 dssoptlen = sizeof (dack_opt);
39236c6e
A
602
603 CHECK_OPTLEN;
604
5ba3f43e 605 bzero(&dack_opt, dssoptlen);
39236c6e 606 dack_opt.mdss_copt.mdss_kind = TCPOPT_MULTIPATH;
5ba3f43e 607 dack_opt.mdss_copt.mdss_len = dssoptlen;
39236c6e
A
608 dack_opt.mdss_copt.mdss_subtype = MPO_DSS;
609 dack_opt.mdss_copt.mdss_flags |= MDSS_A;
39236c6e
A
610 dack_opt.mdss_ack =
611 htonl(MPTCP_DATAACK_LOW32(mp_tp->mpt_rcvnxt));
5ba3f43e
A
612 memcpy(opt + optlen, &dack_opt, dssoptlen);
613 optlen += dssoptlen;
39236c6e
A
614 VERIFY(optlen <= MAX_TCPOPTLEN);
615 tp->t_mpflags &= ~TMPF_MPTCP_ACKNOW;
fe8ab488 616 goto ret_optlen;
39236c6e
A
617 }
618
619 /* 64-bit Data ACK option */
620 if ((tp->t_mpflags & TMPF_MPTCP_ACKNOW) &&
621 (send_64bit_ack) &&
622 !(tp->t_mpflags & TMPF_SEND_DSN) &&
623 !(tp->t_mpflags & TMPF_SEND_DFIN)) {
624 struct mptcp_data_ack64_opt dack_opt;
5ba3f43e 625 unsigned int dssoptlen = 0;
39236c6e 626do_ack64_only:
5ba3f43e 627 dssoptlen = sizeof (dack_opt);
39236c6e
A
628
629 CHECK_OPTLEN;
630
5ba3f43e 631 bzero(&dack_opt, dssoptlen);
39236c6e 632 dack_opt.mdss_copt.mdss_kind = TCPOPT_MULTIPATH;
5ba3f43e 633 dack_opt.mdss_copt.mdss_len = dssoptlen;
39236c6e
A
634 dack_opt.mdss_copt.mdss_subtype = MPO_DSS;
635 dack_opt.mdss_copt.mdss_flags |= (MDSS_A | MDSS_a);
39236c6e
A
636 dack_opt.mdss_ack = mptcp_hton64(mp_tp->mpt_rcvnxt);
637 /*
638 * The other end should retransmit 64-bit DSN until it
639 * receives a 64-bit ACK.
640 */
641 mp_tp->mpt_flags &= ~MPTCPF_SND_64BITACK;
5ba3f43e
A
642 memcpy(opt + optlen, &dack_opt, dssoptlen);
643 optlen += dssoptlen;
39236c6e
A
644 VERIFY(optlen <= MAX_TCPOPTLEN);
645 tp->t_mpflags &= ~TMPF_MPTCP_ACKNOW;
fe8ab488 646 goto ret_optlen;
39236c6e
A
647 }
648
649 /* 32-bit DSS+Data ACK option */
650 if ((tp->t_mpflags & TMPF_SEND_DSN) &&
651 (!send_64bit_dsn) &&
652 (!send_64bit_ack) &&
653 (tp->t_mpflags & TMPF_MPTCP_ACKNOW)) {
654 struct mptcp_dss_ack_opt dss_ack_opt;
5ba3f43e
A
655 unsigned int dssoptlen = sizeof (dss_ack_opt);
656 uint16_t dss_csum;
39236c6e
A
657
658 if (do_csum)
5ba3f43e 659 dssoptlen += 2;
39236c6e
A
660
661 CHECK_OPTLEN;
662
663 bzero(&dss_ack_opt, sizeof (dss_ack_opt));
664 dss_ack_opt.mdss_copt.mdss_kind = TCPOPT_MULTIPATH;
5ba3f43e 665 dss_ack_opt.mdss_copt.mdss_len = dssoptlen;
39236c6e
A
666 dss_ack_opt.mdss_copt.mdss_subtype = MPO_DSS;
667 dss_ack_opt.mdss_copt.mdss_flags |= MDSS_A | MDSS_M;
39236c6e
A
668 dss_ack_opt.mdss_ack =
669 htonl(MPTCP_DATAACK_LOW32(mp_tp->mpt_rcvnxt));
39236c6e
A
670
671 CHECK_DATALEN;
672
5ba3f43e
A
673 mptcp_output_getm_dsnmap32(so, off, &dss_ack_opt.mdss_dsn,
674 &dss_ack_opt.mdss_subflow_seqn,
675 &dss_ack_opt.mdss_data_len,
676 &dss_csum);
39236c6e
A
677
678 if ((dss_ack_opt.mdss_data_len == 0) ||
679 (dss_ack_opt.mdss_dsn == 0)) {
680 goto do_ack32_only;
681 }
682
683 if (tp->t_mpflags & TMPF_SEND_DFIN) {
684 DO_FIN(dss_ack_opt);
685 }
686
687 dss_ack_opt.mdss_dsn = htonl(dss_ack_opt.mdss_dsn);
688 dss_ack_opt.mdss_subflow_seqn =
689 htonl(dss_ack_opt.mdss_subflow_seqn);
690 dss_ack_opt.mdss_data_len = htons(dss_ack_opt.mdss_data_len);
39236c6e 691 memcpy(opt + optlen, &dss_ack_opt, sizeof (dss_ack_opt));
5ba3f43e
A
692 if (do_csum)
693 *((uint16_t *)(void *)(opt + optlen + sizeof (dss_ack_opt))) = dss_csum;
39236c6e 694
5ba3f43e 695 optlen += dssoptlen;
39236c6e
A
696
697 if (optlen > MAX_TCPOPTLEN)
698 panic("optlen too large");
699 tp->t_mpflags &= ~TMPF_MPTCP_ACKNOW;
fe8ab488 700 goto ret_optlen;
39236c6e
A
701 }
702
703 /* 32-bit DSS + 64-bit DACK option */
704 if ((tp->t_mpflags & TMPF_SEND_DSN) &&
705 (!send_64bit_dsn) &&
706 (send_64bit_ack) &&
707 (tp->t_mpflags & TMPF_MPTCP_ACKNOW)) {
708 struct mptcp_dss32_ack64_opt dss_ack_opt;
5ba3f43e
A
709 unsigned int dssoptlen = sizeof (dss_ack_opt);
710 uint16_t dss_csum;
39236c6e
A
711
712 if (do_csum)
5ba3f43e 713 dssoptlen += 2;
39236c6e
A
714
715 CHECK_OPTLEN;
716
717 bzero(&dss_ack_opt, sizeof (dss_ack_opt));
718 dss_ack_opt.mdss_copt.mdss_kind = TCPOPT_MULTIPATH;
5ba3f43e 719 dss_ack_opt.mdss_copt.mdss_len = dssoptlen;
39236c6e
A
720 dss_ack_opt.mdss_copt.mdss_subtype = MPO_DSS;
721 dss_ack_opt.mdss_copt.mdss_flags |= MDSS_M | MDSS_A | MDSS_a;
39236c6e
A
722 dss_ack_opt.mdss_ack =
723 mptcp_hton64(mp_tp->mpt_rcvnxt);
39236c6e
A
724
725 CHECK_DATALEN;
726
5ba3f43e
A
727 mptcp_output_getm_dsnmap32(so, off, &dss_ack_opt.mdss_dsn,
728 &dss_ack_opt.mdss_subflow_seqn,
729 &dss_ack_opt.mdss_data_len,
730 &dss_csum);
39236c6e
A
731
732 if ((dss_ack_opt.mdss_data_len == 0) ||
733 (dss_ack_opt.mdss_dsn == 0)) {
734 goto do_ack64_only;
735 }
736
737 if (tp->t_mpflags & TMPF_SEND_DFIN) {
738 DO_FIN(dss_ack_opt);
739 }
740
741 dss_ack_opt.mdss_dsn = htonl(dss_ack_opt.mdss_dsn);
742 dss_ack_opt.mdss_subflow_seqn =
743 htonl(dss_ack_opt.mdss_subflow_seqn);
744 dss_ack_opt.mdss_data_len = htons(dss_ack_opt.mdss_data_len);
39236c6e 745 memcpy(opt + optlen, &dss_ack_opt, sizeof (dss_ack_opt));
5ba3f43e
A
746 if (do_csum)
747 *((uint16_t *)(void *)(opt + optlen + sizeof (dss_ack_opt))) = dss_csum;
39236c6e 748
5ba3f43e 749 optlen += dssoptlen;
39236c6e
A
750
751 if (optlen > MAX_TCPOPTLEN)
752 panic("optlen too large");
753 tp->t_mpflags &= ~TMPF_MPTCP_ACKNOW;
fe8ab488 754 goto ret_optlen;
39236c6e
A
755 }
756
757 if (tp->t_mpflags & TMPF_SEND_DFIN) {
758 struct mptcp_dss_ack_opt dss_ack_opt;
5ba3f43e 759 unsigned int dssoptlen = sizeof (struct mptcp_dss_ack_opt);
39236c6e
A
760
761 if (do_csum)
5ba3f43e 762 dssoptlen += 2;
39236c6e
A
763
764 CHECK_OPTLEN;
765
766 bzero(&dss_ack_opt, sizeof (dss_ack_opt));
767
fe8ab488
A
768 /*
769 * Data FIN occupies one sequence space.
770 * Don't send it if it has been Acked.
771 */
772 if (((mp_tp->mpt_sndnxt + 1) != mp_tp->mpt_sndmax) ||
5ba3f43e 773 (mp_tp->mpt_snduna == mp_tp->mpt_sndmax))
fe8ab488 774 goto ret_optlen;
39236c6e
A
775
776 dss_ack_opt.mdss_copt.mdss_kind = TCPOPT_MULTIPATH;
5ba3f43e 777 dss_ack_opt.mdss_copt.mdss_len = dssoptlen;
39236c6e
A
778 dss_ack_opt.mdss_copt.mdss_subtype = MPO_DSS;
779 dss_ack_opt.mdss_copt.mdss_flags |= MDSS_A | MDSS_M | MDSS_F;
780 dss_ack_opt.mdss_ack =
781 htonl(MPTCP_DATAACK_LOW32(mp_tp->mpt_rcvnxt));
782 dss_ack_opt.mdss_dsn =
783 htonl(MPTCP_DATASEQ_LOW32(mp_tp->mpt_sndnxt));
39236c6e
A
784 dss_ack_opt.mdss_subflow_seqn = 0;
785 dss_ack_opt.mdss_data_len = 1;
786 dss_ack_opt.mdss_data_len = htons(dss_ack_opt.mdss_data_len);
787 memcpy(opt + optlen, &dss_ack_opt, sizeof (dss_ack_opt));
5ba3f43e 788 optlen += dssoptlen;
39236c6e
A
789 }
790
fe8ab488
A
791ret_optlen:
792 if (TRUE == *p_mptcp_acknow ) {
793 VERIFY(old_mpt_flags != 0);
5ba3f43e 794 u_int32_t new_mpt_flags = tp->t_mpflags & TMPF_MPTCP_SIGNALS;
fe8ab488
A
795
796 /*
797 * If none of the above mpflags were acted on by
798 * this routine, reset these flags and set p_mptcp_acknow
799 * to false.
5ba3f43e 800 *
39037602 801 * XXX The reset value of p_mptcp_acknow can be used
fe8ab488
A
802 * to communicate tcp_output to NOT send a pure ack without any
803 * MPTCP options as it will be treated as a dup ack.
804 * Since the instances of mptcp_setup_opts not acting on
805 * these options are mostly corner cases and sending a dup
806 * ack here would only have an impact if the system
807 * has sent consecutive dup acks before this false one,
808 * we haven't modified the logic in tcp_output to avoid
809 * that.
810 */
5ba3f43e
A
811 if (old_mpt_flags == new_mpt_flags) {
812 tp->t_mpflags &= ~TMPF_MPTCP_SIGNALS;
fe8ab488 813 *p_mptcp_acknow = FALSE;
5ba3f43e
A
814 mptcplog((LOG_DEBUG, "%s: no action \n", __func__),
815 MPTCP_SENDER_DBG, MPTCP_LOGLVL_LOG);
3e170ce0 816 } else {
5ba3f43e
A
817 mptcplog((LOG_DEBUG, "%s: acknow set, old flags %x new flags %x \n",
818 __func__, old_mpt_flags, new_mpt_flags),
3e170ce0 819 MPTCP_SENDER_DBG, MPTCP_LOGLVL_LOG);
fe8ab488
A
820 }
821 }
822
823 return optlen;
39236c6e
A
824}
825
826/*
827 * MPTCP Options Input Processing
828 */
829
3e170ce0
A
830static int
831mptcp_sanitize_option(struct tcpcb *tp, int mptcp_subtype)
832{
833 struct mptcb *mp_tp = tptomptp(tp);
834 int ret = 1;
835
836 if (mp_tp == NULL) {
5ba3f43e
A
837 mptcplog((LOG_ERR, "%s: NULL mpsocket \n", __func__),
838 MPTCP_SOCKET_DBG, MPTCP_LOGLVL_ERR);
3e170ce0
A
839 return (0);
840 }
841
842 switch (mptcp_subtype) {
843 case MPO_CAPABLE:
844 break;
845 case MPO_JOIN: /* fall through */
846 case MPO_DSS: /* fall through */
847 case MPO_FASTCLOSE: /* fall through */
848 case MPO_FAIL: /* fall through */
849 case MPO_REMOVE_ADDR: /* fall through */
850 case MPO_ADD_ADDR: /* fall through */
851 case MPO_PRIO: /* fall through */
852 if (mp_tp->mpt_state < MPTCPS_ESTABLISHED)
853 ret = 0;
854 break;
855 default:
856 ret = 0;
5ba3f43e 857 mptcplog((LOG_ERR, "%s: type = %d \n", __func__,
3e170ce0
A
858 mptcp_subtype),
859 MPTCP_SOCKET_DBG, MPTCP_LOGLVL_ERR);
860 break;
861 }
862 return (ret);
863}
39236c6e
A
864
865static int
3e170ce0 866mptcp_valid_mpcapable_common_opt(u_char *cp)
39236c6e
A
867{
868 struct mptcp_mpcapable_opt_common *rsp =
869 (struct mptcp_mpcapable_opt_common *)cp;
870
871 /* mmco_kind, mmco_len and mmco_subtype are validated before */
872
39236c6e
A
873 if (!(rsp->mmco_flags & MPCAP_PROPOSAL_SBIT))
874 return (0);
875
876 if (rsp->mmco_flags & (MPCAP_BBIT | MPCAP_CBIT | MPCAP_DBIT |
877 MPCAP_EBIT | MPCAP_FBIT | MPCAP_GBIT))
878 return (0);
879
880 return (1);
881}
882
883
884static void
885mptcp_do_mpcapable_opt(struct tcpcb *tp, u_char *cp, struct tcphdr *th,
886 int optlen)
887{
39236c6e
A
888 struct mptcp_mpcapable_opt_rsp *rsp = NULL;
889 struct mptcb *mp_tp = tptomptp(tp);
890
5ba3f43e
A
891 mpte_lock_assert_held(mp_tp->mpt_mpte);
892
39037602
A
893 /* Only valid on SYN/ACK */
894 if ((th->th_flags & (TH_SYN | TH_ACK)) != (TH_SYN | TH_ACK))
895 return;
39236c6e 896
39236c6e 897 /* Validate the kind, len, flags */
3e170ce0 898 if (mptcp_valid_mpcapable_common_opt(cp) != 1) {
39236c6e
A
899 tcpstat.tcps_invalid_mpcap++;
900 return;
901 }
902
39037602 903 /* handle SYN/ACK retransmission by acknowledging with ACK */
d190cdc3 904 if (mp_tp->mpt_state >= MPTCPS_ESTABLISHED)
39037602 905 return;
3e170ce0 906
39037602
A
907 /* A SYN/ACK contains peer's key and flags */
908 if (optlen != sizeof (struct mptcp_mpcapable_opt_rsp)) {
909 /* complain */
5ba3f43e 910 mptcplog((LOG_ERR, "%s: SYN_ACK optlen = %d, sizeof mp opt = %lu \n",
39037602
A
911 __func__, optlen,
912 sizeof (struct mptcp_mpcapable_opt_rsp)),
913 MPTCP_SOCKET_DBG, MPTCP_LOGLVL_ERR);
914 tcpstat.tcps_invalid_mpcap++;
915 return;
916 }
39236c6e 917
39037602
A
918 /*
919 * If checksum flag is set, enable MPTCP checksum, even if
920 * it was not negotiated on the first SYN.
921 */
922 if (((struct mptcp_mpcapable_opt_common *)cp)->mmco_flags &
923 MPCAP_CHECKSUM_CBIT)
924 mp_tp->mpt_flags |= MPTCPF_CHECKSUM;
39236c6e 925
39037602 926 rsp = (struct mptcp_mpcapable_opt_rsp *)cp;
39037602
A
927 mp_tp->mpt_remotekey = rsp->mmc_localkey;
928 /* For now just downgrade to the peer's version */
929 mp_tp->mpt_peer_version = rsp->mmc_common.mmco_version;
930 if (rsp->mmc_common.mmco_version < mp_tp->mpt_version) {
931 mp_tp->mpt_version = rsp->mmc_common.mmco_version;
932 tcpstat.tcps_mp_verdowngrade++;
933 }
934 if (mptcp_init_remote_parms(mp_tp) != 0) {
935 tcpstat.tcps_invalid_mpcap++;
39037602 936 return;
39236c6e 937 }
39037602 938 tcp_heuristic_mptcp_success(tp);
5ba3f43e
A
939 tp->t_mpflags |= (TMPF_SND_KEYS | TMPF_MPTCP_TRUE);
940 tp->t_inpcb->inp_socket->so_flags |= SOF_MPTCP_TRUE;
39236c6e
A
941}
942
943
944static void
945mptcp_do_mpjoin_opt(struct tcpcb *tp, u_char *cp, struct tcphdr *th, int optlen)
946{
947#define MPTCP_JOPT_ERROR_PATH(tp) { \
948 tp->t_mpflags |= TMPF_RESET; \
949 tcpstat.tcps_invalid_joins++; \
950 if (tp->t_inpcb->inp_socket != NULL) { \
951 soevent(tp->t_inpcb->inp_socket, \
952 SO_FILT_HINT_LOCKED | SO_FILT_HINT_MUSTRST); \
953 } \
954}
955 int error = 0;
39037602
A
956 struct mptcp_mpjoin_opt_rsp *join_rsp =
957 (struct mptcp_mpjoin_opt_rsp *)cp;
39236c6e 958
39037602
A
959 /* Only valid on SYN/ACK */
960 if ((th->th_flags & (TH_SYN | TH_ACK)) != (TH_SYN | TH_ACK))
39236c6e 961 return;
39236c6e 962
39037602 963 if (optlen != sizeof (struct mptcp_mpjoin_opt_rsp)) {
5ba3f43e
A
964 mptcplog((LOG_ERR, "%s: SYN_ACK: unexpected optlen = %d mp "
965 "option = %lu\n", __func__, optlen,
39037602
A
966 sizeof (struct mptcp_mpjoin_opt_rsp)),
967 MPTCP_SOCKET_DBG, MPTCP_LOGLVL_ERR);
968 tp->t_mpflags &= ~TMPF_PREESTABLISHED;
969 /* send RST and close */
970 MPTCP_JOPT_ERROR_PATH(tp);
971 return;
972 }
39236c6e 973
39037602
A
974 mptcp_set_raddr_rand(tp->t_local_aid, tptomptp(tp),
975 join_rsp->mmjo_addr_id, join_rsp->mmjo_rand);
976 error = mptcp_validate_join_hmac(tp,
977 (u_char*)&join_rsp->mmjo_mac, SHA1_TRUNCATED);
978 if (error) {
5ba3f43e 979 mptcplog((LOG_ERR, "%s: SYN_ACK error = %d \n", __func__, error),
39037602 980 MPTCP_SOCKET_DBG, MPTCP_LOGLVL_ERR);
39236c6e 981 tp->t_mpflags &= ~TMPF_PREESTABLISHED;
39037602
A
982 /* send RST and close */
983 MPTCP_JOPT_ERROR_PATH(tp);
984 return;
39236c6e 985 }
5ba3f43e 986 tp->t_mpflags |= (TMPF_SENT_JOIN | TMPF_SND_JACK);
39236c6e
A
987}
988
989static int
990mptcp_validate_join_hmac(struct tcpcb *tp, u_char* hmac, int mac_len)
991{
992 u_char digest[SHA1_RESULTLEN] = {0};
5ba3f43e 993 struct mptcb *mp_tp = tptomptp(tp);
39236c6e
A
994 u_int32_t rem_rand, loc_rand;
995
5ba3f43e 996 mpte_lock_assert_held(mp_tp->mpt_mpte);
39236c6e
A
997
998 rem_rand = loc_rand = 0;
999
39236c6e
A
1000 mptcp_get_rands(tp->t_local_aid, mp_tp, &loc_rand, &rem_rand);
1001 if ((rem_rand == 0) || (loc_rand == 0))
1002 return (-1);
1003
5ba3f43e
A
1004 mptcp_hmac_sha1(mp_tp->mpt_remotekey, mp_tp->mpt_localkey, rem_rand, loc_rand,
1005 digest);
39236c6e
A
1006
1007 if (bcmp(digest, hmac, mac_len) == 0)
1008 return (0); /* matches */
1009 else {
1010 printf("%s: remote key %llx local key %llx remote rand %x "
5ba3f43e 1011 "local rand %x \n", __func__, mp_tp->mpt_remotekey, mp_tp->mpt_localkey,
39236c6e
A
1012 rem_rand, loc_rand);
1013 return (-1);
1014 }
1015}
1016
5ba3f43e
A
1017/*
1018 * Update the mptcb send state variables, but the actual sbdrop occurs
1019 * in MPTCP layer
1020 */
1021void
1022mptcp_data_ack_rcvd(struct mptcb *mp_tp, struct tcpcb *tp, u_int64_t full_dack)
1023{
1024 u_int64_t acked = 0;
1025
1026 acked = full_dack - mp_tp->mpt_snduna;
1027
1028 if (acked) {
1029 struct socket *mp_so = mptetoso(mp_tp->mpt_mpte);
1030
1031 if (acked > mp_so->so_snd.sb_cc) {
1032 if (acked > mp_so->so_snd.sb_cc + 1 ||
1033 mp_tp->mpt_state < MPTCPS_FIN_WAIT_1)
1034 mptcplog((LOG_ERR, "%s: acked %u, sb_cc %u full %u suna %u state %u\n",
1035 __func__, (uint32_t)acked, mp_so->so_snd.sb_cc,
1036 (uint32_t)full_dack, (uint32_t)mp_tp->mpt_snduna,
1037 mp_tp->mpt_state),
1038 MPTCP_RECEIVER_DBG, MPTCP_LOGLVL_ERR);
1039
1040 sbdrop(&mp_so->so_snd, (int)mp_so->so_snd.sb_cc);
1041 } else {
1042 sbdrop(&mp_so->so_snd, acked);
1043 }
1044
1045 mp_tp->mpt_snduna += acked;
1046 /* In degraded mode, we may get some Data ACKs */
1047 if ((tp->t_mpflags & TMPF_TCP_FALLBACK) &&
1048 !(mp_tp->mpt_flags & MPTCPF_POST_FALLBACK_SYNC) &&
1049 MPTCP_SEQ_GT(mp_tp->mpt_sndnxt, mp_tp->mpt_snduna)) {
1050 /* bring back sndnxt to retransmit MPTCP data */
1051 mp_tp->mpt_sndnxt = mp_tp->mpt_dsn_at_csum_fail;
1052 mp_tp->mpt_flags |= MPTCPF_POST_FALLBACK_SYNC;
1053 tp->t_inpcb->inp_socket->so_flags1 |=
1054 SOF1_POST_FALLBACK_SYNC;
1055 }
1056
1057 mptcp_clean_reinjectq(mp_tp->mpt_mpte);
1058
1059 sowwakeup(mp_so);
1060 }
1061 if (full_dack == mp_tp->mpt_sndmax &&
1062 mp_tp->mpt_state >= MPTCPS_FIN_WAIT_1) {
1063 mptcp_close_fsm(mp_tp, MPCE_RECV_DATA_ACK);
1064 tp->t_mpflags &= ~TMPF_SEND_DFIN;
1065 }
1066}
1067
1068void
1069mptcp_update_window_fallback(struct tcpcb *tp)
1070{
1071 struct mptcb *mp_tp = tptomptp(tp);
1072
1073 mpte_lock_assert_held(mp_tp->mpt_mpte);
1074
1075 if (!(mp_tp->mpt_flags & MPTCPF_FALLBACK_TO_TCP))
1076 return;
1077
1078 mptcplog((LOG_DEBUG, "%s: update window to %u\n", __func__, tp->snd_wnd),
1079 MPTCP_SOCKET_DBG, MPTCP_LOGLVL_VERBOSE);
1080
1081 mp_tp->mpt_sndwnd = tp->snd_wnd;
1082 mp_tp->mpt_sndwl1 = mp_tp->mpt_rcvnxt;
1083 mp_tp->mpt_sndwl2 = mp_tp->mpt_snduna;
1084
1085 sowwakeup(tp->t_inpcb->inp_socket);
1086}
1087
1088static void
1089mptcp_update_window(struct mptcb *mp_tp, u_int64_t ack, u_int64_t seq,
1090 u_int32_t tiwin)
1091{
1092 /* Don't look at the window if there is no ACK flag */
1093 if ((SEQ_LT(mp_tp->mpt_sndwl1, seq) ||
1094 (mp_tp->mpt_sndwl1 == seq && (SEQ_LT(mp_tp->mpt_sndwl2, ack) ||
1095 (mp_tp->mpt_sndwl2 == ack && tiwin > mp_tp->mpt_sndwnd))))) {
1096 mp_tp->mpt_sndwnd = tiwin;
1097 mp_tp->mpt_sndwl1 = seq;
1098 mp_tp->mpt_sndwl2 = ack;
1099
1100 mptcplog((LOG_DEBUG, "%s: Updating window to %u\n", __func__,
1101 mp_tp->mpt_sndwnd), MPTCP_RECEIVER_DBG, MPTCP_LOGLVL_VERBOSE);
1102 }
1103}
1104
39236c6e 1105static void
5ba3f43e
A
1106mptcp_do_dss_opt_ack_meat(u_int64_t full_dack, u_int64_t full_dsn,
1107 struct tcpcb *tp, u_int32_t tiwin)
39236c6e
A
1108{
1109 struct mptcb *mp_tp = tptomptp(tp);
1110 int close_notify = 0;
1111
39037602
A
1112 tp->t_mpflags |= TMPF_RCVD_DACK;
1113
39236c6e
A
1114 if (MPTCP_SEQ_LEQ(full_dack, mp_tp->mpt_sndmax) &&
1115 MPTCP_SEQ_GEQ(full_dack, mp_tp->mpt_snduna)) {
1116 mptcp_data_ack_rcvd(mp_tp, tp, full_dack);
fe8ab488 1117 if (mp_tp->mpt_state > MPTCPS_FIN_WAIT_2)
39236c6e 1118 close_notify = 1;
39236c6e
A
1119 if (mp_tp->mpt_flags & MPTCPF_RCVD_64BITACK) {
1120 mp_tp->mpt_flags &= ~MPTCPF_RCVD_64BITACK;
1121 mp_tp->mpt_flags &= ~MPTCPF_SND_64BITDSN;
1122 }
490019cf
A
1123 mptcp_notify_mpready(tp->t_inpcb->inp_socket);
1124 if (close_notify)
1125 mptcp_notify_close(tp->t_inpcb->inp_socket);
39236c6e 1126 } else {
5ba3f43e
A
1127 mptcplog((LOG_ERR,"%s: unexpected dack %u snduna %u sndmax %u\n", __func__,
1128 (u_int32_t)full_dack, (u_int32_t)mp_tp->mpt_snduna,
1129 (u_int32_t)mp_tp->mpt_sndmax),
3e170ce0
A
1130 (MPTCP_SOCKET_DBG|MPTCP_RECEIVER_DBG),
1131 MPTCP_LOGLVL_LOG);
39236c6e 1132 }
5ba3f43e
A
1133
1134 mptcp_update_window(mp_tp, full_dack, full_dsn, tiwin);
39236c6e
A
1135}
1136
1137static void
5ba3f43e 1138mptcp_do_dss_opt_meat(u_char *cp, struct tcpcb *tp, struct tcphdr *th)
39236c6e
A
1139{
1140 struct mptcp_dss_copt *dss_rsp = (struct mptcp_dss_copt *)cp;
1141 u_int64_t full_dack = 0;
5ba3f43e 1142 u_int32_t tiwin = th->th_win << tp->snd_scale;
39236c6e
A
1143 struct mptcb *mp_tp = tptomptp(tp);
1144 int csum_len = 0;
1145
5ba3f43e
A
1146#define MPTCP_DSS_OPT_SZ_CHK(len, expected_len) { \
1147 if (len != expected_len) { \
1148 mptcplog((LOG_ERR, "%s: bad len = %d dss: %x \n", __func__, \
1149 len, dss_rsp->mdss_flags), \
1150 (MPTCP_SOCKET_DBG|MPTCP_RECEIVER_DBG), \
1151 MPTCP_LOGLVL_LOG); \
1152 return; \
1153 } \
39236c6e 1154}
39236c6e
A
1155
1156 if (mp_tp->mpt_flags & MPTCPF_CHECKSUM)
1157 csum_len = 2;
1158
1159 dss_rsp->mdss_flags &= (MDSS_A|MDSS_a|MDSS_M|MDSS_m);
1160 switch (dss_rsp->mdss_flags) {
1161 case (MDSS_M):
1162 {
1163 /* 32-bit DSS, No Data ACK */
1164 struct mptcp_dsn_opt *dss_rsp1;
1165 dss_rsp1 = (struct mptcp_dsn_opt *)cp;
1166
1167 MPTCP_DSS_OPT_SZ_CHK(dss_rsp1->mdss_copt.mdss_len,
1168 sizeof (struct mptcp_dsn_opt) + csum_len);
1169 if (csum_len == 0)
1170 mptcp_update_dss_rcv_state(dss_rsp1, tp, 0);
1171 else
1172 mptcp_update_dss_rcv_state(dss_rsp1, tp,
1173 *(uint16_t *)(void *)(cp +
1174 (dss_rsp1->mdss_copt.mdss_len - csum_len)));
1175 break;
1176 }
1177 case (MDSS_A):
1178 {
1179 /* 32-bit Data ACK, no DSS */
1180 struct mptcp_data_ack_opt *dack_opt;
1181 dack_opt = (struct mptcp_data_ack_opt *)cp;
1182
1183 MPTCP_DSS_OPT_SZ_CHK(dack_opt->mdss_copt.mdss_len,
1184 sizeof (struct mptcp_data_ack_opt));
1185
1186 u_int32_t dack = dack_opt->mdss_ack;
1187 NTOHL(dack);
39236c6e 1188 MPTCP_EXTEND_DSN(mp_tp->mpt_snduna, dack, full_dack);
5ba3f43e 1189 mptcp_do_dss_opt_ack_meat(full_dack, mp_tp->mpt_sndwl1, tp, tiwin);
39236c6e
A
1190 break;
1191 }
1192 case (MDSS_M | MDSS_A):
1193 {
1194 /* 32-bit Data ACK + 32-bit DSS */
1195 struct mptcp_dss_ack_opt *dss_ack_rsp;
1196 dss_ack_rsp = (struct mptcp_dss_ack_opt *)cp;
5ba3f43e
A
1197 u_int64_t full_dsn;
1198 uint16_t csum = 0;
39236c6e
A
1199
1200 MPTCP_DSS_OPT_SZ_CHK(dss_ack_rsp->mdss_copt.mdss_len,
1201 sizeof (struct mptcp_dss_ack_opt) + csum_len);
1202
1203 u_int32_t dack = dss_ack_rsp->mdss_ack;
1204 NTOHL(dack);
39236c6e 1205 MPTCP_EXTEND_DSN(mp_tp->mpt_snduna, dack, full_dack);
5ba3f43e
A
1206
1207 NTOHL(dss_ack_rsp->mdss_dsn);
1208 NTOHL(dss_ack_rsp->mdss_subflow_seqn);
1209 NTOHS(dss_ack_rsp->mdss_data_len);
1210 MPTCP_EXTEND_DSN(mp_tp->mpt_rcvnxt, dss_ack_rsp->mdss_dsn, full_dsn);
1211
1212 mptcp_do_dss_opt_ack_meat(full_dack, full_dsn, tp, tiwin);
1213
1214 if (csum_len != 0)
1215 csum = *(uint16_t *)(void *)(cp + (dss_ack_rsp->mdss_copt.mdss_len - csum_len));
1216
1217 mptcp_update_rcv_state_meat(mp_tp, tp,
1218 full_dsn,
1219 dss_ack_rsp->mdss_subflow_seqn,
1220 dss_ack_rsp->mdss_data_len,
1221 csum);
39236c6e
A
1222 break;
1223 }
1224 case (MDSS_M | MDSS_m):
1225 {
1226 /* 64-bit DSS , No Data ACK */
1227 struct mptcp_dsn64_opt *dsn64;
1228 dsn64 = (struct mptcp_dsn64_opt *)cp;
1229 u_int64_t full_dsn;
5ba3f43e 1230 uint16_t csum = 0;
39236c6e
A
1231
1232 MPTCP_DSS_OPT_SZ_CHK(dsn64->mdss_copt.mdss_len,
1233 sizeof (struct mptcp_dsn64_opt) + csum_len);
1234
39236c6e 1235 mp_tp->mpt_flags |= MPTCPF_SND_64BITACK;
39236c6e
A
1236
1237 full_dsn = mptcp_ntoh64(dsn64->mdss_dsn);
1238 NTOHL(dsn64->mdss_subflow_seqn);
1239 NTOHS(dsn64->mdss_data_len);
5ba3f43e
A
1240
1241 if (csum_len != 0)
1242 csum = *(uint16_t *)(void *)(cp + dsn64->mdss_copt.mdss_len - csum_len);
1243
1244 mptcp_update_rcv_state_meat(mp_tp, tp, full_dsn,
1245 dsn64->mdss_subflow_seqn,
1246 dsn64->mdss_data_len,
1247 csum);
39236c6e
A
1248 break;
1249 }
1250 case (MDSS_A | MDSS_a):
1251 {
1252 /* 64-bit Data ACK, no DSS */
1253 struct mptcp_data_ack64_opt *dack64;
1254 dack64 = (struct mptcp_data_ack64_opt *)cp;
1255
1256 MPTCP_DSS_OPT_SZ_CHK(dack64->mdss_copt.mdss_len,
1257 sizeof (struct mptcp_data_ack64_opt));
1258
39236c6e 1259 mp_tp->mpt_flags |= MPTCPF_RCVD_64BITACK;
39236c6e
A
1260
1261 full_dack = mptcp_ntoh64(dack64->mdss_ack);
5ba3f43e 1262 mptcp_do_dss_opt_ack_meat(full_dack, mp_tp->mpt_sndwl1, tp, tiwin);
39236c6e
A
1263 break;
1264 }
1265 case (MDSS_M | MDSS_m | MDSS_A):
1266 {
1267 /* 64-bit DSS + 32-bit Data ACK */
1268 struct mptcp_dss64_ack32_opt *dss_ack_rsp;
1269 dss_ack_rsp = (struct mptcp_dss64_ack32_opt *)cp;
5ba3f43e
A
1270 u_int64_t full_dsn;
1271 uint16_t csum = 0;
39236c6e
A
1272
1273 MPTCP_DSS_OPT_SZ_CHK(dss_ack_rsp->mdss_copt.mdss_len,
1274 sizeof (struct mptcp_dss64_ack32_opt) + csum_len);
1275
39236c6e
A
1276 u_int32_t dack = dss_ack_rsp->mdss_ack;
1277 NTOHL(dack);
39236c6e
A
1278 mp_tp->mpt_flags |= MPTCPF_SND_64BITACK;
1279 MPTCP_EXTEND_DSN(mp_tp->mpt_snduna, dack, full_dack);
5ba3f43e
A
1280
1281 full_dsn = mptcp_ntoh64(dss_ack_rsp->mdss_dsn);
1282 NTOHL(dss_ack_rsp->mdss_subflow_seqn);
1283 NTOHS(dss_ack_rsp->mdss_data_len);
1284
1285 mptcp_do_dss_opt_ack_meat(full_dack, full_dsn, tp, tiwin);
1286
1287 if (csum_len != 0)
1288 csum = *(uint16_t *)(void *)(cp + dss_ack_rsp->mdss_copt.mdss_len - csum_len);
1289
1290 mptcp_update_rcv_state_meat(mp_tp, tp, full_dsn,
1291 dss_ack_rsp->mdss_subflow_seqn,
1292 dss_ack_rsp->mdss_data_len,
1293 csum);
1294
39236c6e
A
1295 break;
1296 }
1297 case (MDSS_M | MDSS_A | MDSS_a):
1298 {
1299 /* 32-bit DSS + 64-bit Data ACK */
1300 struct mptcp_dss32_ack64_opt *dss32_ack64_opt;
1301 dss32_ack64_opt = (struct mptcp_dss32_ack64_opt *)cp;
1302 u_int64_t full_dsn;
1303
1304 MPTCP_DSS_OPT_SZ_CHK(
1305 dss32_ack64_opt->mdss_copt.mdss_len,
1306 sizeof (struct mptcp_dss32_ack64_opt) + csum_len);
1307
39236c6e 1308 full_dack = mptcp_ntoh64(dss32_ack64_opt->mdss_ack);
39236c6e 1309 NTOHL(dss32_ack64_opt->mdss_dsn);
39236c6e
A
1310 mp_tp->mpt_flags |= MPTCPF_RCVD_64BITACK;
1311 MPTCP_EXTEND_DSN(mp_tp->mpt_rcvnxt,
1312 dss32_ack64_opt->mdss_dsn, full_dsn);
39236c6e
A
1313 NTOHL(dss32_ack64_opt->mdss_subflow_seqn);
1314 NTOHS(dss32_ack64_opt->mdss_data_len);
5ba3f43e
A
1315
1316 mptcp_do_dss_opt_ack_meat(full_dack, full_dsn, tp, tiwin);
39236c6e
A
1317 if (csum_len == 0)
1318 mptcp_update_rcv_state_meat(mp_tp, tp, full_dsn,
1319 dss32_ack64_opt->mdss_subflow_seqn,
1320 dss32_ack64_opt->mdss_data_len, 0);
1321 else
1322 mptcp_update_rcv_state_meat(mp_tp, tp, full_dsn,
1323 dss32_ack64_opt->mdss_subflow_seqn,
1324 dss32_ack64_opt->mdss_data_len,
1325 *(uint16_t *)(void *)(cp +
1326 dss32_ack64_opt->mdss_copt.mdss_len -
1327 csum_len));
1328 break;
1329 }
1330 case (MDSS_M | MDSS_m | MDSS_A | MDSS_a):
1331 {
1332 /* 64-bit DSS + 64-bit Data ACK */
1333 struct mptcp_dss64_ack64_opt *dss64_ack64;
1334 dss64_ack64 = (struct mptcp_dss64_ack64_opt *)cp;
1335 u_int64_t full_dsn;
1336
1337 MPTCP_DSS_OPT_SZ_CHK(dss64_ack64->mdss_copt.mdss_len,
1338 sizeof (struct mptcp_dss64_ack64_opt) + csum_len);
1339
39236c6e
A
1340 mp_tp->mpt_flags |= MPTCPF_RCVD_64BITACK;
1341 mp_tp->mpt_flags |= MPTCPF_SND_64BITACK;
39236c6e
A
1342 full_dsn = mptcp_ntoh64(dss64_ack64->mdss_dsn);
1343 full_dack = mptcp_ntoh64(dss64_ack64->mdss_dsn);
5ba3f43e 1344 mptcp_do_dss_opt_ack_meat(full_dack, full_dsn, tp, tiwin);
39236c6e
A
1345 NTOHL(dss64_ack64->mdss_subflow_seqn);
1346 NTOHS(dss64_ack64->mdss_data_len);
1347 if (csum_len == 0)
1348 mptcp_update_rcv_state_meat(mp_tp, tp, full_dsn,
1349 dss64_ack64->mdss_subflow_seqn,
1350 dss64_ack64->mdss_data_len, 0);
1351 else
1352 mptcp_update_rcv_state_meat(mp_tp, tp, full_dsn,
1353 dss64_ack64->mdss_subflow_seqn,
1354 dss64_ack64->mdss_data_len,
1355 *(uint16_t *)(void *)(cp +
1356 dss64_ack64->mdss_copt.mdss_len -
1357 csum_len));
1358 break;
1359 }
1360 default:
5ba3f43e
A
1361 mptcplog((LOG_DEBUG,"%s: File bug, DSS flags = %x\n",
1362 __func__, dss_rsp->mdss_flags),
3e170ce0
A
1363 (MPTCP_SOCKET_DBG|MPTCP_RECEIVER_DBG),
1364 MPTCP_LOGLVL_LOG);
39236c6e
A
1365 break;
1366 }
1367}
1368
39236c6e
A
1369static void
1370mptcp_do_dss_opt(struct tcpcb *tp, u_char *cp, struct tcphdr *th, int optlen)
1371{
5ba3f43e
A
1372#pragma unused(optlen)
1373 struct mptcb *mp_tp = tptomptp(tp);
39236c6e
A
1374
1375 if (!mp_tp)
1376 return;
1377
fe8ab488
A
1378 /* We may get Data ACKs just during fallback, so don't ignore those */
1379 if ((tp->t_mpflags & TMPF_MPTCP_TRUE) ||
1380 (tp->t_mpflags & TMPF_TCP_FALLBACK)) {
39236c6e
A
1381 struct mptcp_dss_copt *dss_rsp = (struct mptcp_dss_copt *)cp;
1382
1383 if (dss_rsp->mdss_subtype == MPO_DSS) {
5c9f4661
A
1384 if (dss_rsp->mdss_flags & MDSS_F)
1385 tp->t_rcv_map.mpt_dfin = 1;
39236c6e 1386
5ba3f43e 1387 mptcp_do_dss_opt_meat(cp, tp, th);
39236c6e
A
1388 }
1389 }
1390}
1391
1392static void
1393mptcp_do_fastclose_opt(struct tcpcb *tp, u_char *cp, struct tcphdr *th)
1394{
1395 struct mptcb *mp_tp = NULL;
1396 struct mptcp_fastclose_opt *fc_opt = (struct mptcp_fastclose_opt *)cp;
1397
1398 if (th->th_flags != TH_ACK)
1399 return;
1400
39236c6e
A
1401 if (fc_opt->mfast_len != sizeof (struct mptcp_fastclose_opt)) {
1402 tcpstat.tcps_invalid_opt++;
1403 return;
1404 }
1405
5ba3f43e 1406 mp_tp = tptomptp(tp);
39236c6e
A
1407 if (!mp_tp)
1408 return;
1409
5ba3f43e 1410 if (fc_opt->mfast_key != mp_tp->mpt_localkey) {
39236c6e
A
1411 tcpstat.tcps_invalid_opt++;
1412 return;
1413 }
1414
1415 /*
1416 * fastclose could make us more vulnerable to attacks, hence
1417 * accept only those that are at the next expected sequence number.
1418 */
1419 if (th->th_seq != tp->rcv_nxt) {
1420 tcpstat.tcps_invalid_opt++;
1421 return;
1422 }
1423
39236c6e 1424 /* Reset this flow */
39037602 1425 tp->t_mpflags |= (TMPF_RESET | TMPF_FASTCLOSERCV);
39236c6e
A
1426
1427 if (tp->t_inpcb->inp_socket != NULL) {
1428 soevent(tp->t_inpcb->inp_socket,
1429 SO_FILT_HINT_LOCKED | SO_FILT_HINT_MUSTRST);
1430 }
1431}
1432
1433
1434static void
1435mptcp_do_mpfail_opt(struct tcpcb *tp, u_char *cp, struct tcphdr *th)
1436{
1437 struct mptcb *mp_tp = NULL;
1438 struct mptcp_mpfail_opt *fail_opt = (struct mptcp_mpfail_opt *)cp;
fe8ab488
A
1439 u_int32_t mdss_subflow_seqn = 0;
1440 int error = 0;
39236c6e 1441
fe8ab488
A
1442 /*
1443 * mpfail could make us more vulnerable to attacks. Hence accept
1444 * only those that are the next expected sequence number.
1445 */
1446 if (th->th_seq != tp->rcv_nxt) {
1447 tcpstat.tcps_invalid_opt++;
1448 return;
1449 }
1450
1451 /* A packet without RST, must atleast have the ACK bit set */
1452 if ((th->th_flags != TH_ACK) && (th->th_flags != TH_RST))
39236c6e
A
1453 return;
1454
1455 if (fail_opt->mfail_len != sizeof (struct mptcp_mpfail_opt))
1456 return;
1457
5ba3f43e
A
1458 mp_tp = tptomptp(tp);
1459
39236c6e
A
1460 mp_tp->mpt_flags |= MPTCPF_RECVD_MPFAIL;
1461 mp_tp->mpt_dsn_at_csum_fail = mptcp_hton64(fail_opt->mfail_dsn);
5ba3f43e 1462 error = mptcp_get_map_for_dsn(tp->t_inpcb->inp_socket,
fe8ab488
A
1463 mp_tp->mpt_dsn_at_csum_fail, &mdss_subflow_seqn);
1464 if (error == 0) {
1465 mp_tp->mpt_ssn_at_csum_fail = mdss_subflow_seqn;
1466 }
39236c6e
A
1467
1468 mptcp_notify_mpfail(tp->t_inpcb->inp_socket);
1469}
1470
3e170ce0 1471void
39236c6e
A
1472tcp_do_mptcp_options(struct tcpcb *tp, u_char *cp, struct tcphdr *th,
1473 struct tcpopt *to, int optlen)
1474{
1475 int mptcp_subtype;
5ba3f43e
A
1476 struct mptcb *mp_tp = tptomptp(tp);
1477
1478 if (mp_tp == NULL)
1479 return;
1480
1481 mpte_lock_assert_held(mp_tp->mpt_mpte);
39236c6e
A
1482
1483 /* All MPTCP options have atleast 4 bytes */
1484 if (optlen < 4)
3e170ce0 1485 return;
39236c6e
A
1486
1487 mptcp_subtype = (cp[2] >> 4);
1488
3e170ce0
A
1489 if (mptcp_sanitize_option(tp, mptcp_subtype) == 0)
1490 return;
1491
39236c6e
A
1492 switch (mptcp_subtype) {
1493 case MPO_CAPABLE:
1494 mptcp_do_mpcapable_opt(tp, cp, th, optlen);
1495 break;
1496 case MPO_JOIN:
1497 mptcp_do_mpjoin_opt(tp, cp, th, optlen);
1498 break;
1499 case MPO_DSS:
1500 mptcp_do_dss_opt(tp, cp, th, optlen);
1501 break;
1502 case MPO_FASTCLOSE:
1503 mptcp_do_fastclose_opt(tp, cp, th);
1504 break;
1505 case MPO_FAIL:
1506 mptcp_do_mpfail_opt(tp, cp, th);
1507 break;
1508 case MPO_ADD_ADDR: /* fall through */
1509 case MPO_REMOVE_ADDR: /* fall through */
1510 case MPO_PRIO:
1511 to->to_flags |= TOF_MPTCP;
1512 break;
1513 default:
39236c6e
A
1514 break;
1515 }
3e170ce0 1516 return;
39236c6e
A
1517}
1518
39236c6e 1519/* REMOVE_ADDR option is sent when a source address goes away */
5ba3f43e 1520static void
39236c6e
A
1521mptcp_send_remaddr_opt(struct tcpcb *tp, struct mptcp_remaddr_opt *opt)
1522{
5ba3f43e 1523 mptcplog((LOG_DEBUG,"%s: local id %d remove id %d \n",
3e170ce0
A
1524 __func__, tp->t_local_aid, tp->t_rem_aid),
1525 (MPTCP_SOCKET_DBG|MPTCP_SENDER_DBG), MPTCP_LOGLVL_LOG);
39236c6e 1526
fe8ab488 1527 bzero(opt, sizeof (*opt));
39236c6e 1528 opt->mr_kind = TCPOPT_MULTIPATH;
fe8ab488 1529 opt->mr_len = sizeof (*opt);
39236c6e
A
1530 opt->mr_subtype = MPO_REMOVE_ADDR;
1531 opt->mr_addr_id = tp->t_rem_aid;
1532 tp->t_mpflags &= ~TMPF_SND_REM_ADDR;
1533}
1534
39236c6e
A
1535/* We send MP_PRIO option based on the values set by the SIOCSCONNORDER ioctl */
1536static int
1537mptcp_snd_mpprio(struct tcpcb *tp, u_char *cp, int optlen)
1538{
1539 struct mptcp_mpprio_addr_opt mpprio;
1540
1541 if (tp->t_state != TCPS_ESTABLISHED) {
1542 tp->t_mpflags &= ~TMPF_SND_MPPRIO;
1543 return (optlen);
1544 }
1545
39236c6e
A
1546 if ((MAX_TCPOPTLEN - optlen) <
1547 (int)sizeof (mpprio))
1548 return (optlen);
1549
1550 bzero(&mpprio, sizeof (mpprio));
1551 mpprio.mpprio_kind = TCPOPT_MULTIPATH;
1552 mpprio.mpprio_len = sizeof (mpprio);
1553 mpprio.mpprio_subtype = MPO_PRIO;
1554 if (tp->t_mpflags & TMPF_BACKUP_PATH)
1555 mpprio.mpprio_flags |= MPTCP_MPPRIO_BKP;
1556 mpprio.mpprio_addrid = tp->t_local_aid;
1557 memcpy(cp + optlen, &mpprio, sizeof (mpprio));
1558 optlen += sizeof (mpprio);
1559 tp->t_mpflags &= ~TMPF_SND_MPPRIO;
5ba3f43e 1560 mptcplog((LOG_DEBUG, "%s: aid = %d \n", __func__,
3e170ce0
A
1561 tp->t_local_aid),
1562 (MPTCP_SOCKET_DBG|MPTCP_SENDER_DBG), MPTCP_LOGLVL_LOG);
39236c6e
A
1563 return (optlen);
1564}
5ba3f43e 1565