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