]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/netgraph/atm/sscop/ng_sscop_cust.h
Merge llvm trunk r351319, resolve conflicts, and update FREEBSD-Xlist.
[FreeBSD/FreeBSD.git] / sys / netgraph / atm / sscop / ng_sscop_cust.h
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2001-2003
5  *      Fraunhofer Institute for Open Communication Systems (FhG Fokus).
6  *      All rights reserved.
7  *
8  * Author: Harti Brandt <harti@freebsd.org>
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  *
31  * $FreeBSD$
32  *
33  * Customisation of the SSCOP code to ng_sscop.
34  */
35
36 #include <sys/param.h>
37 #include <sys/types.h>
38 #include <sys/kernel.h>
39 #include <sys/lock.h>
40 #include <sys/mutex.h>
41 #include <sys/mbuf.h>
42 #include <sys/queue.h>
43 #include <sys/systm.h>
44 #include <sys/malloc.h>
45 #include <netgraph/ng_message.h>
46 #include <netgraph/netgraph.h>
47 #include <machine/stdarg.h>
48
49 #include <netnatm/saal/sscopdef.h>
50
51 /*
52  * Allocate zeroed or non-zeroed memory of some size and cast it.
53  * Return NULL on failure.
54  */
55 #ifndef SSCOP_DEBUG
56
57 #define MEMINIT() \
58         MALLOC_DECLARE(M_NG_SSCOP); \
59         DECL_MSGQ_GET \
60         DECL_SIGQ_GET \
61         DECL_MBUF_ALLOC
62
63 #define MEMZALLOC(PTR, CAST, SIZE) \
64         ((PTR) = (CAST)malloc((SIZE), M_NG_SSCOP, M_NOWAIT | M_ZERO))
65 #define MEMFREE(PTR) \
66         free((PTR), M_NG_SSCOP)
67
68 #define MSG_ALLOC(PTR) \
69         MEMZALLOC(PTR, struct sscop_msg *, sizeof(struct sscop_msg))
70 #define MSG_FREE(PTR) \
71         MEMFREE(PTR)
72
73 #define SIG_ALLOC(PTR) \
74         MEMZALLOC(PTR, struct sscop_sig *, sizeof(struct sscop_sig))
75 #define SIG_FREE(PTR) \
76         MEMFREE(PTR)
77
78 #else
79
80 #define MEMINIT()                                                       \
81         MALLOC_DEFINE(M_NG_SSCOP_INS, "sscop_ins", "SSCOP instances");  \
82         MALLOC_DEFINE(M_NG_SSCOP_MSG, "sscop_msg", "SSCOP buffers");    \
83         MALLOC_DEFINE(M_NG_SSCOP_SIG, "sscop_sig", "SSCOP signals");    \
84         DECL_MSGQ_GET \
85         DECL_SIGQ_GET \
86         DECL_MBUF_ALLOC
87
88 #define MEMZALLOC(PTR, CAST, SIZE)                                      \
89         ((PTR) = (CAST)malloc((SIZE), M_NG_SSCOP_INS, M_NOWAIT | M_ZERO))
90 #define MEMFREE(PTR)                                                    \
91         free((PTR), M_NG_SSCOP_INS)
92
93 #define MSG_ALLOC(PTR)                                                  \
94         ((PTR) = malloc(sizeof(struct sscop_msg),                       \
95             M_NG_SSCOP_MSG, M_NOWAIT | M_ZERO))
96 #define MSG_FREE(PTR)                                                   \
97         free((PTR), M_NG_SSCOP_MSG)
98
99 #define SIG_ALLOC(PTR)                                                  \
100         ((PTR) = malloc(sizeof(struct sscop_sig),                       \
101             M_NG_SSCOP_SIG, M_NOWAIT | M_ZERO))
102 #define SIG_FREE(PTR)                                                   \
103         free((PTR), M_NG_SSCOP_SIG)
104
105 #endif
106
107 /*
108  * Timer support.
109  */
110 typedef struct callout sscop_timer_t;
111 #define TIMER_INIT(S, T)        ng_callout_init(&(S)->t_##T)
112 #define TIMER_STOP(S,T) do {                                            \
113         ng_uncallout(&(S)->t_##T, (S)->aarg);                           \
114     } while (0)
115 #define TIMER_RESTART(S, T) do {                                        \
116         TIMER_STOP(S, T);                                               \
117         ng_callout(&(S)->t_##T, (S)->aarg, NULL,                        \
118             hz * (S)->timer##T / 1000, T##_func, (S), 0);               \
119     } while (0)
120 #define TIMER_ISACT(S, T) (callout_pending(&(S)->t_##T))
121
122 /*
123  * This assumes, that the user argument is the node pointer.
124  */
125 #define TIMER_FUNC(T,N)                                                 \
126 static void                                                             \
127 T##_func(node_p node, hook_p hook, void *arg1, int arg2)                \
128 {                                                                       \
129         struct sscop *sscop = arg1;                                     \
130                                                                         \
131         VERBOSE(sscop, SSCOP_DBG_TIMER, (sscop, sscop->aarg,            \
132             "timer_" #T " expired"));                                   \
133         sscop_signal(sscop, SIG_T_##N, NULL);                           \
134 }
135
136
137 /*
138  * Message queues
139  */
140 typedef TAILQ_ENTRY(sscop_msg) sscop_msgq_link_t;
141 typedef TAILQ_HEAD(sscop_msgq, sscop_msg) sscop_msgq_head_t;
142 #define MSGQ_EMPTY(Q)           TAILQ_EMPTY(Q)
143 #define MSGQ_INIT(Q)            TAILQ_INIT(Q)
144 #define MSGQ_FOREACH(P, Q)      TAILQ_FOREACH(P, Q, link)
145 #define MSGQ_REMOVE(Q, M)       TAILQ_REMOVE(Q, M, link)
146 #define MSGQ_INSERT_BEFORE(B, M) TAILQ_INSERT_BEFORE(B, M, link)
147 #define MSGQ_APPEND(Q, M)       TAILQ_INSERT_TAIL(Q, M, link)
148 #define MSGQ_PEEK(Q)            TAILQ_FIRST((Q))
149
150 #define MSGQ_GET(Q) ng_sscop_msgq_get((Q))
151
152 #define DECL_MSGQ_GET                                                   \
153 static __inline struct sscop_msg *                                      \
154 ng_sscop_msgq_get(struct sscop_msgq *q)                                 \
155 {                                                                       \
156         struct sscop_msg *m;                                            \
157                                                                         \
158         m = TAILQ_FIRST(q);                                             \
159         if (m != NULL)                                                  \
160                 TAILQ_REMOVE(q, m, link);                               \
161         return (m);                                                     \
162 }
163
164 #define MSGQ_CLEAR(Q)                                                   \
165         do {                                                            \
166                 struct sscop_msg *_m1, *_m2;                            \
167                                                                         \
168                 _m1 = TAILQ_FIRST(Q);                                   \
169                 while (_m1 != NULL) {                                   \
170                         _m2 = TAILQ_NEXT(_m1, link);                    \
171                         SSCOP_MSG_FREE(_m1);                            \
172                         _m1 = _m2;                                      \
173                 }                                                       \
174                 TAILQ_INIT((Q));                                        \
175         } while (0)
176
177 /*
178  * Signal queues
179  */
180 typedef TAILQ_ENTRY(sscop_sig) sscop_sigq_link_t;
181 typedef TAILQ_HEAD(sscop_sigq, sscop_sig) sscop_sigq_head_t;
182 #define SIGQ_INIT(Q)            TAILQ_INIT(Q)
183 #define SIGQ_APPEND(Q, S)       TAILQ_INSERT_TAIL(Q, S, link)
184 #define SIGQ_EMPTY(Q)           TAILQ_EMPTY(Q)
185
186 #define SIGQ_GET(Q)     ng_sscop_sigq_get((Q))
187 #define DECL_SIGQ_GET                                                   \
188 static __inline struct sscop_sig *                                      \
189 ng_sscop_sigq_get(struct sscop_sigq *q)                                 \
190 {                                                                       \
191         struct sscop_sig *s;                                            \
192                                                                         \
193         s = TAILQ_FIRST(q);                                             \
194         if (s != NULL)                                                  \
195                 TAILQ_REMOVE(q, s, link);                               \
196         return (s);                                                     \
197 }
198
199 #define SIGQ_MOVE(F, T)                                                 \
200     do {                                                                \
201         struct sscop_sig *_s;                                           \
202                                                                         \
203         while (!TAILQ_EMPTY(F)) {                                       \
204                 _s = TAILQ_FIRST(F);                                    \
205                 TAILQ_REMOVE(F, _s, link);                              \
206                 TAILQ_INSERT_TAIL(T, _s, link);                         \
207         }                                                               \
208     } while (0)
209
210 #define SIGQ_PREPEND(F, T)                                              \
211     do {                                                                \
212         struct sscop_sig *_s;                                           \
213                                                                         \
214         while (!TAILQ_EMPTY(F)) {                                       \
215                 _s = TAILQ_LAST(F, sscop_sigq);                         \
216                 TAILQ_REMOVE(F, _s, link);                              \
217                 TAILQ_INSERT_HEAD(T, _s, link);                         \
218         }                                                               \
219     } while (0)
220
221 #define SIGQ_CLEAR(Q)                                                   \
222     do {                                                                \
223         struct sscop_sig *_s1, *_s2;                                    \
224                                                                         \
225         _s1 = TAILQ_FIRST(Q);                                           \
226         while (_s1 != NULL) {                                           \
227                 _s2 = TAILQ_NEXT(_s1, link);                            \
228                 SSCOP_MSG_FREE(_s1->msg);                               \
229                 SIG_FREE(_s1);                                          \
230                 _s1 = _s2;                                              \
231         }                                                               \
232         TAILQ_INIT(Q);                                                  \
233     } while (0)
234
235 /*
236  * Message buffers
237  */
238 #define MBUF_FREE(M)    do { if ((M)) m_freem((M)); } while(0)
239 #define MBUF_DUP(M)     m_copypacket((M), M_NOWAIT)
240 #define MBUF_LEN(M)     ((size_t)(M)->m_pkthdr.len)
241
242 /*
243  * Return the i-th word counted from the end of the buffer.
244  * i=-1 will return the last 32bit word, i=-2 the 2nd last.
245  * Assumes that there is enough space.
246  */
247 #define MBUF_TRAIL32(M ,I) ng_sscop_mbuf_trail32((M), (I))
248
249 static uint32_t __inline        
250 ng_sscop_mbuf_trail32(const struct mbuf *m, int i)
251 {
252         uint32_t w;
253
254         m_copydata(m, m->m_pkthdr.len + 4 * i, 4, (caddr_t)&w);
255         return (ntohl(w));
256 }
257
258 /*
259  * Strip 32bit value from the end
260  */
261 #define MBUF_STRIP32(M) ng_sscop_mbuf_strip32((M))
262
263 static uint32_t __inline
264 ng_sscop_mbuf_strip32(struct mbuf *m)
265 {
266         uint32_t w;
267
268         m_copydata(m, m->m_pkthdr.len - 4, 4, (caddr_t)&w);
269         m_adj(m, -4);
270         return (ntohl(w));
271 }
272
273 #define MBUF_GET32(M) ng_sscop_mbuf_get32((M))
274
275 static uint32_t __inline
276 ng_sscop_mbuf_get32(struct mbuf *m)
277 {
278         uint32_t w;
279
280         m_copydata(m, 0, 4, (caddr_t)&w);
281         m_adj(m, 4);
282         return (ntohl(w));
283 }
284
285 /*
286  * Append a 32bit value to an mbuf. Failures are ignored.
287  */
288 #define MBUF_APPEND32(M, W)                                             \
289      do {                                                               \
290         uint32_t _w = (W);                                              \
291                                                                         \
292         _w = htonl(_w);                                                 \
293         m_copyback((M), (M)->m_pkthdr.len, 4, (caddr_t)&_w);            \
294     } while (0)
295
296 /*
297  * Pad a message to a multiple of four byte and return the amount of padding
298  * Failures are ignored.
299  */
300 #define MBUF_PAD4(M) ng_sscop_mbuf_pad4((M))
301
302 static u_int __inline
303 ng_sscop_mbuf_pad4(struct mbuf *m)
304 {
305         static u_char pad[4] = { 0, 0, 0, 0 };
306         int len = m->m_pkthdr.len;
307         int npad = 3 - ((len + 3) & 3);
308
309         if (npad != 0)
310                 m_copyback(m, len, npad, (caddr_t)pad);
311         return (npad);
312 }
313
314 #define MBUF_UNPAD(M, P) do { if( (P) > 0) m_adj((M), -(P)); } while (0)
315
316 /*
317  * Allocate a message that will probably hold N bytes.
318  */
319 #define MBUF_ALLOC(N) ng_sscop_mbuf_alloc((N))
320
321 #define DECL_MBUF_ALLOC                                                 \
322 static __inline struct mbuf *                                           \
323 ng_sscop_mbuf_alloc(size_t n)                                           \
324 {                                                                       \
325         struct mbuf *m;                                                 \
326                                                                         \
327         MGETHDR(m, M_NOWAIT, MT_DATA);                                  \
328         if (m != NULL) {                                                \
329                 m->m_len = 0;                                           \
330                 m->m_pkthdr.len = 0;                                    \
331                 if (n > MHLEN) {                                        \
332                         if (!(MCLGET(m, M_NOWAIT))){                    \
333                                 m_free(m);                              \
334                                 m = NULL;                               \
335                         }                                               \
336                 }                                                       \
337         }                                                               \
338         return (m);                                                     \
339 }
340
341 #ifdef SSCOP_DEBUG
342 #define ASSERT(X)       KASSERT(X, (#X))
343 #else
344 #define ASSERT(X)
345 #endif