]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/netinet/sctp_asconf.c
Merge ^/head r352537 through r352586.
[FreeBSD/FreeBSD.git] / sys / netinet / sctp_asconf.c
1 /*-
2  * SPDX-License-Identifier: BSD-3-Clause
3  *
4  * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
5  * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
6  * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * a) Redistributions of source code must retain the above copyright notice,
12  *    this list of conditions and the following disclaimer.
13  *
14  * b) Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in
16  *    the documentation and/or other materials provided with the distribution.
17  *
18  * c) Neither the name of Cisco Systems, Inc. nor the names of its
19  *    contributors may be used to endorse or promote products derived
20  *    from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
24  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32  * THE POSSIBILITY OF SUCH DAMAGE.
33  */
34
35 #include <sys/cdefs.h>
36 __FBSDID("$FreeBSD$");
37
38 #include <netinet/sctp_os.h>
39 #include <netinet/sctp_var.h>
40 #include <netinet/sctp_sysctl.h>
41 #include <netinet/sctp_pcb.h>
42 #include <netinet/sctp_header.h>
43 #include <netinet/sctputil.h>
44 #include <netinet/sctp_output.h>
45 #include <netinet/sctp_asconf.h>
46 #include <netinet/sctp_timer.h>
47
48 /*
49  * debug flags:
50  * SCTP_DEBUG_ASCONF1: protocol info, general info and errors
51  * SCTP_DEBUG_ASCONF2: detailed info
52  */
53
54
55 /*
56  * RFC 5061
57  *
58  * An ASCONF parameter queue exists per asoc which holds the pending address
59  * operations.  Lists are updated upon receipt of ASCONF-ACK.
60  *
61  * A restricted_addrs list exists per assoc to hold local addresses that are
62  * not (yet) usable by the assoc as a source address.  These addresses are
63  * either pending an ASCONF operation (and exist on the ASCONF parameter
64  * queue), or they are permanently restricted (the peer has returned an
65  * ERROR indication to an ASCONF(ADD), or the peer does not support ASCONF).
66  *
67  * Deleted addresses are always immediately removed from the lists as they will
68  * (shortly) no longer exist in the kernel.  We send ASCONFs as a courtesy,
69  * only if allowed.
70  */
71
72 /*
73  * ASCONF parameter processing.
74  * response_required: set if a reply is required (eg. SUCCESS_REPORT).
75  * returns a mbuf to an "error" response parameter or NULL/"success" if ok.
76  * FIX: allocating this many mbufs on the fly is pretty inefficient...
77  */
78 static struct mbuf *
79 sctp_asconf_success_response(uint32_t id)
80 {
81         struct mbuf *m_reply = NULL;
82         struct sctp_asconf_paramhdr *aph;
83
84         m_reply = sctp_get_mbuf_for_msg(sizeof(struct sctp_asconf_paramhdr),
85             0, M_NOWAIT, 1, MT_DATA);
86         if (m_reply == NULL) {
87                 SCTPDBG(SCTP_DEBUG_ASCONF1,
88                     "asconf_success_response: couldn't get mbuf!\n");
89                 return (NULL);
90         }
91         aph = mtod(m_reply, struct sctp_asconf_paramhdr *);
92         aph->correlation_id = id;
93         aph->ph.param_type = htons(SCTP_SUCCESS_REPORT);
94         aph->ph.param_length = sizeof(struct sctp_asconf_paramhdr);
95         SCTP_BUF_LEN(m_reply) = aph->ph.param_length;
96         aph->ph.param_length = htons(aph->ph.param_length);
97
98         return (m_reply);
99 }
100
101 static struct mbuf *
102 sctp_asconf_error_response(uint32_t id, uint16_t cause, uint8_t *error_tlv,
103     uint16_t tlv_length)
104 {
105         struct mbuf *m_reply = NULL;
106         struct sctp_asconf_paramhdr *aph;
107         struct sctp_error_cause *error;
108         uint8_t *tlv;
109
110         m_reply = sctp_get_mbuf_for_msg((sizeof(struct sctp_asconf_paramhdr) +
111             tlv_length +
112             sizeof(struct sctp_error_cause)),
113             0, M_NOWAIT, 1, MT_DATA);
114         if (m_reply == NULL) {
115                 SCTPDBG(SCTP_DEBUG_ASCONF1,
116                     "asconf_error_response: couldn't get mbuf!\n");
117                 return (NULL);
118         }
119         aph = mtod(m_reply, struct sctp_asconf_paramhdr *);
120         error = (struct sctp_error_cause *)(aph + 1);
121
122         aph->correlation_id = id;
123         aph->ph.param_type = htons(SCTP_ERROR_CAUSE_IND);
124         error->code = htons(cause);
125         error->length = tlv_length + sizeof(struct sctp_error_cause);
126         aph->ph.param_length = error->length +
127             sizeof(struct sctp_asconf_paramhdr);
128
129         if (aph->ph.param_length > MLEN) {
130                 SCTPDBG(SCTP_DEBUG_ASCONF1,
131                     "asconf_error_response: tlv_length (%xh) too big\n",
132                     tlv_length);
133                 sctp_m_freem(m_reply);  /* discard */
134                 return (NULL);
135         }
136         if (error_tlv != NULL) {
137                 tlv = (uint8_t *)(error + 1);
138                 memcpy(tlv, error_tlv, tlv_length);
139         }
140         SCTP_BUF_LEN(m_reply) = aph->ph.param_length;
141         error->length = htons(error->length);
142         aph->ph.param_length = htons(aph->ph.param_length);
143
144         return (m_reply);
145 }
146
147 static struct mbuf *
148 sctp_process_asconf_add_ip(struct sockaddr *src, struct sctp_asconf_paramhdr *aph,
149     struct sctp_tcb *stcb, int send_hb, int response_required)
150 {
151         struct sctp_nets *net;
152         struct mbuf *m_reply = NULL;
153         union sctp_sockstore store;
154         struct sctp_paramhdr *ph;
155         uint16_t param_type, aparam_length;
156 #if defined(INET) || defined(INET6)
157         uint16_t param_length;
158 #endif
159         struct sockaddr *sa;
160         int zero_address = 0;
161         int bad_address = 0;
162 #ifdef INET
163         struct sockaddr_in *sin;
164         struct sctp_ipv4addr_param *v4addr;
165 #endif
166 #ifdef INET6
167         struct sockaddr_in6 *sin6;
168         struct sctp_ipv6addr_param *v6addr;
169 #endif
170
171         aparam_length = ntohs(aph->ph.param_length);
172         ph = (struct sctp_paramhdr *)(aph + 1);
173         param_type = ntohs(ph->param_type);
174 #if defined(INET) || defined(INET6)
175         param_length = ntohs(ph->param_length);
176 #endif
177         sa = &store.sa;
178         switch (param_type) {
179 #ifdef INET
180         case SCTP_IPV4_ADDRESS:
181                 if (param_length != sizeof(struct sctp_ipv4addr_param)) {
182                         /* invalid param size */
183                         return (NULL);
184                 }
185                 v4addr = (struct sctp_ipv4addr_param *)ph;
186                 sin = &store.sin;
187                 memset(sin, 0, sizeof(*sin));
188                 sin->sin_family = AF_INET;
189                 sin->sin_len = sizeof(struct sockaddr_in);
190                 sin->sin_port = stcb->rport;
191                 sin->sin_addr.s_addr = v4addr->addr;
192                 if ((sin->sin_addr.s_addr == INADDR_BROADCAST) ||
193                     IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) {
194                         bad_address = 1;
195                 }
196                 if (sin->sin_addr.s_addr == INADDR_ANY)
197                         zero_address = 1;
198                 SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_add_ip: adding ");
199                 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
200                 break;
201 #endif
202 #ifdef INET6
203         case SCTP_IPV6_ADDRESS:
204                 if (param_length != sizeof(struct sctp_ipv6addr_param)) {
205                         /* invalid param size */
206                         return (NULL);
207                 }
208                 v6addr = (struct sctp_ipv6addr_param *)ph;
209                 sin6 = &store.sin6;
210                 memset(sin6, 0, sizeof(*sin6));
211                 sin6->sin6_family = AF_INET6;
212                 sin6->sin6_len = sizeof(struct sockaddr_in6);
213                 sin6->sin6_port = stcb->rport;
214                 memcpy((caddr_t)&sin6->sin6_addr, v6addr->addr,
215                     sizeof(struct in6_addr));
216                 if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
217                         bad_address = 1;
218                 }
219                 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
220                         zero_address = 1;
221                 SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_add_ip: adding ");
222                 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
223                 break;
224 #endif
225         default:
226                 m_reply = sctp_asconf_error_response(aph->correlation_id,
227                     SCTP_CAUSE_INVALID_PARAM, (uint8_t *)aph,
228                     aparam_length);
229                 return (m_reply);
230         }                       /* end switch */
231
232         /* if 0.0.0.0/::0, add the source address instead */
233         if (zero_address && SCTP_BASE_SYSCTL(sctp_nat_friendly)) {
234                 sa = src;
235                 SCTPDBG(SCTP_DEBUG_ASCONF1,
236                     "process_asconf_add_ip: using source addr ");
237                 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, src);
238         }
239         /* add the address */
240         if (bad_address) {
241                 m_reply = sctp_asconf_error_response(aph->correlation_id,
242                     SCTP_CAUSE_INVALID_PARAM, (uint8_t *)aph,
243                     aparam_length);
244         } else if (sctp_add_remote_addr(stcb, sa, &net, stcb->asoc.port,
245                     SCTP_DONOT_SETSCOPE,
246             SCTP_ADDR_DYNAMIC_ADDED) != 0) {
247                 SCTPDBG(SCTP_DEBUG_ASCONF1,
248                     "process_asconf_add_ip: error adding address\n");
249                 m_reply = sctp_asconf_error_response(aph->correlation_id,
250                     SCTP_CAUSE_RESOURCE_SHORTAGE, (uint8_t *)aph,
251                     aparam_length);
252         } else {
253                 /* notify upper layer */
254                 sctp_ulp_notify(SCTP_NOTIFY_ASCONF_ADD_IP, stcb, 0, sa, SCTP_SO_NOT_LOCKED);
255                 if (response_required) {
256                         m_reply =
257                             sctp_asconf_success_response(aph->correlation_id);
258                 }
259                 sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, stcb->sctp_ep, stcb, net);
260                 sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep,
261                     stcb, net);
262                 if (send_hb) {
263                         sctp_send_hb(stcb, net, SCTP_SO_NOT_LOCKED);
264                 }
265         }
266         return (m_reply);
267 }
268
269 static int
270 sctp_asconf_del_remote_addrs_except(struct sctp_tcb *stcb, struct sockaddr *src)
271 {
272         struct sctp_nets *src_net, *net;
273
274         /* make sure the source address exists as a destination net */
275         src_net = sctp_findnet(stcb, src);
276         if (src_net == NULL) {
277                 /* not found */
278                 return (-1);
279         }
280
281         /* delete all destination addresses except the source */
282         TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
283                 if (net != src_net) {
284                         /* delete this address */
285                         sctp_remove_net(stcb, net);
286                         SCTPDBG(SCTP_DEBUG_ASCONF1,
287                             "asconf_del_remote_addrs_except: deleting ");
288                         SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1,
289                             (struct sockaddr *)&net->ro._l_addr);
290                         /* notify upper layer */
291                         sctp_ulp_notify(SCTP_NOTIFY_ASCONF_DELETE_IP, stcb, 0,
292                             (struct sockaddr *)&net->ro._l_addr, SCTP_SO_NOT_LOCKED);
293                 }
294         }
295         return (0);
296 }
297
298 static struct mbuf *
299 sctp_process_asconf_delete_ip(struct sockaddr *src,
300     struct sctp_asconf_paramhdr *aph,
301     struct sctp_tcb *stcb, int response_required)
302 {
303         struct mbuf *m_reply = NULL;
304         union sctp_sockstore store;
305         struct sctp_paramhdr *ph;
306         uint16_t param_type, aparam_length;
307 #if defined(INET) || defined(INET6)
308         uint16_t param_length;
309 #endif
310         struct sockaddr *sa;
311         int zero_address = 0;
312         int result;
313 #ifdef INET
314         struct sockaddr_in *sin;
315         struct sctp_ipv4addr_param *v4addr;
316 #endif
317 #ifdef INET6
318         struct sockaddr_in6 *sin6;
319         struct sctp_ipv6addr_param *v6addr;
320 #endif
321
322         aparam_length = ntohs(aph->ph.param_length);
323         ph = (struct sctp_paramhdr *)(aph + 1);
324         param_type = ntohs(ph->param_type);
325 #if defined(INET) || defined(INET6)
326         param_length = ntohs(ph->param_length);
327 #endif
328         sa = &store.sa;
329         switch (param_type) {
330 #ifdef INET
331         case SCTP_IPV4_ADDRESS:
332                 if (param_length != sizeof(struct sctp_ipv4addr_param)) {
333                         /* invalid param size */
334                         return (NULL);
335                 }
336                 v4addr = (struct sctp_ipv4addr_param *)ph;
337                 sin = &store.sin;
338                 memset(sin, 0, sizeof(*sin));
339                 sin->sin_family = AF_INET;
340                 sin->sin_len = sizeof(struct sockaddr_in);
341                 sin->sin_port = stcb->rport;
342                 sin->sin_addr.s_addr = v4addr->addr;
343                 if (sin->sin_addr.s_addr == INADDR_ANY)
344                         zero_address = 1;
345                 SCTPDBG(SCTP_DEBUG_ASCONF1,
346                     "process_asconf_delete_ip: deleting ");
347                 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
348                 break;
349 #endif
350 #ifdef INET6
351         case SCTP_IPV6_ADDRESS:
352                 if (param_length != sizeof(struct sctp_ipv6addr_param)) {
353                         /* invalid param size */
354                         return (NULL);
355                 }
356                 v6addr = (struct sctp_ipv6addr_param *)ph;
357                 sin6 = &store.sin6;
358                 memset(sin6, 0, sizeof(*sin6));
359                 sin6->sin6_family = AF_INET6;
360                 sin6->sin6_len = sizeof(struct sockaddr_in6);
361                 sin6->sin6_port = stcb->rport;
362                 memcpy(&sin6->sin6_addr, v6addr->addr,
363                     sizeof(struct in6_addr));
364                 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
365                         zero_address = 1;
366                 SCTPDBG(SCTP_DEBUG_ASCONF1,
367                     "process_asconf_delete_ip: deleting ");
368                 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
369                 break;
370 #endif
371         default:
372                 m_reply = sctp_asconf_error_response(aph->correlation_id,
373                     SCTP_CAUSE_UNRESOLVABLE_ADDR, (uint8_t *)aph,
374                     aparam_length);
375                 return (m_reply);
376         }
377
378         /* make sure the source address is not being deleted */
379         if (sctp_cmpaddr(sa, src)) {
380                 /* trying to delete the source address! */
381                 SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_delete_ip: tried to delete source addr\n");
382                 m_reply = sctp_asconf_error_response(aph->correlation_id,
383                     SCTP_CAUSE_DELETING_SRC_ADDR, (uint8_t *)aph,
384                     aparam_length);
385                 return (m_reply);
386         }
387
388         /* if deleting 0.0.0.0/::0, delete all addresses except src addr */
389         if (zero_address && SCTP_BASE_SYSCTL(sctp_nat_friendly)) {
390                 result = sctp_asconf_del_remote_addrs_except(stcb, src);
391
392                 if (result) {
393                         /* src address did not exist? */
394                         SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_delete_ip: src addr does not exist?\n");
395                         /* what error to reply with?? */
396                         m_reply =
397                             sctp_asconf_error_response(aph->correlation_id,
398                             SCTP_CAUSE_REQUEST_REFUSED, (uint8_t *)aph,
399                             aparam_length);
400                 } else if (response_required) {
401                         m_reply =
402                             sctp_asconf_success_response(aph->correlation_id);
403                 }
404                 return (m_reply);
405         }
406
407         /* delete the address */
408         result = sctp_del_remote_addr(stcb, sa);
409         /*
410          * note if result == -2, the address doesn't exist in the asoc but
411          * since it's being deleted anyways, we just ack the delete -- but
412          * this probably means something has already gone awry
413          */
414         if (result == -1) {
415                 /* only one address in the asoc */
416                 SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_delete_ip: tried to delete last IP addr!\n");
417                 m_reply = sctp_asconf_error_response(aph->correlation_id,
418                     SCTP_CAUSE_DELETING_LAST_ADDR, (uint8_t *)aph,
419                     aparam_length);
420         } else {
421                 if (response_required) {
422                         m_reply = sctp_asconf_success_response(aph->correlation_id);
423                 }
424                 /* notify upper layer */
425                 sctp_ulp_notify(SCTP_NOTIFY_ASCONF_DELETE_IP, stcb, 0, sa, SCTP_SO_NOT_LOCKED);
426         }
427         return (m_reply);
428 }
429
430 static struct mbuf *
431 sctp_process_asconf_set_primary(struct sockaddr *src,
432     struct sctp_asconf_paramhdr *aph,
433     struct sctp_tcb *stcb, int response_required)
434 {
435         struct mbuf *m_reply = NULL;
436         union sctp_sockstore store;
437         struct sctp_paramhdr *ph;
438         uint16_t param_type, aparam_length;
439 #if defined(INET) || defined(INET6)
440         uint16_t param_length;
441 #endif
442         struct sockaddr *sa;
443         int zero_address = 0;
444 #ifdef INET
445         struct sockaddr_in *sin;
446         struct sctp_ipv4addr_param *v4addr;
447 #endif
448 #ifdef INET6
449         struct sockaddr_in6 *sin6;
450         struct sctp_ipv6addr_param *v6addr;
451 #endif
452
453         aparam_length = ntohs(aph->ph.param_length);
454         ph = (struct sctp_paramhdr *)(aph + 1);
455         param_type = ntohs(ph->param_type);
456 #if defined(INET) || defined(INET6)
457         param_length = ntohs(ph->param_length);
458 #endif
459         sa = &store.sa;
460         switch (param_type) {
461 #ifdef INET
462         case SCTP_IPV4_ADDRESS:
463                 if (param_length != sizeof(struct sctp_ipv4addr_param)) {
464                         /* invalid param size */
465                         return (NULL);
466                 }
467                 v4addr = (struct sctp_ipv4addr_param *)ph;
468                 sin = &store.sin;
469                 memset(sin, 0, sizeof(*sin));
470                 sin->sin_family = AF_INET;
471                 sin->sin_len = sizeof(struct sockaddr_in);
472                 sin->sin_addr.s_addr = v4addr->addr;
473                 if (sin->sin_addr.s_addr == INADDR_ANY)
474                         zero_address = 1;
475                 SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_set_primary: ");
476                 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
477                 break;
478 #endif
479 #ifdef INET6
480         case SCTP_IPV6_ADDRESS:
481                 if (param_length != sizeof(struct sctp_ipv6addr_param)) {
482                         /* invalid param size */
483                         return (NULL);
484                 }
485                 v6addr = (struct sctp_ipv6addr_param *)ph;
486                 sin6 = &store.sin6;
487                 memset(sin6, 0, sizeof(*sin6));
488                 sin6->sin6_family = AF_INET6;
489                 sin6->sin6_len = sizeof(struct sockaddr_in6);
490                 memcpy((caddr_t)&sin6->sin6_addr, v6addr->addr,
491                     sizeof(struct in6_addr));
492                 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
493                         zero_address = 1;
494                 SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_set_primary: ");
495                 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
496                 break;
497 #endif
498         default:
499                 m_reply = sctp_asconf_error_response(aph->correlation_id,
500                     SCTP_CAUSE_UNRESOLVABLE_ADDR, (uint8_t *)aph,
501                     aparam_length);
502                 return (m_reply);
503         }
504
505         /* if 0.0.0.0/::0, use the source address instead */
506         if (zero_address && SCTP_BASE_SYSCTL(sctp_nat_friendly)) {
507                 sa = src;
508                 SCTPDBG(SCTP_DEBUG_ASCONF1,
509                     "process_asconf_set_primary: using source addr ");
510                 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, src);
511         }
512         /* set the primary address */
513         if (sctp_set_primary_addr(stcb, sa, NULL) == 0) {
514                 SCTPDBG(SCTP_DEBUG_ASCONF1,
515                     "process_asconf_set_primary: primary address set\n");
516                 /* notify upper layer */
517                 sctp_ulp_notify(SCTP_NOTIFY_ASCONF_SET_PRIMARY, stcb, 0, sa, SCTP_SO_NOT_LOCKED);
518                 if ((stcb->asoc.primary_destination->dest_state & SCTP_ADDR_REACHABLE) &&
519                     (!(stcb->asoc.primary_destination->dest_state & SCTP_ADDR_PF)) &&
520                     (stcb->asoc.alternate)) {
521                         sctp_free_remote_addr(stcb->asoc.alternate);
522                         stcb->asoc.alternate = NULL;
523                 }
524                 if (response_required) {
525                         m_reply = sctp_asconf_success_response(aph->correlation_id);
526                 }
527                 /*
528                  * Mobility adaptation. Ideally, when the reception of SET
529                  * PRIMARY with DELETE IP ADDRESS of the previous primary
530                  * destination, unacknowledged DATA are retransmitted
531                  * immediately to the new primary destination for seamless
532                  * handover. If the destination is UNCONFIRMED and marked to
533                  * REQ_PRIM, The retransmission occur when reception of the
534                  * HEARTBEAT-ACK.  (See sctp_handle_heartbeat_ack in
535                  * sctp_input.c) Also, when change of the primary
536                  * destination, it is better that all subsequent new DATA
537                  * containing already queued DATA are transmitted to the new
538                  * primary destination. (by micchie)
539                  */
540                 if ((sctp_is_mobility_feature_on(stcb->sctp_ep,
541                     SCTP_MOBILITY_BASE) ||
542                     sctp_is_mobility_feature_on(stcb->sctp_ep,
543                     SCTP_MOBILITY_FASTHANDOFF)) &&
544                     sctp_is_mobility_feature_on(stcb->sctp_ep,
545                     SCTP_MOBILITY_PRIM_DELETED) &&
546                     (stcb->asoc.primary_destination->dest_state &
547                     SCTP_ADDR_UNCONFIRMED) == 0) {
548
549                         sctp_timer_stop(SCTP_TIMER_TYPE_PRIM_DELETED,
550                             stcb->sctp_ep, stcb, NULL,
551                             SCTP_FROM_SCTP_ASCONF + SCTP_LOC_1);
552                         if (sctp_is_mobility_feature_on(stcb->sctp_ep,
553                             SCTP_MOBILITY_FASTHANDOFF)) {
554                                 sctp_assoc_immediate_retrans(stcb,
555                                     stcb->asoc.primary_destination);
556                         }
557                         if (sctp_is_mobility_feature_on(stcb->sctp_ep,
558                             SCTP_MOBILITY_BASE)) {
559                                 sctp_move_chunks_from_net(stcb,
560                                     stcb->asoc.deleted_primary);
561                         }
562                         sctp_delete_prim_timer(stcb->sctp_ep, stcb,
563                             stcb->asoc.deleted_primary);
564                 }
565         } else {
566                 /* couldn't set the requested primary address! */
567                 SCTPDBG(SCTP_DEBUG_ASCONF1,
568                     "process_asconf_set_primary: set primary failed!\n");
569                 /* must have been an invalid address, so report */
570                 m_reply = sctp_asconf_error_response(aph->correlation_id,
571                     SCTP_CAUSE_UNRESOLVABLE_ADDR, (uint8_t *)aph,
572                     aparam_length);
573         }
574
575         return (m_reply);
576 }
577
578 /*
579  * handles an ASCONF chunk.
580  * if all parameters are processed ok, send a plain (empty) ASCONF-ACK
581  */
582 void
583 sctp_handle_asconf(struct mbuf *m, unsigned int offset,
584     struct sockaddr *src,
585     struct sctp_asconf_chunk *cp, struct sctp_tcb *stcb,
586     int first)
587 {
588         struct sctp_association *asoc;
589         uint32_t serial_num;
590         struct mbuf *n, *m_ack, *m_result, *m_tail;
591         struct sctp_asconf_ack_chunk *ack_cp;
592         struct sctp_asconf_paramhdr *aph;
593         struct sctp_ipv6addr_param *p_addr;
594         unsigned int asconf_limit, cnt;
595         int error = 0;          /* did an error occur? */
596
597         /* asconf param buffer */
598         uint8_t aparam_buf[SCTP_PARAM_BUFFER_SIZE];
599         struct sctp_asconf_ack *ack, *ack_next;
600
601         /* verify minimum length */
602         if (ntohs(cp->ch.chunk_length) < sizeof(struct sctp_asconf_chunk)) {
603                 SCTPDBG(SCTP_DEBUG_ASCONF1,
604                     "handle_asconf: chunk too small = %xh\n",
605                     ntohs(cp->ch.chunk_length));
606                 return;
607         }
608         asoc = &stcb->asoc;
609         serial_num = ntohl(cp->serial_number);
610
611         if (SCTP_TSN_GE(asoc->asconf_seq_in, serial_num)) {
612                 /* got a duplicate ASCONF */
613                 SCTPDBG(SCTP_DEBUG_ASCONF1,
614                     "handle_asconf: got duplicate serial number = %xh\n",
615                     serial_num);
616                 return;
617         } else if (serial_num != (asoc->asconf_seq_in + 1)) {
618                 SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: incorrect serial number = %xh (expected next = %xh)\n",
619                     serial_num, asoc->asconf_seq_in + 1);
620                 return;
621         }
622
623         /* it's the expected "next" sequence number, so process it */
624         asoc->asconf_seq_in = serial_num;       /* update sequence */
625         /* get length of all the param's in the ASCONF */
626         asconf_limit = offset + ntohs(cp->ch.chunk_length);
627         SCTPDBG(SCTP_DEBUG_ASCONF1,
628             "handle_asconf: asconf_limit=%u, sequence=%xh\n",
629             asconf_limit, serial_num);
630
631         if (first) {
632                 /* delete old cache */
633                 SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: Now processing first ASCONF. Try to delete old cache\n");
634
635                 TAILQ_FOREACH_SAFE(ack, &asoc->asconf_ack_sent, next, ack_next) {
636                         if (ack->serial_number == serial_num)
637                                 break;
638                         SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: delete old(%u) < first(%u)\n",
639                             ack->serial_number, serial_num);
640                         TAILQ_REMOVE(&asoc->asconf_ack_sent, ack, next);
641                         if (ack->data != NULL) {
642                                 sctp_m_freem(ack->data);
643                         }
644                         SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_asconf_ack), ack);
645                 }
646         }
647
648         m_ack = sctp_get_mbuf_for_msg(sizeof(struct sctp_asconf_ack_chunk), 0,
649             M_NOWAIT, 1, MT_DATA);
650         if (m_ack == NULL) {
651                 SCTPDBG(SCTP_DEBUG_ASCONF1,
652                     "handle_asconf: couldn't get mbuf!\n");
653                 return;
654         }
655         m_tail = m_ack;         /* current reply chain's tail */
656
657         /* fill in ASCONF-ACK header */
658         ack_cp = mtod(m_ack, struct sctp_asconf_ack_chunk *);
659         ack_cp->ch.chunk_type = SCTP_ASCONF_ACK;
660         ack_cp->ch.chunk_flags = 0;
661         ack_cp->serial_number = htonl(serial_num);
662         /* set initial lengths (eg. just an ASCONF-ACK), ntohx at the end! */
663         SCTP_BUF_LEN(m_ack) = sizeof(struct sctp_asconf_ack_chunk);
664         ack_cp->ch.chunk_length = sizeof(struct sctp_asconf_ack_chunk);
665
666         /* skip the lookup address parameter */
667         offset += sizeof(struct sctp_asconf_chunk);
668         p_addr = (struct sctp_ipv6addr_param *)sctp_m_getptr(m, offset, sizeof(struct sctp_paramhdr), (uint8_t *)&aparam_buf);
669         if (p_addr == NULL) {
670                 SCTPDBG(SCTP_DEBUG_ASCONF1,
671                     "handle_asconf: couldn't get lookup addr!\n");
672                 /* respond with a missing/invalid mandatory parameter error */
673                 sctp_m_freem(m_ack);
674                 return;
675         }
676         /* param_length is already validated in process_control... */
677         offset += ntohs(p_addr->ph.param_length);       /* skip lookup addr */
678         /* get pointer to first asconf param in ASCONF */
679         aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(m, offset, sizeof(struct sctp_asconf_paramhdr), (uint8_t *)&aparam_buf);
680         if (aph == NULL) {
681                 SCTPDBG(SCTP_DEBUG_ASCONF1, "Empty ASCONF received?\n");
682                 goto send_reply;
683         }
684         /* process through all parameters */
685         cnt = 0;
686         while (aph != NULL) {
687                 unsigned int param_length, param_type;
688
689                 param_type = ntohs(aph->ph.param_type);
690                 param_length = ntohs(aph->ph.param_length);
691                 if (offset + param_length > asconf_limit) {
692                         /* parameter goes beyond end of chunk! */
693                         sctp_m_freem(m_ack);
694                         return;
695                 }
696                 m_result = NULL;
697
698                 if (param_length > sizeof(aparam_buf)) {
699                         SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: param length (%u) larger than buffer size!\n", param_length);
700                         sctp_m_freem(m_ack);
701                         return;
702                 }
703                 if (param_length <= sizeof(struct sctp_paramhdr)) {
704                         SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: param length (%u) too short\n", param_length);
705                         sctp_m_freem(m_ack);
706                         return;
707                 }
708                 /* get the entire parameter */
709                 aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(m, offset, param_length, aparam_buf);
710                 if (aph == NULL) {
711                         SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: couldn't get entire param\n");
712                         sctp_m_freem(m_ack);
713                         return;
714                 }
715                 switch (param_type) {
716                 case SCTP_ADD_IP_ADDRESS:
717                         m_result = sctp_process_asconf_add_ip(src, aph, stcb,
718                             (cnt < SCTP_BASE_SYSCTL(sctp_hb_maxburst)), error);
719                         cnt++;
720                         break;
721                 case SCTP_DEL_IP_ADDRESS:
722                         m_result = sctp_process_asconf_delete_ip(src, aph, stcb,
723                             error);
724                         break;
725                 case SCTP_ERROR_CAUSE_IND:
726                         /* not valid in an ASCONF chunk */
727                         break;
728                 case SCTP_SET_PRIM_ADDR:
729                         m_result = sctp_process_asconf_set_primary(src, aph,
730                             stcb, error);
731                         break;
732                 case SCTP_NAT_VTAGS:
733                         SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: sees a NAT VTAG state parameter\n");
734                         break;
735                 case SCTP_SUCCESS_REPORT:
736                         /* not valid in an ASCONF chunk */
737                         break;
738                 case SCTP_ULP_ADAPTATION:
739                         /* FIX */
740                         break;
741                 default:
742                         if ((param_type & 0x8000) == 0) {
743                                 /* Been told to STOP at this param */
744                                 asconf_limit = offset;
745                                 /*
746                                  * FIX FIX - We need to call
747                                  * sctp_arethere_unrecognized_parameters()
748                                  * to get a operr and send it for any
749                                  * param's with the 0x4000 bit set OR do it
750                                  * here ourselves... note we still must STOP
751                                  * if the 0x8000 bit is clear.
752                                  */
753                         }
754                         /* unknown/invalid param type */
755                         break;
756                 }               /* switch */
757
758                 /* add any (error) result to the reply mbuf chain */
759                 if (m_result != NULL) {
760                         SCTP_BUF_NEXT(m_tail) = m_result;
761                         m_tail = m_result;
762                         /* update lengths, make sure it's aligned too */
763                         SCTP_BUF_LEN(m_result) = SCTP_SIZE32(SCTP_BUF_LEN(m_result));
764                         ack_cp->ch.chunk_length += SCTP_BUF_LEN(m_result);
765                         /* set flag to force success reports */
766                         error = 1;
767                 }
768                 offset += SCTP_SIZE32(param_length);
769                 /* update remaining ASCONF message length to process */
770                 if (offset >= asconf_limit) {
771                         /* no more data in the mbuf chain */
772                         break;
773                 }
774                 /* get pointer to next asconf param */
775                 aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(m, offset,
776                     sizeof(struct sctp_asconf_paramhdr),
777                     (uint8_t *)&aparam_buf);
778                 if (aph == NULL) {
779                         /* can't get an asconf paramhdr */
780                         SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: can't get asconf param hdr!\n");
781                         /* FIX ME - add error here... */
782                 }
783         }
784
785 send_reply:
786         ack_cp->ch.chunk_length = htons(ack_cp->ch.chunk_length);
787         /* save the ASCONF-ACK reply */
788         ack = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_asconf_ack),
789             struct sctp_asconf_ack);
790         if (ack == NULL) {
791                 sctp_m_freem(m_ack);
792                 return;
793         }
794         ack->serial_number = serial_num;
795         ack->last_sent_to = NULL;
796         ack->data = m_ack;
797         ack->len = 0;
798         for (n = m_ack; n != NULL; n = SCTP_BUF_NEXT(n)) {
799                 ack->len += SCTP_BUF_LEN(n);
800         }
801         TAILQ_INSERT_TAIL(&stcb->asoc.asconf_ack_sent, ack, next);
802
803         /* see if last_control_chunk_from is set properly (use IP src addr) */
804         if (stcb->asoc.last_control_chunk_from == NULL) {
805                 /*
806                  * this could happen if the source address was just newly
807                  * added
808                  */
809                 SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: looking up net for IP source address\n");
810                 SCTPDBG(SCTP_DEBUG_ASCONF1, "Looking for IP source: ");
811                 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, src);
812                 /* look up the from address */
813                 stcb->asoc.last_control_chunk_from = sctp_findnet(stcb, src);
814 #ifdef SCTP_DEBUG
815                 if (stcb->asoc.last_control_chunk_from == NULL) {
816                         SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: IP source address not found?!\n");
817                 }
818 #endif
819         }
820 }
821
822 /*
823  * does the address match? returns 0 if not, 1 if so
824  */
825 static uint32_t
826 sctp_asconf_addr_match(struct sctp_asconf_addr *aa, struct sockaddr *sa)
827 {
828         switch (sa->sa_family) {
829 #ifdef INET6
830         case AF_INET6:
831                 {
832                         /* XXX scopeid */
833                         struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
834
835                         if ((aa->ap.addrp.ph.param_type == SCTP_IPV6_ADDRESS) &&
836                             (memcmp(&aa->ap.addrp.addr, &sin6->sin6_addr,
837                             sizeof(struct in6_addr)) == 0)) {
838                                 return (1);
839                         }
840                         break;
841                 }
842 #endif
843 #ifdef INET
844         case AF_INET:
845                 {
846                         struct sockaddr_in *sin = (struct sockaddr_in *)sa;
847
848                         if ((aa->ap.addrp.ph.param_type == SCTP_IPV4_ADDRESS) &&
849                             (memcmp(&aa->ap.addrp.addr, &sin->sin_addr,
850                             sizeof(struct in_addr)) == 0)) {
851                                 return (1);
852                         }
853                         break;
854                 }
855 #endif
856         default:
857                 break;
858         }
859         return (0);
860 }
861
862 /*
863  * does the address match? returns 0 if not, 1 if so
864  */
865 static uint32_t
866 sctp_addr_match(struct sctp_paramhdr *ph, struct sockaddr *sa)
867 {
868 #if defined(INET) || defined(INET6)
869         uint16_t param_type, param_length;
870
871         param_type = ntohs(ph->param_type);
872         param_length = ntohs(ph->param_length);
873 #endif
874         switch (sa->sa_family) {
875 #ifdef INET6
876         case AF_INET6:
877                 {
878                         /* XXX scopeid */
879                         struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
880                         struct sctp_ipv6addr_param *v6addr;
881
882                         v6addr = (struct sctp_ipv6addr_param *)ph;
883                         if ((param_type == SCTP_IPV6_ADDRESS) &&
884                             (param_length == sizeof(struct sctp_ipv6addr_param)) &&
885                             (memcmp(&v6addr->addr, &sin6->sin6_addr,
886                             sizeof(struct in6_addr)) == 0)) {
887                                 return (1);
888                         }
889                         break;
890                 }
891 #endif
892 #ifdef INET
893         case AF_INET:
894                 {
895                         struct sockaddr_in *sin = (struct sockaddr_in *)sa;
896                         struct sctp_ipv4addr_param *v4addr;
897
898                         v4addr = (struct sctp_ipv4addr_param *)ph;
899                         if ((param_type == SCTP_IPV4_ADDRESS) &&
900                             (param_length == sizeof(struct sctp_ipv4addr_param)) &&
901                             (memcmp(&v4addr->addr, &sin->sin_addr,
902                             sizeof(struct in_addr)) == 0)) {
903                                 return (1);
904                         }
905                         break;
906                 }
907 #endif
908         default:
909                 break;
910         }
911         return (0);
912 }
913
914 /*
915  * Cleanup for non-responded/OP ERR'd ASCONF
916  */
917 void
918 sctp_asconf_cleanup(struct sctp_tcb *stcb, struct sctp_nets *net)
919 {
920         /*
921          * clear out any existing asconfs going out
922          */
923         sctp_timer_stop(SCTP_TIMER_TYPE_ASCONF, stcb->sctp_ep, stcb, net,
924             SCTP_FROM_SCTP_ASCONF + SCTP_LOC_2);
925         stcb->asoc.asconf_seq_out_acked = stcb->asoc.asconf_seq_out;
926         /* remove the old ASCONF on our outbound queue */
927         sctp_toss_old_asconf(stcb);
928 }
929
930 /*
931  * cleanup any cached source addresses that may be topologically
932  * incorrect after a new address has been added to this interface.
933  */
934 static void
935 sctp_asconf_nets_cleanup(struct sctp_tcb *stcb, struct sctp_ifn *ifn)
936 {
937         struct sctp_nets *net;
938
939         /*
940          * Ideally, we want to only clear cached routes and source addresses
941          * that are topologically incorrect.  But since there is no easy way
942          * to know whether the newly added address on the ifn would cause a
943          * routing change (i.e. a new egress interface would be chosen)
944          * without doing a new routing lookup and source address selection,
945          * we will (for now) just flush any cached route using a different
946          * ifn (and cached source addrs) and let output re-choose them
947          * during the next send on that net.
948          */
949         TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
950                 /*
951                  * clear any cached route (and cached source address) if the
952                  * route's interface is NOT the same as the address change.
953                  * If it's the same interface, just clear the cached source
954                  * address.
955                  */
956                 if (SCTP_ROUTE_HAS_VALID_IFN(&net->ro) &&
957                     ((ifn == NULL) ||
958                     (SCTP_GET_IF_INDEX_FROM_ROUTE(&net->ro) != ifn->ifn_index))) {
959                         /* clear any cached route */
960                         RTFREE(net->ro.ro_rt);
961                         net->ro.ro_rt = NULL;
962                 }
963                 /* clear any cached source address */
964                 if (net->src_addr_selected) {
965                         sctp_free_ifa(net->ro._s_addr);
966                         net->ro._s_addr = NULL;
967                         net->src_addr_selected = 0;
968                 }
969         }
970 }
971
972
973 void
974 sctp_assoc_immediate_retrans(struct sctp_tcb *stcb, struct sctp_nets *dstnet)
975 {
976         int error;
977
978         if (dstnet->dest_state & SCTP_ADDR_UNCONFIRMED) {
979                 return;
980         }
981         if (stcb->asoc.deleted_primary == NULL) {
982                 return;
983         }
984
985         if (!TAILQ_EMPTY(&stcb->asoc.sent_queue)) {
986                 SCTPDBG(SCTP_DEBUG_ASCONF1, "assoc_immediate_retrans: Deleted primary is ");
987                 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, &stcb->asoc.deleted_primary->ro._l_addr.sa);
988                 SCTPDBG(SCTP_DEBUG_ASCONF1, "Current Primary is ");
989                 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, &stcb->asoc.primary_destination->ro._l_addr.sa);
990                 sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb,
991                     stcb->asoc.deleted_primary,
992                     SCTP_FROM_SCTP_ASCONF + SCTP_LOC_3);
993                 stcb->asoc.num_send_timers_up--;
994                 if (stcb->asoc.num_send_timers_up < 0) {
995                         stcb->asoc.num_send_timers_up = 0;
996                 }
997                 SCTP_TCB_LOCK_ASSERT(stcb);
998                 error = sctp_t3rxt_timer(stcb->sctp_ep, stcb,
999                     stcb->asoc.deleted_primary);
1000                 if (error) {
1001                         SCTP_INP_DECR_REF(stcb->sctp_ep);
1002                         return;
1003                 }
1004                 SCTP_TCB_LOCK_ASSERT(stcb);
1005 #ifdef SCTP_AUDITING_ENABLED
1006                 sctp_auditing(4, stcb->sctp_ep, stcb, stcb->asoc.deleted_primary);
1007 #endif
1008                 sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_NOT_LOCKED);
1009                 if ((stcb->asoc.num_send_timers_up == 0) &&
1010                     (stcb->asoc.sent_queue_cnt > 0)) {
1011                         struct sctp_tmit_chunk *chk;
1012
1013                         chk = TAILQ_FIRST(&stcb->asoc.sent_queue);
1014                         sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
1015                             stcb, chk->whoTo);
1016                 }
1017         }
1018         return;
1019 }
1020
1021 static int
1022     sctp_asconf_queue_mgmt(struct sctp_tcb *, struct sctp_ifa *, uint16_t);
1023
1024 void
1025 sctp_net_immediate_retrans(struct sctp_tcb *stcb, struct sctp_nets *net)
1026 {
1027         struct sctp_tmit_chunk *chk;
1028
1029         SCTPDBG(SCTP_DEBUG_ASCONF1, "net_immediate_retrans: RTO is %d\n", net->RTO);
1030         sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, net,
1031             SCTP_FROM_SCTP_ASCONF + SCTP_LOC_4);
1032         stcb->asoc.cc_functions.sctp_set_initial_cc_param(stcb, net);
1033         net->error_count = 0;
1034         TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
1035                 if (chk->whoTo == net) {
1036                         if (chk->sent < SCTP_DATAGRAM_RESEND) {
1037                                 chk->sent = SCTP_DATAGRAM_RESEND;
1038                                 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
1039                                 sctp_flight_size_decrease(chk);
1040                                 sctp_total_flight_decrease(stcb, chk);
1041                                 net->marked_retrans++;
1042                                 stcb->asoc.marked_retrans++;
1043                         }
1044                 }
1045         }
1046         if (net->marked_retrans) {
1047                 sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_NOT_LOCKED);
1048         }
1049 }
1050
1051 static void
1052 sctp_path_check_and_react(struct sctp_tcb *stcb, struct sctp_ifa *newifa)
1053 {
1054         struct sctp_nets *net;
1055         int addrnum, changed;
1056
1057         /*
1058          * If number of local valid addresses is 1, the valid address is
1059          * probably newly added address. Several valid addresses in this
1060          * association.  A source address may not be changed.  Additionally,
1061          * they can be configured on a same interface as "alias" addresses.
1062          * (by micchie)
1063          */
1064         addrnum = sctp_local_addr_count(stcb);
1065         SCTPDBG(SCTP_DEBUG_ASCONF1, "p_check_react(): %d local addresses\n",
1066             addrnum);
1067         if (addrnum == 1) {
1068                 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
1069                         /* clear any cached route and source address */
1070                         if (net->ro.ro_rt) {
1071                                 RTFREE(net->ro.ro_rt);
1072                                 net->ro.ro_rt = NULL;
1073                         }
1074                         if (net->src_addr_selected) {
1075                                 sctp_free_ifa(net->ro._s_addr);
1076                                 net->ro._s_addr = NULL;
1077                                 net->src_addr_selected = 0;
1078                         }
1079                         /* Retransmit unacknowledged DATA chunks immediately */
1080                         if (sctp_is_mobility_feature_on(stcb->sctp_ep,
1081                             SCTP_MOBILITY_FASTHANDOFF)) {
1082                                 sctp_net_immediate_retrans(stcb, net);
1083                         }
1084                         /* also, SET PRIMARY is maybe already sent */
1085                 }
1086                 return;
1087         }
1088
1089         /* Multiple local addresses exsist in the association.  */
1090         TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
1091                 /* clear any cached route and source address */
1092                 if (net->ro.ro_rt) {
1093                         RTFREE(net->ro.ro_rt);
1094                         net->ro.ro_rt = NULL;
1095                 }
1096                 if (net->src_addr_selected) {
1097                         sctp_free_ifa(net->ro._s_addr);
1098                         net->ro._s_addr = NULL;
1099                         net->src_addr_selected = 0;
1100                 }
1101                 /*
1102                  * Check if the nexthop is corresponding to the new address.
1103                  * If the new address is corresponding to the current
1104                  * nexthop, the path will be changed. If the new address is
1105                  * NOT corresponding to the current nexthop, the path will
1106                  * not be changed.
1107                  */
1108                 SCTP_RTALLOC((sctp_route_t *)&net->ro,
1109                     stcb->sctp_ep->def_vrf_id,
1110                     stcb->sctp_ep->fibnum);
1111                 if (net->ro.ro_rt == NULL)
1112                         continue;
1113
1114                 changed = 0;
1115                 switch (net->ro._l_addr.sa.sa_family) {
1116 #ifdef INET
1117                 case AF_INET:
1118                         if (sctp_v4src_match_nexthop(newifa, (sctp_route_t *)&net->ro)) {
1119                                 changed = 1;
1120                         }
1121                         break;
1122 #endif
1123 #ifdef INET6
1124                 case AF_INET6:
1125                         if (sctp_v6src_match_nexthop(
1126                             &newifa->address.sin6, (sctp_route_t *)&net->ro)) {
1127                                 changed = 1;
1128                         }
1129                         break;
1130 #endif
1131                 default:
1132                         break;
1133                 }
1134                 /*
1135                  * if the newly added address does not relate routing
1136                  * information, we skip.
1137                  */
1138                 if (changed == 0)
1139                         continue;
1140                 /* Retransmit unacknowledged DATA chunks immediately */
1141                 if (sctp_is_mobility_feature_on(stcb->sctp_ep,
1142                     SCTP_MOBILITY_FASTHANDOFF)) {
1143                         sctp_net_immediate_retrans(stcb, net);
1144                 }
1145                 /* Send SET PRIMARY for this new address */
1146                 if (net == stcb->asoc.primary_destination) {
1147                         (void)sctp_asconf_queue_mgmt(stcb, newifa,
1148                             SCTP_SET_PRIM_ADDR);
1149                 }
1150         }
1151 }
1152
1153 /*
1154  * process an ADD/DELETE IP ack from peer.
1155  * addr: corresponding sctp_ifa to the address being added/deleted.
1156  * type: SCTP_ADD_IP_ADDRESS or SCTP_DEL_IP_ADDRESS.
1157  * flag: 1=success, 0=failure.
1158  */
1159 static void
1160 sctp_asconf_addr_mgmt_ack(struct sctp_tcb *stcb, struct sctp_ifa *addr, uint32_t flag)
1161 {
1162         /*
1163          * do the necessary asoc list work- if we get a failure indication,
1164          * leave the address on the assoc's restricted list.  If we get a
1165          * success indication, remove the address from the restricted list.
1166          */
1167         /*
1168          * Note: this will only occur for ADD_IP_ADDRESS, since
1169          * DEL_IP_ADDRESS is never actually added to the list...
1170          */
1171         if (flag) {
1172                 /* success case, so remove from the restricted list */
1173                 sctp_del_local_addr_restricted(stcb, addr);
1174
1175                 if (sctp_is_mobility_feature_on(stcb->sctp_ep,
1176                     SCTP_MOBILITY_BASE) ||
1177                     sctp_is_mobility_feature_on(stcb->sctp_ep,
1178                     SCTP_MOBILITY_FASTHANDOFF)) {
1179                         sctp_path_check_and_react(stcb, addr);
1180                         return;
1181                 }
1182                 /* clear any cached/topologically incorrect source addresses */
1183                 sctp_asconf_nets_cleanup(stcb, addr->ifn_p);
1184         }
1185         /* else, leave it on the list */
1186 }
1187
1188 /*
1189  * add an asconf add/delete/set primary IP address parameter to the queue.
1190  * type = SCTP_ADD_IP_ADDRESS, SCTP_DEL_IP_ADDRESS, SCTP_SET_PRIM_ADDR.
1191  * returns 0 if queued, -1 if not queued/removed.
1192  * NOTE: if adding, but a delete for the same address is already scheduled
1193  * (and not yet sent out), simply remove it from queue.  Same for deleting
1194  * an address already scheduled for add.  If a duplicate operation is found,
1195  * ignore the new one.
1196  */
1197 static int
1198 sctp_asconf_queue_mgmt(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
1199     uint16_t type)
1200 {
1201         struct sctp_asconf_addr *aa, *aa_next;
1202
1203         /* make sure the request isn't already in the queue */
1204         TAILQ_FOREACH_SAFE(aa, &stcb->asoc.asconf_queue, next, aa_next) {
1205                 /* address match? */
1206                 if (sctp_asconf_addr_match(aa, &ifa->address.sa) == 0)
1207                         continue;
1208                 /*
1209                  * is the request already in queue but not sent? pass the
1210                  * request already sent in order to resolve the following
1211                  * case: 1. arrival of ADD, then sent 2. arrival of DEL. we
1212                  * can't remove the ADD request already sent 3. arrival of
1213                  * ADD
1214                  */
1215                 if (aa->ap.aph.ph.param_type == type && aa->sent == 0) {
1216                         return (-1);
1217                 }
1218                 /* is the negative request already in queue, and not sent */
1219                 if ((aa->sent == 0) && (type == SCTP_ADD_IP_ADDRESS) &&
1220                     (aa->ap.aph.ph.param_type == SCTP_DEL_IP_ADDRESS)) {
1221                         /* add requested, delete already queued */
1222                         TAILQ_REMOVE(&stcb->asoc.asconf_queue, aa, next);
1223                         /* remove the ifa from the restricted list */
1224                         sctp_del_local_addr_restricted(stcb, ifa);
1225                         /* free the asconf param */
1226                         SCTP_FREE(aa, SCTP_M_ASC_ADDR);
1227                         SCTPDBG(SCTP_DEBUG_ASCONF2, "asconf_queue_mgmt: add removes queued entry\n");
1228                         return (-1);
1229                 }
1230                 if ((aa->sent == 0) && (type == SCTP_DEL_IP_ADDRESS) &&
1231                     (aa->ap.aph.ph.param_type == SCTP_ADD_IP_ADDRESS)) {
1232                         /* delete requested, add already queued */
1233                         TAILQ_REMOVE(&stcb->asoc.asconf_queue, aa, next);
1234                         /* remove the aa->ifa from the restricted list */
1235                         sctp_del_local_addr_restricted(stcb, aa->ifa);
1236                         /* free the asconf param */
1237                         SCTP_FREE(aa, SCTP_M_ASC_ADDR);
1238                         SCTPDBG(SCTP_DEBUG_ASCONF2, "asconf_queue_mgmt: delete removes queued entry\n");
1239                         return (-1);
1240                 }
1241         }                       /* for each aa */
1242
1243         /* adding new request to the queue */
1244         SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa),
1245             SCTP_M_ASC_ADDR);
1246         if (aa == NULL) {
1247                 /* didn't get memory */
1248                 SCTPDBG(SCTP_DEBUG_ASCONF1, "asconf_queue_mgmt: failed to get memory!\n");
1249                 return (-1);
1250         }
1251         aa->special_del = 0;
1252         /* fill in asconf address parameter fields */
1253         /* top level elements are "networked" during send */
1254         aa->ap.aph.ph.param_type = type;
1255         aa->ifa = ifa;
1256         atomic_add_int(&ifa->refcount, 1);
1257         /* correlation_id filled in during send routine later... */
1258         switch (ifa->address.sa.sa_family) {
1259 #ifdef INET6
1260         case AF_INET6:
1261                 {
1262                         struct sockaddr_in6 *sin6;
1263
1264                         sin6 = &ifa->address.sin6;
1265                         aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
1266                         aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv6addr_param));
1267                         aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) +
1268                             sizeof(struct sctp_ipv6addr_param);
1269                         memcpy(&aa->ap.addrp.addr, &sin6->sin6_addr,
1270                             sizeof(struct in6_addr));
1271                         break;
1272                 }
1273 #endif
1274 #ifdef INET
1275         case AF_INET:
1276                 {
1277                         struct sockaddr_in *sin;
1278
1279                         sin = &ifa->address.sin;
1280                         aa->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
1281                         aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv4addr_param));
1282                         aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) +
1283                             sizeof(struct sctp_ipv4addr_param);
1284                         memcpy(&aa->ap.addrp.addr, &sin->sin_addr,
1285                             sizeof(struct in_addr));
1286                         break;
1287                 }
1288 #endif
1289         default:
1290                 /* invalid family! */
1291                 SCTP_FREE(aa, SCTP_M_ASC_ADDR);
1292                 sctp_free_ifa(ifa);
1293                 return (-1);
1294         }
1295         aa->sent = 0;           /* clear sent flag */
1296
1297         TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
1298 #ifdef SCTP_DEBUG
1299         if (SCTP_BASE_SYSCTL(sctp_debug_on) & SCTP_DEBUG_ASCONF2) {
1300                 if (type == SCTP_ADD_IP_ADDRESS) {
1301                         SCTP_PRINTF("asconf_queue_mgmt: inserted asconf ADD_IP_ADDRESS: ");
1302                         SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, &ifa->address.sa);
1303                 } else if (type == SCTP_DEL_IP_ADDRESS) {
1304                         SCTP_PRINTF("asconf_queue_mgmt: appended asconf DEL_IP_ADDRESS: ");
1305                         SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, &ifa->address.sa);
1306                 } else {
1307                         SCTP_PRINTF("asconf_queue_mgmt: appended asconf SET_PRIM_ADDR: ");
1308                         SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, &ifa->address.sa);
1309                 }
1310         }
1311 #endif
1312
1313         return (0);
1314 }
1315
1316
1317 /*
1318  * add an asconf operation for the given ifa and type.
1319  * type = SCTP_ADD_IP_ADDRESS, SCTP_DEL_IP_ADDRESS, SCTP_SET_PRIM_ADDR.
1320  * returns 0 if completed, -1 if not completed, 1 if immediate send is
1321  * advisable.
1322  */
1323 static int
1324 sctp_asconf_queue_add(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
1325     uint16_t type)
1326 {
1327         uint32_t status;
1328         int pending_delete_queued = 0;
1329         int last;
1330
1331         /* see if peer supports ASCONF */
1332         if (stcb->asoc.asconf_supported == 0) {
1333                 return (-1);
1334         }
1335
1336         /*
1337          * if this is deleting the last address from the assoc, mark it as
1338          * pending.
1339          */
1340         if ((type == SCTP_DEL_IP_ADDRESS) && !stcb->asoc.asconf_del_pending) {
1341                 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
1342                         last = (sctp_local_addr_count(stcb) == 0);
1343                 } else {
1344                         last = (sctp_local_addr_count(stcb) == 1);
1345                 }
1346                 if (last) {
1347                         /* set the pending delete info only */
1348                         stcb->asoc.asconf_del_pending = 1;
1349                         stcb->asoc.asconf_addr_del_pending = ifa;
1350                         atomic_add_int(&ifa->refcount, 1);
1351                         SCTPDBG(SCTP_DEBUG_ASCONF2,
1352                             "asconf_queue_add: mark delete last address pending\n");
1353                         return (-1);
1354                 }
1355         }
1356
1357         /* queue an asconf parameter */
1358         status = sctp_asconf_queue_mgmt(stcb, ifa, type);
1359
1360         /*
1361          * if this is an add, and there is a delete also pending (i.e. the
1362          * last local address is being changed), queue the pending delete
1363          * too.
1364          */
1365         if ((type == SCTP_ADD_IP_ADDRESS) && stcb->asoc.asconf_del_pending && (status == 0)) {
1366                 /* queue in the pending delete */
1367                 if (sctp_asconf_queue_mgmt(stcb,
1368                     stcb->asoc.asconf_addr_del_pending,
1369                     SCTP_DEL_IP_ADDRESS) == 0) {
1370                         SCTPDBG(SCTP_DEBUG_ASCONF2, "asconf_queue_add: queuing pending delete\n");
1371                         pending_delete_queued = 1;
1372                         /* clear out the pending delete info */
1373                         stcb->asoc.asconf_del_pending = 0;
1374                         sctp_free_ifa(stcb->asoc.asconf_addr_del_pending);
1375                         stcb->asoc.asconf_addr_del_pending = NULL;
1376                 }
1377         }
1378
1379         if (pending_delete_queued) {
1380                 struct sctp_nets *net;
1381
1382                 /*
1383                  * since we know that the only/last address is now being
1384                  * changed in this case, reset the cwnd/rto on all nets to
1385                  * start as a new address and path.  Also clear the error
1386                  * counts to give the assoc the best chance to complete the
1387                  * address change.
1388                  */
1389                 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
1390                         stcb->asoc.cc_functions.sctp_set_initial_cc_param(stcb,
1391                             net);
1392                         net->RTO = 0;
1393                         net->error_count = 0;
1394                 }
1395                 stcb->asoc.overall_error_count = 0;
1396                 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
1397                         sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
1398                             stcb->asoc.overall_error_count,
1399                             0,
1400                             SCTP_FROM_SCTP_ASCONF,
1401                             __LINE__);
1402                 }
1403
1404                 /* queue in an advisory set primary too */
1405                 (void)sctp_asconf_queue_mgmt(stcb, ifa, SCTP_SET_PRIM_ADDR);
1406                 /* let caller know we should send this out immediately */
1407                 status = 1;
1408         }
1409         return (status);
1410 }
1411
1412 /*-
1413  * add an asconf delete IP address parameter to the queue by sockaddr and
1414  * possibly with no sctp_ifa available.  This is only called by the routine
1415  * that checks the addresses in an INIT-ACK against the current address list.
1416  * returns 0 if completed, non-zero if not completed.
1417  * NOTE: if an add is already scheduled (and not yet sent out), simply
1418  * remove it from queue.  If a duplicate operation is found, ignore the
1419  * new one.
1420  */
1421 static int
1422 sctp_asconf_queue_sa_delete(struct sctp_tcb *stcb, struct sockaddr *sa)
1423 {
1424         struct sctp_ifa *ifa;
1425         struct sctp_asconf_addr *aa, *aa_next;
1426
1427         if (stcb == NULL) {
1428                 return (-1);
1429         }
1430         /* see if peer supports ASCONF */
1431         if (stcb->asoc.asconf_supported == 0) {
1432                 return (-1);
1433         }
1434         /* make sure the request isn't already in the queue */
1435         TAILQ_FOREACH_SAFE(aa, &stcb->asoc.asconf_queue, next, aa_next) {
1436                 /* address match? */
1437                 if (sctp_asconf_addr_match(aa, sa) == 0)
1438                         continue;
1439                 /* is the request already in queue (sent or not) */
1440                 if (aa->ap.aph.ph.param_type == SCTP_DEL_IP_ADDRESS) {
1441                         return (-1);
1442                 }
1443                 /* is the negative request already in queue, and not sent */
1444                 if (aa->sent == 1)
1445                         continue;
1446                 if (aa->ap.aph.ph.param_type == SCTP_ADD_IP_ADDRESS) {
1447                         /* add already queued, so remove existing entry */
1448                         TAILQ_REMOVE(&stcb->asoc.asconf_queue, aa, next);
1449                         sctp_del_local_addr_restricted(stcb, aa->ifa);
1450                         /* free the entry */
1451                         SCTP_FREE(aa, SCTP_M_ASC_ADDR);
1452                         return (-1);
1453                 }
1454         }                       /* for each aa */
1455
1456         /* find any existing ifa-- NOTE ifa CAN be allowed to be NULL */
1457         ifa = sctp_find_ifa_by_addr(sa, stcb->asoc.vrf_id, SCTP_ADDR_NOT_LOCKED);
1458
1459         /* adding new request to the queue */
1460         SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa),
1461             SCTP_M_ASC_ADDR);
1462         if (aa == NULL) {
1463                 /* didn't get memory */
1464                 SCTPDBG(SCTP_DEBUG_ASCONF1,
1465                     "sctp_asconf_queue_sa_delete: failed to get memory!\n");
1466                 return (-1);
1467         }
1468         aa->special_del = 0;
1469         /* fill in asconf address parameter fields */
1470         /* top level elements are "networked" during send */
1471         aa->ap.aph.ph.param_type = SCTP_DEL_IP_ADDRESS;
1472         aa->ifa = ifa;
1473         if (ifa)
1474                 atomic_add_int(&ifa->refcount, 1);
1475         /* correlation_id filled in during send routine later... */
1476         switch (sa->sa_family) {
1477 #ifdef INET6
1478         case AF_INET6:
1479                 {
1480                         /* IPv6 address */
1481                         struct sockaddr_in6 *sin6;
1482
1483                         sin6 = (struct sockaddr_in6 *)sa;
1484                         aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
1485                         aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv6addr_param));
1486                         aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) + sizeof(struct sctp_ipv6addr_param);
1487                         memcpy(&aa->ap.addrp.addr, &sin6->sin6_addr,
1488                             sizeof(struct in6_addr));
1489                         break;
1490                 }
1491 #endif
1492 #ifdef INET
1493         case AF_INET:
1494                 {
1495                         /* IPv4 address */
1496                         struct sockaddr_in *sin = (struct sockaddr_in *)sa;
1497
1498                         aa->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
1499                         aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv4addr_param));
1500                         aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) + sizeof(struct sctp_ipv4addr_param);
1501                         memcpy(&aa->ap.addrp.addr, &sin->sin_addr,
1502                             sizeof(struct in_addr));
1503                         break;
1504                 }
1505 #endif
1506         default:
1507                 /* invalid family! */
1508                 SCTP_FREE(aa, SCTP_M_ASC_ADDR);
1509                 if (ifa)
1510                         sctp_free_ifa(ifa);
1511                 return (-1);
1512         }
1513         aa->sent = 0;           /* clear sent flag */
1514
1515         /* delete goes to the back of the queue */
1516         TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
1517
1518         /* sa_ignore MEMLEAK {memory is put on the tailq} */
1519         return (0);
1520 }
1521
1522 /*
1523  * find a specific asconf param on our "sent" queue
1524  */
1525 static struct sctp_asconf_addr *
1526 sctp_asconf_find_param(struct sctp_tcb *stcb, uint32_t correlation_id)
1527 {
1528         struct sctp_asconf_addr *aa;
1529
1530         TAILQ_FOREACH(aa, &stcb->asoc.asconf_queue, next) {
1531                 if (aa->ap.aph.correlation_id == correlation_id &&
1532                     aa->sent == 1) {
1533                         /* found it */
1534                         return (aa);
1535                 }
1536         }
1537         /* didn't find it */
1538         return (NULL);
1539 }
1540
1541 /*
1542  * process an SCTP_ERROR_CAUSE_IND for a ASCONF-ACK parameter and do
1543  * notifications based on the error response
1544  */
1545 static void
1546 sctp_asconf_process_error(struct sctp_tcb *stcb SCTP_UNUSED,
1547     struct sctp_asconf_paramhdr *aph)
1548 {
1549         struct sctp_error_cause *eh;
1550         struct sctp_paramhdr *ph;
1551         uint16_t param_type;
1552         uint16_t error_code;
1553
1554         eh = (struct sctp_error_cause *)(aph + 1);
1555         ph = (struct sctp_paramhdr *)(eh + 1);
1556         /* validate lengths */
1557         if (htons(eh->length) + sizeof(struct sctp_error_cause) >
1558             htons(aph->ph.param_length)) {
1559                 /* invalid error cause length */
1560                 SCTPDBG(SCTP_DEBUG_ASCONF1,
1561                     "asconf_process_error: cause element too long\n");
1562                 return;
1563         }
1564         if (htons(ph->param_length) + sizeof(struct sctp_paramhdr) >
1565             htons(eh->length)) {
1566                 /* invalid included TLV length */
1567                 SCTPDBG(SCTP_DEBUG_ASCONF1,
1568                     "asconf_process_error: included TLV too long\n");
1569                 return;
1570         }
1571         /* which error code ? */
1572         error_code = ntohs(eh->code);
1573         param_type = ntohs(aph->ph.param_type);
1574         /* FIX: this should go back up the REMOTE_ERROR ULP notify */
1575         switch (error_code) {
1576         case SCTP_CAUSE_RESOURCE_SHORTAGE:
1577                 /* we allow ourselves to "try again" for this error */
1578                 break;
1579         default:
1580                 /* peer can't handle it... */
1581                 switch (param_type) {
1582                 case SCTP_ADD_IP_ADDRESS:
1583                 case SCTP_DEL_IP_ADDRESS:
1584                 case SCTP_SET_PRIM_ADDR:
1585                         break;
1586                 default:
1587                         break;
1588                 }
1589         }
1590 }
1591
1592 /*
1593  * process an asconf queue param.
1594  * aparam: parameter to process, will be removed from the queue.
1595  * flag: 1=success case, 0=failure case
1596  */
1597 static void
1598 sctp_asconf_process_param_ack(struct sctp_tcb *stcb,
1599     struct sctp_asconf_addr *aparam, uint32_t flag)
1600 {
1601         uint16_t param_type;
1602
1603         /* process this param */
1604         param_type = aparam->ap.aph.ph.param_type;
1605         switch (param_type) {
1606         case SCTP_ADD_IP_ADDRESS:
1607                 SCTPDBG(SCTP_DEBUG_ASCONF1,
1608                     "process_param_ack: added IP address\n");
1609                 sctp_asconf_addr_mgmt_ack(stcb, aparam->ifa, flag);
1610                 break;
1611         case SCTP_DEL_IP_ADDRESS:
1612                 SCTPDBG(SCTP_DEBUG_ASCONF1,
1613                     "process_param_ack: deleted IP address\n");
1614                 /* nothing really to do... lists already updated */
1615                 break;
1616         case SCTP_SET_PRIM_ADDR:
1617                 SCTPDBG(SCTP_DEBUG_ASCONF1,
1618                     "process_param_ack: set primary IP address\n");
1619                 /* nothing to do... peer may start using this addr */
1620                 break;
1621         default:
1622                 /* should NEVER happen */
1623                 break;
1624         }
1625
1626         /* remove the param and free it */
1627         TAILQ_REMOVE(&stcb->asoc.asconf_queue, aparam, next);
1628         if (aparam->ifa)
1629                 sctp_free_ifa(aparam->ifa);
1630         SCTP_FREE(aparam, SCTP_M_ASC_ADDR);
1631 }
1632
1633 /*
1634  * cleanup from a bad asconf ack parameter
1635  */
1636 static void
1637 sctp_asconf_ack_clear(struct sctp_tcb *stcb SCTP_UNUSED)
1638 {
1639         /* assume peer doesn't really know how to do asconfs */
1640         /* XXX we could free the pending queue here */
1641
1642 }
1643
1644 void
1645 sctp_handle_asconf_ack(struct mbuf *m, int offset,
1646     struct sctp_asconf_ack_chunk *cp, struct sctp_tcb *stcb,
1647     struct sctp_nets *net, int *abort_no_unlock)
1648 {
1649         struct sctp_association *asoc;
1650         uint32_t serial_num;
1651         uint16_t ack_length;
1652         struct sctp_asconf_paramhdr *aph;
1653         struct sctp_asconf_addr *aa, *aa_next;
1654         uint32_t last_error_id = 0;     /* last error correlation id */
1655         uint32_t id;
1656         struct sctp_asconf_addr *ap;
1657
1658         /* asconf param buffer */
1659         uint8_t aparam_buf[SCTP_PARAM_BUFFER_SIZE];
1660
1661         /* verify minimum length */
1662         if (ntohs(cp->ch.chunk_length) < sizeof(struct sctp_asconf_ack_chunk)) {
1663                 SCTPDBG(SCTP_DEBUG_ASCONF1,
1664                     "handle_asconf_ack: chunk too small = %xh\n",
1665                     ntohs(cp->ch.chunk_length));
1666                 return;
1667         }
1668         asoc = &stcb->asoc;
1669         serial_num = ntohl(cp->serial_number);
1670
1671         /*
1672          * NOTE: we may want to handle this differently- currently, we will
1673          * abort when we get an ack for the expected serial number + 1 (eg.
1674          * we didn't send it), process an ack normally if it is the expected
1675          * serial number, and re-send the previous ack for *ALL* other
1676          * serial numbers
1677          */
1678
1679         /*
1680          * if the serial number is the next expected, but I didn't send it,
1681          * abort the asoc, since someone probably just hijacked us...
1682          */
1683         if (serial_num == (asoc->asconf_seq_out + 1)) {
1684                 struct mbuf *op_err;
1685                 char msg[SCTP_DIAG_INFO_LEN];
1686
1687                 SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf_ack: got unexpected next serial number! Aborting asoc!\n");
1688                 snprintf(msg, sizeof(msg), "Never sent serial number %8.8x",
1689                     serial_num);
1690                 op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
1691                 sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
1692                 *abort_no_unlock = 1;
1693                 return;
1694         }
1695         if (serial_num != asoc->asconf_seq_out_acked + 1) {
1696                 /* got a duplicate/unexpected ASCONF-ACK */
1697                 SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf_ack: got duplicate/unexpected serial number = %xh (expected = %xh)\n",
1698                     serial_num, asoc->asconf_seq_out_acked + 1);
1699                 return;
1700         }
1701
1702         if (serial_num == asoc->asconf_seq_out - 1) {
1703                 /* stop our timer */
1704                 sctp_timer_stop(SCTP_TIMER_TYPE_ASCONF, stcb->sctp_ep, stcb, net,
1705                     SCTP_FROM_SCTP_ASCONF + SCTP_LOC_5);
1706         }
1707
1708         /* process the ASCONF-ACK contents */
1709         ack_length = ntohs(cp->ch.chunk_length) -
1710             sizeof(struct sctp_asconf_ack_chunk);
1711         offset += sizeof(struct sctp_asconf_ack_chunk);
1712         /* process through all parameters */
1713         while (ack_length >= sizeof(struct sctp_asconf_paramhdr)) {
1714                 unsigned int param_length, param_type;
1715
1716                 /* get pointer to next asconf parameter */
1717                 aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(m, offset,
1718                     sizeof(struct sctp_asconf_paramhdr), aparam_buf);
1719                 if (aph == NULL) {
1720                         /* can't get an asconf paramhdr */
1721                         sctp_asconf_ack_clear(stcb);
1722                         return;
1723                 }
1724                 param_type = ntohs(aph->ph.param_type);
1725                 param_length = ntohs(aph->ph.param_length);
1726                 if (param_length > ack_length) {
1727                         sctp_asconf_ack_clear(stcb);
1728                         return;
1729                 }
1730                 if (param_length < sizeof(struct sctp_paramhdr)) {
1731                         sctp_asconf_ack_clear(stcb);
1732                         return;
1733                 }
1734                 /* get the complete parameter... */
1735                 if (param_length > sizeof(aparam_buf)) {
1736                         SCTPDBG(SCTP_DEBUG_ASCONF1,
1737                             "param length (%u) larger than buffer size!\n", param_length);
1738                         sctp_asconf_ack_clear(stcb);
1739                         return;
1740                 }
1741                 aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(m, offset, param_length, aparam_buf);
1742                 if (aph == NULL) {
1743                         sctp_asconf_ack_clear(stcb);
1744                         return;
1745                 }
1746                 /* correlation_id is transparent to peer, no ntohl needed */
1747                 id = aph->correlation_id;
1748
1749                 switch (param_type) {
1750                 case SCTP_ERROR_CAUSE_IND:
1751                         last_error_id = id;
1752                         /* find the corresponding asconf param in our queue */
1753                         ap = sctp_asconf_find_param(stcb, id);
1754                         if (ap == NULL) {
1755                                 /* hmm... can't find this in our queue! */
1756                                 break;
1757                         }
1758                         /* process the parameter, failed flag */
1759                         sctp_asconf_process_param_ack(stcb, ap, 0);
1760                         /* process the error response */
1761                         sctp_asconf_process_error(stcb, aph);
1762                         break;
1763                 case SCTP_SUCCESS_REPORT:
1764                         /* find the corresponding asconf param in our queue */
1765                         ap = sctp_asconf_find_param(stcb, id);
1766                         if (ap == NULL) {
1767                                 /* hmm... can't find this in our queue! */
1768                                 break;
1769                         }
1770                         /* process the parameter, success flag */
1771                         sctp_asconf_process_param_ack(stcb, ap, 1);
1772                         break;
1773                 default:
1774                         break;
1775                 }               /* switch */
1776
1777                 /* update remaining ASCONF-ACK message length to process */
1778                 ack_length -= SCTP_SIZE32(param_length);
1779                 if (ack_length <= 0) {
1780                         /* no more data in the mbuf chain */
1781                         break;
1782                 }
1783                 offset += SCTP_SIZE32(param_length);
1784         }                       /* while */
1785
1786         /*
1787          * if there are any "sent" params still on the queue, these are
1788          * implicitly "success", or "failed" (if we got an error back) ...
1789          * so process these appropriately
1790          *
1791          * we assume that the correlation_id's are monotonically increasing
1792          * beginning from 1 and that we don't have *that* many outstanding
1793          * at any given time
1794          */
1795         if (last_error_id == 0)
1796                 last_error_id--;        /* set to "max" value */
1797         TAILQ_FOREACH_SAFE(aa, &stcb->asoc.asconf_queue, next, aa_next) {
1798                 if (aa->sent == 1) {
1799                         /*
1800                          * implicitly successful or failed if correlation_id
1801                          * < last_error_id, then success else, failure
1802                          */
1803                         if (aa->ap.aph.correlation_id < last_error_id)
1804                                 sctp_asconf_process_param_ack(stcb, aa, 1);
1805                         else
1806                                 sctp_asconf_process_param_ack(stcb, aa, 0);
1807                 } else {
1808                         /*
1809                          * since we always process in order (FIFO queue) if
1810                          * we reach one that hasn't been sent, the rest
1811                          * should not have been sent either. so, we're
1812                          * done...
1813                          */
1814                         break;
1815                 }
1816         }
1817
1818         /* update the next sequence number to use */
1819         asoc->asconf_seq_out_acked++;
1820         /* remove the old ASCONF on our outbound queue */
1821         sctp_toss_old_asconf(stcb);
1822         if (!TAILQ_EMPTY(&stcb->asoc.asconf_queue)) {
1823 #ifdef SCTP_TIMER_BASED_ASCONF
1824                 /* we have more params, so restart our timer */
1825                 sctp_timer_start(SCTP_TIMER_TYPE_ASCONF, stcb->sctp_ep,
1826                     stcb, net);
1827 #else
1828                 /* we have more params, so send out more */
1829                 sctp_send_asconf(stcb, net, SCTP_ADDR_NOT_LOCKED);
1830 #endif
1831         }
1832 }
1833
1834 #ifdef INET6
1835 static uint32_t
1836 sctp_is_scopeid_in_nets(struct sctp_tcb *stcb, struct sockaddr *sa)
1837 {
1838         struct sockaddr_in6 *sin6, *net6;
1839         struct sctp_nets *net;
1840
1841         if (sa->sa_family != AF_INET6) {
1842                 /* wrong family */
1843                 return (0);
1844         }
1845         sin6 = (struct sockaddr_in6 *)sa;
1846         if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) == 0) {
1847                 /* not link local address */
1848                 return (0);
1849         }
1850         /* hunt through our destination nets list for this scope_id */
1851         TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
1852                 if (((struct sockaddr *)(&net->ro._l_addr))->sa_family !=
1853                     AF_INET6)
1854                         continue;
1855                 net6 = (struct sockaddr_in6 *)&net->ro._l_addr;
1856                 if (IN6_IS_ADDR_LINKLOCAL(&net6->sin6_addr) == 0)
1857                         continue;
1858                 if (sctp_is_same_scope(sin6, net6)) {
1859                         /* found one */
1860                         return (1);
1861                 }
1862         }
1863         /* didn't find one */
1864         return (0);
1865 }
1866 #endif
1867
1868 /*
1869  * address management functions
1870  */
1871 static void
1872 sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
1873     struct sctp_ifa *ifa, uint16_t type, int addr_locked)
1874 {
1875         int status;
1876
1877         if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0 ||
1878             sctp_is_feature_off(inp, SCTP_PCB_FLAGS_DO_ASCONF)) {
1879                 /* subset bound, no ASCONF allowed case, so ignore */
1880                 return;
1881         }
1882         /*
1883          * note: we know this is not the subset bound, no ASCONF case eg.
1884          * this is boundall or subset bound w/ASCONF allowed
1885          */
1886
1887         /* first, make sure that the address is IPv4 or IPv6 and not jailed */
1888         switch (ifa->address.sa.sa_family) {
1889 #ifdef INET6
1890         case AF_INET6:
1891                 if (prison_check_ip6(inp->ip_inp.inp.inp_cred,
1892                     &ifa->address.sin6.sin6_addr) != 0) {
1893                         return;
1894                 }
1895                 break;
1896 #endif
1897 #ifdef INET
1898         case AF_INET:
1899                 if (prison_check_ip4(inp->ip_inp.inp.inp_cred,
1900                     &ifa->address.sin.sin_addr) != 0) {
1901                         return;
1902                 }
1903                 break;
1904 #endif
1905         default:
1906                 return;
1907         }
1908 #ifdef INET6
1909         /* make sure we're "allowed" to add this type of addr */
1910         if (ifa->address.sa.sa_family == AF_INET6) {
1911                 /* invalid if we're not a v6 endpoint */
1912                 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0)
1913                         return;
1914                 /* is the v6 addr really valid ? */
1915                 if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
1916                         return;
1917                 }
1918         }
1919 #endif
1920         /* put this address on the "pending/do not use yet" list */
1921         sctp_add_local_addr_restricted(stcb, ifa);
1922         /*
1923          * check address scope if address is out of scope, don't queue
1924          * anything... note: this would leave the address on both inp and
1925          * asoc lists
1926          */
1927         switch (ifa->address.sa.sa_family) {
1928 #ifdef INET6
1929         case AF_INET6:
1930                 {
1931                         struct sockaddr_in6 *sin6;
1932
1933                         sin6 = &ifa->address.sin6;
1934                         if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
1935                                 /* we skip unspecifed addresses */
1936                                 return;
1937                         }
1938                         if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
1939                                 if (stcb->asoc.scope.local_scope == 0) {
1940                                         return;
1941                                 }
1942                                 /* is it the right link local scope? */
1943                                 if (sctp_is_scopeid_in_nets(stcb, &ifa->address.sa) == 0) {
1944                                         return;
1945                                 }
1946                         }
1947                         if (stcb->asoc.scope.site_scope == 0 &&
1948                             IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) {
1949                                 return;
1950                         }
1951                         break;
1952                 }
1953 #endif
1954 #ifdef INET
1955         case AF_INET:
1956                 {
1957                         struct sockaddr_in *sin;
1958
1959                         /* invalid if we are a v6 only endpoint */
1960                         if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
1961                             SCTP_IPV6_V6ONLY(inp))
1962                                 return;
1963
1964                         sin = &ifa->address.sin;
1965                         if (sin->sin_addr.s_addr == 0) {
1966                                 /* we skip unspecifed addresses */
1967                                 return;
1968                         }
1969                         if (stcb->asoc.scope.ipv4_local_scope == 0 &&
1970                             IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
1971                                 return;
1972                         }
1973                         break;
1974                 }
1975 #endif
1976         default:
1977                 /* else, not AF_INET or AF_INET6, so skip */
1978                 return;
1979         }
1980
1981         /* queue an asconf for this address add/delete */
1982         if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_DO_ASCONF)) {
1983                 /* does the peer do asconf? */
1984                 if (stcb->asoc.asconf_supported) {
1985                         /* queue an asconf for this addr */
1986                         status = sctp_asconf_queue_add(stcb, ifa, type);
1987
1988                         /*
1989                          * if queued ok, and in the open state, send out the
1990                          * ASCONF.  If in the non-open state, these will be
1991                          * sent when the state goes open.
1992                          */
1993                         if (status == 0 &&
1994                             ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) ||
1995                             (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED))) {
1996 #ifdef SCTP_TIMER_BASED_ASCONF
1997                                 sctp_timer_start(SCTP_TIMER_TYPE_ASCONF, inp,
1998                                     stcb, stcb->asoc.primary_destination);
1999 #else
2000                                 sctp_send_asconf(stcb, NULL, addr_locked);
2001 #endif
2002                         }
2003                 }
2004         }
2005 }
2006
2007
2008 int
2009 sctp_asconf_iterator_ep(struct sctp_inpcb *inp, void *ptr, uint32_t val SCTP_UNUSED)
2010 {
2011         struct sctp_asconf_iterator *asc;
2012         struct sctp_ifa *ifa;
2013         struct sctp_laddr *l;
2014         int cnt_invalid = 0;
2015
2016         asc = (struct sctp_asconf_iterator *)ptr;
2017         LIST_FOREACH(l, &asc->list_of_work, sctp_nxt_addr) {
2018                 ifa = l->ifa;
2019                 switch (ifa->address.sa.sa_family) {
2020 #ifdef INET6
2021                 case AF_INET6:
2022                         /* invalid if we're not a v6 endpoint */
2023                         if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
2024                                 cnt_invalid++;
2025                                 if (asc->cnt == cnt_invalid)
2026                                         return (1);
2027                         }
2028                         break;
2029 #endif
2030 #ifdef INET
2031                 case AF_INET:
2032                         {
2033                                 /* invalid if we are a v6 only endpoint */
2034                                 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
2035                                     SCTP_IPV6_V6ONLY(inp)) {
2036                                         cnt_invalid++;
2037                                         if (asc->cnt == cnt_invalid)
2038                                                 return (1);
2039                                 }
2040                                 break;
2041                         }
2042 #endif
2043                 default:
2044                         /* invalid address family */
2045                         cnt_invalid++;
2046                         if (asc->cnt == cnt_invalid)
2047                                 return (1);
2048                 }
2049         }
2050         return (0);
2051 }
2052
2053 static int
2054 sctp_asconf_iterator_ep_end(struct sctp_inpcb *inp, void *ptr, uint32_t val SCTP_UNUSED)
2055 {
2056         struct sctp_ifa *ifa;
2057         struct sctp_asconf_iterator *asc;
2058         struct sctp_laddr *laddr, *nladdr, *l;
2059
2060         /* Only for specific case not bound all */
2061         asc = (struct sctp_asconf_iterator *)ptr;
2062         LIST_FOREACH(l, &asc->list_of_work, sctp_nxt_addr) {
2063                 ifa = l->ifa;
2064                 if (l->action == SCTP_ADD_IP_ADDRESS) {
2065                         LIST_FOREACH(laddr, &inp->sctp_addr_list,
2066                             sctp_nxt_addr) {
2067                                 if (laddr->ifa == ifa) {
2068                                         laddr->action = 0;
2069                                         break;
2070                                 }
2071
2072                         }
2073                 } else if (l->action == SCTP_DEL_IP_ADDRESS) {
2074                         LIST_FOREACH_SAFE(laddr, &inp->sctp_addr_list, sctp_nxt_addr, nladdr) {
2075                                 /* remove only after all guys are done */
2076                                 if (laddr->ifa == ifa) {
2077                                         sctp_del_local_addr_ep(inp, ifa);
2078                                 }
2079                         }
2080                 }
2081         }
2082         return (0);
2083 }
2084
2085 void
2086 sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
2087     void *ptr, uint32_t val SCTP_UNUSED)
2088 {
2089         struct sctp_asconf_iterator *asc;
2090         struct sctp_ifa *ifa;
2091         struct sctp_laddr *l;
2092         int cnt_invalid = 0;
2093         int type, status;
2094         int num_queued = 0;
2095
2096         asc = (struct sctp_asconf_iterator *)ptr;
2097         LIST_FOREACH(l, &asc->list_of_work, sctp_nxt_addr) {
2098                 ifa = l->ifa;
2099                 type = l->action;
2100
2101                 /* address's vrf_id must be the vrf_id of the assoc */
2102                 if (ifa->vrf_id != stcb->asoc.vrf_id) {
2103                         continue;
2104                 }
2105
2106                 /* Same checks again for assoc */
2107                 switch (ifa->address.sa.sa_family) {
2108 #ifdef INET6
2109                 case AF_INET6:
2110                         {
2111                                 /* invalid if we're not a v6 endpoint */
2112                                 struct sockaddr_in6 *sin6;
2113
2114                                 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
2115                                         cnt_invalid++;
2116                                         if (asc->cnt == cnt_invalid)
2117                                                 return;
2118                                         else
2119                                                 continue;
2120                                 }
2121                                 sin6 = &ifa->address.sin6;
2122                                 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
2123                                         /* we skip unspecifed addresses */
2124                                         continue;
2125                                 }
2126                                 if (prison_check_ip6(inp->ip_inp.inp.inp_cred,
2127                                     &sin6->sin6_addr) != 0) {
2128                                         continue;
2129                                 }
2130                                 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
2131                                         if (stcb->asoc.scope.local_scope == 0) {
2132                                                 continue;
2133                                         }
2134                                         /* is it the right link local scope? */
2135                                         if (sctp_is_scopeid_in_nets(stcb, &ifa->address.sa) == 0) {
2136                                                 continue;
2137                                         }
2138                                 }
2139                                 break;
2140                         }
2141 #endif
2142 #ifdef INET
2143                 case AF_INET:
2144                         {
2145                                 /* invalid if we are a v6 only endpoint */
2146                                 struct sockaddr_in *sin;
2147
2148                                 /* invalid if we are a v6 only endpoint */
2149                                 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
2150                                     SCTP_IPV6_V6ONLY(inp))
2151                                         continue;
2152
2153                                 sin = &ifa->address.sin;
2154                                 if (sin->sin_addr.s_addr == 0) {
2155                                         /* we skip unspecifed addresses */
2156                                         continue;
2157                                 }
2158                                 if (prison_check_ip4(inp->ip_inp.inp.inp_cred,
2159                                     &sin->sin_addr) != 0) {
2160                                         continue;
2161                                 }
2162                                 if (stcb->asoc.scope.ipv4_local_scope == 0 &&
2163                                     IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
2164                                         continue;
2165                                 }
2166                                 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
2167                                     SCTP_IPV6_V6ONLY(inp)) {
2168                                         cnt_invalid++;
2169                                         if (asc->cnt == cnt_invalid)
2170                                                 return;
2171                                         else
2172                                                 continue;
2173                                 }
2174                                 break;
2175                         }
2176 #endif
2177                 default:
2178                         /* invalid address family */
2179                         cnt_invalid++;
2180                         if (asc->cnt == cnt_invalid)
2181                                 return;
2182                         else
2183                                 continue;
2184                         break;
2185                 }
2186
2187                 if (type == SCTP_ADD_IP_ADDRESS) {
2188                         /* prevent this address from being used as a source */
2189                         sctp_add_local_addr_restricted(stcb, ifa);
2190                 } else if (type == SCTP_DEL_IP_ADDRESS) {
2191                         struct sctp_nets *net;
2192
2193                         TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
2194                                 sctp_rtentry_t *rt;
2195
2196                                 /* delete this address if cached */
2197                                 if (net->ro._s_addr == ifa) {
2198                                         sctp_free_ifa(net->ro._s_addr);
2199                                         net->ro._s_addr = NULL;
2200                                         net->src_addr_selected = 0;
2201                                         rt = net->ro.ro_rt;
2202                                         if (rt) {
2203                                                 RTFREE(rt);
2204                                                 net->ro.ro_rt = NULL;
2205                                         }
2206                                         /*
2207                                          * Now we deleted our src address,
2208                                          * should we not also now reset the
2209                                          * cwnd/rto to start as if its a new
2210                                          * address?
2211                                          */
2212                                         stcb->asoc.cc_functions.sctp_set_initial_cc_param(stcb, net);
2213                                         net->RTO = 0;
2214
2215                                 }
2216                         }
2217                 } else if (type == SCTP_SET_PRIM_ADDR) {
2218                         if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) {
2219                                 /* must validate the ifa is in the ep */
2220                                 if (sctp_is_addr_in_ep(stcb->sctp_ep, ifa) == 0) {
2221                                         continue;
2222                                 }
2223                         } else {
2224                                 /* Need to check scopes for this guy */
2225                                 if (sctp_is_address_in_scope(ifa, &stcb->asoc.scope, 0) == 0) {
2226                                         continue;
2227                                 }
2228                         }
2229                 }
2230                 /* queue an asconf for this address add/delete */
2231                 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_DO_ASCONF) &&
2232                     stcb->asoc.asconf_supported == 1) {
2233                         /* queue an asconf for this addr */
2234                         status = sctp_asconf_queue_add(stcb, ifa, type);
2235                         /*
2236                          * if queued ok, and in the open state, update the
2237                          * count of queued params.  If in the non-open
2238                          * state, these get sent when the assoc goes open.
2239                          */
2240                         if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) ||
2241                             (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
2242                                 if (status >= 0) {
2243                                         num_queued++;
2244                                 }
2245                         }
2246                 }
2247         }
2248         /*
2249          * If we have queued params in the open state, send out an ASCONF.
2250          */
2251         if (num_queued > 0) {
2252                 sctp_send_asconf(stcb, NULL, SCTP_ADDR_NOT_LOCKED);
2253         }
2254 }
2255
2256 void
2257 sctp_asconf_iterator_end(void *ptr, uint32_t val SCTP_UNUSED)
2258 {
2259         struct sctp_asconf_iterator *asc;
2260         struct sctp_ifa *ifa;
2261         struct sctp_laddr *l, *nl;
2262
2263         asc = (struct sctp_asconf_iterator *)ptr;
2264         LIST_FOREACH_SAFE(l, &asc->list_of_work, sctp_nxt_addr, nl) {
2265                 ifa = l->ifa;
2266                 if (l->action == SCTP_ADD_IP_ADDRESS) {
2267                         /* Clear the defer use flag */
2268                         ifa->localifa_flags &= ~SCTP_ADDR_DEFER_USE;
2269                 }
2270                 sctp_free_ifa(ifa);
2271                 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_laddr), l);
2272                 SCTP_DECR_LADDR_COUNT();
2273         }
2274         SCTP_FREE(asc, SCTP_M_ASC_IT);
2275 }
2276
2277 /*
2278  * sa is the sockaddr to ask the peer to set primary to.
2279  * returns: 0 = completed, -1 = error
2280  */
2281 int32_t
2282 sctp_set_primary_ip_address_sa(struct sctp_tcb *stcb, struct sockaddr *sa)
2283 {
2284         uint32_t vrf_id;
2285         struct sctp_ifa *ifa;
2286
2287         /* find the ifa for the desired set primary */
2288         vrf_id = stcb->asoc.vrf_id;
2289         ifa = sctp_find_ifa_by_addr(sa, vrf_id, SCTP_ADDR_NOT_LOCKED);
2290         if (ifa == NULL) {
2291                 /* Invalid address */
2292                 return (-1);
2293         }
2294
2295         /* queue an ASCONF:SET_PRIM_ADDR to be sent */
2296         if (!sctp_asconf_queue_add(stcb, ifa, SCTP_SET_PRIM_ADDR)) {
2297                 /* set primary queuing succeeded */
2298                 SCTPDBG(SCTP_DEBUG_ASCONF1,
2299                     "set_primary_ip_address_sa: queued on tcb=%p, ",
2300                     (void *)stcb);
2301                 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
2302                 if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) ||
2303                     (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
2304 #ifdef SCTP_TIMER_BASED_ASCONF
2305                         sctp_timer_start(SCTP_TIMER_TYPE_ASCONF,
2306                             stcb->sctp_ep, stcb,
2307                             stcb->asoc.primary_destination);
2308 #else
2309                         sctp_send_asconf(stcb, NULL, SCTP_ADDR_NOT_LOCKED);
2310 #endif
2311                 }
2312         } else {
2313                 SCTPDBG(SCTP_DEBUG_ASCONF1, "set_primary_ip_address_sa: failed to add to queue on tcb=%p, ",
2314                     (void *)stcb);
2315                 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
2316                 return (-1);
2317         }
2318         return (0);
2319 }
2320
2321 int
2322 sctp_is_addr_pending(struct sctp_tcb *stcb, struct sctp_ifa *sctp_ifa)
2323 {
2324         struct sctp_tmit_chunk *chk, *nchk;
2325         unsigned int offset, asconf_limit;
2326         struct sctp_asconf_chunk *acp;
2327         struct sctp_asconf_paramhdr *aph;
2328         uint8_t aparam_buf[SCTP_PARAM_BUFFER_SIZE];
2329         struct sctp_paramhdr *ph;
2330         int add_cnt, del_cnt;
2331         uint16_t last_param_type;
2332
2333         add_cnt = del_cnt = 0;
2334         last_param_type = 0;
2335         TAILQ_FOREACH_SAFE(chk, &stcb->asoc.asconf_send_queue, sctp_next, nchk) {
2336                 if (chk->data == NULL) {
2337                         SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: No mbuf data?\n");
2338                         continue;
2339                 }
2340                 offset = 0;
2341                 acp = mtod(chk->data, struct sctp_asconf_chunk *);
2342                 offset += sizeof(struct sctp_asconf_chunk);
2343                 asconf_limit = ntohs(acp->ch.chunk_length);
2344                 ph = (struct sctp_paramhdr *)sctp_m_getptr(chk->data, offset, sizeof(struct sctp_paramhdr), aparam_buf);
2345                 if (ph == NULL) {
2346                         SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: couldn't get lookup addr!\n");
2347                         continue;
2348                 }
2349                 offset += ntohs(ph->param_length);
2350
2351                 aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(chk->data, offset, sizeof(struct sctp_asconf_paramhdr), aparam_buf);
2352                 if (aph == NULL) {
2353                         SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: Empty ASCONF will be sent?\n");
2354                         continue;
2355                 }
2356                 while (aph != NULL) {
2357                         unsigned int param_length, param_type;
2358
2359                         param_type = ntohs(aph->ph.param_type);
2360                         param_length = ntohs(aph->ph.param_length);
2361                         if (offset + param_length > asconf_limit) {
2362                                 /* parameter goes beyond end of chunk! */
2363                                 break;
2364                         }
2365                         if (param_length > sizeof(aparam_buf)) {
2366                                 SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: param length (%u) larger than buffer size!\n", param_length);
2367                                 break;
2368                         }
2369                         if (param_length <= sizeof(struct sctp_paramhdr)) {
2370                                 SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: param length(%u) too short\n", param_length);
2371                                 break;
2372                         }
2373
2374                         aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(chk->data, offset, param_length, aparam_buf);
2375                         if (aph == NULL) {
2376                                 SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: couldn't get entire param\n");
2377                                 break;
2378                         }
2379
2380                         ph = (struct sctp_paramhdr *)(aph + 1);
2381                         if (sctp_addr_match(ph, &sctp_ifa->address.sa) != 0) {
2382                                 switch (param_type) {
2383                                 case SCTP_ADD_IP_ADDRESS:
2384                                         add_cnt++;
2385                                         break;
2386                                 case SCTP_DEL_IP_ADDRESS:
2387                                         del_cnt++;
2388                                         break;
2389                                 default:
2390                                         break;
2391                                 }
2392                                 last_param_type = param_type;
2393                         }
2394
2395                         offset += SCTP_SIZE32(param_length);
2396                         if (offset >= asconf_limit) {
2397                                 /* no more data in the mbuf chain */
2398                                 break;
2399                         }
2400                         /* get pointer to next asconf param */
2401                         aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(chk->data, offset, sizeof(struct sctp_asconf_paramhdr), aparam_buf);
2402                 }
2403         }
2404
2405         /*
2406          * we want to find the sequences which consist of ADD -> DEL -> ADD
2407          * or DEL -> ADD
2408          */
2409         if (add_cnt > del_cnt ||
2410             (add_cnt == del_cnt && last_param_type == SCTP_ADD_IP_ADDRESS)) {
2411                 return (1);
2412         }
2413         return (0);
2414 }
2415
2416 static struct sockaddr *
2417 sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked)
2418 {
2419         struct sctp_vrf *vrf = NULL;
2420         struct sctp_ifn *sctp_ifn;
2421         struct sctp_ifa *sctp_ifa;
2422
2423         if (addr_locked == SCTP_ADDR_NOT_LOCKED)
2424                 SCTP_IPI_ADDR_RLOCK();
2425         vrf = sctp_find_vrf(stcb->asoc.vrf_id);
2426         if (vrf == NULL) {
2427                 if (addr_locked == SCTP_ADDR_NOT_LOCKED)
2428                         SCTP_IPI_ADDR_RUNLOCK();
2429                 return (NULL);
2430         }
2431         LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
2432                 if (stcb->asoc.scope.loopback_scope == 0 &&
2433                     SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) {
2434                         /* Skip if loopback_scope not set */
2435                         continue;
2436                 }
2437                 LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
2438                         switch (sctp_ifa->address.sa.sa_family) {
2439 #ifdef INET
2440                         case AF_INET:
2441                                 if (stcb->asoc.scope.ipv4_addr_legal) {
2442                                         struct sockaddr_in *sin;
2443
2444                                         sin = &sctp_ifa->address.sin;
2445                                         if (sin->sin_addr.s_addr == 0) {
2446                                                 /* skip unspecifed addresses */
2447                                                 continue;
2448                                         }
2449                                         if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred,
2450                                             &sin->sin_addr) != 0) {
2451                                                 continue;
2452                                         }
2453                                         if (stcb->asoc.scope.ipv4_local_scope == 0 &&
2454                                             IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))
2455                                                 continue;
2456
2457                                         if (sctp_is_addr_restricted(stcb, sctp_ifa) &&
2458                                             (!sctp_is_addr_pending(stcb, sctp_ifa)))
2459                                                 continue;
2460                                         /*
2461                                          * found a valid local v4 address to
2462                                          * use
2463                                          */
2464                                         if (addr_locked == SCTP_ADDR_NOT_LOCKED)
2465                                                 SCTP_IPI_ADDR_RUNLOCK();
2466                                         return (&sctp_ifa->address.sa);
2467                                 }
2468                                 break;
2469 #endif
2470 #ifdef INET6
2471                         case AF_INET6:
2472                                 if (stcb->asoc.scope.ipv6_addr_legal) {
2473                                         struct sockaddr_in6 *sin6;
2474
2475                                         if (sctp_ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
2476                                                 continue;
2477                                         }
2478
2479                                         sin6 = &sctp_ifa->address.sin6;
2480                                         if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
2481                                                 /*
2482                                                  * we skip unspecifed
2483                                                  * addresses
2484                                                  */
2485                                                 continue;
2486                                         }
2487                                         if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred,
2488                                             &sin6->sin6_addr) != 0) {
2489                                                 continue;
2490                                         }
2491                                         if (stcb->asoc.scope.local_scope == 0 &&
2492                                             IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
2493                                                 continue;
2494                                         if (stcb->asoc.scope.site_scope == 0 &&
2495                                             IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))
2496                                                 continue;
2497
2498                                         if (sctp_is_addr_restricted(stcb, sctp_ifa) &&
2499                                             (!sctp_is_addr_pending(stcb, sctp_ifa)))
2500                                                 continue;
2501                                         /*
2502                                          * found a valid local v6 address to
2503                                          * use
2504                                          */
2505                                         if (addr_locked == SCTP_ADDR_NOT_LOCKED)
2506                                                 SCTP_IPI_ADDR_RUNLOCK();
2507                                         return (&sctp_ifa->address.sa);
2508                                 }
2509                                 break;
2510 #endif
2511                         default:
2512                                 break;
2513                         }
2514                 }
2515         }
2516         /* no valid addresses found */
2517         if (addr_locked == SCTP_ADDR_NOT_LOCKED)
2518                 SCTP_IPI_ADDR_RUNLOCK();
2519         return (NULL);
2520 }
2521
2522 static struct sockaddr *
2523 sctp_find_valid_localaddr_ep(struct sctp_tcb *stcb)
2524 {
2525         struct sctp_laddr *laddr;
2526
2527         LIST_FOREACH(laddr, &stcb->sctp_ep->sctp_addr_list, sctp_nxt_addr) {
2528                 if (laddr->ifa == NULL) {
2529                         continue;
2530                 }
2531                 /* is the address restricted ? */
2532                 if (sctp_is_addr_restricted(stcb, laddr->ifa) &&
2533                     (!sctp_is_addr_pending(stcb, laddr->ifa)))
2534                         continue;
2535
2536                 /* found a valid local address to use */
2537                 return (&laddr->ifa->address.sa);
2538         }
2539         /* no valid addresses found */
2540         return (NULL);
2541 }
2542
2543 /*
2544  * builds an ASCONF chunk from queued ASCONF params.
2545  * returns NULL on error (no mbuf, no ASCONF params queued, etc).
2546  */
2547 struct mbuf *
2548 sctp_compose_asconf(struct sctp_tcb *stcb, int *retlen, int addr_locked)
2549 {
2550         struct mbuf *m_asconf, *m_asconf_chk;
2551         struct sctp_asconf_addr *aa;
2552         struct sctp_asconf_chunk *acp;
2553         struct sctp_asconf_paramhdr *aph;
2554         struct sctp_asconf_addr_param *aap;
2555         uint32_t p_length;
2556         uint32_t correlation_id = 1;    /* 0 is reserved... */
2557         caddr_t ptr, lookup_ptr;
2558         uint8_t lookup_used = 0;
2559
2560         /* are there any asconf params to send? */
2561         TAILQ_FOREACH(aa, &stcb->asoc.asconf_queue, next) {
2562                 if (aa->sent == 0)
2563                         break;
2564         }
2565         if (aa == NULL)
2566                 return (NULL);
2567
2568         /*
2569          * get a chunk header mbuf and a cluster for the asconf params since
2570          * it's simpler to fill in the asconf chunk header lookup address on
2571          * the fly
2572          */
2573         m_asconf_chk = sctp_get_mbuf_for_msg(sizeof(struct sctp_asconf_chunk), 0, M_NOWAIT, 1, MT_DATA);
2574         if (m_asconf_chk == NULL) {
2575                 /* no mbuf's */
2576                 SCTPDBG(SCTP_DEBUG_ASCONF1,
2577                     "compose_asconf: couldn't get chunk mbuf!\n");
2578                 return (NULL);
2579         }
2580         m_asconf = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_NOWAIT, 1, MT_DATA);
2581         if (m_asconf == NULL) {
2582                 /* no mbuf's */
2583                 SCTPDBG(SCTP_DEBUG_ASCONF1,
2584                     "compose_asconf: couldn't get mbuf!\n");
2585                 sctp_m_freem(m_asconf_chk);
2586                 return (NULL);
2587         }
2588         SCTP_BUF_LEN(m_asconf_chk) = sizeof(struct sctp_asconf_chunk);
2589         SCTP_BUF_LEN(m_asconf) = 0;
2590         acp = mtod(m_asconf_chk, struct sctp_asconf_chunk *);
2591         memset(acp, 0, sizeof(struct sctp_asconf_chunk));
2592         /* save pointers to lookup address and asconf params */
2593         lookup_ptr = (caddr_t)(acp + 1);        /* after the header */
2594         ptr = mtod(m_asconf, caddr_t);  /* beginning of cluster */
2595
2596         /* fill in chunk header info */
2597         acp->ch.chunk_type = SCTP_ASCONF;
2598         acp->ch.chunk_flags = 0;
2599         acp->serial_number = htonl(stcb->asoc.asconf_seq_out);
2600         stcb->asoc.asconf_seq_out++;
2601
2602         /* add parameters... up to smallest MTU allowed */
2603         TAILQ_FOREACH(aa, &stcb->asoc.asconf_queue, next) {
2604                 if (aa->sent)
2605                         continue;
2606                 /* get the parameter length */
2607                 p_length = SCTP_SIZE32(aa->ap.aph.ph.param_length);
2608                 /* will it fit in current chunk? */
2609                 if ((SCTP_BUF_LEN(m_asconf) + p_length > stcb->asoc.smallest_mtu) ||
2610                     (SCTP_BUF_LEN(m_asconf) + p_length > MCLBYTES)) {
2611                         /* won't fit, so we're done with this chunk */
2612                         break;
2613                 }
2614                 /* assign (and store) a correlation id */
2615                 aa->ap.aph.correlation_id = correlation_id++;
2616
2617                 /*
2618                  * fill in address if we're doing a delete this is a simple
2619                  * way for us to fill in the correlation address, which
2620                  * should only be used by the peer if we're deleting our
2621                  * source address and adding a new address (e.g. renumbering
2622                  * case)
2623                  */
2624                 if (lookup_used == 0 &&
2625                     (aa->special_del == 0) &&
2626                     aa->ap.aph.ph.param_type == SCTP_DEL_IP_ADDRESS) {
2627                         struct sctp_ipv6addr_param *lookup;
2628                         uint16_t p_size, addr_size;
2629
2630                         lookup = (struct sctp_ipv6addr_param *)lookup_ptr;
2631                         lookup->ph.param_type =
2632                             htons(aa->ap.addrp.ph.param_type);
2633                         if (aa->ap.addrp.ph.param_type == SCTP_IPV6_ADDRESS) {
2634                                 /* copy IPv6 address */
2635                                 p_size = sizeof(struct sctp_ipv6addr_param);
2636                                 addr_size = sizeof(struct in6_addr);
2637                         } else {
2638                                 /* copy IPv4 address */
2639                                 p_size = sizeof(struct sctp_ipv4addr_param);
2640                                 addr_size = sizeof(struct in_addr);
2641                         }
2642                         lookup->ph.param_length = htons(SCTP_SIZE32(p_size));
2643                         memcpy(lookup->addr, &aa->ap.addrp.addr, addr_size);
2644                         SCTP_BUF_LEN(m_asconf_chk) += SCTP_SIZE32(p_size);
2645                         lookup_used = 1;
2646                 }
2647                 /* copy into current space */
2648                 memcpy(ptr, &aa->ap, p_length);
2649
2650                 /* network elements and update lengths */
2651                 aph = (struct sctp_asconf_paramhdr *)ptr;
2652                 aap = (struct sctp_asconf_addr_param *)ptr;
2653                 /* correlation_id is transparent to peer, no htonl needed */
2654                 aph->ph.param_type = htons(aph->ph.param_type);
2655                 aph->ph.param_length = htons(aph->ph.param_length);
2656                 aap->addrp.ph.param_type = htons(aap->addrp.ph.param_type);
2657                 aap->addrp.ph.param_length = htons(aap->addrp.ph.param_length);
2658
2659                 SCTP_BUF_LEN(m_asconf) += SCTP_SIZE32(p_length);
2660                 ptr += SCTP_SIZE32(p_length);
2661
2662                 /*
2663                  * these params are removed off the pending list upon
2664                  * getting an ASCONF-ACK back from the peer, just set flag
2665                  */
2666                 aa->sent = 1;
2667         }
2668         /* check to see if the lookup addr has been populated yet */
2669         if (lookup_used == 0) {
2670                 /* NOTE: if the address param is optional, can skip this... */
2671                 /* add any valid (existing) address... */
2672                 struct sctp_ipv6addr_param *lookup;
2673                 uint16_t p_size, addr_size;
2674                 struct sockaddr *found_addr;
2675                 caddr_t addr_ptr;
2676
2677                 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL)
2678                         found_addr = sctp_find_valid_localaddr(stcb,
2679                             addr_locked);
2680                 else
2681                         found_addr = sctp_find_valid_localaddr_ep(stcb);
2682
2683                 lookup = (struct sctp_ipv6addr_param *)lookup_ptr;
2684                 if (found_addr != NULL) {
2685                         switch (found_addr->sa_family) {
2686 #ifdef INET6
2687                         case AF_INET6:
2688                                 /* copy IPv6 address */
2689                                 lookup->ph.param_type =
2690                                     htons(SCTP_IPV6_ADDRESS);
2691                                 p_size = sizeof(struct sctp_ipv6addr_param);
2692                                 addr_size = sizeof(struct in6_addr);
2693                                 addr_ptr = (caddr_t)&((struct sockaddr_in6 *)
2694                                     found_addr)->sin6_addr;
2695                                 break;
2696 #endif
2697 #ifdef INET
2698                         case AF_INET:
2699                                 /* copy IPv4 address */
2700                                 lookup->ph.param_type =
2701                                     htons(SCTP_IPV4_ADDRESS);
2702                                 p_size = sizeof(struct sctp_ipv4addr_param);
2703                                 addr_size = sizeof(struct in_addr);
2704                                 addr_ptr = (caddr_t)&((struct sockaddr_in *)
2705                                     found_addr)->sin_addr;
2706                                 break;
2707 #endif
2708                         default:
2709                                 p_size = 0;
2710                                 addr_size = 0;
2711                                 addr_ptr = NULL;
2712                                 break;
2713                         }
2714                         lookup->ph.param_length = htons(SCTP_SIZE32(p_size));
2715                         memcpy(lookup->addr, addr_ptr, addr_size);
2716                         SCTP_BUF_LEN(m_asconf_chk) += SCTP_SIZE32(p_size);
2717                 } else {
2718                         /* uh oh... don't have any address?? */
2719                         SCTPDBG(SCTP_DEBUG_ASCONF1,
2720                             "compose_asconf: no lookup addr!\n");
2721                         /* XXX for now, we send a IPv4 address of 0.0.0.0 */
2722                         lookup->ph.param_type = htons(SCTP_IPV4_ADDRESS);
2723                         lookup->ph.param_length = htons(SCTP_SIZE32(sizeof(struct sctp_ipv4addr_param)));
2724                         memset(lookup->addr, 0, sizeof(struct in_addr));
2725                         SCTP_BUF_LEN(m_asconf_chk) += SCTP_SIZE32(sizeof(struct sctp_ipv4addr_param));
2726                 }
2727         }
2728         /* chain it all together */
2729         SCTP_BUF_NEXT(m_asconf_chk) = m_asconf;
2730         *retlen = SCTP_BUF_LEN(m_asconf_chk) + SCTP_BUF_LEN(m_asconf);
2731         acp->ch.chunk_length = htons(*retlen);
2732
2733         return (m_asconf_chk);
2734 }
2735
2736 /*
2737  * section to handle address changes before an association is up eg. changes
2738  * during INIT/INIT-ACK/COOKIE-ECHO handshake
2739  */
2740
2741 /*
2742  * processes the (local) addresses in the INIT-ACK chunk
2743  */
2744 static void
2745 sctp_process_initack_addresses(struct sctp_tcb *stcb, struct mbuf *m,
2746     unsigned int offset, unsigned int length)
2747 {
2748         struct sctp_paramhdr tmp_param, *ph;
2749         uint16_t plen, ptype;
2750         struct sctp_ifa *sctp_ifa;
2751         union sctp_sockstore store;
2752 #ifdef INET6
2753         struct sctp_ipv6addr_param addr6_store;
2754 #endif
2755 #ifdef INET
2756         struct sctp_ipv4addr_param addr4_store;
2757 #endif
2758
2759         SCTPDBG(SCTP_DEBUG_ASCONF2, "processing init-ack addresses\n");
2760         if (stcb == NULL)       /* Un-needed check for SA */
2761                 return;
2762
2763         /* convert to upper bound */
2764         length += offset;
2765
2766         if ((offset + sizeof(struct sctp_paramhdr)) > length) {
2767                 return;
2768         }
2769         /* go through the addresses in the init-ack */
2770         ph = (struct sctp_paramhdr *)
2771             sctp_m_getptr(m, offset, sizeof(struct sctp_paramhdr),
2772             (uint8_t *)&tmp_param);
2773         while (ph != NULL) {
2774                 ptype = ntohs(ph->param_type);
2775                 plen = ntohs(ph->param_length);
2776                 switch (ptype) {
2777 #ifdef INET6
2778                 case SCTP_IPV6_ADDRESS:
2779                         {
2780                                 struct sctp_ipv6addr_param *a6p;
2781
2782                                 /* get the entire IPv6 address param */
2783                                 a6p = (struct sctp_ipv6addr_param *)
2784                                     sctp_m_getptr(m, offset,
2785                                     sizeof(struct sctp_ipv6addr_param),
2786                                     (uint8_t *)&addr6_store);
2787                                 if (plen != sizeof(struct sctp_ipv6addr_param) ||
2788                                     a6p == NULL) {
2789                                         return;
2790                                 }
2791                                 memset(&store, 0, sizeof(union sctp_sockstore));
2792                                 store.sin6.sin6_family = AF_INET6;
2793                                 store.sin6.sin6_len = sizeof(struct sockaddr_in6);
2794                                 store.sin6.sin6_port = stcb->rport;
2795                                 memcpy(&store.sin6.sin6_addr, a6p->addr, sizeof(struct in6_addr));
2796                                 break;
2797                         }
2798 #endif
2799 #ifdef INET
2800                 case SCTP_IPV4_ADDRESS:
2801                         {
2802                                 struct sctp_ipv4addr_param *a4p;
2803
2804                                 /* get the entire IPv4 address param */
2805                                 a4p = (struct sctp_ipv4addr_param *)sctp_m_getptr(m, offset,
2806                                     sizeof(struct sctp_ipv4addr_param),
2807                                     (uint8_t *)&addr4_store);
2808                                 if (plen != sizeof(struct sctp_ipv4addr_param) ||
2809                                     a4p == NULL) {
2810                                         return;
2811                                 }
2812                                 memset(&store, 0, sizeof(union sctp_sockstore));
2813                                 store.sin.sin_family = AF_INET;
2814                                 store.sin.sin_len = sizeof(struct sockaddr_in);
2815                                 store.sin.sin_port = stcb->rport;
2816                                 store.sin.sin_addr.s_addr = a4p->addr;
2817                                 break;
2818                         }
2819 #endif
2820                 default:
2821                         goto next_addr;
2822                 }
2823
2824                 /* see if this address really (still) exists */
2825                 sctp_ifa = sctp_find_ifa_by_addr(&store.sa, stcb->asoc.vrf_id,
2826                     SCTP_ADDR_NOT_LOCKED);
2827                 if (sctp_ifa == NULL) {
2828                         /* address doesn't exist anymore */
2829                         int status;
2830
2831                         /* are ASCONFs allowed ? */
2832                         if ((sctp_is_feature_on(stcb->sctp_ep,
2833                             SCTP_PCB_FLAGS_DO_ASCONF)) &&
2834                             stcb->asoc.asconf_supported) {
2835                                 /* queue an ASCONF DEL_IP_ADDRESS */
2836                                 status = sctp_asconf_queue_sa_delete(stcb, &store.sa);
2837                                 /*
2838                                  * if queued ok, and in correct state, send
2839                                  * out the ASCONF.
2840                                  */
2841                                 if (status == 0 &&
2842                                     SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) {
2843 #ifdef SCTP_TIMER_BASED_ASCONF
2844                                         sctp_timer_start(SCTP_TIMER_TYPE_ASCONF,
2845                                             stcb->sctp_ep, stcb,
2846                                             stcb->asoc.primary_destination);
2847 #else
2848                                         sctp_send_asconf(stcb, NULL, SCTP_ADDR_NOT_LOCKED);
2849 #endif
2850                                 }
2851                         }
2852                 }
2853
2854 next_addr:
2855                 /*
2856                  * Sanity check:  Make sure the length isn't 0, otherwise
2857                  * we'll be stuck in this loop for a long time...
2858                  */
2859                 if (SCTP_SIZE32(plen) == 0) {
2860                         SCTP_PRINTF("process_initack_addrs: bad len (%d) type=%xh\n",
2861                             plen, ptype);
2862                         return;
2863                 }
2864                 /* get next parameter */
2865                 offset += SCTP_SIZE32(plen);
2866                 if ((offset + sizeof(struct sctp_paramhdr)) > length)
2867                         return;
2868                 ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset,
2869                     sizeof(struct sctp_paramhdr), (uint8_t *)&tmp_param);
2870         }                       /* while */
2871 }
2872
2873 /* FIX ME: need to verify return result for v6 address type if v6 disabled */
2874 /*
2875  * checks to see if a specific address is in the initack address list returns
2876  * 1 if found, 0 if not
2877  */
2878 static uint32_t
2879 sctp_addr_in_initack(struct mbuf *m, uint32_t offset, uint32_t length, struct sockaddr *sa)
2880 {
2881         struct sctp_paramhdr tmp_param, *ph;
2882         uint16_t plen, ptype;
2883 #ifdef INET
2884         struct sockaddr_in *sin;
2885         struct sctp_ipv4addr_param *a4p;
2886         struct sctp_ipv6addr_param addr4_store;
2887 #endif
2888 #ifdef INET6
2889         struct sockaddr_in6 *sin6;
2890         struct sctp_ipv6addr_param *a6p;
2891         struct sctp_ipv6addr_param addr6_store;
2892         struct sockaddr_in6 sin6_tmp;
2893 #endif
2894
2895         switch (sa->sa_family) {
2896 #ifdef INET
2897         case AF_INET:
2898                 break;
2899 #endif
2900 #ifdef INET6
2901         case AF_INET6:
2902                 break;
2903 #endif
2904         default:
2905                 return (0);
2906         }
2907
2908         SCTPDBG(SCTP_DEBUG_ASCONF2, "find_initack_addr: starting search for ");
2909         SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, sa);
2910         /* convert to upper bound */
2911         length += offset;
2912
2913         if ((offset + sizeof(struct sctp_paramhdr)) > length) {
2914                 SCTPDBG(SCTP_DEBUG_ASCONF1,
2915                     "find_initack_addr: invalid offset?\n");
2916                 return (0);
2917         }
2918         /* go through the addresses in the init-ack */
2919         ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset,
2920             sizeof(struct sctp_paramhdr), (uint8_t *)&tmp_param);
2921         while (ph != NULL) {
2922                 ptype = ntohs(ph->param_type);
2923                 plen = ntohs(ph->param_length);
2924                 switch (ptype) {
2925 #ifdef INET6
2926                 case SCTP_IPV6_ADDRESS:
2927                         if (sa->sa_family == AF_INET6) {
2928                                 /* get the entire IPv6 address param */
2929                                 if (plen != sizeof(struct sctp_ipv6addr_param)) {
2930                                         break;
2931                                 }
2932                                 /* get the entire IPv6 address param */
2933                                 a6p = (struct sctp_ipv6addr_param *)
2934                                     sctp_m_getptr(m, offset,
2935                                     sizeof(struct sctp_ipv6addr_param),
2936                                     (uint8_t *)&addr6_store);
2937                                 if (a6p == NULL) {
2938                                         return (0);
2939                                 }
2940                                 sin6 = (struct sockaddr_in6 *)sa;
2941                                 if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr)) {
2942                                         /* create a copy and clear scope */
2943                                         memcpy(&sin6_tmp, sin6,
2944                                             sizeof(struct sockaddr_in6));
2945                                         sin6 = &sin6_tmp;
2946                                         in6_clearscope(&sin6->sin6_addr);
2947                                 }
2948                                 if (memcmp(&sin6->sin6_addr, a6p->addr,
2949                                     sizeof(struct in6_addr)) == 0) {
2950                                         /* found it */
2951                                         return (1);
2952                                 }
2953                         }
2954                         break;
2955 #endif                          /* INET6 */
2956 #ifdef INET
2957                 case SCTP_IPV4_ADDRESS:
2958                         if (sa->sa_family == AF_INET) {
2959                                 if (plen != sizeof(struct sctp_ipv4addr_param)) {
2960                                         break;
2961                                 }
2962                                 /* get the entire IPv4 address param */
2963                                 a4p = (struct sctp_ipv4addr_param *)
2964                                     sctp_m_getptr(m, offset,
2965                                     sizeof(struct sctp_ipv4addr_param),
2966                                     (uint8_t *)&addr4_store);
2967                                 if (a4p == NULL) {
2968                                         return (0);
2969                                 }
2970                                 sin = (struct sockaddr_in *)sa;
2971                                 if (sin->sin_addr.s_addr == a4p->addr) {
2972                                         /* found it */
2973                                         return (1);
2974                                 }
2975                         }
2976                         break;
2977 #endif
2978                 default:
2979                         break;
2980                 }
2981                 /* get next parameter */
2982                 offset += SCTP_SIZE32(plen);
2983                 if (offset + sizeof(struct sctp_paramhdr) > length) {
2984                         return (0);
2985                 }
2986                 ph = (struct sctp_paramhdr *)
2987                     sctp_m_getptr(m, offset, sizeof(struct sctp_paramhdr),
2988                     (uint8_t *)&tmp_param);
2989         }                       /* while */
2990         /* not found! */
2991         return (0);
2992 }
2993
2994 /*
2995  * makes sure that the current endpoint local addr list is consistent with
2996  * the new association (eg. subset bound, asconf allowed) adds addresses as
2997  * necessary
2998  */
2999 static void
3000 sctp_check_address_list_ep(struct sctp_tcb *stcb, struct mbuf *m, int offset,
3001     int length, struct sockaddr *init_addr)
3002 {
3003         struct sctp_laddr *laddr;
3004
3005         /* go through the endpoint list */
3006         LIST_FOREACH(laddr, &stcb->sctp_ep->sctp_addr_list, sctp_nxt_addr) {
3007                 /* be paranoid and validate the laddr */
3008                 if (laddr->ifa == NULL) {
3009                         SCTPDBG(SCTP_DEBUG_ASCONF1,
3010                             "check_addr_list_ep: laddr->ifa is NULL");
3011                         continue;
3012                 }
3013                 if (laddr->ifa == NULL) {
3014                         SCTPDBG(SCTP_DEBUG_ASCONF1, "check_addr_list_ep: laddr->ifa->ifa_addr is NULL");
3015                         continue;
3016                 }
3017                 /* do i have it implicitly? */
3018                 if (sctp_cmpaddr(&laddr->ifa->address.sa, init_addr)) {
3019                         continue;
3020                 }
3021                 /* check to see if in the init-ack */
3022                 if (!sctp_addr_in_initack(m, offset, length, &laddr->ifa->address.sa)) {
3023                         /* try to add it */
3024                         sctp_addr_mgmt_assoc(stcb->sctp_ep, stcb, laddr->ifa,
3025                             SCTP_ADD_IP_ADDRESS, SCTP_ADDR_NOT_LOCKED);
3026                 }
3027         }
3028 }
3029
3030 /*
3031  * makes sure that the current kernel address list is consistent with the new
3032  * association (with all addrs bound) adds addresses as necessary
3033  */
3034 static void
3035 sctp_check_address_list_all(struct sctp_tcb *stcb, struct mbuf *m, int offset,
3036     int length, struct sockaddr *init_addr,
3037     uint16_t local_scope, uint16_t site_scope,
3038     uint16_t ipv4_scope, uint16_t loopback_scope)
3039 {
3040         struct sctp_vrf *vrf = NULL;
3041         struct sctp_ifn *sctp_ifn;
3042         struct sctp_ifa *sctp_ifa;
3043         uint32_t vrf_id;
3044 #ifdef INET
3045         struct sockaddr_in *sin;
3046 #endif
3047 #ifdef INET6
3048         struct sockaddr_in6 *sin6;
3049 #endif
3050
3051         if (stcb) {
3052                 vrf_id = stcb->asoc.vrf_id;
3053         } else {
3054                 return;
3055         }
3056         SCTP_IPI_ADDR_RLOCK();
3057         vrf = sctp_find_vrf(vrf_id);
3058         if (vrf == NULL) {
3059                 SCTP_IPI_ADDR_RUNLOCK();
3060                 return;
3061         }
3062         /* go through all our known interfaces */
3063         LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
3064                 if (loopback_scope == 0 && SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) {
3065                         /* skip loopback interface */
3066                         continue;
3067                 }
3068                 /* go through each interface address */
3069                 LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
3070                         /* do i have it implicitly? */
3071                         if (sctp_cmpaddr(&sctp_ifa->address.sa, init_addr)) {
3072                                 continue;
3073                         }
3074                         switch (sctp_ifa->address.sa.sa_family) {
3075 #ifdef INET
3076                         case AF_INET:
3077                                 sin = &sctp_ifa->address.sin;
3078                                 if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred,
3079                                     &sin->sin_addr) != 0) {
3080                                         continue;
3081                                 }
3082                                 if ((ipv4_scope == 0) &&
3083                                     (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
3084                                         /* private address not in scope */
3085                                         continue;
3086                                 }
3087                                 break;
3088 #endif
3089 #ifdef INET6
3090                         case AF_INET6:
3091                                 sin6 = &sctp_ifa->address.sin6;
3092                                 if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred,
3093                                     &sin6->sin6_addr) != 0) {
3094                                         continue;
3095                                 }
3096                                 if ((local_scope == 0) &&
3097                                     (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))) {
3098                                         continue;
3099                                 }
3100                                 if ((site_scope == 0) &&
3101                                     (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) {
3102                                         continue;
3103                                 }
3104                                 break;
3105 #endif
3106                         default:
3107                                 break;
3108                         }
3109                         /* check to see if in the init-ack */
3110                         if (!sctp_addr_in_initack(m, offset, length, &sctp_ifa->address.sa)) {
3111                                 /* try to add it */
3112                                 sctp_addr_mgmt_assoc(stcb->sctp_ep, stcb,
3113                                     sctp_ifa, SCTP_ADD_IP_ADDRESS,
3114                                     SCTP_ADDR_LOCKED);
3115                         }
3116                 }               /* end foreach ifa */
3117         }                       /* end foreach ifn */
3118         SCTP_IPI_ADDR_RUNLOCK();
3119 }
3120
3121 /*
3122  * validates an init-ack chunk (from a cookie-echo) with current addresses
3123  * adds addresses from the init-ack into our local address list, if needed
3124  * queues asconf adds/deletes addresses as needed and makes appropriate list
3125  * changes for source address selection m, offset: points to the start of the
3126  * address list in an init-ack chunk length: total length of the address
3127  * params only init_addr: address where my INIT-ACK was sent from
3128  */
3129 void
3130 sctp_check_address_list(struct sctp_tcb *stcb, struct mbuf *m, int offset,
3131     int length, struct sockaddr *init_addr,
3132     uint16_t local_scope, uint16_t site_scope,
3133     uint16_t ipv4_scope, uint16_t loopback_scope)
3134 {
3135         /* process the local addresses in the initack */
3136         sctp_process_initack_addresses(stcb, m, offset, length);
3137
3138         if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
3139                 /* bound all case */
3140                 sctp_check_address_list_all(stcb, m, offset, length, init_addr,
3141                     local_scope, site_scope, ipv4_scope, loopback_scope);
3142         } else {
3143                 /* subset bound case */
3144                 if (sctp_is_feature_on(stcb->sctp_ep,
3145                     SCTP_PCB_FLAGS_DO_ASCONF)) {
3146                         /* asconf's allowed */
3147                         sctp_check_address_list_ep(stcb, m, offset, length,
3148                             init_addr);
3149                 }
3150                 /* else, no asconfs allowed, so what we sent is what we get */
3151         }
3152 }
3153
3154 /*
3155  * sctp_bindx() support
3156  */
3157 uint32_t
3158 sctp_addr_mgmt_ep_sa(struct sctp_inpcb *inp, struct sockaddr *sa,
3159     uint32_t type, uint32_t vrf_id, struct sctp_ifa *sctp_ifap)
3160 {
3161         struct sctp_ifa *ifa;
3162         struct sctp_laddr *laddr, *nladdr;
3163
3164         if (sa->sa_len == 0) {
3165                 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, EINVAL);
3166                 return (EINVAL);
3167         }
3168         if (sctp_ifap) {
3169                 ifa = sctp_ifap;
3170         } else if (type == SCTP_ADD_IP_ADDRESS) {
3171                 /* For an add the address MUST be on the system */
3172                 ifa = sctp_find_ifa_by_addr(sa, vrf_id, SCTP_ADDR_NOT_LOCKED);
3173         } else if (type == SCTP_DEL_IP_ADDRESS) {
3174                 /* For a delete we need to find it in the inp */
3175                 ifa = sctp_find_ifa_in_ep(inp, sa, SCTP_ADDR_NOT_LOCKED);
3176         } else {
3177                 ifa = NULL;
3178         }
3179         if (ifa != NULL) {
3180                 if (type == SCTP_ADD_IP_ADDRESS) {
3181                         sctp_add_local_addr_ep(inp, ifa, type);
3182                 } else if (type == SCTP_DEL_IP_ADDRESS) {
3183                         if (inp->laddr_count < 2) {
3184                                 /* can't delete the last local address */
3185                                 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, EINVAL);
3186                                 return (EINVAL);
3187                         }
3188                         LIST_FOREACH(laddr, &inp->sctp_addr_list,
3189                             sctp_nxt_addr) {
3190                                 if (ifa == laddr->ifa) {
3191                                         /* Mark in the delete */
3192                                         laddr->action = type;
3193                                 }
3194                         }
3195                 }
3196                 if (LIST_EMPTY(&inp->sctp_asoc_list)) {
3197                         /*
3198                          * There is no need to start the iterator if the inp
3199                          * has no associations.
3200                          */
3201                         if (type == SCTP_DEL_IP_ADDRESS) {
3202                                 LIST_FOREACH_SAFE(laddr, &inp->sctp_addr_list, sctp_nxt_addr, nladdr) {
3203                                         if (laddr->ifa == ifa) {
3204                                                 sctp_del_local_addr_ep(inp, ifa);
3205                                         }
3206                                 }
3207                         }
3208                 } else {
3209                         struct sctp_asconf_iterator *asc;
3210                         struct sctp_laddr *wi;
3211                         int ret;
3212
3213                         SCTP_MALLOC(asc, struct sctp_asconf_iterator *,
3214                             sizeof(struct sctp_asconf_iterator),
3215                             SCTP_M_ASC_IT);
3216                         if (asc == NULL) {
3217                                 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, ENOMEM);
3218                                 return (ENOMEM);
3219                         }
3220                         wi = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_laddr), struct sctp_laddr);
3221                         if (wi == NULL) {
3222                                 SCTP_FREE(asc, SCTP_M_ASC_IT);
3223                                 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, ENOMEM);
3224                                 return (ENOMEM);
3225                         }
3226                         LIST_INIT(&asc->list_of_work);
3227                         asc->cnt = 1;
3228                         SCTP_INCR_LADDR_COUNT();
3229                         wi->ifa = ifa;
3230                         wi->action = type;
3231                         atomic_add_int(&ifa->refcount, 1);
3232                         LIST_INSERT_HEAD(&asc->list_of_work, wi, sctp_nxt_addr);
3233                         ret = sctp_initiate_iterator(sctp_asconf_iterator_ep,
3234                             sctp_asconf_iterator_stcb,
3235                             sctp_asconf_iterator_ep_end,
3236                             SCTP_PCB_ANY_FLAGS,
3237                             SCTP_PCB_ANY_FEATURES,
3238                             SCTP_ASOC_ANY_STATE,
3239                             (void *)asc, 0,
3240                             sctp_asconf_iterator_end, inp, 0);
3241                         if (ret) {
3242                                 SCTP_PRINTF("Failed to initiate iterator for addr_mgmt_ep_sa\n");
3243                                 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, EFAULT);
3244                                 sctp_asconf_iterator_end(asc, 0);
3245                                 return (EFAULT);
3246                         }
3247                 }
3248                 return (0);
3249         } else {
3250                 /* invalid address! */
3251                 SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_ASCONF, EADDRNOTAVAIL);
3252                 return (EADDRNOTAVAIL);
3253         }
3254 }
3255
3256 void
3257 sctp_asconf_send_nat_state_update(struct sctp_tcb *stcb,
3258     struct sctp_nets *net)
3259 {
3260         struct sctp_asconf_addr *aa;
3261         struct sctp_ifa *sctp_ifap;
3262         struct sctp_asconf_tag_param *vtag;
3263 #ifdef INET
3264         struct sockaddr_in *to;
3265 #endif
3266 #ifdef INET6
3267         struct sockaddr_in6 *to6;
3268 #endif
3269         if (net == NULL) {
3270                 SCTPDBG(SCTP_DEBUG_ASCONF1, "sctp_asconf_send_nat_state_update: Missing net\n");
3271                 return;
3272         }
3273         if (stcb == NULL) {
3274                 SCTPDBG(SCTP_DEBUG_ASCONF1, "sctp_asconf_send_nat_state_update: Missing stcb\n");
3275                 return;
3276         }
3277         /*
3278          * Need to have in the asconf: - vtagparam(my_vtag/peer_vtag) -
3279          * add(0.0.0.0) - del(0.0.0.0) - Any global addresses add(addr)
3280          */
3281         SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa),
3282             SCTP_M_ASC_ADDR);
3283         if (aa == NULL) {
3284                 /* didn't get memory */
3285                 SCTPDBG(SCTP_DEBUG_ASCONF1,
3286                     "sctp_asconf_send_nat_state_update: failed to get memory!\n");
3287                 return;
3288         }
3289         aa->special_del = 0;
3290         /* fill in asconf address parameter fields */
3291         /* top level elements are "networked" during send */
3292         aa->ifa = NULL;
3293         aa->sent = 0;           /* clear sent flag */
3294         vtag = (struct sctp_asconf_tag_param *)&aa->ap.aph;
3295         vtag->aph.ph.param_type = SCTP_NAT_VTAGS;
3296         vtag->aph.ph.param_length = sizeof(struct sctp_asconf_tag_param);
3297         vtag->local_vtag = htonl(stcb->asoc.my_vtag);
3298         vtag->remote_vtag = htonl(stcb->asoc.peer_vtag);
3299         TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
3300
3301         SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa),
3302             SCTP_M_ASC_ADDR);
3303         if (aa == NULL) {
3304                 /* didn't get memory */
3305                 SCTPDBG(SCTP_DEBUG_ASCONF1,
3306                     "sctp_asconf_send_nat_state_update: failed to get memory!\n");
3307                 return;
3308         }
3309         memset(aa, 0, sizeof(struct sctp_asconf_addr));
3310         /* fill in asconf address parameter fields */
3311         /* ADD(0.0.0.0) */
3312         switch (net->ro._l_addr.sa.sa_family) {
3313 #ifdef INET
3314         case AF_INET:
3315                 aa->ap.aph.ph.param_type = SCTP_ADD_IP_ADDRESS;
3316                 aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_addrv4_param);
3317                 aa->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
3318                 aa->ap.addrp.ph.param_length = sizeof(struct sctp_ipv4addr_param);
3319                 /* No need to add an address, we are using 0.0.0.0 */
3320                 TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
3321                 break;
3322 #endif
3323 #ifdef INET6
3324         case AF_INET6:
3325                 aa->ap.aph.ph.param_type = SCTP_ADD_IP_ADDRESS;
3326                 aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_addr_param);
3327                 aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
3328                 aa->ap.addrp.ph.param_length = sizeof(struct sctp_ipv6addr_param);
3329                 /* No need to add an address, we are using 0.0.0.0 */
3330                 TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
3331                 break;
3332 #endif
3333         default:
3334                 SCTPDBG(SCTP_DEBUG_ASCONF1,
3335                     "sctp_asconf_send_nat_state_update: unknown address family\n");
3336                 SCTP_FREE(aa, SCTP_M_ASC_ADDR);
3337                 return;
3338         }
3339         SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa),
3340             SCTP_M_ASC_ADDR);
3341         if (aa == NULL) {
3342                 /* didn't get memory */
3343                 SCTPDBG(SCTP_DEBUG_ASCONF1,
3344                     "sctp_asconf_send_nat_state_update: failed to get memory!\n");
3345                 return;
3346         }
3347         memset(aa, 0, sizeof(struct sctp_asconf_addr));
3348         /* fill in asconf address parameter fields */
3349         /* ADD(0.0.0.0) */
3350         switch (net->ro._l_addr.sa.sa_family) {
3351 #ifdef INET
3352         case AF_INET:
3353                 aa->ap.aph.ph.param_type = SCTP_ADD_IP_ADDRESS;
3354                 aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_addrv4_param);
3355                 aa->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
3356                 aa->ap.addrp.ph.param_length = sizeof(struct sctp_ipv4addr_param);
3357                 /* No need to add an address, we are using 0.0.0.0 */
3358                 TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
3359                 break;
3360 #endif
3361 #ifdef INET6
3362         case AF_INET6:
3363                 aa->ap.aph.ph.param_type = SCTP_DEL_IP_ADDRESS;
3364                 aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_addr_param);
3365                 aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
3366                 aa->ap.addrp.ph.param_length = sizeof(struct sctp_ipv6addr_param);
3367                 /* No need to add an address, we are using 0.0.0.0 */
3368                 TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
3369                 break;
3370 #endif
3371         default:
3372                 SCTPDBG(SCTP_DEBUG_ASCONF1,
3373                     "sctp_asconf_send_nat_state_update: unknown address family\n");
3374                 SCTP_FREE(aa, SCTP_M_ASC_ADDR);
3375                 return;
3376         }
3377         /* Now we must hunt the addresses and add all global addresses */
3378         if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
3379                 struct sctp_vrf *vrf = NULL;
3380                 struct sctp_ifn *sctp_ifnp;
3381                 uint32_t vrf_id;
3382
3383                 vrf_id = stcb->sctp_ep->def_vrf_id;
3384                 vrf = sctp_find_vrf(vrf_id);
3385                 if (vrf == NULL) {
3386                         goto skip_rest;
3387                 }
3388
3389                 SCTP_IPI_ADDR_RLOCK();
3390                 LIST_FOREACH(sctp_ifnp, &vrf->ifnlist, next_ifn) {
3391                         LIST_FOREACH(sctp_ifap, &sctp_ifnp->ifalist, next_ifa) {
3392                                 switch (sctp_ifap->address.sa.sa_family) {
3393 #ifdef INET
3394                                 case AF_INET:
3395                                         to = &sctp_ifap->address.sin;
3396                                         if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred,
3397                                             &to->sin_addr) != 0) {
3398                                                 continue;
3399                                         }
3400                                         if (IN4_ISPRIVATE_ADDRESS(&to->sin_addr)) {
3401                                                 continue;
3402                                         }
3403                                         if (IN4_ISLOOPBACK_ADDRESS(&to->sin_addr)) {
3404                                                 continue;
3405                                         }
3406                                         break;
3407 #endif
3408 #ifdef INET6
3409                                 case AF_INET6:
3410                                         to6 = &sctp_ifap->address.sin6;
3411                                         if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred,
3412                                             &to6->sin6_addr) != 0) {
3413                                                 continue;
3414                                         }
3415                                         if (IN6_IS_ADDR_LOOPBACK(&to6->sin6_addr)) {
3416                                                 continue;
3417                                         }
3418                                         if (IN6_IS_ADDR_LINKLOCAL(&to6->sin6_addr)) {
3419                                                 continue;
3420                                         }
3421                                         break;
3422 #endif
3423                                 default:
3424                                         continue;
3425                                 }
3426                                 sctp_asconf_queue_mgmt(stcb, sctp_ifap, SCTP_ADD_IP_ADDRESS);
3427                         }
3428                 }
3429                 SCTP_IPI_ADDR_RUNLOCK();
3430         } else {
3431                 struct sctp_laddr *laddr;
3432
3433                 LIST_FOREACH(laddr, &stcb->sctp_ep->sctp_addr_list, sctp_nxt_addr) {
3434                         if (laddr->ifa == NULL) {
3435                                 continue;
3436                         }
3437                         if (laddr->ifa->localifa_flags & SCTP_BEING_DELETED)
3438                                 /*
3439                                  * Address being deleted by the system, dont
3440                                  * list.
3441                                  */
3442                                 continue;
3443                         if (laddr->action == SCTP_DEL_IP_ADDRESS) {
3444                                 /*
3445                                  * Address being deleted on this ep don't
3446                                  * list.
3447                                  */
3448                                 continue;
3449                         }
3450                         sctp_ifap = laddr->ifa;
3451                         switch (sctp_ifap->address.sa.sa_family) {
3452 #ifdef INET
3453                         case AF_INET:
3454                                 to = &sctp_ifap->address.sin;
3455                                 if (IN4_ISPRIVATE_ADDRESS(&to->sin_addr)) {
3456                                         continue;
3457                                 }
3458                                 if (IN4_ISLOOPBACK_ADDRESS(&to->sin_addr)) {
3459                                         continue;
3460                                 }
3461                                 break;
3462 #endif
3463 #ifdef INET6
3464                         case AF_INET6:
3465                                 to6 = &sctp_ifap->address.sin6;
3466                                 if (IN6_IS_ADDR_LOOPBACK(&to6->sin6_addr)) {
3467                                         continue;
3468                                 }
3469                                 if (IN6_IS_ADDR_LINKLOCAL(&to6->sin6_addr)) {
3470                                         continue;
3471                                 }
3472                                 break;
3473 #endif
3474                         default:
3475                                 continue;
3476                         }
3477                         sctp_asconf_queue_mgmt(stcb, sctp_ifap, SCTP_ADD_IP_ADDRESS);
3478                 }
3479         }
3480 skip_rest:
3481         /* Now we must send the asconf into the queue */
3482         sctp_send_asconf(stcb, net, SCTP_ADDR_NOT_LOCKED);
3483 }