xref: /netbsd-src/sys/netinet/sctp_pcb.h (revision cb40c69b164a69aec47d70a50d23979d0f1752cb)
18c2654abSrjs /*	$KAME: sctp_pcb.h,v 1.21 2005/07/16 01:18:47 suz Exp $	*/
2*cb40c69bSandvar /*	$NetBSD: sctp_pcb.h,v 1.8 2023/06/02 08:51:48 andvar Exp $ */
38c2654abSrjs 
48c2654abSrjs #ifndef __SCTP_PCB_H__
58c2654abSrjs #define __SCTP_PCB_H__
68c2654abSrjs 
78c2654abSrjs /*
88c2654abSrjs  * Copyright (c) 2001, 2002, 2003, 2004 Cisco Systems, Inc.
98c2654abSrjs  * All rights reserved.
108c2654abSrjs  *
118c2654abSrjs  * Redistribution and use in source and binary forms, with or without
128c2654abSrjs  * modification, are permitted provided that the following conditions
138c2654abSrjs  * are met:
148c2654abSrjs  * 1. Redistributions of source code must retain the above copyright
158c2654abSrjs  *    notice, this list of conditions and the following disclaimer.
168c2654abSrjs  * 2. Redistributions in binary form must reproduce the above copyright
178c2654abSrjs  *    notice, this list of conditions and the following disclaimer in the
188c2654abSrjs  *    documentation and/or other materials provided with the distribution.
198c2654abSrjs  * 3. All advertising materials mentioning features or use of this software
208c2654abSrjs  *    must display the following acknowledgement:
218c2654abSrjs  *      This product includes software developed by Cisco Systems, Inc.
228c2654abSrjs  * 4. Neither the name of the project nor the names of its contributors
238c2654abSrjs  *    may be used to endorse or promote products derived from this software
248c2654abSrjs  *    without specific prior written permission.
258c2654abSrjs  *
268c2654abSrjs  * THIS SOFTWARE IS PROVIDED BY CISCO SYSTEMS AND CONTRIBUTORS ``AS IS'' AND
278c2654abSrjs  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
288c2654abSrjs  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
298c2654abSrjs  * ARE DISCLAIMED.  IN NO EVENT SHALL CISCO SYSTEMS OR CONTRIBUTORS BE LIABLE
308c2654abSrjs  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
318c2654abSrjs  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
328c2654abSrjs  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
338c2654abSrjs  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
348c2654abSrjs  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
358c2654abSrjs  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
368c2654abSrjs  * SUCH DAMAGE.
378c2654abSrjs  */
388c2654abSrjs 
398c2654abSrjs /*
408c2654abSrjs  * We must have V6 so the size of the proto can be calculated. Otherwise
418c2654abSrjs  * we would not allocate enough for Net/Open BSD :-<
428c2654abSrjs  */
438c2654abSrjs #include <net/if.h>
44f8c27a68Sozaki-r #include <netinet/in_pcb.h>
458c2654abSrjs #include <netinet/ip6.h>
468c2654abSrjs #include <netinet6/ip6_var.h>
478c2654abSrjs #include <netinet6/ip6protosw.h>
488c2654abSrjs #include <netinet6/in6_var.h>
498c2654abSrjs #include <netinet6/in6_pcb.h>
508c2654abSrjs 
518c2654abSrjs #include <netinet/sctp.h>
528c2654abSrjs #include <netinet/sctp_constants.h>
538c2654abSrjs 
548c2654abSrjs LIST_HEAD(sctppcbhead, sctp_inpcb);
558c2654abSrjs LIST_HEAD(sctpasochead, sctp_tcb);
568c2654abSrjs TAILQ_HEAD(sctpsocketq, sctp_socket_q_list);
578c2654abSrjs LIST_HEAD(sctpladdr, sctp_laddr);
588c2654abSrjs LIST_HEAD(sctpvtaghead, sctp_tagblock);
598c2654abSrjs 
608c2654abSrjs #include <netinet/sctp_structs.h>
618c2654abSrjs #include <netinet/sctp_uio.h>
628c2654abSrjs 
638c2654abSrjs /*
648c2654abSrjs  * PCB flags
658c2654abSrjs  */
668c2654abSrjs #define SCTP_PCB_FLAGS_UDPTYPE		0x00000001
678c2654abSrjs #define SCTP_PCB_FLAGS_TCPTYPE		0x00000002
688c2654abSrjs #define SCTP_PCB_FLAGS_BOUNDALL		0x00000004
698c2654abSrjs #define SCTP_PCB_FLAGS_ACCEPTING	0x00000008
708c2654abSrjs #define SCTP_PCB_FLAGS_UNBOUND		0x00000010
718c2654abSrjs #define SCTP_PCB_FLAGS_DO_ASCONF	0x00000020
728c2654abSrjs #define SCTP_PCB_FLAGS_AUTO_ASCONF	0x00000040
738c2654abSrjs /* socket options */
748c2654abSrjs #define SCTP_PCB_FLAGS_NODELAY		0x00000100
758c2654abSrjs #define SCTP_PCB_FLAGS_AUTOCLOSE	0x00000200
768c2654abSrjs #define SCTP_PCB_FLAGS_RECVDATAIOEVNT	0x00000400
778c2654abSrjs #define SCTP_PCB_FLAGS_RECVASSOCEVNT	0x00000800
788c2654abSrjs #define SCTP_PCB_FLAGS_RECVPADDREVNT	0x00001000
798c2654abSrjs #define SCTP_PCB_FLAGS_RECVPEERERR	0x00002000
808c2654abSrjs #define SCTP_PCB_FLAGS_RECVSENDFAILEVNT	0x00004000
818c2654abSrjs #define SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT	0x00008000
828c2654abSrjs #define SCTP_PCB_FLAGS_ADAPTIONEVNT	0x00010000
838c2654abSrjs #define SCTP_PCB_FLAGS_PDAPIEVNT	0x00020000
848c2654abSrjs #define SCTP_PCB_FLAGS_STREAM_RESETEVNT 0x00040000
858c2654abSrjs #define SCTP_PCB_FLAGS_NO_FRAGMENT	0x00080000
868c2654abSrjs /* TCP model support */
878c2654abSrjs #define SCTP_PCB_FLAGS_CONNECTED	0x00100000
888c2654abSrjs #define SCTP_PCB_FLAGS_IN_TCPPOOL	0x00200000
898c2654abSrjs #define SCTP_PCB_FLAGS_DONT_WAKE	0x00400000
908c2654abSrjs #define SCTP_PCB_FLAGS_WAKEOUTPUT	0x00800000
918c2654abSrjs #define SCTP_PCB_FLAGS_WAKEINPUT	0x01000000
928c2654abSrjs #define SCTP_PCB_FLAGS_BOUND_V6		0x02000000
938c2654abSrjs #define SCTP_PCB_FLAGS_NEEDS_MAPPED_V4	0x04000000
948c2654abSrjs #define SCTP_PCB_FLAGS_BLOCKING_IO	0x08000000
958c2654abSrjs #define SCTP_PCB_FLAGS_SOCKET_GONE	0x10000000
968c2654abSrjs #define SCTP_PCB_FLAGS_SOCKET_ALLGONE	0x20000000
978c2654abSrjs 
988c2654abSrjs /* flags to copy to new PCB */
998c2654abSrjs #define SCTP_PCB_COPY_FLAGS		0x0707ff64
1008c2654abSrjs 
1018c2654abSrjs #define SCTP_PCBHASH_ALLADDR(port, mask) (port & mask)
1028c2654abSrjs #define SCTP_PCBHASH_ASOC(tag, mask) (tag & mask)
1038c2654abSrjs 
1048c2654abSrjs struct sctp_laddr {
1058c2654abSrjs 	LIST_ENTRY(sctp_laddr) sctp_nxt_addr;	/* next in list */
1068c2654abSrjs 	struct ifaddr *ifa;
1078c2654abSrjs };
1088c2654abSrjs 
1098c2654abSrjs struct sctp_timewait {
1108c2654abSrjs 	uint32_t tv_sec_at_expire;	/* the seconds from boot to expire */
1118c2654abSrjs 	uint32_t v_tag;		/* the vtag that can not be reused */
1128c2654abSrjs };
1138c2654abSrjs 
1148c2654abSrjs struct sctp_tagblock {
1158c2654abSrjs         LIST_ENTRY(sctp_tagblock) sctp_nxt_tagblock;
1168c2654abSrjs 	struct sctp_timewait vtag_block[SCTP_NUMBER_IN_VTAG_BLOCK];
1178c2654abSrjs };
1188c2654abSrjs 
1198c2654abSrjs struct sctp_epinfo {
1208c2654abSrjs 	struct sctpasochead *sctp_asochash;
1218c2654abSrjs 	u_long hashasocmark;
1228c2654abSrjs 
1238c2654abSrjs 	struct sctppcbhead *sctp_ephash;
1248c2654abSrjs 	u_long hashmark;
1258c2654abSrjs 
1268c2654abSrjs 	/*
1278c2654abSrjs 	 * The TCP model represents a substantial overhead in that we get
1288c2654abSrjs 	 * an additional hash table to keep explicit connections in. The
1298c2654abSrjs 	 * listening TCP endpoint will exist in the usual ephash above and
1308c2654abSrjs 	 * accept only INIT's. It will be incapable of sending off an INIT.
1318c2654abSrjs 	 * When a dg arrives we must look in the normal ephash. If we find
1328c2654abSrjs 	 * a TCP endpoint that will tell us to go to the specific endpoint
1338c2654abSrjs 	 * hash and re-hash to find the right assoc/socket. If we find a
1348c2654abSrjs 	 * UDP model socket we then must complete the lookup. If this fails,
1358c2654abSrjs 	 * i.e. no association can be found then we must continue to see if
1368c2654abSrjs 	 * a sctp_peeloff()'d socket is in the tcpephash (a spun off socket
1378c2654abSrjs 	 * acts like a TCP model connected socket).
1388c2654abSrjs 	 */
1398c2654abSrjs 	struct sctppcbhead *sctp_tcpephash;
1408c2654abSrjs 	u_long hashtcpmark;
1418c2654abSrjs 	uint32_t hashtblsize;
1428c2654abSrjs 
1438c2654abSrjs 	struct sctppcbhead listhead;
1448c2654abSrjs 
1458c2654abSrjs 	struct sctpiterators iteratorhead;
1468c2654abSrjs 
1478c2654abSrjs 	/* ep zone info */
1488c2654abSrjs #if defined(__FreeBSD__) || defined(__APPLE__)
1498c2654abSrjs #if __FreeBSD_version >= 500000
1508c2654abSrjs 	struct uma_zone *ipi_zone_ep;
1518c2654abSrjs 	struct uma_zone *ipi_zone_asoc;
1528c2654abSrjs 	struct uma_zone *ipi_zone_laddr;
1538c2654abSrjs 	struct uma_zone *ipi_zone_net;
1548c2654abSrjs 	struct uma_zone *ipi_zone_chunk;
1558c2654abSrjs 	struct uma_zone *ipi_zone_sockq;
1568c2654abSrjs #else
1578c2654abSrjs 	struct vm_zone *ipi_zone_ep;
1588c2654abSrjs 	struct vm_zone *ipi_zone_asoc;
1598c2654abSrjs 	struct vm_zone *ipi_zone_laddr;
1608c2654abSrjs 	struct vm_zone *ipi_zone_net;
1618c2654abSrjs 	struct vm_zone *ipi_zone_chunk;
1628c2654abSrjs 	struct vm_zone *ipi_zone_sockq;
1638c2654abSrjs #endif
1648c2654abSrjs #endif
1658c2654abSrjs #if defined(__NetBSD__) || defined(__OpenBSD__)
1668c2654abSrjs 	struct pool ipi_zone_ep;
1678c2654abSrjs 	struct pool ipi_zone_asoc;
1688c2654abSrjs 	struct pool ipi_zone_laddr;
1698c2654abSrjs 	struct pool ipi_zone_net;
1708c2654abSrjs 	struct pool ipi_zone_chunk;
1718c2654abSrjs 	struct pool ipi_zone_sockq;
1728c2654abSrjs 	struct pool ipi_zone_hash;
1738c2654abSrjs #endif
1748c2654abSrjs 
1758c2654abSrjs #if defined(__FreeBSD__) && __FreeBSD_version >= 503000
1768c2654abSrjs 	struct mtx ipi_ep_mtx;
1778c2654abSrjs 	struct mtx it_mtx;
1788c2654abSrjs #elif 0 /* defined(__NetBSD__) */
1798c2654abSrjs 	krwlock_t ipi_ep_mtx;
1808c2654abSrjs 	kmutex_t it_mtx;
1818c2654abSrjs #endif
1828c2654abSrjs 	u_int ipi_count_ep;
1838c2654abSrjs 	u_quad_t ipi_gencnt_ep;
1848c2654abSrjs 
1858c2654abSrjs 	/* assoc/tcb zone info */
1868c2654abSrjs 	u_int ipi_count_asoc;
1878c2654abSrjs 	u_quad_t ipi_gencnt_asoc;
1888c2654abSrjs 
1898c2654abSrjs 	/* local addrlist zone info */
1908c2654abSrjs 	u_int ipi_count_laddr;
1918c2654abSrjs 	u_quad_t ipi_gencnt_laddr;
1928c2654abSrjs 
1938c2654abSrjs 	/* remote addrlist zone info */
1948c2654abSrjs 	u_int ipi_count_raddr;
1958c2654abSrjs 	u_quad_t ipi_gencnt_raddr;
1968c2654abSrjs 
1978c2654abSrjs 	/* chunk structure list for output */
1988c2654abSrjs 	u_int ipi_count_chunk;
1998c2654abSrjs 	u_quad_t ipi_gencnt_chunk;
2008c2654abSrjs 
2018c2654abSrjs 	/* socket queue zone info */
2028c2654abSrjs 	u_int ipi_count_sockq;
2038c2654abSrjs 	u_quad_t ipi_gencnt_sockq;
2048c2654abSrjs 
2058c2654abSrjs 	struct sctpvtaghead vtag_timewait[SCTP_STACK_VTAG_HASH_SIZE];
2068c2654abSrjs 
2078c2654abSrjs #ifdef _SCTP_NEEDS_CALLOUT_
2088c2654abSrjs 	struct calloutlist callqueue;
2098c2654abSrjs #endif /* _SCTP_NEEDS_CALLOUT_ */
2108c2654abSrjs 
2118c2654abSrjs 	uint32_t mbuf_track;
2128c2654abSrjs 
2138c2654abSrjs 	/* for port allocations */
2148c2654abSrjs 	uint16_t lastport;
2158c2654abSrjs 	uint16_t lastlow;
2168c2654abSrjs 	uint16_t lasthi;
2178c2654abSrjs 
2188c2654abSrjs };
2198c2654abSrjs 
2208c2654abSrjs extern uint32_t sctp_pegs[SCTP_NUMBER_OF_PEGS];
2218c2654abSrjs /*
2228c2654abSrjs  * Here we have all the relevant information for each SCTP entity created.
2238c2654abSrjs  * We will need to modify this as approprate. We also need to figure out
2248c2654abSrjs  * how to access /dev/random.
2258c2654abSrjs  */
2268c2654abSrjs struct sctp_pcb {
2278c2654abSrjs 	unsigned int time_of_secret_change; /* number of seconds from timeval.tv_sec */
2288c2654abSrjs 	uint32_t secret_key[SCTP_HOW_MANY_SECRETS][SCTP_NUMBER_OF_SECRETS];
2298c2654abSrjs 	unsigned int size_of_a_cookie;
2308c2654abSrjs 
2318c2654abSrjs 	unsigned int sctp_timeoutticks[SCTP_NUM_TMRS];
2328c2654abSrjs 	unsigned int sctp_minrto;
2338c2654abSrjs 	unsigned int sctp_maxrto;
2348c2654abSrjs 	unsigned int initial_rto;
2358c2654abSrjs 
2368c2654abSrjs 	int initial_init_rto_max;
2378c2654abSrjs 
2388c2654abSrjs 	uint32_t sctp_sws_sender;
2398c2654abSrjs 	uint32_t sctp_sws_receiver;
2408c2654abSrjs 
2418c2654abSrjs 	/* various thresholds */
2428c2654abSrjs 	/* Max times I will init at a guy */
2438c2654abSrjs 	uint16_t max_init_times;
2448c2654abSrjs 
2458c2654abSrjs 	/* Max times I will send before we consider someone dead */
2468c2654abSrjs 	uint16_t max_send_times;
2478c2654abSrjs 
2488c2654abSrjs 	uint16_t def_net_failure;
2498c2654abSrjs 
2508c2654abSrjs 	/* number of streams to pre-open on a association */
2518c2654abSrjs 	uint16_t pre_open_stream_count;
2528c2654abSrjs 	uint16_t max_open_streams_intome;
2538c2654abSrjs 
2548c2654abSrjs 	/*
2558c2654abSrjs 	 * This timer is kept running per endpoint.  When it fires it
2568c2654abSrjs 	 * will change the secret key.  The default is once a hour
2578c2654abSrjs 	 */
2588c2654abSrjs 	struct sctp_timer signature_change;
2598c2654abSrjs 	int def_cookie_life;
2608c2654abSrjs 	/* defaults to 0 */
2618c2654abSrjs 	int auto_close_time;
2628c2654abSrjs 	uint32_t initial_sequence_debug;
2638c2654abSrjs 	uint32_t adaption_layer_indicator;
2648c2654abSrjs 	uint8_t max_burst;
2658c2654abSrjs 	char current_secret_number;
2668c2654abSrjs 	char last_secret_number;
2678c2654abSrjs };
2688c2654abSrjs 
2698c2654abSrjs #ifndef SCTP_ALIGNMENT
2708c2654abSrjs #define SCTP_ALIGNMENT 32
2718c2654abSrjs #endif
2728c2654abSrjs 
2738c2654abSrjs #ifndef SCTP_ALIGNM1
2748c2654abSrjs #define SCTP_ALIGNM1 (SCTP_ALIGNMENT-1)
2758c2654abSrjs #endif
2768c2654abSrjs 
2778c2654abSrjs #define sctp_lport ip_inp.inp.inp_lport
2788c2654abSrjs 
2798c2654abSrjs struct sctp_socket_q_list {
2808c2654abSrjs 	struct sctp_tcb *tcb;
2818c2654abSrjs 	TAILQ_ENTRY(sctp_socket_q_list) next_sq;
2828c2654abSrjs };
2838c2654abSrjs 
2848c2654abSrjs struct sctp_inpcb {
2858c2654abSrjs 	/*
2868c2654abSrjs 	 * put an inpcb in front of it all, kind of a waste but we need
2876584ea56Sandvar 	 * to for compatibility with all the other stuff.
2888c2654abSrjs 	 */
2898c2654abSrjs 	union {
2908c2654abSrjs 		struct inpcb inp;
2917118c214Sozaki-r 		char align[(sizeof(struct in6pcb) + SCTP_ALIGNM1) &
2928c2654abSrjs 			  ~SCTP_ALIGNM1];
2938c2654abSrjs 	} ip_inp;
2948c2654abSrjs 	LIST_ENTRY(sctp_inpcb) sctp_list;	/* lists all endpoints */
2958c2654abSrjs 	/* hash of all endpoints for model */
2968c2654abSrjs 	LIST_ENTRY(sctp_inpcb) sctp_hash;
2978c2654abSrjs 
2988c2654abSrjs 	/* count of local addresses bound, 0 if bound all */
2998c2654abSrjs 	int laddr_count;
3008c2654abSrjs 	/* list of addrs in use by the EP */
3018c2654abSrjs 	struct sctpladdr sctp_addr_list;
3028c2654abSrjs 	/* used for source address selection rotation */
3038c2654abSrjs 	struct sctp_laddr *next_addr_touse;
3048c2654abSrjs 	struct ifnet *next_ifn_touse;
3058c2654abSrjs 	/* back pointer to our socket */
3068c2654abSrjs 	struct socket *sctp_socket;
3078c2654abSrjs 	uint32_t sctp_flags;			/* flag set */
3088c2654abSrjs 	struct sctp_pcb sctp_ep;		/* SCTP ep data */
3098c2654abSrjs 	/* head of the hash of all associations */
3108c2654abSrjs 	struct sctpasochead *sctp_tcbhash;
3118c2654abSrjs 	u_long sctp_hashmark;
3128c2654abSrjs 	/* head of the list of all associations */
3138c2654abSrjs 	struct sctpasochead sctp_asoc_list;
3148c2654abSrjs 	/* queue of TCB's waiting to stuff data up the socket */
3158c2654abSrjs 	struct sctpsocketq sctp_queue_list;
3168c2654abSrjs 	void *sctp_tcb_at_block;
3178c2654abSrjs 	struct sctp_iterator *inp_starting_point_for_iterator;
3188c2654abSrjs 	int  error_on_block;
3198c2654abSrjs 	uint32_t sctp_frag_point;
3208c2654abSrjs 	uint32_t sctp_vtag_first;
3218c2654abSrjs 	struct mbuf *pkt, *pkt_last, *sb_last_mpkt;
3228c2654abSrjs 	struct mbuf *control;
3238c2654abSrjs #if !(defined(__FreeBSD__) || defined(__APPLE__))
3248c2654abSrjs #ifndef INP_IPV6
3258c2654abSrjs #define INP_IPV6	0x1
3268c2654abSrjs #endif
3278c2654abSrjs #ifndef INP_IPV4
3288c2654abSrjs #define INP_IPV4	0x2
3298c2654abSrjs #endif
3308c2654abSrjs 	u_char inp_vflag;
3318c2654abSrjs 	u_char inp_ip_ttl;
3328c2654abSrjs 	u_char inp_ip_tos;
3338c2654abSrjs 	u_char inp_ip_resv;
3348c2654abSrjs #endif
3358c2654abSrjs #if defined(__FreeBSD__) && __FreeBSD_version >= 503000
3368c2654abSrjs 	struct mtx inp_mtx;
3378c2654abSrjs 	struct mtx inp_create_mtx;
3388c2654abSrjs 	u_int32_t refcount;
3398c2654abSrjs #elif defined(__NetBSD__)
3408c2654abSrjs 	kmutex_t inp_mtx;
3418c2654abSrjs 	kmutex_t inp_create_mtx;
3428c2654abSrjs 	u_int32_t refcount;
3438c2654abSrjs #endif
3448c2654abSrjs };
3458c2654abSrjs 
3468c2654abSrjs struct sctp_tcb {
3478c2654abSrjs 	struct socket *sctp_socket;		/* back pointer to socket */
3488c2654abSrjs 	struct sctp_inpcb *sctp_ep;		/* back pointer to ep */
3498c2654abSrjs 	LIST_ENTRY(sctp_tcb) sctp_tcbhash;	/* next link in hash table */
3508c2654abSrjs 	LIST_ENTRY(sctp_tcb) sctp_tcblist;	/* list of all of the TCB's */
3518c2654abSrjs 	LIST_ENTRY(sctp_tcb) sctp_asocs;
3528c2654abSrjs 	struct sctp_association asoc;
3538c2654abSrjs 	uint16_t rport;			/* remote port in network format */
3548c2654abSrjs 	uint16_t resv;
3558c2654abSrjs #if defined(__FreeBSD__) && __FreeBSD_version >= 503000
3568c2654abSrjs 	struct mtx tcb_mtx;
3578c2654abSrjs #elif defined(__NetBSD__)
3588c2654abSrjs 	kmutex_t tcb_mtx;
3598c2654abSrjs #endif
3608c2654abSrjs };
3618c2654abSrjs 
3628c2654abSrjs #if defined(__FreeBSD__) && __FreeBSD_version >= 503000
3638c2654abSrjs 
3648c2654abSrjs /* General locking concepts:
3658c2654abSrjs  * The goal of our locking is to of course provide
3668c2654abSrjs  * consistency and yet minimize overhead. We will
3678c2654abSrjs  * attempt to use non-recursive locks which are supposed
3688c2654abSrjs  * to be quite inexpensive. Now in order to do this the goal
3698c2654abSrjs  * is that most functions are not aware of locking. Once we
3708c2654abSrjs  * have a TCB we lock it and unlock when we are through. This
3718c2654abSrjs  * means that the TCB lock is kind-of a "global" lock when
3728c2654abSrjs  * working on an association. Caution must be used when
3738c2654abSrjs  * asserting a TCB_LOCK since if we recurse we deadlock.
3748c2654abSrjs  *
3758c2654abSrjs  * Most other locks (INP and INFO) attempt to localize
3768c2654abSrjs  * the locking i.e. we try to contain the lock and
3778c2654abSrjs  * unlock within the function that needs to lock it. This
378*cb40c69bSandvar  * sometimes mean we do extra locks and unlocks and lose
379cdc507f0Sandvar  * a bit of efficiency, but if the performance statements about
3808c2654abSrjs  * non-recursive locks are true this should not be a problem.
3818c2654abSrjs  * One issue that arises with this only lock when needed
3828c2654abSrjs  * is that if an implicit association setup is done we
3838c2654abSrjs  * have a problem. If at the time I lookup an association
3848c2654abSrjs  * I have NULL in the tcb return, by the time I call to
3858c2654abSrjs  * create the association some other processor could
3868c2654abSrjs  * have created it. This is what the CREATE lock on
3878c2654abSrjs  * the endpoint. Places where we will be implicitly
3888c2654abSrjs  * creating the association OR just creating an association
3898c2654abSrjs  * (the connect call) will assert the CREATE_INP lock. This
3908c2654abSrjs  * will assure us that during all the lookup of INP and INFO
3918c2654abSrjs  * if another creator is also locking/looking up we can
3928c2654abSrjs  * gate the two to synchronize. So the CREATE_INP lock is
3938c2654abSrjs  * also another one we must use extreme caution in locking
3948c2654abSrjs  * to make sure we don't hit a re-entrancy issue.
3958c2654abSrjs  *
3968c2654abSrjs  * For non FreeBSD 5.x and above we provide a bunch
3978c2654abSrjs  * of EMPTY lock macro's so we can blatantly put locks
3988c2654abSrjs  * everywhere and they reduce to nothing on NetBSD/OpenBSD
3998c2654abSrjs  * and FreeBSD 4.x
4008c2654abSrjs  *
4018c2654abSrjs  */
4028c2654abSrjs 
4038c2654abSrjs 
4048c2654abSrjs /* When working with the global SCTP lists we lock and unlock
4058c2654abSrjs  * the INP_INFO lock. So when we go to lookup an association
4068c2654abSrjs  * we will want to do a SCTP_INP_INFO_RLOCK() and then when
4078c2654abSrjs  * we want to add a new association to the sctppcbinfo list's
4088c2654abSrjs  * we will do a SCTP_INP_INFO_WLOCK().
4098c2654abSrjs  */
4108c2654abSrjs 
4118c2654abSrjs /*
4128c2654abSrjs  * FIX ME, all locks right now have a
4138c2654abSrjs  * recursive check/panic to validate that I
4148c2654abSrjs  * don't have any lock recursion going on.
4158c2654abSrjs  */
4168c2654abSrjs 
4178c2654abSrjs #define SCTP_INP_INFO_LOCK_INIT() \
4188c2654abSrjs         mtx_init(&sctppcbinfo.ipi_ep_mtx, "sctp", "inp_info", MTX_DEF)
4198c2654abSrjs 
4208c2654abSrjs #ifdef xyzzy
4218c2654abSrjs #define SCTP_INP_INFO_RLOCK()	do { 					\
4228c2654abSrjs              if (mtx_owned(&sctppcbinfo.ipi_ep_mtx))                     \
4238c2654abSrjs 		panic("INP INFO Recursive Lock-R");                     \
4248c2654abSrjs              mtx_lock(&sctppcbinfo.ipi_ep_mtx);                         \
4258c2654abSrjs } while (0)
4268c2654abSrjs 
4278c2654abSrjs #define SCTP_INP_INFO_WLOCK()	do { 					\
4288c2654abSrjs              if (mtx_owned(&sctppcbinfo.ipi_ep_mtx))                     \
4298c2654abSrjs 		panic("INP INFO Recursive Lock-W");                     \
4308c2654abSrjs              mtx_lock(&sctppcbinfo.ipi_ep_mtx);                         \
4318c2654abSrjs } while (0)
4328c2654abSrjs 
4338c2654abSrjs #else
4348c2654abSrjs 
4358c2654abSrjs void SCTP_INP_INFO_RLOCK(void);
4368c2654abSrjs void SCTP_INP_INFO_WLOCK(void);
4378c2654abSrjs 
4388c2654abSrjs #endif
4398c2654abSrjs 
4408c2654abSrjs #define SCTP_INP_INFO_RUNLOCK()		mtx_unlock(&sctppcbinfo.ipi_ep_mtx)
4418c2654abSrjs #define SCTP_INP_INFO_WUNLOCK()		mtx_unlock(&sctppcbinfo.ipi_ep_mtx)
4428c2654abSrjs 
4438c2654abSrjs /* The INP locks we will use for locking an SCTP endpoint, so for
4448c2654abSrjs  * example if we want to change something at the endpoint level for
445a2f9ec55Sriastradh  * example cookie secrets we lock the INP level.
4468c2654abSrjs  */
4478c2654abSrjs #define SCTP_INP_LOCK_INIT(_inp) \
4488c2654abSrjs 	mtx_init(&(_inp)->inp_mtx, "sctp", "inp", MTX_DEF | MTX_DUPOK)
4498c2654abSrjs 
4508c2654abSrjs #define SCTP_ASOC_CREATE_LOCK_INIT(_inp) \
4518c2654abSrjs 	mtx_init(&(_inp)->inp_create_mtx, "sctp", "inp_create", \
4528c2654abSrjs 		 MTX_DEF | MTX_DUPOK)
4538c2654abSrjs 
4548c2654abSrjs #define SCTP_INP_LOCK_DESTROY(_inp)	mtx_destroy(&(_inp)->inp_mtx)
4558c2654abSrjs #define SCTP_ASOC_CREATE_LOCK_DESTROY(_inp)	mtx_destroy(&(_inp)->inp_create_mtx)
4568c2654abSrjs 
4578c2654abSrjs #ifdef xyzzy
4588c2654abSrjs #define SCTP_INP_RLOCK(_inp)	do { 					\
4598c2654abSrjs         struct sctp_tcb *xx_stcb;					\
4608c2654abSrjs         xx_stcb = LIST_FIRST(&_inp->sctp_asoc_list);                    \
4618c2654abSrjs         if (xx_stcb)                                                     \
4628c2654abSrjs               if (mtx_owned(&(xx_stcb)->tcb_mtx))                        \
4638c2654abSrjs                      panic("I own TCB lock?");                          \
4648c2654abSrjs         if (mtx_owned(&(_inp)->inp_mtx))                                 \
4658c2654abSrjs 		panic("INP Recursive Lock-R");                          \
4668c2654abSrjs         mtx_lock(&(_inp)->inp_mtx);                                     \
4678c2654abSrjs } while (0)
4688c2654abSrjs 
4698c2654abSrjs #define SCTP_INP_WLOCK(_inp)	do { 					\
4708c2654abSrjs         struct sctp_tcb *xx_stcb;					\
4718c2654abSrjs         xx_stcb = LIST_FIRST(&_inp->sctp_asoc_list);                    \
4728c2654abSrjs         if (xx_stcb)                                                     \
4738c2654abSrjs               if (mtx_owned(&(xx_stcb)->tcb_mtx))                        \
4748c2654abSrjs                      panic("I own TCB lock?");                          \
4758c2654abSrjs         if (mtx_owned(&(_inp)->inp_mtx))                                 \
4768c2654abSrjs 		panic("INP Recursive Lock-W");                          \
4778c2654abSrjs         mtx_lock(&(_inp)->inp_mtx);                                     \
4788c2654abSrjs } while (0)
4798c2654abSrjs 
4808c2654abSrjs #else
4818c2654abSrjs void SCTP_INP_RLOCK(struct sctp_inpcb *);
4828c2654abSrjs void SCTP_INP_WLOCK(struct sctp_inpcb *);
4838c2654abSrjs 
4848c2654abSrjs #endif
4858c2654abSrjs 
4868c2654abSrjs 
4878c2654abSrjs #define SCTP_INP_INCR_REF(_inp)        _inp->refcount++
4888c2654abSrjs 
4898c2654abSrjs #define SCTP_INP_DECR_REF(_inp)         do {                                 \
4908c2654abSrjs                                              if (_inp->refcount > 0)          \
4918c2654abSrjs                                                   _inp->refcount--;          \
4928c2654abSrjs                                              else                            \
4938c2654abSrjs                                                   panic("bad inp refcount"); \
4948c2654abSrjs }while (0)
4958c2654abSrjs 
4968c2654abSrjs #define SCTP_ASOC_CREATE_LOCK(_inp)  do {				\
4978c2654abSrjs         if (mtx_owned(&(_inp)->inp_create_mtx))                          \
4988c2654abSrjs 		panic("INP Recursive CREATE");                          \
4998c2654abSrjs         mtx_lock(&(_inp)->inp_create_mtx);                              \
5008c2654abSrjs } while (0)
5018c2654abSrjs 
5028c2654abSrjs #define SCTP_INP_RUNLOCK(_inp)		mtx_unlock(&(_inp)->inp_mtx)
5038c2654abSrjs #define SCTP_INP_WUNLOCK(_inp)		mtx_unlock(&(_inp)->inp_mtx)
5048c2654abSrjs #define SCTP_ASOC_CREATE_UNLOCK(_inp)	mtx_unlock(&(_inp)->inp_create_mtx)
5058c2654abSrjs 
5068c2654abSrjs /* For the majority of things (once we have found the association) we
5078c2654abSrjs  * will lock the actual association mutex. This will protect all
5088c2654abSrjs  * the assoiciation level queues and streams and such. We will
5098c2654abSrjs  * need to lock the socket layer when we stuff data up into
5108c2654abSrjs  * the receiving sb_mb. I.e. we will need to do an extra
5118c2654abSrjs  * SOCKBUF_LOCK(&so->so_rcv) even though the association is
5128c2654abSrjs  * locked.
5138c2654abSrjs  */
5148c2654abSrjs 
5158c2654abSrjs #define SCTP_TCB_LOCK_INIT(_tcb) \
5168c2654abSrjs 	mutex_init(&(_tcb)->tcb_mtx, MUTEX_DEFAULT, IPL_NET)
5178c2654abSrjs #define SCTP_TCB_LOCK_DESTROY(_tcb)	mtx_destroy(&(_tcb)->tcb_mtx)
5188c2654abSrjs #define SCTP_TCB_LOCK(_tcb)  do {					\
5198c2654abSrjs         if (!mtx_owned(&(_tcb->sctp_ep->inp_mtx)))                       \
5208c2654abSrjs 		panic("TCB locking and no INP lock");                   \
5218c2654abSrjs         if (mtx_owned(&(_tcb)->tcb_mtx))                                 \
5228c2654abSrjs 		panic("TCB Lock-recursive");                            \
5238c2654abSrjs 	mtx_lock(&(_tcb)->tcb_mtx);                                     \
5248c2654abSrjs } while (0)
5258c2654abSrjs #define SCTP_TCB_UNLOCK(_tcb)		mtx_unlock(&(_tcb)->tcb_mtx)
5268c2654abSrjs 
5278c2654abSrjs #define SCTP_ITERATOR_LOCK_INIT() \
5288c2654abSrjs         mtx_init(&sctppcbinfo.it_mtx, "sctp", "iterator", MTX_DEF)
5298c2654abSrjs #define SCTP_ITERATOR_LOCK()  do {					\
5308c2654abSrjs         if (mtx_owned(&sctppcbinfo.it_mtx))                              \
5318c2654abSrjs 		panic("Iterator Lock");                                 \
5328c2654abSrjs 	mtx_lock(&sctppcbinfo.it_mtx);                                  \
5338c2654abSrjs } while (0)
5348c2654abSrjs 
5358c2654abSrjs #define SCTP_ITERATOR_UNLOCK()	        mtx_unlock(&sctppcbinfo.it_mtx)
5368c2654abSrjs #define SCTP_ITERATOR_LOCK_DESTROY()	mtx_destroy(&sctppcbinfo.it_mtx)
5378c2654abSrjs #elif 0 /* defined(__NetBSD__) */
5388c2654abSrjs #define SCTP_INP_INFO_LOCK_INIT() \
5398c2654abSrjs 	rw_init(&sctppcbinfo.ipi_ep_mtx)
5408c2654abSrjs 
5418c2654abSrjs #define SCTP_INP_INFO_RLOCK()	do { 					\
5428c2654abSrjs 		rw_enter(&sctppcbinfo.ipi_ep_mtx, RW_READER);           \
5438c2654abSrjs } while (0)
5448c2654abSrjs 
5458c2654abSrjs #define SCTP_INP_INFO_WLOCK()	do { 					\
5468c2654abSrjs              rw_enter(&sctppcbinfo.ipi_ep_mtx, RW_WRITER);              \
5478c2654abSrjs } while (0)
5488c2654abSrjs 
5498c2654abSrjs #define SCTP_INP_INFO_RUNLOCK()		rw_exit(&sctppcbinfo.ipi_ep_mtx)
5508c2654abSrjs #define SCTP_INP_INFO_WUNLOCK()		rw_exit(&sctppcbinfo.ipi_ep_mtx)
5518c2654abSrjs 
5528c2654abSrjs /* The INP locks we will use for locking an SCTP endpoint, so for
5538c2654abSrjs  * example if we want to change something at the endpoint level for
554a2f9ec55Sriastradh  * example cookie secrets we lock the INP level.
5558c2654abSrjs  */
5568c2654abSrjs #define SCTP_INP_LOCK_INIT(_inp) \
5578c2654abSrjs 	mutex_init(&(_inp)->inp_mtx, MUTEX_DEFAULT, IPL_NET)
5588c2654abSrjs 
5598c2654abSrjs #define SCTP_ASOC_CREATE_LOCK_INIT(_inp) \
5608c2654abSrjs 	mutex_init(&(_inp)->inp_create_mtx, MUTEX_DEFAULT, IPL_NET)
5618c2654abSrjs 
5628c2654abSrjs #define SCTP_INP_LOCK_DESTROY(_inp)	mutex_destroy(&(_inp)->inp_mtx)
5638c2654abSrjs #define SCTP_ASOC_CREATE_LOCK_DESTROY(_inp)	mutex_destroy(&(_inp)->inp_create_mtx)
5648c2654abSrjs 
5658c2654abSrjs #define SCTP_INP_RLOCK(_inp)	do { 					\
5668c2654abSrjs 	mutex_enter(&(_inp)->inp_mtx);                                  \
5678c2654abSrjs } while (0)
5688c2654abSrjs 
5698c2654abSrjs #define SCTP_INP_WLOCK(_inp)	do { 					\
5708c2654abSrjs 	mutex_enter(&(_inp)->inp_mtx);                                  \
5718c2654abSrjs } while (0)
5728c2654abSrjs 
5738c2654abSrjs 
5748c2654abSrjs #define SCTP_INP_INCR_REF(_inp) atomic_add_int(&((_inp)->refcount), 1)
5758c2654abSrjs 
5768c2654abSrjs #define SCTP_INP_DECR_REF(_inp) atomic_add_int(&((_inp)->refcount), -1)
5778c2654abSrjs 
5788c2654abSrjs #define SCTP_ASOC_CREATE_LOCK(_inp)  do {				\
5798c2654abSrjs         mutex_enter(&(_inp)->inp_create_mtx);                              \
5808c2654abSrjs } while (0)
5818c2654abSrjs 
5828c2654abSrjs #define SCTP_INP_RUNLOCK(_inp)		mutex_exit(&(_inp)->inp_mtx)
5838c2654abSrjs #define SCTP_INP_WUNLOCK(_inp)		mutex_exit(&(_inp)->inp_mtx)
5848c2654abSrjs #define SCTP_ASOC_CREATE_UNLOCK(_inp)	mutex_exit(&(_inp)->inp_create_mtx)
5858c2654abSrjs 
5868c2654abSrjs /* For the majority of things (once we have found the association) we
5878c2654abSrjs  * will lock the actual association mutex. This will protect all
5888c2654abSrjs  * the assoiciation level queues and streams and such. We will
5898c2654abSrjs  * need to lock the socket layer when we stuff data up into
5908c2654abSrjs  * the receiving sb_mb. I.e. we will need to do an extra
5918c2654abSrjs  * SOCKBUF_LOCK(&so->so_rcv) even though the association is
5928c2654abSrjs  * locked.
5938c2654abSrjs  */
5948c2654abSrjs 
5958c2654abSrjs #define SCTP_TCB_LOCK_INIT(_tcb) \
5968c2654abSrjs 	mutex_init(&(_tcb)->tcb_mtx, MUTEX_DEFAULT, IPL_NET)
5978c2654abSrjs #define SCTP_TCB_LOCK_DESTROY(_tcb)	mutex_destroy(&(_tcb)->tcb_mtx)
5988c2654abSrjs #define SCTP_TCB_LOCK(_tcb)  do {					\
5998c2654abSrjs 	mutex_enter(&(_tcb)->tcb_mtx);                                     \
6008c2654abSrjs } while (0)
6018c2654abSrjs #define SCTP_TCB_UNLOCK(_tcb)		mutex_exit(&(_tcb)->tcb_mtx)
6028c2654abSrjs 
6038c2654abSrjs #define SCTP_ITERATOR_LOCK_INIT() \
6048c2654abSrjs         mutex_init(&sctppcbinfo.it_mtx, MUTEX_DEFAULT, IPL_NET)
6058c2654abSrjs #define SCTP_ITERATOR_LOCK()  do {					\
6068c2654abSrjs         if (mutex_owned(&sctppcbinfo.it_mtx))                           \
6078c2654abSrjs 		panic("Iterator Lock");                                 \
6088c2654abSrjs 	mutex_enter(&sctppcbinfo.it_mtx);                               \
6098c2654abSrjs } while (0)
6108c2654abSrjs 
6118c2654abSrjs #define SCTP_ITERATOR_UNLOCK()	        mutex_exit(&sctppcbinfo.it_mtx)
6128c2654abSrjs #define SCTP_ITERATOR_LOCK_DESTROY()	mutex_destroy(&sctppcbinfo.it_mtx)
6138c2654abSrjs #else
6148c2654abSrjs 
6158c2654abSrjs /* Empty Lock declarations for all other
6168c2654abSrjs  * platforms pre-process away to nothing.
6178c2654abSrjs  */
6188c2654abSrjs 
6198c2654abSrjs /* Lock for INFO stuff */
6208c2654abSrjs #define SCTP_INP_INFO_LOCK_INIT()
6218c2654abSrjs #define SCTP_INP_INFO_RLOCK()
6228c2654abSrjs #define SCTP_INP_INFO_RLOCK()
6238c2654abSrjs #define SCTP_INP_INFO_WLOCK()
6248c2654abSrjs 
6258c2654abSrjs #define SCTP_INP_INFO_RUNLOCK()
6268c2654abSrjs #define SCTP_INP_INFO_WUNLOCK()
6278c2654abSrjs /* Lock for INP */
6288c2654abSrjs #define SCTP_INP_LOCK_INIT(_inp)
6298c2654abSrjs #define SCTP_INP_LOCK_DESTROY(_inp)
6308c2654abSrjs #define SCTP_INP_RLOCK(_inp)
6318c2654abSrjs #define SCTP_INP_RUNLOCK(_inp)
6328c2654abSrjs #define SCTP_INP_WLOCK(_inp)
6338c2654abSrjs #define SCTP_INP_INCR_REF(_inp)
6348c2654abSrjs #define SCTP_INP_DECR_REF(_inp)
6358c2654abSrjs #define SCTP_INP_WUNLOCK(_inp)
6368c2654abSrjs #define SCTP_ASOC_CREATE_LOCK_INIT(_inp)
6378c2654abSrjs #define SCTP_ASOC_CREATE_LOCK_DESTROY(_inp)
6388c2654abSrjs #define SCTP_ASOC_CREATE_LOCK(_inp)
6398c2654abSrjs #define SCTP_ASOC_CREATE_UNLOCK(_inp)
6408c2654abSrjs /* Lock for TCB */
6418c2654abSrjs #define SCTP_TCB_LOCK_INIT(_tcb)
6428c2654abSrjs #define SCTP_TCB_LOCK_DESTROY(_tcb)
6438c2654abSrjs #define SCTP_TCB_LOCK(_tcb)
6448c2654abSrjs #define SCTP_TCB_UNLOCK(_tcb)
6458c2654abSrjs /* iterator locks */
6468c2654abSrjs #define SCTP_ITERATOR_LOCK_INIT()
6478c2654abSrjs #define SCTP_ITERATOR_LOCK()
6488c2654abSrjs #define SCTP_ITERATOR_UNLOCK()
6498c2654abSrjs #define SCTP_ITERATOR_LOCK_DESTROY()
6508c2654abSrjs #endif
6518c2654abSrjs 
6528c2654abSrjs #if defined(_KERNEL)
6538c2654abSrjs 
6548c2654abSrjs extern struct sctp_epinfo sctppcbinfo;
6558c2654abSrjs extern int sctp_auto_asconf;
6568c2654abSrjs 
6578c2654abSrjs int SCTP6_ARE_ADDR_EQUAL(const struct in6_addr *a, const struct in6_addr *b);
6588c2654abSrjs 
6598c2654abSrjs void sctp_fill_pcbinfo(struct sctp_pcbinfo *);
6608c2654abSrjs 
6618c2654abSrjs struct sctp_nets *sctp_findnet(struct sctp_tcb *, struct sockaddr *);
6628c2654abSrjs 
6638c2654abSrjs struct sctp_inpcb *sctp_pcb_findep(struct sockaddr *, int, int);
6648c2654abSrjs 
6658c2654abSrjs int sctp_inpcb_bind(struct socket *, struct sockaddr *, struct lwp *);
6668c2654abSrjs 
6678c2654abSrjs struct sctp_tcb *sctp_findassociation_addr(struct mbuf *, int, int,
6688c2654abSrjs     struct sctphdr *, struct sctp_chunkhdr *, struct sctp_inpcb **,
6698c2654abSrjs     struct sctp_nets **);
6708c2654abSrjs 
6718c2654abSrjs struct sctp_tcb *sctp_findassociation_addr_sa(struct sockaddr *,
6728c2654abSrjs 	struct sockaddr *, struct sctp_inpcb **, struct sctp_nets **, int);
6738c2654abSrjs 
6748c2654abSrjs void sctp_move_pcb_and_assoc(struct sctp_inpcb *, struct sctp_inpcb *,
6758c2654abSrjs 	struct sctp_tcb *);
6768c2654abSrjs 
6778c2654abSrjs /*
6788c2654abSrjs  * For this call ep_addr, the to is the destination endpoint address
6798c2654abSrjs  * of the peer (relative to outbound). The from field is only used if
6808c2654abSrjs  * the TCP model is enabled and helps distingush amongst the subset
6818c2654abSrjs  * bound (non-boundall). The TCP model MAY change the actual ep field,
6828c2654abSrjs  * this is why it is passed.
6838c2654abSrjs  */
6848c2654abSrjs struct sctp_tcb *sctp_findassociation_ep_addr(struct sctp_inpcb **,
6858c2654abSrjs 	struct sockaddr *, struct sctp_nets **, struct sockaddr *, struct sctp_tcb *);
6868c2654abSrjs 
6878c2654abSrjs struct sctp_tcb *sctp_findassociation_ep_asocid(struct sctp_inpcb *, vaddr_t);
6888c2654abSrjs 
6898c2654abSrjs struct sctp_tcb *sctp_findassociation_ep_asconf(struct mbuf *, int, int,
6908c2654abSrjs     struct sctphdr *, struct sctp_inpcb **, struct sctp_nets **);
6918c2654abSrjs 
6928c2654abSrjs int sctp_inpcb_alloc(struct socket *);
6938c2654abSrjs 
6948c2654abSrjs 
6958c2654abSrjs int sctp_is_address_on_local_host(struct sockaddr *addr);
6968c2654abSrjs 
6978c2654abSrjs void sctp_inpcb_free(struct sctp_inpcb *, int);
6988c2654abSrjs 
6998c2654abSrjs struct sctp_tcb *sctp_aloc_assoc(struct sctp_inpcb *, struct sockaddr *,
7008c2654abSrjs 	int, int *, uint32_t);
7018c2654abSrjs 
7028c2654abSrjs void sctp_free_assoc(struct sctp_inpcb *, struct sctp_tcb *);
7038c2654abSrjs 
7048c2654abSrjs int sctp_add_local_addr_ep(struct sctp_inpcb *, struct ifaddr *);
7058c2654abSrjs 
7068c2654abSrjs int sctp_insert_laddr(struct sctpladdr *, struct ifaddr *);
7078c2654abSrjs 
7088c2654abSrjs void sctp_remove_laddr(struct sctp_laddr *);
7098c2654abSrjs 
7108c2654abSrjs int sctp_del_local_addr_ep(struct sctp_inpcb *, struct ifaddr *);
7118c2654abSrjs 
7128c2654abSrjs int sctp_del_local_addr_ep_sa(struct sctp_inpcb *, struct sockaddr *);
7138c2654abSrjs 
7148c2654abSrjs int sctp_add_remote_addr(struct sctp_tcb *, struct sockaddr *, int, int);
7158c2654abSrjs 
7168c2654abSrjs int sctp_del_remote_addr(struct sctp_tcb *, struct sockaddr *);
7178c2654abSrjs 
7188c2654abSrjs void sctp_pcb_init(void);
7198c2654abSrjs 
7208c2654abSrjs void sctp_free_remote_addr(struct sctp_nets *);
7218c2654abSrjs 
7228c2654abSrjs int sctp_add_local_addr_assoc(struct sctp_tcb *, struct ifaddr *);
7238c2654abSrjs 
7248c2654abSrjs int sctp_del_local_addr_assoc(struct sctp_tcb *, struct ifaddr *);
7258c2654abSrjs 
7268c2654abSrjs int sctp_del_local_addr_assoc_sa(struct sctp_tcb *, struct sockaddr *);
7278c2654abSrjs 
7288c2654abSrjs int sctp_load_addresses_from_init(struct sctp_tcb *, struct mbuf *, int, int,
7298c2654abSrjs     int, struct sctphdr *, struct sockaddr *);
7308c2654abSrjs 
7318c2654abSrjs int sctp_set_primary_addr(struct sctp_tcb *, struct sockaddr *, struct sctp_nets *);
7328c2654abSrjs 
7338c2654abSrjs int sctp_is_vtag_good(struct sctp_inpcb *, uint32_t, struct timeval *);
7348c2654abSrjs 
7358c2654abSrjs /*void sctp_drain(void);*/
7368c2654abSrjs 
7378c2654abSrjs int sctp_destination_is_reachable(struct sctp_tcb *, const struct sockaddr *);
7388c2654abSrjs 
7398c2654abSrjs int sctp_add_to_socket_q(struct sctp_inpcb *, struct sctp_tcb *);
7408c2654abSrjs 
7418c2654abSrjs struct sctp_tcb *sctp_remove_from_socket_q(struct sctp_inpcb *);
7428c2654abSrjs 
7438c2654abSrjs 
7448c2654abSrjs /* Null in last arg inpcb indicate run on ALL ep's. Specific
7458c2654abSrjs  * inp in last arg indicates run on ONLY assoc's of the
7468c2654abSrjs  * specified endpoint.
7478c2654abSrjs  */
7488c2654abSrjs int
7498c2654abSrjs sctp_initiate_iterator(asoc_func af, uint32_t, uint32_t, void *, uint32_t,
7508c2654abSrjs 		       end_func ef, struct sctp_inpcb *);
7518c2654abSrjs 
752a050c7fbSrjs void in6_sin6_2_sin (struct sockaddr_in *,
7538c2654abSrjs                             struct sockaddr_in6 *sin6);
7548c2654abSrjs 
755f8c27a68Sozaki-r #ifdef __NetBSD__
756f8c27a68Sozaki-r #ifndef sotoin6pcb
7577118c214Sozaki-r #define sotoin6pcb(so)	((struct in6pcb *)((so)->so_pcb))
758f8c27a68Sozaki-r #endif
759f8c27a68Sozaki-r #ifndef in6p_flags
7607118c214Sozaki-r #define in6p_flags	in6p_pcb.inp_flags
761f8c27a68Sozaki-r #endif
762f8c27a68Sozaki-r #ifndef in6p_af
7637118c214Sozaki-r #define in6p_af		in6p_pcb.inp_af
764f8c27a68Sozaki-r #endif
765f8c27a68Sozaki-r #ifndef inpcb_hdr
766f8c27a68Sozaki-r #define inpcb_hdr	inpcb
767f8c27a68Sozaki-r #endif
768f8c27a68Sozaki-r #ifndef sp_inph
769f8c27a68Sozaki-r #define sp_inph		sp_inp
770f8c27a68Sozaki-r #endif
771f8c27a68Sozaki-r #endif
772f8c27a68Sozaki-r 
7738c2654abSrjs #endif /* _KERNEL */
7748c2654abSrjs #endif /* !__SCTP_PCB_H__ */
775