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