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