1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <sys/types.h> 27 #include <sys/systm.h> 28 #include <sys/stream.h> 29 #include <sys/cmn_err.h> 30 #include <sys/ddi.h> 31 #include <sys/sunddi.h> 32 #include <sys/kmem.h> 33 #include <sys/socket.h> 34 #include <sys/sysmacros.h> 35 #include <sys/list.h> 36 37 #include <netinet/in.h> 38 #include <netinet/ip6.h> 39 #include <netinet/sctp.h> 40 41 #include <inet/common.h> 42 #include <inet/ip.h> 43 #include <inet/ip6.h> 44 #include <inet/ip_if.h> 45 #include <inet/ipclassifier.h> 46 #include <inet/sctp_ip.h> 47 #include "sctp_impl.h" 48 #include "sctp_addr.h" 49 50 static void sctp_ipif_inactive(sctp_ipif_t *); 51 static sctp_ipif_t *sctp_lookup_ipif_addr(in6_addr_t *, boolean_t, 52 zoneid_t, boolean_t, uint_t, uint_t, boolean_t, 53 sctp_stack_t *); 54 static int sctp_get_all_ipifs(sctp_t *, int); 55 static int sctp_ipif_hash_insert(sctp_t *, sctp_ipif_t *, int, 56 boolean_t, boolean_t); 57 static void sctp_ipif_hash_remove(sctp_t *, sctp_ipif_t *); 58 static void sctp_fix_saddr(sctp_t *, in6_addr_t *); 59 static int sctp_compare_ipif_list(sctp_ipif_hash_t *, 60 sctp_ipif_hash_t *); 61 static int sctp_copy_ipifs(sctp_ipif_hash_t *, sctp_t *, int); 62 63 #define SCTP_ADDR4_HASH(addr) \ 64 (((addr) ^ ((addr) >> 8) ^ ((addr) >> 16) ^ ((addr) >> 24)) & \ 65 (SCTP_IPIF_HASH - 1)) 66 67 #define SCTP_ADDR6_HASH(addr) \ 68 (((addr).s6_addr32[3] ^ \ 69 (((addr).s6_addr32[3] ^ (addr).s6_addr32[2]) >> 12)) & \ 70 (SCTP_IPIF_HASH - 1)) 71 72 #define SCTP_IPIF_ADDR_HASH(addr, isv6) \ 73 ((isv6) ? SCTP_ADDR6_HASH((addr)) : \ 74 SCTP_ADDR4_HASH((addr)._S6_un._S6_u32[3])) 75 76 #define SCTP_IPIF_USABLE(sctp_ipif_state) \ 77 ((sctp_ipif_state) == SCTP_IPIFS_UP || \ 78 (sctp_ipif_state) == SCTP_IPIFS_DOWN) 79 80 #define SCTP_IPIF_DISCARD(sctp_ipif_flags) \ 81 ((sctp_ipif_flags) & (IPIF_PRIVATE | IPIF_DEPRECATED)) 82 83 #define SCTP_IS_IPIF_LOOPBACK(ipif) \ 84 ((ipif)->sctp_ipif_ill->sctp_ill_flags & PHYI_LOOPBACK) 85 86 #define SCTP_IS_IPIF_LINKLOCAL(ipif) \ 87 ((ipif)->sctp_ipif_isv6 && \ 88 IN6_IS_ADDR_LINKLOCAL(&(ipif)->sctp_ipif_saddr)) 89 90 #define SCTP_UNSUPP_AF(ipif, supp_af) \ 91 ((!(ipif)->sctp_ipif_isv6 && !((supp_af) & PARM_SUPP_V4)) || \ 92 ((ipif)->sctp_ipif_isv6 && !((supp_af) & PARM_SUPP_V6))) 93 94 #define SCTP_IPIF_ZONE_MATCH(sctp, ipif) \ 95 IPCL_ZONE_MATCH((sctp)->sctp_connp, (ipif)->sctp_ipif_zoneid) 96 97 #define SCTP_ILL_HASH_FN(index) ((index) % SCTP_ILL_HASH) 98 #define SCTP_ILL_TO_PHYINDEX(ill) ((ill)->ill_phyint->phyint_ifindex) 99 100 /* 101 * SCTP Interface list manipulation functions, locking used. 102 */ 103 104 /* 105 * Delete an SCTP IPIF from the list if the refcount goes to 0 and it is 106 * marked as condemned. Also, check if the ILL needs to go away. 107 */ 108 static void 109 sctp_ipif_inactive(sctp_ipif_t *sctp_ipif) 110 { 111 sctp_ill_t *sctp_ill; 112 uint_t hindex; 113 uint_t ill_index; 114 sctp_stack_t *sctps = sctp_ipif->sctp_ipif_ill-> 115 sctp_ill_netstack->netstack_sctp; 116 117 rw_enter(&sctps->sctps_g_ills_lock, RW_READER); 118 rw_enter(&sctps->sctps_g_ipifs_lock, RW_WRITER); 119 120 hindex = SCTP_IPIF_ADDR_HASH(sctp_ipif->sctp_ipif_saddr, 121 sctp_ipif->sctp_ipif_isv6); 122 123 sctp_ill = sctp_ipif->sctp_ipif_ill; 124 ASSERT(sctp_ill != NULL); 125 ill_index = SCTP_ILL_HASH_FN(sctp_ill->sctp_ill_index); 126 if (sctp_ipif->sctp_ipif_state != SCTP_IPIFS_CONDEMNED || 127 sctp_ipif->sctp_ipif_refcnt != 0) { 128 rw_exit(&sctps->sctps_g_ipifs_lock); 129 rw_exit(&sctps->sctps_g_ills_lock); 130 return; 131 } 132 list_remove(&sctps->sctps_g_ipifs[hindex].sctp_ipif_list, 133 sctp_ipif); 134 sctps->sctps_g_ipifs[hindex].ipif_count--; 135 sctps->sctps_g_ipifs_count--; 136 rw_destroy(&sctp_ipif->sctp_ipif_lock); 137 kmem_free(sctp_ipif, sizeof (sctp_ipif_t)); 138 139 (void) atomic_add_32_nv(&sctp_ill->sctp_ill_ipifcnt, -1); 140 if (rw_tryupgrade(&sctps->sctps_g_ills_lock) != 0) { 141 rw_downgrade(&sctps->sctps_g_ipifs_lock); 142 if (sctp_ill->sctp_ill_ipifcnt == 0 && 143 sctp_ill->sctp_ill_state == SCTP_ILLS_CONDEMNED) { 144 list_remove(&sctps->sctps_g_ills[ill_index]. 145 sctp_ill_list, (void *)sctp_ill); 146 sctps->sctps_g_ills[ill_index].ill_count--; 147 sctps->sctps_ills_count--; 148 kmem_free(sctp_ill->sctp_ill_name, 149 sctp_ill->sctp_ill_name_length); 150 kmem_free(sctp_ill, sizeof (sctp_ill_t)); 151 } 152 } 153 rw_exit(&sctps->sctps_g_ipifs_lock); 154 rw_exit(&sctps->sctps_g_ills_lock); 155 } 156 157 /* 158 * Lookup an SCTP IPIF given an IP address. Increments sctp_ipif refcnt. 159 * We are either looking for a IPIF with the given address before 160 * inserting it into the global list or looking for an IPIF for an 161 * address given an SCTP. In the former case we always check the zoneid, 162 * but for the latter case, check_zid could be B_FALSE if the connp 163 * for the sctp has conn_all_zones set. When looking for an address we 164 * give preference to one that is up, so even though we may find one that 165 * is not up we keep looking if there is one up, we hold the down addr 166 * in backup_ipif in case we don't find one that is up - i.e. we return 167 * the backup_ipif in that case. Note that if we are looking for. If we 168 * are specifically looking for an up address, then usable will be set 169 * to true. 170 */ 171 static sctp_ipif_t * 172 sctp_lookup_ipif_addr(in6_addr_t *addr, boolean_t refhold, zoneid_t zoneid, 173 boolean_t check_zid, uint_t ifindex, uint_t seqid, boolean_t usable, 174 sctp_stack_t *sctps) 175 { 176 int j; 177 sctp_ipif_t *sctp_ipif; 178 sctp_ipif_t *backup_ipif = NULL; 179 int hindex; 180 181 hindex = SCTP_IPIF_ADDR_HASH(*addr, !IN6_IS_ADDR_V4MAPPED(addr)); 182 183 rw_enter(&sctps->sctps_g_ipifs_lock, RW_READER); 184 if (sctps->sctps_g_ipifs[hindex].ipif_count == 0) { 185 rw_exit(&sctps->sctps_g_ipifs_lock); 186 return (NULL); 187 } 188 sctp_ipif = list_head(&sctps->sctps_g_ipifs[hindex].sctp_ipif_list); 189 for (j = 0; j < sctps->sctps_g_ipifs[hindex].ipif_count; j++) { 190 rw_enter(&sctp_ipif->sctp_ipif_lock, RW_READER); 191 if ((!check_zid || 192 (sctp_ipif->sctp_ipif_zoneid == ALL_ZONES || 193 zoneid == sctp_ipif->sctp_ipif_zoneid)) && 194 (ifindex == 0 || ifindex == 195 sctp_ipif->sctp_ipif_ill->sctp_ill_index) && 196 ((seqid != 0 && seqid == sctp_ipif->sctp_ipif_id) || 197 (IN6_ARE_ADDR_EQUAL(&sctp_ipif->sctp_ipif_saddr, 198 addr)))) { 199 if (!usable || sctp_ipif->sctp_ipif_state == 200 SCTP_IPIFS_UP) { 201 rw_exit(&sctp_ipif->sctp_ipif_lock); 202 if (refhold) 203 SCTP_IPIF_REFHOLD(sctp_ipif); 204 rw_exit(&sctps->sctps_g_ipifs_lock); 205 return (sctp_ipif); 206 } else if (sctp_ipif->sctp_ipif_state == 207 SCTP_IPIFS_DOWN && backup_ipif == NULL) { 208 backup_ipif = sctp_ipif; 209 } 210 } 211 rw_exit(&sctp_ipif->sctp_ipif_lock); 212 sctp_ipif = list_next( 213 &sctps->sctps_g_ipifs[hindex].sctp_ipif_list, sctp_ipif); 214 } 215 if (backup_ipif != NULL) { 216 if (refhold) 217 SCTP_IPIF_REFHOLD(backup_ipif); 218 rw_exit(&sctps->sctps_g_ipifs_lock); 219 return (backup_ipif); 220 } 221 rw_exit(&sctps->sctps_g_ipifs_lock); 222 return (NULL); 223 } 224 225 /* 226 * Populate the list with all the SCTP ipifs for a given ipversion. 227 * Increments sctp_ipif refcnt. 228 * Called with no locks held. 229 */ 230 static int 231 sctp_get_all_ipifs(sctp_t *sctp, int sleep) 232 { 233 sctp_ipif_t *sctp_ipif; 234 int i; 235 int j; 236 int error = 0; 237 sctp_stack_t *sctps = sctp->sctp_sctps; 238 239 rw_enter(&sctps->sctps_g_ipifs_lock, RW_READER); 240 for (i = 0; i < SCTP_IPIF_HASH; i++) { 241 if (sctps->sctps_g_ipifs[i].ipif_count == 0) 242 continue; 243 sctp_ipif = list_head(&sctps->sctps_g_ipifs[i].sctp_ipif_list); 244 for (j = 0; j < sctps->sctps_g_ipifs[i].ipif_count; j++) { 245 rw_enter(&sctp_ipif->sctp_ipif_lock, RW_READER); 246 if (SCTP_IPIF_DISCARD(sctp_ipif->sctp_ipif_flags) || 247 !SCTP_IPIF_USABLE(sctp_ipif->sctp_ipif_state) || 248 !SCTP_IPIF_ZONE_MATCH(sctp, sctp_ipif) || 249 (sctp->sctp_ipversion == IPV4_VERSION && 250 sctp_ipif->sctp_ipif_isv6) || 251 (sctp->sctp_connp->conn_ipv6_v6only && 252 !sctp_ipif->sctp_ipif_isv6)) { 253 rw_exit(&sctp_ipif->sctp_ipif_lock); 254 sctp_ipif = list_next( 255 &sctps->sctps_g_ipifs[i].sctp_ipif_list, 256 sctp_ipif); 257 continue; 258 } 259 rw_exit(&sctp_ipif->sctp_ipif_lock); 260 SCTP_IPIF_REFHOLD(sctp_ipif); 261 error = sctp_ipif_hash_insert(sctp, sctp_ipif, sleep, 262 B_FALSE, B_FALSE); 263 if (error != 0 && error != EALREADY) 264 goto free_stuff; 265 sctp_ipif = list_next( 266 &sctps->sctps_g_ipifs[i].sctp_ipif_list, 267 sctp_ipif); 268 } 269 } 270 rw_exit(&sctps->sctps_g_ipifs_lock); 271 return (0); 272 free_stuff: 273 rw_exit(&sctps->sctps_g_ipifs_lock); 274 sctp_free_saddrs(sctp); 275 return (ENOMEM); 276 } 277 278 /* 279 * Given a list of address, fills in the list of SCTP ipifs if all the addresses 280 * are present in the SCTP interface list, return number of addresses filled 281 * or error. If the caller wants the list of addresses, it sends a pre-allocated 282 * buffer - list. Currently, this list is only used on a clustered node when 283 * the SCTP is in the listen state (from sctp_bind_add()). When called on a 284 * clustered node, the input is always a list of addresses (even if the 285 * original bind() was to INADDR_ANY). 286 * Called with no locks held. 287 */ 288 int 289 sctp_valid_addr_list(sctp_t *sctp, const void *addrs, uint32_t addrcnt, 290 uchar_t *list, size_t lsize) 291 { 292 struct sockaddr_in *sin4; 293 struct sockaddr_in6 *sin6; 294 struct in_addr *addr4; 295 in6_addr_t addr; 296 int cnt; 297 int err = 0; 298 int saddr_cnt = 0; 299 sctp_ipif_t *ipif; 300 boolean_t bind_to_all = B_FALSE; 301 boolean_t check_addrs = B_FALSE; 302 boolean_t check_lport = B_FALSE; 303 uchar_t *p = list; 304 305 /* 306 * Need to check for port and address depending on the state. 307 * After a socket is bound, we need to make sure that subsequent 308 * bindx() has correct port. After an association is established, 309 * we need to check for changing the bound address to invalid 310 * addresses. 311 */ 312 if (sctp->sctp_state >= SCTPS_BOUND) { 313 check_lport = B_TRUE; 314 if (sctp->sctp_state > SCTPS_LISTEN) 315 check_addrs = B_TRUE; 316 } 317 318 if (sctp->sctp_conn_tfp != NULL) 319 mutex_enter(&sctp->sctp_conn_tfp->tf_lock); 320 if (sctp->sctp_listen_tfp != NULL) 321 mutex_enter(&sctp->sctp_listen_tfp->tf_lock); 322 for (cnt = 0; cnt < addrcnt; cnt++) { 323 boolean_t lookup_saddr = B_TRUE; 324 uint_t ifindex = 0; 325 326 switch (sctp->sctp_family) { 327 case AF_INET: 328 sin4 = (struct sockaddr_in *)addrs + cnt; 329 if (sin4->sin_family != AF_INET || (check_lport && 330 sin4->sin_port != sctp->sctp_lport)) { 331 err = EINVAL; 332 goto free_ret; 333 } 334 addr4 = &sin4->sin_addr; 335 if (check_addrs && 336 (addr4->s_addr == INADDR_ANY || 337 addr4->s_addr == INADDR_BROADCAST || 338 CLASSD(addr4->s_addr))) { 339 err = EINVAL; 340 goto free_ret; 341 } 342 IN6_INADDR_TO_V4MAPPED(addr4, &addr); 343 if (!check_addrs && addr4->s_addr == INADDR_ANY) { 344 lookup_saddr = B_FALSE; 345 bind_to_all = B_TRUE; 346 } 347 348 break; 349 case AF_INET6: 350 sin6 = (struct sockaddr_in6 *)addrs + cnt; 351 if (sin6->sin6_family != AF_INET6 || (check_lport && 352 sin6->sin6_port != sctp->sctp_lport)) { 353 err = EINVAL; 354 goto free_ret; 355 } 356 addr = sin6->sin6_addr; 357 /* Contains the interface index */ 358 ifindex = sin6->sin6_scope_id; 359 if (sctp->sctp_connp->conn_ipv6_v6only && 360 IN6_IS_ADDR_V4MAPPED(&addr)) { 361 err = EAFNOSUPPORT; 362 goto free_ret; 363 } 364 if (check_addrs && 365 (IN6_IS_ADDR_LINKLOCAL(&addr) || 366 IN6_IS_ADDR_MULTICAST(&addr) || 367 IN6_IS_ADDR_UNSPECIFIED(&addr))) { 368 err = EINVAL; 369 goto free_ret; 370 } 371 if (!check_addrs && IN6_IS_ADDR_UNSPECIFIED(&addr)) { 372 lookup_saddr = B_FALSE; 373 bind_to_all = B_TRUE; 374 } 375 376 break; 377 default: 378 err = EAFNOSUPPORT; 379 goto free_ret; 380 } 381 if (lookup_saddr) { 382 ipif = sctp_lookup_ipif_addr(&addr, B_TRUE, 383 sctp->sctp_zoneid, !sctp->sctp_connp->conn_allzones, 384 ifindex, 0, B_TRUE, sctp->sctp_sctps); 385 if (ipif == NULL) { 386 /* Address not in the list */ 387 err = EINVAL; 388 goto free_ret; 389 } else if (check_addrs && SCTP_IS_IPIF_LOOPBACK(ipif) && 390 cl_sctp_check_addrs == NULL) { 391 SCTP_IPIF_REFRELE(ipif); 392 err = EINVAL; 393 goto free_ret; 394 } 395 } 396 if (!bind_to_all) { 397 /* 398 * If an address is added after association setup, 399 * we need to wait for the peer to send us an ASCONF 400 * ACK before we can start using it. 401 * saddr_ipif_dontsrc will be reset (to 0) when we 402 * get the ASCONF ACK for this address. 403 */ 404 err = sctp_ipif_hash_insert(sctp, ipif, KM_SLEEP, 405 check_addrs ? B_TRUE : B_FALSE, B_FALSE); 406 if (err != 0) { 407 SCTP_IPIF_REFRELE(ipif); 408 if (check_addrs && err == EALREADY) 409 err = EADDRINUSE; 410 goto free_ret; 411 } 412 saddr_cnt++; 413 if (lsize >= sizeof (addr)) { 414 bcopy(&addr, p, sizeof (addr)); 415 p += sizeof (addr); 416 lsize -= sizeof (addr); 417 } 418 } 419 } 420 if (bind_to_all) { 421 /* 422 * Free whatever we might have added before encountering 423 * inaddr_any. 424 */ 425 if (sctp->sctp_nsaddrs > 0) { 426 sctp_free_saddrs(sctp); 427 ASSERT(sctp->sctp_nsaddrs == 0); 428 } 429 err = sctp_get_all_ipifs(sctp, KM_SLEEP); 430 if (err != 0) 431 return (err); 432 sctp->sctp_bound_to_all = 1; 433 } 434 if (sctp->sctp_listen_tfp != NULL) 435 mutex_exit(&sctp->sctp_listen_tfp->tf_lock); 436 if (sctp->sctp_conn_tfp != NULL) 437 mutex_exit(&sctp->sctp_conn_tfp->tf_lock); 438 return (0); 439 free_ret: 440 if (saddr_cnt != 0) 441 sctp_del_saddr_list(sctp, addrs, saddr_cnt, B_TRUE); 442 if (sctp->sctp_listen_tfp != NULL) 443 mutex_exit(&sctp->sctp_listen_tfp->tf_lock); 444 if (sctp->sctp_conn_tfp != NULL) 445 mutex_exit(&sctp->sctp_conn_tfp->tf_lock); 446 return (err); 447 } 448 449 static int 450 sctp_ipif_hash_insert(sctp_t *sctp, sctp_ipif_t *ipif, int sleep, 451 boolean_t dontsrc, boolean_t allow_dup) 452 { 453 int cnt; 454 sctp_saddr_ipif_t *ipif_obj; 455 int hindex; 456 457 hindex = SCTP_IPIF_ADDR_HASH(ipif->sctp_ipif_saddr, 458 ipif->sctp_ipif_isv6); 459 ipif_obj = list_head(&sctp->sctp_saddrs[hindex].sctp_ipif_list); 460 for (cnt = 0; cnt < sctp->sctp_saddrs[hindex].ipif_count; cnt++) { 461 if (IN6_ARE_ADDR_EQUAL(&ipif_obj->saddr_ipifp->sctp_ipif_saddr, 462 &ipif->sctp_ipif_saddr)) { 463 if (ipif->sctp_ipif_id != 464 ipif_obj->saddr_ipifp->sctp_ipif_id && 465 ipif_obj->saddr_ipifp->sctp_ipif_state == 466 SCTP_IPIFS_DOWN && ipif->sctp_ipif_state == 467 SCTP_IPIFS_UP) { 468 SCTP_IPIF_REFRELE(ipif_obj->saddr_ipifp); 469 ipif_obj->saddr_ipifp = ipif; 470 ipif_obj->saddr_ipif_dontsrc = dontsrc ? 1 : 0; 471 return (0); 472 } else if (!allow_dup || ipif->sctp_ipif_id == 473 ipif_obj->saddr_ipifp->sctp_ipif_id) { 474 return (EALREADY); 475 } 476 } 477 ipif_obj = list_next(&sctp->sctp_saddrs[hindex].sctp_ipif_list, 478 ipif_obj); 479 } 480 ipif_obj = kmem_zalloc(sizeof (sctp_saddr_ipif_t), sleep); 481 if (ipif_obj == NULL) { 482 /* Need to do something */ 483 return (ENOMEM); 484 } 485 ipif_obj->saddr_ipifp = ipif; 486 ipif_obj->saddr_ipif_dontsrc = dontsrc ? 1 : 0; 487 list_insert_tail(&sctp->sctp_saddrs[hindex].sctp_ipif_list, ipif_obj); 488 sctp->sctp_saddrs[hindex].ipif_count++; 489 sctp->sctp_nsaddrs++; 490 return (0); 491 } 492 493 /* 494 * Given a source address, walk through the peer address list to see 495 * if the source address is being used. If it is, reset that. 496 */ 497 static void 498 sctp_fix_saddr(sctp_t *sctp, in6_addr_t *saddr) 499 { 500 sctp_faddr_t *fp; 501 502 for (fp = sctp->sctp_faddrs; fp != NULL; fp = fp->next) { 503 if (!IN6_ARE_ADDR_EQUAL(&fp->saddr, saddr)) 504 continue; 505 if (fp->ire != NULL) { 506 IRE_REFRELE_NOTR(fp->ire); 507 fp->ire = NULL; 508 } 509 V6_SET_ZERO(fp->saddr); 510 } 511 } 512 513 static void 514 sctp_ipif_hash_remove(sctp_t *sctp, sctp_ipif_t *ipif) 515 { 516 int cnt; 517 sctp_saddr_ipif_t *ipif_obj; 518 int hindex; 519 520 hindex = SCTP_IPIF_ADDR_HASH(ipif->sctp_ipif_saddr, 521 ipif->sctp_ipif_isv6); 522 ipif_obj = list_head(&sctp->sctp_saddrs[hindex].sctp_ipif_list); 523 for (cnt = 0; cnt < sctp->sctp_saddrs[hindex].ipif_count; cnt++) { 524 if (IN6_ARE_ADDR_EQUAL(&ipif_obj->saddr_ipifp->sctp_ipif_saddr, 525 &ipif->sctp_ipif_saddr)) { 526 list_remove(&sctp->sctp_saddrs[hindex].sctp_ipif_list, 527 ipif_obj); 528 sctp->sctp_saddrs[hindex].ipif_count--; 529 sctp->sctp_nsaddrs--; 530 sctp_fix_saddr(sctp, &ipif->sctp_ipif_saddr); 531 SCTP_IPIF_REFRELE(ipif_obj->saddr_ipifp); 532 kmem_free(ipif_obj, sizeof (sctp_saddr_ipif_t)); 533 break; 534 } 535 ipif_obj = list_next(&sctp->sctp_saddrs[hindex].sctp_ipif_list, 536 ipif_obj); 537 } 538 } 539 540 static int 541 sctp_compare_ipif_list(sctp_ipif_hash_t *list1, sctp_ipif_hash_t *list2) 542 { 543 int i; 544 int j; 545 sctp_saddr_ipif_t *obj1; 546 sctp_saddr_ipif_t *obj2; 547 int overlap = 0; 548 549 obj1 = list_head(&list1->sctp_ipif_list); 550 for (i = 0; i < list1->ipif_count; i++) { 551 obj2 = list_head(&list2->sctp_ipif_list); 552 for (j = 0; j < list2->ipif_count; j++) { 553 if (IN6_ARE_ADDR_EQUAL( 554 &obj1->saddr_ipifp->sctp_ipif_saddr, 555 &obj2->saddr_ipifp->sctp_ipif_saddr)) { 556 overlap++; 557 break; 558 } 559 obj2 = list_next(&list2->sctp_ipif_list, 560 obj2); 561 } 562 obj1 = list_next(&list1->sctp_ipif_list, obj1); 563 } 564 return (overlap); 565 } 566 567 int 568 sctp_compare_saddrs(sctp_t *sctp1, sctp_t *sctp2) 569 { 570 int i; 571 int overlap = 0; 572 573 for (i = 0; i < SCTP_IPIF_HASH; i++) { 574 overlap += sctp_compare_ipif_list(&sctp1->sctp_saddrs[i], 575 &sctp2->sctp_saddrs[i]); 576 } 577 578 if (sctp1->sctp_nsaddrs == sctp2->sctp_nsaddrs && 579 overlap == sctp1->sctp_nsaddrs) { 580 return (SCTP_ADDR_EQUAL); 581 } 582 583 if (overlap == sctp1->sctp_nsaddrs) 584 return (SCTP_ADDR_SUBSET); 585 586 if (overlap > 0) 587 return (SCTP_ADDR_OVERLAP); 588 589 return (SCTP_ADDR_DISJOINT); 590 } 591 592 static int 593 sctp_copy_ipifs(sctp_ipif_hash_t *list1, sctp_t *sctp2, int sleep) 594 { 595 int i; 596 sctp_saddr_ipif_t *obj; 597 int error = 0; 598 599 obj = list_head(&list1->sctp_ipif_list); 600 for (i = 0; i < list1->ipif_count; i++) { 601 SCTP_IPIF_REFHOLD(obj->saddr_ipifp); 602 error = sctp_ipif_hash_insert(sctp2, obj->saddr_ipifp, sleep, 603 B_FALSE, B_FALSE); 604 ASSERT(error != EALREADY); 605 if (error != 0) 606 return (error); 607 obj = list_next(&list1->sctp_ipif_list, obj); 608 } 609 return (error); 610 } 611 612 int 613 sctp_dup_saddrs(sctp_t *sctp1, sctp_t *sctp2, int sleep) 614 { 615 int error = 0; 616 int i; 617 618 if (sctp1 == NULL || sctp1->sctp_bound_to_all == 1) 619 return (sctp_get_all_ipifs(sctp2, sleep)); 620 621 for (i = 0; i < SCTP_IPIF_HASH; i++) { 622 if (sctp1->sctp_saddrs[i].ipif_count == 0) 623 continue; 624 error = sctp_copy_ipifs(&sctp1->sctp_saddrs[i], sctp2, sleep); 625 if (error != 0) { 626 sctp_free_saddrs(sctp2); 627 return (error); 628 } 629 } 630 return (0); 631 } 632 633 void 634 sctp_free_saddrs(sctp_t *sctp) 635 { 636 int i; 637 int l; 638 sctp_saddr_ipif_t *obj; 639 640 if (sctp->sctp_nsaddrs == 0) 641 return; 642 for (i = 0; i < SCTP_IPIF_HASH; i++) { 643 if (sctp->sctp_saddrs[i].ipif_count == 0) 644 continue; 645 obj = list_tail(&sctp->sctp_saddrs[i].sctp_ipif_list); 646 for (l = 0; l < sctp->sctp_saddrs[i].ipif_count; l++) { 647 list_remove(&sctp->sctp_saddrs[i].sctp_ipif_list, obj); 648 SCTP_IPIF_REFRELE(obj->saddr_ipifp); 649 sctp->sctp_nsaddrs--; 650 kmem_free(obj, sizeof (sctp_saddr_ipif_t)); 651 obj = list_tail(&sctp->sctp_saddrs[i].sctp_ipif_list); 652 } 653 sctp->sctp_saddrs[i].ipif_count = 0; 654 } 655 if (sctp->sctp_bound_to_all == 1) 656 sctp->sctp_bound_to_all = 0; 657 ASSERT(sctp->sctp_nsaddrs == 0); 658 } 659 660 /* 661 * Add/Delete the given ILL from the SCTP ILL list. Called with no locks 662 * held. 663 */ 664 void 665 sctp_update_ill(ill_t *ill, int op) 666 { 667 int i; 668 sctp_ill_t *sctp_ill = NULL; 669 uint_t index; 670 netstack_t *ns = ill->ill_ipst->ips_netstack; 671 sctp_stack_t *sctps = ns->netstack_sctp; 672 673 rw_enter(&sctps->sctps_g_ills_lock, RW_WRITER); 674 675 index = SCTP_ILL_HASH_FN(SCTP_ILL_TO_PHYINDEX(ill)); 676 sctp_ill = list_head(&sctps->sctps_g_ills[index].sctp_ill_list); 677 for (i = 0; i < sctps->sctps_g_ills[index].ill_count; i++) { 678 if ((sctp_ill->sctp_ill_index == SCTP_ILL_TO_PHYINDEX(ill)) && 679 (sctp_ill->sctp_ill_isv6 == ill->ill_isv6)) { 680 break; 681 } 682 sctp_ill = list_next(&sctps->sctps_g_ills[index].sctp_ill_list, 683 sctp_ill); 684 } 685 686 switch (op) { 687 case SCTP_ILL_INSERT: 688 if (sctp_ill != NULL) { 689 /* Unmark it if it is condemned */ 690 if (sctp_ill->sctp_ill_state == SCTP_ILLS_CONDEMNED) 691 sctp_ill->sctp_ill_state = 0; 692 rw_exit(&sctps->sctps_g_ills_lock); 693 return; 694 } 695 sctp_ill = kmem_zalloc(sizeof (sctp_ill_t), KM_NOSLEEP); 696 /* Need to re-try? */ 697 if (sctp_ill == NULL) { 698 cmn_err(CE_WARN, "sctp_update_ill: error adding " 699 "ILL %p to SCTP's ILL list", (void *)ill); 700 rw_exit(&sctps->sctps_g_ills_lock); 701 return; 702 } 703 sctp_ill->sctp_ill_name = kmem_zalloc(ill->ill_name_length, 704 KM_NOSLEEP); 705 if (sctp_ill->sctp_ill_name == NULL) { 706 cmn_err(CE_WARN, "sctp_update_ill: error adding " 707 "ILL %p to SCTP's ILL list", (void *)ill); 708 kmem_free(sctp_ill, sizeof (sctp_ill_t)); 709 rw_exit(&sctps->sctps_g_ills_lock); 710 return; 711 } 712 bcopy(ill->ill_name, sctp_ill->sctp_ill_name, 713 ill->ill_name_length); 714 sctp_ill->sctp_ill_name_length = ill->ill_name_length; 715 sctp_ill->sctp_ill_index = SCTP_ILL_TO_PHYINDEX(ill); 716 sctp_ill->sctp_ill_flags = ill->ill_phyint->phyint_flags; 717 sctp_ill->sctp_ill_netstack = ns; /* No netstack_hold */ 718 sctp_ill->sctp_ill_isv6 = ill->ill_isv6; 719 list_insert_tail(&sctps->sctps_g_ills[index].sctp_ill_list, 720 (void *)sctp_ill); 721 sctps->sctps_g_ills[index].ill_count++; 722 sctps->sctps_ills_count++; 723 724 break; 725 726 case SCTP_ILL_REMOVE: 727 728 if (sctp_ill == NULL) { 729 rw_exit(&sctps->sctps_g_ills_lock); 730 return; 731 } 732 if (sctp_ill->sctp_ill_ipifcnt == 0) { 733 list_remove(&sctps->sctps_g_ills[index].sctp_ill_list, 734 (void *)sctp_ill); 735 sctps->sctps_g_ills[index].ill_count--; 736 sctps->sctps_ills_count--; 737 kmem_free(sctp_ill->sctp_ill_name, 738 ill->ill_name_length); 739 kmem_free(sctp_ill, sizeof (sctp_ill_t)); 740 } else { 741 sctp_ill->sctp_ill_state = SCTP_ILLS_CONDEMNED; 742 } 743 744 break; 745 } 746 rw_exit(&sctps->sctps_g_ills_lock); 747 } 748 749 /* 750 * The ILL's index is being changed, just remove it from the old list, 751 * change the SCTP ILL's index and re-insert using the new index. 752 */ 753 void 754 sctp_ill_reindex(ill_t *ill, uint_t orig_ill_index) 755 { 756 sctp_ill_t *sctp_ill = NULL; 757 sctp_ill_t *nxt_sill; 758 uint_t indx; 759 uint_t nindx; 760 boolean_t once = B_FALSE; 761 netstack_t *ns = ill->ill_ipst->ips_netstack; 762 sctp_stack_t *sctps = ns->netstack_sctp; 763 764 rw_enter(&sctps->sctps_g_ills_lock, RW_WRITER); 765 766 indx = SCTP_ILL_HASH_FN(orig_ill_index); 767 nindx = SCTP_ILL_HASH_FN(SCTP_ILL_TO_PHYINDEX(ill)); 768 sctp_ill = list_head(&sctps->sctps_g_ills[indx].sctp_ill_list); 769 while (sctp_ill != NULL) { 770 nxt_sill = list_next(&sctps->sctps_g_ills[indx].sctp_ill_list, 771 sctp_ill); 772 if (sctp_ill->sctp_ill_index == orig_ill_index) { 773 sctp_ill->sctp_ill_index = SCTP_ILL_TO_PHYINDEX(ill); 774 /* 775 * if the new index hashes to the same value, all's 776 * done. 777 */ 778 if (nindx != indx) { 779 list_remove( 780 &sctps->sctps_g_ills[indx].sctp_ill_list, 781 (void *)sctp_ill); 782 sctps->sctps_g_ills[indx].ill_count--; 783 list_insert_tail( 784 &sctps->sctps_g_ills[nindx].sctp_ill_list, 785 (void *)sctp_ill); 786 sctps->sctps_g_ills[nindx].ill_count++; 787 } 788 if (once) 789 break; 790 /* We might have one for v4 and for v6 */ 791 once = B_TRUE; 792 } 793 sctp_ill = nxt_sill; 794 } 795 rw_exit(&sctps->sctps_g_ills_lock); 796 } 797 798 /* move ipif from f_ill to t_ill */ 799 void 800 sctp_move_ipif(ipif_t *ipif, ill_t *f_ill, ill_t *t_ill) 801 { 802 sctp_ill_t *fsctp_ill = NULL; 803 sctp_ill_t *tsctp_ill = NULL; 804 sctp_ipif_t *sctp_ipif; 805 uint_t hindex; 806 int i; 807 netstack_t *ns = ipif->ipif_ill->ill_ipst->ips_netstack; 808 sctp_stack_t *sctps = ns->netstack_sctp; 809 810 rw_enter(&sctps->sctps_g_ills_lock, RW_READER); 811 rw_enter(&sctps->sctps_g_ipifs_lock, RW_READER); 812 813 hindex = SCTP_ILL_HASH_FN(SCTP_ILL_TO_PHYINDEX(f_ill)); 814 fsctp_ill = list_head(&sctps->sctps_g_ills[hindex].sctp_ill_list); 815 for (i = 0; i < sctps->sctps_g_ills[hindex].ill_count; i++) { 816 if (fsctp_ill->sctp_ill_index == SCTP_ILL_TO_PHYINDEX(f_ill) && 817 fsctp_ill->sctp_ill_isv6 == f_ill->ill_isv6) { 818 break; 819 } 820 fsctp_ill = list_next( 821 &sctps->sctps_g_ills[hindex].sctp_ill_list, fsctp_ill); 822 } 823 824 hindex = SCTP_ILL_HASH_FN(SCTP_ILL_TO_PHYINDEX(t_ill)); 825 tsctp_ill = list_head(&sctps->sctps_g_ills[hindex].sctp_ill_list); 826 for (i = 0; i < sctps->sctps_g_ills[hindex].ill_count; i++) { 827 if (tsctp_ill->sctp_ill_index == SCTP_ILL_TO_PHYINDEX(t_ill) && 828 tsctp_ill->sctp_ill_isv6 == t_ill->ill_isv6) { 829 break; 830 } 831 tsctp_ill = list_next( 832 &sctps->sctps_g_ills[hindex].sctp_ill_list, tsctp_ill); 833 } 834 835 hindex = SCTP_IPIF_ADDR_HASH(ipif->ipif_v6lcl_addr, 836 ipif->ipif_ill->ill_isv6); 837 sctp_ipif = list_head(&sctps->sctps_g_ipifs[hindex].sctp_ipif_list); 838 for (i = 0; i < sctps->sctps_g_ipifs[hindex].ipif_count; i++) { 839 if (sctp_ipif->sctp_ipif_id == ipif->ipif_seqid) 840 break; 841 sctp_ipif = list_next( 842 &sctps->sctps_g_ipifs[hindex].sctp_ipif_list, sctp_ipif); 843 } 844 /* Should be an ASSERT? */ 845 if (fsctp_ill == NULL || tsctp_ill == NULL || sctp_ipif == NULL) { 846 ip1dbg(("sctp_move_ipif: error moving ipif %p from %p to %p\n", 847 (void *)ipif, (void *)f_ill, (void *)t_ill)); 848 rw_exit(&sctps->sctps_g_ipifs_lock); 849 rw_exit(&sctps->sctps_g_ills_lock); 850 return; 851 } 852 rw_enter(&sctp_ipif->sctp_ipif_lock, RW_WRITER); 853 ASSERT(sctp_ipif->sctp_ipif_ill == fsctp_ill); 854 sctp_ipif->sctp_ipif_ill = tsctp_ill; 855 rw_exit(&sctp_ipif->sctp_ipif_lock); 856 (void) atomic_add_32_nv(&fsctp_ill->sctp_ill_ipifcnt, -1); 857 atomic_add_32(&tsctp_ill->sctp_ill_ipifcnt, 1); 858 rw_exit(&sctps->sctps_g_ipifs_lock); 859 rw_exit(&sctps->sctps_g_ills_lock); 860 } 861 862 /* 863 * Walk the list of SCTPs and find each that has oipif in it's saddr list, and 864 * if so replace it with nipif. 865 */ 866 void 867 sctp_update_saddrs(sctp_ipif_t *oipif, sctp_ipif_t *nipif, int idx, 868 sctp_stack_t *sctps) 869 { 870 sctp_t *sctp; 871 sctp_t *sctp_prev = NULL; 872 sctp_saddr_ipif_t *sobj; 873 int count; 874 875 sctp = sctps->sctps_gsctp; 876 mutex_enter(&sctps->sctps_g_lock); 877 while (sctp != NULL && oipif->sctp_ipif_refcnt > 0) { 878 mutex_enter(&sctp->sctp_reflock); 879 if (sctp->sctp_condemned || 880 sctp->sctp_saddrs[idx].ipif_count <= 0) { 881 mutex_exit(&sctp->sctp_reflock); 882 sctp = list_next(&sctps->sctps_g_list, sctp); 883 continue; 884 } 885 sctp->sctp_refcnt++; 886 mutex_exit(&sctp->sctp_reflock); 887 mutex_exit(&sctps->sctps_g_lock); 888 if (sctp_prev != NULL) 889 SCTP_REFRELE(sctp_prev); 890 891 RUN_SCTP(sctp); 892 sobj = list_head(&sctp->sctp_saddrs[idx].sctp_ipif_list); 893 for (count = 0; count < 894 sctp->sctp_saddrs[idx].ipif_count; count++) { 895 if (sobj->saddr_ipifp == oipif) { 896 SCTP_IPIF_REFHOLD(nipif); 897 sobj->saddr_ipifp = nipif; 898 ASSERT(oipif->sctp_ipif_refcnt > 0); 899 /* We have the writer lock */ 900 oipif->sctp_ipif_refcnt--; 901 /* 902 * Can't have more than one referring 903 * to the same sctp_ipif. 904 */ 905 break; 906 } 907 sobj = list_next(&sctp->sctp_saddrs[idx].sctp_ipif_list, 908 sobj); 909 } 910 WAKE_SCTP(sctp); 911 sctp_prev = sctp; 912 mutex_enter(&sctps->sctps_g_lock); 913 sctp = list_next(&sctps->sctps_g_list, sctp); 914 } 915 mutex_exit(&sctps->sctps_g_lock); 916 if (sctp_prev != NULL) 917 SCTP_REFRELE(sctp_prev); 918 } 919 920 /* 921 * Given an ipif, walk the hash list in the global ipif table and for 922 * any other SCTP ipif with the same address and non-zero reference, walk 923 * the SCTP list and update the saddr list, if required, to point to the 924 * new SCTP ipif. 925 */ 926 void 927 sctp_chk_and_updt_saddr(int hindex, sctp_ipif_t *ipif, sctp_stack_t *sctps) 928 { 929 int cnt; 930 sctp_ipif_t *sipif; 931 932 ASSERT(sctps->sctps_g_ipifs[hindex].ipif_count > 0); 933 ASSERT(ipif->sctp_ipif_state == SCTP_IPIFS_UP); 934 935 sipif = list_head(&sctps->sctps_g_ipifs[hindex].sctp_ipif_list); 936 for (cnt = 0; cnt < sctps->sctps_g_ipifs[hindex].ipif_count; cnt++) { 937 rw_enter(&sipif->sctp_ipif_lock, RW_WRITER); 938 if (sipif->sctp_ipif_id != ipif->sctp_ipif_id && 939 IN6_ARE_ADDR_EQUAL(&sipif->sctp_ipif_saddr, 940 &ipif->sctp_ipif_saddr) && sipif->sctp_ipif_refcnt > 0) { 941 /* 942 * There can only be one address up at any time 943 * and we are here because ipif has been brought 944 * up. 945 */ 946 ASSERT(sipif->sctp_ipif_state != SCTP_IPIFS_UP); 947 /* 948 * Someone has a reference to this we need to update to 949 * point to the new sipif. 950 */ 951 sctp_update_saddrs(sipif, ipif, hindex, sctps); 952 } 953 rw_exit(&sipif->sctp_ipif_lock); 954 sipif = list_next(&sctps->sctps_g_ipifs[hindex].sctp_ipif_list, 955 sipif); 956 } 957 } 958 959 /* 960 * Insert a new SCTP ipif using 'ipif'. v6addr is the address that existed 961 * prior to the current address in 'ipif'. Only when an existing address 962 * is changed on an IPIF, will v6addr be specified. If the IPIF already 963 * exists in the global SCTP ipif table, then we either removed it, if 964 * it doesn't have any existing reference, or mark it condemned otherwise. 965 * If an address is being brought up (IPIF_UP), then we need to scan 966 * the SCTP list to check if there is any SCTP that points to the *same* 967 * address on a different SCTP ipif and update in that case. 968 */ 969 void 970 sctp_update_ipif_addr(ipif_t *ipif, in6_addr_t v6addr) 971 { 972 ill_t *ill = ipif->ipif_ill; 973 int i; 974 sctp_ill_t *sctp_ill; 975 sctp_ill_t *osctp_ill; 976 sctp_ipif_t *sctp_ipif = NULL; 977 sctp_ipif_t *osctp_ipif = NULL; 978 uint_t ill_index; 979 int hindex; 980 sctp_stack_t *sctps; 981 982 983 sctps = ipif->ipif_ill->ill_ipst->ips_netstack->netstack_sctp; 984 985 /* Index for new address */ 986 hindex = SCTP_IPIF_ADDR_HASH(ipif->ipif_v6lcl_addr, ill->ill_isv6); 987 988 /* 989 * The address on this IPIF is changing, we need to look for 990 * this old address and mark it condemned, before creating 991 * one for the new address. 992 */ 993 osctp_ipif = sctp_lookup_ipif_addr(&v6addr, B_FALSE, 994 ipif->ipif_zoneid, B_TRUE, SCTP_ILL_TO_PHYINDEX(ill), 995 ipif->ipif_seqid, B_FALSE, sctps); 996 997 rw_enter(&sctps->sctps_g_ills_lock, RW_READER); 998 rw_enter(&sctps->sctps_g_ipifs_lock, RW_WRITER); 999 1000 ill_index = SCTP_ILL_HASH_FN(SCTP_ILL_TO_PHYINDEX(ill)); 1001 sctp_ill = list_head(&sctps->sctps_g_ills[ill_index].sctp_ill_list); 1002 for (i = 0; i < sctps->sctps_g_ills[ill_index].ill_count; i++) { 1003 if (sctp_ill->sctp_ill_index == SCTP_ILL_TO_PHYINDEX(ill) && 1004 sctp_ill->sctp_ill_isv6 == ill->ill_isv6) { 1005 break; 1006 } 1007 sctp_ill = list_next( 1008 &sctps->sctps_g_ills[ill_index].sctp_ill_list, sctp_ill); 1009 } 1010 1011 if (sctp_ill == NULL) { 1012 ip1dbg(("sctp_update_ipif_addr: ill not found ..\n")); 1013 rw_exit(&sctps->sctps_g_ipifs_lock); 1014 rw_exit(&sctps->sctps_g_ills_lock); 1015 return; 1016 } 1017 1018 if (osctp_ipif != NULL) { 1019 1020 /* The address is the same? */ 1021 if (IN6_ARE_ADDR_EQUAL(&ipif->ipif_v6lcl_addr, &v6addr)) { 1022 boolean_t chk_n_updt = B_FALSE; 1023 1024 rw_downgrade(&sctps->sctps_g_ipifs_lock); 1025 rw_enter(&osctp_ipif->sctp_ipif_lock, RW_WRITER); 1026 if (ipif->ipif_flags & IPIF_UP && 1027 osctp_ipif->sctp_ipif_state != SCTP_IPIFS_UP) { 1028 osctp_ipif->sctp_ipif_state = SCTP_IPIFS_UP; 1029 chk_n_updt = B_TRUE; 1030 } else { 1031 osctp_ipif->sctp_ipif_state = SCTP_IPIFS_DOWN; 1032 } 1033 osctp_ipif->sctp_ipif_flags = ipif->ipif_flags; 1034 rw_exit(&osctp_ipif->sctp_ipif_lock); 1035 if (chk_n_updt) { 1036 sctp_chk_and_updt_saddr(hindex, osctp_ipif, 1037 sctps); 1038 } 1039 rw_exit(&sctps->sctps_g_ipifs_lock); 1040 rw_exit(&sctps->sctps_g_ills_lock); 1041 return; 1042 } 1043 /* 1044 * We are effectively removing this address from the ILL. 1045 */ 1046 if (osctp_ipif->sctp_ipif_refcnt != 0) { 1047 osctp_ipif->sctp_ipif_state = SCTP_IPIFS_CONDEMNED; 1048 } else { 1049 list_t *ipif_list; 1050 int ohindex; 1051 1052 osctp_ill = osctp_ipif->sctp_ipif_ill; 1053 /* hash index for the old one */ 1054 ohindex = SCTP_IPIF_ADDR_HASH( 1055 osctp_ipif->sctp_ipif_saddr, 1056 osctp_ipif->sctp_ipif_isv6); 1057 1058 ipif_list = 1059 &sctps->sctps_g_ipifs[ohindex].sctp_ipif_list; 1060 1061 list_remove(ipif_list, (void *)osctp_ipif); 1062 sctps->sctps_g_ipifs[ohindex].ipif_count--; 1063 sctps->sctps_g_ipifs_count--; 1064 rw_destroy(&osctp_ipif->sctp_ipif_lock); 1065 kmem_free(osctp_ipif, sizeof (sctp_ipif_t)); 1066 (void) atomic_add_32_nv(&osctp_ill->sctp_ill_ipifcnt, 1067 -1); 1068 } 1069 } 1070 1071 sctp_ipif = kmem_zalloc(sizeof (sctp_ipif_t), KM_NOSLEEP); 1072 /* Try again? */ 1073 if (sctp_ipif == NULL) { 1074 cmn_err(CE_WARN, "sctp_update_ipif_addr: error adding " 1075 "IPIF %p to SCTP's IPIF list", (void *)ipif); 1076 rw_exit(&sctps->sctps_g_ipifs_lock); 1077 rw_exit(&sctps->sctps_g_ills_lock); 1078 return; 1079 } 1080 sctps->sctps_g_ipifs_count++; 1081 rw_init(&sctp_ipif->sctp_ipif_lock, NULL, RW_DEFAULT, NULL); 1082 sctp_ipif->sctp_ipif_saddr = ipif->ipif_v6lcl_addr; 1083 sctp_ipif->sctp_ipif_ill = sctp_ill; 1084 sctp_ipif->sctp_ipif_isv6 = ill->ill_isv6; 1085 sctp_ipif->sctp_ipif_zoneid = ipif->ipif_zoneid; 1086 sctp_ipif->sctp_ipif_id = ipif->ipif_seqid; 1087 if (ipif->ipif_flags & IPIF_UP) 1088 sctp_ipif->sctp_ipif_state = SCTP_IPIFS_UP; 1089 else 1090 sctp_ipif->sctp_ipif_state = SCTP_IPIFS_DOWN; 1091 sctp_ipif->sctp_ipif_flags = ipif->ipif_flags; 1092 /* 1093 * We add it to the head so that it is quicker to find good/recent 1094 * additions. 1095 */ 1096 list_insert_head(&sctps->sctps_g_ipifs[hindex].sctp_ipif_list, 1097 (void *)sctp_ipif); 1098 sctps->sctps_g_ipifs[hindex].ipif_count++; 1099 atomic_add_32(&sctp_ill->sctp_ill_ipifcnt, 1); 1100 if (sctp_ipif->sctp_ipif_state == SCTP_IPIFS_UP) 1101 sctp_chk_and_updt_saddr(hindex, sctp_ipif, sctps); 1102 rw_exit(&sctps->sctps_g_ipifs_lock); 1103 rw_exit(&sctps->sctps_g_ills_lock); 1104 } 1105 1106 /* Insert, Remove, Mark up or Mark down the ipif */ 1107 void 1108 sctp_update_ipif(ipif_t *ipif, int op) 1109 { 1110 ill_t *ill = ipif->ipif_ill; 1111 int i; 1112 sctp_ill_t *sctp_ill; 1113 sctp_ipif_t *sctp_ipif; 1114 uint_t ill_index; 1115 uint_t hindex; 1116 netstack_t *ns = ipif->ipif_ill->ill_ipst->ips_netstack; 1117 sctp_stack_t *sctps = ns->netstack_sctp; 1118 1119 ip2dbg(("sctp_update_ipif: %s %d\n", ill->ill_name, ipif->ipif_seqid)); 1120 1121 rw_enter(&sctps->sctps_g_ills_lock, RW_READER); 1122 rw_enter(&sctps->sctps_g_ipifs_lock, RW_WRITER); 1123 1124 ill_index = SCTP_ILL_HASH_FN(SCTP_ILL_TO_PHYINDEX(ill)); 1125 sctp_ill = list_head(&sctps->sctps_g_ills[ill_index].sctp_ill_list); 1126 for (i = 0; i < sctps->sctps_g_ills[ill_index].ill_count; i++) { 1127 if (sctp_ill->sctp_ill_index == SCTP_ILL_TO_PHYINDEX(ill) && 1128 sctp_ill->sctp_ill_isv6 == ill->ill_isv6) { 1129 break; 1130 } 1131 sctp_ill = list_next( 1132 &sctps->sctps_g_ills[ill_index].sctp_ill_list, sctp_ill); 1133 } 1134 if (sctp_ill == NULL) { 1135 rw_exit(&sctps->sctps_g_ipifs_lock); 1136 rw_exit(&sctps->sctps_g_ills_lock); 1137 return; 1138 } 1139 1140 hindex = SCTP_IPIF_ADDR_HASH(ipif->ipif_v6lcl_addr, 1141 ipif->ipif_ill->ill_isv6); 1142 sctp_ipif = list_head(&sctps->sctps_g_ipifs[hindex].sctp_ipif_list); 1143 for (i = 0; i < sctps->sctps_g_ipifs[hindex].ipif_count; i++) { 1144 if (sctp_ipif->sctp_ipif_id == ipif->ipif_seqid) { 1145 ASSERT(IN6_ARE_ADDR_EQUAL(&sctp_ipif->sctp_ipif_saddr, 1146 &ipif->ipif_v6lcl_addr)); 1147 break; 1148 } 1149 sctp_ipif = list_next( 1150 &sctps->sctps_g_ipifs[hindex].sctp_ipif_list, 1151 sctp_ipif); 1152 } 1153 if (sctp_ipif == NULL) { 1154 ip1dbg(("sctp_update_ipif: null sctp_ipif for %d\n", op)); 1155 rw_exit(&sctps->sctps_g_ipifs_lock); 1156 rw_exit(&sctps->sctps_g_ills_lock); 1157 return; 1158 } 1159 ASSERT(sctp_ill == sctp_ipif->sctp_ipif_ill); 1160 switch (op) { 1161 case SCTP_IPIF_REMOVE: 1162 { 1163 list_t *ipif_list; 1164 list_t *ill_list; 1165 1166 ill_list = &sctps->sctps_g_ills[ill_index].sctp_ill_list; 1167 ipif_list = &sctps->sctps_g_ipifs[hindex].sctp_ipif_list; 1168 if (sctp_ipif->sctp_ipif_refcnt != 0) { 1169 sctp_ipif->sctp_ipif_state = SCTP_IPIFS_CONDEMNED; 1170 rw_exit(&sctps->sctps_g_ipifs_lock); 1171 rw_exit(&sctps->sctps_g_ills_lock); 1172 return; 1173 } 1174 list_remove(ipif_list, (void *)sctp_ipif); 1175 sctps->sctps_g_ipifs[hindex].ipif_count--; 1176 sctps->sctps_g_ipifs_count--; 1177 rw_destroy(&sctp_ipif->sctp_ipif_lock); 1178 kmem_free(sctp_ipif, sizeof (sctp_ipif_t)); 1179 (void) atomic_add_32_nv(&sctp_ill->sctp_ill_ipifcnt, -1); 1180 if (rw_tryupgrade(&sctps->sctps_g_ills_lock) != 0) { 1181 rw_downgrade(&sctps->sctps_g_ipifs_lock); 1182 if (sctp_ill->sctp_ill_ipifcnt == 0 && 1183 sctp_ill->sctp_ill_state == SCTP_ILLS_CONDEMNED) { 1184 list_remove(ill_list, (void *)sctp_ill); 1185 sctps->sctps_ills_count--; 1186 sctps->sctps_g_ills[ill_index].ill_count--; 1187 kmem_free(sctp_ill->sctp_ill_name, 1188 sctp_ill->sctp_ill_name_length); 1189 kmem_free(sctp_ill, sizeof (sctp_ill_t)); 1190 } 1191 } 1192 break; 1193 } 1194 1195 case SCTP_IPIF_UP: 1196 1197 rw_downgrade(&sctps->sctps_g_ipifs_lock); 1198 rw_enter(&sctp_ipif->sctp_ipif_lock, RW_WRITER); 1199 sctp_ipif->sctp_ipif_state = SCTP_IPIFS_UP; 1200 sctp_ipif->sctp_ipif_mtu = ipif->ipif_mtu; 1201 sctp_ipif->sctp_ipif_flags = ipif->ipif_flags; 1202 rw_exit(&sctp_ipif->sctp_ipif_lock); 1203 sctp_chk_and_updt_saddr(hindex, sctp_ipif, 1204 ipif->ipif_ill->ill_ipst->ips_netstack->netstack_sctp); 1205 1206 break; 1207 1208 case SCTP_IPIF_UPDATE: 1209 1210 rw_downgrade(&sctps->sctps_g_ipifs_lock); 1211 rw_enter(&sctp_ipif->sctp_ipif_lock, RW_WRITER); 1212 sctp_ipif->sctp_ipif_mtu = ipif->ipif_mtu; 1213 sctp_ipif->sctp_ipif_zoneid = ipif->ipif_zoneid; 1214 sctp_ipif->sctp_ipif_flags = ipif->ipif_flags; 1215 rw_exit(&sctp_ipif->sctp_ipif_lock); 1216 1217 break; 1218 1219 case SCTP_IPIF_DOWN: 1220 1221 rw_downgrade(&sctps->sctps_g_ipifs_lock); 1222 rw_enter(&sctp_ipif->sctp_ipif_lock, RW_WRITER); 1223 sctp_ipif->sctp_ipif_state = SCTP_IPIFS_DOWN; 1224 sctp_ipif->sctp_ipif_mtu = ipif->ipif_mtu; 1225 sctp_ipif->sctp_ipif_flags = ipif->ipif_flags; 1226 rw_exit(&sctp_ipif->sctp_ipif_lock); 1227 1228 break; 1229 } 1230 rw_exit(&sctps->sctps_g_ipifs_lock); 1231 rw_exit(&sctps->sctps_g_ills_lock); 1232 } 1233 1234 /* 1235 * SCTP source address list manipulaton, locking not used (except for 1236 * sctp locking by the caller. 1237 */ 1238 1239 /* Remove a specific saddr from the list */ 1240 void 1241 sctp_del_saddr(sctp_t *sctp, sctp_saddr_ipif_t *sp) 1242 { 1243 if (sctp->sctp_conn_tfp != NULL) 1244 mutex_enter(&sctp->sctp_conn_tfp->tf_lock); 1245 1246 if (sctp->sctp_listen_tfp != NULL) 1247 mutex_enter(&sctp->sctp_listen_tfp->tf_lock); 1248 1249 sctp_ipif_hash_remove(sctp, sp->saddr_ipifp); 1250 1251 if (sctp->sctp_bound_to_all == 1) 1252 sctp->sctp_bound_to_all = 0; 1253 1254 if (sctp->sctp_conn_tfp != NULL) 1255 mutex_exit(&sctp->sctp_conn_tfp->tf_lock); 1256 1257 if (sctp->sctp_listen_tfp != NULL) 1258 mutex_exit(&sctp->sctp_listen_tfp->tf_lock); 1259 } 1260 1261 /* 1262 * Delete source address from the existing list. No error checking done here 1263 * Called with no locks held. 1264 */ 1265 void 1266 sctp_del_saddr_list(sctp_t *sctp, const void *addrs, int addcnt, 1267 boolean_t fanout_locked) 1268 { 1269 struct sockaddr_in *sin4; 1270 struct sockaddr_in6 *sin6; 1271 int cnt; 1272 in6_addr_t addr; 1273 sctp_ipif_t *sctp_ipif; 1274 int ifindex = 0; 1275 1276 ASSERT(sctp->sctp_nsaddrs >= addcnt); 1277 1278 if (!fanout_locked) { 1279 if (sctp->sctp_conn_tfp != NULL) 1280 mutex_enter(&sctp->sctp_conn_tfp->tf_lock); 1281 if (sctp->sctp_listen_tfp != NULL) 1282 mutex_enter(&sctp->sctp_listen_tfp->tf_lock); 1283 } 1284 1285 for (cnt = 0; cnt < addcnt; cnt++) { 1286 switch (sctp->sctp_family) { 1287 case AF_INET: 1288 sin4 = (struct sockaddr_in *)addrs + cnt; 1289 IN6_INADDR_TO_V4MAPPED(&sin4->sin_addr, &addr); 1290 break; 1291 1292 case AF_INET6: 1293 sin6 = (struct sockaddr_in6 *)addrs + cnt; 1294 addr = sin6->sin6_addr; 1295 ifindex = sin6->sin6_scope_id; 1296 break; 1297 } 1298 sctp_ipif = sctp_lookup_ipif_addr(&addr, B_FALSE, 1299 sctp->sctp_zoneid, !sctp->sctp_connp->conn_allzones, 1300 ifindex, 0, B_TRUE, sctp->sctp_sctps); 1301 ASSERT(sctp_ipif != NULL); 1302 sctp_ipif_hash_remove(sctp, sctp_ipif); 1303 } 1304 if (sctp->sctp_bound_to_all == 1) 1305 sctp->sctp_bound_to_all = 0; 1306 1307 if (!fanout_locked) { 1308 if (sctp->sctp_conn_tfp != NULL) 1309 mutex_exit(&sctp->sctp_conn_tfp->tf_lock); 1310 if (sctp->sctp_listen_tfp != NULL) 1311 mutex_exit(&sctp->sctp_listen_tfp->tf_lock); 1312 } 1313 } 1314 1315 /* 1316 * Given an address get the corresponding entry from the list 1317 * Called with no locks held. 1318 */ 1319 sctp_saddr_ipif_t * 1320 sctp_saddr_lookup(sctp_t *sctp, in6_addr_t *addr, uint_t ifindex) 1321 { 1322 int cnt; 1323 sctp_saddr_ipif_t *ipif_obj; 1324 int hindex; 1325 sctp_ipif_t *sctp_ipif; 1326 1327 hindex = SCTP_IPIF_ADDR_HASH(*addr, !IN6_IS_ADDR_V4MAPPED(addr)); 1328 if (sctp->sctp_saddrs[hindex].ipif_count == 0) 1329 return (NULL); 1330 1331 ipif_obj = list_head(&sctp->sctp_saddrs[hindex].sctp_ipif_list); 1332 for (cnt = 0; cnt < sctp->sctp_saddrs[hindex].ipif_count; cnt++) { 1333 sctp_ipif = ipif_obj->saddr_ipifp; 1334 /* 1335 * Zone check shouldn't be needed. 1336 */ 1337 if (IN6_ARE_ADDR_EQUAL(addr, &sctp_ipif->sctp_ipif_saddr) && 1338 (ifindex == 0 || 1339 ifindex == sctp_ipif->sctp_ipif_ill->sctp_ill_index) && 1340 SCTP_IPIF_USABLE(sctp_ipif->sctp_ipif_state)) { 1341 return (ipif_obj); 1342 } 1343 ipif_obj = list_next(&sctp->sctp_saddrs[hindex].sctp_ipif_list, 1344 ipif_obj); 1345 } 1346 return (NULL); 1347 } 1348 1349 /* Given an address, add it to the source address list */ 1350 int 1351 sctp_saddr_add_addr(sctp_t *sctp, in6_addr_t *addr, uint_t ifindex) 1352 { 1353 sctp_ipif_t *sctp_ipif; 1354 1355 sctp_ipif = sctp_lookup_ipif_addr(addr, B_TRUE, sctp->sctp_zoneid, 1356 !sctp->sctp_connp->conn_allzones, ifindex, 0, B_TRUE, 1357 sctp->sctp_sctps); 1358 if (sctp_ipif == NULL) 1359 return (EINVAL); 1360 1361 if (sctp_ipif_hash_insert(sctp, sctp_ipif, KM_NOSLEEP, B_FALSE, 1362 B_FALSE) != 0) { 1363 SCTP_IPIF_REFRELE(sctp_ipif); 1364 return (EINVAL); 1365 } 1366 return (0); 1367 } 1368 1369 /* 1370 * Remove or mark as dontsrc addresses that are currently not part of the 1371 * association. One would delete addresses when processing an INIT and 1372 * mark as dontsrc when processing an INIT-ACK. 1373 */ 1374 void 1375 sctp_check_saddr(sctp_t *sctp, int supp_af, boolean_t delete, 1376 in6_addr_t *no_del_addr) 1377 { 1378 int i; 1379 int l; 1380 sctp_saddr_ipif_t *obj; 1381 int scanned = 0; 1382 int naddr; 1383 int nsaddr; 1384 1385 ASSERT(!sctp->sctp_loopback && !sctp->sctp_linklocal && supp_af != 0); 1386 1387 /* 1388 * Irregardless of the supported address in the INIT, v4 1389 * must be supported. 1390 */ 1391 if (sctp->sctp_family == AF_INET) 1392 supp_af = PARM_SUPP_V4; 1393 1394 nsaddr = sctp->sctp_nsaddrs; 1395 for (i = 0; i < SCTP_IPIF_HASH; i++) { 1396 if (sctp->sctp_saddrs[i].ipif_count == 0) 1397 continue; 1398 obj = list_head(&sctp->sctp_saddrs[i].sctp_ipif_list); 1399 naddr = sctp->sctp_saddrs[i].ipif_count; 1400 for (l = 0; l < naddr; l++) { 1401 sctp_ipif_t *ipif; 1402 1403 ipif = obj->saddr_ipifp; 1404 scanned++; 1405 1406 if (IN6_ARE_ADDR_EQUAL(&ipif->sctp_ipif_saddr, 1407 no_del_addr)) { 1408 goto next_obj; 1409 } 1410 1411 /* 1412 * Delete/mark dontsrc loopback/linklocal addresses and 1413 * unsupported address. 1414 * On a clustered node, we trust the clustering module 1415 * to do the right thing w.r.t loopback addresses, so 1416 * we ignore loopback addresses in this check. 1417 */ 1418 if ((SCTP_IS_IPIF_LOOPBACK(ipif) && 1419 cl_sctp_check_addrs == NULL) || 1420 SCTP_IS_IPIF_LINKLOCAL(ipif) || 1421 SCTP_UNSUPP_AF(ipif, supp_af)) { 1422 if (!delete) { 1423 obj->saddr_ipif_unconfirmed = 1; 1424 goto next_obj; 1425 } 1426 if (sctp->sctp_bound_to_all == 1) 1427 sctp->sctp_bound_to_all = 0; 1428 if (scanned < nsaddr) { 1429 obj = list_next(&sctp->sctp_saddrs[i]. 1430 sctp_ipif_list, obj); 1431 sctp_ipif_hash_remove(sctp, ipif); 1432 continue; 1433 } 1434 sctp_ipif_hash_remove(sctp, ipif); 1435 } 1436 next_obj: 1437 if (scanned >= nsaddr) 1438 return; 1439 obj = list_next(&sctp->sctp_saddrs[i].sctp_ipif_list, 1440 obj); 1441 } 1442 } 1443 } 1444 1445 1446 /* Get the first valid address from the list. Called with no locks held */ 1447 in6_addr_t 1448 sctp_get_valid_addr(sctp_t *sctp, boolean_t isv6, boolean_t *addr_set) 1449 { 1450 int i; 1451 int l; 1452 sctp_saddr_ipif_t *obj; 1453 int scanned = 0; 1454 in6_addr_t addr; 1455 1456 for (i = 0; i < SCTP_IPIF_HASH; i++) { 1457 if (sctp->sctp_saddrs[i].ipif_count == 0) 1458 continue; 1459 obj = list_head(&sctp->sctp_saddrs[i].sctp_ipif_list); 1460 for (l = 0; l < sctp->sctp_saddrs[i].ipif_count; l++) { 1461 sctp_ipif_t *ipif; 1462 1463 ipif = obj->saddr_ipifp; 1464 if (!SCTP_DONT_SRC(obj) && 1465 ipif->sctp_ipif_isv6 == isv6 && 1466 ipif->sctp_ipif_state == SCTP_IPIFS_UP) { 1467 *addr_set = B_TRUE; 1468 return (ipif->sctp_ipif_saddr); 1469 } 1470 scanned++; 1471 if (scanned >= sctp->sctp_nsaddrs) 1472 goto got_none; 1473 obj = list_next(&sctp->sctp_saddrs[i].sctp_ipif_list, 1474 obj); 1475 } 1476 } 1477 got_none: 1478 /* Need to double check this */ 1479 if (isv6 == B_TRUE) 1480 addr = ipv6_all_zeros; 1481 else 1482 IN6_IPADDR_TO_V4MAPPED(0, &addr); 1483 *addr_set = B_FALSE; 1484 return (addr); 1485 } 1486 1487 /* 1488 * Return the list of local addresses of an association. The parameter 1489 * myaddrs is supposed to be either (struct sockaddr_in *) or (struct 1490 * sockaddr_in6 *) depending on the address family. 1491 */ 1492 int 1493 sctp_getmyaddrs(void *conn, void *myaddrs, int *addrcnt) 1494 { 1495 int i; 1496 int l; 1497 sctp_saddr_ipif_t *obj; 1498 sctp_t *sctp = (sctp_t *)conn; 1499 int family = sctp->sctp_family; 1500 int max = *addrcnt; 1501 size_t added = 0; 1502 struct sockaddr_in6 *sin6; 1503 struct sockaddr_in *sin4; 1504 int scanned = 0; 1505 boolean_t skip_lback = B_FALSE; 1506 1507 if (sctp->sctp_nsaddrs == 0) 1508 return (EINVAL); 1509 1510 /* 1511 * Skip loopback addresses for non-loopback assoc., ignore 1512 * this on a clustered node. 1513 */ 1514 if (sctp->sctp_state >= SCTPS_ESTABLISHED && !sctp->sctp_loopback && 1515 (cl_sctp_check_addrs == NULL)) { 1516 skip_lback = B_TRUE; 1517 } 1518 1519 for (i = 0; i < SCTP_IPIF_HASH; i++) { 1520 if (sctp->sctp_saddrs[i].ipif_count == 0) 1521 continue; 1522 obj = list_head(&sctp->sctp_saddrs[i].sctp_ipif_list); 1523 for (l = 0; l < sctp->sctp_saddrs[i].ipif_count; l++) { 1524 sctp_ipif_t *ipif = obj->saddr_ipifp; 1525 in6_addr_t addr = ipif->sctp_ipif_saddr; 1526 1527 scanned++; 1528 if ((ipif->sctp_ipif_state == SCTP_IPIFS_CONDEMNED) || 1529 SCTP_DONT_SRC(obj) || 1530 (SCTP_IS_IPIF_LOOPBACK(ipif) && skip_lback)) { 1531 if (scanned >= sctp->sctp_nsaddrs) 1532 goto done; 1533 obj = list_next(&sctp->sctp_saddrs[i]. 1534 sctp_ipif_list, obj); 1535 continue; 1536 } 1537 switch (family) { 1538 case AF_INET: 1539 sin4 = (struct sockaddr_in *)myaddrs + added; 1540 sin4->sin_family = AF_INET; 1541 sin4->sin_port = sctp->sctp_lport; 1542 IN6_V4MAPPED_TO_INADDR(&addr, &sin4->sin_addr); 1543 break; 1544 1545 case AF_INET6: 1546 sin6 = (struct sockaddr_in6 *)myaddrs + added; 1547 sin6->sin6_family = AF_INET6; 1548 sin6->sin6_port = sctp->sctp_lport; 1549 sin6->sin6_addr = addr; 1550 break; 1551 } 1552 added++; 1553 if (added >= max || scanned >= sctp->sctp_nsaddrs) 1554 goto done; 1555 obj = list_next(&sctp->sctp_saddrs[i].sctp_ipif_list, 1556 obj); 1557 } 1558 } 1559 done: 1560 *addrcnt = added; 1561 return (0); 1562 } 1563 1564 /* 1565 * Given the supported address family, walk through the source address list 1566 * and return the total length of the available addresses. If 'p' is not 1567 * null, construct the parameter list for the addresses in 'p'. 1568 * 'modify' will only be set when we want the source address list to 1569 * be modified. The source address list will be modified only when 1570 * generating an INIT chunk. For generating an INIT-ACK 'modify' will 1571 * be false since the 'sctp' will be that of the listener. 1572 */ 1573 size_t 1574 sctp_saddr_info(sctp_t *sctp, int supp_af, uchar_t *p, boolean_t modify) 1575 { 1576 int i; 1577 int l; 1578 sctp_saddr_ipif_t *obj; 1579 size_t paramlen = 0; 1580 sctp_parm_hdr_t *hdr; 1581 int scanned = 0; 1582 int naddr; 1583 int nsaddr; 1584 boolean_t del_ll = B_FALSE; 1585 boolean_t del_lb = B_FALSE; 1586 1587 1588 /* 1589 * On a clustered node don't bother changing anything 1590 * on the loopback interface. 1591 */ 1592 if (modify && !sctp->sctp_loopback && (cl_sctp_check_addrs == NULL)) 1593 del_lb = B_TRUE; 1594 1595 if (modify && !sctp->sctp_linklocal) 1596 del_ll = B_TRUE; 1597 1598 nsaddr = sctp->sctp_nsaddrs; 1599 for (i = 0; i < SCTP_IPIF_HASH; i++) { 1600 if (sctp->sctp_saddrs[i].ipif_count == 0) 1601 continue; 1602 obj = list_head(&sctp->sctp_saddrs[i].sctp_ipif_list); 1603 naddr = sctp->sctp_saddrs[i].ipif_count; 1604 for (l = 0; l < naddr; l++) { 1605 in6_addr_t addr; 1606 sctp_ipif_t *ipif; 1607 boolean_t ipif_lb; 1608 boolean_t ipif_ll; 1609 boolean_t unsupp_af; 1610 1611 ipif = obj->saddr_ipifp; 1612 scanned++; 1613 1614 ipif_lb = SCTP_IS_IPIF_LOOPBACK(ipif); 1615 ipif_ll = SCTP_IS_IPIF_LINKLOCAL(ipif); 1616 unsupp_af = SCTP_UNSUPP_AF(ipif, supp_af); 1617 /* 1618 * We need to either delete or skip loopback/linklocal 1619 * or unsupported addresses, if required. 1620 */ 1621 if ((ipif_ll && del_ll) || (ipif_lb && del_lb) || 1622 (unsupp_af && modify)) { 1623 if (sctp->sctp_bound_to_all == 1) 1624 sctp->sctp_bound_to_all = 0; 1625 if (scanned < nsaddr) { 1626 obj = list_next(&sctp->sctp_saddrs[i]. 1627 sctp_ipif_list, obj); 1628 sctp_ipif_hash_remove(sctp, ipif); 1629 continue; 1630 } 1631 sctp_ipif_hash_remove(sctp, ipif); 1632 goto next_addr; 1633 } else if (ipif_ll || unsupp_af || 1634 (ipif_lb && (cl_sctp_check_addrs == NULL))) { 1635 goto next_addr; 1636 } 1637 1638 if (!SCTP_IPIF_USABLE(ipif->sctp_ipif_state)) 1639 goto next_addr; 1640 if (p != NULL) 1641 hdr = (sctp_parm_hdr_t *)(p + paramlen); 1642 addr = ipif->sctp_ipif_saddr; 1643 if (!ipif->sctp_ipif_isv6) { 1644 struct in_addr *v4; 1645 1646 if (p != NULL) { 1647 hdr->sph_type = htons(PARM_ADDR4); 1648 hdr->sph_len = htons(PARM_ADDR4_LEN); 1649 v4 = (struct in_addr *)(hdr + 1); 1650 IN6_V4MAPPED_TO_INADDR(&addr, v4); 1651 } 1652 paramlen += PARM_ADDR4_LEN; 1653 } else { 1654 if (p != NULL) { 1655 hdr->sph_type = htons(PARM_ADDR6); 1656 hdr->sph_len = htons(PARM_ADDR6_LEN); 1657 bcopy(&addr, hdr + 1, sizeof (addr)); 1658 } 1659 paramlen += PARM_ADDR6_LEN; 1660 } 1661 next_addr: 1662 if (scanned >= nsaddr) 1663 return (paramlen); 1664 obj = list_next(&sctp->sctp_saddrs[i].sctp_ipif_list, 1665 obj); 1666 } 1667 } 1668 return (paramlen); 1669 } 1670 1671 /* 1672 * This is used on a clustered node to obtain a list of addresses, the list 1673 * consists of sockaddr_in structs for v4 and sockaddr_in6 for v6. The list 1674 * is then passed onto the clustering module which sends back the correct 1675 * list based on the port info. Regardless of the input, i.e INADDR_ANY 1676 * or specific address(es), we create the list since it could be modified by 1677 * the clustering module. When given a list of addresses, we simply 1678 * create the list of sockaddr_in or sockaddr_in6 structs using those 1679 * addresses. If there is an INADDR_ANY in the input list, or if the 1680 * input is INADDR_ANY, we create a list of sockaddr_in or sockaddr_in6 1681 * structs consisting all the addresses in the global interface list 1682 * except those that are hosted on the loopback interface. We create 1683 * a list of sockaddr_in[6] structs just so that it can be directly input 1684 * to sctp_valid_addr_list() once the clustering module has processed it. 1685 */ 1686 int 1687 sctp_get_addrlist(sctp_t *sctp, const void *addrs, uint32_t *addrcnt, 1688 uchar_t **addrlist, int *uspec, size_t *size) 1689 { 1690 int cnt; 1691 int icnt; 1692 sctp_ipif_t *sctp_ipif; 1693 struct sockaddr_in *s4; 1694 struct sockaddr_in6 *s6; 1695 uchar_t *p; 1696 int err = 0; 1697 sctp_stack_t *sctps = sctp->sctp_sctps; 1698 1699 *addrlist = NULL; 1700 *size = 0; 1701 1702 /* 1703 * Create a list of sockaddr_in[6] structs using the input list. 1704 */ 1705 if (sctp->sctp_family == AF_INET) { 1706 *size = sizeof (struct sockaddr_in) * *addrcnt; 1707 *addrlist = kmem_zalloc(*size, KM_SLEEP); 1708 p = *addrlist; 1709 for (cnt = 0; cnt < *addrcnt; cnt++) { 1710 s4 = (struct sockaddr_in *)addrs + cnt; 1711 /* 1712 * We need to create a list of all the available 1713 * addresses if there is an INADDR_ANY. However, 1714 * if we are beyond LISTEN, then this is invalid 1715 * (see sctp_valid_addr_list(). So, we just fail 1716 * it here rather than wait till it fails in 1717 * sctp_valid_addr_list(). 1718 */ 1719 if (s4->sin_addr.s_addr == INADDR_ANY) { 1720 kmem_free(*addrlist, *size); 1721 *addrlist = NULL; 1722 *size = 0; 1723 if (sctp->sctp_state > SCTPS_LISTEN) { 1724 *addrcnt = 0; 1725 return (EINVAL); 1726 } 1727 if (uspec != NULL) 1728 *uspec = 1; 1729 goto get_all_addrs; 1730 } else { 1731 bcopy(s4, p, sizeof (*s4)); 1732 p += sizeof (*s4); 1733 } 1734 } 1735 } else { 1736 *size = sizeof (struct sockaddr_in6) * *addrcnt; 1737 *addrlist = kmem_zalloc(*size, KM_SLEEP); 1738 p = *addrlist; 1739 for (cnt = 0; cnt < *addrcnt; cnt++) { 1740 s6 = (struct sockaddr_in6 *)addrs + cnt; 1741 /* 1742 * Comments for INADDR_ANY, above, apply here too. 1743 */ 1744 if (IN6_IS_ADDR_UNSPECIFIED(&s6->sin6_addr)) { 1745 kmem_free(*addrlist, *size); 1746 *size = 0; 1747 *addrlist = NULL; 1748 if (sctp->sctp_state > SCTPS_LISTEN) { 1749 *addrcnt = 0; 1750 return (EINVAL); 1751 } 1752 if (uspec != NULL) 1753 *uspec = 1; 1754 goto get_all_addrs; 1755 } else { 1756 bcopy(addrs, p, sizeof (*s6)); 1757 p += sizeof (*s6); 1758 } 1759 } 1760 } 1761 return (err); 1762 get_all_addrs: 1763 1764 /* 1765 * Allocate max possible size. We allocate the max. size here because 1766 * the clustering module could end up adding addresses to the list. 1767 * We allocate upfront so that the clustering module need to bother 1768 * re-sizing the list. 1769 */ 1770 if (sctp->sctp_family == AF_INET) { 1771 *size = sizeof (struct sockaddr_in) * 1772 sctps->sctps_g_ipifs_count; 1773 } else { 1774 *size = sizeof (struct sockaddr_in6) * 1775 sctps->sctps_g_ipifs_count; 1776 } 1777 *addrlist = kmem_zalloc(*size, KM_SLEEP); 1778 *addrcnt = 0; 1779 p = *addrlist; 1780 rw_enter(&sctps->sctps_g_ipifs_lock, RW_READER); 1781 1782 /* 1783 * Walk through the global interface list and add all addresses, 1784 * except those that are hosted on loopback interfaces. 1785 */ 1786 for (cnt = 0; cnt < SCTP_IPIF_HASH; cnt++) { 1787 if (sctps->sctps_g_ipifs[cnt].ipif_count == 0) 1788 continue; 1789 sctp_ipif = list_head( 1790 &sctps->sctps_g_ipifs[cnt].sctp_ipif_list); 1791 for (icnt = 0; 1792 icnt < sctps->sctps_g_ipifs[cnt].ipif_count; 1793 icnt++) { 1794 in6_addr_t addr; 1795 1796 rw_enter(&sctp_ipif->sctp_ipif_lock, RW_READER); 1797 addr = sctp_ipif->sctp_ipif_saddr; 1798 if (SCTP_IPIF_DISCARD(sctp_ipif->sctp_ipif_flags) || 1799 !SCTP_IPIF_USABLE(sctp_ipif->sctp_ipif_state) || 1800 SCTP_IS_IPIF_LOOPBACK(sctp_ipif) || 1801 SCTP_IS_IPIF_LINKLOCAL(sctp_ipif) || 1802 !SCTP_IPIF_ZONE_MATCH(sctp, sctp_ipif) || 1803 (sctp->sctp_ipversion == IPV4_VERSION && 1804 sctp_ipif->sctp_ipif_isv6) || 1805 (sctp->sctp_connp->conn_ipv6_v6only && 1806 !sctp_ipif->sctp_ipif_isv6)) { 1807 rw_exit(&sctp_ipif->sctp_ipif_lock); 1808 sctp_ipif = list_next( 1809 &sctps->sctps_g_ipifs[cnt].sctp_ipif_list, 1810 sctp_ipif); 1811 continue; 1812 } 1813 rw_exit(&sctp_ipif->sctp_ipif_lock); 1814 if (sctp->sctp_family == AF_INET) { 1815 s4 = (struct sockaddr_in *)p; 1816 IN6_V4MAPPED_TO_INADDR(&addr, &s4->sin_addr); 1817 s4->sin_family = AF_INET; 1818 p += sizeof (*s4); 1819 } else { 1820 s6 = (struct sockaddr_in6 *)p; 1821 s6->sin6_addr = addr; 1822 s6->sin6_family = AF_INET6; 1823 s6->sin6_scope_id = 1824 sctp_ipif->sctp_ipif_ill->sctp_ill_index; 1825 p += sizeof (*s6); 1826 } 1827 (*addrcnt)++; 1828 sctp_ipif = list_next( 1829 &sctps->sctps_g_ipifs[cnt].sctp_ipif_list, 1830 sctp_ipif); 1831 } 1832 } 1833 rw_exit(&sctps->sctps_g_ipifs_lock); 1834 return (err); 1835 } 1836 1837 /* 1838 * Get a list of addresses from the source address list. The caller is 1839 * responsible for allocating sufficient buffer for this. 1840 */ 1841 void 1842 sctp_get_saddr_list(sctp_t *sctp, uchar_t *p, size_t psize) 1843 { 1844 int cnt; 1845 int icnt; 1846 sctp_saddr_ipif_t *obj; 1847 int naddr; 1848 int scanned = 0; 1849 1850 for (cnt = 0; cnt < SCTP_IPIF_HASH; cnt++) { 1851 if (sctp->sctp_saddrs[cnt].ipif_count == 0) 1852 continue; 1853 obj = list_head(&sctp->sctp_saddrs[cnt].sctp_ipif_list); 1854 naddr = sctp->sctp_saddrs[cnt].ipif_count; 1855 for (icnt = 0; icnt < naddr; icnt++) { 1856 sctp_ipif_t *ipif; 1857 1858 if (psize < sizeof (ipif->sctp_ipif_saddr)) 1859 return; 1860 1861 scanned++; 1862 ipif = obj->saddr_ipifp; 1863 bcopy(&ipif->sctp_ipif_saddr, p, 1864 sizeof (ipif->sctp_ipif_saddr)); 1865 p += sizeof (ipif->sctp_ipif_saddr); 1866 psize -= sizeof (ipif->sctp_ipif_saddr); 1867 if (scanned >= sctp->sctp_nsaddrs) 1868 return; 1869 obj = list_next( 1870 &sctp->sctp_saddrs[icnt].sctp_ipif_list, 1871 obj); 1872 } 1873 } 1874 } 1875 1876 /* 1877 * Get a list of addresses from the remote address list. The caller is 1878 * responsible for allocating sufficient buffer for this. 1879 */ 1880 void 1881 sctp_get_faddr_list(sctp_t *sctp, uchar_t *p, size_t psize) 1882 { 1883 sctp_faddr_t *fp; 1884 1885 for (fp = sctp->sctp_faddrs; fp != NULL; fp = fp->next) { 1886 if (psize < sizeof (fp->faddr)) 1887 return; 1888 bcopy(&fp->faddr, p, sizeof (fp->faddr)); 1889 p += sizeof (fp->faddr); 1890 psize -= sizeof (fp->faddr); 1891 } 1892 } 1893 1894 static void 1895 sctp_free_ills(sctp_stack_t *sctps) 1896 { 1897 int i; 1898 int l; 1899 sctp_ill_t *sctp_ill; 1900 1901 if (sctps->sctps_ills_count == 0) 1902 return; 1903 1904 for (i = 0; i < SCTP_ILL_HASH; i++) { 1905 sctp_ill = list_tail(&sctps->sctps_g_ills[i].sctp_ill_list); 1906 for (l = 0; l < sctps->sctps_g_ills[i].ill_count; l++) { 1907 ASSERT(sctp_ill->sctp_ill_ipifcnt == 0); 1908 list_remove(&sctps->sctps_g_ills[i].sctp_ill_list, 1909 sctp_ill); 1910 sctps->sctps_ills_count--; 1911 kmem_free(sctp_ill->sctp_ill_name, 1912 sctp_ill->sctp_ill_name_length); 1913 kmem_free(sctp_ill, sizeof (sctp_ill_t)); 1914 sctp_ill = 1915 list_tail(&sctps->sctps_g_ills[i].sctp_ill_list); 1916 } 1917 sctps->sctps_g_ills[i].ill_count = 0; 1918 } 1919 ASSERT(sctps->sctps_ills_count == 0); 1920 } 1921 1922 static void 1923 sctp_free_ipifs(sctp_stack_t *sctps) 1924 { 1925 int i; 1926 int l; 1927 sctp_ipif_t *sctp_ipif; 1928 sctp_ill_t *sctp_ill; 1929 1930 if (sctps->sctps_g_ipifs_count == 0) 1931 return; 1932 1933 for (i = 0; i < SCTP_IPIF_HASH; i++) { 1934 sctp_ipif = list_tail(&sctps->sctps_g_ipifs[i].sctp_ipif_list); 1935 for (l = 0; l < sctps->sctps_g_ipifs[i].ipif_count; l++) { 1936 sctp_ill = sctp_ipif->sctp_ipif_ill; 1937 1938 list_remove(&sctps->sctps_g_ipifs[i].sctp_ipif_list, 1939 sctp_ipif); 1940 sctps->sctps_g_ipifs_count--; 1941 (void) atomic_add_32_nv(&sctp_ill->sctp_ill_ipifcnt, 1942 -1); 1943 kmem_free(sctp_ipif, sizeof (sctp_ipif_t)); 1944 sctp_ipif = 1945 list_tail(&sctps->sctps_g_ipifs[i].sctp_ipif_list); 1946 } 1947 sctps->sctps_g_ipifs[i].ipif_count = 0; 1948 } 1949 ASSERT(sctps->sctps_g_ipifs_count == 0); 1950 } 1951 1952 1953 /* Initialize the SCTP ILL list and lock */ 1954 void 1955 sctp_saddr_init(sctp_stack_t *sctps) 1956 { 1957 int i; 1958 1959 sctps->sctps_g_ills = kmem_zalloc(sizeof (sctp_ill_hash_t) * 1960 SCTP_ILL_HASH, KM_SLEEP); 1961 sctps->sctps_g_ipifs = kmem_zalloc(sizeof (sctp_ipif_hash_t) * 1962 SCTP_IPIF_HASH, KM_SLEEP); 1963 1964 rw_init(&sctps->sctps_g_ills_lock, NULL, RW_DEFAULT, NULL); 1965 rw_init(&sctps->sctps_g_ipifs_lock, NULL, RW_DEFAULT, NULL); 1966 1967 for (i = 0; i < SCTP_ILL_HASH; i++) { 1968 sctps->sctps_g_ills[i].ill_count = 0; 1969 list_create(&sctps->sctps_g_ills[i].sctp_ill_list, 1970 sizeof (sctp_ill_t), 1971 offsetof(sctp_ill_t, sctp_ills)); 1972 } 1973 for (i = 0; i < SCTP_IPIF_HASH; i++) { 1974 sctps->sctps_g_ipifs[i].ipif_count = 0; 1975 list_create(&sctps->sctps_g_ipifs[i].sctp_ipif_list, 1976 sizeof (sctp_ipif_t), offsetof(sctp_ipif_t, sctp_ipifs)); 1977 } 1978 } 1979 1980 void 1981 sctp_saddr_fini(sctp_stack_t *sctps) 1982 { 1983 int i; 1984 1985 sctp_free_ipifs(sctps); 1986 sctp_free_ills(sctps); 1987 1988 for (i = 0; i < SCTP_ILL_HASH; i++) 1989 list_destroy(&sctps->sctps_g_ills[i].sctp_ill_list); 1990 for (i = 0; i < SCTP_IPIF_HASH; i++) 1991 list_destroy(&sctps->sctps_g_ipifs[i].sctp_ipif_list); 1992 1993 ASSERT(sctps->sctps_ills_count == 0 && sctps->sctps_g_ipifs_count == 0); 1994 kmem_free(sctps->sctps_g_ills, sizeof (sctp_ill_hash_t) * 1995 SCTP_ILL_HASH); 1996 sctps->sctps_g_ills = NULL; 1997 kmem_free(sctps->sctps_g_ipifs, sizeof (sctp_ipif_hash_t) * 1998 SCTP_IPIF_HASH); 1999 sctps->sctps_g_ipifs = NULL; 2000 rw_destroy(&sctps->sctps_g_ills_lock); 2001 rw_destroy(&sctps->sctps_g_ipifs_lock); 2002 } 2003