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