The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/netgraph/atm/sscop/ng_sscop_cust.h

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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  * Message queues
  138  */
  139 typedef TAILQ_ENTRY(sscop_msg) sscop_msgq_link_t;
  140 typedef TAILQ_HEAD(sscop_msgq, sscop_msg) sscop_msgq_head_t;
  141 #define MSGQ_EMPTY(Q)           TAILQ_EMPTY(Q)
  142 #define MSGQ_INIT(Q)            TAILQ_INIT(Q)
  143 #define MSGQ_FOREACH(P, Q)      TAILQ_FOREACH(P, Q, link)
  144 #define MSGQ_REMOVE(Q, M)       TAILQ_REMOVE(Q, M, link)
  145 #define MSGQ_INSERT_BEFORE(B, M) TAILQ_INSERT_BEFORE(B, M, link)
  146 #define MSGQ_APPEND(Q, M)       TAILQ_INSERT_TAIL(Q, M, link)
  147 #define MSGQ_PEEK(Q)            TAILQ_FIRST((Q))
  148 
  149 #define MSGQ_GET(Q) ng_sscop_msgq_get((Q))
  150 
  151 #define DECL_MSGQ_GET                                                   \
  152 static __inline struct sscop_msg *                                      \
  153 ng_sscop_msgq_get(struct sscop_msgq *q)                                 \
  154 {                                                                       \
  155         struct sscop_msg *m;                                            \
  156                                                                         \
  157         m = TAILQ_FIRST(q);                                             \
  158         if (m != NULL)                                                  \
  159                 TAILQ_REMOVE(q, m, link);                               \
  160         return (m);                                                     \
  161 }
  162 
  163 #define MSGQ_CLEAR(Q)                                                   \
  164         do {                                                            \
  165                 struct sscop_msg *_m1, *_m2;                            \
  166                                                                         \
  167                 _m1 = TAILQ_FIRST(Q);                                   \
  168                 while (_m1 != NULL) {                                   \
  169                         _m2 = TAILQ_NEXT(_m1, link);                    \
  170                         SSCOP_MSG_FREE(_m1);                            \
  171                         _m1 = _m2;                                      \
  172                 }                                                       \
  173                 TAILQ_INIT((Q));                                        \
  174         } while (0)
  175 
  176 /*
  177  * Signal queues
  178  */
  179 typedef TAILQ_ENTRY(sscop_sig) sscop_sigq_link_t;
  180 typedef TAILQ_HEAD(sscop_sigq, sscop_sig) sscop_sigq_head_t;
  181 #define SIGQ_INIT(Q)            TAILQ_INIT(Q)
  182 #define SIGQ_APPEND(Q, S)       TAILQ_INSERT_TAIL(Q, S, link)
  183 #define SIGQ_EMPTY(Q)           TAILQ_EMPTY(Q)
  184 
  185 #define SIGQ_GET(Q)     ng_sscop_sigq_get((Q))
  186 #define DECL_SIGQ_GET                                                   \
  187 static __inline struct sscop_sig *                                      \
  188 ng_sscop_sigq_get(struct sscop_sigq *q)                                 \
  189 {                                                                       \
  190         struct sscop_sig *s;                                            \
  191                                                                         \
  192         s = TAILQ_FIRST(q);                                             \
  193         if (s != NULL)                                                  \
  194                 TAILQ_REMOVE(q, s, link);                               \
  195         return (s);                                                     \
  196 }
  197 
  198 #define SIGQ_MOVE(F, T)                                                 \
  199     do {                                                                \
  200         struct sscop_sig *_s;                                           \
  201                                                                         \
  202         while (!TAILQ_EMPTY(F)) {                                       \
  203                 _s = TAILQ_FIRST(F);                                    \
  204                 TAILQ_REMOVE(F, _s, link);                              \
  205                 TAILQ_INSERT_TAIL(T, _s, link);                         \
  206         }                                                               \
  207     } while (0)
  208 
  209 #define SIGQ_PREPEND(F, T)                                              \
  210     do {                                                                \
  211         struct sscop_sig *_s;                                           \
  212                                                                         \
  213         while (!TAILQ_EMPTY(F)) {                                       \
  214                 _s = TAILQ_LAST(F, sscop_sigq);                         \
  215                 TAILQ_REMOVE(F, _s, link);                              \
  216                 TAILQ_INSERT_HEAD(T, _s, link);                         \
  217         }                                                               \
  218     } while (0)
  219 
  220 #define SIGQ_CLEAR(Q)                                                   \
  221     do {                                                                \
  222         struct sscop_sig *_s1, *_s2;                                    \
  223                                                                         \
  224         _s1 = TAILQ_FIRST(Q);                                           \
  225         while (_s1 != NULL) {                                           \
  226                 _s2 = TAILQ_NEXT(_s1, link);                            \
  227                 SSCOP_MSG_FREE(_s1->msg);                               \
  228                 SIG_FREE(_s1);                                          \
  229                 _s1 = _s2;                                              \
  230         }                                                               \
  231         TAILQ_INIT(Q);                                                  \
  232     } while (0)
  233 
  234 /*
  235  * Message buffers
  236  */
  237 #define MBUF_FREE(M)    do { if ((M)) m_freem((M)); } while(0)
  238 #define MBUF_DUP(M)     m_copypacket((M), M_NOWAIT)
  239 #define MBUF_LEN(M)     ((size_t)(M)->m_pkthdr.len)
  240 
  241 /*
  242  * Return the i-th word counted from the end of the buffer.
  243  * i=-1 will return the last 32bit word, i=-2 the 2nd last.
  244  * Assumes that there is enough space.
  245  */
  246 #define MBUF_TRAIL32(M ,I) ng_sscop_mbuf_trail32((M), (I))
  247 
  248 static uint32_t __inline        
  249 ng_sscop_mbuf_trail32(const struct mbuf *m, int i)
  250 {
  251         uint32_t w;
  252 
  253         m_copydata(m, m->m_pkthdr.len + 4 * i, 4, (caddr_t)&w);
  254         return (ntohl(w));
  255 }
  256 
  257 /*
  258  * Strip 32bit value from the end
  259  */
  260 #define MBUF_STRIP32(M) ng_sscop_mbuf_strip32((M))
  261 
  262 static uint32_t __inline
  263 ng_sscop_mbuf_strip32(struct mbuf *m)
  264 {
  265         uint32_t w;
  266 
  267         m_copydata(m, m->m_pkthdr.len - 4, 4, (caddr_t)&w);
  268         m_adj(m, -4);
  269         return (ntohl(w));
  270 }
  271 
  272 #define MBUF_GET32(M) ng_sscop_mbuf_get32((M))
  273 
  274 static uint32_t __inline
  275 ng_sscop_mbuf_get32(struct mbuf *m)
  276 {
  277         uint32_t w;
  278 
  279         m_copydata(m, 0, 4, (caddr_t)&w);
  280         m_adj(m, 4);
  281         return (ntohl(w));
  282 }
  283 
  284 /*
  285  * Append a 32bit value to an mbuf. Failures are ignored.
  286  */
  287 #define MBUF_APPEND32(M, W)                                             \
  288      do {                                                               \
  289         uint32_t _w = (W);                                              \
  290                                                                         \
  291         _w = htonl(_w);                                                 \
  292         m_copyback((M), (M)->m_pkthdr.len, 4, (caddr_t)&_w);            \
  293     } while (0)
  294 
  295 /*
  296  * Pad a message to a multiple of four byte and return the amount of padding
  297  * Failures are ignored.
  298  */
  299 #define MBUF_PAD4(M) ng_sscop_mbuf_pad4((M))
  300 
  301 static u_int __inline
  302 ng_sscop_mbuf_pad4(struct mbuf *m)
  303 {
  304         static u_char pad[4] = { 0, 0, 0, 0 };
  305         int len = m->m_pkthdr.len;
  306         int npad = 3 - ((len + 3) & 3);
  307 
  308         if (npad != 0)
  309                 m_copyback(m, len, npad, (caddr_t)pad);
  310         return (npad);
  311 }
  312 
  313 #define MBUF_UNPAD(M, P) do { if( (P) > 0) m_adj((M), -(P)); } while (0)
  314 
  315 /*
  316  * Allocate a message that will probably hold N bytes.
  317  */
  318 #define MBUF_ALLOC(N) ng_sscop_mbuf_alloc((N))
  319 
  320 #define DECL_MBUF_ALLOC                                                 \
  321 static __inline struct mbuf *                                           \
  322 ng_sscop_mbuf_alloc(size_t n)                                           \
  323 {                                                                       \
  324         struct mbuf *m;                                                 \
  325                                                                         \
  326         MGETHDR(m, M_NOWAIT, MT_DATA);                                  \
  327         if (m != NULL) {                                                \
  328                 m->m_len = 0;                                           \
  329                 m->m_pkthdr.len = 0;                                    \
  330                 if (n > MHLEN) {                                        \
  331                         if (!(MCLGET(m, M_NOWAIT))){                    \
  332                                 m_free(m);                              \
  333                                 m = NULL;                               \
  334                         }                                               \
  335                 }                                                       \
  336         }                                                               \
  337         return (m);                                                     \
  338 }
  339 
  340 #ifdef SSCOP_DEBUG
  341 #define ASSERT(X)       KASSERT(X, (#X))
  342 #else
  343 #define ASSERT(X)
  344 #endif

Cache object: 8a65a08fe220685a206fbb4a2757ebec


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.