1163953Srrs/*-
2169382Srrs * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
3235828Stuexen * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
4235828Stuexen * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
5163953Srrs *
6163953Srrs * Redistribution and use in source and binary forms, with or without
7163953Srrs * modification, are permitted provided that the following conditions are met:
8163953Srrs *
9163953Srrs * a) Redistributions of source code must retain the above copyright notice,
10163953Srrs *   this list of conditions and the following disclaimer.
11163953Srrs *
12163953Srrs * b) Redistributions in binary form must reproduce the above copyright
13163953Srrs *    notice, this list of conditions and the following disclaimer in
14163953Srrs *   the documentation and/or other materials provided with the distribution.
15163953Srrs *
16163953Srrs * c) Neither the name of Cisco Systems, Inc. nor the names of its
17163953Srrs *    contributors may be used to endorse or promote products derived
18163953Srrs *    from this software without specific prior written permission.
19163953Srrs *
20163953Srrs * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21163953Srrs * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22163953Srrs * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23163953Srrs * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24163953Srrs * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25163953Srrs * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26163953Srrs * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27163953Srrs * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28163953Srrs * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29163953Srrs * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30163953Srrs * THE POSSIBILITY OF SUCH DAMAGE.
31163953Srrs */
32163953Srrs
33235828Stuexen#include <sys/cdefs.h>
34235828Stuexen__FBSDID("$FreeBSD$");
35235828Stuexen
36235828Stuexen#ifndef _NETINET_SCTP_LOCK_BSD_H_
37235828Stuexen#define _NETINET_SCTP_LOCK_BSD_H_
38235828Stuexen
39163953Srrs/*
40163953Srrs * General locking concepts: The goal of our locking is to of course provide
41163953Srrs * consistency and yet minimize overhead. We will attempt to use
42163953Srrs * non-recursive locks which are supposed to be quite inexpensive. Now in
43163953Srrs * order to do this the goal is that most functions are not aware of locking.
44163953Srrs * Once we have a TCB we lock it and unlock when we are through. This means
45163953Srrs * that the TCB lock is kind-of a "global" lock when working on an
46163953Srrs * association. Caution must be used when asserting a TCB_LOCK since if we
47163953Srrs * recurse we deadlock.
48163953Srrs *
49163953Srrs * Most other locks (INP and INFO) attempt to localize the locking i.e. we try
50163953Srrs * to contain the lock and unlock within the function that needs to lock it.
51163953Srrs * This sometimes mean we do extra locks and unlocks and lose a bit of
52163953Srrs * efficency, but if the performance statements about non-recursive locks are
53163953Srrs * true this should not be a problem.  One issue that arises with this only
54163953Srrs * lock when needed is that if an implicit association setup is done we have
55163953Srrs * a problem. If at the time I lookup an association I have NULL in the tcb
56163953Srrs * return, by the time I call to create the association some other processor
57163953Srrs * could have created it. This is what the CREATE lock on the endpoint.
58163953Srrs * Places where we will be implicitly creating the association OR just
59163953Srrs * creating an association (the connect call) will assert the CREATE_INP
60163953Srrs * lock. This will assure us that during all the lookup of INP and INFO if
61163953Srrs * another creator is also locking/looking up we can gate the two to
62163953Srrs * synchronize. So the CREATE_INP lock is also another one we must use
63163953Srrs * extreme caution in locking to make sure we don't hit a re-entrancy issue.
64163953Srrs *
65163953Srrs * For non FreeBSD 5.x we provide a bunch of EMPTY lock macros so we can
66163953Srrs * blatantly put locks everywhere and they reduce to nothing on
67163953Srrs * NetBSD/OpenBSD and FreeBSD 4.x
68163953Srrs *
69163953Srrs */
70163953Srrs
71163953Srrs/*
72163953Srrs * When working with the global SCTP lists we lock and unlock the INP_INFO
73163953Srrs * lock. So when we go to lookup an association we will want to do a
74163953Srrs * SCTP_INP_INFO_RLOCK() and then when we want to add a new association to
75179783Srrs * the SCTP_BASE_INFO() list's we will do a SCTP_INP_INFO_WLOCK().
76163953Srrs */
77163953Srrs
78165220Srrsextern struct sctp_foo_stuff sctp_logoff[];
79165220Srrsextern int sctp_logoff_stuff;
80165220Srrs
81163953Srrs#define SCTP_IPI_COUNT_INIT()
82163953Srrs
83163953Srrs#define SCTP_STATLOG_INIT_LOCK()
84163953Srrs#define SCTP_STATLOG_LOCK()
85163953Srrs#define SCTP_STATLOG_UNLOCK()
86163953Srrs#define SCTP_STATLOG_DESTROY()
87163953Srrs
88172218Srrs#define SCTP_INP_INFO_LOCK_DESTROY() do { \
89179783Srrs        if(rw_wowned(&SCTP_BASE_INFO(ipi_ep_mtx))) { \
90179783Srrs             rw_wunlock(&SCTP_BASE_INFO(ipi_ep_mtx)); \
91172218Srrs        } \
92179783Srrs        rw_destroy(&SCTP_BASE_INFO(ipi_ep_mtx)); \
93172218Srrs      }  while (0)
94163953Srrs
95163953Srrs#define SCTP_INP_INFO_LOCK_INIT() \
96179783Srrs        rw_init(&SCTP_BASE_INFO(ipi_ep_mtx), "sctp-info");
97163953Srrs
98163953Srrs
99163953Srrs#define SCTP_INP_INFO_RLOCK()	do { 					\
100179783Srrs             rw_rlock(&SCTP_BASE_INFO(ipi_ep_mtx));                         \
101163953Srrs} while (0)
102163953Srrs
103218211Srrs#define SCTP_MCORE_QLOCK_INIT(cpstr) do { \
104218211Srrs		mtx_init(&(cpstr)->que_mtx,	      \
105218211Srrs			 "sctp-mcore_queue","queue_lock",	\
106218211Srrs			 MTX_DEF|MTX_DUPOK);		\
107218211Srrs} while (0)
108163953Srrs
109218211Srrs#define SCTP_MCORE_QLOCK(cpstr)  do { \
110218211Srrs		mtx_lock(&(cpstr)->que_mtx);	\
111218211Srrs} while (0)
112218211Srrs
113218211Srrs#define SCTP_MCORE_QUNLOCK(cpstr)  do { \
114218211Srrs		mtx_unlock(&(cpstr)->que_mtx);	\
115218211Srrs} while (0)
116218211Srrs
117218211Srrs#define SCTP_MCORE_QDESTROY(cpstr)  do { \
118218211Srrs	if(mtx_owned(&(cpstr)->core_mtx)) {	\
119218211Srrs		mtx_unlock(&(cpstr)->que_mtx);	\
120218211Srrs        } \
121218211Srrs	mtx_destroy(&(cpstr)->que_mtx);	\
122218211Srrs} while (0)
123218211Srrs
124218211Srrs
125218211Srrs#define SCTP_MCORE_LOCK_INIT(cpstr) do { \
126218211Srrs		mtx_init(&(cpstr)->core_mtx,	      \
127218211Srrs			 "sctp-cpulck","cpu_proc_lock",	\
128218211Srrs			 MTX_DEF|MTX_DUPOK);		\
129218211Srrs} while (0)
130218211Srrs
131218211Srrs#define SCTP_MCORE_LOCK(cpstr)  do { \
132218211Srrs		mtx_lock(&(cpstr)->core_mtx);	\
133218211Srrs} while (0)
134218211Srrs
135218211Srrs#define SCTP_MCORE_UNLOCK(cpstr)  do { \
136218211Srrs		mtx_unlock(&(cpstr)->core_mtx);	\
137218211Srrs} while (0)
138218211Srrs
139218211Srrs#define SCTP_MCORE_DESTROY(cpstr)  do { \
140218211Srrs	if(mtx_owned(&(cpstr)->core_mtx)) {	\
141218211Srrs		mtx_unlock(&(cpstr)->core_mtx);	\
142218211Srrs        } \
143218211Srrs	mtx_destroy(&(cpstr)->core_mtx);	\
144218211Srrs} while (0)
145218211Srrs
146163953Srrs#define SCTP_INP_INFO_WLOCK()	do { 					\
147179783Srrs            rw_wlock(&SCTP_BASE_INFO(ipi_ep_mtx));                         \
148163953Srrs} while (0)
149163953Srrs
150163953Srrs
151179783Srrs#define SCTP_INP_INFO_RUNLOCK()		rw_runlock(&SCTP_BASE_INFO(ipi_ep_mtx))
152179783Srrs#define SCTP_INP_INFO_WUNLOCK()		rw_wunlock(&SCTP_BASE_INFO(ipi_ep_mtx))
153172218Srrs
154172218Srrs
155208160Srrs#define SCTP_IPI_ADDR_INIT()								\
156179783Srrs        rw_init(&SCTP_BASE_INFO(ipi_addr_mtx), "sctp-addr")
157172218Srrs#define SCTP_IPI_ADDR_DESTROY() do  { \
158179783Srrs        if(rw_wowned(&SCTP_BASE_INFO(ipi_addr_mtx))) { \
159179783Srrs             rw_wunlock(&SCTP_BASE_INFO(ipi_addr_mtx)); \
160172218Srrs        } \
161179783Srrs	rw_destroy(&SCTP_BASE_INFO(ipi_addr_mtx)); \
162172218Srrs      }  while (0)
163172218Srrs#define SCTP_IPI_ADDR_RLOCK()	do { 					\
164179783Srrs             rw_rlock(&SCTP_BASE_INFO(ipi_addr_mtx));                         \
165163953Srrs} while (0)
166172218Srrs#define SCTP_IPI_ADDR_WLOCK()	do { 					\
167179783Srrs             rw_wlock(&SCTP_BASE_INFO(ipi_addr_mtx));                         \
168172218Srrs} while (0)
169163953Srrs
170179783Srrs#define SCTP_IPI_ADDR_RUNLOCK()		rw_runlock(&SCTP_BASE_INFO(ipi_addr_mtx))
171179783Srrs#define SCTP_IPI_ADDR_WUNLOCK()		rw_wunlock(&SCTP_BASE_INFO(ipi_addr_mtx))
172167598Srrs
173172218Srrs
174167598Srrs#define SCTP_IPI_ITERATOR_WQ_INIT() \
175208160Srrs        mtx_init(&sctp_it_ctl.ipi_iterator_wq_mtx, "sctp-it-wq", "sctp_it_wq", MTX_DEF)
176167598Srrs
177167598Srrs#define SCTP_IPI_ITERATOR_WQ_DESTROY() \
178208160Srrs	mtx_destroy(&sctp_it_ctl.ipi_iterator_wq_mtx)
179167598Srrs
180167598Srrs#define SCTP_IPI_ITERATOR_WQ_LOCK()	do { 					\
181208160Srrs             mtx_lock(&sctp_it_ctl.ipi_iterator_wq_mtx);                \
182167598Srrs} while (0)
183167598Srrs
184208160Srrs#define SCTP_IPI_ITERATOR_WQ_UNLOCK()		mtx_unlock(&sctp_it_ctl.ipi_iterator_wq_mtx)
185167598Srrs
186167598Srrs
187170091Srrs#define SCTP_IP_PKTLOG_INIT() \
188179783Srrs        mtx_init(&SCTP_BASE_INFO(ipi_pktlog_mtx), "sctp-pktlog", "packetlog", MTX_DEF)
189167598Srrs
190167598Srrs
191170091Srrs#define SCTP_IP_PKTLOG_LOCK()	do { 			\
192179783Srrs             mtx_lock(&SCTP_BASE_INFO(ipi_pktlog_mtx));     \
193170091Srrs} while (0)
194167598Srrs
195179783Srrs#define SCTP_IP_PKTLOG_UNLOCK()	mtx_unlock(&SCTP_BASE_INFO(ipi_pktlog_mtx))
196170091Srrs
197170091Srrs#define SCTP_IP_PKTLOG_DESTROY() \
198179783Srrs	mtx_destroy(&SCTP_BASE_INFO(ipi_pktlog_mtx))
199170091Srrs
200170091Srrs
201170091Srrs
202170091Srrs
203163953Srrs
204163953Srrs/*
205163953Srrs * The INP locks we will use for locking an SCTP endpoint, so for example if
206163953Srrs * we want to change something at the endpoint level for example random_store
207163953Srrs * or cookie secrets we lock the INP level.
208163953Srrs */
209163953Srrs
210163953Srrs#define SCTP_INP_READ_INIT(_inp) \
211163953Srrs	mtx_init(&(_inp)->inp_rdata_mtx, "sctp-read", "inpr", MTX_DEF | MTX_DUPOK)
212163953Srrs
213163953Srrs#define SCTP_INP_READ_DESTROY(_inp) \
214163953Srrs	mtx_destroy(&(_inp)->inp_rdata_mtx)
215163953Srrs
216163953Srrs#define SCTP_INP_READ_LOCK(_inp)	do { \
217163953Srrs        mtx_lock(&(_inp)->inp_rdata_mtx);    \
218163953Srrs} while (0)
219163953Srrs
220163953Srrs
221163953Srrs#define SCTP_INP_READ_UNLOCK(_inp) mtx_unlock(&(_inp)->inp_rdata_mtx)
222163953Srrs
223163953Srrs
224163953Srrs#define SCTP_INP_LOCK_INIT(_inp) \
225163953Srrs	mtx_init(&(_inp)->inp_mtx, "sctp-inp", "inp", MTX_DEF | MTX_DUPOK)
226163953Srrs#define SCTP_ASOC_CREATE_LOCK_INIT(_inp) \
227163953Srrs	mtx_init(&(_inp)->inp_create_mtx, "sctp-create", "inp_create", \
228163953Srrs		 MTX_DEF | MTX_DUPOK)
229163953Srrs
230163953Srrs#define SCTP_INP_LOCK_DESTROY(_inp) \
231163953Srrs	mtx_destroy(&(_inp)->inp_mtx)
232163953Srrs
233208879Srrs#define SCTP_INP_LOCK_CONTENDED(_inp) ((_inp)->inp_mtx.mtx_lock & MTX_CONTESTED)
234208879Srrs
235208879Srrs#define SCTP_INP_READ_CONTENDED(_inp) ((_inp)->inp_rdata_mtx.mtx_lock & MTX_CONTESTED)
236208879Srrs
237208879Srrs#define SCTP_ASOC_CREATE_LOCK_CONTENDED(_inp) ((_inp)->inp_create_mtx.mtx_lock & MTX_CONTESTED)
238208879Srrs
239208879Srrs
240163953Srrs#define SCTP_ASOC_CREATE_LOCK_DESTROY(_inp) \
241163953Srrs	mtx_destroy(&(_inp)->inp_create_mtx)
242163953Srrs
243163953Srrs
244163953Srrs#ifdef SCTP_LOCK_LOGGING
245163953Srrs#define SCTP_INP_RLOCK(_inp)	do { 					\
246179786Srrs	if(SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) sctp_log_lock(_inp, (struct sctp_tcb *)NULL, SCTP_LOG_LOCK_INP);\
247163953Srrs        mtx_lock(&(_inp)->inp_mtx);                                     \
248163953Srrs} while (0)
249163953Srrs
250163953Srrs#define SCTP_INP_WLOCK(_inp)	do { 					\
251179786Srrs	if(SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) sctp_log_lock(_inp, (struct sctp_tcb *)NULL, SCTP_LOG_LOCK_INP);\
252163953Srrs        mtx_lock(&(_inp)->inp_mtx);                                     \
253163953Srrs} while (0)
254163953Srrs
255163953Srrs#else
256163953Srrs
257163953Srrs#define SCTP_INP_RLOCK(_inp)	do { 					\
258163953Srrs        mtx_lock(&(_inp)->inp_mtx);                                     \
259163953Srrs} while (0)
260163953Srrs
261163953Srrs#define SCTP_INP_WLOCK(_inp)	do { 					\
262163953Srrs        mtx_lock(&(_inp)->inp_mtx);                                     \
263163953Srrs} while (0)
264163953Srrs
265163953Srrs#endif
266163953Srrs
267163953Srrs
268163953Srrs#define SCTP_TCB_SEND_LOCK_INIT(_tcb) \
269163953Srrs	mtx_init(&(_tcb)->tcb_send_mtx, "sctp-send-tcb", "tcbs", MTX_DEF | MTX_DUPOK)
270163953Srrs
271163953Srrs#define SCTP_TCB_SEND_LOCK_DESTROY(_tcb) mtx_destroy(&(_tcb)->tcb_send_mtx)
272163953Srrs
273163953Srrs#define SCTP_TCB_SEND_LOCK(_tcb)  do { \
274163953Srrs	mtx_lock(&(_tcb)->tcb_send_mtx); \
275163953Srrs} while (0)
276163953Srrs
277163953Srrs#define SCTP_TCB_SEND_UNLOCK(_tcb) mtx_unlock(&(_tcb)->tcb_send_mtx)
278163953Srrs
279163953Srrs#define SCTP_INP_INCR_REF(_inp) atomic_add_int(&((_inp)->refcount), 1)
280163953Srrs#define SCTP_INP_DECR_REF(_inp) atomic_add_int(&((_inp)->refcount), -1)
281163953Srrs
282165220Srrs
283163953Srrs#ifdef SCTP_LOCK_LOGGING
284163953Srrs#define SCTP_ASOC_CREATE_LOCK(_inp) \
285163953Srrs	do {								\
286179786Srrs	if(SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) sctp_log_lock(_inp, (struct sctp_tcb *)NULL, SCTP_LOG_LOCK_CREATE); \
287163953Srrs		mtx_lock(&(_inp)->inp_create_mtx);			\
288163953Srrs	} while (0)
289163953Srrs#else
290163953Srrs
291163953Srrs#define SCTP_ASOC_CREATE_LOCK(_inp) \
292163953Srrs	do {								\
293163953Srrs		mtx_lock(&(_inp)->inp_create_mtx);			\
294163953Srrs	} while (0)
295163953Srrs#endif
296163953Srrs
297163953Srrs#define SCTP_INP_RUNLOCK(_inp)		mtx_unlock(&(_inp)->inp_mtx)
298163953Srrs#define SCTP_INP_WUNLOCK(_inp)		mtx_unlock(&(_inp)->inp_mtx)
299163953Srrs#define SCTP_ASOC_CREATE_UNLOCK(_inp)	mtx_unlock(&(_inp)->inp_create_mtx)
300163953Srrs
301163953Srrs/*
302163953Srrs * For the majority of things (once we have found the association) we will
303163953Srrs * lock the actual association mutex. This will protect all the assoiciation
304163953Srrs * level queues and streams and such. We will need to lock the socket layer
305163953Srrs * when we stuff data up into the receiving sb_mb. I.e. we will need to do an
306163953Srrs * extra SOCKBUF_LOCK(&so->so_rcv) even though the association is locked.
307163953Srrs */
308163953Srrs
309163953Srrs#define SCTP_TCB_LOCK_INIT(_tcb) \
310163953Srrs	mtx_init(&(_tcb)->tcb_mtx, "sctp-tcb", "tcb", MTX_DEF | MTX_DUPOK)
311163953Srrs
312163953Srrs#define SCTP_TCB_LOCK_DESTROY(_tcb)	mtx_destroy(&(_tcb)->tcb_mtx)
313163953Srrs
314163953Srrs#ifdef SCTP_LOCK_LOGGING
315163953Srrs#define SCTP_TCB_LOCK(_tcb)  do {					\
316179786Srrs	if(SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE)  sctp_log_lock(_tcb->sctp_ep, _tcb, SCTP_LOG_LOCK_TCB);          \
317163953Srrs	mtx_lock(&(_tcb)->tcb_mtx);                                     \
318163953Srrs} while (0)
319163953Srrs
320163953Srrs#else
321163953Srrs#define SCTP_TCB_LOCK(_tcb)  do {					\
322163953Srrs	mtx_lock(&(_tcb)->tcb_mtx);                                     \
323163953Srrs} while (0)
324163953Srrs
325163953Srrs#endif
326163953Srrs
327163953Srrs
328163953Srrs#define SCTP_TCB_TRYLOCK(_tcb) 	mtx_trylock(&(_tcb)->tcb_mtx)
329163953Srrs
330163953Srrs#define SCTP_TCB_UNLOCK(_tcb)		mtx_unlock(&(_tcb)->tcb_mtx)
331163953Srrs
332163953Srrs#define SCTP_TCB_UNLOCK_IFOWNED(_tcb)	      do { \
333163953Srrs                                                if (mtx_owned(&(_tcb)->tcb_mtx)) \
334163953Srrs                                                     mtx_unlock(&(_tcb)->tcb_mtx); \
335163953Srrs                                              } while (0)
336163953Srrs
337163953Srrs
338163953Srrs
339163953Srrs#ifdef INVARIANTS
340163953Srrs#define SCTP_TCB_LOCK_ASSERT(_tcb) do { \
341163953Srrs                            if (mtx_owned(&(_tcb)->tcb_mtx) == 0) \
342163953Srrs                                panic("Don't own TCB lock"); \
343163953Srrs                            } while (0)
344163953Srrs#else
345163953Srrs#define SCTP_TCB_LOCK_ASSERT(_tcb)
346163953Srrs#endif
347163953Srrs
348163953Srrs#define SCTP_ITERATOR_LOCK_INIT() \
349208160Srrs        mtx_init(&sctp_it_ctl.it_mtx, "sctp-it", "iterator", MTX_DEF)
350163953Srrs
351163953Srrs#ifdef INVARIANTS
352163953Srrs#define SCTP_ITERATOR_LOCK() \
353163953Srrs	do {								\
354208160Srrs		if (mtx_owned(&sctp_it_ctl.it_mtx))			\
355163953Srrs			panic("Iterator Lock");				\
356208160Srrs		mtx_lock(&sctp_it_ctl.it_mtx);				\
357163953Srrs	} while (0)
358163953Srrs#else
359163953Srrs#define SCTP_ITERATOR_LOCK() \
360163953Srrs	do {								\
361208160Srrs		mtx_lock(&sctp_it_ctl.it_mtx);				\
362163953Srrs	} while (0)
363163953Srrs
364163953Srrs#endif
365163953Srrs
366208160Srrs#define SCTP_ITERATOR_UNLOCK()	        mtx_unlock(&sctp_it_ctl.it_mtx)
367208160Srrs#define SCTP_ITERATOR_LOCK_DESTROY()	mtx_destroy(&sctp_it_ctl.it_mtx)
368163953Srrs
369163953Srrs
370208160Srrs#define SCTP_WQ_ADDR_INIT() do { \
371208160Srrs        mtx_init(&SCTP_BASE_INFO(wq_addr_mtx), "sctp-addr-wq","sctp_addr_wq",MTX_DEF); \
372208160Srrs } while (0)
373208160Srrs
374208160Srrs#define SCTP_WQ_ADDR_DESTROY() do  { \
375208160Srrs        if(mtx_owned(&SCTP_BASE_INFO(wq_addr_mtx))) { \
376208160Srrs             mtx_unlock(&SCTP_BASE_INFO(wq_addr_mtx)); \
377208160Srrs        } \
378208160Srrs	    mtx_destroy(&SCTP_BASE_INFO(wq_addr_mtx)); \
379208160Srrs      }  while (0)
380208160Srrs
381208160Srrs#define SCTP_WQ_ADDR_LOCK()	do { \
382208160Srrs             mtx_lock(&SCTP_BASE_INFO(wq_addr_mtx));  \
383208160Srrs} while (0)
384208160Srrs#define SCTP_WQ_ADDR_UNLOCK() do { \
385208160Srrs		mtx_unlock(&SCTP_BASE_INFO(wq_addr_mtx)); \
386208160Srrs} while (0)
387208160Srrs
388208160Srrs
389208160Srrs
390163953Srrs#define SCTP_INCR_EP_COUNT() \
391163953Srrs                do { \
392179783Srrs		       atomic_add_int(&SCTP_BASE_INFO(ipi_count_ep), 1); \
393163953Srrs	        } while (0)
394163953Srrs
395163953Srrs#define SCTP_DECR_EP_COUNT() \
396163953Srrs                do { \
397179783Srrs		       atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_ep), 1); \
398163953Srrs	        } while (0)
399163953Srrs
400163953Srrs#define SCTP_INCR_ASOC_COUNT() \
401163953Srrs                do { \
402179783Srrs	               atomic_add_int(&SCTP_BASE_INFO(ipi_count_asoc), 1); \
403163953Srrs	        } while (0)
404163953Srrs
405163953Srrs#define SCTP_DECR_ASOC_COUNT() \
406163953Srrs                do { \
407179783Srrs	               atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_asoc), 1); \
408163953Srrs	        } while (0)
409163953Srrs
410163953Srrs#define SCTP_INCR_LADDR_COUNT() \
411163953Srrs                do { \
412179783Srrs	               atomic_add_int(&SCTP_BASE_INFO(ipi_count_laddr), 1); \
413163953Srrs	        } while (0)
414163953Srrs
415163953Srrs#define SCTP_DECR_LADDR_COUNT() \
416163953Srrs                do { \
417179783Srrs	               atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_laddr), 1); \
418163953Srrs	        } while (0)
419163953Srrs
420163953Srrs#define SCTP_INCR_RADDR_COUNT() \
421163953Srrs                do { \
422179783Srrs 	               atomic_add_int(&SCTP_BASE_INFO(ipi_count_raddr), 1); \
423163953Srrs	        } while (0)
424163953Srrs
425163953Srrs#define SCTP_DECR_RADDR_COUNT() \
426163953Srrs                do { \
427179783Srrs 	               atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_raddr),1); \
428163953Srrs	        } while (0)
429163953Srrs
430163953Srrs#define SCTP_INCR_CHK_COUNT() \
431163953Srrs                do { \
432179783Srrs  	               atomic_add_int(&SCTP_BASE_INFO(ipi_count_chunk), 1); \
433163953Srrs	        } while (0)
434182367Srrs#ifdef INVARIANTS
435163953Srrs#define SCTP_DECR_CHK_COUNT() \
436163953Srrs                do { \
437179783Srrs                       if(SCTP_BASE_INFO(ipi_count_chunk) == 0) \
438163953Srrs                             panic("chunk count to 0?");    \
439179783Srrs  	               atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_chunk), 1); \
440163953Srrs	        } while (0)
441182367Srrs#else
442182367Srrs#define SCTP_DECR_CHK_COUNT() \
443182367Srrs                do { \
444182367Srrs                       if(SCTP_BASE_INFO(ipi_count_chunk) != 0) \
445182367Srrs  	               atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_chunk), 1); \
446182367Srrs	        } while (0)
447182367Srrs#endif
448163953Srrs#define SCTP_INCR_READQ_COUNT() \
449163953Srrs                do { \
450179783Srrs		       atomic_add_int(&SCTP_BASE_INFO(ipi_count_readq),1); \
451163953Srrs	        } while (0)
452163953Srrs
453163953Srrs#define SCTP_DECR_READQ_COUNT() \
454163953Srrs                do { \
455179783Srrs		       atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_readq), 1); \
456163953Srrs	        } while (0)
457163953Srrs
458163953Srrs#define SCTP_INCR_STRMOQ_COUNT() \
459163953Srrs                do { \
460179783Srrs		       atomic_add_int(&SCTP_BASE_INFO(ipi_count_strmoq), 1); \
461163953Srrs	        } while (0)
462163953Srrs
463163953Srrs#define SCTP_DECR_STRMOQ_COUNT() \
464163953Srrs                do { \
465179783Srrs		       atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_strmoq), 1); \
466163953Srrs	        } while (0)
467163953Srrs
468163953Srrs
469172090Srrs#if defined(SCTP_SO_LOCK_TESTING)
470172090Srrs#define SCTP_INP_SO(sctpinp)	(sctpinp)->ip_inp.inp.inp_socket
471172090Srrs#define SCTP_SOCKET_LOCK(so, refcnt)
472172090Srrs#define SCTP_SOCKET_UNLOCK(so, refcnt)
473163953Srrs#endif
474172090Srrs
475172090Srrs#endif
476