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.
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.
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]
22 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
25 #include <sys/types.h>
26 #include <sys/systm.h>
27 #include <sys/stream.h>
28 #include <sys/cmn_err.h>
30 #include <sys/sunddi.h>
32 #include <sys/socket.h>
33 #include <sys/sysmacros.h>
36 #include <netinet/in.h>
37 #include <netinet/ip6.h>
38 #include <netinet/sctp.h>
40 #include <inet/common.h>
43 #include <inet/ip_ire.h>
44 #include <inet/ip_if.h>
45 #include <inet/ipclassifier.h>
46 #include <inet/sctp_ip.h>
47 #include "sctp_impl.h"
48 #include "sctp_addr.h"
50 static void sctp_ipif_inactive(sctp_ipif_t
*);
51 static sctp_ipif_t
*sctp_lookup_ipif_addr(in6_addr_t
*, boolean_t
,
52 zoneid_t
, boolean_t
, uint_t
, uint_t
, boolean_t
,
54 static int sctp_get_all_ipifs(sctp_t
*, int);
55 static int sctp_ipif_hash_insert(sctp_t
*, sctp_ipif_t
*, int,
56 boolean_t
, boolean_t
);
57 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
*,
62 static int sctp_copy_ipifs(sctp_ipif_hash_t
*, sctp_t
*, int);
64 #define SCTP_ADDR4_HASH(addr) \
65 (((addr) ^ ((addr) >> 8) ^ ((addr) >> 16) ^ ((addr) >> 24)) & \
68 #define SCTP_ADDR6_HASH(addr) \
69 (((addr).s6_addr32[3] ^ \
70 (((addr).s6_addr32[3] ^ (addr).s6_addr32[2]) >> 12)) & \
73 #define SCTP_IPIF_ADDR_HASH(addr, isv6) \
74 ((isv6) ? SCTP_ADDR6_HASH((addr)) : \
75 SCTP_ADDR4_HASH((addr)._S6_un._S6_u32[3]))
77 #define SCTP_IPIF_USABLE(sctp_ipif_state) \
78 ((sctp_ipif_state) == SCTP_IPIFS_UP || \
79 (sctp_ipif_state) == SCTP_IPIFS_DOWN)
81 #define SCTP_IPIF_DISCARD(sctp_ipif_flags) \
82 ((sctp_ipif_flags) & (IPIF_PRIVATE | IPIF_DEPRECATED))
84 #define SCTP_IS_IPIF_LOOPBACK(ipif) \
85 ((ipif)->sctp_ipif_ill->sctp_ill_flags & PHYI_LOOPBACK)
87 #define SCTP_IS_IPIF_LINKLOCAL(ipif) \
88 ((ipif)->sctp_ipif_isv6 && \
89 IN6_IS_ADDR_LINKLOCAL(&(ipif)->sctp_ipif_saddr))
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)))
95 #define SCTP_IPIF_ZONE_MATCH(sctp, ipif) \
96 IPCL_ZONE_MATCH((sctp)->sctp_connp, (ipif)->sctp_ipif_zoneid)
98 #define SCTP_ILL_HASH_FN(index) ((index) % SCTP_ILL_HASH)
99 #define SCTP_ILL_TO_PHYINDEX(ill) ((ill)->ill_phyint->phyint_ifindex)
102 * SCTP Interface list manipulation functions, locking used.
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.
110 sctp_ipif_inactive(sctp_ipif_t
*sctp_ipif
)
112 sctp_ill_t
*sctp_ill
;
115 sctp_stack_t
*sctps
= sctp_ipif
->sctp_ipif_ill
->
116 sctp_ill_netstack
->netstack_sctp
;
118 rw_enter(&sctps
->sctps_g_ills_lock
, RW_READER
);
119 rw_enter(&sctps
->sctps_g_ipifs_lock
, RW_WRITER
);
121 hindex
= SCTP_IPIF_ADDR_HASH(sctp_ipif
->sctp_ipif_saddr
,
122 sctp_ipif
->sctp_ipif_isv6
);
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
);
133 list_remove(&sctps
->sctps_g_ipifs
[hindex
].sctp_ipif_list
,
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
));
140 atomic_dec_32(&sctp_ill
->sctp_ill_ipifcnt
);
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
));
154 rw_exit(&sctps
->sctps_g_ipifs_lock
);
155 rw_exit(&sctps
->sctps_g_ills_lock
);
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
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
,
178 sctp_ipif_t
*sctp_ipif
;
179 sctp_ipif_t
*backup_ipif
= NULL
;
182 hindex
= SCTP_IPIF_ADDR_HASH(*addr
, !IN6_IS_ADDR_V4MAPPED(addr
));
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
);
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
);
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
,
200 if (!usable
|| sctp_ipif
->sctp_ipif_state
==
202 rw_exit(&sctp_ipif
->sctp_ipif_lock
);
204 SCTP_IPIF_REFHOLD(sctp_ipif
);
205 rw_exit(&sctps
->sctps_g_ipifs_lock
);
207 } else if (sctp_ipif
->sctp_ipif_state
==
208 SCTP_IPIFS_DOWN
&& backup_ipif
== NULL
) {
209 backup_ipif
= sctp_ipif
;
212 rw_exit(&sctp_ipif
->sctp_ipif_lock
);
213 sctp_ipif
= list_next(
214 &sctps
->sctps_g_ipifs
[hindex
].sctp_ipif_list
, sctp_ipif
);
216 if (backup_ipif
!= NULL
) {
218 SCTP_IPIF_REFHOLD(backup_ipif
);
219 rw_exit(&sctps
->sctps_g_ipifs_lock
);
220 return (backup_ipif
);
222 rw_exit(&sctps
->sctps_g_ipifs_lock
);
227 * Populate the list with all the SCTP ipifs for a given ipversion.
228 * Increments sctp_ipif refcnt.
229 * Called with no locks held.
232 sctp_get_all_ipifs(sctp_t
*sctp
, int sleep
)
234 sctp_ipif_t
*sctp_ipif
;
238 sctp_stack_t
*sctps
= sctp
->sctp_sctps
;
240 conn_t
*connp
= sctp
->sctp_connp
;
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)
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
,
263 rw_exit(&sctp_ipif
->sctp_ipif_lock
);
264 SCTP_IPIF_REFHOLD(sctp_ipif
);
265 error
= sctp_ipif_hash_insert(sctp
, sctp_ipif
, sleep
,
267 if (error
!= 0 && error
!= EALREADY
)
269 sctp_ipif
= list_next(
270 &sctps
->sctps_g_ipifs
[i
].sctp_ipif_list
,
274 rw_exit(&sctps
->sctps_g_ipifs_lock
);
277 rw_exit(&sctps
->sctps_g_ipifs_lock
);
278 sctp_free_saddrs(sctp
);
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.
293 sctp_valid_addr_list(sctp_t
*sctp
, const void *addrs
, uint32_t addrcnt
,
294 uchar_t
*list
, size_t lsize
)
296 struct sockaddr_in
*sin4
;
297 struct sockaddr_in6
*sin6
;
298 struct in_addr
*addr4
;
304 boolean_t bind_to_all
= B_FALSE
;
305 boolean_t check_addrs
= B_FALSE
;
306 boolean_t check_lport
= B_FALSE
;
308 conn_t
*connp
= sctp
->sctp_connp
;
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
317 if (sctp
->sctp_state
>= SCTPS_BOUND
) {
318 check_lport
= B_TRUE
;
319 if (sctp
->sctp_state
> SCTPS_LISTEN
)
320 check_addrs
= B_TRUE
;
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
;
331 switch (connp
->conn_family
) {
333 sin4
= (struct sockaddr_in
*)addrs
+ cnt
;
334 if (sin4
->sin_family
!= AF_INET
|| (check_lport
&&
335 sin4
->sin_port
!= connp
->conn_lport
)) {
339 addr4
= &sin4
->sin_addr
;
341 (addr4
->s_addr
== INADDR_ANY
||
342 addr4
->s_addr
== INADDR_BROADCAST
||
343 CLASSD(addr4
->s_addr
))) {
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
;
355 sin6
= (struct sockaddr_in6
*)addrs
+ cnt
;
356 if (sin6
->sin6_family
!= AF_INET6
|| (check_lport
&&
357 sin6
->sin6_port
!= connp
->conn_lport
)) {
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
)) {
370 (IN6_IS_ADDR_LINKLOCAL(&addr
) ||
371 IN6_IS_ADDR_MULTICAST(&addr
) ||
372 IN6_IS_ADDR_UNSPECIFIED(&addr
))) {
376 if (!check_addrs
&& IN6_IS_ADDR_UNSPECIFIED(&addr
)) {
377 lookup_saddr
= B_FALSE
;
378 bind_to_all
= B_TRUE
;
387 ipif
= sctp_lookup_ipif_addr(&addr
, B_TRUE
,
388 IPCL_ZONEID(connp
), !connp
->conn_allzones
,
389 ifindex
, 0, B_TRUE
, sctp
->sctp_sctps
);
391 /* Address not in the list */
394 } else if (check_addrs
&& SCTP_IS_IPIF_LOOPBACK(ipif
) &&
395 cl_sctp_check_addrs
== NULL
) {
396 SCTP_IPIF_REFRELE(ipif
);
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.
409 err
= sctp_ipif_hash_insert(sctp
, ipif
, KM_SLEEP
,
410 check_addrs
? B_TRUE
: B_FALSE
, B_FALSE
);
412 SCTP_IPIF_REFRELE(ipif
);
413 if (check_addrs
&& err
== EALREADY
)
418 if (lsize
>= sizeof (addr
)) {
419 bcopy(&addr
, p
, sizeof (addr
));
421 lsize
-= sizeof (addr
);
427 * Free whatever we might have added before encountering
430 if (sctp
->sctp_nsaddrs
> 0) {
431 sctp_free_saddrs(sctp
);
432 ASSERT(sctp
->sctp_nsaddrs
== 0);
434 err
= sctp_get_all_ipifs(sctp
, KM_SLEEP
);
437 sctp
->sctp_bound_to_all
= 1;
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
);
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
);
455 sctp_ipif_hash_insert(sctp_t
*sctp
, sctp_ipif_t
*ipif
, int sleep
,
456 boolean_t dontsrc
, boolean_t allow_dup
)
459 sctp_saddr_ipif_t
*ipif_obj
;
462 hindex
= SCTP_IPIF_ADDR_HASH(ipif
->sctp_ipif_saddr
,
463 ipif
->sctp_ipif_isv6
);
464 rw_enter(&sctp
->sctp_saddrs
[hindex
].ipif_hash_lock
, RW_WRITER
);
465 ipif_obj
= list_head(&sctp
->sctp_saddrs
[hindex
].sctp_ipif_list
);
466 for (cnt
= 0; cnt
< sctp
->sctp_saddrs
[hindex
].ipif_count
; cnt
++) {
467 if (IN6_ARE_ADDR_EQUAL(&ipif_obj
->saddr_ipifp
->sctp_ipif_saddr
,
468 &ipif
->sctp_ipif_saddr
)) {
469 if (ipif
->sctp_ipif_id
!=
470 ipif_obj
->saddr_ipifp
->sctp_ipif_id
&&
471 ipif_obj
->saddr_ipifp
->sctp_ipif_state
==
472 SCTP_IPIFS_DOWN
&& ipif
->sctp_ipif_state
==
474 SCTP_IPIF_REFRELE(ipif_obj
->saddr_ipifp
);
475 ipif_obj
->saddr_ipifp
= ipif
;
476 ipif_obj
->saddr_ipif_dontsrc
= dontsrc
? 1 : 0;
478 &sctp
->sctp_saddrs
[hindex
].ipif_hash_lock
);
480 } else if (!allow_dup
|| ipif
->sctp_ipif_id
==
481 ipif_obj
->saddr_ipifp
->sctp_ipif_id
) {
483 &sctp
->sctp_saddrs
[hindex
].ipif_hash_lock
);
487 ipif_obj
= list_next(&sctp
->sctp_saddrs
[hindex
].sctp_ipif_list
,
490 ipif_obj
= kmem_zalloc(sizeof (sctp_saddr_ipif_t
), sleep
);
491 if (ipif_obj
== NULL
) {
492 rw_exit(&sctp
->sctp_saddrs
[hindex
].ipif_hash_lock
);
493 /* Need to do something */
496 ipif_obj
->saddr_ipifp
= ipif
;
497 ipif_obj
->saddr_ipif_dontsrc
= dontsrc
? 1 : 0;
498 list_insert_tail(&sctp
->sctp_saddrs
[hindex
].sctp_ipif_list
, ipif_obj
);
499 sctp
->sctp_saddrs
[hindex
].ipif_count
++;
500 sctp
->sctp_nsaddrs
++;
501 rw_exit(&sctp
->sctp_saddrs
[hindex
].ipif_hash_lock
);
506 * Given a source address, walk through the peer address list to see
507 * if the source address is being used. If it is, reset that.
508 * A cleared saddr will then make sctp_make_mp lookup the destination again
509 * and as part of that look for a new source.
512 sctp_fix_saddr(sctp_t
*sctp
, in6_addr_t
*saddr
)
516 for (fp
= sctp
->sctp_faddrs
; fp
!= NULL
; fp
= fp
->sf_next
) {
517 if (!IN6_ARE_ADDR_EQUAL(&fp
->sf_saddr
, saddr
))
519 V6_SET_ZERO(fp
->sf_saddr
);
524 sctp_ipif_hash_remove(sctp_t
*sctp
, sctp_ipif_t
*ipif
, boolean_t locked
)
527 sctp_saddr_ipif_t
*ipif_obj
;
530 hindex
= SCTP_IPIF_ADDR_HASH(ipif
->sctp_ipif_saddr
,
531 ipif
->sctp_ipif_isv6
);
533 rw_enter(&sctp
->sctp_saddrs
[hindex
].ipif_hash_lock
, RW_WRITER
);
534 ipif_obj
= list_head(&sctp
->sctp_saddrs
[hindex
].sctp_ipif_list
);
535 for (cnt
= 0; cnt
< sctp
->sctp_saddrs
[hindex
].ipif_count
; cnt
++) {
536 if (IN6_ARE_ADDR_EQUAL(&ipif_obj
->saddr_ipifp
->sctp_ipif_saddr
,
537 &ipif
->sctp_ipif_saddr
)) {
538 list_remove(&sctp
->sctp_saddrs
[hindex
].sctp_ipif_list
,
540 sctp
->sctp_saddrs
[hindex
].ipif_count
--;
541 sctp
->sctp_nsaddrs
--;
542 sctp_fix_saddr(sctp
, &ipif
->sctp_ipif_saddr
);
543 SCTP_IPIF_REFRELE(ipif_obj
->saddr_ipifp
);
544 kmem_free(ipif_obj
, sizeof (sctp_saddr_ipif_t
));
547 ipif_obj
= list_next(&sctp
->sctp_saddrs
[hindex
].sctp_ipif_list
,
551 rw_exit(&sctp
->sctp_saddrs
[hindex
].ipif_hash_lock
);
555 sctp_compare_ipif_list(sctp_ipif_hash_t
*list1
, sctp_ipif_hash_t
*list2
)
559 sctp_saddr_ipif_t
*obj1
;
560 sctp_saddr_ipif_t
*obj2
;
563 rw_enter(&list1
->ipif_hash_lock
, RW_READER
);
564 rw_enter(&list2
->ipif_hash_lock
, RW_READER
);
565 obj1
= list_head(&list1
->sctp_ipif_list
);
566 for (i
= 0; i
< list1
->ipif_count
; i
++) {
567 obj2
= list_head(&list2
->sctp_ipif_list
);
568 for (j
= 0; j
< list2
->ipif_count
; j
++) {
569 if (IN6_ARE_ADDR_EQUAL(
570 &obj1
->saddr_ipifp
->sctp_ipif_saddr
,
571 &obj2
->saddr_ipifp
->sctp_ipif_saddr
)) {
575 obj2
= list_next(&list2
->sctp_ipif_list
,
578 obj1
= list_next(&list1
->sctp_ipif_list
, obj1
);
580 rw_exit(&list1
->ipif_hash_lock
);
581 rw_exit(&list2
->ipif_hash_lock
);
586 sctp_compare_saddrs(sctp_t
*sctp1
, sctp_t
*sctp2
)
591 for (i
= 0; i
< SCTP_IPIF_HASH
; i
++) {
592 overlap
+= sctp_compare_ipif_list(&sctp1
->sctp_saddrs
[i
],
593 &sctp2
->sctp_saddrs
[i
]);
596 if (sctp1
->sctp_nsaddrs
== sctp2
->sctp_nsaddrs
&&
597 overlap
== sctp1
->sctp_nsaddrs
) {
598 return (SCTP_ADDR_EQUAL
);
601 if (overlap
== sctp1
->sctp_nsaddrs
)
602 return (SCTP_ADDR_SUBSET
);
605 return (SCTP_ADDR_OVERLAP
);
607 return (SCTP_ADDR_DISJOINT
);
611 sctp_copy_ipifs(sctp_ipif_hash_t
*list1
, sctp_t
*sctp2
, int sleep
)
614 sctp_saddr_ipif_t
*obj
;
617 rw_enter(&list1
->ipif_hash_lock
, RW_READER
);
618 obj
= list_head(&list1
->sctp_ipif_list
);
619 for (i
= 0; i
< list1
->ipif_count
; i
++) {
620 SCTP_IPIF_REFHOLD(obj
->saddr_ipifp
);
621 error
= sctp_ipif_hash_insert(sctp2
, obj
->saddr_ipifp
, sleep
,
623 ASSERT(error
!= EALREADY
);
625 rw_exit(&list1
->ipif_hash_lock
);
628 obj
= list_next(&list1
->sctp_ipif_list
, obj
);
630 rw_exit(&list1
->ipif_hash_lock
);
635 sctp_dup_saddrs(sctp_t
*sctp1
, sctp_t
*sctp2
, int sleep
)
640 if (sctp1
== NULL
|| sctp1
->sctp_bound_to_all
== 1)
641 return (sctp_get_all_ipifs(sctp2
, sleep
));
643 for (i
= 0; i
< SCTP_IPIF_HASH
; i
++) {
644 rw_enter(&sctp1
->sctp_saddrs
[i
].ipif_hash_lock
, RW_READER
);
645 if (sctp1
->sctp_saddrs
[i
].ipif_count
== 0) {
646 rw_exit(&sctp1
->sctp_saddrs
[i
].ipif_hash_lock
);
649 error
= sctp_copy_ipifs(&sctp1
->sctp_saddrs
[i
], sctp2
, sleep
);
651 rw_exit(&sctp1
->sctp_saddrs
[i
].ipif_hash_lock
);
652 sctp_free_saddrs(sctp2
);
655 rw_exit(&sctp1
->sctp_saddrs
[i
].ipif_hash_lock
);
661 sctp_free_saddrs(sctp_t
*sctp
)
665 sctp_saddr_ipif_t
*obj
;
667 if (sctp
->sctp_nsaddrs
== 0)
669 for (i
= 0; i
< SCTP_IPIF_HASH
; i
++) {
670 rw_enter(&sctp
->sctp_saddrs
[i
].ipif_hash_lock
, RW_WRITER
);
671 if (sctp
->sctp_saddrs
[i
].ipif_count
== 0) {
672 rw_exit(&sctp
->sctp_saddrs
[i
].ipif_hash_lock
);
675 obj
= list_tail(&sctp
->sctp_saddrs
[i
].sctp_ipif_list
);
676 for (l
= 0; l
< sctp
->sctp_saddrs
[i
].ipif_count
; l
++) {
677 list_remove(&sctp
->sctp_saddrs
[i
].sctp_ipif_list
, obj
);
678 SCTP_IPIF_REFRELE(obj
->saddr_ipifp
);
679 sctp
->sctp_nsaddrs
--;
680 kmem_free(obj
, sizeof (sctp_saddr_ipif_t
));
681 obj
= list_tail(&sctp
->sctp_saddrs
[i
].sctp_ipif_list
);
683 sctp
->sctp_saddrs
[i
].ipif_count
= 0;
684 rw_exit(&sctp
->sctp_saddrs
[i
].ipif_hash_lock
);
686 if (sctp
->sctp_bound_to_all
== 1)
687 sctp
->sctp_bound_to_all
= 0;
688 ASSERT(sctp
->sctp_nsaddrs
== 0);
692 * Add/Delete the given ILL from the SCTP ILL list. Called with no locks
696 sctp_update_ill(ill_t
*ill
, int op
)
699 sctp_ill_t
*sctp_ill
= NULL
;
701 netstack_t
*ns
= ill
->ill_ipst
->ips_netstack
;
702 sctp_stack_t
*sctps
= ns
->netstack_sctp
;
704 rw_enter(&sctps
->sctps_g_ills_lock
, RW_WRITER
);
706 index
= SCTP_ILL_HASH_FN(SCTP_ILL_TO_PHYINDEX(ill
));
707 sctp_ill
= list_head(&sctps
->sctps_g_ills
[index
].sctp_ill_list
);
708 for (i
= 0; i
< sctps
->sctps_g_ills
[index
].ill_count
; i
++) {
709 if ((sctp_ill
->sctp_ill_index
== SCTP_ILL_TO_PHYINDEX(ill
)) &&
710 (sctp_ill
->sctp_ill_isv6
== ill
->ill_isv6
)) {
713 sctp_ill
= list_next(&sctps
->sctps_g_ills
[index
].sctp_ill_list
,
718 case SCTP_ILL_INSERT
:
719 if (sctp_ill
!= NULL
) {
720 /* Unmark it if it is condemned */
721 if (sctp_ill
->sctp_ill_state
== SCTP_ILLS_CONDEMNED
)
722 sctp_ill
->sctp_ill_state
= 0;
723 rw_exit(&sctps
->sctps_g_ills_lock
);
726 sctp_ill
= kmem_zalloc(sizeof (sctp_ill_t
), KM_NOSLEEP
);
727 /* Need to re-try? */
728 if (sctp_ill
== NULL
) {
729 cmn_err(CE_WARN
, "sctp_update_ill: error adding "
730 "ILL %p to SCTP's ILL list", (void *)ill
);
731 rw_exit(&sctps
->sctps_g_ills_lock
);
734 sctp_ill
->sctp_ill_name
= kmem_zalloc(ill
->ill_name_length
,
736 if (sctp_ill
->sctp_ill_name
== NULL
) {
737 cmn_err(CE_WARN
, "sctp_update_ill: error adding "
738 "ILL %p to SCTP's ILL list", (void *)ill
);
739 kmem_free(sctp_ill
, sizeof (sctp_ill_t
));
740 rw_exit(&sctps
->sctps_g_ills_lock
);
743 bcopy(ill
->ill_name
, sctp_ill
->sctp_ill_name
,
744 ill
->ill_name_length
);
745 sctp_ill
->sctp_ill_name_length
= ill
->ill_name_length
;
746 sctp_ill
->sctp_ill_index
= SCTP_ILL_TO_PHYINDEX(ill
);
747 sctp_ill
->sctp_ill_flags
= ill
->ill_phyint
->phyint_flags
;
748 sctp_ill
->sctp_ill_netstack
= ns
; /* No netstack_hold */
749 sctp_ill
->sctp_ill_isv6
= ill
->ill_isv6
;
750 list_insert_tail(&sctps
->sctps_g_ills
[index
].sctp_ill_list
,
752 sctps
->sctps_g_ills
[index
].ill_count
++;
753 sctps
->sctps_ills_count
++;
757 case SCTP_ILL_REMOVE
:
759 if (sctp_ill
== NULL
) {
760 rw_exit(&sctps
->sctps_g_ills_lock
);
763 if (sctp_ill
->sctp_ill_ipifcnt
== 0) {
764 list_remove(&sctps
->sctps_g_ills
[index
].sctp_ill_list
,
766 sctps
->sctps_g_ills
[index
].ill_count
--;
767 sctps
->sctps_ills_count
--;
768 kmem_free(sctp_ill
->sctp_ill_name
,
769 ill
->ill_name_length
);
770 kmem_free(sctp_ill
, sizeof (sctp_ill_t
));
772 sctp_ill
->sctp_ill_state
= SCTP_ILLS_CONDEMNED
;
777 rw_exit(&sctps
->sctps_g_ills_lock
);
781 * The ILL's index is being changed, just remove it from the old list,
782 * change the SCTP ILL's index and re-insert using the new index.
785 sctp_ill_reindex(ill_t
*ill
, uint_t orig_ill_index
)
787 sctp_ill_t
*sctp_ill
= NULL
;
788 sctp_ill_t
*nxt_sill
;
791 boolean_t once
= B_FALSE
;
792 netstack_t
*ns
= ill
->ill_ipst
->ips_netstack
;
793 sctp_stack_t
*sctps
= ns
->netstack_sctp
;
795 rw_enter(&sctps
->sctps_g_ills_lock
, RW_WRITER
);
797 indx
= SCTP_ILL_HASH_FN(orig_ill_index
);
798 nindx
= SCTP_ILL_HASH_FN(SCTP_ILL_TO_PHYINDEX(ill
));
799 sctp_ill
= list_head(&sctps
->sctps_g_ills
[indx
].sctp_ill_list
);
800 while (sctp_ill
!= NULL
) {
801 nxt_sill
= list_next(&sctps
->sctps_g_ills
[indx
].sctp_ill_list
,
803 if (sctp_ill
->sctp_ill_index
== orig_ill_index
) {
804 sctp_ill
->sctp_ill_index
= SCTP_ILL_TO_PHYINDEX(ill
);
806 * if the new index hashes to the same value, all's
811 &sctps
->sctps_g_ills
[indx
].sctp_ill_list
,
813 sctps
->sctps_g_ills
[indx
].ill_count
--;
815 &sctps
->sctps_g_ills
[nindx
].sctp_ill_list
,
817 sctps
->sctps_g_ills
[nindx
].ill_count
++;
821 /* We might have one for v4 and for v6 */
826 rw_exit(&sctps
->sctps_g_ills_lock
);
829 /* move ipif from f_ill to t_ill */
831 sctp_move_ipif(ipif_t
*ipif
, ill_t
*f_ill
, ill_t
*t_ill
)
833 sctp_ill_t
*fsctp_ill
= NULL
;
834 sctp_ill_t
*tsctp_ill
= NULL
;
835 sctp_ipif_t
*sctp_ipif
;
838 netstack_t
*ns
= ipif
->ipif_ill
->ill_ipst
->ips_netstack
;
839 sctp_stack_t
*sctps
= ns
->netstack_sctp
;
841 rw_enter(&sctps
->sctps_g_ills_lock
, RW_READER
);
842 rw_enter(&sctps
->sctps_g_ipifs_lock
, RW_READER
);
844 hindex
= SCTP_ILL_HASH_FN(SCTP_ILL_TO_PHYINDEX(f_ill
));
845 fsctp_ill
= list_head(&sctps
->sctps_g_ills
[hindex
].sctp_ill_list
);
846 for (i
= 0; i
< sctps
->sctps_g_ills
[hindex
].ill_count
; i
++) {
847 if (fsctp_ill
->sctp_ill_index
== SCTP_ILL_TO_PHYINDEX(f_ill
) &&
848 fsctp_ill
->sctp_ill_isv6
== f_ill
->ill_isv6
) {
851 fsctp_ill
= list_next(
852 &sctps
->sctps_g_ills
[hindex
].sctp_ill_list
, fsctp_ill
);
855 hindex
= SCTP_ILL_HASH_FN(SCTP_ILL_TO_PHYINDEX(t_ill
));
856 tsctp_ill
= list_head(&sctps
->sctps_g_ills
[hindex
].sctp_ill_list
);
857 for (i
= 0; i
< sctps
->sctps_g_ills
[hindex
].ill_count
; i
++) {
858 if (tsctp_ill
->sctp_ill_index
== SCTP_ILL_TO_PHYINDEX(t_ill
) &&
859 tsctp_ill
->sctp_ill_isv6
== t_ill
->ill_isv6
) {
862 tsctp_ill
= list_next(
863 &sctps
->sctps_g_ills
[hindex
].sctp_ill_list
, tsctp_ill
);
866 hindex
= SCTP_IPIF_ADDR_HASH(ipif
->ipif_v6lcl_addr
,
867 ipif
->ipif_ill
->ill_isv6
);
868 sctp_ipif
= list_head(&sctps
->sctps_g_ipifs
[hindex
].sctp_ipif_list
);
869 for (i
= 0; i
< sctps
->sctps_g_ipifs
[hindex
].ipif_count
; i
++) {
870 if (sctp_ipif
->sctp_ipif_id
== ipif
->ipif_seqid
)
872 sctp_ipif
= list_next(
873 &sctps
->sctps_g_ipifs
[hindex
].sctp_ipif_list
, sctp_ipif
);
875 /* Should be an ASSERT? */
876 if (fsctp_ill
== NULL
|| tsctp_ill
== NULL
|| sctp_ipif
== NULL
) {
877 ip1dbg(("sctp_move_ipif: error moving ipif %p from %p to %p\n",
878 (void *)ipif
, (void *)f_ill
, (void *)t_ill
));
879 rw_exit(&sctps
->sctps_g_ipifs_lock
);
880 rw_exit(&sctps
->sctps_g_ills_lock
);
883 rw_enter(&sctp_ipif
->sctp_ipif_lock
, RW_WRITER
);
884 ASSERT(sctp_ipif
->sctp_ipif_ill
== fsctp_ill
);
885 sctp_ipif
->sctp_ipif_ill
= tsctp_ill
;
886 rw_exit(&sctp_ipif
->sctp_ipif_lock
);
887 atomic_dec_32(&fsctp_ill
->sctp_ill_ipifcnt
);
888 atomic_inc_32(&tsctp_ill
->sctp_ill_ipifcnt
);
889 rw_exit(&sctps
->sctps_g_ipifs_lock
);
890 rw_exit(&sctps
->sctps_g_ills_lock
);
894 * Walk the list of SCTPs and find each that has oipif in it's saddr list, and
895 * if so replace it with nipif.
898 sctp_update_saddrs(sctp_ipif_t
*oipif
, sctp_ipif_t
*nipif
, int idx
,
902 sctp_t
*sctp_prev
= NULL
;
903 sctp_saddr_ipif_t
*sobj
;
906 mutex_enter(&sctps
->sctps_g_lock
);
907 sctp
= list_head(&sctps
->sctps_g_list
);
908 while (sctp
!= NULL
&& oipif
->sctp_ipif_refcnt
> 0) {
909 mutex_enter(&sctp
->sctp_reflock
);
910 if (sctp
->sctp_condemned
||
911 sctp
->sctp_saddrs
[idx
].ipif_count
<= 0) {
912 mutex_exit(&sctp
->sctp_reflock
);
913 sctp
= list_next(&sctps
->sctps_g_list
, sctp
);
917 mutex_exit(&sctp
->sctp_reflock
);
918 mutex_exit(&sctps
->sctps_g_lock
);
919 if (sctp_prev
!= NULL
)
920 SCTP_REFRELE(sctp_prev
);
923 sobj
= list_head(&sctp
->sctp_saddrs
[idx
].sctp_ipif_list
);
924 for (count
= 0; count
<
925 sctp
->sctp_saddrs
[idx
].ipif_count
; count
++) {
926 if (sobj
->saddr_ipifp
== oipif
) {
927 SCTP_IPIF_REFHOLD(nipif
);
928 sobj
->saddr_ipifp
= nipif
;
929 ASSERT(oipif
->sctp_ipif_refcnt
> 0);
930 /* We have the writer lock */
931 oipif
->sctp_ipif_refcnt
--;
933 * Can't have more than one referring
934 * to the same sctp_ipif.
938 sobj
= list_next(&sctp
->sctp_saddrs
[idx
].sctp_ipif_list
,
943 mutex_enter(&sctps
->sctps_g_lock
);
944 sctp
= list_next(&sctps
->sctps_g_list
, sctp
);
946 mutex_exit(&sctps
->sctps_g_lock
);
947 if (sctp_prev
!= NULL
)
948 SCTP_REFRELE(sctp_prev
);
952 * Given an ipif, walk the hash list in the global ipif table and for
953 * any other SCTP ipif with the same address and non-zero reference, walk
954 * the SCTP list and update the saddr list, if required, to point to the
955 * new SCTP ipif. If it is a loopback interface, then there could be
956 * multiple interfaces with 127.0.0.1 if there are zones configured, so
957 * check the zoneid in addition to the address.
960 sctp_chk_and_updt_saddr(int hindex
, sctp_ipif_t
*ipif
, sctp_stack_t
*sctps
)
965 ASSERT(sctps
->sctps_g_ipifs
[hindex
].ipif_count
> 0);
966 ASSERT(ipif
->sctp_ipif_state
== SCTP_IPIFS_UP
);
968 sipif
= list_head(&sctps
->sctps_g_ipifs
[hindex
].sctp_ipif_list
);
969 for (cnt
= 0; cnt
< sctps
->sctps_g_ipifs
[hindex
].ipif_count
; cnt
++) {
970 rw_enter(&sipif
->sctp_ipif_lock
, RW_WRITER
);
971 if (sipif
->sctp_ipif_id
!= ipif
->sctp_ipif_id
&&
972 IN6_ARE_ADDR_EQUAL(&sipif
->sctp_ipif_saddr
,
973 &ipif
->sctp_ipif_saddr
) && sipif
->sctp_ipif_refcnt
> 0 &&
974 (!SCTP_IS_IPIF_LOOPBACK(ipif
) || ipif
->sctp_ipif_zoneid
==
975 sipif
->sctp_ipif_zoneid
)) {
977 * There can only be one address up at any time
978 * and we are here because ipif has been brought
981 ASSERT(sipif
->sctp_ipif_state
!= SCTP_IPIFS_UP
);
983 * Someone has a reference to this we need to update to
984 * point to the new sipif.
986 sctp_update_saddrs(sipif
, ipif
, hindex
, sctps
);
988 rw_exit(&sipif
->sctp_ipif_lock
);
989 sipif
= list_next(&sctps
->sctps_g_ipifs
[hindex
].sctp_ipif_list
,
995 * Insert a new SCTP ipif using 'ipif'. v6addr is the address that existed
996 * prior to the current address in 'ipif'. Only when an existing address
997 * is changed on an IPIF, will v6addr be specified. If the IPIF already
998 * exists in the global SCTP ipif table, then we either removed it, if
999 * it doesn't have any existing reference, or mark it condemned otherwise.
1000 * If an address is being brought up (IPIF_UP), then we need to scan
1001 * the SCTP list to check if there is any SCTP that points to the *same*
1002 * address on a different SCTP ipif and update in that case.
1005 sctp_update_ipif_addr(ipif_t
*ipif
, in6_addr_t v6addr
)
1007 ill_t
*ill
= ipif
->ipif_ill
;
1009 sctp_ill_t
*sctp_ill
;
1010 sctp_ill_t
*osctp_ill
;
1011 sctp_ipif_t
*sctp_ipif
= NULL
;
1012 sctp_ipif_t
*osctp_ipif
= NULL
;
1015 sctp_stack_t
*sctps
;
1017 sctps
= ipif
->ipif_ill
->ill_ipst
->ips_netstack
->netstack_sctp
;
1019 /* Index for new address */
1020 hindex
= SCTP_IPIF_ADDR_HASH(ipif
->ipif_v6lcl_addr
, ill
->ill_isv6
);
1023 * The address on this IPIF is changing, we need to look for
1024 * this old address and mark it condemned, before creating
1025 * one for the new address.
1027 osctp_ipif
= sctp_lookup_ipif_addr(&v6addr
, B_FALSE
,
1028 ipif
->ipif_zoneid
, B_TRUE
, SCTP_ILL_TO_PHYINDEX(ill
),
1029 ipif
->ipif_seqid
, B_FALSE
, sctps
);
1031 rw_enter(&sctps
->sctps_g_ills_lock
, RW_READER
);
1032 rw_enter(&sctps
->sctps_g_ipifs_lock
, RW_WRITER
);
1034 ill_index
= SCTP_ILL_HASH_FN(SCTP_ILL_TO_PHYINDEX(ill
));
1035 sctp_ill
= list_head(&sctps
->sctps_g_ills
[ill_index
].sctp_ill_list
);
1036 for (i
= 0; i
< sctps
->sctps_g_ills
[ill_index
].ill_count
; i
++) {
1037 if (sctp_ill
->sctp_ill_index
== SCTP_ILL_TO_PHYINDEX(ill
) &&
1038 sctp_ill
->sctp_ill_isv6
== ill
->ill_isv6
) {
1041 sctp_ill
= list_next(
1042 &sctps
->sctps_g_ills
[ill_index
].sctp_ill_list
, sctp_ill
);
1045 if (sctp_ill
== NULL
) {
1046 ip1dbg(("sctp_update_ipif_addr: ill not found ..\n"));
1047 rw_exit(&sctps
->sctps_g_ipifs_lock
);
1048 rw_exit(&sctps
->sctps_g_ills_lock
);
1052 if (osctp_ipif
!= NULL
) {
1054 /* The address is the same? */
1055 if (IN6_ARE_ADDR_EQUAL(&ipif
->ipif_v6lcl_addr
, &v6addr
)) {
1056 boolean_t chk_n_updt
= B_FALSE
;
1058 rw_downgrade(&sctps
->sctps_g_ipifs_lock
);
1059 rw_enter(&osctp_ipif
->sctp_ipif_lock
, RW_WRITER
);
1060 if (ipif
->ipif_flags
& IPIF_UP
&&
1061 osctp_ipif
->sctp_ipif_state
!= SCTP_IPIFS_UP
) {
1062 osctp_ipif
->sctp_ipif_state
= SCTP_IPIFS_UP
;
1063 chk_n_updt
= B_TRUE
;
1065 osctp_ipif
->sctp_ipif_state
= SCTP_IPIFS_DOWN
;
1067 osctp_ipif
->sctp_ipif_flags
= ipif
->ipif_flags
;
1068 rw_exit(&osctp_ipif
->sctp_ipif_lock
);
1070 sctp_chk_and_updt_saddr(hindex
, osctp_ipif
,
1073 rw_exit(&sctps
->sctps_g_ipifs_lock
);
1074 rw_exit(&sctps
->sctps_g_ills_lock
);
1078 * We are effectively removing this address from the ILL.
1080 if (osctp_ipif
->sctp_ipif_refcnt
!= 0) {
1081 osctp_ipif
->sctp_ipif_state
= SCTP_IPIFS_CONDEMNED
;
1086 osctp_ill
= osctp_ipif
->sctp_ipif_ill
;
1087 /* hash index for the old one */
1088 ohindex
= SCTP_IPIF_ADDR_HASH(
1089 osctp_ipif
->sctp_ipif_saddr
,
1090 osctp_ipif
->sctp_ipif_isv6
);
1093 &sctps
->sctps_g_ipifs
[ohindex
].sctp_ipif_list
;
1095 list_remove(ipif_list
, (void *)osctp_ipif
);
1096 sctps
->sctps_g_ipifs
[ohindex
].ipif_count
--;
1097 sctps
->sctps_g_ipifs_count
--;
1098 rw_destroy(&osctp_ipif
->sctp_ipif_lock
);
1099 kmem_free(osctp_ipif
, sizeof (sctp_ipif_t
));
1100 atomic_dec_32(&osctp_ill
->sctp_ill_ipifcnt
);
1104 sctp_ipif
= kmem_zalloc(sizeof (sctp_ipif_t
), KM_NOSLEEP
);
1106 if (sctp_ipif
== NULL
) {
1107 cmn_err(CE_WARN
, "sctp_update_ipif_addr: error adding "
1108 "IPIF %p to SCTP's IPIF list", (void *)ipif
);
1109 rw_exit(&sctps
->sctps_g_ipifs_lock
);
1110 rw_exit(&sctps
->sctps_g_ills_lock
);
1113 sctps
->sctps_g_ipifs_count
++;
1114 rw_init(&sctp_ipif
->sctp_ipif_lock
, NULL
, RW_DEFAULT
, NULL
);
1115 sctp_ipif
->sctp_ipif_saddr
= ipif
->ipif_v6lcl_addr
;
1116 sctp_ipif
->sctp_ipif_ill
= sctp_ill
;
1117 sctp_ipif
->sctp_ipif_isv6
= ill
->ill_isv6
;
1118 sctp_ipif
->sctp_ipif_zoneid
= ipif
->ipif_zoneid
;
1119 sctp_ipif
->sctp_ipif_id
= ipif
->ipif_seqid
;
1120 if (ipif
->ipif_flags
& IPIF_UP
)
1121 sctp_ipif
->sctp_ipif_state
= SCTP_IPIFS_UP
;
1123 sctp_ipif
->sctp_ipif_state
= SCTP_IPIFS_DOWN
;
1124 sctp_ipif
->sctp_ipif_flags
= ipif
->ipif_flags
;
1126 * We add it to the head so that it is quicker to find good/recent
1129 list_insert_head(&sctps
->sctps_g_ipifs
[hindex
].sctp_ipif_list
,
1131 sctps
->sctps_g_ipifs
[hindex
].ipif_count
++;
1132 atomic_inc_32(&sctp_ill
->sctp_ill_ipifcnt
);
1133 if (sctp_ipif
->sctp_ipif_state
== SCTP_IPIFS_UP
)
1134 sctp_chk_and_updt_saddr(hindex
, sctp_ipif
, sctps
);
1135 rw_exit(&sctps
->sctps_g_ipifs_lock
);
1136 rw_exit(&sctps
->sctps_g_ills_lock
);
1139 /* Insert, Remove, Mark up or Mark down the ipif */
1141 sctp_update_ipif(ipif_t
*ipif
, int op
)
1143 ill_t
*ill
= ipif
->ipif_ill
;
1145 sctp_ill_t
*sctp_ill
;
1146 sctp_ipif_t
*sctp_ipif
;
1149 netstack_t
*ns
= ipif
->ipif_ill
->ill_ipst
->ips_netstack
;
1150 sctp_stack_t
*sctps
= ns
->netstack_sctp
;
1152 ip2dbg(("sctp_update_ipif: %s %d\n", ill
->ill_name
, ipif
->ipif_seqid
));
1154 rw_enter(&sctps
->sctps_g_ills_lock
, RW_READER
);
1155 rw_enter(&sctps
->sctps_g_ipifs_lock
, RW_WRITER
);
1157 ill_index
= SCTP_ILL_HASH_FN(SCTP_ILL_TO_PHYINDEX(ill
));
1158 sctp_ill
= list_head(&sctps
->sctps_g_ills
[ill_index
].sctp_ill_list
);
1159 for (i
= 0; i
< sctps
->sctps_g_ills
[ill_index
].ill_count
; i
++) {
1160 if (sctp_ill
->sctp_ill_index
== SCTP_ILL_TO_PHYINDEX(ill
) &&
1161 sctp_ill
->sctp_ill_isv6
== ill
->ill_isv6
) {
1164 sctp_ill
= list_next(
1165 &sctps
->sctps_g_ills
[ill_index
].sctp_ill_list
, sctp_ill
);
1167 if (sctp_ill
== NULL
) {
1168 rw_exit(&sctps
->sctps_g_ipifs_lock
);
1169 rw_exit(&sctps
->sctps_g_ills_lock
);
1173 hindex
= SCTP_IPIF_ADDR_HASH(ipif
->ipif_v6lcl_addr
,
1174 ipif
->ipif_ill
->ill_isv6
);
1175 sctp_ipif
= list_head(&sctps
->sctps_g_ipifs
[hindex
].sctp_ipif_list
);
1176 for (i
= 0; i
< sctps
->sctps_g_ipifs
[hindex
].ipif_count
; i
++) {
1177 if (sctp_ipif
->sctp_ipif_id
== ipif
->ipif_seqid
) {
1178 ASSERT(IN6_ARE_ADDR_EQUAL(&sctp_ipif
->sctp_ipif_saddr
,
1179 &ipif
->ipif_v6lcl_addr
));
1182 sctp_ipif
= list_next(
1183 &sctps
->sctps_g_ipifs
[hindex
].sctp_ipif_list
,
1186 if (sctp_ipif
== NULL
) {
1187 ip1dbg(("sctp_update_ipif: null sctp_ipif for %d\n", op
));
1188 rw_exit(&sctps
->sctps_g_ipifs_lock
);
1189 rw_exit(&sctps
->sctps_g_ills_lock
);
1192 ASSERT(sctp_ill
== sctp_ipif
->sctp_ipif_ill
);
1194 case SCTP_IPIF_REMOVE
:
1199 ill_list
= &sctps
->sctps_g_ills
[ill_index
].sctp_ill_list
;
1200 ipif_list
= &sctps
->sctps_g_ipifs
[hindex
].sctp_ipif_list
;
1201 if (sctp_ipif
->sctp_ipif_refcnt
!= 0) {
1202 sctp_ipif
->sctp_ipif_state
= SCTP_IPIFS_CONDEMNED
;
1203 rw_exit(&sctps
->sctps_g_ipifs_lock
);
1204 rw_exit(&sctps
->sctps_g_ills_lock
);
1207 list_remove(ipif_list
, (void *)sctp_ipif
);
1208 sctps
->sctps_g_ipifs
[hindex
].ipif_count
--;
1209 sctps
->sctps_g_ipifs_count
--;
1210 rw_destroy(&sctp_ipif
->sctp_ipif_lock
);
1211 kmem_free(sctp_ipif
, sizeof (sctp_ipif_t
));
1212 atomic_dec_32(&sctp_ill
->sctp_ill_ipifcnt
);
1213 if (rw_tryupgrade(&sctps
->sctps_g_ills_lock
) != 0) {
1214 rw_downgrade(&sctps
->sctps_g_ipifs_lock
);
1215 if (sctp_ill
->sctp_ill_ipifcnt
== 0 &&
1216 sctp_ill
->sctp_ill_state
== SCTP_ILLS_CONDEMNED
) {
1217 list_remove(ill_list
, (void *)sctp_ill
);
1218 sctps
->sctps_ills_count
--;
1219 sctps
->sctps_g_ills
[ill_index
].ill_count
--;
1220 kmem_free(sctp_ill
->sctp_ill_name
,
1221 sctp_ill
->sctp_ill_name_length
);
1222 kmem_free(sctp_ill
, sizeof (sctp_ill_t
));
1230 rw_downgrade(&sctps
->sctps_g_ipifs_lock
);
1231 rw_enter(&sctp_ipif
->sctp_ipif_lock
, RW_WRITER
);
1232 sctp_ipif
->sctp_ipif_state
= SCTP_IPIFS_UP
;
1233 sctp_ipif
->sctp_ipif_flags
= ipif
->ipif_flags
;
1234 rw_exit(&sctp_ipif
->sctp_ipif_lock
);
1235 sctp_chk_and_updt_saddr(hindex
, sctp_ipif
,
1236 ipif
->ipif_ill
->ill_ipst
->ips_netstack
->netstack_sctp
);
1240 case SCTP_IPIF_UPDATE
:
1242 rw_downgrade(&sctps
->sctps_g_ipifs_lock
);
1243 rw_enter(&sctp_ipif
->sctp_ipif_lock
, RW_WRITER
);
1244 sctp_ipif
->sctp_ipif_zoneid
= ipif
->ipif_zoneid
;
1245 sctp_ipif
->sctp_ipif_flags
= ipif
->ipif_flags
;
1246 rw_exit(&sctp_ipif
->sctp_ipif_lock
);
1250 case SCTP_IPIF_DOWN
:
1252 rw_downgrade(&sctps
->sctps_g_ipifs_lock
);
1253 rw_enter(&sctp_ipif
->sctp_ipif_lock
, RW_WRITER
);
1254 sctp_ipif
->sctp_ipif_state
= SCTP_IPIFS_DOWN
;
1255 sctp_ipif
->sctp_ipif_flags
= ipif
->ipif_flags
;
1256 rw_exit(&sctp_ipif
->sctp_ipif_lock
);
1260 rw_exit(&sctps
->sctps_g_ipifs_lock
);
1261 rw_exit(&sctps
->sctps_g_ills_lock
);
1265 * SCTP source address list manipulaton, locking not used (except for
1266 * sctp locking by the caller.
1269 /* Remove a specific saddr from the list */
1271 sctp_del_saddr(sctp_t
*sctp
, sctp_saddr_ipif_t
*sp
)
1273 if (sctp
->sctp_conn_tfp
!= NULL
)
1274 mutex_enter(&sctp
->sctp_conn_tfp
->tf_lock
);
1276 if (sctp
->sctp_listen_tfp
!= NULL
)
1277 mutex_enter(&sctp
->sctp_listen_tfp
->tf_lock
);
1279 sctp_ipif_hash_remove(sctp
, sp
->saddr_ipifp
, B_FALSE
);
1281 if (sctp
->sctp_bound_to_all
== 1)
1282 sctp
->sctp_bound_to_all
= 0;
1284 if (sctp
->sctp_conn_tfp
!= NULL
)
1285 mutex_exit(&sctp
->sctp_conn_tfp
->tf_lock
);
1287 if (sctp
->sctp_listen_tfp
!= NULL
)
1288 mutex_exit(&sctp
->sctp_listen_tfp
->tf_lock
);
1292 * Delete source address from the existing list. No error checking done here
1293 * Called with no locks held.
1296 sctp_del_saddr_list(sctp_t
*sctp
, const void *addrs
, int addcnt
,
1297 boolean_t fanout_locked
)
1299 struct sockaddr_in
*sin4
;
1300 struct sockaddr_in6
*sin6
;
1303 sctp_ipif_t
*sctp_ipif
;
1305 conn_t
*connp
= sctp
->sctp_connp
;
1307 ASSERT(sctp
->sctp_nsaddrs
>= addcnt
);
1309 if (!fanout_locked
) {
1310 if (sctp
->sctp_conn_tfp
!= NULL
)
1311 mutex_enter(&sctp
->sctp_conn_tfp
->tf_lock
);
1312 if (sctp
->sctp_listen_tfp
!= NULL
)
1313 mutex_enter(&sctp
->sctp_listen_tfp
->tf_lock
);
1316 for (cnt
= 0; cnt
< addcnt
; cnt
++) {
1317 switch (connp
->conn_family
) {
1319 sin4
= (struct sockaddr_in
*)addrs
+ cnt
;
1320 IN6_INADDR_TO_V4MAPPED(&sin4
->sin_addr
, &addr
);
1324 sin6
= (struct sockaddr_in6
*)addrs
+ cnt
;
1325 addr
= sin6
->sin6_addr
;
1326 ifindex
= sin6
->sin6_scope_id
;
1329 sctp_ipif
= sctp_lookup_ipif_addr(&addr
, B_FALSE
,
1330 IPCL_ZONEID(connp
), !connp
->conn_allzones
,
1331 ifindex
, 0, B_TRUE
, sctp
->sctp_sctps
);
1332 ASSERT(sctp_ipif
!= NULL
);
1333 sctp_ipif_hash_remove(sctp
, sctp_ipif
, B_FALSE
);
1335 if (sctp
->sctp_bound_to_all
== 1)
1336 sctp
->sctp_bound_to_all
= 0;
1338 if (!fanout_locked
) {
1339 if (sctp
->sctp_conn_tfp
!= NULL
)
1340 mutex_exit(&sctp
->sctp_conn_tfp
->tf_lock
);
1341 if (sctp
->sctp_listen_tfp
!= NULL
)
1342 mutex_exit(&sctp
->sctp_listen_tfp
->tf_lock
);
1347 * Given an address get the corresponding entry from the list
1348 * Called with no locks held.
1351 sctp_saddr_lookup(sctp_t
*sctp
, in6_addr_t
*addr
, uint_t ifindex
)
1354 sctp_saddr_ipif_t
*ipif_obj
;
1356 sctp_ipif_t
*sctp_ipif
;
1358 hindex
= SCTP_IPIF_ADDR_HASH(*addr
, !IN6_IS_ADDR_V4MAPPED(addr
));
1359 rw_enter(&sctp
->sctp_saddrs
[hindex
].ipif_hash_lock
, RW_READER
);
1360 if (sctp
->sctp_saddrs
[hindex
].ipif_count
== 0) {
1361 rw_exit(&sctp
->sctp_saddrs
[hindex
].ipif_hash_lock
);
1365 ipif_obj
= list_head(&sctp
->sctp_saddrs
[hindex
].sctp_ipif_list
);
1366 for (cnt
= 0; cnt
< sctp
->sctp_saddrs
[hindex
].ipif_count
; cnt
++) {
1367 sctp_ipif
= ipif_obj
->saddr_ipifp
;
1369 * Zone check shouldn't be needed.
1371 if (IN6_ARE_ADDR_EQUAL(addr
, &sctp_ipif
->sctp_ipif_saddr
) &&
1373 ifindex
== sctp_ipif
->sctp_ipif_ill
->sctp_ill_index
) &&
1374 SCTP_IPIF_USABLE(sctp_ipif
->sctp_ipif_state
)) {
1375 rw_exit(&sctp
->sctp_saddrs
[hindex
].ipif_hash_lock
);
1378 ipif_obj
= list_next(&sctp
->sctp_saddrs
[hindex
].sctp_ipif_list
,
1381 rw_exit(&sctp
->sctp_saddrs
[hindex
].ipif_hash_lock
);
1385 /* Given an address, add it to the source address list */
1387 sctp_saddr_add_addr(sctp_t
*sctp
, in6_addr_t
*addr
, uint_t ifindex
)
1389 sctp_ipif_t
*sctp_ipif
;
1390 conn_t
*connp
= sctp
->sctp_connp
;
1392 sctp_ipif
= sctp_lookup_ipif_addr(addr
, B_TRUE
, IPCL_ZONEID(connp
),
1393 !connp
->conn_allzones
, ifindex
, 0, B_TRUE
, sctp
->sctp_sctps
);
1394 if (sctp_ipif
== NULL
)
1397 if (sctp_ipif_hash_insert(sctp
, sctp_ipif
, KM_NOSLEEP
, B_FALSE
,
1399 SCTP_IPIF_REFRELE(sctp_ipif
);
1406 * Remove or mark as dontsrc addresses that are currently not part of the
1407 * association. One would delete addresses when processing an INIT and
1408 * mark as dontsrc when processing an INIT-ACK.
1411 sctp_check_saddr(sctp_t
*sctp
, int supp_af
, boolean_t
delete,
1412 in6_addr_t
*no_del_addr
)
1416 sctp_saddr_ipif_t
*obj
;
1420 conn_t
*connp
= sctp
->sctp_connp
;
1422 ASSERT(!sctp
->sctp_loopback
&& !sctp
->sctp_linklocal
&& supp_af
!= 0);
1425 * Irregardless of the supported address in the INIT, v4
1426 * must be supported.
1428 if (connp
->conn_family
== AF_INET
)
1429 supp_af
= PARM_SUPP_V4
;
1431 nsaddr
= sctp
->sctp_nsaddrs
;
1432 for (i
= 0; i
< SCTP_IPIF_HASH
; i
++) {
1433 rw_enter(&sctp
->sctp_saddrs
[i
].ipif_hash_lock
, RW_WRITER
);
1434 if (sctp
->sctp_saddrs
[i
].ipif_count
== 0) {
1435 rw_exit(&sctp
->sctp_saddrs
[i
].ipif_hash_lock
);
1438 obj
= list_head(&sctp
->sctp_saddrs
[i
].sctp_ipif_list
);
1439 naddr
= sctp
->sctp_saddrs
[i
].ipif_count
;
1440 for (l
= 0; l
< naddr
; l
++) {
1443 ipif
= obj
->saddr_ipifp
;
1446 if (IN6_ARE_ADDR_EQUAL(&ipif
->sctp_ipif_saddr
,
1452 * Delete/mark dontsrc loopback/linklocal addresses and
1453 * unsupported address.
1454 * On a clustered node, we trust the clustering module
1455 * to do the right thing w.r.t loopback addresses, so
1456 * we ignore loopback addresses in this check.
1458 if ((SCTP_IS_IPIF_LOOPBACK(ipif
) &&
1459 cl_sctp_check_addrs
== NULL
) ||
1460 SCTP_IS_IPIF_LINKLOCAL(ipif
) ||
1461 SCTP_UNSUPP_AF(ipif
, supp_af
)) {
1463 obj
->saddr_ipif_unconfirmed
= 1;
1466 if (sctp
->sctp_bound_to_all
== 1)
1467 sctp
->sctp_bound_to_all
= 0;
1468 if (scanned
< nsaddr
) {
1469 obj
= list_next(&sctp
->sctp_saddrs
[i
].
1470 sctp_ipif_list
, obj
);
1471 sctp_ipif_hash_remove(sctp
, ipif
,
1475 sctp_ipif_hash_remove(sctp
, ipif
, B_TRUE
);
1478 if (scanned
>= nsaddr
) {
1479 rw_exit(&sctp
->sctp_saddrs
[i
].ipif_hash_lock
);
1482 obj
= list_next(&sctp
->sctp_saddrs
[i
].sctp_ipif_list
,
1485 rw_exit(&sctp
->sctp_saddrs
[i
].ipif_hash_lock
);
1490 /* Get the first valid address from the list. Called with no locks held */
1492 sctp_get_valid_addr(sctp_t
*sctp
, boolean_t isv6
, boolean_t
*addr_set
)
1496 sctp_saddr_ipif_t
*obj
;
1500 for (i
= 0; i
< SCTP_IPIF_HASH
; i
++) {
1501 rw_enter(&sctp
->sctp_saddrs
[i
].ipif_hash_lock
, RW_READER
);
1502 if (sctp
->sctp_saddrs
[i
].ipif_count
== 0) {
1503 rw_exit(&sctp
->sctp_saddrs
[i
].ipif_hash_lock
);
1506 obj
= list_head(&sctp
->sctp_saddrs
[i
].sctp_ipif_list
);
1507 for (l
= 0; l
< sctp
->sctp_saddrs
[i
].ipif_count
; l
++) {
1510 ipif
= obj
->saddr_ipifp
;
1511 if (!SCTP_DONT_SRC(obj
) &&
1512 ipif
->sctp_ipif_isv6
== isv6
&&
1513 ipif
->sctp_ipif_state
== SCTP_IPIFS_UP
) {
1515 rw_exit(&sctp
->sctp_saddrs
[i
].ipif_hash_lock
);
1516 return (ipif
->sctp_ipif_saddr
);
1519 if (scanned
>= sctp
->sctp_nsaddrs
) {
1520 rw_exit(&sctp
->sctp_saddrs
[i
].ipif_hash_lock
);
1523 obj
= list_next(&sctp
->sctp_saddrs
[i
].sctp_ipif_list
,
1526 rw_exit(&sctp
->sctp_saddrs
[i
].ipif_hash_lock
);
1529 /* Need to double check this */
1531 addr
= ipv6_all_zeros
;
1533 IN6_IPADDR_TO_V4MAPPED(0, &addr
);
1534 *addr_set
= B_FALSE
;
1539 * Return the list of local addresses of an association. The parameter
1540 * myaddrs is supposed to be either (struct sockaddr_in *) or (struct
1541 * sockaddr_in6 *) depending on the address family.
1544 sctp_getmyaddrs(void *conn
, void *myaddrs
, int *addrcnt
)
1548 sctp_saddr_ipif_t
*obj
;
1549 sctp_t
*sctp
= (sctp_t
*)conn
;
1550 conn_t
*connp
= sctp
->sctp_connp
;
1551 int family
= connp
->conn_family
;
1554 struct sockaddr_in6
*sin6
;
1555 struct sockaddr_in
*sin4
;
1557 boolean_t skip_lback
= B_FALSE
;
1558 ip_xmit_attr_t
*ixa
= connp
->conn_ixa
;
1560 if (sctp
->sctp_nsaddrs
== 0)
1564 * Skip loopback addresses for non-loopback assoc., ignore
1565 * this on a clustered node.
1567 if (sctp
->sctp_state
>= SCTPS_ESTABLISHED
&& !sctp
->sctp_loopback
&&
1568 (cl_sctp_check_addrs
== NULL
)) {
1569 skip_lback
= B_TRUE
;
1572 for (i
= 0; i
< SCTP_IPIF_HASH
; i
++) {
1573 rw_enter(&sctp
->sctp_saddrs
[i
].ipif_hash_lock
, RW_READER
);
1574 if (sctp
->sctp_saddrs
[i
].ipif_count
== 0) {
1575 rw_exit(&sctp
->sctp_saddrs
[i
].ipif_hash_lock
);
1578 obj
= list_head(&sctp
->sctp_saddrs
[i
].sctp_ipif_list
);
1579 for (l
= 0; l
< sctp
->sctp_saddrs
[i
].ipif_count
; l
++) {
1580 sctp_ipif_t
*ipif
= obj
->saddr_ipifp
;
1581 in6_addr_t addr
= ipif
->sctp_ipif_saddr
;
1584 if ((ipif
->sctp_ipif_state
== SCTP_IPIFS_CONDEMNED
) ||
1585 SCTP_DONT_SRC(obj
) ||
1586 (SCTP_IS_IPIF_LOOPBACK(ipif
) && skip_lback
)) {
1587 if (scanned
>= sctp
->sctp_nsaddrs
) {
1589 sctp_saddrs
[i
].ipif_hash_lock
);
1592 obj
= list_next(&sctp
->sctp_saddrs
[i
].
1593 sctp_ipif_list
, obj
);
1598 sin4
= (struct sockaddr_in
*)myaddrs
+ added
;
1599 sin4
->sin_family
= AF_INET
;
1600 sin4
->sin_port
= connp
->conn_lport
;
1601 IN6_V4MAPPED_TO_INADDR(&addr
, &sin4
->sin_addr
);
1605 sin6
= (struct sockaddr_in6
*)myaddrs
+ added
;
1606 sin6
->sin6_family
= AF_INET6
;
1607 sin6
->sin6_port
= connp
->conn_lport
;
1608 sin6
->sin6_addr
= addr
;
1610 * Note that flowinfo is only returned for
1611 * getpeername just like for TCP and UDP.
1613 sin6
->sin6_flowinfo
= 0;
1615 if (IN6_IS_ADDR_LINKSCOPE(&sin6
->sin6_addr
) &&
1616 (ixa
->ixa_flags
& IXAF_SCOPEID_SET
))
1617 sin6
->sin6_scope_id
= ixa
->ixa_scopeid
;
1619 sin6
->sin6_scope_id
= 0;
1620 sin6
->__sin6_src_id
= 0;
1624 if (added
>= max
|| scanned
>= sctp
->sctp_nsaddrs
) {
1625 rw_exit(&sctp
->sctp_saddrs
[i
].ipif_hash_lock
);
1628 obj
= list_next(&sctp
->sctp_saddrs
[i
].sctp_ipif_list
,
1631 rw_exit(&sctp
->sctp_saddrs
[i
].ipif_hash_lock
);
1639 * Given the supported address family, walk through the source address list
1640 * and return the total length of the available addresses. If 'p' is not
1641 * null, construct the parameter list for the addresses in 'p'.
1642 * 'modify' will only be set when we want the source address list to
1643 * be modified. The source address list will be modified only when
1644 * generating an INIT chunk. For generating an INIT-ACK 'modify' will
1645 * be false since the 'sctp' will be that of the listener.
1648 sctp_saddr_info(sctp_t
*sctp
, int supp_af
, uchar_t
*p
, boolean_t modify
)
1652 sctp_saddr_ipif_t
*obj
;
1653 size_t paramlen
= 0;
1654 sctp_parm_hdr_t
*hdr
;
1658 boolean_t del_ll
= B_FALSE
;
1659 boolean_t del_lb
= B_FALSE
;
1663 * On a clustered node don't bother changing anything
1664 * on the loopback interface.
1666 if (modify
&& !sctp
->sctp_loopback
&& (cl_sctp_check_addrs
== NULL
))
1669 if (modify
&& !sctp
->sctp_linklocal
)
1672 nsaddr
= sctp
->sctp_nsaddrs
;
1673 for (i
= 0; i
< SCTP_IPIF_HASH
; i
++) {
1674 rw_enter(&sctp
->sctp_saddrs
[i
].ipif_hash_lock
, RW_WRITER
);
1675 if (sctp
->sctp_saddrs
[i
].ipif_count
== 0) {
1676 rw_exit(&sctp
->sctp_saddrs
[i
].ipif_hash_lock
);
1679 obj
= list_head(&sctp
->sctp_saddrs
[i
].sctp_ipif_list
);
1680 naddr
= sctp
->sctp_saddrs
[i
].ipif_count
;
1681 for (l
= 0; l
< naddr
; l
++) {
1686 boolean_t unsupp_af
;
1688 ipif
= obj
->saddr_ipifp
;
1691 ipif_lb
= SCTP_IS_IPIF_LOOPBACK(ipif
);
1692 ipif_ll
= SCTP_IS_IPIF_LINKLOCAL(ipif
);
1693 unsupp_af
= SCTP_UNSUPP_AF(ipif
, supp_af
);
1695 * We need to either delete or skip loopback/linklocal
1696 * or unsupported addresses, if required.
1698 if ((ipif_ll
&& del_ll
) || (ipif_lb
&& del_lb
) ||
1699 (unsupp_af
&& modify
)) {
1700 if (sctp
->sctp_bound_to_all
== 1)
1701 sctp
->sctp_bound_to_all
= 0;
1702 if (scanned
< nsaddr
) {
1703 obj
= list_next(&sctp
->sctp_saddrs
[i
].
1704 sctp_ipif_list
, obj
);
1705 sctp_ipif_hash_remove(sctp
, ipif
,
1709 sctp_ipif_hash_remove(sctp
, ipif
, B_TRUE
);
1712 } else if (ipif_ll
|| unsupp_af
||
1713 (ipif_lb
&& (cl_sctp_check_addrs
== NULL
))) {
1717 if (!SCTP_IPIF_USABLE(ipif
->sctp_ipif_state
))
1720 hdr
= (sctp_parm_hdr_t
*)(p
+ paramlen
);
1721 addr
= ipif
->sctp_ipif_saddr
;
1722 if (!ipif
->sctp_ipif_isv6
) {
1726 hdr
->sph_type
= htons(PARM_ADDR4
);
1727 hdr
->sph_len
= htons(PARM_ADDR4_LEN
);
1728 v4
= (struct in_addr
*)(hdr
+ 1);
1729 IN6_V4MAPPED_TO_INADDR(&addr
, v4
);
1731 paramlen
+= PARM_ADDR4_LEN
;
1734 hdr
->sph_type
= htons(PARM_ADDR6
);
1735 hdr
->sph_len
= htons(PARM_ADDR6_LEN
);
1736 bcopy(&addr
, hdr
+ 1, sizeof (addr
));
1738 paramlen
+= PARM_ADDR6_LEN
;
1741 if (scanned
>= nsaddr
) {
1742 rw_exit(&sctp
->sctp_saddrs
[i
].ipif_hash_lock
);
1745 obj
= list_next(&sctp
->sctp_saddrs
[i
].sctp_ipif_list
,
1748 rw_exit(&sctp
->sctp_saddrs
[i
].ipif_hash_lock
);
1754 * This is used on a clustered node to obtain a list of addresses, the list
1755 * consists of sockaddr_in structs for v4 and sockaddr_in6 for v6. The list
1756 * is then passed onto the clustering module which sends back the correct
1757 * list based on the port info. Regardless of the input, i.e INADDR_ANY
1758 * or specific address(es), we create the list since it could be modified by
1759 * the clustering module. When given a list of addresses, we simply
1760 * create the list of sockaddr_in or sockaddr_in6 structs using those
1761 * addresses. If there is an INADDR_ANY in the input list, or if the
1762 * input is INADDR_ANY, we create a list of sockaddr_in or sockaddr_in6
1763 * structs consisting all the addresses in the global interface list
1764 * except those that are hosted on the loopback interface. We create
1765 * a list of sockaddr_in[6] structs just so that it can be directly input
1766 * to sctp_valid_addr_list() once the clustering module has processed it.
1769 sctp_get_addrlist(sctp_t
*sctp
, const void *addrs
, uint32_t *addrcnt
,
1770 uchar_t
**addrlist
, int *uspec
, size_t *size
)
1774 sctp_ipif_t
*sctp_ipif
;
1775 struct sockaddr_in
*s4
;
1776 struct sockaddr_in6
*s6
;
1779 sctp_stack_t
*sctps
= sctp
->sctp_sctps
;
1780 conn_t
*connp
= sctp
->sctp_connp
;
1786 * Create a list of sockaddr_in[6] structs using the input list.
1788 if (connp
->conn_family
== AF_INET
) {
1789 *size
= sizeof (struct sockaddr_in
) * *addrcnt
;
1790 *addrlist
= kmem_zalloc(*size
, KM_SLEEP
);
1792 for (cnt
= 0; cnt
< *addrcnt
; cnt
++) {
1793 s4
= (struct sockaddr_in
*)addrs
+ cnt
;
1795 * We need to create a list of all the available
1796 * addresses if there is an INADDR_ANY. However,
1797 * if we are beyond LISTEN, then this is invalid
1798 * (see sctp_valid_addr_list(). So, we just fail
1799 * it here rather than wait till it fails in
1800 * sctp_valid_addr_list().
1802 if (s4
->sin_addr
.s_addr
== INADDR_ANY
) {
1803 kmem_free(*addrlist
, *size
);
1806 if (sctp
->sctp_state
> SCTPS_LISTEN
) {
1814 bcopy(s4
, p
, sizeof (*s4
));
1819 *size
= sizeof (struct sockaddr_in6
) * *addrcnt
;
1820 *addrlist
= kmem_zalloc(*size
, KM_SLEEP
);
1822 for (cnt
= 0; cnt
< *addrcnt
; cnt
++) {
1823 s6
= (struct sockaddr_in6
*)addrs
+ cnt
;
1825 * Comments for INADDR_ANY, above, apply here too.
1827 if (IN6_IS_ADDR_UNSPECIFIED(&s6
->sin6_addr
)) {
1828 kmem_free(*addrlist
, *size
);
1831 if (sctp
->sctp_state
> SCTPS_LISTEN
) {
1839 bcopy(addrs
, p
, sizeof (*s6
));
1848 * Allocate max possible size. We allocate the max. size here because
1849 * the clustering module could end up adding addresses to the list.
1850 * We allocate upfront so that the clustering module need to bother
1851 * re-sizing the list.
1853 if (connp
->conn_family
== AF_INET
) {
1854 *size
= sizeof (struct sockaddr_in
) *
1855 sctps
->sctps_g_ipifs_count
;
1857 *size
= sizeof (struct sockaddr_in6
) *
1858 sctps
->sctps_g_ipifs_count
;
1860 *addrlist
= kmem_zalloc(*size
, KM_SLEEP
);
1863 rw_enter(&sctps
->sctps_g_ipifs_lock
, RW_READER
);
1866 * Walk through the global interface list and add all addresses,
1867 * except those that are hosted on loopback interfaces.
1869 for (cnt
= 0; cnt
< SCTP_IPIF_HASH
; cnt
++) {
1870 if (sctps
->sctps_g_ipifs
[cnt
].ipif_count
== 0)
1872 sctp_ipif
= list_head(
1873 &sctps
->sctps_g_ipifs
[cnt
].sctp_ipif_list
);
1875 icnt
< sctps
->sctps_g_ipifs
[cnt
].ipif_count
;
1879 rw_enter(&sctp_ipif
->sctp_ipif_lock
, RW_READER
);
1880 addr
= sctp_ipif
->sctp_ipif_saddr
;
1881 if (SCTP_IPIF_DISCARD(sctp_ipif
->sctp_ipif_flags
) ||
1882 !SCTP_IPIF_USABLE(sctp_ipif
->sctp_ipif_state
) ||
1883 SCTP_IS_IPIF_LOOPBACK(sctp_ipif
) ||
1884 SCTP_IS_IPIF_LINKLOCAL(sctp_ipif
) ||
1885 !SCTP_IPIF_ZONE_MATCH(sctp
, sctp_ipif
) ||
1886 (connp
->conn_family
== AF_INET
&&
1887 sctp_ipif
->sctp_ipif_isv6
) ||
1888 (sctp
->sctp_connp
->conn_ipv6_v6only
&&
1889 !sctp_ipif
->sctp_ipif_isv6
)) {
1890 rw_exit(&sctp_ipif
->sctp_ipif_lock
);
1891 sctp_ipif
= list_next(
1892 &sctps
->sctps_g_ipifs
[cnt
].sctp_ipif_list
,
1896 rw_exit(&sctp_ipif
->sctp_ipif_lock
);
1897 if (connp
->conn_family
== AF_INET
) {
1898 s4
= (struct sockaddr_in
*)p
;
1899 IN6_V4MAPPED_TO_INADDR(&addr
, &s4
->sin_addr
);
1900 s4
->sin_family
= AF_INET
;
1903 s6
= (struct sockaddr_in6
*)p
;
1904 s6
->sin6_addr
= addr
;
1905 s6
->sin6_family
= AF_INET6
;
1907 sctp_ipif
->sctp_ipif_ill
->sctp_ill_index
;
1911 sctp_ipif
= list_next(
1912 &sctps
->sctps_g_ipifs
[cnt
].sctp_ipif_list
,
1916 rw_exit(&sctps
->sctps_g_ipifs_lock
);
1921 * Get a list of addresses from the source address list. The caller is
1922 * responsible for allocating sufficient buffer for this.
1925 sctp_get_saddr_list(sctp_t
*sctp
, uchar_t
*p
, size_t psize
)
1929 sctp_saddr_ipif_t
*obj
;
1933 for (cnt
= 0; cnt
< SCTP_IPIF_HASH
; cnt
++) {
1934 rw_enter(&sctp
->sctp_saddrs
[cnt
].ipif_hash_lock
, RW_READER
);
1935 if (sctp
->sctp_saddrs
[cnt
].ipif_count
== 0) {
1936 rw_exit(&sctp
->sctp_saddrs
[cnt
].ipif_hash_lock
);
1939 obj
= list_head(&sctp
->sctp_saddrs
[cnt
].sctp_ipif_list
);
1940 naddr
= sctp
->sctp_saddrs
[cnt
].ipif_count
;
1941 for (icnt
= 0; icnt
< naddr
; icnt
++) {
1944 if (psize
< sizeof (ipif
->sctp_ipif_saddr
)) {
1945 rw_exit(&sctp
->sctp_saddrs
[cnt
].ipif_hash_lock
);
1950 ipif
= obj
->saddr_ipifp
;
1951 bcopy(&ipif
->sctp_ipif_saddr
, p
,
1952 sizeof (ipif
->sctp_ipif_saddr
));
1953 p
+= sizeof (ipif
->sctp_ipif_saddr
);
1954 psize
-= sizeof (ipif
->sctp_ipif_saddr
);
1955 if (scanned
>= sctp
->sctp_nsaddrs
) {
1956 rw_exit(&sctp
->sctp_saddrs
[cnt
].ipif_hash_lock
);
1960 &sctp
->sctp_saddrs
[icnt
].sctp_ipif_list
,
1963 rw_exit(&sctp
->sctp_saddrs
[cnt
].ipif_hash_lock
);
1968 * Get a list of addresses from the remote address list. The caller is
1969 * responsible for allocating sufficient buffer for this.
1972 sctp_get_faddr_list(sctp_t
*sctp
, uchar_t
*p
, size_t psize
)
1976 for (fp
= sctp
->sctp_faddrs
; fp
!= NULL
; fp
= fp
->sf_next
) {
1977 if (psize
< sizeof (fp
->sf_faddr
))
1979 bcopy(&fp
->sf_faddr
, p
, sizeof (fp
->sf_faddr
));
1980 p
+= sizeof (fp
->sf_faddr
);
1981 psize
-= sizeof (fp
->sf_faddr
);
1986 sctp_free_ills(sctp_stack_t
*sctps
)
1990 sctp_ill_t
*sctp_ill
;
1992 if (sctps
->sctps_ills_count
== 0)
1995 for (i
= 0; i
< SCTP_ILL_HASH
; i
++) {
1996 sctp_ill
= list_tail(&sctps
->sctps_g_ills
[i
].sctp_ill_list
);
1997 for (l
= 0; l
< sctps
->sctps_g_ills
[i
].ill_count
; l
++) {
1998 ASSERT(sctp_ill
->sctp_ill_ipifcnt
== 0);
1999 list_remove(&sctps
->sctps_g_ills
[i
].sctp_ill_list
,
2001 sctps
->sctps_ills_count
--;
2002 kmem_free(sctp_ill
->sctp_ill_name
,
2003 sctp_ill
->sctp_ill_name_length
);
2004 kmem_free(sctp_ill
, sizeof (sctp_ill_t
));
2006 list_tail(&sctps
->sctps_g_ills
[i
].sctp_ill_list
);
2008 sctps
->sctps_g_ills
[i
].ill_count
= 0;
2010 ASSERT(sctps
->sctps_ills_count
== 0);
2014 sctp_free_ipifs(sctp_stack_t
*sctps
)
2018 sctp_ipif_t
*sctp_ipif
;
2019 sctp_ill_t
*sctp_ill
;
2021 if (sctps
->sctps_g_ipifs_count
== 0)
2024 for (i
= 0; i
< SCTP_IPIF_HASH
; i
++) {
2025 sctp_ipif
= list_tail(&sctps
->sctps_g_ipifs
[i
].sctp_ipif_list
);
2026 for (l
= 0; l
< sctps
->sctps_g_ipifs
[i
].ipif_count
; l
++) {
2027 sctp_ill
= sctp_ipif
->sctp_ipif_ill
;
2029 list_remove(&sctps
->sctps_g_ipifs
[i
].sctp_ipif_list
,
2031 sctps
->sctps_g_ipifs_count
--;
2032 atomic_dec_32(&sctp_ill
->sctp_ill_ipifcnt
);
2033 kmem_free(sctp_ipif
, sizeof (sctp_ipif_t
));
2035 list_tail(&sctps
->sctps_g_ipifs
[i
].sctp_ipif_list
);
2037 sctps
->sctps_g_ipifs
[i
].ipif_count
= 0;
2039 ASSERT(sctps
->sctps_g_ipifs_count
== 0);
2043 /* Initialize the SCTP ILL list and lock */
2045 sctp_saddr_init(sctp_stack_t
*sctps
)
2049 sctps
->sctps_g_ills
= kmem_zalloc(sizeof (sctp_ill_hash_t
) *
2050 SCTP_ILL_HASH
, KM_SLEEP
);
2051 sctps
->sctps_g_ipifs
= kmem_zalloc(sizeof (sctp_ipif_hash_t
) *
2052 SCTP_IPIF_HASH
, KM_SLEEP
);
2054 rw_init(&sctps
->sctps_g_ills_lock
, NULL
, RW_DEFAULT
, NULL
);
2055 rw_init(&sctps
->sctps_g_ipifs_lock
, NULL
, RW_DEFAULT
, NULL
);
2057 for (i
= 0; i
< SCTP_ILL_HASH
; i
++) {
2058 sctps
->sctps_g_ills
[i
].ill_count
= 0;
2059 list_create(&sctps
->sctps_g_ills
[i
].sctp_ill_list
,
2060 sizeof (sctp_ill_t
),
2061 offsetof(sctp_ill_t
, sctp_ills
));
2063 for (i
= 0; i
< SCTP_IPIF_HASH
; i
++) {
2064 sctps
->sctps_g_ipifs
[i
].ipif_count
= 0;
2065 list_create(&sctps
->sctps_g_ipifs
[i
].sctp_ipif_list
,
2066 sizeof (sctp_ipif_t
), offsetof(sctp_ipif_t
, sctp_ipifs
));
2071 sctp_saddr_fini(sctp_stack_t
*sctps
)
2075 sctp_free_ipifs(sctps
);
2076 sctp_free_ills(sctps
);
2078 for (i
= 0; i
< SCTP_ILL_HASH
; i
++)
2079 list_destroy(&sctps
->sctps_g_ills
[i
].sctp_ill_list
);
2080 for (i
= 0; i
< SCTP_IPIF_HASH
; i
++)
2081 list_destroy(&sctps
->sctps_g_ipifs
[i
].sctp_ipif_list
);
2083 ASSERT(sctps
->sctps_ills_count
== 0 && sctps
->sctps_g_ipifs_count
== 0);
2084 kmem_free(sctps
->sctps_g_ills
, sizeof (sctp_ill_hash_t
) *
2086 sctps
->sctps_g_ills
= NULL
;
2087 kmem_free(sctps
->sctps_g_ipifs
, sizeof (sctp_ipif_hash_t
) *
2089 sctps
->sctps_g_ipifs
= NULL
;
2090 rw_destroy(&sctps
->sctps_g_ills_lock
);
2091 rw_destroy(&sctps
->sctps_g_ipifs_lock
);