xref: /illumos-gate/usr/src/uts/common/sys/hook_impl.h (revision b22a70ab)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  * Copyright 2018, Joyent, Inc.
25  */
26 
27 /*
28  * This file include internal used definition and data structure of hooks
29  */
30 
31 #ifndef _SYS_HOOK_IMPL_H
32 #define	_SYS_HOOK_IMPL_H
33 
34 #include <sys/hook.h>
35 #include <sys/condvar_impl.h>
36 #include <sys/netstack.h>
37 
38 #ifdef	__cplusplus
39 extern "C" {
40 #endif
41 
42 typedef enum fwflag_e {
43 	FWF_NONE		= 0x00,
44 	FWF_DESTROY_ACTIVE	= 0x01,
45 	FWF_ADD_ACTIVE		= 0x04,
46 	FWF_DEL_ACTIVE		= 0x08,
47 	FWF_DESTROY_WANTED	= 0x10,
48 	FWF_ADD_WANTED		= 0x40,
49 	FWF_DEL_WANTED		= 0x80,
50 	FWF_NOT_READY		= 0x100
51 } fwflag_t;
52 
53 #define	FWF_ADD_WAIT_MASK	(FWF_ADD_ACTIVE|FWF_DEL_ACTIVE|FWF_ADD_WANTED)
54 #define	FWF_DEL_WAIT_MASK	(FWF_ADD_ACTIVE|FWF_DEL_ACTIVE|\
55     FWF_ADD_WANTED|FWF_DEL_WANTED)
56 #define	FWF_UNSAFE		(FWF_DESTROY_ACTIVE|FWF_NOT_READY)
57 #define	FWF_DESTROY		(FWF_DESTROY_ACTIVE|FWF_DESTROY_WANTED)
58 #define	FWF_DESTROY_OK(x)	((x)->fw_flags == FWF_DESTROY_WANTED)
59 
60 typedef struct flagwait_s {
61 	kcondvar_t	fw_cv;
62 	kmutex_t	fw_lock;
63 	uint32_t	fw_flags;
64 	cvwaitlock_t	*fw_owner;
65 } flagwait_t;
66 
67 
68 /*
69  * The following diagram describes the linking together of data structures
70  * used in this implementation of callback hooks.  The start of it all is
71  * the "familylist" variable in hook.c.  The relationships between data
72  * structures is:
73  * - there is a list of hook families;
74  * - each hook family can have a list of hook events;
75  * - each hook_event_t must be uniquely associated with one family and event;
76  * - each hook event can have a list of registered hooks to call.
77  *
78  *   familylist                    +--------------+
79  *       |                         | hook_event_t |<--\
80  *       |                         +--------------+   |
81  *       V                                            |
82  * +-------------------+       ->+------------------+ |     ->+--------------+
83  * | hook_family_int_t |      /  | hook_event_int_t | |    /  | hook_int_t   |
84  * | +---------------+ |     /   |                  | /   /   | +----------+ |
85  * | | hook_family_t | |    /    | hei_event---------/   /    | | hook_t   | |
86  * | +---------------+ |   /     | hei_nhead----------\ /     | +----------+ |
87  * |                   |  /      |                  |  X      |              |
88  * | hfi_head------------/       | hei_head-----------/ \     | hi_entry--\  |
89  * | hfi_entry--\      |         | hei_entry--\     |   |     +-----------|--+
90  * +------------|------+         +------------|-----+   |                 |
91  *              |                             |         |                 |
92  *              V                             V         |                 V
93  * +-------------------+         +------------------+   |     +--------------+
94  * | hook_family_int_t |         | hook_event_int_t |   |     | hook_int_t   |
95  *                                                      V
96  *                                             +--------------+
97  *                                             |
98  * ...
99  */
100 
101 typedef struct hook_hook_kstat {
102 	kstat_named_t			hook_version;
103 	kstat_named_t			hook_flags;
104 	kstat_named_t			hook_hint;
105 	kstat_named_t			hook_hintvalue;
106 	kstat_named_t			hook_position;
107 	kstat_named_t			hook_hits;
108 } hook_hook_kstat_t;
109 
110 /*
111  * hook_int: internal storage of hook
112  */
113 typedef struct hook_int {
114 	TAILQ_ENTRY(hook_int)		hi_entry;
115 	hook_t				hi_hook;
116 	hook_hook_kstat_t		hi_kstats;
117 	kstat_t				*hi_kstatp;
118 	char				*hi_ksname;
119 	cvwaitlock_t			hi_notify_lock;
120 } hook_int_t;
121 
122 /*
123  * hook_int_head: tail queue of hook_int
124  */
125 TAILQ_HEAD(hook_int_head, hook_int);
126 typedef struct hook_int_head hook_int_head_t;
127 
128 
129 typedef struct hook_notify {
130 	TAILQ_ENTRY(hook_notify)	hn_entry;
131 	hook_notify_fn_t		hn_func;
132 	void				*hn_arg;
133 	uint32_t			hn_flags;
134 } hook_notify_t;
135 
136 TAILQ_HEAD(hook_notify_head, hook_notify);
137 typedef struct hook_notify_head hook_notify_head_t;
138 
139 
140 typedef struct hook_event_kstat {
141 	kstat_named_t			hooks_added;
142 	kstat_named_t			hooks_removed;
143 	kstat_named_t			events;
144 } hook_event_kstat_t;
145 
146 /*
147  * hook_event_int: internal storage of hook_event
148  */
149 typedef struct hook_event_int {
150 	cvwaitlock_t			hei_lock;
151 	SLIST_ENTRY(hook_event_int)	hei_entry;
152 	hook_event_t			*hei_event;
153 	hook_int_head_t			hei_head;
154 	kstat_t				*hei_kstatp;
155 	hook_event_kstat_t		hei_kstats;
156 	hook_notify_head_t		hei_nhead;
157 	flagwait_t			hei_waiter;
158 	boolean_t			hei_condemned;
159 	boolean_t			hei_shutdown;
160 } hook_event_int_t;
161 
162 /*
163  * hook_event_int_head: singly-linked list of hook_event_int
164  */
165 SLIST_HEAD(hook_event_int_head, hook_event_int);
166 typedef struct hook_event_int_head hook_event_int_head_t;
167 
168 /*
169  * hook_family_int: internal storage of hook_family
170  */
171 typedef struct hook_family_int {
172 	cvwaitlock_t			hfi_lock;
173 	SLIST_ENTRY(hook_family_int)	hfi_entry;
174 	hook_event_int_head_t		hfi_head;
175 	hook_family_t			hfi_family;
176 	kstat_t				*hfi_kstat;
177 	struct hook_stack		*hfi_stack;
178 	hook_notify_head_t		hfi_nhead;
179 	flagwait_t			hfi_waiter;
180 	boolean_t			hfi_condemned;
181 	boolean_t			hfi_shutdown;
182 } hook_family_int_t;
183 
184 /*
185  * hook_family_int_head: singly-linked list of hook_family
186  */
187 SLIST_HEAD(hook_family_int_head, hook_family_int);
188 typedef struct hook_family_int_head hook_family_int_head_t;
189 
190 /*
191  * hook stack instances
192  */
193 struct hook_stack {
194 	cvwaitlock_t			hks_lock;
195 	SLIST_ENTRY(hook_stack)		hks_entry;
196 	hook_family_int_head_t		hks_familylist;	/* family list head */
197 	netstack_t			*hks_netstack;
198 	netstackid_t			hks_netstackid;
199 	hook_notify_head_t		hks_nhead;
200 	int				hks_shutdown;
201 	flagwait_t			hks_waiter;
202 };
203 typedef struct hook_stack hook_stack_t;
204 SLIST_HEAD(hook_stack_head, hook_stack);
205 typedef struct hook_stack_head hook_stack_head_t;
206 
207 /*
208  * Names of hooks families currently defined by Solaris
209  */
210 #define	Hn_ARP	"arp"
211 #define	Hn_IPV4	"inet"
212 #define	Hn_IPV6	"inet6"
213 #define	Hn_VIONA "viona_inet"
214 
215 extern int hook_run(hook_family_int_t *, hook_event_token_t, hook_data_t);
216 extern int hook_register(hook_family_int_t *, char *, hook_t *);
217 
218 extern int hook_unregister(hook_family_int_t *, char *, hook_t *);
219 extern hook_event_int_t *hook_event_add(hook_family_int_t *, hook_event_t *);
220 extern int hook_event_notify_register(hook_family_int_t *, char *,
221     hook_notify_fn_t, void *);
222 extern int hook_event_notify_unregister(hook_family_int_t *, char *,
223     hook_notify_fn_t);
224 extern int hook_event_remove(hook_family_int_t *, hook_event_t *);
225 extern int hook_event_shutdown(hook_family_int_t *, hook_event_t *);
226 
227 extern hook_family_int_t *hook_family_add(hook_family_t *, hook_stack_t *,
228     void **);
229 extern int hook_family_notify_register(hook_family_int_t *, hook_notify_fn_t,
230     void *);
231 extern int hook_family_notify_unregister(hook_family_int_t *, hook_notify_fn_t);
232 extern int hook_family_remove(hook_family_int_t *);
233 extern int hook_family_shutdown(hook_family_int_t *);
234 
235 extern int hook_stack_notify_register(netstackid_t, hook_notify_fn_t, void *);
236 extern int hook_stack_notify_unregister(netstackid_t, hook_notify_fn_t);
237 
238 
239 #ifdef	__cplusplus
240 }
241 #endif
242 
243 #endif /* _SYS_HOOK_IMPL_H */
244