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