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