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