2 * SPDX-License-Identifier: BSD-3-Clause
4 * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
5 * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
6 * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
11 * a) Redistributions of source code must retain the above copyright notice,
12 * this list of conditions and the following disclaimer.
14 * b) Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the distribution.
18 * c) Neither the name of Cisco Systems, Inc. nor the names of its
19 * contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
24 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32 * THE POSSIBILITY OF SUCH DAMAGE.
35 #if defined(__FreeBSD__) && !defined(__Userspace__)
36 #include <sys/cdefs.h>
37 __FBSDID("$FreeBSD: head/sys/netinet/sctp_asconf.c 363194 2020-07-14 20:32:50Z tuexen $");
40 #include <netinet/sctp_os.h>
41 #include <netinet/sctp_var.h>
42 #include <netinet/sctp_sysctl.h>
43 #include <netinet/sctp_pcb.h>
44 #include <netinet/sctp_header.h>
45 #include <netinet/sctputil.h>
46 #include <netinet/sctp_output.h>
47 #include <netinet/sctp_asconf.h>
48 #include <netinet/sctp_timer.h>
52 * SCTP_DEBUG_ASCONF1: protocol info, general info and errors
53 * SCTP_DEBUG_ASCONF2: detailed info
59 * An ASCONF parameter queue exists per asoc which holds the pending address
60 * operations. Lists are updated upon receipt of ASCONF-ACK.
62 * A restricted_addrs list exists per assoc to hold local addresses that are
63 * not (yet) usable by the assoc as a source address. These addresses are
64 * either pending an ASCONF operation (and exist on the ASCONF parameter
65 * queue), or they are permanently restricted (the peer has returned an
66 * ERROR indication to an ASCONF(ADD), or the peer does not support ASCONF).
68 * Deleted addresses are always immediately removed from the lists as they will
69 * (shortly) no longer exist in the kernel. We send ASCONFs as a courtesy,
74 * ASCONF parameter processing.
75 * response_required: set if a reply is required (eg. SUCCESS_REPORT).
76 * returns a mbuf to an "error" response parameter or NULL/"success" if ok.
77 * FIX: allocating this many mbufs on the fly is pretty inefficient...
80 sctp_asconf_success_response(uint32_t id)
82 struct mbuf *m_reply = NULL;
83 struct sctp_asconf_paramhdr *aph;
85 m_reply = sctp_get_mbuf_for_msg(sizeof(struct sctp_asconf_paramhdr),
86 0, M_NOWAIT, 1, MT_DATA);
87 if (m_reply == NULL) {
88 SCTPDBG(SCTP_DEBUG_ASCONF1,
89 "asconf_success_response: couldn't get mbuf!\n");
92 aph = mtod(m_reply, struct sctp_asconf_paramhdr *);
93 aph->correlation_id = id;
94 aph->ph.param_type = htons(SCTP_SUCCESS_REPORT);
95 aph->ph.param_length = sizeof(struct sctp_asconf_paramhdr);
96 SCTP_BUF_LEN(m_reply) = aph->ph.param_length;
97 aph->ph.param_length = htons(aph->ph.param_length);
103 sctp_asconf_error_response(uint32_t id, uint16_t cause, uint8_t *error_tlv,
106 struct mbuf *m_reply = NULL;
107 struct sctp_asconf_paramhdr *aph;
108 struct sctp_error_cause *error;
110 uint16_t i, param_length, cause_length, padding_length;
113 if (error_tlv == NULL) {
116 cause_length = sizeof(struct sctp_error_cause) + tlv_length;
117 param_length = sizeof(struct sctp_asconf_paramhdr) + cause_length;
118 padding_length = tlv_length % 4;
119 if (padding_length != 0) {
120 padding_length = 4 - padding_length;
122 buf_len = param_length + padding_length;
123 if (buf_len > MLEN) {
124 SCTPDBG(SCTP_DEBUG_ASCONF1,
125 "asconf_error_response: tlv_length (%xh) too big\n",
129 m_reply = sctp_get_mbuf_for_msg(buf_len, 0, M_NOWAIT, 1, MT_DATA);
130 if (m_reply == NULL) {
131 SCTPDBG(SCTP_DEBUG_ASCONF1,
132 "asconf_error_response: couldn't get mbuf!\n");
135 aph = mtod(m_reply, struct sctp_asconf_paramhdr *);
136 aph->ph.param_type = htons(SCTP_ERROR_CAUSE_IND);
137 aph->ph.param_length = htons(param_length);
138 aph->correlation_id = id;
139 error = (struct sctp_error_cause *)(aph + 1);
140 error->code = htons(cause);
141 error->length = htons(cause_length);
142 if (error_tlv != NULL) {
143 tlv = (uint8_t *) (error + 1);
144 memcpy(tlv, error_tlv, tlv_length);
145 for (i = 0; i < padding_length; i++) {
146 tlv[tlv_length + i] = 0;
149 SCTP_BUF_LEN(m_reply) = buf_len;
154 sctp_process_asconf_add_ip(struct sockaddr *src, struct sctp_asconf_paramhdr *aph,
155 struct sctp_tcb *stcb, int send_hb, int response_required)
157 struct sctp_nets *net;
158 struct mbuf *m_reply = NULL;
159 union sctp_sockstore store;
160 struct sctp_paramhdr *ph;
161 uint16_t param_type, aparam_length;
162 #if defined(INET) || defined(INET6)
163 uint16_t param_length;
166 int zero_address = 0;
169 struct sockaddr_in *sin;
170 struct sctp_ipv4addr_param *v4addr;
173 struct sockaddr_in6 *sin6;
174 struct sctp_ipv6addr_param *v6addr;
177 aparam_length = ntohs(aph->ph.param_length);
178 if (aparam_length < sizeof(struct sctp_asconf_paramhdr) + sizeof(struct sctp_paramhdr)) {
181 ph = (struct sctp_paramhdr *)(aph + 1);
182 param_type = ntohs(ph->param_type);
183 #if defined(INET) || defined(INET6)
184 param_length = ntohs(ph->param_length);
185 if (param_length + sizeof(struct sctp_asconf_paramhdr) != aparam_length) {
190 switch (param_type) {
192 case SCTP_IPV4_ADDRESS:
193 if (param_length != sizeof(struct sctp_ipv4addr_param)) {
194 /* invalid param size */
197 v4addr = (struct sctp_ipv4addr_param *)ph;
199 memset(sin, 0, sizeof(*sin));
200 sin->sin_family = AF_INET;
202 sin->sin_len = sizeof(struct sockaddr_in);
204 sin->sin_port = stcb->rport;
205 sin->sin_addr.s_addr = v4addr->addr;
206 if ((sin->sin_addr.s_addr == INADDR_BROADCAST) ||
207 IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) {
210 if (sin->sin_addr.s_addr == INADDR_ANY)
212 SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_add_ip: adding ");
213 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
217 case SCTP_IPV6_ADDRESS:
218 if (param_length != sizeof(struct sctp_ipv6addr_param)) {
219 /* invalid param size */
222 v6addr = (struct sctp_ipv6addr_param *)ph;
224 memset(sin6, 0, sizeof(*sin6));
225 sin6->sin6_family = AF_INET6;
227 sin6->sin6_len = sizeof(struct sockaddr_in6);
229 sin6->sin6_port = stcb->rport;
230 memcpy((caddr_t)&sin6->sin6_addr, v6addr->addr,
231 sizeof(struct in6_addr));
232 if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
235 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
237 SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_add_ip: adding ");
238 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
242 m_reply = sctp_asconf_error_response(aph->correlation_id,
243 SCTP_CAUSE_INVALID_PARAM, (uint8_t *) aph,
248 /* if 0.0.0.0/::0, add the source address instead */
249 if (zero_address && SCTP_BASE_SYSCTL(sctp_nat_friendly)) {
251 SCTPDBG(SCTP_DEBUG_ASCONF1,
252 "process_asconf_add_ip: using source addr ");
253 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, src);
256 /* add the address */
258 m_reply = sctp_asconf_error_response(aph->correlation_id,
259 SCTP_CAUSE_INVALID_PARAM, (uint8_t *) aph,
261 } else if (sctp_add_remote_addr(stcb, sa, &net, stcb->asoc.port,
263 SCTP_ADDR_DYNAMIC_ADDED) != 0) {
264 SCTPDBG(SCTP_DEBUG_ASCONF1,
265 "process_asconf_add_ip: error adding address\n");
266 m_reply = sctp_asconf_error_response(aph->correlation_id,
267 SCTP_CAUSE_RESOURCE_SHORTAGE, (uint8_t *) aph,
270 if (response_required) {
272 sctp_asconf_success_response(aph->correlation_id);
275 /* notify upper layer */
276 sctp_ulp_notify(SCTP_NOTIFY_ASCONF_ADD_IP, stcb, 0, sa, SCTP_SO_NOT_LOCKED);
277 sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, stcb->sctp_ep, stcb, net);
278 sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep,
281 sctp_send_hb(stcb, net, SCTP_SO_NOT_LOCKED);
289 sctp_asconf_del_remote_addrs_except(struct sctp_tcb *stcb, struct sockaddr *src)
291 struct sctp_nets *src_net, *net, *nnet;
293 /* make sure the source address exists as a destination net */
294 src_net = sctp_findnet(stcb, src);
295 if (src_net == NULL) {
300 /* delete all destination addresses except the source */
301 TAILQ_FOREACH_SAFE(net, &stcb->asoc.nets, sctp_next, nnet) {
302 if (net != src_net) {
303 /* delete this address */
304 SCTPDBG(SCTP_DEBUG_ASCONF1,
305 "asconf_del_remote_addrs_except: deleting ");
306 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1,
307 (struct sockaddr *)&net->ro._l_addr);
308 /* notify upper layer */
309 sctp_ulp_notify(SCTP_NOTIFY_ASCONF_DELETE_IP, stcb, 0,
310 (struct sockaddr *)&net->ro._l_addr, SCTP_SO_NOT_LOCKED);
311 sctp_remove_net(stcb, net);
318 sctp_process_asconf_delete_ip(struct sockaddr *src,
319 struct sctp_asconf_paramhdr *aph,
320 struct sctp_tcb *stcb, int response_required)
322 struct mbuf *m_reply = NULL;
323 union sctp_sockstore store;
324 struct sctp_paramhdr *ph;
325 uint16_t param_type, aparam_length;
326 #if defined(INET) || defined(INET6)
327 uint16_t param_length;
330 int zero_address = 0;
333 struct sockaddr_in *sin;
334 struct sctp_ipv4addr_param *v4addr;
337 struct sockaddr_in6 *sin6;
338 struct sctp_ipv6addr_param *v6addr;
341 aparam_length = ntohs(aph->ph.param_length);
342 if (aparam_length < sizeof(struct sctp_asconf_paramhdr) + sizeof(struct sctp_paramhdr)) {
345 ph = (struct sctp_paramhdr *)(aph + 1);
346 param_type = ntohs(ph->param_type);
347 #if defined(INET) || defined(INET6)
348 param_length = ntohs(ph->param_length);
349 if (param_length + sizeof(struct sctp_asconf_paramhdr) != aparam_length) {
354 switch (param_type) {
356 case SCTP_IPV4_ADDRESS:
357 if (param_length != sizeof(struct sctp_ipv4addr_param)) {
358 /* invalid param size */
361 v4addr = (struct sctp_ipv4addr_param *)ph;
363 memset(sin, 0, sizeof(*sin));
364 sin->sin_family = AF_INET;
366 sin->sin_len = sizeof(struct sockaddr_in);
368 sin->sin_port = stcb->rport;
369 sin->sin_addr.s_addr = v4addr->addr;
370 if (sin->sin_addr.s_addr == INADDR_ANY)
372 SCTPDBG(SCTP_DEBUG_ASCONF1,
373 "process_asconf_delete_ip: deleting ");
374 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
378 case SCTP_IPV6_ADDRESS:
379 if (param_length != sizeof(struct sctp_ipv6addr_param)) {
380 /* invalid param size */
383 v6addr = (struct sctp_ipv6addr_param *)ph;
385 memset(sin6, 0, sizeof(*sin6));
386 sin6->sin6_family = AF_INET6;
388 sin6->sin6_len = sizeof(struct sockaddr_in6);
390 sin6->sin6_port = stcb->rport;
391 memcpy(&sin6->sin6_addr, v6addr->addr,
392 sizeof(struct in6_addr));
393 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
395 SCTPDBG(SCTP_DEBUG_ASCONF1,
396 "process_asconf_delete_ip: deleting ");
397 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
401 m_reply = sctp_asconf_error_response(aph->correlation_id,
402 SCTP_CAUSE_UNRESOLVABLE_ADDR, (uint8_t *) aph,
407 /* make sure the source address is not being deleted */
408 if (sctp_cmpaddr(sa, src)) {
409 /* trying to delete the source address! */
410 SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_delete_ip: tried to delete source addr\n");
411 m_reply = sctp_asconf_error_response(aph->correlation_id,
412 SCTP_CAUSE_DELETING_SRC_ADDR, (uint8_t *) aph,
417 /* if deleting 0.0.0.0/::0, delete all addresses except src addr */
418 if (zero_address && SCTP_BASE_SYSCTL(sctp_nat_friendly)) {
419 result = sctp_asconf_del_remote_addrs_except(stcb, src);
422 /* src address did not exist? */
423 SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_delete_ip: src addr does not exist?\n");
424 /* what error to reply with?? */
426 sctp_asconf_error_response(aph->correlation_id,
427 SCTP_CAUSE_REQUEST_REFUSED, (uint8_t *) aph,
429 } else if (response_required) {
431 sctp_asconf_success_response(aph->correlation_id);
436 /* delete the address */
437 result = sctp_del_remote_addr(stcb, sa);
439 * note if result == -2, the address doesn't exist in the asoc but
440 * since it's being deleted anyways, we just ack the delete -- but
441 * this probably means something has already gone awry
444 /* only one address in the asoc */
445 SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_delete_ip: tried to delete last IP addr!\n");
446 m_reply = sctp_asconf_error_response(aph->correlation_id,
447 SCTP_CAUSE_DELETING_LAST_ADDR, (uint8_t *) aph,
450 if (response_required) {
451 m_reply = sctp_asconf_success_response(aph->correlation_id);
453 /* notify upper layer */
454 sctp_ulp_notify(SCTP_NOTIFY_ASCONF_DELETE_IP, stcb, 0, sa, SCTP_SO_NOT_LOCKED);
460 sctp_process_asconf_set_primary(struct sockaddr *src,
461 struct sctp_asconf_paramhdr *aph,
462 struct sctp_tcb *stcb, int response_required)
464 struct mbuf *m_reply = NULL;
465 union sctp_sockstore store;
466 struct sctp_paramhdr *ph;
467 uint16_t param_type, aparam_length;
468 #if defined(INET) || defined(INET6)
469 uint16_t param_length;
472 int zero_address = 0;
474 struct sockaddr_in *sin;
475 struct sctp_ipv4addr_param *v4addr;
478 struct sockaddr_in6 *sin6;
479 struct sctp_ipv6addr_param *v6addr;
482 aparam_length = ntohs(aph->ph.param_length);
483 if (aparam_length < sizeof(struct sctp_asconf_paramhdr) + sizeof(struct sctp_paramhdr)) {
486 ph = (struct sctp_paramhdr *)(aph + 1);
487 param_type = ntohs(ph->param_type);
488 #if defined(INET) || defined(INET6)
489 param_length = ntohs(ph->param_length);
490 if (param_length + sizeof(struct sctp_asconf_paramhdr) != aparam_length) {
495 switch (param_type) {
497 case SCTP_IPV4_ADDRESS:
498 if (param_length != sizeof(struct sctp_ipv4addr_param)) {
499 /* invalid param size */
502 v4addr = (struct sctp_ipv4addr_param *)ph;
504 memset(sin, 0, sizeof(*sin));
505 sin->sin_family = AF_INET;
507 sin->sin_len = sizeof(struct sockaddr_in);
509 sin->sin_addr.s_addr = v4addr->addr;
510 if (sin->sin_addr.s_addr == INADDR_ANY)
512 SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_set_primary: ");
513 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
517 case SCTP_IPV6_ADDRESS:
518 if (param_length != sizeof(struct sctp_ipv6addr_param)) {
519 /* invalid param size */
522 v6addr = (struct sctp_ipv6addr_param *)ph;
524 memset(sin6, 0, sizeof(*sin6));
525 sin6->sin6_family = AF_INET6;
527 sin6->sin6_len = sizeof(struct sockaddr_in6);
529 memcpy((caddr_t)&sin6->sin6_addr, v6addr->addr,
530 sizeof(struct in6_addr));
531 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
533 SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_set_primary: ");
534 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
538 m_reply = sctp_asconf_error_response(aph->correlation_id,
539 SCTP_CAUSE_UNRESOLVABLE_ADDR, (uint8_t *) aph,
544 /* if 0.0.0.0/::0, use the source address instead */
545 if (zero_address && SCTP_BASE_SYSCTL(sctp_nat_friendly)) {
547 SCTPDBG(SCTP_DEBUG_ASCONF1,
548 "process_asconf_set_primary: using source addr ");
549 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, src);
551 /* set the primary address */
552 if (sctp_set_primary_addr(stcb, sa, NULL) == 0) {
553 SCTPDBG(SCTP_DEBUG_ASCONF1,
554 "process_asconf_set_primary: primary address set\n");
555 /* notify upper layer */
556 sctp_ulp_notify(SCTP_NOTIFY_ASCONF_SET_PRIMARY, stcb, 0, sa, SCTP_SO_NOT_LOCKED);
557 if ((stcb->asoc.primary_destination->dest_state & SCTP_ADDR_REACHABLE) &&
558 (!(stcb->asoc.primary_destination->dest_state & SCTP_ADDR_PF)) &&
559 (stcb->asoc.alternate)) {
560 sctp_free_remote_addr(stcb->asoc.alternate);
561 stcb->asoc.alternate = NULL;
563 if (response_required) {
564 m_reply = sctp_asconf_success_response(aph->correlation_id);
566 /* Mobility adaptation.
567 Ideally, when the reception of SET PRIMARY with DELETE IP
568 ADDRESS of the previous primary destination, unacknowledged
569 DATA are retransmitted immediately to the new primary
570 destination for seamless handover.
571 If the destination is UNCONFIRMED and marked to REQ_PRIM,
572 The retransmission occur when reception of the
573 HEARTBEAT-ACK. (See sctp_handle_heartbeat_ack in
575 Also, when change of the primary destination, it is better
576 that all subsequent new DATA containing already queued DATA
577 are transmitted to the new primary destination. (by micchie)
579 if ((sctp_is_mobility_feature_on(stcb->sctp_ep,
580 SCTP_MOBILITY_BASE) ||
581 sctp_is_mobility_feature_on(stcb->sctp_ep,
582 SCTP_MOBILITY_FASTHANDOFF)) &&
583 sctp_is_mobility_feature_on(stcb->sctp_ep,
584 SCTP_MOBILITY_PRIM_DELETED) &&
585 (stcb->asoc.primary_destination->dest_state &
586 SCTP_ADDR_UNCONFIRMED) == 0) {
588 sctp_timer_stop(SCTP_TIMER_TYPE_PRIM_DELETED,
589 stcb->sctp_ep, stcb, NULL,
590 SCTP_FROM_SCTP_ASCONF + SCTP_LOC_1);
591 if (sctp_is_mobility_feature_on(stcb->sctp_ep,
592 SCTP_MOBILITY_FASTHANDOFF)) {
593 sctp_assoc_immediate_retrans(stcb,
594 stcb->asoc.primary_destination);
596 if (sctp_is_mobility_feature_on(stcb->sctp_ep,
597 SCTP_MOBILITY_BASE)) {
598 sctp_move_chunks_from_net(stcb,
599 stcb->asoc.deleted_primary);
601 sctp_delete_prim_timer(stcb->sctp_ep, stcb);
604 /* couldn't set the requested primary address! */
605 SCTPDBG(SCTP_DEBUG_ASCONF1,
606 "process_asconf_set_primary: set primary failed!\n");
607 /* must have been an invalid address, so report */
608 m_reply = sctp_asconf_error_response(aph->correlation_id,
609 SCTP_CAUSE_UNRESOLVABLE_ADDR, (uint8_t *) aph,
617 * handles an ASCONF chunk.
618 * if all parameters are processed ok, send a plain (empty) ASCONF-ACK
621 sctp_handle_asconf(struct mbuf *m, unsigned int offset,
622 struct sockaddr *src,
623 struct sctp_asconf_chunk *cp, struct sctp_tcb *stcb,
626 struct sctp_association *asoc;
628 struct mbuf *n, *m_ack, *m_result, *m_tail;
629 struct sctp_asconf_ack_chunk *ack_cp;
630 struct sctp_asconf_paramhdr *aph;
631 struct sctp_ipv6addr_param *p_addr;
632 unsigned int asconf_limit, cnt;
633 int error = 0; /* did an error occur? */
635 /* asconf param buffer */
636 uint8_t aparam_buf[SCTP_PARAM_BUFFER_SIZE];
637 struct sctp_asconf_ack *ack, *ack_next;
639 /* verify minimum length */
640 if (ntohs(cp->ch.chunk_length) < sizeof(struct sctp_asconf_chunk)) {
641 SCTPDBG(SCTP_DEBUG_ASCONF1,
642 "handle_asconf: chunk too small = %xh\n",
643 ntohs(cp->ch.chunk_length));
647 serial_num = ntohl(cp->serial_number);
649 if (SCTP_TSN_GE(asoc->asconf_seq_in, serial_num)) {
650 /* got a duplicate ASCONF */
651 SCTPDBG(SCTP_DEBUG_ASCONF1,
652 "handle_asconf: got duplicate serial number = %xh\n",
655 } else if (serial_num != (asoc->asconf_seq_in + 1)) {
656 SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: incorrect serial number = %xh (expected next = %xh)\n",
657 serial_num, asoc->asconf_seq_in + 1);
661 /* it's the expected "next" sequence number, so process it */
662 asoc->asconf_seq_in = serial_num; /* update sequence */
663 /* get length of all the param's in the ASCONF */
664 asconf_limit = offset + ntohs(cp->ch.chunk_length);
665 SCTPDBG(SCTP_DEBUG_ASCONF1,
666 "handle_asconf: asconf_limit=%u, sequence=%xh\n",
667 asconf_limit, serial_num);
670 /* delete old cache */
671 SCTPDBG(SCTP_DEBUG_ASCONF1,"handle_asconf: Now processing first ASCONF. Try to delete old cache\n");
673 TAILQ_FOREACH_SAFE(ack, &asoc->asconf_ack_sent, next, ack_next) {
674 if (ack->serial_number == serial_num)
676 SCTPDBG(SCTP_DEBUG_ASCONF1,"handle_asconf: delete old(%u) < first(%u)\n",
677 ack->serial_number, serial_num);
678 TAILQ_REMOVE(&asoc->asconf_ack_sent, ack, next);
679 if (ack->data != NULL) {
680 sctp_m_freem(ack->data);
682 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_asconf_ack), ack);
686 m_ack = sctp_get_mbuf_for_msg(sizeof(struct sctp_asconf_ack_chunk), 0,
687 M_NOWAIT, 1, MT_DATA);
689 SCTPDBG(SCTP_DEBUG_ASCONF1,
690 "handle_asconf: couldn't get mbuf!\n");
693 m_tail = m_ack; /* current reply chain's tail */
695 /* fill in ASCONF-ACK header */
696 ack_cp = mtod(m_ack, struct sctp_asconf_ack_chunk *);
697 ack_cp->ch.chunk_type = SCTP_ASCONF_ACK;
698 ack_cp->ch.chunk_flags = 0;
699 ack_cp->serial_number = htonl(serial_num);
700 /* set initial lengths (eg. just an ASCONF-ACK), ntohx at the end! */
701 SCTP_BUF_LEN(m_ack) = sizeof(struct sctp_asconf_ack_chunk);
702 ack_cp->ch.chunk_length = sizeof(struct sctp_asconf_ack_chunk);
704 /* skip the lookup address parameter */
705 offset += sizeof(struct sctp_asconf_chunk);
706 p_addr = (struct sctp_ipv6addr_param *)sctp_m_getptr(m, offset, sizeof(struct sctp_paramhdr), (uint8_t *)&aparam_buf);
707 if (p_addr == NULL) {
708 SCTPDBG(SCTP_DEBUG_ASCONF1,
709 "handle_asconf: couldn't get lookup addr!\n");
710 /* respond with a missing/invalid mandatory parameter error */
714 /* skip lookup addr */
715 offset += SCTP_SIZE32(ntohs(p_addr->ph.param_length));
716 /* get pointer to first asconf param in ASCONF */
717 aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(m, offset, sizeof(struct sctp_asconf_paramhdr), (uint8_t *)&aparam_buf);
719 SCTPDBG(SCTP_DEBUG_ASCONF1, "Empty ASCONF received?\n");
722 /* process through all parameters */
724 while (aph != NULL) {
725 unsigned int param_length, param_type;
727 param_type = ntohs(aph->ph.param_type);
728 param_length = ntohs(aph->ph.param_length);
729 if (offset + param_length > asconf_limit) {
730 /* parameter goes beyond end of chunk! */
736 if (param_length > sizeof(aparam_buf)) {
737 SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: param length (%u) larger than buffer size!\n", param_length);
741 if (param_length <= sizeof(struct sctp_paramhdr)) {
742 SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: param length (%u) too short\n", param_length);
746 /* get the entire parameter */
747 aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(m, offset, param_length, aparam_buf);
749 SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: couldn't get entire param\n");
753 switch (param_type) {
754 case SCTP_ADD_IP_ADDRESS:
755 m_result = sctp_process_asconf_add_ip(src, aph, stcb,
756 (cnt < SCTP_BASE_SYSCTL(sctp_hb_maxburst)), error);
759 case SCTP_DEL_IP_ADDRESS:
760 m_result = sctp_process_asconf_delete_ip(src, aph, stcb,
763 case SCTP_ERROR_CAUSE_IND:
764 /* not valid in an ASCONF chunk */
766 case SCTP_SET_PRIM_ADDR:
767 m_result = sctp_process_asconf_set_primary(src, aph,
771 SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: sees a NAT VTAG state parameter\n");
773 case SCTP_SUCCESS_REPORT:
774 /* not valid in an ASCONF chunk */
776 case SCTP_ULP_ADAPTATION:
780 if ((param_type & 0x8000) == 0) {
781 /* Been told to STOP at this param */
782 asconf_limit = offset;
784 * FIX FIX - We need to call
785 * sctp_arethere_unrecognized_parameters()
786 * to get a operr and send it for any
787 * param's with the 0x4000 bit set OR do it
788 * here ourselves... note we still must STOP
789 * if the 0x8000 bit is clear.
792 /* unknown/invalid param type */
796 /* add any (error) result to the reply mbuf chain */
797 if (m_result != NULL) {
798 SCTP_BUF_NEXT(m_tail) = m_result;
800 ack_cp->ch.chunk_length += SCTP_BUF_LEN(m_result);
801 /* set flag to force success reports */
804 offset += SCTP_SIZE32(param_length);
805 /* update remaining ASCONF message length to process */
806 if (offset >= asconf_limit) {
807 /* no more data in the mbuf chain */
810 /* get pointer to next asconf param */
811 aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(m, offset,
812 sizeof(struct sctp_asconf_paramhdr),
813 (uint8_t *)&aparam_buf);
815 /* can't get an asconf paramhdr */
816 SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: can't get asconf param hdr!\n");
817 /* FIX ME - add error here... */
822 ack_cp->ch.chunk_length = htons(ack_cp->ch.chunk_length);
823 /* save the ASCONF-ACK reply */
824 ack = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_asconf_ack),
825 struct sctp_asconf_ack);
830 ack->serial_number = serial_num;
831 ack->last_sent_to = NULL;
834 for (n = m_ack; n != NULL; n = SCTP_BUF_NEXT(n)) {
835 ack->len += SCTP_BUF_LEN(n);
837 TAILQ_INSERT_TAIL(&stcb->asoc.asconf_ack_sent, ack, next);
839 /* see if last_control_chunk_from is set properly (use IP src addr) */
840 if (stcb->asoc.last_control_chunk_from == NULL) {
842 * this could happen if the source address was just newly
845 SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: looking up net for IP source address\n");
846 SCTPDBG(SCTP_DEBUG_ASCONF1, "Looking for IP source: ");
847 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, src);
848 /* look up the from address */
849 stcb->asoc.last_control_chunk_from = sctp_findnet(stcb, src);
851 if (stcb->asoc.last_control_chunk_from == NULL) {
852 SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: IP source address not found?!\n");
859 * does the address match? returns 0 if not, 1 if so
862 sctp_asconf_addr_match(struct sctp_asconf_addr *aa, struct sockaddr *sa)
864 switch (sa->sa_family) {
869 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
871 if ((aa->ap.addrp.ph.param_type == SCTP_IPV6_ADDRESS) &&
872 (memcmp(&aa->ap.addrp.addr, &sin6->sin6_addr,
873 sizeof(struct in6_addr)) == 0)) {
882 struct sockaddr_in *sin = (struct sockaddr_in *)sa;
884 if ((aa->ap.addrp.ph.param_type == SCTP_IPV4_ADDRESS) &&
885 (memcmp(&aa->ap.addrp.addr, &sin->sin_addr,
886 sizeof(struct in_addr)) == 0)) {
899 * does the address match? returns 0 if not, 1 if so
902 sctp_addr_match(struct sctp_paramhdr *ph, struct sockaddr *sa)
904 #if defined(INET) || defined(INET6)
905 uint16_t param_type, param_length;
907 param_type = ntohs(ph->param_type);
908 param_length = ntohs(ph->param_length);
910 switch (sa->sa_family) {
915 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
916 struct sctp_ipv6addr_param *v6addr;
918 v6addr = (struct sctp_ipv6addr_param *)ph;
919 if ((param_type == SCTP_IPV6_ADDRESS) &&
920 (param_length == sizeof(struct sctp_ipv6addr_param)) &&
921 (memcmp(&v6addr->addr, &sin6->sin6_addr,
922 sizeof(struct in6_addr)) == 0)) {
931 struct sockaddr_in *sin = (struct sockaddr_in *)sa;
932 struct sctp_ipv4addr_param *v4addr;
934 v4addr = (struct sctp_ipv4addr_param *)ph;
935 if ((param_type == SCTP_IPV4_ADDRESS) &&
936 (param_length == sizeof(struct sctp_ipv4addr_param)) &&
937 (memcmp(&v4addr->addr, &sin->sin_addr,
938 sizeof(struct in_addr)) == 0)) {
950 * Cleanup for non-responded/OP ERR'd ASCONF
953 sctp_asconf_cleanup(struct sctp_tcb *stcb)
956 * clear out any existing asconfs going out
958 sctp_timer_stop(SCTP_TIMER_TYPE_ASCONF, stcb->sctp_ep, stcb, NULL,
959 SCTP_FROM_SCTP_ASCONF + SCTP_LOC_2);
960 stcb->asoc.asconf_seq_out_acked = stcb->asoc.asconf_seq_out;
961 /* remove the old ASCONF on our outbound queue */
962 sctp_toss_old_asconf(stcb);
966 * cleanup any cached source addresses that may be topologically
967 * incorrect after a new address has been added to this interface.
970 sctp_asconf_nets_cleanup(struct sctp_tcb *stcb, struct sctp_ifn *ifn)
972 struct sctp_nets *net;
975 * Ideally, we want to only clear cached routes and source addresses
976 * that are topologically incorrect. But since there is no easy way
977 * to know whether the newly added address on the ifn would cause a
978 * routing change (i.e. a new egress interface would be chosen)
979 * without doing a new routing lookup and source address selection,
980 * we will (for now) just flush any cached route using a different
981 * ifn (and cached source addrs) and let output re-choose them during
982 * the next send on that net.
984 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
986 * clear any cached route (and cached source address) if the
987 * route's interface is NOT the same as the address change.
988 * If it's the same interface, just clear the cached source
991 if (SCTP_ROUTE_HAS_VALID_IFN(&net->ro) &&
993 (SCTP_GET_IF_INDEX_FROM_ROUTE(&net->ro) != ifn->ifn_index))) {
994 /* clear any cached route */
995 #if defined(__FreeBSD__) && !defined(__Userspace__)
998 RTFREE(net->ro.ro_rt);
999 net->ro.ro_rt = NULL;
1002 /* clear any cached source address */
1003 if (net->src_addr_selected) {
1004 sctp_free_ifa(net->ro._s_addr);
1005 net->ro._s_addr = NULL;
1006 net->src_addr_selected = 0;
1013 sctp_assoc_immediate_retrans(struct sctp_tcb *stcb, struct sctp_nets *dstnet)
1017 if (dstnet->dest_state & SCTP_ADDR_UNCONFIRMED) {
1020 if (stcb->asoc.deleted_primary == NULL) {
1024 if (!TAILQ_EMPTY(&stcb->asoc.sent_queue)) {
1025 SCTPDBG(SCTP_DEBUG_ASCONF1, "assoc_immediate_retrans: Deleted primary is ");
1026 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, &stcb->asoc.deleted_primary->ro._l_addr.sa);
1027 SCTPDBG(SCTP_DEBUG_ASCONF1, "Current Primary is ");
1028 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, &stcb->asoc.primary_destination->ro._l_addr.sa);
1029 sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb,
1030 stcb->asoc.deleted_primary,
1031 SCTP_FROM_SCTP_ASCONF + SCTP_LOC_3);
1032 stcb->asoc.num_send_timers_up--;
1033 if (stcb->asoc.num_send_timers_up < 0) {
1034 stcb->asoc.num_send_timers_up = 0;
1036 SCTP_TCB_LOCK_ASSERT(stcb);
1037 error = sctp_t3rxt_timer(stcb->sctp_ep, stcb,
1038 stcb->asoc.deleted_primary);
1040 SCTP_INP_DECR_REF(stcb->sctp_ep);
1043 SCTP_TCB_LOCK_ASSERT(stcb);
1044 #ifdef SCTP_AUDITING_ENABLED
1045 sctp_auditing(4, stcb->sctp_ep, stcb, stcb->asoc.deleted_primary);
1047 sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_NOT_LOCKED);
1048 if ((stcb->asoc.num_send_timers_up == 0) &&
1049 (stcb->asoc.sent_queue_cnt > 0)) {
1050 struct sctp_tmit_chunk *chk;
1052 TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
1053 if (chk->whoTo != NULL) {
1058 sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, chk->whoTo);
1065 #if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Userspace__)
1067 sctp_asconf_queue_mgmt(struct sctp_tcb *, struct sctp_ifa *, uint16_t);
1070 sctp_net_immediate_retrans(struct sctp_tcb *stcb, struct sctp_nets *net)
1072 struct sctp_tmit_chunk *chk;
1074 SCTPDBG(SCTP_DEBUG_ASCONF1, "net_immediate_retrans: RTO is %d\n", net->RTO);
1075 sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, net,
1076 SCTP_FROM_SCTP_ASCONF + SCTP_LOC_4);
1077 stcb->asoc.cc_functions.sctp_set_initial_cc_param(stcb, net);
1078 net->error_count = 0;
1079 TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
1080 if (chk->whoTo == net) {
1081 if (chk->sent < SCTP_DATAGRAM_RESEND) {
1082 chk->sent = SCTP_DATAGRAM_RESEND;
1083 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
1084 sctp_flight_size_decrease(chk);
1085 sctp_total_flight_decrease(stcb, chk);
1086 net->marked_retrans++;
1087 stcb->asoc.marked_retrans++;
1091 if (net->marked_retrans) {
1092 sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_NOT_LOCKED);
1097 sctp_path_check_and_react(struct sctp_tcb *stcb, struct sctp_ifa *newifa)
1099 struct sctp_nets *net;
1100 int addrnum, changed;
1102 /* If number of local valid addresses is 1, the valid address is
1103 probably newly added address.
1104 Several valid addresses in this association. A source address
1105 may not be changed. Additionally, they can be configured on a
1106 same interface as "alias" addresses. (by micchie)
1108 addrnum = sctp_local_addr_count(stcb);
1109 SCTPDBG(SCTP_DEBUG_ASCONF1, "p_check_react(): %d local addresses\n",
1112 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
1113 /* clear any cached route and source address */
1114 #if defined(__FreeBSD__) && !defined(__Userspace__)
1115 RO_NHFREE(&net->ro);
1117 if (net->ro.ro_rt) {
1118 RTFREE(net->ro.ro_rt);
1119 net->ro.ro_rt = NULL;
1122 if (net->src_addr_selected) {
1123 sctp_free_ifa(net->ro._s_addr);
1124 net->ro._s_addr = NULL;
1125 net->src_addr_selected = 0;
1127 /* Retransmit unacknowledged DATA chunks immediately */
1128 if (sctp_is_mobility_feature_on(stcb->sctp_ep,
1129 SCTP_MOBILITY_FASTHANDOFF)) {
1130 sctp_net_immediate_retrans(stcb, net);
1132 /* also, SET PRIMARY is maybe already sent */
1137 /* Multiple local addresses exsist in the association. */
1138 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
1139 /* clear any cached route and source address */
1140 #if defined(__FreeBSD__) && !defined(__Userspace__)
1141 RO_NHFREE(&net->ro);
1143 if (net->ro.ro_rt) {
1144 RTFREE(net->ro.ro_rt);
1145 net->ro.ro_rt = NULL;
1148 if (net->src_addr_selected) {
1149 sctp_free_ifa(net->ro._s_addr);
1150 net->ro._s_addr = NULL;
1151 net->src_addr_selected = 0;
1153 /* Check if the nexthop is corresponding to the new address.
1154 If the new address is corresponding to the current nexthop,
1155 the path will be changed.
1156 If the new address is NOT corresponding to the current
1157 nexthop, the path will not be changed.
1159 SCTP_RTALLOC((sctp_route_t *)&net->ro,
1160 stcb->sctp_ep->def_vrf_id,
1161 stcb->sctp_ep->fibnum);
1162 #if defined(__FreeBSD__) && !defined(__Userspace__)
1163 if (net->ro.ro_nh == NULL)
1165 if (net->ro.ro_rt == NULL)
1170 switch (net->ro._l_addr.sa.sa_family) {
1173 if (sctp_v4src_match_nexthop(newifa, (sctp_route_t *)&net->ro)) {
1180 if (sctp_v6src_match_nexthop(
1181 &newifa->address.sin6, (sctp_route_t *)&net->ro)) {
1189 /* if the newly added address does not relate routing
1190 information, we skip.
1194 /* Retransmit unacknowledged DATA chunks immediately */
1195 if (sctp_is_mobility_feature_on(stcb->sctp_ep,
1196 SCTP_MOBILITY_FASTHANDOFF)) {
1197 sctp_net_immediate_retrans(stcb, net);
1199 /* Send SET PRIMARY for this new address */
1200 if (net == stcb->asoc.primary_destination) {
1201 (void)sctp_asconf_queue_mgmt(stcb, newifa,
1202 SCTP_SET_PRIM_ADDR);
1209 * process an ADD/DELETE IP ack from peer.
1210 * addr: corresponding sctp_ifa to the address being added/deleted.
1211 * type: SCTP_ADD_IP_ADDRESS or SCTP_DEL_IP_ADDRESS.
1212 * flag: 1=success, 0=failure.
1215 sctp_asconf_addr_mgmt_ack(struct sctp_tcb *stcb, struct sctp_ifa *addr, uint32_t flag)
1218 * do the necessary asoc list work- if we get a failure indication,
1219 * leave the address on the assoc's restricted list. If we get a
1220 * success indication, remove the address from the restricted list.
1223 * Note: this will only occur for ADD_IP_ADDRESS, since
1224 * DEL_IP_ADDRESS is never actually added to the list...
1227 /* success case, so remove from the restricted list */
1228 sctp_del_local_addr_restricted(stcb, addr);
1230 #if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Userspace__)
1231 if (sctp_is_mobility_feature_on(stcb->sctp_ep,
1232 SCTP_MOBILITY_BASE) ||
1233 sctp_is_mobility_feature_on(stcb->sctp_ep,
1234 SCTP_MOBILITY_FASTHANDOFF)) {
1235 sctp_path_check_and_react(stcb, addr);
1239 /* clear any cached/topologically incorrect source addresses */
1240 sctp_asconf_nets_cleanup(stcb, addr->ifn_p);
1242 /* else, leave it on the list */
1246 * add an asconf add/delete/set primary IP address parameter to the queue.
1247 * type = SCTP_ADD_IP_ADDRESS, SCTP_DEL_IP_ADDRESS, SCTP_SET_PRIM_ADDR.
1248 * returns 0 if queued, -1 if not queued/removed.
1249 * NOTE: if adding, but a delete for the same address is already scheduled
1250 * (and not yet sent out), simply remove it from queue. Same for deleting
1251 * an address already scheduled for add. If a duplicate operation is found,
1252 * ignore the new one.
1255 sctp_asconf_queue_mgmt(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
1258 struct sctp_asconf_addr *aa, *aa_next;
1260 /* make sure the request isn't already in the queue */
1261 TAILQ_FOREACH_SAFE(aa, &stcb->asoc.asconf_queue, next, aa_next) {
1262 /* address match? */
1263 if (sctp_asconf_addr_match(aa, &ifa->address.sa) == 0)
1265 /* is the request already in queue but not sent?
1266 * pass the request already sent in order to resolve the following case:
1267 * 1. arrival of ADD, then sent
1268 * 2. arrival of DEL. we can't remove the ADD request already sent
1271 if (aa->ap.aph.ph.param_type == type && aa->sent == 0) {
1274 /* is the negative request already in queue, and not sent */
1275 if ((aa->sent == 0) && (type == SCTP_ADD_IP_ADDRESS) &&
1276 (aa->ap.aph.ph.param_type == SCTP_DEL_IP_ADDRESS)) {
1277 /* add requested, delete already queued */
1278 TAILQ_REMOVE(&stcb->asoc.asconf_queue, aa, next);
1279 /* remove the ifa from the restricted list */
1280 sctp_del_local_addr_restricted(stcb, ifa);
1281 /* free the asconf param */
1282 SCTP_FREE(aa, SCTP_M_ASC_ADDR);
1283 SCTPDBG(SCTP_DEBUG_ASCONF2, "asconf_queue_mgmt: add removes queued entry\n");
1286 if ((aa->sent == 0) && (type == SCTP_DEL_IP_ADDRESS) &&
1287 (aa->ap.aph.ph.param_type == SCTP_ADD_IP_ADDRESS)) {
1288 /* delete requested, add already queued */
1289 TAILQ_REMOVE(&stcb->asoc.asconf_queue, aa, next);
1290 /* remove the aa->ifa from the restricted list */
1291 sctp_del_local_addr_restricted(stcb, aa->ifa);
1292 /* free the asconf param */
1293 SCTP_FREE(aa, SCTP_M_ASC_ADDR);
1294 SCTPDBG(SCTP_DEBUG_ASCONF2, "asconf_queue_mgmt: delete removes queued entry\n");
1299 /* adding new request to the queue */
1300 SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa),
1303 /* didn't get memory */
1304 SCTPDBG(SCTP_DEBUG_ASCONF1, "asconf_queue_mgmt: failed to get memory!\n");
1307 aa->special_del = 0;
1308 /* fill in asconf address parameter fields */
1309 /* top level elements are "networked" during send */
1310 aa->ap.aph.ph.param_type = type;
1312 atomic_add_int(&ifa->refcount, 1);
1313 /* correlation_id filled in during send routine later... */
1314 switch (ifa->address.sa.sa_family) {
1318 struct sockaddr_in6 *sin6;
1320 sin6 = &ifa->address.sin6;
1321 aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
1322 aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv6addr_param));
1323 aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) +
1324 sizeof(struct sctp_ipv6addr_param);
1325 memcpy(&aa->ap.addrp.addr, &sin6->sin6_addr,
1326 sizeof(struct in6_addr));
1333 struct sockaddr_in *sin;
1335 sin = &ifa->address.sin;
1336 aa->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
1337 aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv4addr_param));
1338 aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) +
1339 sizeof(struct sctp_ipv4addr_param);
1340 memcpy(&aa->ap.addrp.addr, &sin->sin_addr,
1341 sizeof(struct in_addr));
1346 /* invalid family! */
1347 SCTP_FREE(aa, SCTP_M_ASC_ADDR);
1351 aa->sent = 0; /* clear sent flag */
1353 TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
1355 if (SCTP_BASE_SYSCTL(sctp_debug_on) & SCTP_DEBUG_ASCONF2) {
1356 if (type == SCTP_ADD_IP_ADDRESS) {
1357 SCTP_PRINTF("asconf_queue_mgmt: inserted asconf ADD_IP_ADDRESS: ");
1358 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, &ifa->address.sa);
1359 } else if (type == SCTP_DEL_IP_ADDRESS) {
1360 SCTP_PRINTF("asconf_queue_mgmt: appended asconf DEL_IP_ADDRESS: ");
1361 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, &ifa->address.sa);
1363 SCTP_PRINTF("asconf_queue_mgmt: appended asconf SET_PRIM_ADDR: ");
1364 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, &ifa->address.sa);
1374 * add an asconf operation for the given ifa and type.
1375 * type = SCTP_ADD_IP_ADDRESS, SCTP_DEL_IP_ADDRESS, SCTP_SET_PRIM_ADDR.
1376 * returns 0 if completed, -1 if not completed, 1 if immediate send is
1380 sctp_asconf_queue_add(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
1384 int pending_delete_queued = 0;
1387 /* see if peer supports ASCONF */
1388 if (stcb->asoc.asconf_supported == 0) {
1393 * if this is deleting the last address from the assoc, mark it as
1396 if ((type == SCTP_DEL_IP_ADDRESS) && !stcb->asoc.asconf_del_pending) {
1397 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
1398 last = (sctp_local_addr_count(stcb) == 0);
1400 last = (sctp_local_addr_count(stcb) == 1);
1403 /* set the pending delete info only */
1404 stcb->asoc.asconf_del_pending = 1;
1405 stcb->asoc.asconf_addr_del_pending = ifa;
1406 atomic_add_int(&ifa->refcount, 1);
1407 SCTPDBG(SCTP_DEBUG_ASCONF2,
1408 "asconf_queue_add: mark delete last address pending\n");
1413 /* queue an asconf parameter */
1414 status = sctp_asconf_queue_mgmt(stcb, ifa, type);
1417 * if this is an add, and there is a delete also pending (i.e. the
1418 * last local address is being changed), queue the pending delete too.
1420 if ((type == SCTP_ADD_IP_ADDRESS) && stcb->asoc.asconf_del_pending && (status == 0)) {
1421 /* queue in the pending delete */
1422 if (sctp_asconf_queue_mgmt(stcb,
1423 stcb->asoc.asconf_addr_del_pending,
1424 SCTP_DEL_IP_ADDRESS) == 0) {
1425 SCTPDBG(SCTP_DEBUG_ASCONF2, "asconf_queue_add: queuing pending delete\n");
1426 pending_delete_queued = 1;
1427 /* clear out the pending delete info */
1428 stcb->asoc.asconf_del_pending = 0;
1429 sctp_free_ifa(stcb->asoc.asconf_addr_del_pending);
1430 stcb->asoc.asconf_addr_del_pending = NULL;
1434 if (pending_delete_queued) {
1435 struct sctp_nets *net;
1437 * since we know that the only/last address is now being
1438 * changed in this case, reset the cwnd/rto on all nets to
1439 * start as a new address and path. Also clear the error
1440 * counts to give the assoc the best chance to complete the
1443 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
1444 stcb->asoc.cc_functions.sctp_set_initial_cc_param(stcb,
1447 net->error_count = 0;
1449 stcb->asoc.overall_error_count = 0;
1450 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
1451 sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
1452 stcb->asoc.overall_error_count,
1454 SCTP_FROM_SCTP_ASCONF,
1458 /* queue in an advisory set primary too */
1459 (void)sctp_asconf_queue_mgmt(stcb, ifa, SCTP_SET_PRIM_ADDR);
1460 /* let caller know we should send this out immediately */
1467 * add an asconf delete IP address parameter to the queue by sockaddr and
1468 * possibly with no sctp_ifa available. This is only called by the routine
1469 * that checks the addresses in an INIT-ACK against the current address list.
1470 * returns 0 if completed, non-zero if not completed.
1471 * NOTE: if an add is already scheduled (and not yet sent out), simply
1472 * remove it from queue. If a duplicate operation is found, ignore the
1476 sctp_asconf_queue_sa_delete(struct sctp_tcb *stcb, struct sockaddr *sa)
1478 struct sctp_ifa *ifa;
1479 struct sctp_asconf_addr *aa, *aa_next;
1484 /* see if peer supports ASCONF */
1485 if (stcb->asoc.asconf_supported == 0) {
1488 /* make sure the request isn't already in the queue */
1489 TAILQ_FOREACH_SAFE(aa, &stcb->asoc.asconf_queue, next, aa_next) {
1490 /* address match? */
1491 if (sctp_asconf_addr_match(aa, sa) == 0)
1493 /* is the request already in queue (sent or not) */
1494 if (aa->ap.aph.ph.param_type == SCTP_DEL_IP_ADDRESS) {
1497 /* is the negative request already in queue, and not sent */
1500 if (aa->ap.aph.ph.param_type == SCTP_ADD_IP_ADDRESS) {
1501 /* add already queued, so remove existing entry */
1502 TAILQ_REMOVE(&stcb->asoc.asconf_queue, aa, next);
1503 sctp_del_local_addr_restricted(stcb, aa->ifa);
1504 /* free the entry */
1505 SCTP_FREE(aa, SCTP_M_ASC_ADDR);
1510 /* find any existing ifa-- NOTE ifa CAN be allowed to be NULL */
1511 ifa = sctp_find_ifa_by_addr(sa, stcb->asoc.vrf_id, SCTP_ADDR_NOT_LOCKED);
1513 /* adding new request to the queue */
1514 SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa),
1517 /* didn't get memory */
1518 SCTPDBG(SCTP_DEBUG_ASCONF1,
1519 "sctp_asconf_queue_sa_delete: failed to get memory!\n");
1522 aa->special_del = 0;
1523 /* fill in asconf address parameter fields */
1524 /* top level elements are "networked" during send */
1525 aa->ap.aph.ph.param_type = SCTP_DEL_IP_ADDRESS;
1528 atomic_add_int(&ifa->refcount, 1);
1529 /* correlation_id filled in during send routine later... */
1530 switch (sa->sa_family) {
1535 struct sockaddr_in6 *sin6;
1537 sin6 = (struct sockaddr_in6 *)sa;
1538 aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
1539 aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv6addr_param));
1540 aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) + sizeof(struct sctp_ipv6addr_param);
1541 memcpy(&aa->ap.addrp.addr, &sin6->sin6_addr,
1542 sizeof(struct in6_addr));
1550 struct sockaddr_in *sin = (struct sockaddr_in *)sa;
1552 aa->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
1553 aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv4addr_param));
1554 aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) + sizeof(struct sctp_ipv4addr_param);
1555 memcpy(&aa->ap.addrp.addr, &sin->sin_addr,
1556 sizeof(struct in_addr));
1561 /* invalid family! */
1562 SCTP_FREE(aa, SCTP_M_ASC_ADDR);
1567 aa->sent = 0; /* clear sent flag */
1569 /* delete goes to the back of the queue */
1570 TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
1572 /* sa_ignore MEMLEAK {memory is put on the tailq} */
1577 * find a specific asconf param on our "sent" queue
1579 static struct sctp_asconf_addr *
1580 sctp_asconf_find_param(struct sctp_tcb *stcb, uint32_t correlation_id)
1582 struct sctp_asconf_addr *aa;
1584 TAILQ_FOREACH(aa, &stcb->asoc.asconf_queue, next) {
1585 if (aa->ap.aph.correlation_id == correlation_id &&
1591 /* didn't find it */
1596 * process an SCTP_ERROR_CAUSE_IND for a ASCONF-ACK parameter and do
1597 * notifications based on the error response
1600 sctp_asconf_process_error(struct sctp_tcb *stcb SCTP_UNUSED,
1601 struct sctp_asconf_paramhdr *aph)
1603 struct sctp_error_cause *eh;
1604 struct sctp_paramhdr *ph;
1605 uint16_t param_type;
1606 uint16_t error_code;
1608 eh = (struct sctp_error_cause *)(aph + 1);
1609 ph = (struct sctp_paramhdr *)(eh + 1);
1610 /* validate lengths */
1611 if (htons(eh->length) + sizeof(struct sctp_error_cause) >
1612 htons(aph->ph.param_length)) {
1613 /* invalid error cause length */
1614 SCTPDBG(SCTP_DEBUG_ASCONF1,
1615 "asconf_process_error: cause element too long\n");
1618 if (htons(ph->param_length) + sizeof(struct sctp_paramhdr) >
1619 htons(eh->length)) {
1620 /* invalid included TLV length */
1621 SCTPDBG(SCTP_DEBUG_ASCONF1,
1622 "asconf_process_error: included TLV too long\n");
1625 /* which error code ? */
1626 error_code = ntohs(eh->code);
1627 param_type = ntohs(aph->ph.param_type);
1628 /* FIX: this should go back up the REMOTE_ERROR ULP notify */
1629 switch (error_code) {
1630 case SCTP_CAUSE_RESOURCE_SHORTAGE:
1631 /* we allow ourselves to "try again" for this error */
1634 /* peer can't handle it... */
1635 switch (param_type) {
1636 case SCTP_ADD_IP_ADDRESS:
1637 case SCTP_DEL_IP_ADDRESS:
1638 case SCTP_SET_PRIM_ADDR:
1647 * process an asconf queue param.
1648 * aparam: parameter to process, will be removed from the queue.
1649 * flag: 1=success case, 0=failure case
1652 sctp_asconf_process_param_ack(struct sctp_tcb *stcb,
1653 struct sctp_asconf_addr *aparam, uint32_t flag)
1655 uint16_t param_type;
1657 /* process this param */
1658 param_type = aparam->ap.aph.ph.param_type;
1659 switch (param_type) {
1660 case SCTP_ADD_IP_ADDRESS:
1661 SCTPDBG(SCTP_DEBUG_ASCONF1,
1662 "process_param_ack: added IP address\n");
1663 sctp_asconf_addr_mgmt_ack(stcb, aparam->ifa, flag);
1665 case SCTP_DEL_IP_ADDRESS:
1666 SCTPDBG(SCTP_DEBUG_ASCONF1,
1667 "process_param_ack: deleted IP address\n");
1668 /* nothing really to do... lists already updated */
1670 case SCTP_SET_PRIM_ADDR:
1671 SCTPDBG(SCTP_DEBUG_ASCONF1,
1672 "process_param_ack: set primary IP address\n");
1673 /* nothing to do... peer may start using this addr */
1676 /* should NEVER happen */
1680 /* remove the param and free it */
1681 TAILQ_REMOVE(&stcb->asoc.asconf_queue, aparam, next);
1683 sctp_free_ifa(aparam->ifa);
1684 SCTP_FREE(aparam, SCTP_M_ASC_ADDR);
1688 * cleanup from a bad asconf ack parameter
1691 sctp_asconf_ack_clear(struct sctp_tcb *stcb SCTP_UNUSED)
1693 /* assume peer doesn't really know how to do asconfs */
1694 /* XXX we could free the pending queue here */
1699 sctp_handle_asconf_ack(struct mbuf *m, int offset,
1700 struct sctp_asconf_ack_chunk *cp, struct sctp_tcb *stcb,
1701 struct sctp_nets *net, int *abort_no_unlock)
1703 struct sctp_association *asoc;
1704 uint32_t serial_num;
1705 uint16_t ack_length;
1706 struct sctp_asconf_paramhdr *aph;
1707 struct sctp_asconf_addr *aa, *aa_next;
1708 uint32_t last_error_id = 0; /* last error correlation id */
1710 struct sctp_asconf_addr *ap;
1712 /* asconf param buffer */
1713 uint8_t aparam_buf[SCTP_PARAM_BUFFER_SIZE];
1715 /* verify minimum length */
1716 if (ntohs(cp->ch.chunk_length) < sizeof(struct sctp_asconf_ack_chunk)) {
1717 SCTPDBG(SCTP_DEBUG_ASCONF1,
1718 "handle_asconf_ack: chunk too small = %xh\n",
1719 ntohs(cp->ch.chunk_length));
1723 serial_num = ntohl(cp->serial_number);
1726 * NOTE: we may want to handle this differently- currently, we will
1727 * abort when we get an ack for the expected serial number + 1 (eg.
1728 * we didn't send it), process an ack normally if it is the expected
1729 * serial number, and re-send the previous ack for *ALL* other
1734 * if the serial number is the next expected, but I didn't send it,
1735 * abort the asoc, since someone probably just hijacked us...
1737 if (serial_num == (asoc->asconf_seq_out + 1)) {
1738 struct mbuf *op_err;
1739 char msg[SCTP_DIAG_INFO_LEN];
1741 SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf_ack: got unexpected next serial number! Aborting asoc!\n");
1742 SCTP_SNPRINTF(msg, sizeof(msg), "Never sent serial number %8.8x", serial_num);
1743 op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
1744 sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
1745 *abort_no_unlock = 1;
1748 if (serial_num != asoc->asconf_seq_out_acked + 1) {
1749 /* got a duplicate/unexpected ASCONF-ACK */
1750 SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf_ack: got duplicate/unexpected serial number = %xh (expected = %xh)\n",
1751 serial_num, asoc->asconf_seq_out_acked + 1);
1755 if (serial_num == asoc->asconf_seq_out - 1) {
1756 /* stop our timer */
1757 sctp_timer_stop(SCTP_TIMER_TYPE_ASCONF, stcb->sctp_ep, stcb, NULL,
1758 SCTP_FROM_SCTP_ASCONF + SCTP_LOC_5);
1761 /* process the ASCONF-ACK contents */
1762 ack_length = ntohs(cp->ch.chunk_length) -
1763 sizeof(struct sctp_asconf_ack_chunk);
1764 offset += sizeof(struct sctp_asconf_ack_chunk);
1765 /* process through all parameters */
1766 while (ack_length >= sizeof(struct sctp_asconf_paramhdr)) {
1767 unsigned int param_length, param_type;
1769 /* get pointer to next asconf parameter */
1770 aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(m, offset,
1771 sizeof(struct sctp_asconf_paramhdr), aparam_buf);
1773 /* can't get an asconf paramhdr */
1774 sctp_asconf_ack_clear(stcb);
1777 param_type = ntohs(aph->ph.param_type);
1778 param_length = ntohs(aph->ph.param_length);
1779 if (param_length > ack_length) {
1780 sctp_asconf_ack_clear(stcb);
1783 if (param_length < sizeof(struct sctp_paramhdr)) {
1784 sctp_asconf_ack_clear(stcb);
1787 /* get the complete parameter... */
1788 if (param_length > sizeof(aparam_buf)) {
1789 SCTPDBG(SCTP_DEBUG_ASCONF1,
1790 "param length (%u) larger than buffer size!\n", param_length);
1791 sctp_asconf_ack_clear(stcb);
1794 aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(m, offset, param_length, aparam_buf);
1796 sctp_asconf_ack_clear(stcb);
1799 /* correlation_id is transparent to peer, no ntohl needed */
1800 id = aph->correlation_id;
1802 switch (param_type) {
1803 case SCTP_ERROR_CAUSE_IND:
1805 /* find the corresponding asconf param in our queue */
1806 ap = sctp_asconf_find_param(stcb, id);
1808 /* hmm... can't find this in our queue! */
1811 /* process the parameter, failed flag */
1812 sctp_asconf_process_param_ack(stcb, ap, 0);
1813 /* process the error response */
1814 sctp_asconf_process_error(stcb, aph);
1816 case SCTP_SUCCESS_REPORT:
1817 /* find the corresponding asconf param in our queue */
1818 ap = sctp_asconf_find_param(stcb, id);
1820 /* hmm... can't find this in our queue! */
1823 /* process the parameter, success flag */
1824 sctp_asconf_process_param_ack(stcb, ap, 1);
1830 /* update remaining ASCONF-ACK message length to process */
1831 if (ack_length > SCTP_SIZE32(param_length)) {
1832 ack_length -= SCTP_SIZE32(param_length);
1836 offset += SCTP_SIZE32(param_length);
1840 * if there are any "sent" params still on the queue, these are
1841 * implicitly "success", or "failed" (if we got an error back) ...
1842 * so process these appropriately
1844 * we assume that the correlation_id's are monotonically increasing
1845 * beginning from 1 and that we don't have *that* many outstanding
1848 if (last_error_id == 0)
1849 last_error_id--; /* set to "max" value */
1850 TAILQ_FOREACH_SAFE(aa, &stcb->asoc.asconf_queue, next, aa_next) {
1851 if (aa->sent == 1) {
1853 * implicitly successful or failed if correlation_id
1854 * < last_error_id, then success else, failure
1856 if (aa->ap.aph.correlation_id < last_error_id)
1857 sctp_asconf_process_param_ack(stcb, aa, 1);
1859 sctp_asconf_process_param_ack(stcb, aa, 0);
1862 * since we always process in order (FIFO queue) if
1863 * we reach one that hasn't been sent, the rest
1864 * should not have been sent either. so, we're
1871 /* update the next sequence number to use */
1872 asoc->asconf_seq_out_acked++;
1873 /* remove the old ASCONF on our outbound queue */
1874 sctp_toss_old_asconf(stcb);
1875 if (!TAILQ_EMPTY(&stcb->asoc.asconf_queue)) {
1876 #ifdef SCTP_TIMER_BASED_ASCONF
1877 /* we have more params, so restart our timer */
1878 sctp_timer_start(SCTP_TIMER_TYPE_ASCONF, stcb->sctp_ep,
1881 /* we have more params, so send out more */
1882 sctp_send_asconf(stcb, net, SCTP_ADDR_NOT_LOCKED);
1889 sctp_is_scopeid_in_nets(struct sctp_tcb *stcb, struct sockaddr *sa)
1891 struct sockaddr_in6 *sin6, *net6;
1892 struct sctp_nets *net;
1894 if (sa->sa_family != AF_INET6) {
1898 sin6 = (struct sockaddr_in6 *)sa;
1899 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) == 0) {
1900 /* not link local address */
1903 /* hunt through our destination nets list for this scope_id */
1904 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
1905 if (((struct sockaddr *)(&net->ro._l_addr))->sa_family !=
1908 net6 = (struct sockaddr_in6 *)&net->ro._l_addr;
1909 if (IN6_IS_ADDR_LINKLOCAL(&net6->sin6_addr) == 0)
1911 if (sctp_is_same_scope(sin6, net6)) {
1916 /* didn't find one */
1922 * address management functions
1925 sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
1926 struct sctp_ifa *ifa, uint16_t type, int addr_locked)
1930 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0 ||
1931 sctp_is_feature_off(inp, SCTP_PCB_FLAGS_DO_ASCONF)) {
1932 /* subset bound, no ASCONF allowed case, so ignore */
1936 * note: we know this is not the subset bound, no ASCONF case eg.
1937 * this is boundall or subset bound w/ASCONF allowed
1940 /* first, make sure that the address is IPv4 or IPv6 and not jailed */
1941 switch (ifa->address.sa.sa_family) {
1944 #if defined(__FreeBSD__) && !defined(__Userspace__)
1945 if (prison_check_ip6(inp->ip_inp.inp.inp_cred,
1946 &ifa->address.sin6.sin6_addr) != 0) {
1954 #if defined(__FreeBSD__) && !defined(__Userspace__)
1955 if (prison_check_ip4(inp->ip_inp.inp.inp_cred,
1956 &ifa->address.sin.sin_addr) != 0) {
1966 /* make sure we're "allowed" to add this type of addr */
1967 if (ifa->address.sa.sa_family == AF_INET6) {
1968 /* invalid if we're not a v6 endpoint */
1969 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0)
1971 /* is the v6 addr really valid ? */
1972 if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
1977 /* put this address on the "pending/do not use yet" list */
1978 sctp_add_local_addr_restricted(stcb, ifa);
1980 * check address scope if address is out of scope, don't queue
1981 * anything... note: this would leave the address on both inp and
1984 switch (ifa->address.sa.sa_family) {
1988 struct sockaddr_in6 *sin6;
1990 sin6 = &ifa->address.sin6;
1991 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
1992 /* we skip unspecifed addresses */
1995 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
1996 if (stcb->asoc.scope.local_scope == 0) {
1999 /* is it the right link local scope? */
2000 if (sctp_is_scopeid_in_nets(stcb, &ifa->address.sa) == 0) {
2004 if (stcb->asoc.scope.site_scope == 0 &&
2005 IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) {
2014 struct sockaddr_in *sin;
2016 /* invalid if we are a v6 only endpoint */
2017 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
2018 SCTP_IPV6_V6ONLY(inp))
2021 sin = &ifa->address.sin;
2022 if (sin->sin_addr.s_addr == 0) {
2023 /* we skip unspecifed addresses */
2026 if (stcb->asoc.scope.ipv4_local_scope == 0 &&
2027 IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
2034 /* else, not AF_INET or AF_INET6, so skip */
2038 /* queue an asconf for this address add/delete */
2039 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_DO_ASCONF)) {
2040 /* does the peer do asconf? */
2041 if (stcb->asoc.asconf_supported) {
2042 /* queue an asconf for this addr */
2043 status = sctp_asconf_queue_add(stcb, ifa, type);
2046 * if queued ok, and in the open state, send out the
2047 * ASCONF. If in the non-open state, these will be
2048 * sent when the state goes open.
2051 ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) ||
2052 (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED))) {
2053 #ifdef SCTP_TIMER_BASED_ASCONF
2054 sctp_timer_start(SCTP_TIMER_TYPE_ASCONF, inp,
2055 stcb, stcb->asoc.primary_destination);
2057 sctp_send_asconf(stcb, NULL, addr_locked);
2066 sctp_asconf_iterator_ep(struct sctp_inpcb *inp, void *ptr, uint32_t val SCTP_UNUSED)
2068 struct sctp_asconf_iterator *asc;
2069 struct sctp_ifa *ifa;
2070 struct sctp_laddr *l;
2071 int cnt_invalid = 0;
2073 asc = (struct sctp_asconf_iterator *)ptr;
2074 LIST_FOREACH(l, &asc->list_of_work, sctp_nxt_addr) {
2076 switch (ifa->address.sa.sa_family) {
2079 /* invalid if we're not a v6 endpoint */
2080 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
2082 if (asc->cnt == cnt_invalid)
2090 /* invalid if we are a v6 only endpoint */
2091 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
2092 SCTP_IPV6_V6ONLY(inp)) {
2094 if (asc->cnt == cnt_invalid)
2101 /* invalid address family */
2103 if (asc->cnt == cnt_invalid)
2111 sctp_asconf_iterator_ep_end(struct sctp_inpcb *inp, void *ptr, uint32_t val SCTP_UNUSED)
2113 struct sctp_ifa *ifa;
2114 struct sctp_asconf_iterator *asc;
2115 struct sctp_laddr *laddr, *nladdr, *l;
2117 /* Only for specific case not bound all */
2118 asc = (struct sctp_asconf_iterator *)ptr;
2119 LIST_FOREACH(l, &asc->list_of_work, sctp_nxt_addr) {
2121 if (l->action == SCTP_ADD_IP_ADDRESS) {
2122 LIST_FOREACH(laddr, &inp->sctp_addr_list,
2124 if (laddr->ifa == ifa) {
2130 } else if (l->action == SCTP_DEL_IP_ADDRESS) {
2131 LIST_FOREACH_SAFE(laddr, &inp->sctp_addr_list, sctp_nxt_addr, nladdr) {
2132 /* remove only after all guys are done */
2133 if (laddr->ifa == ifa) {
2134 sctp_del_local_addr_ep(inp, ifa);
2143 sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
2144 void *ptr, uint32_t val SCTP_UNUSED)
2146 struct sctp_asconf_iterator *asc;
2147 struct sctp_ifa *ifa;
2148 struct sctp_laddr *l;
2149 int cnt_invalid = 0;
2153 asc = (struct sctp_asconf_iterator *)ptr;
2154 LIST_FOREACH(l, &asc->list_of_work, sctp_nxt_addr) {
2158 /* address's vrf_id must be the vrf_id of the assoc */
2159 if (ifa->vrf_id != stcb->asoc.vrf_id) {
2163 /* Same checks again for assoc */
2164 switch (ifa->address.sa.sa_family) {
2168 /* invalid if we're not a v6 endpoint */
2169 struct sockaddr_in6 *sin6;
2171 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
2173 if (asc->cnt == cnt_invalid)
2178 sin6 = &ifa->address.sin6;
2179 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
2180 /* we skip unspecifed addresses */
2183 #if defined(__FreeBSD__) && !defined(__Userspace__)
2184 if (prison_check_ip6(inp->ip_inp.inp.inp_cred,
2185 &sin6->sin6_addr) != 0) {
2189 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
2190 if (stcb->asoc.scope.local_scope == 0) {
2193 /* is it the right link local scope? */
2194 if (sctp_is_scopeid_in_nets(stcb, &ifa->address.sa) == 0) {
2204 /* invalid if we are a v6 only endpoint */
2205 struct sockaddr_in *sin;
2207 /* invalid if we are a v6 only endpoint */
2208 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
2209 SCTP_IPV6_V6ONLY(inp))
2212 sin = &ifa->address.sin;
2213 if (sin->sin_addr.s_addr == 0) {
2214 /* we skip unspecifed addresses */
2217 #if defined(__FreeBSD__) && !defined(__Userspace__)
2218 if (prison_check_ip4(inp->ip_inp.inp.inp_cred,
2219 &sin->sin_addr) != 0) {
2223 if (stcb->asoc.scope.ipv4_local_scope == 0 &&
2224 IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
2227 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
2228 SCTP_IPV6_V6ONLY(inp)) {
2230 if (asc->cnt == cnt_invalid)
2239 /* invalid address family */
2241 if (asc->cnt == cnt_invalid)
2248 if (type == SCTP_ADD_IP_ADDRESS) {
2249 /* prevent this address from being used as a source */
2250 sctp_add_local_addr_restricted(stcb, ifa);
2251 } else if (type == SCTP_DEL_IP_ADDRESS) {
2252 struct sctp_nets *net;
2253 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
2254 /* delete this address if cached */
2255 if (net->ro._s_addr == ifa) {
2256 sctp_free_ifa(net->ro._s_addr);
2257 net->ro._s_addr = NULL;
2258 net->src_addr_selected = 0;
2259 #if defined(__FreeBSD__) && !defined(__Userspace__)
2260 RO_NHFREE(&net->ro);
2262 if (net->ro.ro_rt) {
2263 RTFREE(net->ro.ro_rt);
2264 net->ro.ro_rt = NULL;
2268 * Now we deleted our src address,
2269 * should we not also now reset the
2270 * cwnd/rto to start as if its a new
2273 stcb->asoc.cc_functions.sctp_set_initial_cc_param(stcb, net);
2278 } else if (type == SCTP_SET_PRIM_ADDR) {
2279 if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) {
2280 /* must validate the ifa is in the ep */
2281 if (sctp_is_addr_in_ep(stcb->sctp_ep, ifa) == 0) {
2285 /* Need to check scopes for this guy */
2286 if (sctp_is_address_in_scope(ifa, &stcb->asoc.scope, 0) == 0) {
2291 /* queue an asconf for this address add/delete */
2292 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_DO_ASCONF) &&
2293 stcb->asoc.asconf_supported == 1) {
2294 /* queue an asconf for this addr */
2295 status = sctp_asconf_queue_add(stcb, ifa, type);
2297 * if queued ok, and in the open state, update the
2298 * count of queued params. If in the non-open state,
2299 * these get sent when the assoc goes open.
2301 if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) ||
2302 (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
2310 * If we have queued params in the open state, send out an ASCONF.
2312 if (num_queued > 0) {
2313 sctp_send_asconf(stcb, NULL, SCTP_ADDR_NOT_LOCKED);
2318 sctp_asconf_iterator_end(void *ptr, uint32_t val SCTP_UNUSED)
2320 struct sctp_asconf_iterator *asc;
2321 struct sctp_ifa *ifa;
2322 struct sctp_laddr *l, *nl;
2324 asc = (struct sctp_asconf_iterator *)ptr;
2325 LIST_FOREACH_SAFE(l, &asc->list_of_work, sctp_nxt_addr, nl) {
2327 if (l->action == SCTP_ADD_IP_ADDRESS) {
2328 /* Clear the defer use flag */
2329 ifa->localifa_flags &= ~SCTP_ADDR_DEFER_USE;
2332 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_laddr), l);
2333 SCTP_DECR_LADDR_COUNT();
2335 SCTP_FREE(asc, SCTP_M_ASC_IT);
2339 * sa is the sockaddr to ask the peer to set primary to.
2340 * returns: 0 = completed, -1 = error
2343 sctp_set_primary_ip_address_sa(struct sctp_tcb *stcb, struct sockaddr *sa)
2346 struct sctp_ifa *ifa;
2348 /* find the ifa for the desired set primary */
2349 vrf_id = stcb->asoc.vrf_id;
2350 ifa = sctp_find_ifa_by_addr(sa, vrf_id, SCTP_ADDR_NOT_LOCKED);
2352 /* Invalid address */
2356 /* queue an ASCONF:SET_PRIM_ADDR to be sent */
2357 if (!sctp_asconf_queue_add(stcb, ifa, SCTP_SET_PRIM_ADDR)) {
2358 /* set primary queuing succeeded */
2359 SCTPDBG(SCTP_DEBUG_ASCONF1,
2360 "set_primary_ip_address_sa: queued on tcb=%p, ",
2362 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
2363 if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) ||
2364 (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
2365 #ifdef SCTP_TIMER_BASED_ASCONF
2366 sctp_timer_start(SCTP_TIMER_TYPE_ASCONF,
2367 stcb->sctp_ep, stcb,
2368 stcb->asoc.primary_destination);
2370 sctp_send_asconf(stcb, NULL, SCTP_ADDR_NOT_LOCKED);
2374 SCTPDBG(SCTP_DEBUG_ASCONF1, "set_primary_ip_address_sa: failed to add to queue on tcb=%p, ",
2376 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
2383 sctp_is_addr_pending(struct sctp_tcb *stcb, struct sctp_ifa *sctp_ifa)
2385 struct sctp_tmit_chunk *chk, *nchk;
2386 unsigned int offset, asconf_limit;
2387 struct sctp_asconf_chunk *acp;
2388 struct sctp_asconf_paramhdr *aph;
2389 uint8_t aparam_buf[SCTP_PARAM_BUFFER_SIZE];
2390 struct sctp_paramhdr *ph;
2391 int add_cnt, del_cnt;
2392 uint16_t last_param_type;
2394 add_cnt = del_cnt = 0;
2395 last_param_type = 0;
2396 TAILQ_FOREACH_SAFE(chk, &stcb->asoc.asconf_send_queue, sctp_next, nchk) {
2397 if (chk->data == NULL) {
2398 SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: No mbuf data?\n");
2402 acp = mtod(chk->data, struct sctp_asconf_chunk *);
2403 offset += sizeof(struct sctp_asconf_chunk);
2404 asconf_limit = ntohs(acp->ch.chunk_length);
2405 ph = (struct sctp_paramhdr *)sctp_m_getptr(chk->data, offset, sizeof(struct sctp_paramhdr), aparam_buf);
2407 SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: couldn't get lookup addr!\n");
2410 offset += ntohs(ph->param_length);
2412 aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(chk->data, offset, sizeof(struct sctp_asconf_paramhdr), aparam_buf);
2414 SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: Empty ASCONF will be sent?\n");
2417 while (aph != NULL) {
2418 unsigned int param_length, param_type;
2420 param_type = ntohs(aph->ph.param_type);
2421 param_length = ntohs(aph->ph.param_length);
2422 if (offset + param_length > asconf_limit) {
2423 /* parameter goes beyond end of chunk! */
2426 if (param_length > sizeof(aparam_buf)) {
2427 SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: param length (%u) larger than buffer size!\n", param_length);
2430 if (param_length <= sizeof(struct sctp_paramhdr)) {
2431 SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: param length(%u) too short\n", param_length);
2435 aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(chk->data, offset, param_length, aparam_buf);
2437 SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: couldn't get entire param\n");
2441 ph = (struct sctp_paramhdr *)(aph + 1);
2442 if (sctp_addr_match(ph, &sctp_ifa->address.sa) != 0) {
2443 switch (param_type) {
2444 case SCTP_ADD_IP_ADDRESS:
2447 case SCTP_DEL_IP_ADDRESS:
2453 last_param_type = param_type;
2456 offset += SCTP_SIZE32(param_length);
2457 if (offset >= asconf_limit) {
2458 /* no more data in the mbuf chain */
2461 /* get pointer to next asconf param */
2462 aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(chk->data, offset, sizeof(struct sctp_asconf_paramhdr), aparam_buf);
2466 /* we want to find the sequences which consist of ADD -> DEL -> ADD or DEL -> ADD */
2467 if (add_cnt > del_cnt ||
2468 (add_cnt == del_cnt && last_param_type == SCTP_ADD_IP_ADDRESS)) {
2474 static struct sockaddr *
2475 sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked)
2477 struct sctp_vrf *vrf = NULL;
2478 struct sctp_ifn *sctp_ifn;
2479 struct sctp_ifa *sctp_ifa;
2481 if (addr_locked == SCTP_ADDR_NOT_LOCKED)
2482 SCTP_IPI_ADDR_RLOCK();
2483 vrf = sctp_find_vrf(stcb->asoc.vrf_id);
2485 if (addr_locked == SCTP_ADDR_NOT_LOCKED)
2486 SCTP_IPI_ADDR_RUNLOCK();
2489 LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
2490 if (stcb->asoc.scope.loopback_scope == 0 &&
2491 SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) {
2492 /* Skip if loopback_scope not set */
2495 LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
2496 switch (sctp_ifa->address.sa.sa_family) {
2499 if (stcb->asoc.scope.ipv4_addr_legal) {
2500 struct sockaddr_in *sin;
2502 sin = &sctp_ifa->address.sin;
2503 if (sin->sin_addr.s_addr == 0) {
2504 /* skip unspecifed addresses */
2507 #if defined(__FreeBSD__) && !defined(__Userspace__)
2508 if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred,
2509 &sin->sin_addr) != 0) {
2513 if (stcb->asoc.scope.ipv4_local_scope == 0 &&
2514 IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))
2517 if (sctp_is_addr_restricted(stcb, sctp_ifa) &&
2518 (!sctp_is_addr_pending(stcb, sctp_ifa)))
2520 /* found a valid local v4 address to use */
2521 if (addr_locked == SCTP_ADDR_NOT_LOCKED)
2522 SCTP_IPI_ADDR_RUNLOCK();
2523 return (&sctp_ifa->address.sa);
2529 if (stcb->asoc.scope.ipv6_addr_legal) {
2530 struct sockaddr_in6 *sin6;
2532 if (sctp_ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
2536 sin6 = &sctp_ifa->address.sin6;
2537 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
2538 /* we skip unspecifed addresses */
2541 #if defined(__FreeBSD__) && !defined(__Userspace__)
2542 if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred,
2543 &sin6->sin6_addr) != 0) {
2547 if (stcb->asoc.scope.local_scope == 0 &&
2548 IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
2550 if (stcb->asoc.scope.site_scope == 0 &&
2551 IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))
2554 if (sctp_is_addr_restricted(stcb, sctp_ifa) &&
2555 (!sctp_is_addr_pending(stcb, sctp_ifa)))
2557 /* found a valid local v6 address to use */
2558 if (addr_locked == SCTP_ADDR_NOT_LOCKED)
2559 SCTP_IPI_ADDR_RUNLOCK();
2560 return (&sctp_ifa->address.sa);
2569 /* no valid addresses found */
2570 if (addr_locked == SCTP_ADDR_NOT_LOCKED)
2571 SCTP_IPI_ADDR_RUNLOCK();
2575 static struct sockaddr *
2576 sctp_find_valid_localaddr_ep(struct sctp_tcb *stcb)
2578 struct sctp_laddr *laddr;
2580 LIST_FOREACH(laddr, &stcb->sctp_ep->sctp_addr_list, sctp_nxt_addr) {
2581 if (laddr->ifa == NULL) {
2584 /* is the address restricted ? */
2585 if (sctp_is_addr_restricted(stcb, laddr->ifa) &&
2586 (!sctp_is_addr_pending(stcb, laddr->ifa)))
2589 /* found a valid local address to use */
2590 return (&laddr->ifa->address.sa);
2592 /* no valid addresses found */
2597 * builds an ASCONF chunk from queued ASCONF params.
2598 * returns NULL on error (no mbuf, no ASCONF params queued, etc).
2601 sctp_compose_asconf(struct sctp_tcb *stcb, int *retlen, int addr_locked)
2603 struct mbuf *m_asconf, *m_asconf_chk;
2604 struct sctp_asconf_addr *aa;
2605 struct sctp_asconf_chunk *acp;
2606 struct sctp_asconf_paramhdr *aph;
2607 struct sctp_asconf_addr_param *aap;
2609 uint32_t correlation_id = 1; /* 0 is reserved... */
2610 caddr_t ptr, lookup_ptr;
2611 uint8_t lookup_used = 0;
2613 /* are there any asconf params to send? */
2614 TAILQ_FOREACH(aa, &stcb->asoc.asconf_queue, next) {
2622 * get a chunk header mbuf and a cluster for the asconf params since
2623 * it's simpler to fill in the asconf chunk header lookup address on
2626 m_asconf_chk = sctp_get_mbuf_for_msg(sizeof(struct sctp_asconf_chunk), 0, M_NOWAIT, 1, MT_DATA);
2627 if (m_asconf_chk == NULL) {
2629 SCTPDBG(SCTP_DEBUG_ASCONF1,
2630 "sctp_compose_asconf: couldn't get chunk mbuf!\n");
2633 m_asconf = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_NOWAIT, 1, MT_DATA);
2634 if (m_asconf == NULL) {
2636 SCTPDBG(SCTP_DEBUG_ASCONF1,
2637 "sctp_compose_asconf: couldn't get mbuf!\n");
2638 sctp_m_freem(m_asconf_chk);
2641 SCTP_BUF_LEN(m_asconf_chk) = sizeof(struct sctp_asconf_chunk);
2642 SCTP_BUF_LEN(m_asconf) = 0;
2643 acp = mtod(m_asconf_chk, struct sctp_asconf_chunk *);
2644 memset(acp, 0, sizeof(struct sctp_asconf_chunk));
2645 /* save pointers to lookup address and asconf params */
2646 lookup_ptr = (caddr_t)(acp + 1); /* after the header */
2647 ptr = mtod(m_asconf, caddr_t); /* beginning of cluster */
2649 /* fill in chunk header info */
2650 acp->ch.chunk_type = SCTP_ASCONF;
2651 acp->ch.chunk_flags = 0;
2652 acp->serial_number = htonl(stcb->asoc.asconf_seq_out);
2653 stcb->asoc.asconf_seq_out++;
2655 /* add parameters... up to smallest MTU allowed */
2656 TAILQ_FOREACH(aa, &stcb->asoc.asconf_queue, next) {
2659 /* get the parameter length */
2660 p_length = SCTP_SIZE32(aa->ap.aph.ph.param_length);
2661 /* will it fit in current chunk? */
2662 if ((SCTP_BUF_LEN(m_asconf) + p_length > stcb->asoc.smallest_mtu) ||
2663 (SCTP_BUF_LEN(m_asconf) + p_length > MCLBYTES)) {
2664 /* won't fit, so we're done with this chunk */
2667 /* assign (and store) a correlation id */
2668 aa->ap.aph.correlation_id = correlation_id++;
2671 * fill in address if we're doing a delete this is a simple
2672 * way for us to fill in the correlation address, which
2673 * should only be used by the peer if we're deleting our
2674 * source address and adding a new address (e.g. renumbering
2677 if (lookup_used == 0 &&
2678 (aa->special_del == 0) &&
2679 aa->ap.aph.ph.param_type == SCTP_DEL_IP_ADDRESS) {
2680 struct sctp_ipv6addr_param *lookup;
2681 uint16_t p_size, addr_size;
2683 lookup = (struct sctp_ipv6addr_param *)lookup_ptr;
2684 lookup->ph.param_type =
2685 htons(aa->ap.addrp.ph.param_type);
2686 if (aa->ap.addrp.ph.param_type == SCTP_IPV6_ADDRESS) {
2687 /* copy IPv6 address */
2688 p_size = sizeof(struct sctp_ipv6addr_param);
2689 addr_size = sizeof(struct in6_addr);
2691 /* copy IPv4 address */
2692 p_size = sizeof(struct sctp_ipv4addr_param);
2693 addr_size = sizeof(struct in_addr);
2695 lookup->ph.param_length = htons(SCTP_SIZE32(p_size));
2696 memcpy(lookup->addr, &aa->ap.addrp.addr, addr_size);
2697 SCTP_BUF_LEN(m_asconf_chk) += SCTP_SIZE32(p_size);
2700 /* copy into current space */
2701 memcpy(ptr, &aa->ap, p_length);
2703 /* network elements and update lengths */
2704 aph = (struct sctp_asconf_paramhdr *)ptr;
2705 aap = (struct sctp_asconf_addr_param *)ptr;
2706 /* correlation_id is transparent to peer, no htonl needed */
2707 aph->ph.param_type = htons(aph->ph.param_type);
2708 aph->ph.param_length = htons(aph->ph.param_length);
2709 aap->addrp.ph.param_type = htons(aap->addrp.ph.param_type);
2710 aap->addrp.ph.param_length = htons(aap->addrp.ph.param_length);
2712 SCTP_BUF_LEN(m_asconf) += SCTP_SIZE32(p_length);
2713 ptr += SCTP_SIZE32(p_length);
2716 * these params are removed off the pending list upon
2717 * getting an ASCONF-ACK back from the peer, just set flag
2721 /* check to see if the lookup addr has been populated yet */
2722 if (lookup_used == 0) {
2723 /* NOTE: if the address param is optional, can skip this... */
2724 /* add any valid (existing) address... */
2725 struct sctp_ipv6addr_param *lookup;
2726 uint16_t p_size, addr_size;
2727 struct sockaddr *found_addr;
2730 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL)
2731 found_addr = sctp_find_valid_localaddr(stcb,
2734 found_addr = sctp_find_valid_localaddr_ep(stcb);
2736 lookup = (struct sctp_ipv6addr_param *)lookup_ptr;
2737 if (found_addr != NULL) {
2738 switch (found_addr->sa_family) {
2741 /* copy IPv6 address */
2742 lookup->ph.param_type =
2743 htons(SCTP_IPV6_ADDRESS);
2744 p_size = sizeof(struct sctp_ipv6addr_param);
2745 addr_size = sizeof(struct in6_addr);
2746 addr_ptr = (caddr_t)&((struct sockaddr_in6 *)
2747 found_addr)->sin6_addr;
2752 /* copy IPv4 address */
2753 lookup->ph.param_type =
2754 htons(SCTP_IPV4_ADDRESS);
2755 p_size = sizeof(struct sctp_ipv4addr_param);
2756 addr_size = sizeof(struct in_addr);
2757 addr_ptr = (caddr_t)&((struct sockaddr_in *)
2758 found_addr)->sin_addr;
2762 SCTPDBG(SCTP_DEBUG_ASCONF1,
2763 "sctp_compose_asconf: no usable lookup addr (family = %d)!\n",
2764 found_addr->sa_family);
2765 sctp_m_freem(m_asconf_chk);
2766 sctp_m_freem(m_asconf);
2769 lookup->ph.param_length = htons(SCTP_SIZE32(p_size));
2770 memcpy(lookup->addr, addr_ptr, addr_size);
2771 SCTP_BUF_LEN(m_asconf_chk) += SCTP_SIZE32(p_size);
2773 /* uh oh... don't have any address?? */
2774 SCTPDBG(SCTP_DEBUG_ASCONF1,
2775 "sctp_compose_asconf: no lookup addr!\n");
2776 sctp_m_freem(m_asconf_chk);
2777 sctp_m_freem(m_asconf);
2781 /* chain it all together */
2782 SCTP_BUF_NEXT(m_asconf_chk) = m_asconf;
2783 *retlen = SCTP_BUF_LEN(m_asconf_chk) + SCTP_BUF_LEN(m_asconf);
2784 acp->ch.chunk_length = htons(*retlen);
2786 return (m_asconf_chk);
2790 * section to handle address changes before an association is up eg. changes
2791 * during INIT/INIT-ACK/COOKIE-ECHO handshake
2795 * processes the (local) addresses in the INIT-ACK chunk
2798 sctp_process_initack_addresses(struct sctp_tcb *stcb, struct mbuf *m,
2799 unsigned int offset, unsigned int length)
2801 struct sctp_paramhdr tmp_param, *ph;
2802 uint16_t plen, ptype;
2803 struct sctp_ifa *sctp_ifa;
2804 union sctp_sockstore store;
2806 struct sctp_ipv6addr_param addr6_store;
2809 struct sctp_ipv4addr_param addr4_store;
2812 SCTPDBG(SCTP_DEBUG_ASCONF2, "processing init-ack addresses\n");
2813 if (stcb == NULL) /* Un-needed check for SA */
2816 /* convert to upper bound */
2819 if ((offset + sizeof(struct sctp_paramhdr)) > length) {
2822 /* go through the addresses in the init-ack */
2823 ph = (struct sctp_paramhdr *)
2824 sctp_m_getptr(m, offset, sizeof(struct sctp_paramhdr),
2825 (uint8_t *)&tmp_param);
2826 while (ph != NULL) {
2827 ptype = ntohs(ph->param_type);
2828 plen = ntohs(ph->param_length);
2831 case SCTP_IPV6_ADDRESS:
2833 struct sctp_ipv6addr_param *a6p;
2835 /* get the entire IPv6 address param */
2836 a6p = (struct sctp_ipv6addr_param *)
2837 sctp_m_getptr(m, offset,
2838 sizeof(struct sctp_ipv6addr_param),
2839 (uint8_t *)&addr6_store);
2840 if (plen != sizeof(struct sctp_ipv6addr_param) ||
2844 memset(&store, 0, sizeof(union sctp_sockstore));
2845 store.sin6.sin6_family = AF_INET6;
2846 #ifdef HAVE_SIN6_LEN
2847 store.sin6.sin6_len = sizeof(struct sockaddr_in6);
2849 store.sin6.sin6_port = stcb->rport;
2850 memcpy(&store.sin6.sin6_addr, a6p->addr, sizeof(struct in6_addr));
2855 case SCTP_IPV4_ADDRESS:
2857 struct sctp_ipv4addr_param *a4p;
2859 /* get the entire IPv4 address param */
2860 a4p = (struct sctp_ipv4addr_param *)sctp_m_getptr(m, offset,
2861 sizeof(struct sctp_ipv4addr_param),
2862 (uint8_t *)&addr4_store);
2863 if (plen != sizeof(struct sctp_ipv4addr_param) ||
2867 memset(&store, 0, sizeof(union sctp_sockstore));
2868 store.sin.sin_family = AF_INET;
2870 store.sin.sin_len = sizeof(struct sockaddr_in);
2872 store.sin.sin_port = stcb->rport;
2873 store.sin.sin_addr.s_addr = a4p->addr;
2881 /* see if this address really (still) exists */
2882 sctp_ifa = sctp_find_ifa_by_addr(&store.sa, stcb->asoc.vrf_id,
2883 SCTP_ADDR_NOT_LOCKED);
2884 if (sctp_ifa == NULL) {
2885 /* address doesn't exist anymore */
2888 /* are ASCONFs allowed ? */
2889 if ((sctp_is_feature_on(stcb->sctp_ep,
2890 SCTP_PCB_FLAGS_DO_ASCONF)) &&
2891 stcb->asoc.asconf_supported) {
2892 /* queue an ASCONF DEL_IP_ADDRESS */
2893 status = sctp_asconf_queue_sa_delete(stcb, &store.sa);
2895 * if queued ok, and in correct state, send
2899 SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) {
2900 #ifdef SCTP_TIMER_BASED_ASCONF
2901 sctp_timer_start(SCTP_TIMER_TYPE_ASCONF,
2902 stcb->sctp_ep, stcb,
2903 stcb->asoc.primary_destination);
2905 sctp_send_asconf(stcb, NULL, SCTP_ADDR_NOT_LOCKED);
2913 * Sanity check: Make sure the length isn't 0, otherwise
2914 * we'll be stuck in this loop for a long time...
2916 if (SCTP_SIZE32(plen) == 0) {
2917 SCTP_PRINTF("process_initack_addrs: bad len (%d) type=%xh\n",
2921 /* get next parameter */
2922 offset += SCTP_SIZE32(plen);
2923 if ((offset + sizeof(struct sctp_paramhdr)) > length)
2925 ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset,
2926 sizeof(struct sctp_paramhdr), (uint8_t *)&tmp_param);
2930 /* FIX ME: need to verify return result for v6 address type if v6 disabled */
2932 * checks to see if a specific address is in the initack address list returns
2933 * 1 if found, 0 if not
2936 sctp_addr_in_initack(struct mbuf *m, uint32_t offset, uint32_t length, struct sockaddr *sa)
2938 struct sctp_paramhdr tmp_param, *ph;
2939 uint16_t plen, ptype;
2941 struct sockaddr_in *sin;
2942 struct sctp_ipv4addr_param *a4p;
2943 struct sctp_ipv6addr_param addr4_store;
2946 struct sockaddr_in6 *sin6;
2947 struct sctp_ipv6addr_param *a6p;
2948 struct sctp_ipv6addr_param addr6_store;
2949 #ifdef SCTP_EMBEDDED_V6_SCOPE
2950 struct sockaddr_in6 sin6_tmp;
2954 switch (sa->sa_family) {
2967 SCTPDBG(SCTP_DEBUG_ASCONF2, "find_initack_addr: starting search for ");
2968 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, sa);
2969 /* convert to upper bound */
2972 if ((offset + sizeof(struct sctp_paramhdr)) > length) {
2973 SCTPDBG(SCTP_DEBUG_ASCONF1,
2974 "find_initack_addr: invalid offset?\n");
2977 /* go through the addresses in the init-ack */
2978 ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset,
2979 sizeof(struct sctp_paramhdr), (uint8_t *) & tmp_param);
2980 while (ph != NULL) {
2981 ptype = ntohs(ph->param_type);
2982 plen = ntohs(ph->param_length);
2985 case SCTP_IPV6_ADDRESS:
2986 if (sa->sa_family == AF_INET6) {
2987 /* get the entire IPv6 address param */
2988 if (plen != sizeof(struct sctp_ipv6addr_param)) {
2991 /* get the entire IPv6 address param */
2992 a6p = (struct sctp_ipv6addr_param *)
2993 sctp_m_getptr(m, offset,
2994 sizeof(struct sctp_ipv6addr_param),
2995 (uint8_t *)&addr6_store);
2999 sin6 = (struct sockaddr_in6 *)sa;
3000 #ifdef SCTP_EMBEDDED_V6_SCOPE
3001 if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr)) {
3002 /* create a copy and clear scope */
3003 memcpy(&sin6_tmp, sin6,
3004 sizeof(struct sockaddr_in6));
3006 in6_clearscope(&sin6->sin6_addr);
3008 #endif /* SCTP_EMBEDDED_V6_SCOPE */
3009 if (memcmp(&sin6->sin6_addr, a6p->addr,
3010 sizeof(struct in6_addr)) == 0) {
3018 case SCTP_IPV4_ADDRESS:
3019 if (sa->sa_family == AF_INET) {
3020 if (plen != sizeof(struct sctp_ipv4addr_param)) {
3023 /* get the entire IPv4 address param */
3024 a4p = (struct sctp_ipv4addr_param *)
3025 sctp_m_getptr(m, offset,
3026 sizeof(struct sctp_ipv4addr_param),
3027 (uint8_t *)&addr4_store);
3031 sin = (struct sockaddr_in *)sa;
3032 if (sin->sin_addr.s_addr == a4p->addr) {
3042 /* get next parameter */
3043 offset += SCTP_SIZE32(plen);
3044 if (offset + sizeof(struct sctp_paramhdr) > length) {
3047 ph = (struct sctp_paramhdr *)
3048 sctp_m_getptr(m, offset, sizeof(struct sctp_paramhdr),
3049 (uint8_t *) & tmp_param);
3056 * makes sure that the current endpoint local addr list is consistent with
3057 * the new association (eg. subset bound, asconf allowed) adds addresses as
3061 sctp_check_address_list_ep(struct sctp_tcb *stcb, struct mbuf *m, int offset,
3062 int length, struct sockaddr *init_addr)
3064 struct sctp_laddr *laddr;
3066 /* go through the endpoint list */
3067 LIST_FOREACH(laddr, &stcb->sctp_ep->sctp_addr_list, sctp_nxt_addr) {
3068 /* be paranoid and validate the laddr */
3069 if (laddr->ifa == NULL) {
3070 SCTPDBG(SCTP_DEBUG_ASCONF1,
3071 "check_addr_list_ep: laddr->ifa is NULL");
3074 /* do i have it implicitly? */
3075 if (sctp_cmpaddr(&laddr->ifa->address.sa, init_addr)) {
3078 /* check to see if in the init-ack */
3079 if (!sctp_addr_in_initack(m, offset, length, &laddr->ifa->address.sa)) {
3081 sctp_addr_mgmt_assoc(stcb->sctp_ep, stcb, laddr->ifa,
3082 SCTP_ADD_IP_ADDRESS, SCTP_ADDR_NOT_LOCKED);
3088 * makes sure that the current kernel address list is consistent with the new
3089 * association (with all addrs bound) adds addresses as necessary
3092 sctp_check_address_list_all(struct sctp_tcb *stcb, struct mbuf *m, int offset,
3093 int length, struct sockaddr *init_addr,
3094 uint16_t local_scope, uint16_t site_scope,
3095 uint16_t ipv4_scope, uint16_t loopback_scope)
3097 struct sctp_vrf *vrf = NULL;
3098 struct sctp_ifn *sctp_ifn;
3099 struct sctp_ifa *sctp_ifa;
3102 struct sockaddr_in *sin;
3105 struct sockaddr_in6 *sin6;
3109 vrf_id = stcb->asoc.vrf_id;
3113 SCTP_IPI_ADDR_RLOCK();
3114 vrf = sctp_find_vrf(vrf_id);
3116 SCTP_IPI_ADDR_RUNLOCK();
3119 /* go through all our known interfaces */
3120 LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
3121 if (loopback_scope == 0 && SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) {
3122 /* skip loopback interface */
3125 /* go through each interface address */
3126 LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
3127 /* do i have it implicitly? */
3128 if (sctp_cmpaddr(&sctp_ifa->address.sa, init_addr)) {
3131 switch (sctp_ifa->address.sa.sa_family) {
3134 sin = &sctp_ifa->address.sin;
3135 #if defined(__FreeBSD__) && !defined(__Userspace__)
3136 if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred,
3137 &sin->sin_addr) != 0) {
3141 if ((ipv4_scope == 0) &&
3142 (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
3143 /* private address not in scope */
3150 sin6 = &sctp_ifa->address.sin6;
3151 #if defined(__FreeBSD__) && !defined(__Userspace__)
3152 if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred,
3153 &sin6->sin6_addr) != 0) {
3157 if ((local_scope == 0) &&
3158 (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))) {
3161 if ((site_scope == 0) &&
3162 (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) {
3170 /* check to see if in the init-ack */
3171 if (!sctp_addr_in_initack(m, offset, length, &sctp_ifa->address.sa)) {
3173 sctp_addr_mgmt_assoc(stcb->sctp_ep, stcb,
3174 sctp_ifa, SCTP_ADD_IP_ADDRESS,
3177 } /* end foreach ifa */
3178 } /* end foreach ifn */
3179 SCTP_IPI_ADDR_RUNLOCK();
3183 * validates an init-ack chunk (from a cookie-echo) with current addresses
3184 * adds addresses from the init-ack into our local address list, if needed
3185 * queues asconf adds/deletes addresses as needed and makes appropriate list
3186 * changes for source address selection m, offset: points to the start of the
3187 * address list in an init-ack chunk length: total length of the address
3188 * params only init_addr: address where my INIT-ACK was sent from
3191 sctp_check_address_list(struct sctp_tcb *stcb, struct mbuf *m, int offset,
3192 int length, struct sockaddr *init_addr,
3193 uint16_t local_scope, uint16_t site_scope,
3194 uint16_t ipv4_scope, uint16_t loopback_scope)
3196 /* process the local addresses in the initack */
3197 sctp_process_initack_addresses(stcb, m, offset, length);
3199 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
3200 /* bound all case */
3201 sctp_check_address_list_all(stcb, m, offset, length, init_addr,
3202 local_scope, site_scope, ipv4_scope, loopback_scope);
3204 /* subset bound case */
3205 if (sctp_is_feature_on(stcb->sctp_ep,
3206 SCTP_PCB_FLAGS_DO_ASCONF)) {
3207 /* asconf's allowed */
3208 sctp_check_address_list_ep(stcb, m, offset, length,
3211 /* else, no asconfs allowed, so what we sent is what we get */
3216 * sctp_bindx() support
3219 sctp_addr_mgmt_ep_sa(struct sctp_inpcb *inp, struct sockaddr *sa,
3220 uint32_t type, uint32_t vrf_id)
3222 struct sctp_ifa *ifa;
3223 struct sctp_laddr *laddr, *nladdr;
3226 if (sa->sa_len == 0) {
3227 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, EINVAL);
3231 if (type == SCTP_ADD_IP_ADDRESS) {
3232 /* For an add the address MUST be on the system */
3233 ifa = sctp_find_ifa_by_addr(sa, vrf_id, SCTP_ADDR_NOT_LOCKED);
3234 } else if (type == SCTP_DEL_IP_ADDRESS) {
3235 /* For a delete we need to find it in the inp */
3236 ifa = sctp_find_ifa_in_ep(inp, sa, SCTP_ADDR_NOT_LOCKED);
3241 if (type == SCTP_ADD_IP_ADDRESS) {
3242 sctp_add_local_addr_ep(inp, ifa, type);
3243 } else if (type == SCTP_DEL_IP_ADDRESS) {
3244 if (inp->laddr_count < 2) {
3245 /* can't delete the last local address */
3246 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, EINVAL);
3249 LIST_FOREACH(laddr, &inp->sctp_addr_list,
3251 if (ifa == laddr->ifa) {
3252 /* Mark in the delete */
3253 laddr->action = type;
3257 if (LIST_EMPTY(&inp->sctp_asoc_list)) {
3259 * There is no need to start the iterator if
3260 * the inp has no associations.
3262 if (type == SCTP_DEL_IP_ADDRESS) {
3263 LIST_FOREACH_SAFE(laddr, &inp->sctp_addr_list, sctp_nxt_addr, nladdr) {
3264 if (laddr->ifa == ifa) {
3265 sctp_del_local_addr_ep(inp, ifa);
3270 struct sctp_asconf_iterator *asc;
3271 struct sctp_laddr *wi;
3274 SCTP_MALLOC(asc, struct sctp_asconf_iterator *,
3275 sizeof(struct sctp_asconf_iterator),
3278 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, ENOMEM);
3281 wi = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_laddr), struct sctp_laddr);
3283 SCTP_FREE(asc, SCTP_M_ASC_IT);
3284 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, ENOMEM);
3287 LIST_INIT(&asc->list_of_work);
3289 SCTP_INCR_LADDR_COUNT();
3292 atomic_add_int(&ifa->refcount, 1);
3293 LIST_INSERT_HEAD(&asc->list_of_work, wi, sctp_nxt_addr);
3294 ret = sctp_initiate_iterator(sctp_asconf_iterator_ep,
3295 sctp_asconf_iterator_stcb,
3296 sctp_asconf_iterator_ep_end,
3298 SCTP_PCB_ANY_FEATURES,
3299 SCTP_ASOC_ANY_STATE,
3301 sctp_asconf_iterator_end, inp, 0);
3303 SCTP_PRINTF("Failed to initiate iterator for addr_mgmt_ep_sa\n");
3304 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, EFAULT);
3305 sctp_asconf_iterator_end(asc, 0);
3311 /* invalid address! */
3312 SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_ASCONF, EADDRNOTAVAIL);
3313 return (EADDRNOTAVAIL);
3318 sctp_asconf_send_nat_state_update(struct sctp_tcb *stcb, struct sctp_nets *net)
3320 struct sctp_asconf_addr *aa_vtag, *aa_add, *aa_del;
3321 struct sctp_ifa *sctp_ifap;
3322 struct sctp_asconf_tag_param *vtag;
3324 struct sockaddr_in *to;
3327 struct sockaddr_in6 *to6;
3331 SCTPDBG(SCTP_DEBUG_ASCONF1, "sctp_asconf_send_nat_state_update: Missing net\n");
3335 SCTPDBG(SCTP_DEBUG_ASCONF1, "sctp_asconf_send_nat_state_update: Missing stcb\n");
3338 /* Need to have in the ASCONF:
3339 * - VTAG(my_vtag/peer_vtag)
3342 * - ADD(Any global addresses)
3344 SCTP_MALLOC(aa_vtag, struct sctp_asconf_addr *, sizeof(struct sctp_asconf_addr), SCTP_M_ASC_ADDR);
3345 SCTP_MALLOC(aa_add, struct sctp_asconf_addr *, sizeof(struct sctp_asconf_addr), SCTP_M_ASC_ADDR);
3346 SCTP_MALLOC(aa_del, struct sctp_asconf_addr *, sizeof(struct sctp_asconf_addr), SCTP_M_ASC_ADDR);
3348 if ((aa_vtag == NULL) || (aa_add == NULL) || (aa_del == NULL)) {
3349 /* Didn't get memory */
3350 SCTPDBG(SCTP_DEBUG_ASCONF1, "sctp_asconf_send_nat_state_update: failed to get memory!\n");
3352 if (aa_vtag != NULL) {
3353 SCTP_FREE(aa_vtag, SCTP_M_ASC_ADDR);
3355 if (aa_add != NULL) {
3356 SCTP_FREE(aa_add, SCTP_M_ASC_ADDR);
3358 if (aa_del != NULL) {
3359 SCTP_FREE(aa_del, SCTP_M_ASC_ADDR);
3363 memset(aa_vtag, 0, sizeof(struct sctp_asconf_addr));
3364 aa_vtag->special_del = 0;
3365 /* Fill in ASCONF address parameter fields. */
3366 /* Top level elements are "networked" during send. */
3367 aa_vtag->ifa = NULL;
3368 aa_vtag->sent = 0; /* clear sent flag */
3369 vtag = (struct sctp_asconf_tag_param *)&aa_vtag->ap.aph;
3370 vtag->aph.ph.param_type = SCTP_NAT_VTAGS;
3371 vtag->aph.ph.param_length = sizeof(struct sctp_asconf_tag_param);
3372 vtag->local_vtag = htonl(stcb->asoc.my_vtag);
3373 vtag->remote_vtag = htonl(stcb->asoc.peer_vtag);
3375 memset(aa_add, 0, sizeof(struct sctp_asconf_addr));
3376 memset(aa_del, 0, sizeof(struct sctp_asconf_addr));
3377 switch (net->ro._l_addr.sa.sa_family) {
3380 aa_add->ap.aph.ph.param_type = SCTP_ADD_IP_ADDRESS;
3381 aa_add->ap.aph.ph.param_length = sizeof(struct sctp_asconf_addrv4_param);
3382 aa_add->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
3383 aa_add->ap.addrp.ph.param_length = sizeof (struct sctp_ipv4addr_param);
3384 /* No need to fill the address, we are using 0.0.0.0 */
3385 aa_del->ap.aph.ph.param_type = SCTP_ADD_IP_ADDRESS;
3386 aa_del->ap.aph.ph.param_length = sizeof(struct sctp_asconf_addrv4_param);
3387 aa_del->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
3388 aa_del->ap.addrp.ph.param_length = sizeof (struct sctp_ipv4addr_param);
3389 /* No need to fill the address, we are using 0.0.0.0 */
3394 aa_add->ap.aph.ph.param_type = SCTP_ADD_IP_ADDRESS;
3395 aa_add->ap.aph.ph.param_length = sizeof(struct sctp_asconf_addr_param);
3396 aa_add->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
3397 aa_add->ap.addrp.ph.param_length = sizeof (struct sctp_ipv6addr_param);
3398 /* No need to fill the address, we are using ::0 */
3399 aa_del->ap.aph.ph.param_type = SCTP_DEL_IP_ADDRESS;
3400 aa_del->ap.aph.ph.param_length = sizeof(struct sctp_asconf_addr_param);
3401 aa_del->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
3402 aa_del->ap.addrp.ph.param_length = sizeof (struct sctp_ipv6addr_param);
3403 /* No need to fill the address, we are using ::0 */
3407 SCTPDBG(SCTP_DEBUG_ASCONF1,
3408 "sctp_asconf_send_nat_state_update: unknown address family %d\n",
3409 net->ro._l_addr.sa.sa_family);
3412 TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa_vtag, next);
3413 TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa_add, next);
3414 TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa_del, next);
3416 /* Now we must hunt the addresses and add all global addresses */
3417 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
3418 struct sctp_vrf *vrf = NULL;
3419 struct sctp_ifn *sctp_ifnp;
3422 vrf_id = stcb->sctp_ep->def_vrf_id;
3423 vrf = sctp_find_vrf(vrf_id);
3428 SCTP_IPI_ADDR_RLOCK();
3429 LIST_FOREACH(sctp_ifnp, &vrf->ifnlist, next_ifn) {
3430 LIST_FOREACH(sctp_ifap, &sctp_ifnp->ifalist, next_ifa) {
3431 switch (sctp_ifap->address.sa.sa_family) {
3434 to = &sctp_ifap->address.sin;
3435 #if defined(__FreeBSD__) && !defined(__Userspace__)
3436 if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred,
3437 &to->sin_addr) != 0) {
3441 if (IN4_ISPRIVATE_ADDRESS(&to->sin_addr)) {
3444 if (IN4_ISLOOPBACK_ADDRESS(&to->sin_addr)) {
3451 to6 = &sctp_ifap->address.sin6;
3452 #if defined(__FreeBSD__) && !defined(__Userspace__)
3453 if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred,
3454 &to6->sin6_addr) != 0) {
3458 if (IN6_IS_ADDR_LOOPBACK(&to6->sin6_addr)) {
3461 if (IN6_IS_ADDR_LINKLOCAL(&to6->sin6_addr)) {
3469 sctp_asconf_queue_mgmt(stcb, sctp_ifap, SCTP_ADD_IP_ADDRESS);
3472 SCTP_IPI_ADDR_RUNLOCK();
3474 struct sctp_laddr *laddr;
3476 LIST_FOREACH(laddr, &stcb->sctp_ep->sctp_addr_list, sctp_nxt_addr) {
3477 if (laddr->ifa == NULL) {
3480 if (laddr->ifa->localifa_flags & SCTP_BEING_DELETED)
3481 /* Address being deleted by the system, dont
3485 if (laddr->action == SCTP_DEL_IP_ADDRESS) {
3486 /* Address being deleted on this ep
3491 sctp_ifap = laddr->ifa;
3492 switch (sctp_ifap->address.sa.sa_family) {
3495 to = &sctp_ifap->address.sin;
3496 if (IN4_ISPRIVATE_ADDRESS(&to->sin_addr)) {
3499 if (IN4_ISLOOPBACK_ADDRESS(&to->sin_addr)) {
3506 to6 = &sctp_ifap->address.sin6;
3507 if (IN6_IS_ADDR_LOOPBACK(&to6->sin6_addr)) {
3510 if (IN6_IS_ADDR_LINKLOCAL(&to6->sin6_addr)) {
3518 sctp_asconf_queue_mgmt(stcb, sctp_ifap, SCTP_ADD_IP_ADDRESS);
3522 /* Now we must send the asconf into the queue */
3523 sctp_send_asconf(stcb, net, SCTP_ADDR_NOT_LOCKED);