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