]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/net/vnet.h
MFV r328323,328324:
[FreeBSD/FreeBSD.git] / sys / net / vnet.h
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
97 #define VNET_PCPUSTAT_ALLOC(name, wait) \
98     COUNTER_ARRAY_ALLOC(VNET(name), \
99         sizeof(VNET(name)) / sizeof(counter_u64_t), (wait))
100
101 #define VNET_PCPUSTAT_FREE(name)        \
102     COUNTER_ARRAY_FREE(VNET(name), sizeof(VNET(name)) / sizeof(counter_u64_t))
103
104 #define VNET_PCPUSTAT_ADD(type, name, f, v)     \
105     counter_u64_add(VNET(name)[offsetof(type, f) / sizeof(uint64_t)], (v))
106
107 #define VNET_PCPUSTAT_FETCH(type, name, f)      \
108     counter_u64_fetch(VNET(name)[offsetof(type, f) / sizeof(uint64_t)])
109
110 #define VNET_PCPUSTAT_SYSINIT(name)     \
111 static void                             \
112 vnet_##name##_init(const void *unused)  \
113 {                                       \
114         VNET_PCPUSTAT_ALLOC(name, M_WAITOK);    \
115 }                                       \
116 VNET_SYSINIT(vnet_ ## name ## _init, SI_SUB_INIT_IF,                    \
117     SI_ORDER_FIRST, vnet_ ## name ## _init, NULL)
118
119 #define VNET_PCPUSTAT_SYSUNINIT(name)                                   \
120 static void                                                             \
121 vnet_##name##_uninit(const void *unused)                                \
122 {                                                                       \
123         VNET_PCPUSTAT_FREE(name);                                       \
124 }                                                                       \
125 VNET_SYSUNINIT(vnet_ ## name ## _uninit, SI_SUB_INIT_IF,                \
126     SI_ORDER_FIRST, vnet_ ## name ## _uninit, NULL)
127
128 #ifdef SYSCTL_OID
129 #define SYSCTL_VNET_PCPUSTAT(parent, nbr, name, type, array, desc)      \
130 static int                                                              \
131 array##_sysctl(SYSCTL_HANDLER_ARGS)                                     \
132 {                                                                       \
133         type s;                                                         \
134         CTASSERT((sizeof(type) / sizeof(uint64_t)) ==                   \
135             (sizeof(VNET(array)) / sizeof(counter_u64_t)));             \
136         COUNTER_ARRAY_COPY(VNET(array), &s, sizeof(type) / sizeof(uint64_t));\
137         if (req->newptr)                                                \
138                 COUNTER_ARRAY_ZERO(VNET(array),                         \
139                     sizeof(type) / sizeof(uint64_t));                   \
140         return (SYSCTL_OUT(req, &s, sizeof(type)));                     \
141 }                                                                       \
142 SYSCTL_PROC(parent, nbr, name, CTLFLAG_VNET | CTLTYPE_OPAQUE | CTLFLAG_RW, \
143     NULL, 0, array ## _sysctl, "I", desc)
144 #endif /* SYSCTL_OID */
145
146 #ifdef VIMAGE
147 #include <sys/lock.h>
148 #include <sys/proc.h>                   /* for struct thread */
149 #include <sys/rwlock.h>
150 #include <sys/sx.h>
151
152 /*
153  * Location of the kernel's 'set_vnet' linker set.
154  */
155 extern uintptr_t        *__start_set_vnet;
156 __GLOBL(__start_set_vnet);
157 extern uintptr_t        *__stop_set_vnet;
158 __GLOBL(__stop_set_vnet);
159
160 #define VNET_START      (uintptr_t)&__start_set_vnet
161 #define VNET_STOP       (uintptr_t)&__stop_set_vnet
162
163 /*
164  * Functions to allocate and destroy virtual network stacks.
165  */
166 struct vnet *vnet_alloc(void);
167 void    vnet_destroy(struct vnet *vnet);
168
169 /*
170  * The current virtual network stack -- we may wish to move this to struct
171  * pcpu in the future.
172  */
173 #define curvnet curthread->td_vnet
174
175 /*
176  * Various macros -- get and set the current network stack, but also
177  * assertions.
178  */
179 #if defined(INVARIANTS) || defined(VNET_DEBUG)
180 #define VNET_ASSERT(exp, msg)   do {                                    \
181         if (!(exp))                                                     \
182                 panic msg;                                              \
183 } while (0)
184 #else
185 #define VNET_ASSERT(exp, msg)   do {                                    \
186 } while (0)
187 #endif
188
189 #ifdef VNET_DEBUG
190 void vnet_log_recursion(struct vnet *, const char *, int);
191
192 #define CURVNET_SET_QUIET(arg)                                          \
193         VNET_ASSERT((arg) != NULL && (arg)->vnet_magic_n == VNET_MAGIC_N, \
194             ("CURVNET_SET at %s:%d %s() curvnet=%p vnet=%p",            \
195             __FILE__, __LINE__, __func__, curvnet, (arg)));             \
196         struct vnet *saved_vnet = curvnet;                              \
197         const char *saved_vnet_lpush = curthread->td_vnet_lpush;        \
198         curvnet = arg;                                                  \
199         curthread->td_vnet_lpush = __func__;
200  
201 #define CURVNET_SET_VERBOSE(arg)                                        \
202         CURVNET_SET_QUIET(arg)                                          \
203         if (saved_vnet)                                                 \
204                 vnet_log_recursion(saved_vnet, saved_vnet_lpush, __LINE__);
205
206 #define CURVNET_SET(arg)        CURVNET_SET_VERBOSE(arg)
207  
208 #define CURVNET_RESTORE()                                               \
209         VNET_ASSERT(curvnet != NULL && (saved_vnet == NULL ||           \
210             saved_vnet->vnet_magic_n == VNET_MAGIC_N),                  \
211             ("CURVNET_RESTORE at %s:%d %s() curvnet=%p saved_vnet=%p",  \
212             __FILE__, __LINE__, __func__, curvnet, saved_vnet));        \
213         curvnet = saved_vnet;                                           \
214         curthread->td_vnet_lpush = saved_vnet_lpush;
215 #else /* !VNET_DEBUG */
216
217 #define CURVNET_SET_QUIET(arg)                                          \
218         VNET_ASSERT((arg) != NULL && (arg)->vnet_magic_n == VNET_MAGIC_N, \
219             ("CURVNET_SET at %s:%d %s() curvnet=%p vnet=%p",            \
220             __FILE__, __LINE__, __func__, curvnet, (arg)));             \
221         struct vnet *saved_vnet = curvnet;                              \
222         curvnet = arg;  
223  
224 #define CURVNET_SET_VERBOSE(arg)                                        \
225         CURVNET_SET_QUIET(arg)
226
227 #define CURVNET_SET(arg)        CURVNET_SET_VERBOSE(arg)
228  
229 #define CURVNET_RESTORE()                                               \
230         VNET_ASSERT(curvnet != NULL && (saved_vnet == NULL ||           \
231             saved_vnet->vnet_magic_n == VNET_MAGIC_N),                  \
232             ("CURVNET_RESTORE at %s:%d %s() curvnet=%p saved_vnet=%p",  \
233             __FILE__, __LINE__, __func__, curvnet, saved_vnet));        \
234         curvnet = saved_vnet;
235 #endif /* VNET_DEBUG */
236
237 extern struct vnet *vnet0;
238 #define IS_DEFAULT_VNET(arg)    ((arg) == vnet0)
239
240 #define CRED_TO_VNET(cr)        (cr)->cr_prison->pr_vnet
241 #define TD_TO_VNET(td)          CRED_TO_VNET((td)->td_ucred)
242 #define P_TO_VNET(p)            CRED_TO_VNET((p)->p_ucred)
243
244 /*
245  * Global linked list of all virtual network stacks, along with read locks to
246  * access it.  If a caller may sleep while accessing the list, it must use
247  * the sleepable lock macros.
248  */
249 LIST_HEAD(vnet_list_head, vnet);
250 extern struct vnet_list_head vnet_head;
251 extern struct rwlock vnet_rwlock;
252 extern struct sx vnet_sxlock;
253
254 #define VNET_LIST_RLOCK()               sx_slock(&vnet_sxlock)
255 #define VNET_LIST_RLOCK_NOSLEEP()       rw_rlock(&vnet_rwlock)
256 #define VNET_LIST_RUNLOCK()             sx_sunlock(&vnet_sxlock)
257 #define VNET_LIST_RUNLOCK_NOSLEEP()     rw_runlock(&vnet_rwlock)
258
259 /*
260  * Iteration macros to walk the global list of virtual network stacks.
261  */
262 #define VNET_ITERATOR_DECL(arg) struct vnet *arg
263 #define VNET_FOREACH(arg)       LIST_FOREACH((arg), &vnet_head, vnet_le)
264
265 /*
266  * Virtual network stack memory allocator, which allows global variables to
267  * be automatically instantiated for each network stack instance.
268  */
269 #define VNET_NAME(n)            vnet_entry_##n
270 #define VNET_DECLARE(t, n)      extern t VNET_NAME(n)
271 #define VNET_DEFINE(t, n)       t VNET_NAME(n) __section(VNET_SETNAME) __used
272 #define _VNET_PTR(b, n)         (__typeof(VNET_NAME(n))*)               \
273                                     ((b) + (uintptr_t)&VNET_NAME(n))
274
275 #define _VNET(b, n)             (*_VNET_PTR(b, n))
276
277 /*
278  * Virtualized global variable accessor macros.
279  */
280 #define VNET_VNET_PTR(vnet, n)          _VNET_PTR((vnet)->vnet_data_base, n)
281 #define VNET_VNET(vnet, n)              (*VNET_VNET_PTR((vnet), n))
282
283 #define VNET_PTR(n)             VNET_VNET_PTR(curvnet, n)
284 #define VNET(n)                 VNET_VNET(curvnet, n)
285
286 /*
287  * Virtual network stack allocator interfaces from the kernel linker.
288  */
289 void    *vnet_data_alloc(int size);
290 void     vnet_data_copy(void *start, int size);
291 void     vnet_data_free(void *start_arg, int size);
292
293 /*
294  * Virtual sysinit mechanism, allowing network stack components to declare
295  * startup and shutdown methods to be run when virtual network stack
296  * instances are created and destroyed.
297  */
298 #include <sys/kernel.h>
299
300 /*
301  * SYSINIT/SYSUNINIT variants that provide per-vnet constructors and
302  * destructors.
303  */
304 struct vnet_sysinit {
305         enum sysinit_sub_id     subsystem;
306         enum sysinit_elem_order order;
307         sysinit_cfunc_t         func;
308         const void              *arg;
309         TAILQ_ENTRY(vnet_sysinit) link;
310 };
311
312 #define VNET_SYSINIT(ident, subsystem, order, func, arg)                \
313         static struct vnet_sysinit ident ## _vnet_init = {              \
314                 subsystem,                                              \
315                 order,                                                  \
316                 (sysinit_cfunc_t)(sysinit_nfunc_t)func,                 \
317                 (arg)                                                   \
318         };                                                              \
319         SYSINIT(vnet_init_ ## ident, subsystem, order,                  \
320             vnet_register_sysinit, &ident ## _vnet_init);               \
321         SYSUNINIT(vnet_init_ ## ident, subsystem, order,                \
322             vnet_deregister_sysinit, &ident ## _vnet_init)
323
324 #define VNET_SYSUNINIT(ident, subsystem, order, func, arg)              \
325         static struct vnet_sysinit ident ## _vnet_uninit = {            \
326                 subsystem,                                              \
327                 order,                                                  \
328                 (sysinit_cfunc_t)(sysinit_nfunc_t)func,                 \
329                 (arg)                                                   \
330         };                                                              \
331         SYSINIT(vnet_uninit_ ## ident, subsystem, order,                \
332             vnet_register_sysuninit, &ident ## _vnet_uninit);           \
333         SYSUNINIT(vnet_uninit_ ## ident, subsystem, order,              \
334             vnet_deregister_sysuninit, &ident ## _vnet_uninit)
335
336 /*
337  * Run per-vnet sysinits or sysuninits during vnet creation/destruction.
338  */
339 void     vnet_sysinit(void);
340 void     vnet_sysuninit(void);
341
342 /*
343  * Interfaces for managing per-vnet constructors and destructors.
344  */
345 void    vnet_register_sysinit(void *arg);
346 void    vnet_register_sysuninit(void *arg);
347 void    vnet_deregister_sysinit(void *arg);
348 void    vnet_deregister_sysuninit(void *arg);
349
350 /*
351  * EVENTHANDLER(9) extensions.
352  */
353 #include <sys/eventhandler.h>
354
355 void    vnet_global_eventhandler_iterator_func(void *, ...);
356 #define VNET_GLOBAL_EVENTHANDLER_REGISTER_TAG(tag, name, func, arg, priority) \
357 do {                                                                    \
358         if (IS_DEFAULT_VNET(curvnet)) {                                 \
359                 (tag) = vimage_eventhandler_register(NULL, #name, func, \
360                     arg, priority,                                      \
361                     vnet_global_eventhandler_iterator_func);            \
362         }                                                               \
363 } while(0)
364 #define VNET_GLOBAL_EVENTHANDLER_REGISTER(name, func, arg, priority)    \
365 do {                                                                    \
366         if (IS_DEFAULT_VNET(curvnet)) {                                 \
367                 vimage_eventhandler_register(NULL, #name, func,         \
368                     arg, priority,                                      \
369                     vnet_global_eventhandler_iterator_func);            \
370         }                                                               \
371 } while(0)
372
373 #else /* !VIMAGE */
374
375 /*
376  * Various virtual network stack macros compile to no-ops without VIMAGE.
377  */
378 #define curvnet                 NULL
379
380 #define VNET_ASSERT(exp, msg)
381 #define CURVNET_SET(arg)
382 #define CURVNET_SET_QUIET(arg)
383 #define CURVNET_RESTORE()
384
385 #define VNET_LIST_RLOCK()
386 #define VNET_LIST_RLOCK_NOSLEEP()
387 #define VNET_LIST_RUNLOCK()
388 #define VNET_LIST_RUNLOCK_NOSLEEP()
389 #define VNET_ITERATOR_DECL(arg)
390 #define VNET_FOREACH(arg)
391
392 #define IS_DEFAULT_VNET(arg)    1
393 #define CRED_TO_VNET(cr)        NULL
394 #define TD_TO_VNET(td)          NULL
395 #define P_TO_VNET(p)            NULL
396
397 /*
398  * Versions of the VNET macros that compile to normal global variables and
399  * standard sysctl definitions.
400  */
401 #define VNET_NAME(n)            n
402 #define VNET_DECLARE(t, n)      extern t n
403 #define VNET_DEFINE(t, n)       t n
404 #define _VNET_PTR(b, n)         &VNET_NAME(n)
405
406 /*
407  * Virtualized global variable accessor macros.
408  */
409 #define VNET_VNET_PTR(vnet, n)          (&(n))
410 #define VNET_VNET(vnet, n)              (n)
411
412 #define VNET_PTR(n)             (&(n))
413 #define VNET(n)                 (n)
414
415 /*
416  * When VIMAGE isn't compiled into the kernel, VNET_SYSINIT/VNET_SYSUNINIT
417  * map into normal sysinits, which have the same ordering properties.
418  */
419 #define VNET_SYSINIT(ident, subsystem, order, func, arg)                \
420         SYSINIT(ident, subsystem, order, func, arg)
421 #define VNET_SYSUNINIT(ident, subsystem, order, func, arg)              \
422         SYSUNINIT(ident, subsystem, order, func, arg)
423
424 /*
425  * Without VIMAGE revert to the default implementation.
426  */
427 #define VNET_GLOBAL_EVENTHANDLER_REGISTER_TAG(tag, name, func, arg, priority) \
428         (tag) = eventhandler_register(NULL, #name, func, arg, priority)
429 #define VNET_GLOBAL_EVENTHANDLER_REGISTER(name, func, arg, priority)    \
430         eventhandler_register(NULL, #name, func, arg, priority)
431 #endif /* VIMAGE */
432 #endif /* _KERNEL */
433
434 #endif /* !_NET_VNET_H_ */