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]
23 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
26 #include <sys/sysmacros.h>
27 #include <sys/socket.h>
29 #include <sys/sunddi.h>
30 #include <sys/tsol/tndb.h>
31 #include <sys/tsol/tnet.h>
33 #include <netinet/in.h>
34 #include <netinet/ip6.h>
36 #include <inet/common.h>
39 #include <inet/ipclassifier.h>
40 #include <inet/ipsec_impl.h>
41 #include <inet/ipp_common.h>
42 #include <inet/sctp_ip.h>
44 #include "sctp_impl.h"
45 #include "sctp_addr.h"
47 /* Default association hash size. The size must be a power of 2. */
48 #define SCTP_CONN_HASH_SIZE 8192
50 uint_t sctp_conn_hash_size
= SCTP_CONN_HASH_SIZE
; /* /etc/system */
53 * Cluster networking hook for traversing current assoc list.
54 * This routine is used to extract the current list of live associations
55 * which must continue to to be dispatched to this node.
57 int cl_sctp_walk_list(int (*cl_callback
)(cl_sctp_info_t
*, void *), void *,
59 static int cl_sctp_walk_list_stack(int (*cl_callback
)(cl_sctp_info_t
*,
60 void *), void *arg
, boolean_t cansleep
, sctp_stack_t
*sctps
);
63 sctp_hash_init(sctp_stack_t
*sctps
)
67 /* Start with /etc/system value */
68 sctps
->sctps_conn_hash_size
= sctp_conn_hash_size
;
70 if (!ISP2(sctps
->sctps_conn_hash_size
)) {
71 /* Not a power of two. Round up to nearest power of two */
72 for (i
= 0; i
< 31; i
++) {
73 if (sctps
->sctps_conn_hash_size
< (1 << i
))
76 sctps
->sctps_conn_hash_size
= 1 << i
;
78 if (sctps
->sctps_conn_hash_size
< SCTP_CONN_HASH_SIZE
) {
79 sctps
->sctps_conn_hash_size
= SCTP_CONN_HASH_SIZE
;
80 cmn_err(CE_CONT
, "using sctp_conn_hash_size = %u\n",
81 sctps
->sctps_conn_hash_size
);
83 sctps
->sctps_conn_fanout
=
84 (sctp_tf_t
*)kmem_zalloc(sctps
->sctps_conn_hash_size
*
85 sizeof (sctp_tf_t
), KM_SLEEP
);
86 for (i
= 0; i
< sctps
->sctps_conn_hash_size
; i
++) {
87 mutex_init(&sctps
->sctps_conn_fanout
[i
].tf_lock
, NULL
,
90 sctps
->sctps_listen_fanout
= kmem_zalloc(SCTP_LISTEN_FANOUT_SIZE
*
91 sizeof (sctp_tf_t
), KM_SLEEP
);
92 for (i
= 0; i
< SCTP_LISTEN_FANOUT_SIZE
; i
++) {
93 mutex_init(&sctps
->sctps_listen_fanout
[i
].tf_lock
, NULL
,
96 sctps
->sctps_bind_fanout
= kmem_zalloc(SCTP_BIND_FANOUT_SIZE
*
97 sizeof (sctp_tf_t
), KM_SLEEP
);
98 for (i
= 0; i
< SCTP_BIND_FANOUT_SIZE
; i
++) {
99 mutex_init(&sctps
->sctps_bind_fanout
[i
].tf_lock
, NULL
,
100 MUTEX_DEFAULT
, NULL
);
105 sctp_hash_destroy(sctp_stack_t
*sctps
)
109 for (i
= 0; i
< sctps
->sctps_conn_hash_size
; i
++) {
110 mutex_destroy(&sctps
->sctps_conn_fanout
[i
].tf_lock
);
112 kmem_free(sctps
->sctps_conn_fanout
, sctps
->sctps_conn_hash_size
*
114 sctps
->sctps_conn_fanout
= NULL
;
116 for (i
= 0; i
< SCTP_LISTEN_FANOUT_SIZE
; i
++) {
117 mutex_destroy(&sctps
->sctps_listen_fanout
[i
].tf_lock
);
119 kmem_free(sctps
->sctps_listen_fanout
, SCTP_LISTEN_FANOUT_SIZE
*
121 sctps
->sctps_listen_fanout
= NULL
;
123 for (i
= 0; i
< SCTP_BIND_FANOUT_SIZE
; i
++) {
124 mutex_destroy(&sctps
->sctps_bind_fanout
[i
].tf_lock
);
126 kmem_free(sctps
->sctps_bind_fanout
, SCTP_BIND_FANOUT_SIZE
*
128 sctps
->sctps_bind_fanout
= NULL
;
132 * Exported routine for extracting active SCTP associations.
133 * Like TCP, we terminate the walk if the callback returns non-zero.
135 * Need to walk all sctp_stack_t instances since this clustering
136 * interface is assumed global for all instances
139 cl_sctp_walk_list(int (*cl_callback
)(cl_sctp_info_t
*, void *),
140 void *arg
, boolean_t cansleep
)
142 netstack_handle_t nh
;
146 netstack_next_init(&nh
);
147 while ((ns
= netstack_next(&nh
)) != NULL
) {
148 ret
= cl_sctp_walk_list_stack(cl_callback
, arg
, cansleep
,
152 netstack_next_fini(&nh
);
157 cl_sctp_walk_list_stack(int (*cl_callback
)(cl_sctp_info_t
*, void *),
158 void *arg
, boolean_t cansleep
, sctp_stack_t
*sctps
)
162 cl_sctp_info_t cl_sctpi
;
167 mutex_enter(&sctps
->sctps_g_lock
);
168 sctp
= list_head(&sctps
->sctps_g_list
);
169 while (sctp
!= NULL
) {
173 mutex_enter(&sctp
->sctp_reflock
);
174 if (sctp
->sctp_condemned
|| sctp
->sctp_state
<= SCTPS_LISTEN
) {
175 mutex_exit(&sctp
->sctp_reflock
);
176 sctp
= list_next(&sctps
->sctps_g_list
, sctp
);
180 mutex_exit(&sctp
->sctp_reflock
);
181 mutex_exit(&sctps
->sctps_g_lock
);
182 if (sctp_prev
!= NULL
)
183 SCTP_REFRELE(sctp_prev
);
185 ssize
= sizeof (in6_addr_t
) * sctp
->sctp_nsaddrs
;
186 fsize
= sizeof (in6_addr_t
) * sctp
->sctp_nfaddrs
;
188 slist
= kmem_alloc(ssize
, cansleep
? KM_SLEEP
: KM_NOSLEEP
);
189 flist
= kmem_alloc(fsize
, cansleep
? KM_SLEEP
: KM_NOSLEEP
);
190 if (slist
== NULL
|| flist
== NULL
) {
193 kmem_free(slist
, ssize
);
195 kmem_free(flist
, fsize
);
199 cl_sctpi
.cl_sctpi_version
= CL_SCTPI_V1
;
200 sctp_get_saddr_list(sctp
, slist
, ssize
);
201 sctp_get_faddr_list(sctp
, flist
, fsize
);
202 cl_sctpi
.cl_sctpi_nladdr
= sctp
->sctp_nsaddrs
;
203 cl_sctpi
.cl_sctpi_nfaddr
= sctp
->sctp_nfaddrs
;
204 cl_sctpi
.cl_sctpi_family
= sctp
->sctp_connp
->conn_family
;
205 if (cl_sctpi
.cl_sctpi_family
== AF_INET
)
206 cl_sctpi
.cl_sctpi_ipversion
= IPV4_VERSION
;
208 cl_sctpi
.cl_sctpi_ipversion
= IPV6_VERSION
;
209 cl_sctpi
.cl_sctpi_state
= sctp
->sctp_state
;
210 cl_sctpi
.cl_sctpi_lport
= sctp
->sctp_connp
->conn_lport
;
211 cl_sctpi
.cl_sctpi_fport
= sctp
->sctp_connp
->conn_fport
;
212 cl_sctpi
.cl_sctpi_handle
= (cl_sctp_handle_t
)sctp
;
214 cl_sctpi
.cl_sctpi_laddrp
= slist
;
215 cl_sctpi
.cl_sctpi_faddrp
= flist
;
216 if ((*cl_callback
)(&cl_sctpi
, arg
) != 0) {
217 kmem_free(slist
, ssize
);
218 kmem_free(flist
, fsize
);
222 /* list will be freed by cl_callback */
224 mutex_enter(&sctps
->sctps_g_lock
);
225 sctp
= list_next(&sctps
->sctps_g_list
, sctp
);
227 mutex_exit(&sctps
->sctps_g_lock
);
228 if (sctp_prev
!= NULL
)
229 SCTP_REFRELE(sctp_prev
);
234 sctp_conn_match(in6_addr_t
**faddrpp
, uint32_t nfaddr
, in6_addr_t
*laddr
,
235 uint32_t ports
, zoneid_t zoneid
, iaflags_t iraflags
, sctp_stack_t
*sctps
)
241 in6_addr_t
**faddrs
, **endaddrs
= &faddrpp
[nfaddr
];
243 tf
= &(sctps
->sctps_conn_fanout
[SCTP_CONN_HASH(sctps
, ports
)]);
244 mutex_enter(&tf
->tf_lock
);
246 for (sctp
= tf
->tf_sctp
; sctp
!= NULL
; sctp
=
247 sctp
->sctp_conn_hash_next
) {
248 connp
= sctp
->sctp_connp
;
249 if (ports
!= connp
->conn_ports
)
251 if (!(connp
->conn_zoneid
== zoneid
||
252 connp
->conn_allzones
||
253 ((connp
->conn_mac_mode
!= CONN_MAC_DEFAULT
) &&
254 (iraflags
& IRAF_TX_MAC_EXEMPTABLE
) &&
255 (iraflags
& IRAF_TX_SHARED_ADDR
))))
258 /* check for faddr match */
259 for (fp
= sctp
->sctp_faddrs
; fp
!= NULL
; fp
= fp
->sf_next
) {
260 for (faddrs
= faddrpp
; faddrs
< endaddrs
; faddrs
++) {
261 if (IN6_ARE_ADDR_EQUAL(*faddrs
,
263 /* check for laddr match */
264 if (sctp_saddr_lookup(sctp
, laddr
, 0)
267 mutex_exit(&tf
->tf_lock
);
274 /* no match; continue to the next in the chain */
277 mutex_exit(&tf
->tf_lock
);
282 listen_match(in6_addr_t
*laddr
, uint32_t ports
, zoneid_t zoneid
,
283 iaflags_t iraflags
, sctp_stack_t
*sctps
)
290 lport
= ((uint16_t *)&ports
)[1];
292 tf
= &(sctps
->sctps_listen_fanout
[SCTP_LISTEN_HASH(ntohs(lport
))]);
293 mutex_enter(&tf
->tf_lock
);
295 for (sctp
= tf
->tf_sctp
; sctp
; sctp
= sctp
->sctp_listen_hash_next
) {
296 connp
= sctp
->sctp_connp
;
297 if (lport
!= connp
->conn_lport
)
300 if (!(connp
->conn_zoneid
== zoneid
||
301 connp
->conn_allzones
||
302 ((connp
->conn_mac_mode
!= CONN_MAC_DEFAULT
) &&
303 (iraflags
& IRAF_TX_MAC_EXEMPTABLE
) &&
304 (iraflags
& IRAF_TX_SHARED_ADDR
))))
307 if (sctp_saddr_lookup(sctp
, laddr
, 0) != NULL
) {
311 /* no match; continue to the next in the chain */
315 mutex_exit(&tf
->tf_lock
);
319 /* called by ipsec_sctp_pol */
321 sctp_find_conn(in6_addr_t
*src
, in6_addr_t
*dst
, uint32_t ports
,
322 zoneid_t zoneid
, iaflags_t iraflags
, sctp_stack_t
*sctps
)
326 sctp
= sctp_conn_match(&src
, 1, dst
, ports
, zoneid
, iraflags
, sctps
);
328 /* Not in conn fanout; check listen fanout */
329 sctp
= listen_match(dst
, ports
, zoneid
, iraflags
, sctps
);
333 return (sctp
->sctp_connp
);
337 * This is called from sctp_fanout() with IP header src & dst addresses.
338 * First call sctp_conn_match() to get a match by passing in src & dst
339 * addresses from IP header.
340 * However sctp_conn_match() can return no match under condition such as :
341 * A host can send an INIT ACK from a different address than the INIT was sent
342 * to (in a multi-homed env).
343 * According to RFC4960, a host can send additional addresses in an INIT
345 * Therefore extract all addresses from the INIT ACK chunk, pass to
346 * sctp_conn_match() to get a match.
349 sctp_lookup_by_faddrs(mblk_t
*mp
, sctp_hdr_t
*sctph
, in6_addr_t
*srcp
,
350 in6_addr_t
*dstp
, uint32_t ports
, zoneid_t zoneid
, sctp_stack_t
*sctps
,
354 sctp_chunk_hdr_t
*ich
;
355 sctp_init_chunk_t
*iack
;
357 ssize_t mlen
, remaining
;
358 uint16_t param_type
, addr_len
= PARM_ADDR4_LEN
;
360 in6_addr_t
**addrbuf
= NULL
, **faddrpp
= NULL
;
362 uint32_t totaddr
, nfaddr
= 0;
365 * If we get a match with the passed-in IP header src & dst addresses,
366 * quickly return the matched sctp.
368 if ((sctp
= sctp_conn_match(&srcp
, 1, dstp
, ports
, zoneid
, iraflags
,
374 * Currently sctph is set to NULL in icmp error fanout case
375 * (ip_fanout_sctp()).
376 * The above sctp_conn_match() should handle that, otherwise
377 * return no match found.
383 * Do a pullup again in case the previous one was partially successful,
384 * so try to complete the pullup here and have a single contiguous
385 * chunk for processing of entire INIT ACK chunk below.
387 if (mp
->b_cont
!= NULL
) {
388 if (pullupmsg(mp
, -1) == 0) {
393 mlen
= mp
->b_wptr
- (uchar_t
*)(sctph
+ 1);
394 if ((ich
= sctp_first_chunk((uchar_t
*)(sctph
+ 1), mlen
)) == NULL
) {
398 if (ich
->sch_id
== CHUNK_INIT_ACK
) {
399 remaining
= ntohs(ich
->sch_len
) - sizeof (*ich
) -
401 if (remaining
< sizeof (*ph
)) {
405 isv4
= (iraflags
& IRAF_IS_IPV4
) ? B_TRUE
: B_FALSE
;
407 addr_len
= PARM_ADDR6_LEN
;
408 totaddr
= remaining
/addr_len
;
410 iack
= (sctp_init_chunk_t
*)(ich
+ 1);
411 ph
= (sctp_parm_hdr_t
*)(iack
+ 1);
413 addrbuf
= (in6_addr_t
**)
414 kmem_zalloc(totaddr
* sizeof (in6_addr_t
*), KM_NOSLEEP
);
421 * According to RFC4960 :
422 * All integer fields in an SCTP packet MUST be
423 * transmitted in network byte order,
424 * unless otherwise stated.
425 * Therefore convert the param type to host byte order.
426 * Also do not add src address present in IP header
427 * as it has already been thru sctp_conn_match() above.
429 param_type
= ntohs(ph
->sph_type
);
430 switch (param_type
) {
432 IN6_INADDR_TO_V4MAPPED((struct in_addr
*)
434 if (IN6_ARE_ADDR_EQUAL(&src
, srcp
))
436 *faddrpp
= (in6_addr_t
*)
437 kmem_zalloc(sizeof (in6_addr_t
),
439 if (*faddrpp
== NULL
)
441 IN6_INADDR_TO_V4MAPPED((struct in_addr
*)
447 *faddrpp
= (in6_addr_t
*)(ph
+ 1);
448 if (IN6_ARE_ADDR_EQUAL(*faddrpp
, srcp
))
456 ph
= sctp_next_parm(ph
, &remaining
);
459 ASSERT(nfaddr
< totaddr
);
462 sctp
= sctp_conn_match(addrbuf
, nfaddr
, dstp
, ports
,
463 zoneid
, iraflags
, sctps
);
466 for (faddrpp
= addrbuf
; nfaddr
> 0;
467 faddrpp
++, nfaddr
--) {
468 if (IN6_IS_ADDR_V4MAPPED(*faddrpp
)) {
470 sizeof (in6_addr_t
));
475 kmem_free(addrbuf
, totaddr
* sizeof (in6_addr_t
*));
481 * Fanout to a sctp instance.
484 sctp_fanout(in6_addr_t
*src
, in6_addr_t
*dst
, uint32_t ports
,
485 ip_recv_attr_t
*ira
, mblk_t
*mp
, sctp_stack_t
*sctps
, sctp_hdr_t
*sctph
)
487 zoneid_t zoneid
= ira
->ira_zoneid
;
488 iaflags_t iraflags
= ira
->ira_flags
;
491 sctp
= sctp_lookup_by_faddrs(mp
, sctph
, src
, dst
, ports
, zoneid
,
494 /* Not in conn fanout; check listen fanout */
495 sctp
= listen_match(dst
, ports
, zoneid
, iraflags
, sctps
);
499 * On systems running trusted extensions, check if dst
500 * should accept the packet. "IPV6_VERSION" indicates
501 * that dst is in 16 byte AF_INET6 format. IPv4-mapped
502 * IPv6 addresses are supported.
504 if ((iraflags
& IRAF_SYSTEM_LABELED
) &&
505 !tsol_receive_local(mp
, dst
, IPV6_VERSION
, ira
,
508 tx__ip__log__info__classify__sctp
,
510 "connp(1) could not receive mp(2)",
511 conn_t
*, sctp
->sctp_connp
, mblk_t
*, mp
);
517 * For labeled systems, there's no need to check the
518 * label here. It's known to be good as we checked
519 * before allowing the connection to become bound.
521 return (sctp
->sctp_connp
);
525 * Fanout for ICMP errors for SCTP
526 * The caller puts <fport, lport> in the ports parameter.
529 ip_fanout_sctp(mblk_t
*mp
, ipha_t
*ipha
, ip6_t
*ip6h
, uint32_t ports
,
534 in6_addr_t map_src
, map_dst
;
535 in6_addr_t
*src
, *dst
;
537 ill_t
*ill
= ira
->ira_ill
;
538 ip_stack_t
*ipst
= ill
->ill_ipst
;
539 netstack_t
*ns
= ipst
->ips_netstack
;
540 ipsec_stack_t
*ipss
= ns
->netstack_ipsec
;
541 sctp_stack_t
*sctps
= ns
->netstack_sctp
;
542 iaflags_t iraflags
= ira
->ira_flags
;
543 ill_t
*rill
= ira
->ira_rill
;
545 ASSERT(iraflags
& IRAF_ICMP_ERROR
);
547 secure
= iraflags
& IRAF_IPSEC_SECURE
;
549 /* Assume IP provides aligned packets - otherwise toss */
550 if (!OK_32PTR(mp
->b_rptr
)) {
551 BUMP_MIB(ill
->ill_ip_mib
, ipIfStatsInDiscards
);
552 ip_drop_input("ipIfStatsInDiscards", mp
, ill
);
557 if (!(iraflags
& IRAF_IS_IPV4
)) {
558 src
= &ip6h
->ip6_src
;
559 dst
= &ip6h
->ip6_dst
;
561 IN6_IPADDR_TO_V4MAPPED(ipha
->ipha_src
, &map_src
);
562 IN6_IPADDR_TO_V4MAPPED(ipha
->ipha_dst
, &map_dst
);
566 connp
= sctp_fanout(src
, dst
, ports
, ira
, mp
, sctps
, NULL
);
568 ip_fanout_sctp_raw(mp
, ipha
, ip6h
, ports
, ira
);
571 sctp
= CONN2SCTP(connp
);
574 * We check some fields in conn_t without holding a lock.
575 * This should be fine.
577 if (((iraflags
& IRAF_IS_IPV4
) ?
578 CONN_INBOUND_POLICY_PRESENT(connp
, ipss
) :
579 CONN_INBOUND_POLICY_PRESENT_V6(connp
, ipss
)) ||
581 mp
= ipsec_check_inbound_policy(mp
, connp
, ipha
,
589 ira
->ira_ill
= ira
->ira_rill
= NULL
;
591 mutex_enter(&sctp
->sctp_lock
);
592 if (sctp
->sctp_running
) {
593 sctp_add_recvq(sctp
, mp
, B_FALSE
, ira
);
594 mutex_exit(&sctp
->sctp_lock
);
596 sctp
->sctp_running
= B_TRUE
;
597 mutex_exit(&sctp
->sctp_lock
);
599 mutex_enter(&sctp
->sctp_recvq_lock
);
600 if (sctp
->sctp_recvq
!= NULL
) {
601 sctp_add_recvq(sctp
, mp
, B_TRUE
, ira
);
602 mutex_exit(&sctp
->sctp_recvq_lock
);
605 mutex_exit(&sctp
->sctp_recvq_lock
);
606 if (ira
->ira_flags
& IRAF_ICMP_ERROR
) {
607 sctp_icmp_error(sctp
, mp
);
609 sctp_input_data(sctp
, mp
, ira
);
616 ira
->ira_rill
= rill
;
620 sctp_conn_hash_remove(sctp_t
*sctp
)
622 sctp_tf_t
*tf
= sctp
->sctp_conn_tfp
;
628 * On a clustered note send this notification to the clustering
631 if (cl_sctp_disconnect
!= NULL
) {
632 (*cl_sctp_disconnect
)(sctp
->sctp_connp
->conn_family
,
633 (cl_sctp_handle_t
)sctp
);
636 mutex_enter(&tf
->tf_lock
);
638 if (tf
->tf_sctp
== sctp
) {
639 tf
->tf_sctp
= sctp
->sctp_conn_hash_next
;
640 if (sctp
->sctp_conn_hash_next
) {
641 ASSERT(tf
->tf_sctp
->sctp_conn_hash_prev
== sctp
);
642 tf
->tf_sctp
->sctp_conn_hash_prev
= NULL
;
645 ASSERT(sctp
->sctp_conn_hash_prev
);
646 ASSERT(sctp
->sctp_conn_hash_prev
->sctp_conn_hash_next
== sctp
);
647 sctp
->sctp_conn_hash_prev
->sctp_conn_hash_next
=
648 sctp
->sctp_conn_hash_next
;
650 if (sctp
->sctp_conn_hash_next
) {
651 ASSERT(sctp
->sctp_conn_hash_next
->sctp_conn_hash_prev
653 sctp
->sctp_conn_hash_next
->sctp_conn_hash_prev
=
654 sctp
->sctp_conn_hash_prev
;
657 sctp
->sctp_conn_hash_next
= NULL
;
658 sctp
->sctp_conn_hash_prev
= NULL
;
659 sctp
->sctp_conn_tfp
= NULL
;
660 mutex_exit(&tf
->tf_lock
);
664 sctp_conn_hash_insert(sctp_tf_t
*tf
, sctp_t
*sctp
, int caller_holds_lock
)
666 if (sctp
->sctp_conn_tfp
) {
667 sctp_conn_hash_remove(sctp
);
670 if (!caller_holds_lock
) {
671 mutex_enter(&tf
->tf_lock
);
673 ASSERT(MUTEX_HELD(&tf
->tf_lock
));
676 sctp
->sctp_conn_hash_next
= tf
->tf_sctp
;
678 tf
->tf_sctp
->sctp_conn_hash_prev
= sctp
;
680 sctp
->sctp_conn_hash_prev
= NULL
;
682 sctp
->sctp_conn_tfp
= tf
;
683 if (!caller_holds_lock
) {
684 mutex_exit(&tf
->tf_lock
);
689 sctp_listen_hash_remove(sctp_t
*sctp
)
691 sctp_tf_t
*tf
= sctp
->sctp_listen_tfp
;
692 conn_t
*connp
= sctp
->sctp_connp
;
698 * On a clustered note send this notification to the clustering
701 if (cl_sctp_unlisten
!= NULL
) {
705 ssize
= sizeof (in6_addr_t
) * sctp
->sctp_nsaddrs
;
706 slist
= kmem_alloc(ssize
, KM_SLEEP
);
707 sctp_get_saddr_list(sctp
, slist
, ssize
);
708 (*cl_sctp_unlisten
)(connp
->conn_family
, slist
,
709 sctp
->sctp_nsaddrs
, connp
->conn_lport
);
710 /* list will be freed by the clustering module */
713 mutex_enter(&tf
->tf_lock
);
715 if (tf
->tf_sctp
== sctp
) {
716 tf
->tf_sctp
= sctp
->sctp_listen_hash_next
;
717 if (sctp
->sctp_listen_hash_next
!= NULL
) {
718 ASSERT(tf
->tf_sctp
->sctp_listen_hash_prev
== sctp
);
719 tf
->tf_sctp
->sctp_listen_hash_prev
= NULL
;
722 ASSERT(sctp
->sctp_listen_hash_prev
);
723 ASSERT(sctp
->sctp_listen_hash_prev
->sctp_listen_hash_next
==
725 ASSERT(sctp
->sctp_listen_hash_next
== NULL
||
726 sctp
->sctp_listen_hash_next
->sctp_listen_hash_prev
== sctp
);
728 sctp
->sctp_listen_hash_prev
->sctp_listen_hash_next
=
729 sctp
->sctp_listen_hash_next
;
731 if (sctp
->sctp_listen_hash_next
!= NULL
) {
732 sctp_t
*next
= sctp
->sctp_listen_hash_next
;
734 ASSERT(next
->sctp_listen_hash_prev
== sctp
);
735 next
->sctp_listen_hash_prev
=
736 sctp
->sctp_listen_hash_prev
;
739 sctp
->sctp_listen_hash_next
= NULL
;
740 sctp
->sctp_listen_hash_prev
= NULL
;
741 sctp
->sctp_listen_tfp
= NULL
;
742 mutex_exit(&tf
->tf_lock
);
746 sctp_listen_hash_insert(sctp_tf_t
*tf
, sctp_t
*sctp
)
748 conn_t
*connp
= sctp
->sctp_connp
;
750 if (sctp
->sctp_listen_tfp
) {
751 sctp_listen_hash_remove(sctp
);
754 mutex_enter(&tf
->tf_lock
);
755 sctp
->sctp_listen_hash_next
= tf
->tf_sctp
;
757 tf
->tf_sctp
->sctp_listen_hash_prev
= sctp
;
759 sctp
->sctp_listen_hash_prev
= NULL
;
761 sctp
->sctp_listen_tfp
= tf
;
762 mutex_exit(&tf
->tf_lock
);
764 * On a clustered note send this notification to the clustering
767 if (cl_sctp_listen
!= NULL
) {
771 ssize
= sizeof (in6_addr_t
) * sctp
->sctp_nsaddrs
;
772 slist
= kmem_alloc(ssize
, KM_SLEEP
);
773 sctp_get_saddr_list(sctp
, slist
, ssize
);
774 (*cl_sctp_listen
)(connp
->conn_family
, slist
,
775 sctp
->sctp_nsaddrs
, connp
->conn_lport
);
776 /* list will be freed by the clustering module */
781 * Hash list insertion routine for sctp_t structures.
782 * Inserts entries with the ones bound to a specific IP address first
783 * followed by those bound to INADDR_ANY.
786 sctp_bind_hash_insert(sctp_tf_t
*tbf
, sctp_t
*sctp
, int caller_holds_lock
)
791 if (sctp
->sctp_ptpbhn
!= NULL
) {
792 ASSERT(!caller_holds_lock
);
793 sctp_bind_hash_remove(sctp
);
795 sctpp
= &tbf
->tf_sctp
;
796 if (!caller_holds_lock
) {
797 mutex_enter(&tbf
->tf_lock
);
799 ASSERT(MUTEX_HELD(&tbf
->tf_lock
));
803 sctpnext
->sctp_ptpbhn
= &sctp
->sctp_bind_hash
;
805 sctp
->sctp_bind_hash
= sctpnext
;
806 sctp
->sctp_ptpbhn
= sctpp
;
808 /* For sctp_*_hash_remove */
809 sctp
->sctp_bind_lockp
= &tbf
->tf_lock
;
810 if (!caller_holds_lock
)
811 mutex_exit(&tbf
->tf_lock
);
815 * Hash list removal routine for sctp_t structures.
818 sctp_bind_hash_remove(sctp_t
*sctp
)
823 lockp
= sctp
->sctp_bind_lockp
;
825 if (sctp
->sctp_ptpbhn
== NULL
)
828 ASSERT(lockp
!= NULL
);
830 if (sctp
->sctp_ptpbhn
) {
831 sctpnext
= sctp
->sctp_bind_hash
;
833 sctpnext
->sctp_ptpbhn
= sctp
->sctp_ptpbhn
;
834 sctp
->sctp_bind_hash
= NULL
;
836 *sctp
->sctp_ptpbhn
= sctpnext
;
837 sctp
->sctp_ptpbhn
= NULL
;
840 sctp
->sctp_bind_lockp
= NULL
;
844 * Similar to but different from sctp_conn_match().
846 * Matches sets of addresses as follows: if the argument addr set is
847 * a complete subset of the corresponding addr set in the sctp_t, it
850 * Caller must hold tf->tf_lock.
852 * Returns with a SCTP_REFHOLD sctp structure. Caller must do a SCTP_REFRELE.
855 sctp_lookup(sctp_t
*sctp1
, in6_addr_t
*faddr
, sctp_tf_t
*tf
, uint32_t *ports
,
861 ASSERT(MUTEX_HELD(&tf
->tf_lock
));
863 for (sctp
= tf
->tf_sctp
; sctp
!= NULL
;
864 sctp
= sctp
->sctp_conn_hash_next
) {
865 if (*ports
!= sctp
->sctp_connp
->conn_ports
||
866 sctp
->sctp_state
< min_state
) {
870 /* check for faddr match */
871 for (fp
= sctp
->sctp_faddrs
; fp
!= NULL
; fp
= fp
->sf_next
) {
872 if (IN6_ARE_ADDR_EQUAL(faddr
, &fp
->sf_faddr
)) {
878 /* no faddr match; keep looking */
883 * There is an existing association with the same peer
884 * address. So now we need to check if our local address
885 * set overlaps with the one of the existing association.
886 * If they overlap, we should return it.
888 if (sctp_compare_saddrs(sctp1
, sctp
) <= SCTP_ADDR_OVERLAP
) {
892 /* no match; continue searching */