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