2 * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
3 * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
4 * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
9 * a) Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
12 * b) Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the distribution.
16 * c) Neither the name of Cisco Systems, Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30 * THE POSSIBILITY OF SUCH DAMAGE.
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
36 #include <netinet/sctp_os.h>
37 #include <netinet/sctp_var.h>
38 #include <netinet/sctp_sysctl.h>
39 #include <netinet/sctp_pcb.h>
40 #include <netinet/sctp_header.h>
41 #include <netinet/sctputil.h>
42 #include <netinet/sctp_output.h>
43 #include <netinet/sctp_asconf.h>
44 #include <netinet/sctp_timer.h>
48 * SCTP_DEBUG_ASCONF1: protocol info, general info and errors
49 * SCTP_DEBUG_ASCONF2: detailed info
54 sctp_asconf_get_source_ip(struct mbuf *m, struct sockaddr *sa)
59 struct sockaddr_in *sin;
63 struct sockaddr_in6 *sin6;
67 iph = mtod(m, struct ip *);
73 sin = (struct sockaddr_in *)sa;
74 bzero(sin, sizeof(*sin));
75 sin->sin_family = AF_INET;
76 sin->sin_len = sizeof(struct sockaddr_in);
78 sin->sin_addr.s_addr = iph->ip_src.s_addr;
83 case (IPV6_VERSION >> 4):
88 sin6 = (struct sockaddr_in6 *)sa;
89 bzero(sin6, sizeof(*sin6));
90 sin6->sin6_family = AF_INET6;
91 sin6->sin6_len = sizeof(struct sockaddr_in6);
93 ip6 = mtod(m, struct ip6_hdr *);
94 sin6->sin6_addr = ip6->ip6_src;
105 * draft-ietf-tsvwg-addip-sctp
107 * An ASCONF parameter queue exists per asoc which holds the pending address
108 * operations. Lists are updated upon receipt of ASCONF-ACK.
110 * A restricted_addrs list exists per assoc to hold local addresses that are
111 * not (yet) usable by the assoc as a source address. These addresses are
112 * either pending an ASCONF operation (and exist on the ASCONF parameter
113 * queue), or they are permanently restricted (the peer has returned an
114 * ERROR indication to an ASCONF(ADD), or the peer does not support ASCONF).
116 * Deleted addresses are always immediately removed from the lists as they will
117 * (shortly) no longer exist in the kernel. We send ASCONFs as a courtesy,
122 * ASCONF parameter processing.
123 * response_required: set if a reply is required (eg. SUCCESS_REPORT).
124 * returns a mbuf to an "error" response parameter or NULL/"success" if ok.
125 * FIX: allocating this many mbufs on the fly is pretty inefficient...
128 sctp_asconf_success_response(uint32_t id)
130 struct mbuf *m_reply = NULL;
131 struct sctp_asconf_paramhdr *aph;
133 m_reply = sctp_get_mbuf_for_msg(sizeof(struct sctp_asconf_paramhdr),
134 0, M_DONTWAIT, 1, MT_DATA);
135 if (m_reply == NULL) {
136 SCTPDBG(SCTP_DEBUG_ASCONF1,
137 "asconf_success_response: couldn't get mbuf!\n");
140 aph = mtod(m_reply, struct sctp_asconf_paramhdr *);
141 aph->correlation_id = id;
142 aph->ph.param_type = htons(SCTP_SUCCESS_REPORT);
143 aph->ph.param_length = sizeof(struct sctp_asconf_paramhdr);
144 SCTP_BUF_LEN(m_reply) = aph->ph.param_length;
145 aph->ph.param_length = htons(aph->ph.param_length);
151 sctp_asconf_error_response(uint32_t id, uint16_t cause, uint8_t * error_tlv,
154 struct mbuf *m_reply = NULL;
155 struct sctp_asconf_paramhdr *aph;
156 struct sctp_error_cause *error;
159 m_reply = sctp_get_mbuf_for_msg((sizeof(struct sctp_asconf_paramhdr) +
161 sizeof(struct sctp_error_cause)),
162 0, M_DONTWAIT, 1, MT_DATA);
163 if (m_reply == NULL) {
164 SCTPDBG(SCTP_DEBUG_ASCONF1,
165 "asconf_error_response: couldn't get mbuf!\n");
168 aph = mtod(m_reply, struct sctp_asconf_paramhdr *);
169 error = (struct sctp_error_cause *)(aph + 1);
171 aph->correlation_id = id;
172 aph->ph.param_type = htons(SCTP_ERROR_CAUSE_IND);
173 error->code = htons(cause);
174 error->length = tlv_length + sizeof(struct sctp_error_cause);
175 aph->ph.param_length = error->length +
176 sizeof(struct sctp_asconf_paramhdr);
178 if (aph->ph.param_length > MLEN) {
179 SCTPDBG(SCTP_DEBUG_ASCONF1,
180 "asconf_error_response: tlv_length (%xh) too big\n",
182 sctp_m_freem(m_reply); /* discard */
185 if (error_tlv != NULL) {
186 tlv = (uint8_t *) (error + 1);
187 memcpy(tlv, error_tlv, tlv_length);
189 SCTP_BUF_LEN(m_reply) = aph->ph.param_length;
190 error->length = htons(error->length);
191 aph->ph.param_length = htons(aph->ph.param_length);
197 sctp_process_asconf_add_ip(struct mbuf *m, struct sctp_asconf_paramhdr *aph,
198 struct sctp_tcb *stcb, int send_hb, int response_required)
200 struct sctp_nets *net;
201 struct mbuf *m_reply = NULL;
202 struct sockaddr_storage sa_source, sa_store;
203 struct sctp_paramhdr *ph;
204 uint16_t param_type, param_length, aparam_length;
206 int zero_address = 0;
210 struct sockaddr_in *sin;
211 struct sctp_ipv4addr_param *v4addr;
215 struct sockaddr_in6 *sin6;
216 struct sctp_ipv6addr_param *v6addr;
220 aparam_length = ntohs(aph->ph.param_length);
221 ph = (struct sctp_paramhdr *)(aph + 1);
222 param_type = ntohs(ph->param_type);
223 param_length = ntohs(ph->param_length);
225 sa = (struct sockaddr *)&sa_store;
226 switch (param_type) {
228 case SCTP_IPV4_ADDRESS:
229 if (param_length != sizeof(struct sctp_ipv4addr_param)) {
230 /* invalid param size */
233 v4addr = (struct sctp_ipv4addr_param *)ph;
234 sin = (struct sockaddr_in *)&sa_store;
235 bzero(sin, sizeof(*sin));
236 sin->sin_family = AF_INET;
237 sin->sin_len = sizeof(struct sockaddr_in);
238 sin->sin_port = stcb->rport;
239 sin->sin_addr.s_addr = v4addr->addr;
240 if ((sin->sin_addr.s_addr == INADDR_BROADCAST) ||
241 IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) {
244 if (sin->sin_addr.s_addr == INADDR_ANY)
246 SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_add_ip: adding ");
247 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
251 case SCTP_IPV6_ADDRESS:
252 if (param_length != sizeof(struct sctp_ipv6addr_param)) {
253 /* invalid param size */
256 v6addr = (struct sctp_ipv6addr_param *)ph;
257 sin6 = (struct sockaddr_in6 *)&sa_store;
258 bzero(sin6, sizeof(*sin6));
259 sin6->sin6_family = AF_INET6;
260 sin6->sin6_len = sizeof(struct sockaddr_in6);
261 sin6->sin6_port = stcb->rport;
262 memcpy((caddr_t)&sin6->sin6_addr, v6addr->addr,
263 sizeof(struct in6_addr));
264 if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
267 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
269 SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_add_ip: adding ");
270 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
274 m_reply = sctp_asconf_error_response(aph->correlation_id,
275 SCTP_CAUSE_INVALID_PARAM, (uint8_t *) aph,
280 /* if 0.0.0.0/::0, add the source address instead */
281 if (zero_address && SCTP_BASE_SYSCTL(sctp_nat_friendly)) {
282 sa = (struct sockaddr *)&sa_source;
283 sctp_asconf_get_source_ip(m, sa);
284 SCTPDBG(SCTP_DEBUG_ASCONF1,
285 "process_asconf_add_ip: using source addr ");
286 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
288 /* add the address */
290 m_reply = sctp_asconf_error_response(aph->correlation_id,
291 SCTP_CAUSE_INVALID_PARAM, (uint8_t *) aph,
293 } else if (sctp_add_remote_addr(stcb, sa, &net, SCTP_DONOT_SETSCOPE,
294 SCTP_ADDR_DYNAMIC_ADDED) != 0) {
295 SCTPDBG(SCTP_DEBUG_ASCONF1,
296 "process_asconf_add_ip: error adding address\n");
297 m_reply = sctp_asconf_error_response(aph->correlation_id,
298 SCTP_CAUSE_RESOURCE_SHORTAGE, (uint8_t *) aph,
301 /* notify upper layer */
302 sctp_ulp_notify(SCTP_NOTIFY_ASCONF_ADD_IP, stcb, 0, sa, SCTP_SO_NOT_LOCKED);
303 if (response_required) {
305 sctp_asconf_success_response(aph->correlation_id);
307 sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, stcb->sctp_ep, stcb, net);
308 sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep,
311 sctp_send_hb(stcb, net, SCTP_SO_NOT_LOCKED);
318 sctp_asconf_del_remote_addrs_except(struct sctp_tcb *stcb, struct sockaddr *src)
320 struct sctp_nets *src_net, *net;
322 /* make sure the source address exists as a destination net */
323 src_net = sctp_findnet(stcb, src);
324 if (src_net == NULL) {
328 /* delete all destination addresses except the source */
329 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
330 if (net != src_net) {
331 /* delete this address */
332 sctp_remove_net(stcb, net);
333 SCTPDBG(SCTP_DEBUG_ASCONF1,
334 "asconf_del_remote_addrs_except: deleting ");
335 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1,
336 (struct sockaddr *)&net->ro._l_addr);
337 /* notify upper layer */
338 sctp_ulp_notify(SCTP_NOTIFY_ASCONF_DELETE_IP, stcb, 0,
339 (struct sockaddr *)&net->ro._l_addr, SCTP_SO_NOT_LOCKED);
346 sctp_process_asconf_delete_ip(struct mbuf *m, struct sctp_asconf_paramhdr *aph,
347 struct sctp_tcb *stcb, int response_required)
349 struct mbuf *m_reply = NULL;
350 struct sockaddr_storage sa_source, sa_store;
351 struct sctp_paramhdr *ph;
352 uint16_t param_type, param_length, aparam_length;
354 int zero_address = 0;
358 struct sockaddr_in *sin;
359 struct sctp_ipv4addr_param *v4addr;
363 struct sockaddr_in6 *sin6;
364 struct sctp_ipv6addr_param *v6addr;
368 /* get the source IP address for src and 0.0.0.0/::0 delete checks */
369 sctp_asconf_get_source_ip(m, (struct sockaddr *)&sa_source);
371 aparam_length = ntohs(aph->ph.param_length);
372 ph = (struct sctp_paramhdr *)(aph + 1);
373 param_type = ntohs(ph->param_type);
374 param_length = ntohs(ph->param_length);
376 sa = (struct sockaddr *)&sa_store;
377 switch (param_type) {
379 case SCTP_IPV4_ADDRESS:
380 if (param_length != sizeof(struct sctp_ipv4addr_param)) {
381 /* invalid param size */
384 v4addr = (struct sctp_ipv4addr_param *)ph;
385 sin = (struct sockaddr_in *)&sa_store;
386 bzero(sin, sizeof(*sin));
387 sin->sin_family = AF_INET;
388 sin->sin_len = sizeof(struct sockaddr_in);
389 sin->sin_port = stcb->rport;
390 sin->sin_addr.s_addr = v4addr->addr;
391 if (sin->sin_addr.s_addr == INADDR_ANY)
393 SCTPDBG(SCTP_DEBUG_ASCONF1,
394 "process_asconf_delete_ip: deleting ");
395 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
399 case SCTP_IPV6_ADDRESS:
400 if (param_length != sizeof(struct sctp_ipv6addr_param)) {
401 /* invalid param size */
404 v6addr = (struct sctp_ipv6addr_param *)ph;
405 sin6 = (struct sockaddr_in6 *)&sa_store;
406 bzero(sin6, sizeof(*sin6));
407 sin6->sin6_family = AF_INET6;
408 sin6->sin6_len = sizeof(struct sockaddr_in6);
409 sin6->sin6_port = stcb->rport;
410 memcpy(&sin6->sin6_addr, v6addr->addr,
411 sizeof(struct in6_addr));
412 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
414 SCTPDBG(SCTP_DEBUG_ASCONF1,
415 "process_asconf_delete_ip: deleting ");
416 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
420 m_reply = sctp_asconf_error_response(aph->correlation_id,
421 SCTP_CAUSE_UNRESOLVABLE_ADDR, (uint8_t *) aph,
426 /* make sure the source address is not being deleted */
427 if (sctp_cmpaddr(sa, (struct sockaddr *)&sa_source)) {
428 /* trying to delete the source address! */
429 SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_delete_ip: tried to delete source addr\n");
430 m_reply = sctp_asconf_error_response(aph->correlation_id,
431 SCTP_CAUSE_DELETING_SRC_ADDR, (uint8_t *) aph,
435 /* if deleting 0.0.0.0/::0, delete all addresses except src addr */
436 if (zero_address && SCTP_BASE_SYSCTL(sctp_nat_friendly)) {
437 result = sctp_asconf_del_remote_addrs_except(stcb,
438 (struct sockaddr *)&sa_source);
441 /* src address did not exist? */
442 SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_delete_ip: src addr does not exist?\n");
443 /* what error to reply with?? */
445 sctp_asconf_error_response(aph->correlation_id,
446 SCTP_CAUSE_REQUEST_REFUSED, (uint8_t *) aph,
448 } else if (response_required) {
450 sctp_asconf_success_response(aph->correlation_id);
454 /* delete the address */
455 result = sctp_del_remote_addr(stcb, sa);
457 * note if result == -2, the address doesn't exist in the asoc but
458 * since it's being deleted anyways, we just ack the delete -- but
459 * this probably means something has already gone awry
462 /* only one address in the asoc */
463 SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_delete_ip: tried to delete last IP addr!\n");
464 m_reply = sctp_asconf_error_response(aph->correlation_id,
465 SCTP_CAUSE_DELETING_LAST_ADDR, (uint8_t *) aph,
468 if (response_required) {
469 m_reply = sctp_asconf_success_response(aph->correlation_id);
471 /* notify upper layer */
472 sctp_ulp_notify(SCTP_NOTIFY_ASCONF_DELETE_IP, stcb, 0, sa, SCTP_SO_NOT_LOCKED);
478 sctp_process_asconf_set_primary(struct mbuf *m,
479 struct sctp_asconf_paramhdr *aph,
480 struct sctp_tcb *stcb, int response_required)
482 struct mbuf *m_reply = NULL;
483 struct sockaddr_storage sa_source, sa_store;
484 struct sctp_paramhdr *ph;
485 uint16_t param_type, param_length, aparam_length;
487 int zero_address = 0;
490 struct sockaddr_in *sin;
491 struct sctp_ipv4addr_param *v4addr;
495 struct sockaddr_in6 *sin6;
496 struct sctp_ipv6addr_param *v6addr;
500 aparam_length = ntohs(aph->ph.param_length);
501 ph = (struct sctp_paramhdr *)(aph + 1);
502 param_type = ntohs(ph->param_type);
503 param_length = ntohs(ph->param_length);
505 sa = (struct sockaddr *)&sa_store;
506 switch (param_type) {
508 case SCTP_IPV4_ADDRESS:
509 if (param_length != sizeof(struct sctp_ipv4addr_param)) {
510 /* invalid param size */
513 v4addr = (struct sctp_ipv4addr_param *)ph;
514 sin = (struct sockaddr_in *)&sa_store;
515 bzero(sin, sizeof(*sin));
516 sin->sin_family = AF_INET;
517 sin->sin_len = sizeof(struct sockaddr_in);
518 sin->sin_addr.s_addr = v4addr->addr;
519 if (sin->sin_addr.s_addr == INADDR_ANY)
521 SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_set_primary: ");
522 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
526 case SCTP_IPV6_ADDRESS:
527 if (param_length != sizeof(struct sctp_ipv6addr_param)) {
528 /* invalid param size */
531 v6addr = (struct sctp_ipv6addr_param *)ph;
532 sin6 = (struct sockaddr_in6 *)&sa_store;
533 bzero(sin6, sizeof(*sin6));
534 sin6->sin6_family = AF_INET6;
535 sin6->sin6_len = sizeof(struct sockaddr_in6);
536 memcpy((caddr_t)&sin6->sin6_addr, v6addr->addr,
537 sizeof(struct in6_addr));
538 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
540 SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_set_primary: ");
541 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
545 m_reply = sctp_asconf_error_response(aph->correlation_id,
546 SCTP_CAUSE_UNRESOLVABLE_ADDR, (uint8_t *) aph,
551 /* if 0.0.0.0/::0, use the source address instead */
552 if (zero_address && SCTP_BASE_SYSCTL(sctp_nat_friendly)) {
553 sa = (struct sockaddr *)&sa_source;
554 sctp_asconf_get_source_ip(m, sa);
555 SCTPDBG(SCTP_DEBUG_ASCONF1,
556 "process_asconf_set_primary: using source addr ");
557 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
559 /* set the primary address */
560 if (sctp_set_primary_addr(stcb, sa, NULL) == 0) {
561 SCTPDBG(SCTP_DEBUG_ASCONF1,
562 "process_asconf_set_primary: primary address set\n");
563 /* notify upper layer */
564 sctp_ulp_notify(SCTP_NOTIFY_ASCONF_SET_PRIMARY, stcb, 0, sa, SCTP_SO_NOT_LOCKED);
565 if ((stcb->asoc.primary_destination->dest_state & SCTP_ADDR_REACHABLE) &&
566 (!(stcb->asoc.primary_destination->dest_state & SCTP_ADDR_PF)) &&
567 (stcb->asoc.alternate)) {
568 sctp_free_remote_addr(stcb->asoc.alternate);
569 stcb->asoc.alternate = NULL;
571 if (response_required) {
572 m_reply = sctp_asconf_success_response(aph->correlation_id);
575 * Mobility adaptation. Ideally, when the reception of SET
576 * PRIMARY with DELETE IP ADDRESS of the previous primary
577 * destination, unacknowledged DATA are retransmitted
578 * immediately to the new primary destination for seamless
579 * handover. If the destination is UNCONFIRMED and marked to
580 * REQ_PRIM, The retransmission occur when reception of the
581 * HEARTBEAT-ACK. (See sctp_handle_heartbeat_ack in
582 * sctp_input.c) Also, when change of the primary
583 * destination, it is better that all subsequent new DATA
584 * containing already queued DATA are transmitted to the new
585 * primary destination. (by micchie)
587 if ((sctp_is_mobility_feature_on(stcb->sctp_ep,
588 SCTP_MOBILITY_BASE) ||
589 sctp_is_mobility_feature_on(stcb->sctp_ep,
590 SCTP_MOBILITY_FASTHANDOFF)) &&
591 sctp_is_mobility_feature_on(stcb->sctp_ep,
592 SCTP_MOBILITY_PRIM_DELETED) &&
593 (stcb->asoc.primary_destination->dest_state &
594 SCTP_ADDR_UNCONFIRMED) == 0) {
596 sctp_timer_stop(SCTP_TIMER_TYPE_PRIM_DELETED, stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTP_TIMER + SCTP_LOC_7);
597 if (sctp_is_mobility_feature_on(stcb->sctp_ep,
598 SCTP_MOBILITY_FASTHANDOFF)) {
599 sctp_assoc_immediate_retrans(stcb,
600 stcb->asoc.primary_destination);
602 if (sctp_is_mobility_feature_on(stcb->sctp_ep,
603 SCTP_MOBILITY_BASE)) {
604 sctp_move_chunks_from_net(stcb,
605 stcb->asoc.deleted_primary);
607 sctp_delete_prim_timer(stcb->sctp_ep, stcb,
608 stcb->asoc.deleted_primary);
611 /* couldn't set the requested primary address! */
612 SCTPDBG(SCTP_DEBUG_ASCONF1,
613 "process_asconf_set_primary: set primary failed!\n");
614 /* must have been an invalid address, so report */
615 m_reply = sctp_asconf_error_response(aph->correlation_id,
616 SCTP_CAUSE_UNRESOLVABLE_ADDR, (uint8_t *) aph,
624 * handles an ASCONF chunk.
625 * if all parameters are processed ok, send a plain (empty) ASCONF-ACK
628 sctp_handle_asconf(struct mbuf *m, unsigned int offset,
629 struct sctp_asconf_chunk *cp, struct sctp_tcb *stcb,
632 struct sctp_association *asoc;
634 struct mbuf *n, *m_ack, *m_result, *m_tail;
635 struct sctp_asconf_ack_chunk *ack_cp;
636 struct sctp_asconf_paramhdr *aph, *ack_aph;
637 struct sctp_ipv6addr_param *p_addr;
638 unsigned int asconf_limit, cnt;
639 int error = 0; /* did an error occur? */
641 /* asconf param buffer */
642 uint8_t aparam_buf[SCTP_PARAM_BUFFER_SIZE];
643 struct sctp_asconf_ack *ack, *ack_next;
645 /* verify minimum length */
646 if (ntohs(cp->ch.chunk_length) < sizeof(struct sctp_asconf_chunk)) {
647 SCTPDBG(SCTP_DEBUG_ASCONF1,
648 "handle_asconf: chunk too small = %xh\n",
649 ntohs(cp->ch.chunk_length));
653 serial_num = ntohl(cp->serial_number);
655 if (SCTP_TSN_GE(asoc->asconf_seq_in, serial_num)) {
656 /* got a duplicate ASCONF */
657 SCTPDBG(SCTP_DEBUG_ASCONF1,
658 "handle_asconf: got duplicate serial number = %xh\n",
661 } else if (serial_num != (asoc->asconf_seq_in + 1)) {
662 SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: incorrect serial number = %xh (expected next = %xh)\n",
663 serial_num, asoc->asconf_seq_in + 1);
666 /* it's the expected "next" sequence number, so process it */
667 asoc->asconf_seq_in = serial_num; /* update sequence */
668 /* get length of all the param's in the ASCONF */
669 asconf_limit = offset + ntohs(cp->ch.chunk_length);
670 SCTPDBG(SCTP_DEBUG_ASCONF1,
671 "handle_asconf: asconf_limit=%u, sequence=%xh\n",
672 asconf_limit, serial_num);
675 /* delete old cache */
676 SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: Now processing first ASCONF. Try to delete old cache\n");
678 TAILQ_FOREACH_SAFE(ack, &asoc->asconf_ack_sent, next, ack_next) {
679 if (ack->serial_number == serial_num)
681 SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: delete old(%u) < first(%u)\n",
682 ack->serial_number, serial_num);
683 TAILQ_REMOVE(&asoc->asconf_ack_sent, ack, next);
684 if (ack->data != NULL) {
685 sctp_m_freem(ack->data);
687 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_asconf_ack), ack);
690 m_ack = sctp_get_mbuf_for_msg(sizeof(struct sctp_asconf_ack_chunk), 0,
691 M_DONTWAIT, 1, MT_DATA);
693 SCTPDBG(SCTP_DEBUG_ASCONF1,
694 "handle_asconf: couldn't get mbuf!\n");
697 m_tail = m_ack; /* current reply chain's tail */
699 /* fill in ASCONF-ACK header */
700 ack_cp = mtod(m_ack, struct sctp_asconf_ack_chunk *);
701 ack_cp->ch.chunk_type = SCTP_ASCONF_ACK;
702 ack_cp->ch.chunk_flags = 0;
703 ack_cp->serial_number = htonl(serial_num);
704 /* set initial lengths (eg. just an ASCONF-ACK), ntohx at the end! */
705 SCTP_BUF_LEN(m_ack) = sizeof(struct sctp_asconf_ack_chunk);
706 ack_cp->ch.chunk_length = sizeof(struct sctp_asconf_ack_chunk);
708 /* skip the lookup address parameter */
709 offset += sizeof(struct sctp_asconf_chunk);
710 p_addr = (struct sctp_ipv6addr_param *)sctp_m_getptr(m, offset, sizeof(struct sctp_paramhdr), (uint8_t *) & aparam_buf);
711 if (p_addr == NULL) {
712 SCTPDBG(SCTP_DEBUG_ASCONF1,
713 "handle_asconf: couldn't get lookup addr!\n");
714 /* respond with a missing/invalid mandatory parameter error */
717 /* param_length is already validated in process_control... */
718 offset += ntohs(p_addr->ph.param_length); /* skip lookup addr */
720 /* get pointer to first asconf param in ASCONF-ACK */
721 ack_aph = (struct sctp_asconf_paramhdr *)(mtod(m_ack, caddr_t)+sizeof(struct sctp_asconf_ack_chunk));
722 if (ack_aph == NULL) {
723 SCTPDBG(SCTP_DEBUG_ASCONF1, "Gak in asconf2\n");
726 /* get pointer to first asconf param in ASCONF */
727 aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(m, offset, sizeof(struct sctp_asconf_paramhdr), (uint8_t *) & aparam_buf);
729 SCTPDBG(SCTP_DEBUG_ASCONF1, "Empty ASCONF received?\n");
732 /* process through all parameters */
734 while (aph != NULL) {
735 unsigned int param_length, param_type;
737 param_type = ntohs(aph->ph.param_type);
738 param_length = ntohs(aph->ph.param_length);
739 if (offset + param_length > asconf_limit) {
740 /* parameter goes beyond end of chunk! */
746 if (param_length > sizeof(aparam_buf)) {
747 SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: param length (%u) larger than buffer size!\n", param_length);
751 if (param_length <= sizeof(struct sctp_paramhdr)) {
752 SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: param length (%u) too short\n", param_length);
755 /* get the entire parameter */
756 aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(m, offset, param_length, aparam_buf);
758 SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: couldn't get entire param\n");
762 switch (param_type) {
763 case SCTP_ADD_IP_ADDRESS:
764 asoc->peer_supports_asconf = 1;
765 m_result = sctp_process_asconf_add_ip(m, aph, stcb,
766 (cnt < SCTP_BASE_SYSCTL(sctp_hb_maxburst)), error);
769 case SCTP_DEL_IP_ADDRESS:
770 asoc->peer_supports_asconf = 1;
771 m_result = sctp_process_asconf_delete_ip(m, aph, stcb,
774 case SCTP_ERROR_CAUSE_IND:
775 /* not valid in an ASCONF chunk */
777 case SCTP_SET_PRIM_ADDR:
778 asoc->peer_supports_asconf = 1;
779 m_result = sctp_process_asconf_set_primary(m, aph,
783 SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: sees a NAT VTAG state parameter\n");
785 case SCTP_SUCCESS_REPORT:
786 /* not valid in an ASCONF chunk */
788 case SCTP_ULP_ADAPTATION:
792 if ((param_type & 0x8000) == 0) {
793 /* Been told to STOP at this param */
794 asconf_limit = offset;
796 * FIX FIX - We need to call
797 * sctp_arethere_unrecognized_parameters()
798 * to get a operr and send it for any
799 * param's with the 0x4000 bit set OR do it
800 * here ourselves... note we still must STOP
801 * if the 0x8000 bit is clear.
804 /* unknown/invalid param type */
808 /* add any (error) result to the reply mbuf chain */
809 if (m_result != NULL) {
810 SCTP_BUF_NEXT(m_tail) = m_result;
812 /* update lengths, make sure it's aligned too */
813 SCTP_BUF_LEN(m_result) = SCTP_SIZE32(SCTP_BUF_LEN(m_result));
814 ack_cp->ch.chunk_length += SCTP_BUF_LEN(m_result);
815 /* set flag to force success reports */
818 offset += SCTP_SIZE32(param_length);
819 /* update remaining ASCONF message length to process */
820 if (offset >= asconf_limit) {
821 /* no more data in the mbuf chain */
824 /* get pointer to next asconf param */
825 aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(m, offset,
826 sizeof(struct sctp_asconf_paramhdr),
827 (uint8_t *) & aparam_buf);
829 /* can't get an asconf paramhdr */
830 SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: can't get asconf param hdr!\n");
831 /* FIX ME - add error here... */
836 ack_cp->ch.chunk_length = htons(ack_cp->ch.chunk_length);
837 /* save the ASCONF-ACK reply */
838 ack = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_asconf_ack),
839 struct sctp_asconf_ack);
844 ack->serial_number = serial_num;
845 ack->last_sent_to = NULL;
848 for (n = m_ack; n != NULL; n = SCTP_BUF_NEXT(n)) {
849 ack->len += SCTP_BUF_LEN(n);
851 TAILQ_INSERT_TAIL(&stcb->asoc.asconf_ack_sent, ack, next);
853 /* see if last_control_chunk_from is set properly (use IP src addr) */
854 if (stcb->asoc.last_control_chunk_from == NULL) {
856 * this could happen if the source address was just newly
859 struct sockaddr_storage addr;
860 struct sockaddr *src = (struct sockaddr *)&addr;
862 SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: looking up net for IP source address\n");
863 sctp_asconf_get_source_ip(m, src);
864 SCTPDBG(SCTP_DEBUG_ASCONF1, "Looking for IP source: ");
865 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, src);
866 /* look up the from address */
867 stcb->asoc.last_control_chunk_from = sctp_findnet(stcb, src);
869 if (stcb->asoc.last_control_chunk_from == NULL) {
870 SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: IP source address not found?!\n");
877 * does the address match? returns 0 if not, 1 if so
880 sctp_asconf_addr_match(struct sctp_asconf_addr *aa, struct sockaddr *sa)
882 switch (sa->sa_family) {
887 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
889 if ((aa->ap.addrp.ph.param_type == SCTP_IPV6_ADDRESS) &&
890 (memcmp(&aa->ap.addrp.addr, &sin6->sin6_addr,
891 sizeof(struct in6_addr)) == 0)) {
900 struct sockaddr_in *sin = (struct sockaddr_in *)sa;
902 if ((aa->ap.addrp.ph.param_type == SCTP_IPV4_ADDRESS) &&
903 (memcmp(&aa->ap.addrp.addr, &sin->sin_addr,
904 sizeof(struct in_addr)) == 0)) {
917 * does the address match? returns 0 if not, 1 if so
920 sctp_addr_match(struct sctp_paramhdr *ph, struct sockaddr *sa)
922 uint16_t param_type, param_length;
924 param_type = ntohs(ph->param_type);
925 param_length = ntohs(ph->param_length);
926 switch (sa->sa_family) {
931 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
932 struct sctp_ipv6addr_param *v6addr;
934 v6addr = (struct sctp_ipv6addr_param *)ph;
935 if ((param_type == SCTP_IPV6_ADDRESS) &&
936 param_length == sizeof(struct sctp_ipv6addr_param) &&
937 (memcmp(&v6addr->addr, &sin6->sin6_addr,
938 sizeof(struct in6_addr)) == 0)) {
947 struct sockaddr_in *sin = (struct sockaddr_in *)sa;
948 struct sctp_ipv4addr_param *v4addr;
950 v4addr = (struct sctp_ipv4addr_param *)ph;
951 if ((param_type == SCTP_IPV4_ADDRESS) &&
952 param_length == sizeof(struct sctp_ipv4addr_param) &&
953 (memcmp(&v4addr->addr, &sin->sin_addr,
954 sizeof(struct in_addr)) == 0)) {
967 * Cleanup for non-responded/OP ERR'd ASCONF
970 sctp_asconf_cleanup(struct sctp_tcb *stcb, struct sctp_nets *net)
972 /* mark peer as ASCONF incapable */
973 stcb->asoc.peer_supports_asconf = 0;
975 * clear out any existing asconfs going out
977 sctp_timer_stop(SCTP_TIMER_TYPE_ASCONF, stcb->sctp_ep, stcb, net,
978 SCTP_FROM_SCTP_ASCONF + SCTP_LOC_2);
979 stcb->asoc.asconf_seq_out_acked = stcb->asoc.asconf_seq_out;
980 /* remove the old ASCONF on our outbound queue */
981 sctp_toss_old_asconf(stcb);
985 * cleanup any cached source addresses that may be topologically
986 * incorrect after a new address has been added to this interface.
989 sctp_asconf_nets_cleanup(struct sctp_tcb *stcb, struct sctp_ifn *ifn)
991 struct sctp_nets *net;
994 * Ideally, we want to only clear cached routes and source addresses
995 * that are topologically incorrect. But since there is no easy way
996 * to know whether the newly added address on the ifn would cause a
997 * routing change (i.e. a new egress interface would be chosen)
998 * without doing a new routing lookup and source address selection,
999 * we will (for now) just flush any cached route using a different
1000 * ifn (and cached source addrs) and let output re-choose them
1001 * during the next send on that net.
1003 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
1005 * clear any cached route (and cached source address) if the
1006 * route's interface is NOT the same as the address change.
1007 * If it's the same interface, just clear the cached source
1010 if (SCTP_ROUTE_HAS_VALID_IFN(&net->ro) &&
1012 (SCTP_GET_IF_INDEX_FROM_ROUTE(&net->ro) != ifn->ifn_index))) {
1013 /* clear any cached route */
1014 RTFREE(net->ro.ro_rt);
1015 net->ro.ro_rt = NULL;
1017 /* clear any cached source address */
1018 if (net->src_addr_selected) {
1019 sctp_free_ifa(net->ro._s_addr);
1020 net->ro._s_addr = NULL;
1021 net->src_addr_selected = 0;
1028 sctp_assoc_immediate_retrans(struct sctp_tcb *stcb, struct sctp_nets *dstnet)
1032 if (dstnet->dest_state & SCTP_ADDR_UNCONFIRMED) {
1035 if (stcb->asoc.deleted_primary == NULL) {
1038 if (!TAILQ_EMPTY(&stcb->asoc.sent_queue)) {
1039 SCTPDBG(SCTP_DEBUG_ASCONF1, "assoc_immediate_retrans: Deleted primary is ");
1040 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, &stcb->asoc.deleted_primary->ro._l_addr.sa);
1041 SCTPDBG(SCTP_DEBUG_ASCONF1, "Current Primary is ");
1042 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, &stcb->asoc.primary_destination->ro._l_addr.sa);
1043 sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb,
1044 stcb->asoc.deleted_primary,
1045 SCTP_FROM_SCTP_TIMER + SCTP_LOC_8);
1046 stcb->asoc.num_send_timers_up--;
1047 if (stcb->asoc.num_send_timers_up < 0) {
1048 stcb->asoc.num_send_timers_up = 0;
1050 SCTP_TCB_LOCK_ASSERT(stcb);
1051 error = sctp_t3rxt_timer(stcb->sctp_ep, stcb,
1052 stcb->asoc.deleted_primary);
1054 SCTP_INP_DECR_REF(stcb->sctp_ep);
1057 SCTP_TCB_LOCK_ASSERT(stcb);
1058 #ifdef SCTP_AUDITING_ENABLED
1059 sctp_auditing(4, stcb->sctp_ep, stcb, stcb->asoc.deleted_primary);
1061 sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_NOT_LOCKED);
1062 if ((stcb->asoc.num_send_timers_up == 0) &&
1063 (stcb->asoc.sent_queue_cnt > 0)) {
1064 struct sctp_tmit_chunk *chk;
1066 chk = TAILQ_FIRST(&stcb->asoc.sent_queue);
1067 sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
1075 sctp_asconf_queue_mgmt(struct sctp_tcb *, struct sctp_ifa *, uint16_t);
1078 sctp_net_immediate_retrans(struct sctp_tcb *stcb, struct sctp_nets *net)
1080 struct sctp_tmit_chunk *chk;
1082 SCTPDBG(SCTP_DEBUG_ASCONF1, "net_immediate_retrans: RTO is %d\n", net->RTO);
1083 sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, net,
1084 SCTP_FROM_SCTP_TIMER + SCTP_LOC_5);
1085 stcb->asoc.cc_functions.sctp_set_initial_cc_param(stcb, net);
1086 net->error_count = 0;
1087 TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
1088 if (chk->whoTo == net) {
1089 if (chk->sent < SCTP_DATAGRAM_RESEND) {
1090 chk->sent = SCTP_DATAGRAM_RESEND;
1091 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
1092 sctp_flight_size_decrease(chk);
1093 sctp_total_flight_decrease(stcb, chk);
1094 net->marked_retrans++;
1095 stcb->asoc.marked_retrans++;
1099 if (net->marked_retrans) {
1100 sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_NOT_LOCKED);
1105 sctp_path_check_and_react(struct sctp_tcb *stcb, struct sctp_ifa *newifa)
1107 struct sctp_nets *net;
1108 int addrnum, changed;
1111 * If number of local valid addresses is 1, the valid address is
1112 * probably newly added address. Several valid addresses in this
1113 * association. A source address may not be changed. Additionally,
1114 * they can be configured on a same interface as "alias" addresses.
1117 addrnum = sctp_local_addr_count(stcb);
1118 SCTPDBG(SCTP_DEBUG_ASCONF1, "p_check_react(): %d local addresses\n",
1121 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
1122 /* clear any cached route and source address */
1123 if (net->ro.ro_rt) {
1124 RTFREE(net->ro.ro_rt);
1125 net->ro.ro_rt = NULL;
1127 if (net->src_addr_selected) {
1128 sctp_free_ifa(net->ro._s_addr);
1129 net->ro._s_addr = NULL;
1130 net->src_addr_selected = 0;
1132 /* Retransmit unacknowledged DATA chunks immediately */
1133 if (sctp_is_mobility_feature_on(stcb->sctp_ep,
1134 SCTP_MOBILITY_FASTHANDOFF)) {
1135 sctp_net_immediate_retrans(stcb, net);
1137 /* also, SET PRIMARY is maybe already sent */
1141 /* Multiple local addresses exsist in the association. */
1142 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
1143 /* clear any cached route and source address */
1144 if (net->ro.ro_rt) {
1145 RTFREE(net->ro.ro_rt);
1146 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;
1154 * Check if the nexthop is corresponding to the new address.
1155 * If the new address is corresponding to the current
1156 * nexthop, the path will be changed. If the new address is
1157 * NOT corresponding to the current nexthop, the path will
1160 SCTP_RTALLOC((sctp_route_t *) & net->ro,
1161 stcb->sctp_ep->def_vrf_id);
1162 if (net->ro.ro_rt == NULL)
1166 switch (net->ro._l_addr.sa.sa_family) {
1169 if (sctp_v4src_match_nexthop(newifa, (sctp_route_t *) & net->ro)) {
1176 if (sctp_v6src_match_nexthop(
1177 &newifa->address.sin6, (sctp_route_t *) & net->ro)) {
1186 * if the newly added address does not relate routing
1187 * information, we skip.
1191 /* Retransmit unacknowledged DATA chunks immediately */
1192 if (sctp_is_mobility_feature_on(stcb->sctp_ep,
1193 SCTP_MOBILITY_FASTHANDOFF)) {
1194 sctp_net_immediate_retrans(stcb, net);
1196 /* Send SET PRIMARY for this new address */
1197 if (net == stcb->asoc.primary_destination) {
1198 (void)sctp_asconf_queue_mgmt(stcb, newifa,
1199 SCTP_SET_PRIM_ADDR);
1205 * process an ADD/DELETE IP ack from peer.
1206 * addr: corresponding sctp_ifa to the address being added/deleted.
1207 * type: SCTP_ADD_IP_ADDRESS or SCTP_DEL_IP_ADDRESS.
1208 * flag: 1=success, 0=failure.
1211 sctp_asconf_addr_mgmt_ack(struct sctp_tcb *stcb, struct sctp_ifa *addr, uint32_t flag)
1214 * do the necessary asoc list work- if we get a failure indication,
1215 * leave the address on the assoc's restricted list. If we get a
1216 * success indication, remove the address from the restricted list.
1219 * Note: this will only occur for ADD_IP_ADDRESS, since
1220 * DEL_IP_ADDRESS is never actually added to the list...
1223 /* success case, so remove from the restricted list */
1224 sctp_del_local_addr_restricted(stcb, addr);
1226 if (sctp_is_mobility_feature_on(stcb->sctp_ep,
1227 SCTP_MOBILITY_BASE) ||
1228 sctp_is_mobility_feature_on(stcb->sctp_ep,
1229 SCTP_MOBILITY_FASTHANDOFF)) {
1230 sctp_path_check_and_react(stcb, addr);
1233 /* clear any cached/topologically incorrect source addresses */
1234 sctp_asconf_nets_cleanup(stcb, addr->ifn_p);
1236 /* else, leave it on the list */
1240 * add an asconf add/delete/set primary IP address parameter to the queue.
1241 * type = SCTP_ADD_IP_ADDRESS, SCTP_DEL_IP_ADDRESS, SCTP_SET_PRIM_ADDR.
1242 * returns 0 if queued, -1 if not queued/removed.
1243 * NOTE: if adding, but a delete for the same address is already scheduled
1244 * (and not yet sent out), simply remove it from queue. Same for deleting
1245 * an address already scheduled for add. If a duplicate operation is found,
1246 * ignore the new one.
1249 sctp_asconf_queue_mgmt(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
1252 struct sctp_asconf_addr *aa, *aa_next;
1253 struct sockaddr *sa;
1255 /* make sure the request isn't already in the queue */
1256 TAILQ_FOREACH_SAFE(aa, &stcb->asoc.asconf_queue, next, aa_next) {
1257 /* address match? */
1258 if (sctp_asconf_addr_match(aa, &ifa->address.sa) == 0)
1261 * is the request already in queue but not sent? pass the
1262 * request already sent in order to resolve the following
1263 * case: 1. arrival of ADD, then sent 2. arrival of DEL. we
1264 * can't remove the ADD request already sent 3. arrival of
1267 if (aa->ap.aph.ph.param_type == type && aa->sent == 0) {
1270 /* is the negative request already in queue, and not sent */
1271 if ((aa->sent == 0) && (type == SCTP_ADD_IP_ADDRESS) &&
1272 (aa->ap.aph.ph.param_type == SCTP_DEL_IP_ADDRESS)) {
1273 /* add requested, delete already queued */
1274 TAILQ_REMOVE(&stcb->asoc.asconf_queue, aa, next);
1275 /* remove the ifa from the restricted list */
1276 sctp_del_local_addr_restricted(stcb, ifa);
1277 /* free the asconf param */
1278 SCTP_FREE(aa, SCTP_M_ASC_ADDR);
1279 SCTPDBG(SCTP_DEBUG_ASCONF2, "asconf_queue_mgmt: add removes queued entry\n");
1282 if ((aa->sent == 0) && (type == SCTP_DEL_IP_ADDRESS) &&
1283 (aa->ap.aph.ph.param_type == SCTP_ADD_IP_ADDRESS)) {
1284 /* delete requested, add already queued */
1285 TAILQ_REMOVE(&stcb->asoc.asconf_queue, aa, next);
1286 /* remove the aa->ifa from the restricted list */
1287 sctp_del_local_addr_restricted(stcb, aa->ifa);
1288 /* free the asconf param */
1289 SCTP_FREE(aa, SCTP_M_ASC_ADDR);
1290 SCTPDBG(SCTP_DEBUG_ASCONF2, "asconf_queue_mgmt: delete removes queued entry\n");
1295 /* adding new request to the queue */
1296 SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa),
1299 /* didn't get memory */
1300 SCTPDBG(SCTP_DEBUG_ASCONF1, "asconf_queue_mgmt: failed to get memory!\n");
1303 aa->special_del = 0;
1304 /* fill in asconf address parameter fields */
1305 /* top level elements are "networked" during send */
1306 aa->ap.aph.ph.param_type = type;
1308 atomic_add_int(&ifa->refcount, 1);
1309 /* correlation_id filled in during send routine later... */
1310 switch (ifa->address.sa.sa_family) {
1314 struct sockaddr_in6 *sin6;
1316 sin6 = (struct sockaddr_in6 *)&ifa->address.sa;
1317 sa = (struct sockaddr *)sin6;
1318 aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
1319 aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv6addr_param));
1320 aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) +
1321 sizeof(struct sctp_ipv6addr_param);
1322 memcpy(&aa->ap.addrp.addr, &sin6->sin6_addr,
1323 sizeof(struct in6_addr));
1330 struct sockaddr_in *sin;
1332 sin = (struct sockaddr_in *)&ifa->address.sa;
1333 sa = (struct sockaddr *)sin;
1334 aa->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
1335 aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv4addr_param));
1336 aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) +
1337 sizeof(struct sctp_ipv4addr_param);
1338 memcpy(&aa->ap.addrp.addr, &sin->sin_addr,
1339 sizeof(struct in_addr));
1344 /* invalid family! */
1345 SCTP_FREE(aa, SCTP_M_ASC_ADDR);
1349 aa->sent = 0; /* clear sent flag */
1351 TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
1353 if (SCTP_BASE_SYSCTL(sctp_debug_on) & SCTP_DEBUG_ASCONF2) {
1354 if (type == SCTP_ADD_IP_ADDRESS) {
1355 SCTP_PRINTF("asconf_queue_mgmt: inserted asconf ADD_IP_ADDRESS: ");
1356 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, sa);
1357 } else if (type == SCTP_DEL_IP_ADDRESS) {
1358 SCTP_PRINTF("asconf_queue_mgmt: appended asconf DEL_IP_ADDRESS: ");
1359 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, sa);
1361 SCTP_PRINTF("asconf_queue_mgmt: appended asconf SET_PRIM_ADDR: ");
1362 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, sa);
1372 * add an asconf operation for the given ifa and type.
1373 * type = SCTP_ADD_IP_ADDRESS, SCTP_DEL_IP_ADDRESS, SCTP_SET_PRIM_ADDR.
1374 * returns 0 if completed, -1 if not completed, 1 if immediate send is
1378 sctp_asconf_queue_add(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
1382 int pending_delete_queued = 0;
1384 /* see if peer supports ASCONF */
1385 if (stcb->asoc.peer_supports_asconf == 0) {
1389 * if this is deleting the last address from the assoc, mark it as
1392 if ((type == SCTP_DEL_IP_ADDRESS) && !stcb->asoc.asconf_del_pending &&
1393 (sctp_local_addr_count(stcb) < 2)) {
1394 /* set the pending delete info only */
1395 stcb->asoc.asconf_del_pending = 1;
1396 stcb->asoc.asconf_addr_del_pending = ifa;
1397 atomic_add_int(&ifa->refcount, 1);
1398 SCTPDBG(SCTP_DEBUG_ASCONF2,
1399 "asconf_queue_add: mark delete last address pending\n");
1402 /* queue an asconf parameter */
1403 status = sctp_asconf_queue_mgmt(stcb, ifa, type);
1406 * if this is an add, and there is a delete also pending (i.e. the
1407 * last local address is being changed), queue the pending delete
1410 if ((type == SCTP_ADD_IP_ADDRESS) && stcb->asoc.asconf_del_pending && (status == 0)) {
1411 /* queue in the pending delete */
1412 if (sctp_asconf_queue_mgmt(stcb,
1413 stcb->asoc.asconf_addr_del_pending,
1414 SCTP_DEL_IP_ADDRESS) == 0) {
1415 SCTPDBG(SCTP_DEBUG_ASCONF2, "asconf_queue_add: queing pending delete\n");
1416 pending_delete_queued = 1;
1417 /* clear out the pending delete info */
1418 stcb->asoc.asconf_del_pending = 0;
1419 sctp_free_ifa(stcb->asoc.asconf_addr_del_pending);
1420 stcb->asoc.asconf_addr_del_pending = NULL;
1423 if (pending_delete_queued) {
1424 struct sctp_nets *net;
1427 * since we know that the only/last address is now being
1428 * changed in this case, reset the cwnd/rto on all nets to
1429 * start as a new address and path. Also clear the error
1430 * counts to give the assoc the best chance to complete the
1433 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
1434 stcb->asoc.cc_functions.sctp_set_initial_cc_param(stcb,
1437 net->error_count = 0;
1439 stcb->asoc.overall_error_count = 0;
1440 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
1441 sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
1442 stcb->asoc.overall_error_count,
1444 SCTP_FROM_SCTP_ASCONF,
1447 /* queue in an advisory set primary too */
1448 (void)sctp_asconf_queue_mgmt(stcb, ifa, SCTP_SET_PRIM_ADDR);
1449 /* let caller know we should send this out immediately */
1456 * add an asconf delete IP address parameter to the queue by sockaddr and
1457 * possibly with no sctp_ifa available. This is only called by the routine
1458 * that checks the addresses in an INIT-ACK against the current address list.
1459 * returns 0 if completed, non-zero if not completed.
1460 * NOTE: if an add is already scheduled (and not yet sent out), simply
1461 * remove it from queue. If a duplicate operation is found, ignore the
1465 sctp_asconf_queue_sa_delete(struct sctp_tcb *stcb, struct sockaddr *sa)
1467 struct sctp_ifa *ifa;
1468 struct sctp_asconf_addr *aa, *aa_next;
1474 /* see if peer supports ASCONF */
1475 if (stcb->asoc.peer_supports_asconf == 0) {
1478 /* make sure the request isn't already in the queue */
1479 TAILQ_FOREACH_SAFE(aa, &stcb->asoc.asconf_queue, next, aa_next) {
1480 /* address match? */
1481 if (sctp_asconf_addr_match(aa, sa) == 0)
1483 /* is the request already in queue (sent or not) */
1484 if (aa->ap.aph.ph.param_type == SCTP_DEL_IP_ADDRESS) {
1487 /* is the negative request already in queue, and not sent */
1490 if (aa->ap.aph.ph.param_type == SCTP_ADD_IP_ADDRESS) {
1491 /* add already queued, so remove existing entry */
1492 TAILQ_REMOVE(&stcb->asoc.asconf_queue, aa, next);
1493 sctp_del_local_addr_restricted(stcb, aa->ifa);
1494 /* free the entry */
1495 SCTP_FREE(aa, SCTP_M_ASC_ADDR);
1500 /* find any existing ifa-- NOTE ifa CAN be allowed to be NULL */
1502 vrf_id = stcb->asoc.vrf_id;
1504 vrf_id = SCTP_DEFAULT_VRFID;
1506 ifa = sctp_find_ifa_by_addr(sa, vrf_id, SCTP_ADDR_NOT_LOCKED);
1508 /* adding new request to the queue */
1509 SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa),
1512 /* didn't get memory */
1513 SCTPDBG(SCTP_DEBUG_ASCONF1,
1514 "sctp_asconf_queue_sa_delete: failed to get memory!\n");
1517 aa->special_del = 0;
1518 /* fill in asconf address parameter fields */
1519 /* top level elements are "networked" during send */
1520 aa->ap.aph.ph.param_type = SCTP_DEL_IP_ADDRESS;
1523 atomic_add_int(&ifa->refcount, 1);
1524 /* correlation_id filled in during send routine later... */
1525 switch (sa->sa_family) {
1530 struct sockaddr_in6 *sin6;
1532 sin6 = (struct sockaddr_in6 *)sa;
1533 aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
1534 aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv6addr_param));
1535 aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) + sizeof(struct sctp_ipv6addr_param);
1536 memcpy(&aa->ap.addrp.addr, &sin6->sin6_addr,
1537 sizeof(struct in6_addr));
1545 struct sockaddr_in *sin = (struct sockaddr_in *)sa;
1547 aa->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
1548 aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv4addr_param));
1549 aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) + sizeof(struct sctp_ipv4addr_param);
1550 memcpy(&aa->ap.addrp.addr, &sin->sin_addr,
1551 sizeof(struct in_addr));
1556 /* invalid family! */
1557 SCTP_FREE(aa, SCTP_M_ASC_ADDR);
1562 aa->sent = 0; /* clear sent flag */
1564 /* delete goes to the back of the queue */
1565 TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
1567 /* sa_ignore MEMLEAK {memory is put on the tailq} */
1572 * find a specific asconf param on our "sent" queue
1574 static struct sctp_asconf_addr *
1575 sctp_asconf_find_param(struct sctp_tcb *stcb, uint32_t correlation_id)
1577 struct sctp_asconf_addr *aa;
1579 TAILQ_FOREACH(aa, &stcb->asoc.asconf_queue, next) {
1580 if (aa->ap.aph.correlation_id == correlation_id &&
1586 /* didn't find it */
1591 * process an SCTP_ERROR_CAUSE_IND for a ASCONF-ACK parameter and do
1592 * notifications based on the error response
1595 sctp_asconf_process_error(struct sctp_tcb *stcb,
1596 struct sctp_asconf_paramhdr *aph)
1598 struct sctp_error_cause *eh;
1599 struct sctp_paramhdr *ph;
1600 uint16_t param_type;
1601 uint16_t error_code;
1603 eh = (struct sctp_error_cause *)(aph + 1);
1604 ph = (struct sctp_paramhdr *)(eh + 1);
1605 /* validate lengths */
1606 if (htons(eh->length) + sizeof(struct sctp_error_cause) >
1607 htons(aph->ph.param_length)) {
1608 /* invalid error cause length */
1609 SCTPDBG(SCTP_DEBUG_ASCONF1,
1610 "asconf_process_error: cause element too long\n");
1613 if (htons(ph->param_length) + sizeof(struct sctp_paramhdr) >
1614 htons(eh->length)) {
1615 /* invalid included TLV length */
1616 SCTPDBG(SCTP_DEBUG_ASCONF1,
1617 "asconf_process_error: included TLV too long\n");
1620 /* which error code ? */
1621 error_code = ntohs(eh->code);
1622 param_type = ntohs(aph->ph.param_type);
1623 /* FIX: this should go back up the REMOTE_ERROR ULP notify */
1624 switch (error_code) {
1625 case SCTP_CAUSE_RESOURCE_SHORTAGE:
1626 /* we allow ourselves to "try again" for this error */
1629 /* peer can't handle it... */
1630 switch (param_type) {
1631 case SCTP_ADD_IP_ADDRESS:
1632 case SCTP_DEL_IP_ADDRESS:
1633 stcb->asoc.peer_supports_asconf = 0;
1635 case SCTP_SET_PRIM_ADDR:
1636 stcb->asoc.peer_supports_asconf = 0;
1645 * process an asconf queue param.
1646 * aparam: parameter to process, will be removed from the queue.
1647 * flag: 1=success case, 0=failure case
1650 sctp_asconf_process_param_ack(struct sctp_tcb *stcb,
1651 struct sctp_asconf_addr *aparam, uint32_t flag)
1653 uint16_t param_type;
1655 /* process this param */
1656 param_type = aparam->ap.aph.ph.param_type;
1657 switch (param_type) {
1658 case SCTP_ADD_IP_ADDRESS:
1659 SCTPDBG(SCTP_DEBUG_ASCONF1,
1660 "process_param_ack: added IP address\n");
1661 sctp_asconf_addr_mgmt_ack(stcb, aparam->ifa, flag);
1663 case SCTP_DEL_IP_ADDRESS:
1664 SCTPDBG(SCTP_DEBUG_ASCONF1,
1665 "process_param_ack: deleted IP address\n");
1666 /* nothing really to do... lists already updated */
1668 case SCTP_SET_PRIM_ADDR:
1669 SCTPDBG(SCTP_DEBUG_ASCONF1,
1670 "process_param_ack: set primary IP address\n");
1671 /* nothing to do... peer may start using this addr */
1673 stcb->asoc.peer_supports_asconf = 0;
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)
1693 /* assume peer doesn't really know how to do asconfs */
1694 stcb->asoc.peer_supports_asconf = 0;
1695 /* 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 SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf_ack: got unexpected next serial number! Aborting asoc!\n");
1739 sctp_abort_an_association(stcb->sctp_ep, stcb, NULL, SCTP_SO_NOT_LOCKED);
1740 *abort_no_unlock = 1;
1743 if (serial_num != asoc->asconf_seq_out_acked + 1) {
1744 /* got a duplicate/unexpected ASCONF-ACK */
1745 SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf_ack: got duplicate/unexpected serial number = %xh (expected = %xh)\n",
1746 serial_num, asoc->asconf_seq_out_acked + 1);
1749 if (serial_num == asoc->asconf_seq_out - 1) {
1750 /* stop our timer */
1751 sctp_timer_stop(SCTP_TIMER_TYPE_ASCONF, stcb->sctp_ep, stcb, net,
1752 SCTP_FROM_SCTP_ASCONF + SCTP_LOC_3);
1754 /* process the ASCONF-ACK contents */
1755 ack_length = ntohs(cp->ch.chunk_length) -
1756 sizeof(struct sctp_asconf_ack_chunk);
1757 offset += sizeof(struct sctp_asconf_ack_chunk);
1758 /* process through all parameters */
1759 while (ack_length >= sizeof(struct sctp_asconf_paramhdr)) {
1760 unsigned int param_length, param_type;
1762 /* get pointer to next asconf parameter */
1763 aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(m, offset,
1764 sizeof(struct sctp_asconf_paramhdr), aparam_buf);
1766 /* can't get an asconf paramhdr */
1767 sctp_asconf_ack_clear(stcb);
1770 param_type = ntohs(aph->ph.param_type);
1771 param_length = ntohs(aph->ph.param_length);
1772 if (param_length > ack_length) {
1773 sctp_asconf_ack_clear(stcb);
1776 if (param_length < sizeof(struct sctp_paramhdr)) {
1777 sctp_asconf_ack_clear(stcb);
1780 /* get the complete parameter... */
1781 if (param_length > sizeof(aparam_buf)) {
1782 SCTPDBG(SCTP_DEBUG_ASCONF1,
1783 "param length (%u) larger than buffer size!\n", param_length);
1784 sctp_asconf_ack_clear(stcb);
1787 aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(m, offset, param_length, aparam_buf);
1789 sctp_asconf_ack_clear(stcb);
1792 /* correlation_id is transparent to peer, no ntohl needed */
1793 id = aph->correlation_id;
1795 switch (param_type) {
1796 case SCTP_ERROR_CAUSE_IND:
1798 /* find the corresponding asconf param in our queue */
1799 ap = sctp_asconf_find_param(stcb, id);
1801 /* hmm... can't find this in our queue! */
1804 /* process the parameter, failed flag */
1805 sctp_asconf_process_param_ack(stcb, ap, 0);
1806 /* process the error response */
1807 sctp_asconf_process_error(stcb, aph);
1809 case SCTP_SUCCESS_REPORT:
1810 /* find the corresponding asconf param in our queue */
1811 ap = sctp_asconf_find_param(stcb, id);
1813 /* hmm... can't find this in our queue! */
1816 /* process the parameter, success flag */
1817 sctp_asconf_process_param_ack(stcb, ap, 1);
1823 /* update remaining ASCONF-ACK message length to process */
1824 ack_length -= SCTP_SIZE32(param_length);
1825 if (ack_length <= 0) {
1826 /* no more data in the mbuf chain */
1829 offset += SCTP_SIZE32(param_length);
1833 * if there are any "sent" params still on the queue, these are
1834 * implicitly "success", or "failed" (if we got an error back) ...
1835 * so process these appropriately
1837 * we assume that the correlation_id's are monotonically increasing
1838 * beginning from 1 and that we don't have *that* many outstanding
1841 if (last_error_id == 0)
1842 last_error_id--;/* set to "max" value */
1843 TAILQ_FOREACH_SAFE(aa, &stcb->asoc.asconf_queue, next, aa_next) {
1844 if (aa->sent == 1) {
1846 * implicitly successful or failed if correlation_id
1847 * < last_error_id, then success else, failure
1849 if (aa->ap.aph.correlation_id < last_error_id)
1850 sctp_asconf_process_param_ack(stcb, aa, 1);
1852 sctp_asconf_process_param_ack(stcb, aa, 0);
1855 * since we always process in order (FIFO queue) if
1856 * we reach one that hasn't been sent, the rest
1857 * should not have been sent either. so, we're
1864 /* update the next sequence number to use */
1865 asoc->asconf_seq_out_acked++;
1866 /* remove the old ASCONF on our outbound queue */
1867 sctp_toss_old_asconf(stcb);
1868 if (!TAILQ_EMPTY(&stcb->asoc.asconf_queue)) {
1869 #ifdef SCTP_TIMER_BASED_ASCONF
1870 /* we have more params, so restart our timer */
1871 sctp_timer_start(SCTP_TIMER_TYPE_ASCONF, stcb->sctp_ep,
1874 /* we have more params, so send out more */
1875 sctp_send_asconf(stcb, net, SCTP_ADDR_NOT_LOCKED);
1882 sctp_is_scopeid_in_nets(struct sctp_tcb *stcb, struct sockaddr *sa)
1884 struct sockaddr_in6 *sin6, *net6;
1885 struct sctp_nets *net;
1887 if (sa->sa_family != AF_INET6) {
1891 sin6 = (struct sockaddr_in6 *)sa;
1892 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) == 0) {
1893 /* not link local address */
1896 /* hunt through our destination nets list for this scope_id */
1897 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
1898 if (((struct sockaddr *)(&net->ro._l_addr))->sa_family !=
1901 net6 = (struct sockaddr_in6 *)&net->ro._l_addr;
1902 if (IN6_IS_ADDR_LINKLOCAL(&net6->sin6_addr) == 0)
1904 if (sctp_is_same_scope(sin6, net6)) {
1909 /* didn't find one */
1916 * address management functions
1919 sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
1920 struct sctp_ifa *ifa, uint16_t type, int addr_locked)
1925 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0 ||
1926 sctp_is_feature_off(inp, SCTP_PCB_FLAGS_DO_ASCONF)) {
1927 /* subset bound, no ASCONF allowed case, so ignore */
1931 * note: we know this is not the subset bound, no ASCONF case eg.
1932 * this is boundall or subset bound w/ASCONF allowed
1935 /* first, make sure it's a good address family */
1936 switch (ifa->address.sa.sa_family) {
1949 /* make sure we're "allowed" to add this type of addr */
1950 if (ifa->address.sa.sa_family == AF_INET6) {
1951 /* invalid if we're not a v6 endpoint */
1952 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0)
1954 /* is the v6 addr really valid ? */
1955 if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
1960 /* put this address on the "pending/do not use yet" list */
1961 sctp_add_local_addr_restricted(stcb, ifa);
1963 * check address scope if address is out of scope, don't queue
1964 * anything... note: this would leave the address on both inp and
1967 switch (ifa->address.sa.sa_family) {
1971 struct sockaddr_in6 *sin6;
1973 sin6 = (struct sockaddr_in6 *)&ifa->address.sin6;
1974 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
1975 /* we skip unspecifed addresses */
1978 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
1979 if (stcb->asoc.local_scope == 0) {
1982 /* is it the right link local scope? */
1983 if (sctp_is_scopeid_in_nets(stcb, &ifa->address.sa) == 0) {
1987 if (stcb->asoc.site_scope == 0 &&
1988 IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) {
1997 struct sockaddr_in *sin;
1998 struct in6pcb *inp6;
2000 inp6 = (struct in6pcb *)&inp->ip_inp.inp;
2001 /* invalid if we are a v6 only endpoint */
2002 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
2003 SCTP_IPV6_V6ONLY(inp6))
2006 sin = (struct sockaddr_in *)&ifa->address.sa;
2007 if (sin->sin_addr.s_addr == 0) {
2008 /* we skip unspecifed addresses */
2011 if (stcb->asoc.ipv4_local_scope == 0 &&
2012 IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
2019 /* else, not AF_INET or AF_INET6, so skip */
2023 /* queue an asconf for this address add/delete */
2024 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_DO_ASCONF)) {
2025 /* does the peer do asconf? */
2026 if (stcb->asoc.peer_supports_asconf) {
2027 /* queue an asconf for this addr */
2028 status = sctp_asconf_queue_add(stcb, ifa, type);
2031 * if queued ok, and in the open state, send out the
2032 * ASCONF. If in the non-open state, these will be
2033 * sent when the state goes open.
2036 SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) {
2037 #ifdef SCTP_TIMER_BASED_ASCONF
2038 sctp_timer_start(SCTP_TIMER_TYPE_ASCONF, inp,
2039 stcb, stcb->asoc.primary_destination);
2041 sctp_send_asconf(stcb, NULL, addr_locked);
2050 sctp_asconf_iterator_ep(struct sctp_inpcb *inp, void *ptr, uint32_t val SCTP_UNUSED)
2052 struct sctp_asconf_iterator *asc;
2053 struct sctp_ifa *ifa;
2054 struct sctp_laddr *l;
2055 int cnt_invalid = 0;
2057 asc = (struct sctp_asconf_iterator *)ptr;
2058 LIST_FOREACH(l, &asc->list_of_work, sctp_nxt_addr) {
2060 switch (ifa->address.sa.sa_family) {
2063 /* invalid if we're not a v6 endpoint */
2064 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
2066 if (asc->cnt == cnt_invalid)
2074 /* invalid if we are a v6 only endpoint */
2075 struct in6pcb *inp6;
2077 inp6 = (struct in6pcb *)&inp->ip_inp.inp;
2078 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
2079 SCTP_IPV6_V6ONLY(inp6)) {
2081 if (asc->cnt == cnt_invalid)
2088 /* invalid address family */
2090 if (asc->cnt == cnt_invalid)
2098 sctp_asconf_iterator_ep_end(struct sctp_inpcb *inp, void *ptr, uint32_t val SCTP_UNUSED)
2100 struct sctp_ifa *ifa;
2101 struct sctp_asconf_iterator *asc;
2102 struct sctp_laddr *laddr, *nladdr, *l;
2104 /* Only for specific case not bound all */
2105 asc = (struct sctp_asconf_iterator *)ptr;
2106 LIST_FOREACH(l, &asc->list_of_work, sctp_nxt_addr) {
2108 if (l->action == SCTP_ADD_IP_ADDRESS) {
2109 LIST_FOREACH(laddr, &inp->sctp_addr_list,
2111 if (laddr->ifa == ifa) {
2116 } else if (l->action == SCTP_DEL_IP_ADDRESS) {
2117 LIST_FOREACH_SAFE(laddr, &inp->sctp_addr_list, sctp_nxt_addr, nladdr) {
2118 /* remove only after all guys are done */
2119 if (laddr->ifa == ifa) {
2120 sctp_del_local_addr_ep(inp, ifa);
2129 sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
2130 void *ptr, uint32_t val SCTP_UNUSED)
2132 struct sctp_asconf_iterator *asc;
2133 struct sctp_ifa *ifa;
2134 struct sctp_laddr *l;
2135 int cnt_invalid = 0;
2139 asc = (struct sctp_asconf_iterator *)ptr;
2140 LIST_FOREACH(l, &asc->list_of_work, sctp_nxt_addr) {
2144 /* address's vrf_id must be the vrf_id of the assoc */
2145 if (ifa->vrf_id != stcb->asoc.vrf_id) {
2148 /* Same checks again for assoc */
2149 switch (ifa->address.sa.sa_family) {
2153 /* invalid if we're not a v6 endpoint */
2154 struct sockaddr_in6 *sin6;
2156 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
2158 if (asc->cnt == cnt_invalid)
2163 sin6 = (struct sockaddr_in6 *)&ifa->address.sin6;
2164 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
2165 /* we skip unspecifed addresses */
2168 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
2169 if (stcb->asoc.local_scope == 0) {
2172 /* is it the right link local scope? */
2173 if (sctp_is_scopeid_in_nets(stcb, &ifa->address.sa) == 0) {
2183 /* invalid if we are a v6 only endpoint */
2184 struct in6pcb *inp6;
2185 struct sockaddr_in *sin;
2187 inp6 = (struct in6pcb *)&inp->ip_inp.inp;
2188 /* invalid if we are a v6 only endpoint */
2189 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
2190 SCTP_IPV6_V6ONLY(inp6))
2193 sin = (struct sockaddr_in *)&ifa->address.sa;
2194 if (sin->sin_addr.s_addr == 0) {
2195 /* we skip unspecifed addresses */
2198 if (stcb->asoc.ipv4_local_scope == 0 &&
2199 IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
2202 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
2203 SCTP_IPV6_V6ONLY(inp6)) {
2205 if (asc->cnt == cnt_invalid)
2214 /* invalid address family */
2216 if (asc->cnt == cnt_invalid)
2223 if (type == SCTP_ADD_IP_ADDRESS) {
2224 /* prevent this address from being used as a source */
2225 sctp_add_local_addr_restricted(stcb, ifa);
2226 } else if (type == SCTP_DEL_IP_ADDRESS) {
2227 struct sctp_nets *net;
2229 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
2232 /* delete this address if cached */
2233 if (net->ro._s_addr == ifa) {
2234 sctp_free_ifa(net->ro._s_addr);
2235 net->ro._s_addr = NULL;
2236 net->src_addr_selected = 0;
2240 net->ro.ro_rt = NULL;
2243 * Now we deleted our src address,
2244 * should we not also now reset the
2245 * cwnd/rto to start as if its a new
2248 stcb->asoc.cc_functions.sctp_set_initial_cc_param(stcb, net);
2253 } else if (type == SCTP_SET_PRIM_ADDR) {
2254 if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) {
2255 /* must validate the ifa is in the ep */
2256 if (sctp_is_addr_in_ep(stcb->sctp_ep, ifa) == 0) {
2260 /* Need to check scopes for this guy */
2261 if (sctp_is_address_in_scope(ifa,
2262 stcb->asoc.ipv4_addr_legal,
2263 stcb->asoc.ipv6_addr_legal,
2264 stcb->asoc.loopback_scope,
2265 stcb->asoc.ipv4_local_scope,
2266 stcb->asoc.local_scope,
2267 stcb->asoc.site_scope, 0) == 0) {
2272 /* queue an asconf for this address add/delete */
2273 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_DO_ASCONF) &&
2274 stcb->asoc.peer_supports_asconf) {
2275 /* queue an asconf for this addr */
2276 status = sctp_asconf_queue_add(stcb, ifa, type);
2278 * if queued ok, and in the open state, update the
2279 * count of queued params. If in the non-open
2280 * state, these get sent when the assoc goes open.
2282 if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) {
2290 * If we have queued params in the open state, send out an ASCONF.
2292 if (num_queued > 0) {
2293 sctp_send_asconf(stcb, NULL, SCTP_ADDR_NOT_LOCKED);
2298 sctp_asconf_iterator_end(void *ptr, uint32_t val SCTP_UNUSED)
2300 struct sctp_asconf_iterator *asc;
2301 struct sctp_ifa *ifa;
2302 struct sctp_laddr *l, *nl;
2304 asc = (struct sctp_asconf_iterator *)ptr;
2305 LIST_FOREACH_SAFE(l, &asc->list_of_work, sctp_nxt_addr, nl) {
2307 if (l->action == SCTP_ADD_IP_ADDRESS) {
2308 /* Clear the defer use flag */
2309 ifa->localifa_flags &= ~SCTP_ADDR_DEFER_USE;
2312 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_laddr), l);
2313 SCTP_DECR_LADDR_COUNT();
2315 SCTP_FREE(asc, SCTP_M_ASC_IT);
2319 * sa is the sockaddr to ask the peer to set primary to.
2320 * returns: 0 = completed, -1 = error
2323 sctp_set_primary_ip_address_sa(struct sctp_tcb *stcb, struct sockaddr *sa)
2326 struct sctp_ifa *ifa;
2328 /* find the ifa for the desired set primary */
2329 vrf_id = stcb->asoc.vrf_id;
2330 ifa = sctp_find_ifa_by_addr(sa, vrf_id, SCTP_ADDR_NOT_LOCKED);
2332 /* Invalid address */
2335 /* queue an ASCONF:SET_PRIM_ADDR to be sent */
2336 if (!sctp_asconf_queue_add(stcb, ifa, SCTP_SET_PRIM_ADDR)) {
2337 /* set primary queuing succeeded */
2338 SCTPDBG(SCTP_DEBUG_ASCONF1,
2339 "set_primary_ip_address_sa: queued on tcb=%p, ",
2341 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
2342 if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) {
2343 #ifdef SCTP_TIMER_BASED_ASCONF
2344 sctp_timer_start(SCTP_TIMER_TYPE_ASCONF,
2345 stcb->sctp_ep, stcb,
2346 stcb->asoc.primary_destination);
2348 sctp_send_asconf(stcb, NULL, SCTP_ADDR_NOT_LOCKED);
2352 SCTPDBG(SCTP_DEBUG_ASCONF1, "set_primary_ip_address_sa: failed to add to queue on tcb=%p, ",
2354 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
2361 sctp_set_primary_ip_address(struct sctp_ifa *ifa)
2363 struct sctp_inpcb *inp;
2365 /* go through all our PCB's */
2366 LIST_FOREACH(inp, &SCTP_BASE_INFO(listhead), sctp_list) {
2367 struct sctp_tcb *stcb;
2369 /* process for all associations for this endpoint */
2370 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
2371 /* queue an ASCONF:SET_PRIM_ADDR to be sent */
2372 if (!sctp_asconf_queue_add(stcb, ifa,
2373 SCTP_SET_PRIM_ADDR)) {
2374 /* set primary queuing succeeded */
2375 SCTPDBG(SCTP_DEBUG_ASCONF1, "set_primary_ip_address: queued on stcb=%p, ",
2377 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, &ifa->address.sa);
2378 if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) {
2379 #ifdef SCTP_TIMER_BASED_ASCONF
2380 sctp_timer_start(SCTP_TIMER_TYPE_ASCONF,
2381 stcb->sctp_ep, stcb,
2382 stcb->asoc.primary_destination);
2384 sctp_send_asconf(stcb, NULL, SCTP_ADDR_NOT_LOCKED);
2388 } /* for each stcb */
2389 } /* for each inp */
2393 sctp_is_addr_pending(struct sctp_tcb *stcb, struct sctp_ifa *sctp_ifa)
2395 struct sctp_tmit_chunk *chk, *nchk;
2396 unsigned int offset, asconf_limit;
2397 struct sctp_asconf_chunk *acp;
2398 struct sctp_asconf_paramhdr *aph;
2399 uint8_t aparam_buf[SCTP_PARAM_BUFFER_SIZE];
2400 struct sctp_paramhdr *ph;
2401 int add_cnt, del_cnt;
2402 uint16_t last_param_type;
2404 add_cnt = del_cnt = 0;
2405 last_param_type = 0;
2406 TAILQ_FOREACH_SAFE(chk, &stcb->asoc.asconf_send_queue, sctp_next, nchk) {
2407 if (chk->data == NULL) {
2408 SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: No mbuf data?\n");
2412 acp = mtod(chk->data, struct sctp_asconf_chunk *);
2413 offset += sizeof(struct sctp_asconf_chunk);
2414 asconf_limit = ntohs(acp->ch.chunk_length);
2415 ph = (struct sctp_paramhdr *)sctp_m_getptr(chk->data, offset, sizeof(struct sctp_paramhdr), aparam_buf);
2417 SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: couldn't get lookup addr!\n");
2420 offset += ntohs(ph->param_length);
2422 aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(chk->data, offset, sizeof(struct sctp_asconf_paramhdr), aparam_buf);
2424 SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: Empty ASCONF will be sent?\n");
2427 while (aph != NULL) {
2428 unsigned int param_length, param_type;
2430 param_type = ntohs(aph->ph.param_type);
2431 param_length = ntohs(aph->ph.param_length);
2432 if (offset + param_length > asconf_limit) {
2433 /* parameter goes beyond end of chunk! */
2436 if (param_length > sizeof(aparam_buf)) {
2437 SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: param length (%u) larger than buffer size!\n", param_length);
2440 if (param_length <= sizeof(struct sctp_paramhdr)) {
2441 SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: param length(%u) too short\n", param_length);
2444 aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(chk->data, offset, param_length, aparam_buf);
2446 SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: couldn't get entire param\n");
2449 ph = (struct sctp_paramhdr *)(aph + 1);
2450 if (sctp_addr_match(ph, &sctp_ifa->address.sa) != 0) {
2451 switch (param_type) {
2452 case SCTP_ADD_IP_ADDRESS:
2455 case SCTP_DEL_IP_ADDRESS:
2461 last_param_type = param_type;
2463 offset += SCTP_SIZE32(param_length);
2464 if (offset >= asconf_limit) {
2465 /* no more data in the mbuf chain */
2468 /* get pointer to next asconf param */
2469 aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(chk->data, offset, sizeof(struct sctp_asconf_paramhdr), aparam_buf);
2474 * we want to find the sequences which consist of ADD -> DEL -> ADD
2477 if (add_cnt > del_cnt ||
2478 (add_cnt == del_cnt && last_param_type == SCTP_ADD_IP_ADDRESS)) {
2484 static struct sockaddr *
2485 sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked)
2487 struct sctp_vrf *vrf = NULL;
2488 struct sctp_ifn *sctp_ifn;
2489 struct sctp_ifa *sctp_ifa;
2491 if (addr_locked == SCTP_ADDR_NOT_LOCKED)
2492 SCTP_IPI_ADDR_RLOCK();
2493 vrf = sctp_find_vrf(stcb->asoc.vrf_id);
2495 if (addr_locked == SCTP_ADDR_NOT_LOCKED)
2496 SCTP_IPI_ADDR_RUNLOCK();
2499 LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
2500 if (stcb->asoc.loopback_scope == 0 &&
2501 SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) {
2502 /* Skip if loopback_scope not set */
2505 LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
2506 switch (sctp_ifa->address.sa.sa_family) {
2509 if (stcb->asoc.ipv4_addr_legal) {
2510 struct sockaddr_in *sin;
2512 sin = (struct sockaddr_in *)&sctp_ifa->address.sa;
2513 if (sin->sin_addr.s_addr == 0) {
2514 /* skip unspecifed addresses */
2517 if (stcb->asoc.ipv4_local_scope == 0 &&
2518 IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))
2521 if (sctp_is_addr_restricted(stcb, sctp_ifa) &&
2522 (!sctp_is_addr_pending(stcb, sctp_ifa)))
2525 * found a valid local v4 address to
2528 if (addr_locked == SCTP_ADDR_NOT_LOCKED)
2529 SCTP_IPI_ADDR_RUNLOCK();
2530 return (&sctp_ifa->address.sa);
2536 if (stcb->asoc.ipv6_addr_legal) {
2537 struct sockaddr_in6 *sin6;
2539 if (sctp_ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
2542 sin6 = (struct sockaddr_in6 *)&sctp_ifa->address.sa;
2543 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
2545 * we skip unspecifed
2550 if (stcb->asoc.local_scope == 0 &&
2551 IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
2553 if (stcb->asoc.site_scope == 0 &&
2554 IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))
2557 if (sctp_is_addr_restricted(stcb, sctp_ifa) &&
2558 (!sctp_is_addr_pending(stcb, sctp_ifa)))
2561 * found a valid local v6 address to
2564 if (addr_locked == SCTP_ADDR_NOT_LOCKED)
2565 SCTP_IPI_ADDR_RUNLOCK();
2566 return (&sctp_ifa->address.sa);
2575 /* no valid addresses found */
2576 if (addr_locked == SCTP_ADDR_NOT_LOCKED)
2577 SCTP_IPI_ADDR_RUNLOCK();
2581 static struct sockaddr *
2582 sctp_find_valid_localaddr_ep(struct sctp_tcb *stcb)
2584 struct sctp_laddr *laddr;
2586 LIST_FOREACH(laddr, &stcb->sctp_ep->sctp_addr_list, sctp_nxt_addr) {
2587 if (laddr->ifa == NULL) {
2590 /* is the address restricted ? */
2591 if (sctp_is_addr_restricted(stcb, laddr->ifa) &&
2592 (!sctp_is_addr_pending(stcb, laddr->ifa)))
2595 /* found a valid local address to use */
2596 return (&laddr->ifa->address.sa);
2598 /* no valid addresses found */
2603 * builds an ASCONF chunk from queued ASCONF params.
2604 * returns NULL on error (no mbuf, no ASCONF params queued, etc).
2607 sctp_compose_asconf(struct sctp_tcb *stcb, int *retlen, int addr_locked)
2609 struct mbuf *m_asconf, *m_asconf_chk;
2610 struct sctp_asconf_addr *aa;
2611 struct sctp_asconf_chunk *acp;
2612 struct sctp_asconf_paramhdr *aph;
2613 struct sctp_asconf_addr_param *aap;
2615 uint32_t correlation_id = 1; /* 0 is reserved... */
2616 caddr_t ptr, lookup_ptr;
2617 uint8_t lookup_used = 0;
2619 /* are there any asconf params to send? */
2620 TAILQ_FOREACH(aa, &stcb->asoc.asconf_queue, next) {
2628 * get a chunk header mbuf and a cluster for the asconf params since
2629 * it's simpler to fill in the asconf chunk header lookup address on
2632 m_asconf_chk = sctp_get_mbuf_for_msg(sizeof(struct sctp_asconf_chunk), 0, M_DONTWAIT, 1, MT_DATA);
2633 if (m_asconf_chk == NULL) {
2635 SCTPDBG(SCTP_DEBUG_ASCONF1,
2636 "compose_asconf: couldn't get chunk mbuf!\n");
2639 m_asconf = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_DONTWAIT, 1, MT_DATA);
2640 if (m_asconf == NULL) {
2642 SCTPDBG(SCTP_DEBUG_ASCONF1,
2643 "compose_asconf: couldn't get mbuf!\n");
2644 sctp_m_freem(m_asconf_chk);
2647 SCTP_BUF_LEN(m_asconf_chk) = sizeof(struct sctp_asconf_chunk);
2648 SCTP_BUF_LEN(m_asconf) = 0;
2649 acp = mtod(m_asconf_chk, struct sctp_asconf_chunk *);
2650 bzero(acp, sizeof(struct sctp_asconf_chunk));
2651 /* save pointers to lookup address and asconf params */
2652 lookup_ptr = (caddr_t)(acp + 1); /* after the header */
2653 ptr = mtod(m_asconf, caddr_t); /* beginning of cluster */
2655 /* fill in chunk header info */
2656 acp->ch.chunk_type = SCTP_ASCONF;
2657 acp->ch.chunk_flags = 0;
2658 acp->serial_number = htonl(stcb->asoc.asconf_seq_out);
2659 stcb->asoc.asconf_seq_out++;
2661 /* add parameters... up to smallest MTU allowed */
2662 TAILQ_FOREACH(aa, &stcb->asoc.asconf_queue, next) {
2665 /* get the parameter length */
2666 p_length = SCTP_SIZE32(aa->ap.aph.ph.param_length);
2667 /* will it fit in current chunk? */
2668 if (SCTP_BUF_LEN(m_asconf) + p_length > stcb->asoc.smallest_mtu) {
2669 /* won't fit, so we're done with this chunk */
2672 /* assign (and store) a correlation id */
2673 aa->ap.aph.correlation_id = correlation_id++;
2676 * fill in address if we're doing a delete this is a simple
2677 * way for us to fill in the correlation address, which
2678 * should only be used by the peer if we're deleting our
2679 * source address and adding a new address (e.g. renumbering
2682 if (lookup_used == 0 &&
2683 (aa->special_del == 0) &&
2684 aa->ap.aph.ph.param_type == SCTP_DEL_IP_ADDRESS) {
2685 struct sctp_ipv6addr_param *lookup;
2686 uint16_t p_size, addr_size;
2688 lookup = (struct sctp_ipv6addr_param *)lookup_ptr;
2689 lookup->ph.param_type =
2690 htons(aa->ap.addrp.ph.param_type);
2691 if (aa->ap.addrp.ph.param_type == SCTP_IPV6_ADDRESS) {
2692 /* copy IPv6 address */
2693 p_size = sizeof(struct sctp_ipv6addr_param);
2694 addr_size = sizeof(struct in6_addr);
2696 /* copy IPv4 address */
2697 p_size = sizeof(struct sctp_ipv4addr_param);
2698 addr_size = sizeof(struct in_addr);
2700 lookup->ph.param_length = htons(SCTP_SIZE32(p_size));
2701 memcpy(lookup->addr, &aa->ap.addrp.addr, addr_size);
2702 SCTP_BUF_LEN(m_asconf_chk) += SCTP_SIZE32(p_size);
2705 /* copy into current space */
2706 memcpy(ptr, &aa->ap, p_length);
2708 /* network elements and update lengths */
2709 aph = (struct sctp_asconf_paramhdr *)ptr;
2710 aap = (struct sctp_asconf_addr_param *)ptr;
2711 /* correlation_id is transparent to peer, no htonl needed */
2712 aph->ph.param_type = htons(aph->ph.param_type);
2713 aph->ph.param_length = htons(aph->ph.param_length);
2714 aap->addrp.ph.param_type = htons(aap->addrp.ph.param_type);
2715 aap->addrp.ph.param_length = htons(aap->addrp.ph.param_length);
2717 SCTP_BUF_LEN(m_asconf) += SCTP_SIZE32(p_length);
2718 ptr += SCTP_SIZE32(p_length);
2721 * these params are removed off the pending list upon
2722 * getting an ASCONF-ACK back from the peer, just set flag
2726 /* check to see if the lookup addr has been populated yet */
2727 if (lookup_used == 0) {
2728 /* NOTE: if the address param is optional, can skip this... */
2729 /* add any valid (existing) address... */
2730 struct sctp_ipv6addr_param *lookup;
2731 uint16_t p_size, addr_size;
2732 struct sockaddr *found_addr;
2735 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL)
2736 found_addr = sctp_find_valid_localaddr(stcb,
2739 found_addr = sctp_find_valid_localaddr_ep(stcb);
2741 lookup = (struct sctp_ipv6addr_param *)lookup_ptr;
2742 if (found_addr != NULL) {
2743 switch (found_addr->sa_family) {
2746 /* copy IPv6 address */
2747 lookup->ph.param_type =
2748 htons(SCTP_IPV6_ADDRESS);
2749 p_size = sizeof(struct sctp_ipv6addr_param);
2750 addr_size = sizeof(struct in6_addr);
2751 addr_ptr = (caddr_t)&((struct sockaddr_in6 *)
2752 found_addr)->sin6_addr;
2757 /* copy IPv4 address */
2758 lookup->ph.param_type =
2759 htons(SCTP_IPV4_ADDRESS);
2760 p_size = sizeof(struct sctp_ipv4addr_param);
2761 addr_size = sizeof(struct in_addr);
2762 addr_ptr = (caddr_t)&((struct sockaddr_in *)
2763 found_addr)->sin_addr;
2772 lookup->ph.param_length = htons(SCTP_SIZE32(p_size));
2773 memcpy(lookup->addr, addr_ptr, addr_size);
2774 SCTP_BUF_LEN(m_asconf_chk) += SCTP_SIZE32(p_size);
2776 /* uh oh... don't have any address?? */
2777 SCTPDBG(SCTP_DEBUG_ASCONF1,
2778 "compose_asconf: no lookup addr!\n");
2779 /* XXX for now, we send a IPv4 address of 0.0.0.0 */
2780 lookup->ph.param_type = htons(SCTP_IPV4_ADDRESS);
2781 lookup->ph.param_length = htons(SCTP_SIZE32(sizeof(struct sctp_ipv4addr_param)));
2782 bzero(lookup->addr, sizeof(struct in_addr));
2783 SCTP_BUF_LEN(m_asconf_chk) += SCTP_SIZE32(sizeof(struct sctp_ipv4addr_param));
2786 /* chain it all together */
2787 SCTP_BUF_NEXT(m_asconf_chk) = m_asconf;
2788 *retlen = SCTP_BUF_LEN(m_asconf_chk) + SCTP_BUF_LEN(m_asconf);
2789 acp->ch.chunk_length = ntohs(*retlen);
2791 return (m_asconf_chk);
2795 * section to handle address changes before an association is up eg. changes
2796 * during INIT/INIT-ACK/COOKIE-ECHO handshake
2800 * processes the (local) addresses in the INIT-ACK chunk
2803 sctp_process_initack_addresses(struct sctp_tcb *stcb, struct mbuf *m,
2804 unsigned int offset, unsigned int length)
2806 struct sctp_paramhdr tmp_param, *ph;
2807 uint16_t plen, ptype;
2808 struct sctp_ifa *sctp_ifa;
2811 struct sctp_ipv6addr_param addr6_store;
2812 struct sockaddr_in6 sin6;
2816 struct sctp_ipv4addr_param addr4_store;
2817 struct sockaddr_in sin;
2820 struct sockaddr *sa;
2823 SCTPDBG(SCTP_DEBUG_ASCONF2, "processing init-ack addresses\n");
2824 if (stcb == NULL) /* Un-needed check for SA */
2827 /* convert to upper bound */
2830 if ((offset + sizeof(struct sctp_paramhdr)) > length) {
2833 /* init the addresses */
2835 bzero(&sin6, sizeof(sin6));
2836 sin6.sin6_family = AF_INET6;
2837 sin6.sin6_len = sizeof(sin6);
2838 sin6.sin6_port = stcb->rport;
2842 bzero(&sin, sizeof(sin));
2843 sin.sin_family = AF_INET;
2844 sin.sin_len = sizeof(sin);
2845 sin.sin_port = stcb->rport;
2848 /* go through the addresses in the init-ack */
2849 ph = (struct sctp_paramhdr *)
2850 sctp_m_getptr(m, offset, sizeof(struct sctp_paramhdr),
2851 (uint8_t *) & tmp_param);
2852 while (ph != NULL) {
2853 ptype = ntohs(ph->param_type);
2854 plen = ntohs(ph->param_length);
2857 case SCTP_IPV6_ADDRESS:
2859 struct sctp_ipv6addr_param *a6p;
2861 /* get the entire IPv6 address param */
2862 a6p = (struct sctp_ipv6addr_param *)
2863 sctp_m_getptr(m, offset,
2864 sizeof(struct sctp_ipv6addr_param),
2865 (uint8_t *) & addr6_store);
2866 if (plen != sizeof(struct sctp_ipv6addr_param) ||
2870 memcpy(&sin6.sin6_addr, a6p->addr,
2871 sizeof(struct in6_addr));
2872 sa = (struct sockaddr *)&sin6;
2877 case SCTP_IPV4_ADDRESS:
2879 struct sctp_ipv4addr_param *a4p;
2881 /* get the entire IPv4 address param */
2882 a4p = (struct sctp_ipv4addr_param *)sctp_m_getptr(m, offset,
2883 sizeof(struct sctp_ipv4addr_param),
2884 (uint8_t *) & addr4_store);
2885 if (plen != sizeof(struct sctp_ipv4addr_param) ||
2889 sin.sin_addr.s_addr = a4p->addr;
2890 sa = (struct sockaddr *)&sin;
2898 /* see if this address really (still) exists */
2900 vrf_id = stcb->asoc.vrf_id;
2902 vrf_id = SCTP_DEFAULT_VRFID;
2904 sctp_ifa = sctp_find_ifa_by_addr(sa, vrf_id,
2905 SCTP_ADDR_NOT_LOCKED);
2906 if (sctp_ifa == NULL) {
2907 /* address doesn't exist anymore */
2910 /* are ASCONFs allowed ? */
2911 if ((sctp_is_feature_on(stcb->sctp_ep,
2912 SCTP_PCB_FLAGS_DO_ASCONF)) &&
2913 stcb->asoc.peer_supports_asconf) {
2914 /* queue an ASCONF DEL_IP_ADDRESS */
2915 status = sctp_asconf_queue_sa_delete(stcb, sa);
2917 * if queued ok, and in correct state, send
2921 SCTP_GET_STATE(&stcb->asoc) ==
2923 #ifdef SCTP_TIMER_BASED_ASCONF
2924 sctp_timer_start(SCTP_TIMER_TYPE_ASCONF,
2925 stcb->sctp_ep, stcb,
2926 stcb->asoc.primary_destination);
2928 sctp_send_asconf(stcb, NULL, SCTP_ADDR_NOT_LOCKED);
2935 * Sanity check: Make sure the length isn't 0, otherwise
2936 * we'll be stuck in this loop for a long time...
2938 if (SCTP_SIZE32(plen) == 0) {
2939 SCTP_PRINTF("process_initack_addrs: bad len (%d) type=%xh\n",
2943 /* get next parameter */
2944 offset += SCTP_SIZE32(plen);
2945 if ((offset + sizeof(struct sctp_paramhdr)) > length)
2947 ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset,
2948 sizeof(struct sctp_paramhdr), (uint8_t *) & tmp_param);
2952 /* FIX ME: need to verify return result for v6 address type if v6 disabled */
2954 * checks to see if a specific address is in the initack address list returns
2955 * 1 if found, 0 if not
2958 sctp_addr_in_initack(struct mbuf *m, uint32_t offset, uint32_t length, struct sockaddr *sa)
2960 struct sctp_paramhdr tmp_param, *ph;
2961 uint16_t plen, ptype;
2964 struct sockaddr_in *sin;
2965 struct sctp_ipv4addr_param *a4p;
2966 struct sctp_ipv6addr_param addr4_store;
2970 struct sockaddr_in6 *sin6;
2971 struct sctp_ipv6addr_param *a6p;
2972 struct sctp_ipv6addr_param addr6_store;
2973 struct sockaddr_in6 sin6_tmp;
2977 switch (sa->sa_family) {
2990 SCTPDBG(SCTP_DEBUG_ASCONF2, "find_initack_addr: starting search for ");
2991 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, sa);
2992 /* convert to upper bound */
2995 if ((offset + sizeof(struct sctp_paramhdr)) > length) {
2996 SCTPDBG(SCTP_DEBUG_ASCONF1,
2997 "find_initack_addr: invalid offset?\n");
3000 /* go through the addresses in the init-ack */
3001 ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset,
3002 sizeof(struct sctp_paramhdr), (uint8_t *) & tmp_param);
3003 while (ph != NULL) {
3004 ptype = ntohs(ph->param_type);
3005 plen = ntohs(ph->param_length);
3008 case SCTP_IPV6_ADDRESS:
3009 if (sa->sa_family == AF_INET6) {
3010 /* get the entire IPv6 address param */
3011 if (plen != sizeof(struct sctp_ipv6addr_param)) {
3014 /* get the entire IPv6 address param */
3015 a6p = (struct sctp_ipv6addr_param *)
3016 sctp_m_getptr(m, offset,
3017 sizeof(struct sctp_ipv6addr_param),
3018 (uint8_t *) & addr6_store);
3022 sin6 = (struct sockaddr_in6 *)sa;
3023 if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr)) {
3024 /* create a copy and clear scope */
3025 memcpy(&sin6_tmp, sin6,
3026 sizeof(struct sockaddr_in6));
3028 in6_clearscope(&sin6->sin6_addr);
3030 if (memcmp(&sin6->sin6_addr, a6p->addr,
3031 sizeof(struct in6_addr)) == 0) {
3039 case SCTP_IPV4_ADDRESS:
3040 if (sa->sa_family == AF_INET) {
3041 if (plen != sizeof(struct sctp_ipv4addr_param)) {
3044 /* get the entire IPv4 address param */
3045 a4p = (struct sctp_ipv4addr_param *)
3046 sctp_m_getptr(m, offset,
3047 sizeof(struct sctp_ipv4addr_param),
3048 (uint8_t *) & addr4_store);
3052 sin = (struct sockaddr_in *)sa;
3053 if (sin->sin_addr.s_addr == a4p->addr) {
3063 /* get next parameter */
3064 offset += SCTP_SIZE32(plen);
3065 if (offset + sizeof(struct sctp_paramhdr) > length) {
3068 ph = (struct sctp_paramhdr *)
3069 sctp_m_getptr(m, offset, sizeof(struct sctp_paramhdr),
3070 (uint8_t *) & tmp_param);
3077 * makes sure that the current endpoint local addr list is consistent with
3078 * the new association (eg. subset bound, asconf allowed) adds addresses as
3082 sctp_check_address_list_ep(struct sctp_tcb *stcb, struct mbuf *m, int offset,
3083 int length, struct sockaddr *init_addr)
3085 struct sctp_laddr *laddr;
3087 /* go through the endpoint list */
3088 LIST_FOREACH(laddr, &stcb->sctp_ep->sctp_addr_list, sctp_nxt_addr) {
3089 /* be paranoid and validate the laddr */
3090 if (laddr->ifa == NULL) {
3091 SCTPDBG(SCTP_DEBUG_ASCONF1,
3092 "check_addr_list_ep: laddr->ifa is NULL");
3095 if (laddr->ifa == NULL) {
3096 SCTPDBG(SCTP_DEBUG_ASCONF1, "check_addr_list_ep: laddr->ifa->ifa_addr is NULL");
3099 /* do i have it implicitly? */
3100 if (sctp_cmpaddr(&laddr->ifa->address.sa, init_addr)) {
3103 /* check to see if in the init-ack */
3104 if (!sctp_addr_in_initack(m, offset, length, &laddr->ifa->address.sa)) {
3106 sctp_addr_mgmt_assoc(stcb->sctp_ep, stcb, laddr->ifa,
3107 SCTP_ADD_IP_ADDRESS, SCTP_ADDR_NOT_LOCKED);
3113 * makes sure that the current kernel address list is consistent with the new
3114 * association (with all addrs bound) adds addresses as necessary
3117 sctp_check_address_list_all(struct sctp_tcb *stcb, struct mbuf *m, int offset,
3118 int length, struct sockaddr *init_addr,
3119 uint16_t local_scope, uint16_t site_scope,
3120 uint16_t ipv4_scope, uint16_t loopback_scope)
3122 struct sctp_vrf *vrf = NULL;
3123 struct sctp_ifn *sctp_ifn;
3124 struct sctp_ifa *sctp_ifa;
3128 struct sockaddr_in *sin;
3132 struct sockaddr_in6 *sin6;
3137 vrf_id = stcb->asoc.vrf_id;
3141 SCTP_IPI_ADDR_RLOCK();
3142 vrf = sctp_find_vrf(vrf_id);
3144 SCTP_IPI_ADDR_RUNLOCK();
3147 /* go through all our known interfaces */
3148 LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
3149 if (loopback_scope == 0 && SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) {
3150 /* skip loopback interface */
3153 /* go through each interface address */
3154 LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
3155 /* do i have it implicitly? */
3156 if (sctp_cmpaddr(&sctp_ifa->address.sa, init_addr)) {
3159 switch (sctp_ifa->address.sa.sa_family) {
3162 sin = (struct sockaddr_in *)&sctp_ifa->address.sin;
3163 if ((ipv4_scope == 0) &&
3164 (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
3165 /* private address not in scope */
3172 sin6 = (struct sockaddr_in6 *)&sctp_ifa->address.sin6;
3173 if ((local_scope == 0) &&
3174 (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))) {
3177 if ((site_scope == 0) &&
3178 (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) {
3186 /* check to see if in the init-ack */
3187 if (!sctp_addr_in_initack(m, offset, length, &sctp_ifa->address.sa)) {
3189 sctp_addr_mgmt_assoc(stcb->sctp_ep, stcb,
3190 sctp_ifa, SCTP_ADD_IP_ADDRESS,
3193 } /* end foreach ifa */
3194 } /* end foreach ifn */
3195 SCTP_IPI_ADDR_RUNLOCK();
3199 * validates an init-ack chunk (from a cookie-echo) with current addresses
3200 * adds addresses from the init-ack into our local address list, if needed
3201 * queues asconf adds/deletes addresses as needed and makes appropriate list
3202 * changes for source address selection m, offset: points to the start of the
3203 * address list in an init-ack chunk length: total length of the address
3204 * params only init_addr: address where my INIT-ACK was sent from
3207 sctp_check_address_list(struct sctp_tcb *stcb, struct mbuf *m, int offset,
3208 int length, struct sockaddr *init_addr,
3209 uint16_t local_scope, uint16_t site_scope,
3210 uint16_t ipv4_scope, uint16_t loopback_scope)
3212 /* process the local addresses in the initack */
3213 sctp_process_initack_addresses(stcb, m, offset, length);
3215 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
3216 /* bound all case */
3217 sctp_check_address_list_all(stcb, m, offset, length, init_addr,
3218 local_scope, site_scope, ipv4_scope, loopback_scope);
3220 /* subset bound case */
3221 if (sctp_is_feature_on(stcb->sctp_ep,
3222 SCTP_PCB_FLAGS_DO_ASCONF)) {
3223 /* asconf's allowed */
3224 sctp_check_address_list_ep(stcb, m, offset, length,
3227 /* else, no asconfs allowed, so what we sent is what we get */
3232 * sctp_bindx() support
3235 sctp_addr_mgmt_ep_sa(struct sctp_inpcb *inp, struct sockaddr *sa,
3236 uint32_t type, uint32_t vrf_id, struct sctp_ifa *sctp_ifap)
3238 struct sctp_ifa *ifa;
3239 struct sctp_laddr *laddr, *nladdr;
3241 if (sa->sa_len == 0) {
3242 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, EINVAL);
3247 } else if (type == SCTP_ADD_IP_ADDRESS) {
3248 /* For an add the address MUST be on the system */
3249 ifa = sctp_find_ifa_by_addr(sa, vrf_id, SCTP_ADDR_NOT_LOCKED);
3250 } else if (type == SCTP_DEL_IP_ADDRESS) {
3251 /* For a delete we need to find it in the inp */
3252 ifa = sctp_find_ifa_in_ep(inp, sa, SCTP_ADDR_NOT_LOCKED);
3257 if (type == SCTP_ADD_IP_ADDRESS) {
3258 sctp_add_local_addr_ep(inp, ifa, type);
3259 } else if (type == SCTP_DEL_IP_ADDRESS) {
3260 if (inp->laddr_count < 2) {
3261 /* can't delete the last local address */
3262 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, EINVAL);
3265 LIST_FOREACH(laddr, &inp->sctp_addr_list,
3267 if (ifa == laddr->ifa) {
3268 /* Mark in the delete */
3269 laddr->action = type;
3273 if (LIST_EMPTY(&inp->sctp_asoc_list)) {
3275 * There is no need to start the iterator if the inp
3276 * has no associations.
3278 if (type == SCTP_DEL_IP_ADDRESS) {
3279 LIST_FOREACH_SAFE(laddr, &inp->sctp_addr_list, sctp_nxt_addr, nladdr) {
3280 if (laddr->ifa == ifa) {
3281 sctp_del_local_addr_ep(inp, ifa);
3286 struct sctp_asconf_iterator *asc;
3287 struct sctp_laddr *wi;
3289 SCTP_MALLOC(asc, struct sctp_asconf_iterator *,
3290 sizeof(struct sctp_asconf_iterator),
3293 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, ENOMEM);
3296 wi = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_laddr), struct sctp_laddr);
3298 SCTP_FREE(asc, SCTP_M_ASC_IT);
3299 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, ENOMEM);
3302 LIST_INIT(&asc->list_of_work);
3304 SCTP_INCR_LADDR_COUNT();
3307 atomic_add_int(&ifa->refcount, 1);
3308 LIST_INSERT_HEAD(&asc->list_of_work, wi, sctp_nxt_addr);
3309 (void)sctp_initiate_iterator(sctp_asconf_iterator_ep,
3310 sctp_asconf_iterator_stcb,
3311 sctp_asconf_iterator_ep_end,
3313 SCTP_PCB_ANY_FEATURES,
3314 SCTP_ASOC_ANY_STATE,
3316 sctp_asconf_iterator_end, inp, 0);
3320 /* invalid address! */
3321 SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_ASCONF, EADDRNOTAVAIL);
3322 return (EADDRNOTAVAIL);
3327 sctp_asconf_send_nat_state_update(struct sctp_tcb *stcb,
3328 struct sctp_nets *net)
3330 struct sctp_asconf_addr *aa;
3331 struct sctp_ifa *sctp_ifap;
3332 struct sctp_asconf_tag_param *vtag;
3335 struct sockaddr_in *to;
3339 struct sockaddr_in6 *to6;
3343 SCTPDBG(SCTP_DEBUG_ASCONF1, "sctp_asconf_send_nat_state_update: Missing net\n");
3347 SCTPDBG(SCTP_DEBUG_ASCONF1, "sctp_asconf_send_nat_state_update: Missing stcb\n");
3351 * Need to have in the asconf: - vtagparam(my_vtag/peer_vtag) -
3352 * add(0.0.0.0) - del(0.0.0.0) - Any global addresses add(addr)
3354 SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa),
3357 /* didn't get memory */
3358 SCTPDBG(SCTP_DEBUG_ASCONF1,
3359 "sctp_asconf_send_nat_state_update: failed to get memory!\n");
3362 aa->special_del = 0;
3363 /* fill in asconf address parameter fields */
3364 /* top level elements are "networked" during send */
3366 aa->sent = 0; /* clear sent flag */
3367 vtag = (struct sctp_asconf_tag_param *)&aa->ap.aph;
3368 vtag->aph.ph.param_type = SCTP_NAT_VTAGS;
3369 vtag->aph.ph.param_length = sizeof(struct sctp_asconf_tag_param);
3370 vtag->local_vtag = htonl(stcb->asoc.my_vtag);
3371 vtag->remote_vtag = htonl(stcb->asoc.peer_vtag);
3372 TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
3374 SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa),
3377 /* didn't get memory */
3378 SCTPDBG(SCTP_DEBUG_ASCONF1,
3379 "sctp_asconf_send_nat_state_update: failed to get memory!\n");
3382 memset(aa, 0, sizeof(struct sctp_asconf_addr));
3383 /* fill in asconf address parameter fields */
3385 switch (net->ro._l_addr.sa.sa_family) {
3388 aa->ap.aph.ph.param_type = SCTP_ADD_IP_ADDRESS;
3389 aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_addrv4_param);
3390 aa->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
3391 aa->ap.addrp.ph.param_length = sizeof(struct sctp_ipv4addr_param);
3392 /* No need to add an address, we are using 0.0.0.0 */
3393 TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
3398 aa->ap.aph.ph.param_type = SCTP_ADD_IP_ADDRESS;
3399 aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_addr_param);
3400 aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
3401 aa->ap.addrp.ph.param_length = sizeof(struct sctp_ipv6addr_param);
3402 /* No need to add an address, we are using 0.0.0.0 */
3403 TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
3407 SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa),
3410 /* didn't get memory */
3411 SCTPDBG(SCTP_DEBUG_ASCONF1,
3412 "sctp_asconf_send_nat_state_update: failed to get memory!\n");
3415 memset(aa, 0, sizeof(struct sctp_asconf_addr));
3416 /* fill in asconf address parameter fields */
3418 switch (net->ro._l_addr.sa.sa_family) {
3421 aa->ap.aph.ph.param_type = SCTP_ADD_IP_ADDRESS;
3422 aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_addrv4_param);
3423 aa->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
3424 aa->ap.addrp.ph.param_length = sizeof(struct sctp_ipv4addr_param);
3425 /* No need to add an address, we are using 0.0.0.0 */
3426 TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
3431 aa->ap.aph.ph.param_type = SCTP_DEL_IP_ADDRESS;
3432 aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_addr_param);
3433 aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
3434 aa->ap.addrp.ph.param_length = sizeof(struct sctp_ipv6addr_param);
3435 /* No need to add an address, we are using 0.0.0.0 */
3436 TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
3440 /* Now we must hunt the addresses and add all global addresses */
3441 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
3442 struct sctp_vrf *vrf = NULL;
3443 struct sctp_ifn *sctp_ifnp;
3446 vrf_id = stcb->sctp_ep->def_vrf_id;
3447 vrf = sctp_find_vrf(vrf_id);
3451 SCTP_IPI_ADDR_RLOCK();
3452 LIST_FOREACH(sctp_ifnp, &vrf->ifnlist, next_ifn) {
3453 LIST_FOREACH(sctp_ifap, &sctp_ifnp->ifalist, next_ifa) {
3454 switch (sctp_ifap->address.sa.sa_family) {
3457 to = &sctp_ifap->address.sin;
3458 if (IN4_ISPRIVATE_ADDRESS(&to->sin_addr)) {
3461 if (IN4_ISLOOPBACK_ADDRESS(&to->sin_addr)) {
3468 to6 = &sctp_ifap->address.sin6;
3469 if (IN6_IS_ADDR_LOOPBACK(&to6->sin6_addr)) {
3472 if (IN6_IS_ADDR_LINKLOCAL(&to6->sin6_addr)) {
3480 sctp_asconf_queue_mgmt(stcb, sctp_ifap, SCTP_ADD_IP_ADDRESS);
3483 SCTP_IPI_ADDR_RUNLOCK();
3485 struct sctp_laddr *laddr;
3487 LIST_FOREACH(laddr, &stcb->sctp_ep->sctp_addr_list, sctp_nxt_addr) {
3488 if (laddr->ifa == NULL) {
3491 if (laddr->ifa->localifa_flags & SCTP_BEING_DELETED)
3493 * Address being deleted by the system, dont
3497 if (laddr->action == SCTP_DEL_IP_ADDRESS) {
3499 * Address being deleted on this ep don't
3504 sctp_ifap = laddr->ifa;
3505 switch (sctp_ifap->address.sa.sa_family) {
3508 to = &sctp_ifap->address.sin;
3509 if (IN4_ISPRIVATE_ADDRESS(&to->sin_addr)) {
3512 if (IN4_ISLOOPBACK_ADDRESS(&to->sin_addr)) {
3519 to6 = &sctp_ifap->address.sin6;
3520 if (IN6_IS_ADDR_LOOPBACK(&to6->sin6_addr)) {
3523 if (IN6_IS_ADDR_LINKLOCAL(&to6->sin6_addr)) {
3531 sctp_asconf_queue_mgmt(stcb, sctp_ifap, SCTP_ADD_IP_ADDRESS);
3535 /* Now we must send the asconf into the queue */
3536 sctp_send_asconf(stcb, net, SCTP_ADDR_NOT_LOCKED);