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/net/vnet.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) 2006-2009 University of Zagreb
    5  * Copyright (c) 2006-2009 FreeBSD Foundation
    6  * All rights reserved.
    7  *
    8  * This software was developed by the University of Zagreb and the
    9  * FreeBSD Foundation under sponsorship by the Stichting NLnet and the
   10  * FreeBSD Foundation.
   11  *
   12  * Copyright (c) 2009 Jeffrey Roberson <jeff@freebsd.org>
   13  * Copyright (c) 2009 Robert N. M. Watson
   14  * All rights reserved.
   15  *
   16  * Redistribution and use in source and binary forms, with or without
   17  * modification, are permitted provided that the following conditions
   18  * are met:
   19  * 1. Redistributions of source code must retain the above copyright
   20  *    notice, this list of conditions and the following disclaimer.
   21  * 2. Redistributions in binary form must reproduce the above copyright
   22  *    notice, this list of conditions and the following disclaimer in the
   23  *    documentation and/or other materials provided with the distribution.
   24  *
   25  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   35  * SUCH DAMAGE.
   36  *
   37  * $FreeBSD$
   38  */
   39 
   40 /*-
   41  * This header file defines several sets of interfaces supporting virtualized
   42  * network stacks:
   43  *
   44  * - Definition of 'struct vnet' and functions and macros to allocate/free/
   45  *   manipulate it.
   46  *
   47  * - A virtual network stack memory allocator, which provides support for
   48  *   virtualized global variables via a special linker set, set_vnet.
   49  *
   50  * - Virtualized sysinits/sysuninits, which allow constructors and
   51  *   destructors to be run for each network stack subsystem as virtual
   52  *   instances are created and destroyed.
   53  *
   54  * If VIMAGE isn't compiled into the kernel, virtualized global variables
   55  * compile to normal global variables, and virtualized sysinits to regular
   56  * sysinits.
   57  */
   58 
   59 #ifndef _NET_VNET_H_
   60 #define _NET_VNET_H_
   61 
   62 /*
   63  * struct vnet describes a virtualized network stack, and is primarily a
   64  * pointer to storage for virtualized global variables.  Expose to userspace
   65  * as required for libkvm.
   66  */
   67 #if defined(_KERNEL) || defined(_WANT_VNET)
   68 #include <sys/queue.h>
   69 
   70 struct vnet {
   71         LIST_ENTRY(vnet)         vnet_le;       /* all vnets list */
   72         u_int                    vnet_magic_n;
   73         u_int                    vnet_ifcnt;
   74         u_int                    vnet_sockcnt;
   75         u_int                    vnet_state;    /* SI_SUB_* */
   76         void                    *vnet_data_mem;
   77         uintptr_t                vnet_data_base;
   78 };
   79 #define VNET_MAGIC_N    0x3e0d8f29
   80 
   81 /*
   82  * These two virtual network stack allocator definitions are also required
   83  * for libkvm so that it can evaluate virtualized global variables.
   84  */
   85 #define VNET_SETNAME            "set_vnet"
   86 #define VNET_SYMPREFIX          "vnet_entry_"
   87 #endif
   88 
   89 #ifdef _KERNEL
   90 
   91 #define VNET_PCPUSTAT_DECLARE(type, name)       \
   92     VNET_DECLARE(counter_u64_t, name[sizeof(type) / sizeof(uint64_t)])
   93 
   94 #define VNET_PCPUSTAT_DEFINE(type, name)        \
   95     VNET_DEFINE(counter_u64_t, name[sizeof(type) / sizeof(uint64_t)])
   96 #define VNET_PCPUSTAT_DEFINE_STATIC(type, name) \
   97     VNET_DEFINE_STATIC(counter_u64_t, name[sizeof(type) / sizeof(uint64_t)])
   98 
   99 #define VNET_PCPUSTAT_ALLOC(name, wait) \
  100     COUNTER_ARRAY_ALLOC(VNET(name), \
  101         sizeof(VNET(name)) / sizeof(counter_u64_t), (wait))
  102 
  103 #define VNET_PCPUSTAT_FREE(name)        \
  104     COUNTER_ARRAY_FREE(VNET(name), sizeof(VNET(name)) / sizeof(counter_u64_t))
  105 
  106 #define VNET_PCPUSTAT_ADD(type, name, f, v)     \
  107     counter_u64_add(VNET(name)[offsetof(type, f) / sizeof(uint64_t)], (v))
  108 
  109 #define VNET_PCPUSTAT_FETCH(type, name, f)      \
  110     counter_u64_fetch(VNET(name)[offsetof(type, f) / sizeof(uint64_t)])
  111 
  112 #define VNET_PCPUSTAT_SYSINIT(name)     \
  113 static void                             \
  114 vnet_##name##_init(const void *unused)  \
  115 {                                       \
  116         VNET_PCPUSTAT_ALLOC(name, M_WAITOK);    \
  117 }                                       \
  118 VNET_SYSINIT(vnet_ ## name ## _init, SI_SUB_INIT_IF,                    \
  119     SI_ORDER_FIRST, vnet_ ## name ## _init, NULL)
  120 
  121 #define VNET_PCPUSTAT_SYSUNINIT(name)                                   \
  122 static void                                                             \
  123 vnet_##name##_uninit(const void *unused)                                \
  124 {                                                                       \
  125         VNET_PCPUSTAT_FREE(name);                                       \
  126 }                                                                       \
  127 VNET_SYSUNINIT(vnet_ ## name ## _uninit, SI_SUB_INIT_IF,                \
  128     SI_ORDER_FIRST, vnet_ ## name ## _uninit, NULL)
  129 
  130 #ifdef SYSCTL_OID
  131 #define SYSCTL_VNET_PCPUSTAT(parent, nbr, name, type, array, desc)      \
  132 static int                                                              \
  133 array##_sysctl(SYSCTL_HANDLER_ARGS)                                     \
  134 {                                                                       \
  135         type s;                                                         \
  136         CTASSERT((sizeof(type) / sizeof(uint64_t)) ==                   \
  137             (sizeof(VNET(array)) / sizeof(counter_u64_t)));             \
  138         COUNTER_ARRAY_COPY(VNET(array), &s, sizeof(type) / sizeof(uint64_t));\
  139         if (req->newptr)                                                \
  140                 COUNTER_ARRAY_ZERO(VNET(array),                         \
  141                     sizeof(type) / sizeof(uint64_t));                   \
  142         return (SYSCTL_OUT(req, &s, sizeof(type)));                     \
  143 }                                                                       \
  144 SYSCTL_PROC(parent, nbr, name, CTLFLAG_VNET | CTLTYPE_OPAQUE | CTLFLAG_RW, \
  145     NULL, 0, array ## _sysctl, "I", desc)
  146 #endif /* SYSCTL_OID */
  147 
  148 #ifdef VIMAGE
  149 #include <sys/lock.h>
  150 #include <sys/proc.h>                   /* for struct thread */
  151 #include <sys/rwlock.h>
  152 #include <sys/sx.h>
  153 
  154 /*
  155  * Location of the kernel's 'set_vnet' linker set.
  156  */
  157 extern uintptr_t        *__start_set_vnet;
  158 __GLOBL(__start_set_vnet);
  159 extern uintptr_t        *__stop_set_vnet;
  160 __GLOBL(__stop_set_vnet);
  161 
  162 #define VNET_START      (uintptr_t)&__start_set_vnet
  163 #define VNET_STOP       (uintptr_t)&__stop_set_vnet
  164 
  165 /*
  166  * Functions to allocate and destroy virtual network stacks.
  167  */
  168 struct vnet *vnet_alloc(void);
  169 void    vnet_destroy(struct vnet *vnet);
  170 
  171 /*
  172  * The current virtual network stack -- we may wish to move this to struct
  173  * pcpu in the future.
  174  */
  175 #define curvnet curthread->td_vnet
  176 
  177 /*
  178  * Various macros -- get and set the current network stack, but also
  179  * assertions.
  180  */
  181 #if defined(INVARIANTS) || defined(VNET_DEBUG)
  182 #define VNET_ASSERT(exp, msg)   do {                                    \
  183         if (!(exp))                                                     \
  184                 panic msg;                                              \
  185 } while (0)
  186 #else
  187 #define VNET_ASSERT(exp, msg)   do {                                    \
  188 } while (0)
  189 #endif
  190 
  191 #ifdef VNET_DEBUG
  192 void vnet_log_recursion(struct vnet *, const char *, int);
  193 
  194 #define CURVNET_SET_QUIET(arg)                                          \
  195         VNET_ASSERT((arg) != NULL && (arg)->vnet_magic_n == VNET_MAGIC_N, \
  196             ("CURVNET_SET at %s:%d %s() curvnet=%p vnet=%p",            \
  197             __FILE__, __LINE__, __func__, curvnet, (arg)));             \
  198         struct vnet *saved_vnet = curvnet;                              \
  199         const char *saved_vnet_lpush = curthread->td_vnet_lpush;        \
  200         curvnet = arg;                                                  \
  201         curthread->td_vnet_lpush = __func__;
  202  
  203 #define CURVNET_SET_VERBOSE(arg)                                        \
  204         CURVNET_SET_QUIET(arg)                                          \
  205         if (saved_vnet)                                                 \
  206                 vnet_log_recursion(saved_vnet, saved_vnet_lpush, __LINE__);
  207 
  208 #define CURVNET_SET(arg)        CURVNET_SET_VERBOSE(arg)
  209  
  210 #define CURVNET_RESTORE()                                               \
  211         VNET_ASSERT(curvnet != NULL && (saved_vnet == NULL ||           \
  212             saved_vnet->vnet_magic_n == VNET_MAGIC_N),                  \
  213             ("CURVNET_RESTORE at %s:%d %s() curvnet=%p saved_vnet=%p",  \
  214             __FILE__, __LINE__, __func__, curvnet, saved_vnet));        \
  215         curvnet = saved_vnet;                                           \
  216         curthread->td_vnet_lpush = saved_vnet_lpush;
  217 #else /* !VNET_DEBUG */
  218 
  219 #define CURVNET_SET_QUIET(arg)                                          \
  220         VNET_ASSERT((arg) != NULL && (arg)->vnet_magic_n == VNET_MAGIC_N, \
  221             ("CURVNET_SET at %s:%d %s() curvnet=%p vnet=%p",            \
  222             __FILE__, __LINE__, __func__, curvnet, (arg)));             \
  223         struct vnet *saved_vnet = curvnet;                              \
  224         curvnet = arg;  
  225  
  226 #define CURVNET_SET_VERBOSE(arg)                                        \
  227         CURVNET_SET_QUIET(arg)
  228 
  229 #define CURVNET_SET(arg)        CURVNET_SET_VERBOSE(arg)
  230  
  231 #define CURVNET_RESTORE()                                               \
  232         VNET_ASSERT(curvnet != NULL && (saved_vnet == NULL ||           \
  233             saved_vnet->vnet_magic_n == VNET_MAGIC_N),                  \
  234             ("CURVNET_RESTORE at %s:%d %s() curvnet=%p saved_vnet=%p",  \
  235             __FILE__, __LINE__, __func__, curvnet, saved_vnet));        \
  236         curvnet = saved_vnet;
  237 #endif /* VNET_DEBUG */
  238 
  239 extern struct vnet *vnet0;
  240 #define IS_DEFAULT_VNET(arg)    ((arg) == vnet0)
  241 
  242 #define CRED_TO_VNET(cr)        (cr)->cr_prison->pr_vnet
  243 #define TD_TO_VNET(td)          CRED_TO_VNET((td)->td_ucred)
  244 #define P_TO_VNET(p)            CRED_TO_VNET((p)->p_ucred)
  245 
  246 /*
  247  * Global linked list of all virtual network stacks, along with read locks to
  248  * access it.  If a caller may sleep while accessing the list, it must use
  249  * the sleepable lock macros.
  250  */
  251 LIST_HEAD(vnet_list_head, vnet);
  252 extern struct vnet_list_head vnet_head;
  253 extern struct rwlock vnet_rwlock;
  254 extern struct sx vnet_sxlock;
  255 
  256 #define VNET_LIST_RLOCK()               sx_slock(&vnet_sxlock)
  257 #define VNET_LIST_RLOCK_NOSLEEP()       rw_rlock(&vnet_rwlock)
  258 #define VNET_LIST_RUNLOCK()             sx_sunlock(&vnet_sxlock)
  259 #define VNET_LIST_RUNLOCK_NOSLEEP()     rw_runlock(&vnet_rwlock)
  260 
  261 /*
  262  * Iteration macros to walk the global list of virtual network stacks.
  263  */
  264 #define VNET_ITERATOR_DECL(arg) struct vnet *arg
  265 #define VNET_FOREACH(arg)       LIST_FOREACH((arg), &vnet_head, vnet_le)
  266 
  267 /*
  268  * Virtual network stack memory allocator, which allows global variables to
  269  * be automatically instantiated for each network stack instance.
  270  */
  271 #define VNET_NAME(n)            vnet_entry_##n
  272 #define VNET_DECLARE(t, n)      extern t VNET_NAME(n)
  273 /* struct _hack is to stop this from being used with static data */
  274 #define VNET_DEFINE(t, n)       \
  275     struct _hack; t VNET_NAME(n) __section(VNET_SETNAME) __used
  276 #if defined(KLD_MODULE) && (defined(__aarch64__) || defined(__riscv))
  277 /*
  278  * As with DPCPU_DEFINE_STATIC we are unable to mark this data as static
  279  * in modules on some architectures.
  280  */
  281 #define VNET_DEFINE_STATIC(t, n) \
  282     t VNET_NAME(n) __section(VNET_SETNAME) __used
  283 #else
  284 #define VNET_DEFINE_STATIC(t, n) \
  285     static t VNET_NAME(n) __section(VNET_SETNAME) __used
  286 #endif
  287 #define _VNET_PTR(b, n)         (__typeof(VNET_NAME(n))*)               \
  288                                     ((b) + (uintptr_t)&VNET_NAME(n))
  289 
  290 #define _VNET(b, n)             (*_VNET_PTR(b, n))
  291 
  292 /*
  293  * Virtualized global variable accessor macros.
  294  */
  295 #define VNET_VNET_PTR(vnet, n)          _VNET_PTR((vnet)->vnet_data_base, n)
  296 #define VNET_VNET(vnet, n)              (*VNET_VNET_PTR((vnet), n))
  297 
  298 #define VNET_PTR(n)             VNET_VNET_PTR(curvnet, n)
  299 #define VNET(n)                 VNET_VNET(curvnet, n)
  300 
  301 /*
  302  * Virtual network stack allocator interfaces from the kernel linker.
  303  */
  304 void    *vnet_data_alloc(int size);
  305 void     vnet_data_copy(void *start, int size);
  306 void     vnet_data_free(void *start_arg, int size);
  307 
  308 /*
  309  * Virtual sysinit mechanism, allowing network stack components to declare
  310  * startup and shutdown methods to be run when virtual network stack
  311  * instances are created and destroyed.
  312  */
  313 #include <sys/kernel.h>
  314 
  315 /*
  316  * SYSINIT/SYSUNINIT variants that provide per-vnet constructors and
  317  * destructors.
  318  */
  319 struct vnet_sysinit {
  320         enum sysinit_sub_id     subsystem;
  321         enum sysinit_elem_order order;
  322         sysinit_cfunc_t         func;
  323         const void              *arg;
  324         TAILQ_ENTRY(vnet_sysinit) link;
  325 };
  326 
  327 #define VNET_SYSINIT(ident, subsystem, order, func, arg)                \
  328         CTASSERT((subsystem) > SI_SUB_VNET &&                           \
  329             (subsystem) <= SI_SUB_VNET_DONE);                           \
  330         static struct vnet_sysinit ident ## _vnet_init = {              \
  331                 subsystem,                                              \
  332                 order,                                                  \
  333                 (sysinit_cfunc_t)(sysinit_nfunc_t)func,                 \
  334                 (arg)                                                   \
  335         };                                                              \
  336         SYSINIT(vnet_init_ ## ident, subsystem, order,                  \
  337             vnet_register_sysinit, &ident ## _vnet_init);               \
  338         SYSUNINIT(vnet_init_ ## ident, subsystem, order,                \
  339             vnet_deregister_sysinit, &ident ## _vnet_init)
  340 
  341 #define VNET_SYSUNINIT(ident, subsystem, order, func, arg)              \
  342         CTASSERT((subsystem) > SI_SUB_VNET &&                           \
  343             (subsystem) <= SI_SUB_VNET_DONE);                           \
  344         static struct vnet_sysinit ident ## _vnet_uninit = {            \
  345                 subsystem,                                              \
  346                 order,                                                  \
  347                 (sysinit_cfunc_t)(sysinit_nfunc_t)func,                 \
  348                 (arg)                                                   \
  349         };                                                              \
  350         SYSINIT(vnet_uninit_ ## ident, subsystem, order,                \
  351             vnet_register_sysuninit, &ident ## _vnet_uninit);           \
  352         SYSUNINIT(vnet_uninit_ ## ident, subsystem, order,              \
  353             vnet_deregister_sysuninit, &ident ## _vnet_uninit)
  354 
  355 /*
  356  * Run per-vnet sysinits or sysuninits during vnet creation/destruction.
  357  */
  358 void     vnet_sysinit(void);
  359 void     vnet_sysuninit(void);
  360 
  361 /*
  362  * Interfaces for managing per-vnet constructors and destructors.
  363  */
  364 void    vnet_register_sysinit(void *arg);
  365 void    vnet_register_sysuninit(void *arg);
  366 void    vnet_deregister_sysinit(void *arg);
  367 void    vnet_deregister_sysuninit(void *arg);
  368 
  369 /*
  370  * EVENTHANDLER(9) extensions.
  371  */
  372 #include <sys/eventhandler.h>
  373 
  374 void    vnet_global_eventhandler_iterator_func(void *, ...);
  375 #define VNET_GLOBAL_EVENTHANDLER_REGISTER_TAG(tag, name, func, arg, priority) \
  376 do {                                                                    \
  377         if (IS_DEFAULT_VNET(curvnet)) {                                 \
  378                 (tag) = vimage_eventhandler_register(NULL, #name, func, \
  379                     arg, priority,                                      \
  380                     vnet_global_eventhandler_iterator_func);            \
  381         }                                                               \
  382 } while(0)
  383 #define VNET_GLOBAL_EVENTHANDLER_REGISTER(name, func, arg, priority)    \
  384 do {                                                                    \
  385         if (IS_DEFAULT_VNET(curvnet)) {                                 \
  386                 vimage_eventhandler_register(NULL, #name, func,         \
  387                     arg, priority,                                      \
  388                     vnet_global_eventhandler_iterator_func);            \
  389         }                                                               \
  390 } while(0)
  391 
  392 #else /* !VIMAGE */
  393 
  394 /*
  395  * Various virtual network stack macros compile to no-ops without VIMAGE.
  396  */
  397 #define curvnet                 NULL
  398 
  399 #define VNET_ASSERT(exp, msg)
  400 #define CURVNET_SET(arg)
  401 #define CURVNET_SET_QUIET(arg)
  402 #define CURVNET_RESTORE()
  403 
  404 #define VNET_LIST_RLOCK()
  405 #define VNET_LIST_RLOCK_NOSLEEP()
  406 #define VNET_LIST_RUNLOCK()
  407 #define VNET_LIST_RUNLOCK_NOSLEEP()
  408 #define VNET_ITERATOR_DECL(arg)
  409 #define VNET_FOREACH(arg)
  410 
  411 #define IS_DEFAULT_VNET(arg)    1
  412 #define CRED_TO_VNET(cr)        NULL
  413 #define TD_TO_VNET(td)          NULL
  414 #define P_TO_VNET(p)            NULL
  415 
  416 /*
  417  * Versions of the VNET macros that compile to normal global variables and
  418  * standard sysctl definitions.
  419  */
  420 #define VNET_NAME(n)            n
  421 #define VNET_DECLARE(t, n)      extern t n
  422 #define VNET_DEFINE(t, n)       struct _hack; t n
  423 #define VNET_DEFINE_STATIC(t, n)        static t n
  424 #define _VNET_PTR(b, n)         &VNET_NAME(n)
  425 
  426 /*
  427  * Virtualized global variable accessor macros.
  428  */
  429 #define VNET_VNET_PTR(vnet, n)          (&(n))
  430 #define VNET_VNET(vnet, n)              (n)
  431 
  432 #define VNET_PTR(n)             (&(n))
  433 #define VNET(n)                 (n)
  434 
  435 /*
  436  * When VIMAGE isn't compiled into the kernel, VNET_SYSINIT/VNET_SYSUNINIT
  437  * map into normal sysinits, which have the same ordering properties.
  438  */
  439 #define VNET_SYSINIT(ident, subsystem, order, func, arg)                \
  440         SYSINIT(ident, subsystem, order, func, arg)
  441 #define VNET_SYSUNINIT(ident, subsystem, order, func, arg)              \
  442         SYSUNINIT(ident, subsystem, order, func, arg)
  443 
  444 /*
  445  * Without VIMAGE revert to the default implementation.
  446  */
  447 #define VNET_GLOBAL_EVENTHANDLER_REGISTER_TAG(tag, name, func, arg, priority) \
  448         (tag) = eventhandler_register(NULL, #name, func, arg, priority)
  449 #define VNET_GLOBAL_EVENTHANDLER_REGISTER(name, func, arg, priority)    \
  450         eventhandler_register(NULL, #name, func, arg, priority)
  451 #endif /* VIMAGE */
  452 #endif /* _KERNEL */
  453 
  454 #endif /* !_NET_VNET_H_ */

Cache object: 9c62279cc33da55db5a2dd141540ba5c


[ 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.