Lines Matching +full:tsn +full:- +full:capable
1 // SPDX-License-Identifier: GPL-2.0-or-later
4 * Copyright (c) 1999-2000 Cisco, Inc.
5 * Copyright (c) 1999-2001 Motorola, Inc.
6 * Copyright (c) 2001-2002 Intel Corp.
16 * lksctp developers <linux-sctp@vger.kernel.org>
73 struct sctp_chunk *chunk = skb_shinfo(skb)->destructor_arg; in sctp_control_release_owner()
75 if (chunk->shkey) { in sctp_control_release_owner()
76 struct sctp_shared_key *shkey = chunk->shkey; in sctp_control_release_owner()
77 struct sctp_association *asoc = chunk->asoc; in sctp_control_release_owner()
83 if (shkey->deactivated && !list_empty(&shkey->key_list) && in sctp_control_release_owner()
84 refcount_read(&shkey->refcnt) == 2) { in sctp_control_release_owner()
87 ev = sctp_ulpevent_make_authkey(asoc, shkey->key_id, in sctp_control_release_owner()
91 asoc->stream.si->enqueue_event(&asoc->ulpq, ev); in sctp_control_release_owner()
93 sctp_auth_shkey_release(chunk->shkey); in sctp_control_release_owner()
99 struct sctp_association *asoc = chunk->asoc; in sctp_control_set_owner_w()
100 struct sk_buff *skb = chunk->skb; in sctp_control_set_owner_w()
109 if (chunk->auth) { in sctp_control_set_owner_w()
110 chunk->shkey = asoc->shkey; in sctp_control_set_owner_w()
111 sctp_auth_shkey_hold(chunk->shkey); in sctp_control_set_owner_w()
113 skb->sk = asoc ? asoc->base.sk : NULL; in sctp_control_set_owner_w()
114 skb_shinfo(skb)->destructor_arg = chunk; in sctp_control_set_owner_w()
115 skb->destructor = sctp_control_release_owner; in sctp_control_set_owner_w()
121 struct sk_buff *skb = chunk->skb; in sctp_chunk_iif()
123 return SCTP_INPUT_CB(skb)->af->skb_iif(skb); in sctp_chunk_iif()
128 * Note 2: The ECN capable field is reserved for future use of
154 if (skb_tailroom(chunk->skb) < len) in sctp_init_cause()
155 return -ENOSPC; in sctp_init_cause()
157 chunk->subh.err_hdr = sctp_addto_chunk(chunk, sizeof(err), &err); in sctp_init_cause()
169 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
171 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
173 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
175 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
177 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
178 * | Initial TSN |
179 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
181 * / Optional/Variable-Length Parameters /
183 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
190 * ----------------------------------------------
195 * Initial TSN Mandatory
198 * -------------------------------------------------------------
202 * Reserved for ECN Capable (Note 2) Optional 32768 (0x8000)
215 struct sctp_endpoint *ep = asoc->ep; in sctp_make_init()
235 init.init_tag = htonl(asoc->c.my_vtag); in sctp_make_init()
236 init.a_rwnd = htonl(asoc->rwnd); in sctp_make_init()
237 init.num_outbound_streams = htons(asoc->c.sinit_num_ostreams); in sctp_make_init()
238 init.num_inbound_streams = htons(asoc->c.sinit_max_instreams); in sctp_make_init()
239 init.initial_tsn = htonl(asoc->c.initial_tsn); in sctp_make_init()
242 sp = sctp_sk(asoc->base.sk); in sctp_make_init()
243 num_types = sp->pf->supported_addrs(sp, types); in sctp_make_init()
248 if (asoc->ep->ecn_enable) in sctp_make_init()
251 if (asoc->ep->prsctp_enable) in sctp_make_init()
256 * the ASCONF,the ASCONF-ACK, and the AUTH chunks in its INIT and in sctp_make_init()
257 * INIT-ACK parameters. in sctp_make_init()
259 if (asoc->ep->asconf_enable) { in sctp_make_init()
265 if (asoc->ep->reconf_enable) { in sctp_make_init()
270 if (sp->adaptation_ind) in sctp_make_init()
273 if (asoc->ep->intl_enable) { in sctp_make_init()
281 if (ep->auth_enable) { in sctp_make_init()
283 chunksize += sizeof(asoc->c.auth_random); in sctp_make_init()
286 auth_hmacs = (struct sctp_paramhdr *)asoc->c.auth_hmacs; in sctp_make_init()
287 if (auth_hmacs->length) in sctp_make_init()
288 chunksize += SCTP_PAD4(ntohs(auth_hmacs->length)); in sctp_make_init()
293 auth_chunks = (struct sctp_paramhdr *)asoc->c.auth_chunks; in sctp_make_init()
294 if (auth_chunks->length) in sctp_make_init()
295 chunksize += SCTP_PAD4(ntohs(auth_chunks->length)); in sctp_make_init()
323 retval->subh.init_hdr = in sctp_make_init()
325 retval->param_hdr.v = in sctp_make_init()
340 if (asoc->ep->ecn_enable) in sctp_make_init()
353 if (asoc->ep->prsctp_enable) in sctp_make_init()
356 if (sp->adaptation_ind) { in sctp_make_init()
359 aiparam.adaptation_ind = htonl(sp->adaptation_ind); in sctp_make_init()
363 /* Add SCTP-AUTH chunks to the parameter list */ in sctp_make_init()
364 if (ep->auth_enable) { in sctp_make_init()
365 sctp_addto_chunk(retval, sizeof(asoc->c.auth_random), in sctp_make_init()
366 asoc->c.auth_random); in sctp_make_init()
368 sctp_addto_chunk(retval, ntohs(auth_hmacs->length), in sctp_make_init()
371 sctp_addto_chunk(retval, ntohs(auth_chunks->length), in sctp_make_init()
400 addrs = sctp_bind_addrs_to_raw(&asoc->base.bind_addr, &addrs_len, gfp); in sctp_make_init_ack()
402 initack.init_tag = htonl(asoc->c.my_vtag); in sctp_make_init_ack()
403 initack.a_rwnd = htonl(asoc->rwnd); in sctp_make_init_ack()
404 initack.num_outbound_streams = htons(asoc->c.sinit_num_ostreams); in sctp_make_init_ack()
405 initack.num_inbound_streams = htons(asoc->c.sinit_max_instreams); in sctp_make_init_ack()
406 initack.initial_tsn = htonl(asoc->c.initial_tsn); in sctp_make_init_ack()
411 cookie = sctp_pack_cookie(asoc->ep, asoc, chunk, &cookie_len, in sctp_make_init_ack()
419 sp = sctp_sk(asoc->base.sk); in sctp_make_init_ack()
423 if (asoc->peer.ecn_capable) in sctp_make_init_ack()
426 if (asoc->peer.prsctp_capable) in sctp_make_init_ack()
429 if (asoc->peer.asconf_capable) { in sctp_make_init_ack()
435 if (asoc->peer.reconf_capable) { in sctp_make_init_ack()
440 if (sp->adaptation_ind) in sctp_make_init_ack()
443 if (asoc->peer.intl_capable) { in sctp_make_init_ack()
448 if (asoc->peer.auth_capable) { in sctp_make_init_ack()
449 auth_random = (struct sctp_paramhdr *)asoc->c.auth_random; in sctp_make_init_ack()
450 chunksize += ntohs(auth_random->length); in sctp_make_init_ack()
452 auth_hmacs = (struct sctp_paramhdr *)asoc->c.auth_hmacs; in sctp_make_init_ack()
453 if (auth_hmacs->length) in sctp_make_init_ack()
454 chunksize += SCTP_PAD4(ntohs(auth_hmacs->length)); in sctp_make_init_ack()
458 auth_chunks = (struct sctp_paramhdr *)asoc->c.auth_chunks; in sctp_make_init_ack()
459 if (auth_chunks->length) in sctp_make_init_ack()
460 chunksize += SCTP_PAD4(ntohs(auth_chunks->length)); in sctp_make_init_ack()
476 /* RFC 2960 6.4 Multi-homed SCTP Endpoints in sctp_make_init_ack()
485 if (chunk->transport) in sctp_make_init_ack()
486 retval->transport = in sctp_make_init_ack()
488 &chunk->transport->ipaddr); in sctp_make_init_ack()
490 retval->subh.init_hdr = in sctp_make_init_ack()
492 retval->param_hdr.v = sctp_addto_chunk(retval, addrs_len, addrs.v); in sctp_make_init_ack()
494 if (asoc->peer.ecn_capable) in sctp_make_init_ack()
502 if (asoc->peer.prsctp_capable) in sctp_make_init_ack()
505 if (sp->adaptation_ind) { in sctp_make_init_ack()
508 aiparam.adaptation_ind = htonl(sp->adaptation_ind); in sctp_make_init_ack()
512 if (asoc->peer.auth_capable) { in sctp_make_init_ack()
513 sctp_addto_chunk(retval, ntohs(auth_random->length), in sctp_make_init_ack()
516 sctp_addto_chunk(retval, ntohs(auth_hmacs->length), in sctp_make_init_ack()
519 sctp_addto_chunk(retval, ntohs(auth_chunks->length), in sctp_make_init_ack()
524 retval->asoc = (struct sctp_association *) asoc; in sctp_make_init_ack()
543 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
545 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
548 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
574 cookie = asoc->peer.cookie; in sctp_make_cookie_echo()
575 cookie_len = asoc->peer.cookie_len; in sctp_make_cookie_echo()
582 retval->subh.cookie_hdr = in sctp_make_cookie_echo()
585 /* RFC 2960 6.4 Multi-homed SCTP Endpoints in sctp_make_cookie_echo()
595 retval->transport = chunk->transport; in sctp_make_cookie_echo()
611 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
613 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
626 /* RFC 2960 6.4 Multi-homed SCTP Endpoints in sctp_make_cookie_ack()
635 if (retval && chunk && chunk->transport) in sctp_make_cookie_ack()
636 retval->transport = in sctp_make_cookie_ack()
638 &chunk->transport->ipaddr); in sctp_make_cookie_ack()
651 * This chunk contains one data element, i.e. the TSN number that
653 * TSN number in the datagram that was originally marked with the
658 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
660 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
661 * | Lowest TSN Number |
662 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
680 retval->subh.ecn_cwr_hdr = in sctp_make_cwr()
683 /* RFC 2960 6.4 Multi-homed SCTP Endpoints in sctp_make_cwr()
694 retval->transport = chunk->transport; in sctp_make_cwr()
712 retval->subh.ecne_hdr = in sctp_make_ecne()
729 /* We assign the TSN as LATE as possible, not here when in sctp_make_datafrag_empty()
733 dp.ppid = sinfo->sinfo_ppid; in sctp_make_datafrag_empty()
734 dp.stream = htons(sinfo->sinfo_stream); in sctp_make_datafrag_empty()
737 if (sinfo->sinfo_flags & SCTP_UNORDERED) in sctp_make_datafrag_empty()
744 retval->subh.data_hdr = sctp_addto_chunk(retval, sizeof(dp), &dp); in sctp_make_datafrag_empty()
745 memcpy(&retval->sinfo, sinfo, sizeof(struct sctp_sndrcvinfo)); in sctp_make_datafrag_empty()
751 * association. This reports on which TSN's we've seen to date,
756 struct sctp_tsnmap *map = (struct sctp_tsnmap *)&asoc->peer.tsn_map; in sctp_make_sack()
776 sack.a_rwnd = htonl(asoc->a_rwnd); in sctp_make_sack()
789 /* RFC 2960 6.4 Multi-homed SCTP Endpoints in sctp_make_sack()
807 * duplicates. --piggy] in sctp_make_sack()
810 * multi- homed endpoint it MAY be beneficial to vary the in sctp_make_sack()
813 * from a multi-homed endpoint might indicate that the return in sctp_make_sack()
819 retval->transport = asoc->peer.last_data_from; in sctp_make_sack()
821 retval->subh.sack_hdr = in sctp_make_sack()
829 /* Add the duplicate TSN information. */ in sctp_make_sack()
831 asoc->stats.idupchunks += num_dup_tsns; in sctp_make_sack()
843 if (++asoc->peer.sack_generation == 0) { in sctp_make_sack()
844 list_for_each_entry(trans, &asoc->peer.transport_addr_list, in sctp_make_sack()
846 trans->sack_generation = 0; in sctp_make_sack()
847 asoc->peer.sack_generation = 1; in sctp_make_sack()
861 if (chunk && chunk->asoc) in sctp_make_shutdown()
862 ctsn = sctp_tsnmap_get_ctsn(&chunk->asoc->peer.tsn_map); in sctp_make_shutdown()
864 ctsn = sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map); in sctp_make_shutdown()
873 retval->subh.shutdown_hdr = in sctp_make_shutdown()
877 retval->transport = chunk->transport; in sctp_make_shutdown()
890 /* RFC 2960 6.4 Multi-homed SCTP Endpoints in sctp_make_shutdown_ack()
900 retval->transport = chunk->transport; in sctp_make_shutdown_ack()
912 /* Set the T-bit if we have no association (vtag will be in sctp_make_shutdown_complete()
920 /* RFC 2960 6.4 Multi-homed SCTP Endpoints in sctp_make_shutdown_complete()
931 retval->transport = chunk->transport; in sctp_make_shutdown_complete()
946 /* Set the T-bit if we have no association and 'chunk' is not in sctp_make_abort()
950 if (chunk && chunk->chunk_hdr && in sctp_make_abort()
951 chunk->chunk_hdr->type == SCTP_CID_INIT) in sctp_make_abort()
960 /* RFC 2960 6.4 Multi-homed SCTP Endpoints in sctp_make_abort()
970 retval->transport = chunk->transport; in sctp_make_abort()
979 __u32 tsn) in sctp_make_abort_no_data() argument
985 sizeof(struct sctp_errhdr) + sizeof(tsn)); in sctp_make_abort_no_data()
990 /* Put the tsn back into network byte order. */ in sctp_make_abort_no_data()
991 payload = htonl(tsn); in sctp_make_abort_no_data()
995 /* RFC 2960 6.4 Multi-homed SCTP Endpoints in sctp_make_abort_no_data()
1005 retval->transport = chunk->transport; in sctp_make_abort_no_data()
1059 int chunklen = ntohs(chunk->chunk_hdr->length); in sctp_addto_param()
1062 target = skb_put(chunk->skb, len); in sctp_addto_param()
1070 chunk->chunk_hdr->length = htons(chunklen + len); in sctp_addto_param()
1071 chunk->chunk_end = skb_tail_pointer(chunk->skb); in sctp_addto_param()
1094 phdr.type = htons(chunk->chunk_hdr->type); in sctp_make_abort_violation()
1095 phdr.length = chunk->chunk_hdr->length; in sctp_make_abort_violation()
1160 hbinfo.daddr = transport->ipaddr; in sctp_make_heartbeat()
1162 hbinfo.hb_nonce = transport->hb_nonce; in sctp_make_heartbeat()
1167 retval->transport = (struct sctp_transport *) transport; in sctp_make_heartbeat()
1168 retval->subh.hbs_hdr = sctp_addto_chunk(retval, sizeof(hbinfo), in sctp_make_heartbeat()
1187 retval->subh.hbs_hdr = sctp_addto_chunk(retval, paylen, payload); in sctp_make_heartbeat_ack()
1189 /* RFC 2960 6.4 Multi-homed SCTP Endpoints in sctp_make_heartbeat_ack()
1199 retval->transport = chunk->transport; in sctp_make_heartbeat_ack()
1221 /* RFC 2960 6.4 Multi-homed SCTP Endpoints in sctp_make_op_error_space()
1230 retval->transport = chunk->transport; in sctp_make_op_error_space()
1237 * min(asoc->pathmtu, SCTP_DEFAULT_MAXSEGMENT) - overheads.
1251 size = min_t(size_t, size, asoc->pathmtu); in sctp_make_op_error_limited()
1252 sp = sctp_sk(asoc->base.sk); in sctp_make_op_error_limited()
1294 hmac_desc->hmac_len + sizeof(auth_hdr), in sctp_make_auth()
1299 auth_hdr.hmac_id = htons(hmac_desc->hmac_id); in sctp_make_auth()
1302 retval->subh.auth_hdr = sctp_addto_chunk(retval, sizeof(auth_hdr), in sctp_make_auth()
1305 skb_put_zero(retval->skb, hmac_desc->hmac_len); in sctp_make_auth()
1308 retval->chunk_hdr->length = in sctp_make_auth()
1309 htons(ntohs(retval->chunk_hdr->length) + hmac_desc->hmac_len); in sctp_make_auth()
1310 retval->chunk_end = skb_tail_pointer(retval->skb); in sctp_make_auth()
1321 * FIXME: Eventually move the structure directly inside the skb->cb[].
1323 * sctpimpguide-05.txt Section 2.8.2
1325 * set the 'TSN.Missing.Report' count for that TSN to 0. The
1326 * 'TSN.Missing.Report' count will be used to determine missing chunks
1343 INIT_LIST_HEAD(&retval->list); in sctp_chunkify()
1344 retval->skb = skb; in sctp_chunkify()
1345 retval->asoc = (struct sctp_association *)asoc; in sctp_chunkify()
1346 retval->singleton = 1; in sctp_chunkify()
1348 retval->fast_retransmit = SCTP_CAN_FRTX; in sctp_chunkify()
1351 INIT_LIST_HEAD(&retval->transmitted_list); in sctp_chunkify()
1352 INIT_LIST_HEAD(&retval->frag_list); in sctp_chunkify()
1354 refcount_set(&retval->refcnt, 1); in sctp_chunkify()
1360 /* Set chunk->source and dest based on the IP header in chunk->skb. */
1364 memcpy(&chunk->source, src, sizeof(union sctp_addr)); in sctp_init_addrs()
1365 memcpy(&chunk->dest, dest, sizeof(union sctp_addr)); in sctp_init_addrs()
1372 if (chunk->transport) { in sctp_source()
1373 return &chunk->transport->ipaddr; in sctp_source()
1376 return &chunk->source; in sctp_source()
1404 chunk_hdr->type = type; in _sctp_make_chunk()
1405 chunk_hdr->flags = flags; in _sctp_make_chunk()
1406 chunk_hdr->length = htons(sizeof(*chunk_hdr)); in _sctp_make_chunk()
1408 sk = asoc ? asoc->base.sk : NULL; in _sctp_make_chunk()
1415 retval->chunk_hdr = chunk_hdr; in _sctp_make_chunk()
1416 retval->chunk_end = ((__u8 *)chunk_hdr) + sizeof(*chunk_hdr); in _sctp_make_chunk()
1420 retval->auth = 1; in _sctp_make_chunk()
1455 BUG_ON(!list_empty(&chunk->list)); in sctp_chunk_destroy()
1456 list_del_init(&chunk->transmitted_list); in sctp_chunk_destroy()
1458 consume_skb(chunk->skb); in sctp_chunk_destroy()
1459 consume_skb(chunk->auth_chunk); in sctp_chunk_destroy()
1469 if (chunk->msg) in sctp_chunk_free()
1470 sctp_datamsg_put(chunk->msg); in sctp_chunk_free()
1478 refcount_inc(&ch->refcnt); in sctp_chunk_hold()
1484 if (refcount_dec_and_test(&ch->refcnt)) in sctp_chunk_put()
1493 int chunklen = ntohs(chunk->chunk_hdr->length); in sctp_addto_chunk()
1494 int padlen = SCTP_PAD4(chunklen) - chunklen; in sctp_addto_chunk()
1497 skb_put_zero(chunk->skb, padlen); in sctp_addto_chunk()
1498 target = skb_put_data(chunk->skb, data, len); in sctp_addto_chunk()
1501 chunk->chunk_hdr->length = htons(chunklen + padlen + len); in sctp_addto_chunk()
1502 chunk->chunk_end = skb_tail_pointer(chunk->skb); in sctp_addto_chunk()
1517 target = skb_put(chunk->skb, len); in sctp_user_addto_chunk()
1521 return -EFAULT; in sctp_user_addto_chunk()
1524 chunk->chunk_hdr->length = in sctp_user_addto_chunk()
1525 htons(ntohs(chunk->chunk_hdr->length) + len); in sctp_user_addto_chunk()
1526 chunk->chunk_end = skb_tail_pointer(chunk->skb); in sctp_user_addto_chunk()
1531 /* Helper function to assign a TSN if needed. This assumes that both
1541 if (chunk->has_ssn) in sctp_chunk_assign_ssn()
1545 sid = ntohs(chunk->subh.data_hdr->stream); in sctp_chunk_assign_ssn()
1546 stream = &chunk->asoc->stream; in sctp_chunk_assign_ssn()
1551 msg = chunk->msg; in sctp_chunk_assign_ssn()
1552 list_for_each_entry(lchunk, &msg->chunks, frag_list) { in sctp_chunk_assign_ssn()
1553 if (lchunk->chunk_hdr->flags & SCTP_DATA_UNORDERED) { in sctp_chunk_assign_ssn()
1556 if (lchunk->chunk_hdr->flags & SCTP_DATA_LAST_FRAG) in sctp_chunk_assign_ssn()
1562 lchunk->subh.data_hdr->ssn = htons(ssn); in sctp_chunk_assign_ssn()
1563 lchunk->has_ssn = 1; in sctp_chunk_assign_ssn()
1567 /* Helper function to assign a TSN if needed. This assumes that both
1572 if (!chunk->has_tsn) { in sctp_chunk_assign_tsn()
1574 * assign a TSN. in sctp_chunk_assign_tsn()
1576 chunk->subh.data_hdr->tsn = in sctp_chunk_assign_tsn()
1577 htonl(sctp_association_get_next_tsn(chunk->asoc)); in sctp_chunk_assign_tsn()
1578 chunk->has_tsn = 1; in sctp_chunk_assign_tsn()
1593 asoc = sctp_association_new(ep, ep->base.sk, scope, gfp); in sctp_make_temp_asoc()
1596 asoc->temp = 1; in sctp_make_temp_asoc()
1597 skb = chunk->skb; in sctp_make_temp_asoc()
1599 SCTP_INPUT_CB(skb)->af->from_skb(&asoc->c.peer_addr, skb, 1); in sctp_make_temp_asoc()
1623 (sizeof(struct sctp_signed_cookie) - in sctp_pack_cookie()
1626 + ntohs(init_chunk->chunk_hdr->length) + addrs_len; in sctp_pack_cookie()
1633 - (bodysize % SCTP_COOKIE_MULTIPLE); in sctp_pack_cookie()
1643 cookie = (struct sctp_signed_cookie *) retval->body; in sctp_pack_cookie()
1646 retval->p.type = SCTP_PARAM_STATE_COOKIE; in sctp_pack_cookie()
1647 retval->p.length = htons(*cookie_len); in sctp_pack_cookie()
1650 cookie->c = asoc->c; in sctp_pack_cookie()
1652 cookie->c.raw_addr_list_len = addrs_len; in sctp_pack_cookie()
1654 /* Remember PR-SCTP capability. */ in sctp_pack_cookie()
1655 cookie->c.prsctp_capable = asoc->peer.prsctp_capable; in sctp_pack_cookie()
1658 cookie->c.adaptation_ind = asoc->peer.adaptation_ind; in sctp_pack_cookie()
1661 cookie->c.expiration = ktime_add(asoc->cookie_life, in sctp_pack_cookie()
1665 memcpy(&cookie->c.peer_init[0], init_chunk->chunk_hdr, in sctp_pack_cookie()
1666 ntohs(init_chunk->chunk_hdr->length)); in sctp_pack_cookie()
1669 memcpy((__u8 *)&cookie->c.peer_init[0] + in sctp_pack_cookie()
1670 ntohs(init_chunk->chunk_hdr->length), raw_addrs, addrs_len); in sctp_pack_cookie()
1672 if (sctp_sk(ep->base.sk)->hmac) { in sctp_pack_cookie()
1673 struct crypto_shash *tfm = sctp_sk(ep->base.sk)->hmac; in sctp_pack_cookie()
1677 err = crypto_shash_setkey(tfm, ep->secret_key, in sctp_pack_cookie()
1678 sizeof(ep->secret_key)) ?: in sctp_pack_cookie()
1679 crypto_shash_tfm_digest(tfm, (u8 *)&cookie->c, bodysize, in sctp_pack_cookie()
1680 cookie->signature); in sctp_pack_cookie()
1704 struct sk_buff *skb = chunk->skb; in sctp_unpack_cookie()
1706 __u8 *digest = ep->digest; in sctp_unpack_cookie()
1715 (sizeof(struct sctp_signed_cookie) - in sctp_unpack_cookie()
1717 bodysize = ntohs(chunk->chunk_hdr->length) - headersize; in sctp_unpack_cookie()
1724 len = ntohs(chunk->chunk_hdr->length); in sctp_unpack_cookie()
1733 cookie = chunk->subh.cookie_hdr; in sctp_unpack_cookie()
1734 bear_cookie = &cookie->c; in sctp_unpack_cookie()
1736 if (!sctp_sk(ep->base.sk)->hmac) in sctp_unpack_cookie()
1741 struct crypto_shash *tfm = sctp_sk(ep->base.sk)->hmac; in sctp_unpack_cookie()
1744 err = crypto_shash_setkey(tfm, ep->secret_key, in sctp_unpack_cookie()
1745 sizeof(ep->secret_key)) ?: in sctp_unpack_cookie()
1749 *error = -SCTP_IERROR_NOMEM; in sctp_unpack_cookie()
1754 if (memcmp(digest, cookie->signature, SCTP_SIGNATURE_SIZE)) { in sctp_unpack_cookie()
1755 *error = -SCTP_IERROR_BAD_SIG; in sctp_unpack_cookie()
1767 if (ntohl(chunk->sctp_hdr->vtag) != bear_cookie->my_vtag) { in sctp_unpack_cookie()
1768 *error = -SCTP_IERROR_BAD_TAG; in sctp_unpack_cookie()
1772 if (chunk->sctp_hdr->source != bear_cookie->peer_addr.v4.sin_port || in sctp_unpack_cookie()
1773 ntohs(chunk->sctp_hdr->dest) != bear_cookie->my_port) { in sctp_unpack_cookie()
1774 *error = -SCTP_IERROR_BAD_PORTS; in sctp_unpack_cookie()
1786 if (sock_flag(ep->base.sk, SOCK_TIMESTAMP)) in sctp_unpack_cookie()
1791 if (!asoc && ktime_before(bear_cookie->expiration, kt)) { in sctp_unpack_cookie()
1792 suseconds_t usecs = ktime_to_us(ktime_sub(kt, bear_cookie->expiration)); in sctp_unpack_cookie()
1799 * --------------- in sctp_unpack_cookie()
1807 *error = -SCTP_IERROR_STALE_COOKIE; in sctp_unpack_cookie()
1809 *error = -SCTP_IERROR_NOMEM; in sctp_unpack_cookie()
1816 retval = sctp_association_new(ep, ep->base.sk, scope, gfp); in sctp_unpack_cookie()
1818 *error = -SCTP_IERROR_NOMEM; in sctp_unpack_cookie()
1823 retval->peer.port = ntohs(chunk->sctp_hdr->source); in sctp_unpack_cookie()
1826 memcpy(&retval->c, bear_cookie, sizeof(*bear_cookie)); in sctp_unpack_cookie()
1830 *error = -SCTP_IERROR_NOMEM; in sctp_unpack_cookie()
1835 if (list_empty(&retval->base.bind_addr.address_list)) { in sctp_unpack_cookie()
1836 sctp_add_bind_addr(&retval->base.bind_addr, &chunk->dest, in sctp_unpack_cookie()
1837 sizeof(chunk->dest), SCTP_ADDR_SRC, in sctp_unpack_cookie()
1841 retval->next_tsn = retval->c.initial_tsn; in sctp_unpack_cookie()
1842 retval->ctsn_ack_point = retval->next_tsn - 1; in sctp_unpack_cookie()
1843 retval->addip_serial = retval->c.initial_tsn; in sctp_unpack_cookie()
1844 retval->strreset_outseq = retval->c.initial_tsn; in sctp_unpack_cookie()
1845 retval->adv_peer_ack_point = retval->ctsn_ack_point; in sctp_unpack_cookie()
1846 retval->peer.prsctp_capable = retval->c.prsctp_capable; in sctp_unpack_cookie()
1847 retval->peer.adaptation_ind = retval->c.adaptation_ind; in sctp_unpack_cookie()
1862 *error = -SCTP_IERROR_MALFORMED; in sctp_unpack_cookie()
1928 /* This is a fatal error. Any accumulated non-fatal errors are in sctp_process_inv_paramlength()
1949 __u16 len = ntohs(param.p->length); in sctp_process_hn_param()
1952 * ABORT. If we've accumulated any non-fatal errors, they in sctp_process_hn_param()
1970 __u16 num_ext = ntohs(param.p->length) - sizeof(struct sctp_paramhdr); in sctp_verify_ext_param()
1976 switch (param.ext->chunks[i]) { in sctp_verify_ext_param()
1987 /* ADD-IP Security: The draft requires us to ABORT or ignore the in sctp_verify_ext_param()
1988 * INIT/INIT-ACK if ADD-IP is listed, but AUTH is not. Do this in sctp_verify_ext_param()
1989 * only if ADD-IP is turned on and we are not backward-compatible in sctp_verify_ext_param()
1992 if (net->sctp.addip_noauth) in sctp_verify_ext_param()
1995 if (ep->asconf_enable && !have_auth && have_asconf) in sctp_verify_ext_param()
2004 __u16 num_ext = ntohs(param.p->length) - sizeof(struct sctp_paramhdr); in sctp_process_ext_param()
2008 switch (param.ext->chunks[i]) { in sctp_process_ext_param()
2010 if (asoc->ep->reconf_enable) in sctp_process_ext_param()
2011 asoc->peer.reconf_capable = 1; in sctp_process_ext_param()
2014 if (asoc->ep->prsctp_enable) in sctp_process_ext_param()
2015 asoc->peer.prsctp_capable = 1; in sctp_process_ext_param()
2021 if (asoc->ep->auth_enable) in sctp_process_ext_param()
2022 asoc->peer.auth_capable = 1; in sctp_process_ext_param()
2026 if (asoc->ep->asconf_enable) in sctp_process_ext_param()
2027 asoc->peer.asconf_capable = 1; in sctp_process_ext_param()
2030 if (asoc->ep->intl_enable) in sctp_process_ext_param()
2031 asoc->peer.intl_capable = 1; in sctp_process_ext_param()
2042 * highest-order two bits specify the action that must be
2046 * 00 - Stop processing this parameter; do not process any further
2049 * 01 - Stop processing this parameter, do not process any further
2053 * 10 - Skip this parameter and continue processing.
2055 * 11 - Skip this parameter and continue processing but
2060 * SCTP_IERROR_NO_ERROR - continue with the chunk
2061 * SCTP_IERROR_ERROR - stop and report an error.
2062 * SCTP_IERROR_NOMEME - out of memory.
2072 switch (param.p->type & SCTP_PARAM_ACTION_MASK) { in sctp_process_unk_param()
2099 ntohs(param.p->length))) in sctp_process_unk_param()
2100 sctp_addto_chunk(*errp, ntohs(param.p->length), in sctp_process_unk_param()
2112 * SCTP_IERROR_ABORT - trigger an ABORT
2113 * SCTP_IERROR_NOMEM - out of memory (abort)
2114 * SCTP_IERROR_ERROR - stop processing, trigger an ERROR
2115 * SCTP_IERROR_NO_ERROR - continue with the chunk
2130 /* FIXME - This routine is not looking at each parameter per the in sctp_verify_param()
2135 switch (param.p->type) { in sctp_verify_param()
2153 if (!ep->asconf_enable) in sctp_verify_param()
2156 if (ntohs(param.p->length) < sizeof(struct sctp_addip_param) + in sctp_verify_param()
2171 if (ep->prsctp_enable) in sctp_verify_param()
2176 if (!ep->auth_enable) in sctp_verify_param()
2179 /* SCTP-AUTH: Secion 6.1 in sctp_verify_param()
2184 if (SCTP_AUTH_RANDOM_LENGTH != ntohs(param.p->length) - in sctp_verify_param()
2193 if (!ep->auth_enable) in sctp_verify_param()
2196 /* SCTP-AUTH: Section 3.2 in sctp_verify_param()
2198 * INIT-ACK chunk if the sender wants to receive authenticated in sctp_verify_param()
2201 if (260 < ntohs(param.p->length)) { in sctp_verify_param()
2209 if (!ep->auth_enable) in sctp_verify_param()
2213 n_elt = (ntohs(param.p->length) - in sctp_verify_param()
2216 /* SCTP-AUTH: Section 6.1 in sctp_verify_param()
2217 * The HMAC algorithm based on SHA-1 MUST be supported and in sctp_verify_param()
2218 * included in the HMAC-ALGO parameter. in sctp_verify_param()
2221 id = ntohs(hmacs->hmac_ids[i]); in sctp_verify_param()
2236 __func__, ntohs(param.p->type), cid); in sctp_verify_param()
2254 /* Check for missing mandatory parameters. Note: Initial TSN is in sctp_verify_init()
2256 * is 0..2**32-1. RFC4960, section 3.3.3. in sctp_verify_init()
2258 if (peer_init->init_hdr.num_outbound_streams == 0 || in sctp_verify_init()
2259 peer_init->init_hdr.num_inbound_streams == 0 || in sctp_verify_init()
2260 peer_init->init_hdr.init_tag == 0 || in sctp_verify_init()
2261 ntohl(peer_init->init_hdr.a_rwnd) < SCTP_DEFAULT_MINWINDOW) in sctp_verify_init()
2265 if (param.p->type == SCTP_PARAM_STATE_COOKIE) in sctp_verify_init()
2276 if (param.v != (void *)chunk->chunk_end) in sctp_verify_init()
2280 * the state cookie for an INIT-ACK chunk. in sctp_verify_init()
2340 (param.p->type == SCTP_PARAM_IPV4_ADDRESS || in sctp_process_init()
2341 param.p->type == SCTP_PARAM_IPV6_ADDRESS)) { in sctp_process_init()
2342 af = sctp_get_af_specific(param_type2af(param.p->type)); in sctp_process_init()
2343 if (!af->from_addr_param(&addr, param.addr, in sctp_process_init()
2344 chunk->sctp_hdr->source, 0)) in sctp_process_init()
2361 if (asoc->peer.auth_capable && (!asoc->peer.peer_random || in sctp_process_init()
2362 !asoc->peer.peer_hmacs)) in sctp_process_init()
2363 asoc->peer.auth_capable = 0; in sctp_process_init()
2365 /* In a non-backward compatible mode, if the peer claims in sctp_process_init()
2366 * support for ADD-IP but not AUTH, the ADD-IP spec states in sctp_process_init()
2371 if (!asoc->base.net->sctp.addip_noauth && in sctp_process_init()
2372 (asoc->peer.asconf_capable && !asoc->peer.auth_capable)) { in sctp_process_init()
2373 asoc->peer.addip_disabled_mask |= (SCTP_PARAM_ADD_IP | in sctp_process_init()
2376 asoc->peer.asconf_capable = 0; in sctp_process_init()
2381 list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) { in sctp_process_init()
2383 if (transport->state == SCTP_UNKNOWN) { in sctp_process_init()
2391 asoc->peer.i.init_tag = in sctp_process_init()
2392 ntohl(peer_init->init_hdr.init_tag); in sctp_process_init()
2393 asoc->peer.i.a_rwnd = in sctp_process_init()
2394 ntohl(peer_init->init_hdr.a_rwnd); in sctp_process_init()
2395 asoc->peer.i.num_outbound_streams = in sctp_process_init()
2396 ntohs(peer_init->init_hdr.num_outbound_streams); in sctp_process_init()
2397 asoc->peer.i.num_inbound_streams = in sctp_process_init()
2398 ntohs(peer_init->init_hdr.num_inbound_streams); in sctp_process_init()
2399 asoc->peer.i.initial_tsn = in sctp_process_init()
2400 ntohl(peer_init->init_hdr.initial_tsn); in sctp_process_init()
2402 asoc->strreset_inseq = asoc->peer.i.initial_tsn; in sctp_process_init()
2407 if (asoc->c.sinit_num_ostreams > in sctp_process_init()
2408 ntohs(peer_init->init_hdr.num_inbound_streams)) { in sctp_process_init()
2409 asoc->c.sinit_num_ostreams = in sctp_process_init()
2410 ntohs(peer_init->init_hdr.num_inbound_streams); in sctp_process_init()
2413 if (asoc->c.sinit_max_instreams > in sctp_process_init()
2414 ntohs(peer_init->init_hdr.num_outbound_streams)) { in sctp_process_init()
2415 asoc->c.sinit_max_instreams = in sctp_process_init()
2416 ntohs(peer_init->init_hdr.num_outbound_streams); in sctp_process_init()
2420 asoc->c.peer_vtag = asoc->peer.i.init_tag; in sctp_process_init()
2423 asoc->peer.rwnd = asoc->peer.i.a_rwnd; in sctp_process_init()
2429 list_for_each_entry(transport, &asoc->peer.transport_addr_list, in sctp_process_init()
2431 transport->ssthresh = asoc->peer.i.a_rwnd; in sctp_process_init()
2434 /* Set up the TSN tracking pieces. */ in sctp_process_init()
2435 if (!sctp_tsnmap_init(&asoc->peer.tsn_map, SCTP_TSN_MAP_INITIAL, in sctp_process_init()
2436 asoc->peer.i.initial_tsn, gfp)) in sctp_process_init()
2447 if (sctp_stream_init(&asoc->stream, asoc->c.sinit_num_ostreams, in sctp_process_init()
2448 asoc->c.sinit_max_instreams, gfp)) in sctp_process_init()
2454 if (!asoc->temp && sctp_assoc_set_id(asoc, gfp)) in sctp_process_init()
2465 * association to the same value as the Initial TSN. in sctp_process_init()
2467 asoc->peer.addip_serial = asoc->peer.i.initial_tsn - 1; in sctp_process_init()
2472 list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) { in sctp_process_init()
2474 if (transport->state != SCTP_ACTIVE) in sctp_process_init()
2499 struct sctp_endpoint *ep = asoc->ep; in sctp_process_param()
2501 struct net *net = asoc->base.net; in sctp_process_param()
2514 switch (param.p->type) { in sctp_process_param()
2516 if (PF_INET6 != asoc->base.sk->sk_family) in sctp_process_param()
2521 /* v4 addresses are not allowed on v6-only socket */ in sctp_process_param()
2522 if (ipv6_only_sock(asoc->base.sk)) in sctp_process_param()
2525 af = sctp_get_af_specific(param_type2af(param.p->type)); in sctp_process_param()
2526 if (!af->from_addr_param(&addr, param.addr, htons(asoc->peer.port), 0)) in sctp_process_param()
2535 if (!net->sctp.cookie_preserve_enable) in sctp_process_param()
2538 stale = ntohl(param.life->lifespan_increment); in sctp_process_param()
2543 asoc->cookie_life = ktime_add_ms(asoc->cookie_life, stale); in sctp_process_param()
2554 asoc->peer.ipv4_address = 0; in sctp_process_param()
2555 asoc->peer.ipv6_address = 0; in sctp_process_param()
2560 if (peer_addr->sa.sa_family == AF_INET6) in sctp_process_param()
2561 asoc->peer.ipv6_address = 1; in sctp_process_param()
2562 else if (peer_addr->sa.sa_family == AF_INET) in sctp_process_param()
2563 asoc->peer.ipv4_address = 1; in sctp_process_param()
2566 sat = ntohs(param.p->length) - sizeof(struct sctp_paramhdr); in sctp_process_param()
2571 switch (param.sat->types[i]) { in sctp_process_param()
2573 asoc->peer.ipv4_address = 1; in sctp_process_param()
2577 if (PF_INET6 == asoc->base.sk->sk_family) in sctp_process_param()
2578 asoc->peer.ipv6_address = 1; in sctp_process_param()
2582 asoc->peer.hostname_address = 1; in sctp_process_param()
2592 asoc->peer.cookie_len = in sctp_process_param()
2593 ntohs(param.p->length) - sizeof(struct sctp_paramhdr); in sctp_process_param()
2594 kfree(asoc->peer.cookie); in sctp_process_param()
2595 asoc->peer.cookie = kmemdup(param.cookie->body, asoc->peer.cookie_len, gfp); in sctp_process_param()
2596 if (!asoc->peer.cookie) in sctp_process_param()
2609 if (asoc->ep->ecn_enable) { in sctp_process_param()
2610 asoc->peer.ecn_capable = 1; in sctp_process_param()
2618 asoc->peer.adaptation_ind = ntohl(param.aind->adaptation_ind); in sctp_process_param()
2622 if (!ep->asconf_enable) in sctp_process_param()
2627 af = sctp_get_af_specific(param_type2af(addr_param->p.type)); in sctp_process_param()
2631 if (!af->from_addr_param(&addr, addr_param, in sctp_process_param()
2632 htons(asoc->peer.port), 0)) in sctp_process_param()
2635 if (!af->addr_valid(&addr, NULL, NULL)) in sctp_process_param()
2650 if (asoc->ep->prsctp_enable) { in sctp_process_param()
2651 asoc->peer.prsctp_capable = 1; in sctp_process_param()
2658 if (!ep->auth_enable) in sctp_process_param()
2662 kfree(asoc->peer.peer_random); in sctp_process_param()
2663 asoc->peer.peer_random = kmemdup(param.p, in sctp_process_param()
2664 ntohs(param.p->length), gfp); in sctp_process_param()
2665 if (!asoc->peer.peer_random) { in sctp_process_param()
2672 if (!ep->auth_enable) in sctp_process_param()
2676 kfree(asoc->peer.peer_hmacs); in sctp_process_param()
2677 asoc->peer.peer_hmacs = kmemdup(param.p, in sctp_process_param()
2678 ntohs(param.p->length), gfp); in sctp_process_param()
2679 if (!asoc->peer.peer_hmacs) { in sctp_process_param()
2689 if (!ep->auth_enable) in sctp_process_param()
2692 kfree(asoc->peer.peer_chunks); in sctp_process_param()
2693 asoc->peer.peer_chunks = kmemdup(param.p, in sctp_process_param()
2694 ntohs(param.p->length), gfp); in sctp_process_param()
2695 if (!asoc->peer.peer_chunks) in sctp_process_param()
2706 __func__, ntohs(param.p->type), asoc); in sctp_process_param()
2728 /* Select an initial TSN to send during startup. */
2741 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2743 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2745 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2747 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2749 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2753 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2755 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2768 struct sctp_af *af = sctp_get_af_specific(addr->v4.sin_family); in sctp_make_asconf()
2770 addrlen = af->to_addr_param(addr, &addrparam); in sctp_make_asconf()
2781 asconf.serial = htonl(asoc->addip_serial++); in sctp_make_asconf()
2783 retval->subh.addip_hdr = in sctp_make_asconf()
2785 retval->param_hdr.v = in sctp_make_asconf()
2795 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2797 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2798 * | ASCONF-Request Correlation ID |
2799 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2801 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2806 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2808 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2809 * | ASCONF-Request Correlation ID |
2810 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2812 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2835 af = sctp_get_af_specific(addr->v4.sin_family); in sctp_make_asconf_update_ip()
2836 addr_param_len = af->to_addr_param(addr, &addr_param); in sctp_make_asconf_update_ip()
2841 addr_buf += af->sockaddr_len; in sctp_make_asconf_update_ip()
2842 if (asoc->asconf_addr_del_pending && !del_pickup) { in sctp_make_asconf_update_ip()
2848 pr_debug("%s: picked same-scope del_pending addr, " in sctp_make_asconf_update_ip()
2863 af = sctp_get_af_specific(addr->v4.sin_family); in sctp_make_asconf_update_ip()
2864 addr_param_len = af->to_addr_param(addr, &addr_param); in sctp_make_asconf_update_ip()
2872 addr_buf += af->sockaddr_len; in sctp_make_asconf_update_ip()
2875 addr = asoc->asconf_addr_del_pending; in sctp_make_asconf_update_ip()
2876 af = sctp_get_af_specific(addr->v4.sin_family); in sctp_make_asconf_update_ip()
2877 addr_param_len = af->to_addr_param(addr, &addr_param); in sctp_make_asconf_update_ip()
2892 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2894 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2895 * | ASCONF-Request Correlation ID |
2896 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2898 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2905 struct sctp_af *af = sctp_get_af_specific(addr->v4.sin_family); in sctp_make_asconf_set_prim()
2912 addrlen = af->to_addr_param(addr, &addrparam); in sctp_make_asconf_set_prim()
2932 /* ADDIP 3.1.2 Address Configuration Acknowledgement Chunk (ASCONF-ACK)
2935 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2937 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2939 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2941 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2945 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2947 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2966 retval->subh.addip_hdr = in sctp_make_asconf_ack()
2990 ntohs(asconf_param->param_hdr.length); in sctp_add_asconf_response()
3026 if (asconf_param->param_hdr.type != SCTP_PARAM_ADD_IP && in sctp_process_asconf_param()
3027 asconf_param->param_hdr.type != SCTP_PARAM_DEL_IP && in sctp_process_asconf_param()
3028 asconf_param->param_hdr.type != SCTP_PARAM_SET_PRIMARY) in sctp_process_asconf_param()
3031 switch (addr_param->p.type) { in sctp_process_asconf_param()
3033 if (!asoc->peer.ipv6_address) in sctp_process_asconf_param()
3037 if (!asoc->peer.ipv4_address) in sctp_process_asconf_param()
3044 af = sctp_get_af_specific(param_type2af(addr_param->p.type)); in sctp_process_asconf_param()
3048 if (!af->from_addr_param(&addr, addr_param, htons(asoc->peer.port), 0)) in sctp_process_asconf_param()
3056 if (!af->is_any(&addr) && !af->addr_valid(&addr, NULL, asconf->skb)) in sctp_process_asconf_param()
3059 switch (asconf_param->param_hdr.type) { in sctp_process_asconf_param()
3065 if (af->is_any(&addr)) in sctp_process_asconf_param()
3066 memcpy(&addr, &asconf->source, sizeof(addr)); in sctp_process_asconf_param()
3068 if (security_sctp_bind_connect(asoc->ep->base.sk, in sctp_process_asconf_param()
3071 af->sockaddr_len)) in sctp_process_asconf_param()
3087 asoc->new_transport = peer; in sctp_process_asconf_param()
3095 if (asoc->peer.transport_count == 1) in sctp_process_asconf_param()
3105 if (sctp_cmp_addr_exact(&asconf->source, &addr)) in sctp_process_asconf_param()
3113 if (af->is_any(&addr)) { in sctp_process_asconf_param()
3114 sctp_assoc_set_primary(asoc, asconf->transport); in sctp_process_asconf_param()
3116 asconf->transport); in sctp_process_asconf_param()
3121 * ASCONF-ACK with Error Cause Indication Parameter in sctp_process_asconf_param()
3137 if (af->is_any(&addr)) in sctp_process_asconf_param()
3140 if (security_sctp_bind_connect(asoc->ep->base.sk, in sctp_process_asconf_param()
3143 af->sockaddr_len)) in sctp_process_asconf_param()
3166 addip = (struct sctp_addip_chunk *)chunk->chunk_hdr; in sctp_verify_asconf()
3168 size_t length = ntohs(param.p->length); in sctp_verify_asconf()
3171 switch (param.p->type) { in sctp_verify_asconf()
3180 if (param.v != addip->addip_hdr.params) in sctp_verify_asconf()
3187 if (param.v != addip->addip_hdr.params) in sctp_verify_asconf()
3197 length = ntohs(param.addip->param_hdr.length); in sctp_verify_asconf()
3218 if (param.v != chunk->chunk_end) in sctp_verify_asconf()
3240 addip = (struct sctp_addip_chunk *)asconf->chunk_hdr; in sctp_process_asconf()
3241 chunk_len = ntohs(asconf->chunk_hdr->length) - in sctp_process_asconf()
3243 hdr = (struct sctp_addiphdr *)asconf->skb->data; in sctp_process_asconf()
3244 serial = ntohl(hdr->serial); in sctp_process_asconf()
3248 addr_param = (union sctp_addr_param *)(asconf->skb->data + length); in sctp_process_asconf()
3249 chunk_len -= length; in sctp_process_asconf()
3254 length = ntohs(addr_param->p.length); in sctp_process_asconf()
3255 chunk_len -= length; in sctp_process_asconf()
3269 if (param.p->type == SCTP_PARAM_IPV4_ADDRESS || in sctp_process_asconf()
3270 param.p->type == SCTP_PARAM_IPV6_ADDRESS) in sctp_process_asconf()
3285 sctp_add_asconf_response(asconf_ack, param.addip->crr_id, in sctp_process_asconf()
3297 asoc->peer.addip_serial++; in sctp_process_asconf()
3304 list_add_tail(&asconf_ack->transmitted_list, in sctp_process_asconf()
3305 &asoc->asconf_ack_list); in sctp_process_asconf()
3315 struct sctp_bind_addr *bp = &asoc->base.bind_addr; in sctp_asconf_param_success()
3325 af = sctp_get_af_specific(param_type2af(addr_param->p.type)); in sctp_asconf_param_success()
3326 if (!af->from_addr_param(&addr, addr_param, htons(bp->port), 0)) in sctp_asconf_param_success()
3329 switch (asconf_param->param_hdr.type) { in sctp_asconf_param_success()
3335 list_for_each_entry(saddr, &bp->address_list, list) { in sctp_asconf_param_success()
3336 if (sctp_cmp_addr_exact(&saddr->a, &addr)) in sctp_asconf_param_success()
3337 saddr->state = SCTP_ADDR_SRC; in sctp_asconf_param_success()
3340 list_for_each_entry(transport, &asoc->peer.transport_addr_list, in sctp_asconf_param_success()
3348 if (asoc->asconf_addr_del_pending != NULL && in sctp_asconf_param_success()
3349 sctp_cmp_addr_exact(asoc->asconf_addr_del_pending, &addr)) { in sctp_asconf_param_success()
3350 kfree(asoc->asconf_addr_del_pending); in sctp_asconf_param_success()
3351 asoc->asconf_addr_del_pending = NULL; in sctp_asconf_param_success()
3354 list_for_each_entry(transport, &asoc->peer.transport_addr_list, in sctp_asconf_param_success()
3388 asconf_ack_len = ntohs(asconf_ack->chunk_hdr->length) - in sctp_get_asconf_response()
3395 asconf_ack_param = (struct sctp_addip_param *)(asconf_ack->skb->data + in sctp_get_asconf_response()
3397 asconf_ack_len -= length; in sctp_get_asconf_response()
3400 if (asconf_ack_param->crr_id == asconf_param->crr_id) { in sctp_get_asconf_response()
3401 switch (asconf_ack_param->param_hdr.type) { in sctp_get_asconf_response()
3407 asconf_ack_len -= length; in sctp_get_asconf_response()
3409 return err_param->cause; in sctp_get_asconf_response()
3418 length = ntohs(asconf_ack_param->param_hdr.length); in sctp_get_asconf_response()
3420 asconf_ack_len -= length; in sctp_get_asconf_response()
3430 struct sctp_chunk *asconf = asoc->addip_last_asconf; in sctp_process_asconf_ack()
3434 int asconf_len = asconf->skb->len; in sctp_process_asconf_ack()
3444 addr_param = (union sctp_addr_param *)(asconf->skb->data + length); in sctp_process_asconf_ack()
3445 asconf_len -= length; in sctp_process_asconf_ack()
3450 length = ntohs(addr_param->p.length); in sctp_process_asconf_ack()
3452 asconf_len -= length; in sctp_process_asconf_ack()
3459 if (asconf_ack->skb->len == sizeof(struct sctp_addiphdr)) in sctp_process_asconf_ack()
3487 asoc->peer.addip_disabled_mask |= in sctp_process_asconf_ack()
3488 asconf_param->param_hdr.type; in sctp_process_asconf_ack()
3501 length = ntohs(asconf_param->param_hdr.length); in sctp_process_asconf_ack()
3503 asconf_len -= length; in sctp_process_asconf_ack()
3506 if (no_err && asoc->src_out_of_asoc_ok) { in sctp_process_asconf_ack()
3507 asoc->src_out_of_asoc_ok = 0; in sctp_process_asconf_ack()
3508 sctp_transport_immediate_rtx(asoc->peer.primary_path); in sctp_process_asconf_ack()
3512 list_del_init(&asconf->transmitted_list); in sctp_process_asconf_ack()
3514 asoc->addip_last_asconf = NULL; in sctp_process_asconf_ack()
3519 /* Make a FWD TSN chunk. */
3538 retval->subh.fwdtsn_hdr = in sctp_make_fwdtsn()
3566 retval->subh.ifwdtsn_hdr = in sctp_make_ifwdtsn()
3574 /* RE-CONFIG 3.1 (RE-CONFIG chunk)
3577 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3579 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3581 * / Re-configuration Parameter /
3583 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3585 * / Re-configuration Parameter (optional) /
3587 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3600 reconf = (struct sctp_reconf_chunk *)retval->chunk_hdr; in sctp_make_reconf()
3601 retval->param_hdr.v = reconf->params; in sctp_make_reconf()
3606 /* RE-CONFIG 4.1 (STREAM OUT RESET)
3609 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3611 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3612 * | Re-configuration Request Sequence Number |
3613 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3614 * | Re-configuration Response Sequence Number |
3615 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3616 * | Sender's Last Assigned TSN |
3617 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3619 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3621 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3622 * | Stream Number N-1 (optional) | Stream Number N (optional) |
3623 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3625 * RE-CONFIG 4.2 (STREAM IN RESET)
3628 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3630 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3631 * | Re-configuration Request Sequence Number |
3632 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3634 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3636 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3637 * | Stream Number N-1 (optional) | Stream Number N (optional) |
3638 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3661 outreq.request_seq = htonl(asoc->strreset_outseq); in sctp_make_strreset_req()
3662 outreq.response_seq = htonl(asoc->strreset_inseq - 1); in sctp_make_strreset_req()
3663 outreq.send_reset_at_tsn = htonl(asoc->next_tsn - 1); in sctp_make_strreset_req()
3674 inreq.request_seq = htonl(asoc->strreset_outseq + out); in sctp_make_strreset_req()
3685 /* RE-CONFIG 4.3 (SSN/TSN RESET ALL)
3688 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3690 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3691 * | Re-configuration Request Sequence Number |
3692 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3707 tsnreq.request_seq = htonl(asoc->strreset_outseq); in sctp_make_strreset_tsnreq()
3714 /* RE-CONFIG 4.5/4.6 (ADD STREAM)
3717 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3719 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3720 * | Re-configuration Request Sequence Number |
3721 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3723 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3741 addstrm.request_seq = htonl(asoc->strreset_outseq); in sctp_make_strreset_addstrm()
3751 addstrm.request_seq = htonl(asoc->strreset_outseq + !!out); in sctp_make_strreset_addstrm()
3760 /* RE-CONFIG 4.4 (RESP)
3763 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3765 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3766 * | Re-configuration Response Sequence Number |
3767 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3769 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3792 /* RE-CONFIG 4.4 OPTIONAL (TSNRESP)
3795 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3797 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3798 * | Re-configuration Response Sequence Number |
3799 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3801 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3802 * | Sender's Next TSN (optional) |
3803 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3804 * | Receiver's Next TSN (optional) |
3805 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3842 hdr = (struct sctp_reconf_chunk *)chunk->chunk_hdr; in sctp_verify_reconf()
3844 __u16 length = ntohs(param.p->length); in sctp_verify_reconf()
3849 switch (param.p->type) { in sctp_verify_reconf()
3887 last = param.p->type; in sctp_verify_reconf()