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