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