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