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