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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <sys/types.h> 30 #include <sys/systm.h> 31 #include <sys/stream.h> 32 #include <sys/ddi.h> 33 #include <sys/sunddi.h> 34 #include <sys/kmem.h> 35 #include <sys/socket.h> 36 #include <sys/sysmacros.h> 37 #include <sys/list.h> 38 39 #include <netinet/in.h> 40 #include <netinet/ip6.h> 41 #include <netinet/sctp.h> 42 43 #include <inet/common.h> 44 #include <inet/ip.h> 45 #include <inet/ip6.h> 46 #include <inet/ip_if.h> 47 #include <inet/ipclassifier.h> 48 #include <inet/sctp_ip.h> 49 #include "sctp_impl.h" 50 #include "sctp_addr.h" 51 52 static void sctp_ipif_inactive(sctp_ipif_t *); 53 static sctp_ipif_t *sctp_lookup_ipif_addr(in6_addr_t *, boolean_t, 54 zoneid_t zoneid); 55 static int sctp_get_all_ipifs(sctp_t *, int); 56 int sctp_valid_addr_list(sctp_t *, const void *, uint32_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 static void sctp_ipif_hash_remove(sctp_t *, sctp_ipif_t *); 60 static int sctp_compare_ipif_list(sctp_ipif_hash_t *, 61 sctp_ipif_hash_t *); 62 int sctp_compare_saddrs(sctp_t *, sctp_t *); 63 static int sctp_copy_ipifs(sctp_ipif_hash_t *, sctp_t *, int); 64 int sctp_dup_saddrs(sctp_t *, sctp_t *, int); 65 void sctp_free_saddrs(sctp_t *); 66 void sctp_update_ill(ill_t *, int); 67 void sctp_update_ipif(ipif_t *, int); 68 void sctp_move_ipif(ipif_t *, ill_t *, ill_t *); 69 void sctp_del_saddr(sctp_t *, sctp_saddr_ipif_t *); 70 void sctp_del_saddr_list(sctp_t *, const void *, int, 71 boolean_t); 72 sctp_saddr_ipif_t *sctp_saddr_lookup(sctp_t *, in6_addr_t *); 73 in6_addr_t sctp_get_valid_addr(sctp_t *, boolean_t); 74 int sctp_getmyaddrs(void *, void *, int *); 75 void sctp_saddr_init(); 76 void sctp_saddr_fini(); 77 #define SCTP_IPIF_USABLE(sctp_ipif_state) \ 78 ((sctp_ipif_state) == SCTP_IPIFS_UP || \ 79 ((sctp_ipif_state) == SCTP_IPIFS_DOWN)) 80 81 #define SCTP_ILL_HASH_FN(index) ((index) % SCTP_ILL_HASH) 82 #define SCTP_IPIF_HASH_FN(seqid) ((seqid) % SCTP_IPIF_HASH) 83 #define SCTP_ILL_TO_PHYINDEX(ill) ((ill)->ill_phyint->phyint_ifindex) 84 85 /* Global list of SCTP ILLs */ 86 sctp_ill_hash_t sctp_g_ills[SCTP_ILL_HASH]; 87 uint32_t sctp_ills_count = 0; 88 89 /* Global list of SCTP IPIFs */ 90 sctp_ipif_hash_t sctp_g_ipifs[SCTP_IPIF_HASH]; 91 uint32_t sctp_g_ipifs_count; 92 93 /* 94 * 95 * 96 * SCTP Interface list manipulation functions, locking used. 97 * 98 * 99 */ 100 101 /* 102 * Delete an SCTP IPIF from the list if the refcount goes to 0 and it is 103 * marked as condemned. Also, check if the ILL needs to go away. 104 * Called with no locks held. 105 */ 106 static void 107 sctp_ipif_inactive(sctp_ipif_t *sctp_ipif) 108 { 109 sctp_ill_t *sctp_ill; 110 uint_t ipif_index; 111 uint_t ill_index; 112 113 rw_enter(&sctp_g_ills_lock, RW_READER); 114 rw_enter(&sctp_g_ipifs_lock, RW_WRITER); 115 116 ipif_index = SCTP_IPIF_HASH_FN(sctp_ipif->sctp_ipif_id); 117 sctp_ill = sctp_ipif->sctp_ipif_ill; 118 ASSERT(sctp_ill != NULL); 119 ill_index = SCTP_ILL_HASH_FN(sctp_ill->sctp_ill_index); 120 if (sctp_ipif->sctp_ipif_state != SCTP_IPIFS_CONDEMNED || 121 sctp_ipif->sctp_ipif_refcnt != 0) { 122 rw_exit(&sctp_g_ipifs_lock); 123 rw_exit(&sctp_g_ills_lock); 124 return; 125 } 126 list_remove(&sctp_g_ipifs[ipif_index].sctp_ipif_list, sctp_ipif); 127 sctp_g_ipifs[ipif_index].ipif_count--; 128 sctp_g_ipifs_count--; 129 rw_destroy(&sctp_ipif->sctp_ipif_lock); 130 kmem_free(sctp_ipif, sizeof (sctp_ipif_t)); 131 132 (void) atomic_add_32_nv(&sctp_ill->sctp_ill_ipifcnt, -1); 133 if (rw_tryupgrade(&sctp_g_ills_lock) != 0) { 134 rw_downgrade(&sctp_g_ipifs_lock); 135 if (sctp_ill->sctp_ill_ipifcnt == 0 && 136 sctp_ill->sctp_ill_state == SCTP_ILLS_CONDEMNED) { 137 list_remove(&sctp_g_ills[ill_index].sctp_ill_list, 138 (void *)sctp_ill); 139 sctp_g_ills[ill_index].ill_count--; 140 sctp_ills_count--; 141 kmem_free(sctp_ill->sctp_ill_name, 142 sctp_ill->sctp_ill_name_length); 143 kmem_free(sctp_ill, sizeof (sctp_ill_t)); 144 } 145 } 146 rw_exit(&sctp_g_ipifs_lock); 147 rw_exit(&sctp_g_ills_lock); 148 } 149 150 /* 151 * Lookup an SCTP IPIF given an IP address. Increments sctp_ipif refcnt. 152 * Called with no locks held. 153 */ 154 static sctp_ipif_t * 155 sctp_lookup_ipif_addr(in6_addr_t *addr, boolean_t refhold, zoneid_t zoneid) 156 { 157 int i; 158 int j; 159 sctp_ipif_t *sctp_ipif; 160 161 rw_enter(&sctp_g_ipifs_lock, RW_READER); 162 for (i = 0; i < SCTP_IPIF_HASH; i++) { 163 if (sctp_g_ipifs[i].ipif_count == 0) 164 continue; 165 sctp_ipif = list_head(&sctp_g_ipifs[i].sctp_ipif_list); 166 for (j = 0; j < sctp_g_ipifs[i].ipif_count; j++) { 167 rw_enter(&sctp_ipif->sctp_ipif_lock, RW_READER); 168 if (zoneid == sctp_ipif->sctp_ipif_zoneid && 169 SCTP_IPIF_USABLE(sctp_ipif->sctp_ipif_state) && 170 IN6_ARE_ADDR_EQUAL(&sctp_ipif->sctp_ipif_saddr, 171 addr)) { 172 rw_exit(&sctp_ipif->sctp_ipif_lock); 173 if (refhold) 174 SCTP_IPIF_REFHOLD(sctp_ipif); 175 rw_exit(&sctp_g_ipifs_lock); 176 return (sctp_ipif); 177 } 178 rw_exit(&sctp_ipif->sctp_ipif_lock); 179 sctp_ipif = list_next(&sctp_g_ipifs[i].sctp_ipif_list, 180 sctp_ipif); 181 } 182 } 183 rw_exit(&sctp_g_ipifs_lock); 184 return (NULL); 185 } 186 187 /* 188 * Populate the list with all the SCTP ipifs for a given ipversion. 189 * Increments sctp_ipif refcnt. 190 * Called with no locks held. 191 */ 192 static int 193 sctp_get_all_ipifs(sctp_t *sctp, int sleep) 194 { 195 sctp_ipif_t *sctp_ipif; 196 int i; 197 int j; 198 int error = 0; 199 200 rw_enter(&sctp_g_ipifs_lock, RW_READER); 201 for (i = 0; i < SCTP_IPIF_HASH; i++) { 202 if (sctp_g_ipifs[i].ipif_count == 0) 203 continue; 204 sctp_ipif = list_head(&sctp_g_ipifs[i].sctp_ipif_list); 205 for (j = 0; j < sctp_g_ipifs[i].ipif_count; j++) { 206 rw_enter(&sctp_ipif->sctp_ipif_lock, RW_READER); 207 if (sctp_ipif->sctp_ipif_zoneid != sctp->sctp_zoneid || 208 !SCTP_IPIF_USABLE(sctp_ipif->sctp_ipif_state) || 209 (sctp->sctp_ipversion == IPV4_VERSION && 210 !IN6_IS_ADDR_V4MAPPED( 211 &sctp_ipif->sctp_ipif_saddr)) || 212 (sctp->sctp_connp->conn_ipv6_v6only && 213 IN6_IS_ADDR_V4MAPPED( 214 &sctp_ipif->sctp_ipif_saddr))) { 215 rw_exit(&sctp_ipif->sctp_ipif_lock); 216 sctp_ipif = list_next( 217 &sctp_g_ipifs[i].sctp_ipif_list, sctp_ipif); 218 continue; 219 } 220 rw_exit(&sctp_ipif->sctp_ipif_lock); 221 SCTP_IPIF_REFHOLD(sctp_ipif); 222 error = sctp_ipif_hash_insert(sctp, sctp_ipif, sleep); 223 if (error != 0) 224 goto free_stuff; 225 sctp_ipif = list_next(&sctp_g_ipifs[i].sctp_ipif_list, 226 sctp_ipif); 227 } 228 } 229 rw_exit(&sctp_g_ipifs_lock); 230 return (0); 231 free_stuff: 232 rw_exit(&sctp_g_ipifs_lock); 233 sctp_free_saddrs(sctp); 234 return (ENOMEM); 235 } 236 237 /* 238 * Given a list of address, fills in the list of SCTP ipifs if all the addresses 239 * are present in the SCTP interface list, return number of addresses filled 240 * or error. 241 * Called with no locks held. 242 */ 243 int 244 sctp_valid_addr_list(sctp_t *sctp, const void *addrs, uint32_t addrcnt) 245 { 246 struct sockaddr_in *sin4; 247 struct sockaddr_in6 *sin6; 248 struct in_addr *addr4; 249 in6_addr_t addr; 250 int cnt; 251 int err = 0; 252 int saddr_cnt = 0; 253 sctp_ipif_t *ipif; 254 boolean_t bind_to_all = B_FALSE; 255 boolean_t check_addrs = B_FALSE; 256 boolean_t check_lport = B_FALSE; 257 258 /* 259 * Need to check for port and address depending on the state. 260 * After a socket is bound, we need to make sure that subsequent 261 * bindx() has correct port. After an association is established, 262 * we need to check for changing the bound address to invalid 263 * addresses. 264 */ 265 if (sctp->sctp_state >= SCTPS_BOUND) { 266 check_lport = B_TRUE; 267 if (sctp->sctp_state > SCTPS_LISTEN) 268 check_addrs = B_TRUE; 269 } 270 if (sctp->sctp_conn_tfp != NULL) 271 mutex_enter(&sctp->sctp_conn_tfp->tf_lock); 272 if (sctp->sctp_listen_tfp != NULL) 273 mutex_enter(&sctp->sctp_listen_tfp->tf_lock); 274 for (cnt = 0; cnt < addrcnt; cnt++) { 275 boolean_t lookup_saddr = B_TRUE; 276 277 switch (sctp->sctp_family) { 278 case AF_INET: 279 sin4 = (struct sockaddr_in *)addrs + cnt; 280 if (sin4->sin_family != AF_INET || (check_lport && 281 sin4->sin_port != sctp->sctp_lport)) { 282 err = EINVAL; 283 goto free_ret; 284 } 285 addr4 = &sin4->sin_addr; 286 if (check_addrs && 287 (addr4->s_addr == INADDR_ANY || 288 addr4->s_addr == INADDR_BROADCAST || 289 IN_MULTICAST(addr4->s_addr))) { 290 err = EINVAL; 291 goto free_ret; 292 } 293 IN6_INADDR_TO_V4MAPPED(addr4, &addr); 294 if (!check_addrs && addr4->s_addr == INADDR_ANY) { 295 lookup_saddr = B_FALSE; 296 bind_to_all = B_TRUE; 297 } 298 299 break; 300 case AF_INET6: 301 sin6 = (struct sockaddr_in6 *)addrs + cnt; 302 if (sin6->sin6_family != AF_INET6 || (check_lport && 303 sin6->sin6_port != sctp->sctp_lport)) { 304 err = EINVAL; 305 goto free_ret; 306 } 307 addr = sin6->sin6_addr; 308 if (sctp->sctp_connp->conn_ipv6_v6only && 309 IN6_IS_ADDR_V4MAPPED(&addr)) { 310 err = EAFNOSUPPORT; 311 goto free_ret; 312 } 313 if (check_addrs && 314 (IN6_IS_ADDR_LINKLOCAL(&addr) || 315 IN6_IS_ADDR_MULTICAST(&addr) || 316 IN6_IS_ADDR_UNSPECIFIED(&addr))) { 317 err = EINVAL; 318 goto free_ret; 319 } 320 if (!check_addrs && IN6_IS_ADDR_UNSPECIFIED(&addr)) { 321 lookup_saddr = B_FALSE; 322 bind_to_all = B_TRUE; 323 } 324 325 break; 326 default: 327 err = EAFNOSUPPORT; 328 goto free_ret; 329 } 330 if (lookup_saddr) { 331 ipif = sctp_lookup_ipif_addr(&addr, B_TRUE, 332 sctp->sctp_zoneid); 333 if (ipif == NULL) { 334 /* Address not in the list */ 335 err = EINVAL; 336 goto free_ret; 337 } else if (check_addrs && 338 (ipif->sctp_ipif_ill->sctp_ill_flags & 339 PHYI_LOOPBACK)) { 340 SCTP_IPIF_REFRELE(ipif); 341 err = EINVAL; 342 goto free_ret; 343 } 344 } 345 if (!bind_to_all) { 346 err = sctp_ipif_hash_insert(sctp, ipif, KM_SLEEP); 347 if (err != 0) { 348 SCTP_IPIF_REFRELE(ipif); 349 if (check_addrs && err == EALREADY) 350 err = EADDRINUSE; 351 goto free_ret; 352 } 353 saddr_cnt++; 354 } 355 } 356 if (bind_to_all) { 357 /* 358 * Free whatever we might have added before encountering 359 * inaddr_any. 360 */ 361 if (sctp->sctp_nsaddrs > 0) { 362 sctp_free_saddrs(sctp); 363 ASSERT(sctp->sctp_nsaddrs == 0); 364 } 365 err = sctp_get_all_ipifs(sctp, KM_SLEEP); 366 if (err != 0) 367 return (err); 368 sctp->sctp_bound_to_all = 1; 369 } 370 if (sctp->sctp_listen_tfp != NULL) 371 mutex_exit(&sctp->sctp_listen_tfp->tf_lock); 372 if (sctp->sctp_conn_tfp != NULL) 373 mutex_exit(&sctp->sctp_conn_tfp->tf_lock); 374 return (0); 375 free_ret: 376 if (saddr_cnt != 0) 377 sctp_del_saddr_list(sctp, addrs, saddr_cnt, B_TRUE); 378 if (sctp->sctp_listen_tfp != NULL) 379 mutex_exit(&sctp->sctp_listen_tfp->tf_lock); 380 if (sctp->sctp_conn_tfp != NULL) 381 mutex_exit(&sctp->sctp_conn_tfp->tf_lock); 382 return (err); 383 } 384 385 sctp_saddr_ipif_t * 386 sctp_ipif_lookup(sctp_t *sctp, uint_t ipif_index) 387 { 388 int cnt; 389 int seqid = SCTP_IPIF_HASH_FN(ipif_index); 390 sctp_saddr_ipif_t *ipif_obj; 391 392 if (sctp->sctp_saddrs[seqid].ipif_count == 0) 393 return (NULL); 394 395 ipif_obj = list_head(&sctp->sctp_saddrs[seqid].sctp_ipif_list); 396 for (cnt = 0; cnt < sctp->sctp_saddrs[seqid].ipif_count; cnt++) { 397 if (ipif_obj->saddr_ipifp->sctp_ipif_id == ipif_index) 398 return (ipif_obj); 399 ipif_obj = list_next(&sctp->sctp_saddrs[seqid].sctp_ipif_list, 400 ipif_obj); 401 } 402 return (NULL); 403 } 404 405 static int 406 sctp_ipif_hash_insert(sctp_t *sctp, sctp_ipif_t *ipif, int sleep) 407 { 408 int cnt; 409 sctp_saddr_ipif_t *ipif_obj; 410 int seqid = SCTP_IPIF_HASH_FN(ipif->sctp_ipif_id); 411 412 ipif_obj = list_head(&sctp->sctp_saddrs[seqid].sctp_ipif_list); 413 for (cnt = 0; cnt < sctp->sctp_saddrs[seqid].ipif_count; cnt++) { 414 if (ipif_obj->saddr_ipifp->sctp_ipif_id == ipif->sctp_ipif_id) 415 return (EALREADY); 416 ipif_obj = list_next(&sctp->sctp_saddrs[seqid].sctp_ipif_list, 417 ipif_obj); 418 } 419 ipif_obj = kmem_zalloc(sizeof (sctp_saddr_ipif_t), sleep); 420 if (ipif_obj == NULL) { 421 /* Need to do something */ 422 return (ENOMEM); 423 } 424 ipif_obj->saddr_ipifp = ipif; 425 /* 426 * If an address is added after association setup, we need to wait 427 * for the peer to send us an ASCONF ACK before we can start using it. 428 * saddr_ipif_dontsrc will be reset (to 0) when we get the ASCONF 429 * ACK for this address. 430 */ 431 if (sctp->sctp_state > SCTP_LISTEN) 432 ipif_obj->saddr_ipif_dontsrc = 1; 433 list_insert_tail(&sctp->sctp_saddrs[seqid].sctp_ipif_list, ipif_obj); 434 sctp->sctp_saddrs[seqid].ipif_count++; 435 sctp->sctp_nsaddrs++; 436 return (0); 437 } 438 439 static void 440 sctp_ipif_hash_remove(sctp_t *sctp, sctp_ipif_t *ipif) 441 { 442 int cnt; 443 sctp_saddr_ipif_t *ipif_obj; 444 int seqid = SCTP_IPIF_HASH_FN(ipif->sctp_ipif_id); 445 446 ipif_obj = list_head(&sctp->sctp_saddrs[seqid].sctp_ipif_list); 447 for (cnt = 0; cnt < sctp->sctp_saddrs[seqid].ipif_count; cnt++) { 448 if (ipif_obj->saddr_ipifp->sctp_ipif_id == ipif->sctp_ipif_id) { 449 list_remove(&sctp->sctp_saddrs[seqid].sctp_ipif_list, 450 ipif_obj); 451 sctp->sctp_nsaddrs--; 452 sctp->sctp_saddrs[seqid].ipif_count--; 453 SCTP_IPIF_REFRELE(ipif_obj->saddr_ipifp); 454 kmem_free(ipif_obj, sizeof (sctp_saddr_ipif_t)); 455 break; 456 } 457 ipif_obj = list_next(&sctp->sctp_saddrs[seqid].sctp_ipif_list, 458 ipif_obj); 459 } 460 } 461 462 static int 463 sctp_compare_ipif_list(sctp_ipif_hash_t *list1, sctp_ipif_hash_t *list2) 464 { 465 int i; 466 int j; 467 sctp_saddr_ipif_t *obj1; 468 sctp_saddr_ipif_t *obj2; 469 int overlap = 0; 470 471 obj1 = list_head(&list1->sctp_ipif_list); 472 for (i = 0; i < list1->ipif_count; i++) { 473 obj2 = list_head(&list2->sctp_ipif_list); 474 for (j = 0; j < list2->ipif_count; j++) { 475 if (obj1->saddr_ipifp->sctp_ipif_id == 476 obj2->saddr_ipifp->sctp_ipif_id) { 477 overlap++; 478 break; 479 } 480 obj2 = list_next(&list2->sctp_ipif_list, 481 obj2); 482 } 483 obj1 = list_next(&list1->sctp_ipif_list, obj1); 484 } 485 return (overlap); 486 } 487 488 int 489 sctp_compare_saddrs(sctp_t *sctp1, sctp_t *sctp2) 490 { 491 int i; 492 int overlap = 0; 493 494 for (i = 0; i < SCTP_IPIF_HASH; i++) { 495 overlap += sctp_compare_ipif_list(&sctp1->sctp_saddrs[i], 496 &sctp2->sctp_saddrs[i]); 497 } 498 499 if (sctp1->sctp_nsaddrs == sctp2->sctp_nsaddrs && 500 overlap == sctp1->sctp_nsaddrs) { 501 return (SCTP_ADDR_EQUAL); 502 } 503 504 if (overlap == sctp1->sctp_nsaddrs) 505 return (SCTP_ADDR_SUBSET); 506 507 if (overlap > 0) 508 return (SCTP_ADDR_OVERLAP); 509 510 return (SCTP_ADDR_DISJOINT); 511 } 512 513 static int 514 sctp_copy_ipifs(sctp_ipif_hash_t *list1, sctp_t *sctp2, int sleep) 515 { 516 int i; 517 sctp_saddr_ipif_t *obj; 518 int error = 0; 519 520 obj = list_head(&list1->sctp_ipif_list); 521 for (i = 0; i < list1->ipif_count; i++) { 522 SCTP_IPIF_REFHOLD(obj->saddr_ipifp); 523 error = sctp_ipif_hash_insert(sctp2, obj->saddr_ipifp, sleep); 524 if (error != 0) 525 return (error); 526 obj = list_next(&list1->sctp_ipif_list, obj); 527 } 528 return (error); 529 } 530 531 int 532 sctp_dup_saddrs(sctp_t *sctp1, sctp_t *sctp2, int sleep) 533 { 534 int error = 0; 535 int i; 536 537 if (sctp1 == NULL || sctp1->sctp_bound_to_all) 538 return (sctp_get_all_ipifs(sctp2, sleep)); 539 540 for (i = 0; i < SCTP_IPIF_HASH; i++) { 541 if (sctp1->sctp_saddrs[i].ipif_count == 0) 542 continue; 543 error = sctp_copy_ipifs(&sctp1->sctp_saddrs[i], sctp2, sleep); 544 if (error != 0) { 545 sctp_free_saddrs(sctp2); 546 return (error); 547 } 548 } 549 return (0); 550 } 551 552 void 553 sctp_free_saddrs(sctp_t *sctp) 554 { 555 int i; 556 int l; 557 sctp_saddr_ipif_t *obj; 558 559 if (sctp->sctp_nsaddrs == 0) 560 return; 561 for (i = 0; i < SCTP_IPIF_HASH; i++) { 562 if (sctp->sctp_saddrs[i].ipif_count == 0) 563 continue; 564 obj = list_tail(&sctp->sctp_saddrs[i].sctp_ipif_list); 565 for (l = 0; l < sctp->sctp_saddrs[i].ipif_count; l++) { 566 list_remove(&sctp->sctp_saddrs[i].sctp_ipif_list, obj); 567 SCTP_IPIF_REFRELE(obj->saddr_ipifp); 568 sctp->sctp_nsaddrs--; 569 kmem_free(obj, sizeof (sctp_saddr_ipif_t)); 570 obj = list_tail(&sctp->sctp_saddrs[i].sctp_ipif_list); 571 } 572 sctp->sctp_saddrs[i].ipif_count = 0; 573 } 574 ASSERT(sctp->sctp_nsaddrs == 0); 575 } 576 577 /* 578 * Add/Delete the given ILL from the SCTP ILL list. Called with no locks 579 * held. 580 */ 581 void 582 sctp_update_ill(ill_t *ill, int op) 583 { 584 int i; 585 sctp_ill_t *sctp_ill = NULL; 586 uint_t index; 587 588 ip2dbg(("sctp_update_ill: %s\n", ill->ill_name)); 589 590 rw_enter(&sctp_g_ills_lock, RW_WRITER); 591 592 index = SCTP_ILL_HASH_FN(SCTP_ILL_TO_PHYINDEX(ill)); 593 sctp_ill = list_head(&sctp_g_ills[index].sctp_ill_list); 594 for (i = 0; i < sctp_g_ills[index].ill_count; i++) { 595 if (sctp_ill->sctp_ill_index == SCTP_ILL_TO_PHYINDEX(ill)) 596 break; 597 sctp_ill = list_next(&sctp_g_ills[index].sctp_ill_list, 598 sctp_ill); 599 } 600 601 switch (op) { 602 case SCTP_ILL_INSERT: 603 if (sctp_ill != NULL) { 604 /* Unmark it if it is condemned */ 605 if (sctp_ill->sctp_ill_state == SCTP_ILLS_CONDEMNED) 606 sctp_ill->sctp_ill_state = 0; 607 rw_exit(&sctp_g_ills_lock); 608 return; 609 } 610 sctp_ill = kmem_zalloc(sizeof (sctp_ill_t), KM_NOSLEEP); 611 /* Need to re-try? */ 612 if (sctp_ill == NULL) { 613 ip1dbg(("sctp_ill_insert: mem error..\n")); 614 rw_exit(&sctp_g_ills_lock); 615 return; 616 } 617 sctp_ill->sctp_ill_name = 618 kmem_zalloc(ill->ill_name_length, KM_NOSLEEP); 619 if (sctp_ill->sctp_ill_name == NULL) { 620 ip1dbg(("sctp_ill_insert: mem error..\n")); 621 kmem_free(sctp_ill, sizeof (sctp_ill_t)); 622 rw_exit(&sctp_g_ills_lock); 623 return; 624 } 625 bcopy(ill->ill_name, sctp_ill->sctp_ill_name, 626 ill->ill_name_length); 627 sctp_ill->sctp_ill_name_length = ill->ill_name_length; 628 sctp_ill->sctp_ill_index = SCTP_ILL_TO_PHYINDEX(ill); 629 sctp_ill->sctp_ill_flags = ill->ill_phyint->phyint_flags; 630 list_insert_tail(&sctp_g_ills[index].sctp_ill_list, 631 (void *)sctp_ill); 632 sctp_g_ills[index].ill_count++; 633 sctp_ills_count++; 634 635 break; 636 637 case SCTP_ILL_REMOVE: 638 639 if (sctp_ill == NULL) { 640 rw_exit(&sctp_g_ills_lock); 641 return; 642 } 643 if (sctp_ill->sctp_ill_ipifcnt == 0) { 644 list_remove(&sctp_g_ills[index].sctp_ill_list, 645 (void *)sctp_ill); 646 sctp_g_ills[index].ill_count--; 647 sctp_ills_count--; 648 kmem_free(sctp_ill->sctp_ill_name, 649 ill->ill_name_length); 650 kmem_free(sctp_ill, sizeof (sctp_ill_t)); 651 } else { 652 sctp_ill->sctp_ill_state = SCTP_ILLS_CONDEMNED; 653 } 654 655 break; 656 } 657 rw_exit(&sctp_g_ills_lock); 658 } 659 660 /* move ipif from f_ill to t_ill */ 661 void 662 sctp_move_ipif(ipif_t *ipif, ill_t *f_ill, ill_t *t_ill) 663 { 664 sctp_ill_t *fsctp_ill = NULL; 665 sctp_ill_t *tsctp_ill = NULL; 666 sctp_ipif_t *sctp_ipif; 667 uint_t index; 668 int i; 669 670 rw_enter(&sctp_g_ills_lock, RW_READER); 671 rw_enter(&sctp_g_ipifs_lock, RW_READER); 672 673 index = SCTP_ILL_HASH_FN(SCTP_ILL_TO_PHYINDEX(f_ill)); 674 fsctp_ill = list_head(&sctp_g_ills[index].sctp_ill_list); 675 for (i = 0; i < sctp_g_ills[index].ill_count; i++) { 676 if (fsctp_ill->sctp_ill_index == SCTP_ILL_TO_PHYINDEX(f_ill)) 677 break; 678 fsctp_ill = list_next(&sctp_g_ills[index].sctp_ill_list, 679 fsctp_ill); 680 } 681 682 index = SCTP_ILL_HASH_FN(SCTP_ILL_TO_PHYINDEX(t_ill)); 683 tsctp_ill = list_head(&sctp_g_ills[index].sctp_ill_list); 684 for (i = 0; i < sctp_g_ills[index].ill_count; i++) { 685 if (tsctp_ill->sctp_ill_index == SCTP_ILL_TO_PHYINDEX(t_ill)) 686 break; 687 tsctp_ill = list_next(&sctp_g_ills[index].sctp_ill_list, 688 tsctp_ill); 689 } 690 691 index = SCTP_IPIF_HASH_FN(ipif->ipif_seqid); 692 sctp_ipif = list_head(&sctp_g_ipifs[index].sctp_ipif_list); 693 for (i = 0; i < sctp_g_ipifs[index].ipif_count; i++) { 694 if (sctp_ipif->sctp_ipif_id == ipif->ipif_seqid) 695 break; 696 sctp_ipif = list_next(&sctp_g_ipifs[index].sctp_ipif_list, 697 sctp_ipif); 698 } 699 /* Should be an ASSERT? */ 700 if (fsctp_ill == NULL || tsctp_ill == NULL || sctp_ipif == NULL) { 701 ip1dbg(("sctp_move_ipif: error moving ipif %p from %p to %p\n", 702 (void *)ipif, (void *)f_ill, (void *)t_ill)); 703 rw_exit(&sctp_g_ipifs_lock); 704 rw_exit(&sctp_g_ills_lock); 705 return; 706 } 707 rw_enter(&sctp_ipif->sctp_ipif_lock, RW_WRITER); 708 ASSERT(sctp_ipif->sctp_ipif_ill == fsctp_ill); 709 sctp_ipif->sctp_ipif_ill = tsctp_ill; 710 rw_exit(&sctp_ipif->sctp_ipif_lock); 711 (void) atomic_add_32_nv(&fsctp_ill->sctp_ill_ipifcnt, -1); 712 atomic_add_32(&tsctp_ill->sctp_ill_ipifcnt, 1); 713 rw_exit(&sctp_g_ipifs_lock); 714 rw_exit(&sctp_g_ills_lock); 715 } 716 717 /* Insert, Remove, Mark up or Mark down the ipif */ 718 void 719 sctp_update_ipif(ipif_t *ipif, int op) 720 { 721 ill_t *ill = ipif->ipif_ill; 722 int i; 723 sctp_ill_t *sctp_ill; 724 sctp_ipif_t *sctp_ipif; 725 uint_t ill_index; 726 uint_t ipif_index; 727 728 ip2dbg(("sctp_update_ipif: %s %d\n", ill->ill_name, ipif->ipif_seqid)); 729 730 rw_enter(&sctp_g_ills_lock, RW_READER); 731 rw_enter(&sctp_g_ipifs_lock, RW_WRITER); 732 733 ill_index = SCTP_ILL_HASH_FN(SCTP_ILL_TO_PHYINDEX(ill)); 734 sctp_ill = list_head(&sctp_g_ills[ill_index].sctp_ill_list); 735 for (i = 0; i < sctp_g_ills[ill_index].ill_count; i++) { 736 if (sctp_ill->sctp_ill_index == SCTP_ILL_TO_PHYINDEX(ill)) 737 break; 738 sctp_ill = list_next(&sctp_g_ills[ill_index].sctp_ill_list, 739 sctp_ill); 740 } 741 if (sctp_ill == NULL) { 742 rw_exit(&sctp_g_ipifs_lock); 743 rw_exit(&sctp_g_ills_lock); 744 return; 745 } 746 747 ipif_index = SCTP_IPIF_HASH_FN(ipif->ipif_seqid); 748 sctp_ipif = list_head(&sctp_g_ipifs[ipif_index].sctp_ipif_list); 749 for (i = 0; i < sctp_g_ipifs[ipif_index].ipif_count; i++) { 750 if (sctp_ipif->sctp_ipif_id == ipif->ipif_seqid) 751 break; 752 sctp_ipif = list_next(&sctp_g_ipifs[ipif_index].sctp_ipif_list, 753 sctp_ipif); 754 } 755 if (op != SCTP_IPIF_INSERT && sctp_ipif == NULL) { 756 ip1dbg(("sctp_update_ipif: null sctp_ipif for %d\n", op)); 757 rw_exit(&sctp_g_ipifs_lock); 758 rw_exit(&sctp_g_ills_lock); 759 return; 760 } 761 #ifdef DEBUG 762 if (sctp_ipif != NULL) 763 ASSERT(sctp_ill == sctp_ipif->sctp_ipif_ill); 764 #endif 765 switch (op) { 766 case SCTP_IPIF_INSERT: 767 if (sctp_ipif != NULL) { 768 if (sctp_ipif->sctp_ipif_state == SCTP_IPIFS_CONDEMNED) 769 sctp_ipif->sctp_ipif_state = SCTP_IPIFS_INVALID; 770 rw_exit(&sctp_g_ipifs_lock); 771 rw_exit(&sctp_g_ills_lock); 772 return; 773 } 774 sctp_ipif = kmem_zalloc(sizeof (sctp_ipif_t), KM_NOSLEEP); 775 /* Try again? */ 776 if (sctp_ipif == NULL) { 777 ip1dbg(("sctp_ipif_insert: mem failure..\n")); 778 rw_exit(&sctp_g_ipifs_lock); 779 rw_exit(&sctp_g_ills_lock); 780 return; 781 } 782 sctp_ipif->sctp_ipif_id = ipif->ipif_seqid; 783 sctp_ipif->sctp_ipif_ill = sctp_ill; 784 sctp_ipif->sctp_ipif_state = SCTP_IPIFS_INVALID; 785 sctp_ipif->sctp_ipif_mtu = ipif->ipif_mtu; 786 sctp_ipif->sctp_ipif_zoneid = ipif->ipif_zoneid; 787 sctp_ipif->sctp_ipif_isv6 = ill->ill_isv6; 788 rw_init(&sctp_ipif->sctp_ipif_lock, NULL, RW_DEFAULT, NULL); 789 list_insert_tail(&sctp_g_ipifs[ipif_index].sctp_ipif_list, 790 (void *)sctp_ipif); 791 sctp_g_ipifs[ipif_index].ipif_count++; 792 sctp_g_ipifs_count++; 793 atomic_add_32(&sctp_ill->sctp_ill_ipifcnt, 1); 794 795 break; 796 797 case SCTP_IPIF_REMOVE: 798 { 799 list_t *ipif_list; 800 list_t *ill_list; 801 802 ill_list = &sctp_g_ills[ill_index].sctp_ill_list; 803 ipif_list = &sctp_g_ipifs[ipif_index].sctp_ipif_list; 804 if (sctp_ipif->sctp_ipif_refcnt != 0) { 805 sctp_ipif->sctp_ipif_state = SCTP_IPIFS_CONDEMNED; 806 rw_exit(&sctp_g_ipifs_lock); 807 rw_exit(&sctp_g_ills_lock); 808 return; 809 } 810 list_remove(ipif_list, (void *)sctp_ipif); 811 sctp_g_ipifs[ipif_index].ipif_count--; 812 sctp_g_ipifs_count--; 813 rw_destroy(&sctp_ipif->sctp_ipif_lock); 814 kmem_free(sctp_ipif, sizeof (sctp_ipif_t)); 815 (void) atomic_add_32_nv(&sctp_ill->sctp_ill_ipifcnt, -1); 816 if (rw_tryupgrade(&sctp_g_ills_lock) != 0) { 817 rw_downgrade(&sctp_g_ipifs_lock); 818 if (sctp_ill->sctp_ill_ipifcnt == 0 && 819 sctp_ill->sctp_ill_state == SCTP_ILLS_CONDEMNED) { 820 list_remove(ill_list, (void *)sctp_ill); 821 sctp_ills_count--; 822 sctp_g_ills[ill_index].ill_count--; 823 kmem_free(sctp_ill->sctp_ill_name, 824 sctp_ill->sctp_ill_name_length); 825 kmem_free(sctp_ill, sizeof (sctp_ill_t)); 826 } 827 } 828 break; 829 } 830 831 case SCTP_IPIF_UP: 832 833 rw_downgrade(&sctp_g_ipifs_lock); 834 rw_enter(&sctp_ipif->sctp_ipif_lock, RW_WRITER); 835 sctp_ipif->sctp_ipif_state = SCTP_IPIFS_UP; 836 sctp_ipif->sctp_ipif_saddr = ipif->ipif_v6lcl_addr; 837 rw_exit(&sctp_ipif->sctp_ipif_lock); 838 839 break; 840 841 case SCTP_IPIF_UPDATE: 842 843 rw_downgrade(&sctp_g_ipifs_lock); 844 rw_enter(&sctp_ipif->sctp_ipif_lock, RW_WRITER); 845 sctp_ipif->sctp_ipif_mtu = ipif->ipif_mtu; 846 sctp_ipif->sctp_ipif_saddr = ipif->ipif_v6lcl_addr; 847 sctp_ipif->sctp_ipif_zoneid = ipif->ipif_zoneid; 848 rw_exit(&sctp_ipif->sctp_ipif_lock); 849 850 break; 851 852 case SCTP_IPIF_DOWN: 853 854 rw_downgrade(&sctp_g_ipifs_lock); 855 rw_enter(&sctp_ipif->sctp_ipif_lock, RW_WRITER); 856 sctp_ipif->sctp_ipif_state = SCTP_IPIFS_DOWN; 857 rw_exit(&sctp_ipif->sctp_ipif_lock); 858 859 break; 860 } 861 rw_exit(&sctp_g_ipifs_lock); 862 rw_exit(&sctp_g_ills_lock); 863 } 864 865 /* 866 * 867 * 868 * SCTP source address list manipulaton, locking not used (except for 869 * sctp locking by the caller. 870 * 871 * 872 */ 873 874 /* Remove a specific saddr from the list */ 875 void 876 sctp_del_saddr(sctp_t *sctp, sctp_saddr_ipif_t *sp) 877 { 878 if (sctp->sctp_conn_tfp != NULL) 879 mutex_enter(&sctp->sctp_conn_tfp->tf_lock); 880 881 if (sctp->sctp_listen_tfp != NULL) 882 mutex_enter(&sctp->sctp_listen_tfp->tf_lock); 883 884 sctp_ipif_hash_remove(sctp, sp->saddr_ipifp); 885 886 if (sctp->sctp_bound_to_all) 887 sctp->sctp_bound_to_all = 0; 888 889 if (sctp->sctp_conn_tfp != NULL) 890 mutex_exit(&sctp->sctp_conn_tfp->tf_lock); 891 892 if (sctp->sctp_listen_tfp != NULL) 893 mutex_exit(&sctp->sctp_listen_tfp->tf_lock); 894 } 895 896 /* 897 * Delete source address from the existing list. No error checking done here 898 * Called with no locks held. 899 */ 900 void 901 sctp_del_saddr_list(sctp_t *sctp, const void *addrs, int addcnt, 902 boolean_t fanout_locked) 903 { 904 struct sockaddr_in *sin4; 905 struct sockaddr_in6 *sin6; 906 int cnt; 907 in6_addr_t addr; 908 sctp_ipif_t *sctp_ipif; 909 910 ASSERT(sctp->sctp_nsaddrs > addcnt); 911 912 if (!fanout_locked) { 913 if (sctp->sctp_conn_tfp != NULL) 914 mutex_enter(&sctp->sctp_conn_tfp->tf_lock); 915 if (sctp->sctp_listen_tfp != NULL) 916 mutex_enter(&sctp->sctp_listen_tfp->tf_lock); 917 } 918 919 for (cnt = 0; cnt < addcnt; cnt++) { 920 switch (sctp->sctp_family) { 921 case AF_INET: 922 sin4 = (struct sockaddr_in *)addrs + cnt; 923 IN6_INADDR_TO_V4MAPPED(&sin4->sin_addr, &addr); 924 break; 925 926 case AF_INET6: 927 sin6 = (struct sockaddr_in6 *)addrs + cnt; 928 addr = sin6->sin6_addr; 929 break; 930 } 931 sctp_ipif = sctp_lookup_ipif_addr(&addr, B_FALSE, 932 sctp->sctp_zoneid); 933 ASSERT(sctp_ipif != NULL); 934 sctp_ipif_hash_remove(sctp, sctp_ipif); 935 } 936 if (sctp->sctp_bound_to_all) 937 sctp->sctp_bound_to_all = 0; 938 939 if (!fanout_locked) { 940 if (sctp->sctp_conn_tfp != NULL) 941 mutex_exit(&sctp->sctp_conn_tfp->tf_lock); 942 if (sctp->sctp_listen_tfp != NULL) 943 mutex_exit(&sctp->sctp_listen_tfp->tf_lock); 944 } 945 } 946 947 /* 948 * Given an address get the corresponding entry from the list 949 * Called with no locks held. 950 */ 951 sctp_saddr_ipif_t * 952 sctp_saddr_lookup(sctp_t *sctp, in6_addr_t *addr) 953 { 954 sctp_saddr_ipif_t *saddr_ipifs; 955 sctp_ipif_t *sctp_ipif; 956 957 sctp_ipif = sctp_lookup_ipif_addr(addr, B_FALSE, sctp->sctp_zoneid); 958 if (sctp_ipif == NULL) 959 return (NULL); 960 961 saddr_ipifs = sctp_ipif_lookup(sctp, sctp_ipif->sctp_ipif_id); 962 return (saddr_ipifs); 963 } 964 965 /* Get the first valid address from the list. Called with no locks held */ 966 in6_addr_t 967 sctp_get_valid_addr(sctp_t *sctp, boolean_t isv6) 968 { 969 int i; 970 int l; 971 sctp_saddr_ipif_t *obj; 972 int scanned = 0; 973 in6_addr_t addr; 974 975 for (i = 0; i < SCTP_IPIF_HASH; i++) { 976 if (sctp->sctp_saddrs[i].ipif_count == 0) 977 continue; 978 obj = list_head(&sctp->sctp_saddrs[i].sctp_ipif_list); 979 for (l = 0; l < sctp->sctp_saddrs[i].ipif_count; l++) { 980 sctp_ipif_t *ipif; 981 sctp_ill_t *ill; 982 983 ipif = obj->saddr_ipifp; 984 ill = ipif->sctp_ipif_ill; 985 if (!obj->saddr_ipif_dontsrc && 986 ipif->sctp_ipif_isv6 == isv6 && 987 ipif->sctp_ipif_state == SCTP_IPIFS_UP && 988 !(ill->sctp_ill_flags & PHYI_LOOPBACK) && 989 (!ipif->sctp_ipif_isv6 || 990 !IN6_IS_ADDR_LINKLOCAL(&ipif->sctp_ipif_saddr))) { 991 return (ipif->sctp_ipif_saddr); 992 } 993 scanned++; 994 if (scanned >= sctp->sctp_nsaddrs) 995 goto got_none; 996 obj = list_next(&sctp->sctp_saddrs[i].sctp_ipif_list, 997 obj); 998 } 999 } 1000 got_none: 1001 /* Need to double check this */ 1002 if (isv6 == B_TRUE) 1003 addr = ipv6_all_zeros; 1004 else 1005 IN6_IPADDR_TO_V4MAPPED(0, &addr); 1006 1007 return (addr); 1008 } 1009 1010 /* 1011 * Return the list of local addresses of an association. The parameter 1012 * myaddrs is supposed to be either (struct sockaddr_in *) or (struct 1013 * sockaddr_in6 *) depending on the address family. 1014 */ 1015 int 1016 sctp_getmyaddrs(void *conn, void *myaddrs, int *addrcnt) 1017 { 1018 int i; 1019 int l; 1020 sctp_saddr_ipif_t *obj; 1021 sctp_t *sctp = (sctp_t *)conn; 1022 int family = sctp->sctp_family; 1023 int max = *addrcnt; 1024 size_t added = 0; 1025 struct sockaddr_in6 *sin6; 1026 struct sockaddr_in *sin4; 1027 int scanned = 0; 1028 boolean_t skip_lback = B_FALSE; 1029 1030 if (sctp->sctp_nsaddrs == 0) 1031 return (EINVAL); 1032 1033 /* Skip loopback addresses for non-loopback assoc. */ 1034 if (sctp->sctp_state >= SCTPS_ESTABLISHED && !sctp->sctp_loopback) 1035 skip_lback = B_TRUE; 1036 for (i = 0; i < SCTP_IPIF_HASH; i++) { 1037 if (sctp->sctp_saddrs[i].ipif_count == 0) 1038 continue; 1039 obj = list_head(&sctp->sctp_saddrs[i].sctp_ipif_list); 1040 for (l = 0; l < sctp->sctp_saddrs[i].ipif_count; l++) { 1041 sctp_ipif_t *ipif = obj->saddr_ipifp; 1042 sctp_ill_t *ill = ipif->sctp_ipif_ill; 1043 in6_addr_t addr = ipif->sctp_ipif_saddr; 1044 1045 scanned++; 1046 if ((ipif->sctp_ipif_state == SCTP_IPIFS_CONDEMNED) || 1047 obj->saddr_ipif_dontsrc || 1048 ((ill->sctp_ill_flags & PHYI_LOOPBACK) && 1049 skip_lback)) { 1050 if (scanned >= sctp->sctp_nsaddrs) 1051 goto done; 1052 obj = list_next(&sctp->sctp_saddrs[i]. 1053 sctp_ipif_list, obj); 1054 continue; 1055 } 1056 switch (family) { 1057 case AF_INET: 1058 sin4 = (struct sockaddr_in *)myaddrs + added; 1059 sin4->sin_family = AF_INET; 1060 sin4->sin_port = sctp->sctp_lport; 1061 IN6_V4MAPPED_TO_INADDR(&addr, &sin4->sin_addr); 1062 break; 1063 1064 case AF_INET6: 1065 sin6 = (struct sockaddr_in6 *)myaddrs + added; 1066 sin6->sin6_family = AF_INET6; 1067 sin6->sin6_port = sctp->sctp_lport; 1068 sin6->sin6_addr = addr; 1069 break; 1070 } 1071 added++; 1072 if (added >= max || scanned >= sctp->sctp_nsaddrs) 1073 goto done; 1074 obj = list_next(&sctp->sctp_saddrs[i].sctp_ipif_list, 1075 obj); 1076 } 1077 } 1078 done: 1079 *addrcnt = added; 1080 return (0); 1081 } 1082 1083 /* 1084 * Given the supported address family, walk through the source address list 1085 * and return the total length of the available addresses. If 'p' is not 1086 * null, construct the parameter list for the addresses in 'p'. 1087 */ 1088 size_t 1089 sctp_saddr_info(sctp_t *sctp, int supp_af, uchar_t *p) 1090 { 1091 int i; 1092 int l; 1093 sctp_saddr_ipif_t *obj; 1094 size_t paramlen = 0; 1095 sctp_parm_hdr_t *hdr; 1096 int scanned = 0; 1097 1098 for (i = 0; i < SCTP_IPIF_HASH; i++) { 1099 if (sctp->sctp_saddrs[i].ipif_count == 0) 1100 continue; 1101 obj = list_head(&sctp->sctp_saddrs[i].sctp_ipif_list); 1102 for (l = 0; l < sctp->sctp_saddrs[i].ipif_count; l++) { 1103 in6_addr_t addr; 1104 sctp_ipif_t *ipif; 1105 sctp_ill_t *ill; 1106 1107 ipif = obj->saddr_ipifp; 1108 ill = ipif->sctp_ipif_ill; 1109 scanned++; 1110 if (!SCTP_IPIF_USABLE(ipif->sctp_ipif_state) || 1111 (ill->sctp_ill_flags & PHYI_LOOPBACK)) { 1112 goto next_addr; 1113 } 1114 if (p != NULL) 1115 hdr = (sctp_parm_hdr_t *)(p + paramlen); 1116 addr = ipif->sctp_ipif_saddr; 1117 if (IN6_IS_ADDR_V4MAPPED(&addr)) { 1118 struct in_addr *v4; 1119 1120 /* The other side does not support v4 */ 1121 if (!(supp_af & PARM_SUPP_V4)) 1122 goto next_addr; 1123 1124 if (p != NULL) { 1125 hdr->sph_type = htons(PARM_ADDR4); 1126 hdr->sph_len = htons(PARM_ADDR4_LEN); 1127 v4 = (struct in_addr *)(hdr + 1); 1128 IN6_V4MAPPED_TO_INADDR(&addr, v4); 1129 } 1130 paramlen += PARM_ADDR4_LEN; 1131 } else if (!IN6_IS_ADDR_LINKLOCAL(&addr) && 1132 (supp_af & PARM_SUPP_V6)) { 1133 if (p != NULL) { 1134 hdr->sph_type = htons(PARM_ADDR6); 1135 hdr->sph_len = htons(PARM_ADDR6_LEN); 1136 bcopy(&addr, hdr + 1, sizeof (addr)); 1137 } 1138 paramlen += PARM_ADDR6_LEN; 1139 } 1140 next_addr: 1141 if (scanned >= sctp->sctp_nsaddrs) 1142 return (paramlen); 1143 obj = list_next(&sctp->sctp_saddrs[i].sctp_ipif_list, 1144 obj); 1145 } 1146 } 1147 return (paramlen); 1148 } 1149 1150 1151 /* Initialize the SCTP ILL list and lock */ 1152 void 1153 sctp_saddr_init() 1154 { 1155 int i; 1156 1157 rw_init(&sctp_g_ills_lock, NULL, RW_DEFAULT, NULL); 1158 rw_init(&sctp_g_ipifs_lock, NULL, RW_DEFAULT, NULL); 1159 1160 for (i = 0; i < SCTP_ILL_HASH; i++) { 1161 sctp_g_ills[i].ill_count = 0; 1162 list_create(&sctp_g_ills[i].sctp_ill_list, sizeof (sctp_ill_t), 1163 offsetof(sctp_ill_t, sctp_ills)); 1164 } 1165 for (i = 0; i < SCTP_IPIF_HASH; i++) { 1166 sctp_g_ipifs[i].ipif_count = 0; 1167 list_create(&sctp_g_ipifs[i].sctp_ipif_list, 1168 sizeof (sctp_ipif_t), offsetof(sctp_ipif_t, sctp_ipifs)); 1169 } 1170 } 1171 1172 void 1173 sctp_saddr_fini() 1174 { 1175 int i; 1176 1177 rw_destroy(&sctp_g_ills_lock); 1178 rw_destroy(&sctp_g_ipifs_lock); 1179 ASSERT(sctp_ills_count == 0 && sctp_g_ipifs_count == 0); 1180 for (i = 0; i < SCTP_ILL_HASH; i++) 1181 list_destroy(&sctp_g_ills[i].sctp_ill_list); 1182 for (i = 0; i < SCTP_IPIF_HASH; i++) 1183 list_destroy(&sctp_g_ipifs[i].sctp_ipif_list); 1184 } 1185