xref: /illumos-gate/usr/src/uts/common/sys/hook_impl.h (revision b22a70ab)
1381a2a9aSdr146992 /*
2381a2a9aSdr146992  * CDDL HEADER START
3381a2a9aSdr146992  *
4381a2a9aSdr146992  * The contents of this file are subject to the terms of the
5381a2a9aSdr146992  * Common Development and Distribution License (the "License").
6381a2a9aSdr146992  * You may not use this file except in compliance with the License.
7381a2a9aSdr146992  *
8381a2a9aSdr146992  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9381a2a9aSdr146992  * or http://www.opensolaris.org/os/licensing.
10381a2a9aSdr146992  * See the License for the specific language governing permissions
11381a2a9aSdr146992  * and limitations under the License.
12381a2a9aSdr146992  *
13381a2a9aSdr146992  * When distributing Covered Code, include this CDDL HEADER in each
14381a2a9aSdr146992  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15381a2a9aSdr146992  * If applicable, add the following below this CDDL HEADER, with the
16381a2a9aSdr146992  * fields enclosed by brackets "[]" replaced with your own identifying
17381a2a9aSdr146992  * information: Portions Copyright [yyyy] [name of copyright owner]
18381a2a9aSdr146992  *
19381a2a9aSdr146992  * CDDL HEADER END
20381a2a9aSdr146992  */
21381a2a9aSdr146992 /*
227ddc9b1aSDarren Reed  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23381a2a9aSdr146992  * Use is subject to license terms.
24*b22a70abSPatrick Mooney  * Copyright 2018, Joyent, Inc.
25381a2a9aSdr146992  */
26381a2a9aSdr146992 
27381a2a9aSdr146992 /*
28381a2a9aSdr146992  * This file include internal used definition and data structure of hooks
29381a2a9aSdr146992  */
30381a2a9aSdr146992 
31381a2a9aSdr146992 #ifndef _SYS_HOOK_IMPL_H
32381a2a9aSdr146992 #define	_SYS_HOOK_IMPL_H
33381a2a9aSdr146992 
34381a2a9aSdr146992 #include <sys/hook.h>
35381a2a9aSdr146992 #include <sys/condvar_impl.h>
36f4b3ec61Sdh155122 #include <sys/netstack.h>
37381a2a9aSdr146992 
38381a2a9aSdr146992 #ifdef	__cplusplus
39381a2a9aSdr146992 extern "C" {
40381a2a9aSdr146992 #endif
41381a2a9aSdr146992 
427ddc9b1aSDarren Reed typedef enum fwflag_e {
437ddc9b1aSDarren Reed 	FWF_NONE		= 0x00,
447ddc9b1aSDarren Reed 	FWF_DESTROY_ACTIVE	= 0x01,
457ddc9b1aSDarren Reed 	FWF_ADD_ACTIVE		= 0x04,
467ddc9b1aSDarren Reed 	FWF_DEL_ACTIVE		= 0x08,
477ddc9b1aSDarren Reed 	FWF_DESTROY_WANTED	= 0x10,
487ddc9b1aSDarren Reed 	FWF_ADD_WANTED		= 0x40,
497ddc9b1aSDarren Reed 	FWF_DEL_WANTED		= 0x80,
507ddc9b1aSDarren Reed 	FWF_NOT_READY		= 0x100
517ddc9b1aSDarren Reed } fwflag_t;
527ddc9b1aSDarren Reed 
534a9b8375SDarren Reed #define	FWF_ADD_WAIT_MASK	(FWF_ADD_ACTIVE|FWF_DEL_ACTIVE|FWF_ADD_WANTED)
544a9b8375SDarren Reed #define	FWF_DEL_WAIT_MASK	(FWF_ADD_ACTIVE|FWF_DEL_ACTIVE|\
557ddc9b1aSDarren Reed     FWF_ADD_WANTED|FWF_DEL_WANTED)
567ddc9b1aSDarren Reed #define	FWF_UNSAFE		(FWF_DESTROY_ACTIVE|FWF_NOT_READY)
577ddc9b1aSDarren Reed #define	FWF_DESTROY		(FWF_DESTROY_ACTIVE|FWF_DESTROY_WANTED)
587ddc9b1aSDarren Reed #define	FWF_DESTROY_OK(x)	((x)->fw_flags == FWF_DESTROY_WANTED)
597ddc9b1aSDarren Reed 
607ddc9b1aSDarren Reed typedef struct flagwait_s {
617ddc9b1aSDarren Reed 	kcondvar_t	fw_cv;
627ddc9b1aSDarren Reed 	kmutex_t	fw_lock;
637ddc9b1aSDarren Reed 	uint32_t	fw_flags;
647ddc9b1aSDarren Reed 	cvwaitlock_t	*fw_owner;
657ddc9b1aSDarren Reed } flagwait_t;
667ddc9b1aSDarren Reed 
677ddc9b1aSDarren Reed 
68381a2a9aSdr146992 /*
69381a2a9aSdr146992  * The following diagram describes the linking together of data structures
70381a2a9aSdr146992  * used in this implementation of callback hooks.  The start of it all is
71381a2a9aSdr146992  * the "familylist" variable in hook.c.  The relationships between data
72381a2a9aSdr146992  * structures is:
73381a2a9aSdr146992  * - there is a list of hook families;
74381a2a9aSdr146992  * - each hook family can have a list of hook events;
75381a2a9aSdr146992  * - each hook_event_t must be uniquely associated with one family and event;
76381a2a9aSdr146992  * - each hook event can have a list of registered hooks to call.
77381a2a9aSdr146992  *
78381a2a9aSdr146992  *   familylist                    +--------------+
79381a2a9aSdr146992  *       |                         | hook_event_t |<--\
80381a2a9aSdr146992  *       |                         +--------------+   |
81381a2a9aSdr146992  *       V                                            |
82381a2a9aSdr146992  * +-------------------+       ->+------------------+ |     ->+--------------+
83381a2a9aSdr146992  * | hook_family_int_t |      /  | hook_event_int_t | |    /  | hook_int_t   |
84381a2a9aSdr146992  * | +---------------+ |     /   |                  | /   /   | +----------+ |
85381a2a9aSdr146992  * | | hook_family_t | |    /    | hei_event---------/   /    | | hook_t   | |
867ddc9b1aSDarren Reed  * | +---------------+ |   /     | hei_nhead----------\ /     | +----------+ |
877ddc9b1aSDarren Reed  * |                   |  /      |                  |  X      |              |
887ddc9b1aSDarren Reed  * | hfi_head------------/       | hei_head-----------/ \     | hi_entry--\  |
897ddc9b1aSDarren Reed  * | hfi_entry--\      |         | hei_entry--\     |   |     +-----------|--+
907ddc9b1aSDarren Reed  * +------------|------+         +------------|-----+   |                 |
917ddc9b1aSDarren Reed  *              |                             |         |                 |
927ddc9b1aSDarren Reed  *              V                             V         |                 V
937ddc9b1aSDarren Reed  * +-------------------+         +------------------+   |     +--------------+
947ddc9b1aSDarren Reed  * | hook_family_int_t |         | hook_event_int_t |   |     | hook_int_t   |
957ddc9b1aSDarren Reed  *                                                      V
967ddc9b1aSDarren Reed  *                                             +--------------+
977ddc9b1aSDarren Reed  *                                             |
98381a2a9aSdr146992  * ...
99381a2a9aSdr146992  */
100381a2a9aSdr146992 
1017ddc9b1aSDarren Reed typedef struct hook_hook_kstat {
1027ddc9b1aSDarren Reed 	kstat_named_t			hook_version;
1037ddc9b1aSDarren Reed 	kstat_named_t			hook_flags;
1047ddc9b1aSDarren Reed 	kstat_named_t			hook_hint;
1057ddc9b1aSDarren Reed 	kstat_named_t			hook_hintvalue;
1067ddc9b1aSDarren Reed 	kstat_named_t			hook_position;
1077ddc9b1aSDarren Reed 	kstat_named_t			hook_hits;
1087ddc9b1aSDarren Reed } hook_hook_kstat_t;
1097ddc9b1aSDarren Reed 
110381a2a9aSdr146992 /*
111381a2a9aSdr146992  * hook_int: internal storage of hook
112381a2a9aSdr146992  */
113381a2a9aSdr146992 typedef struct hook_int {
114381a2a9aSdr146992 	TAILQ_ENTRY(hook_int)		hi_entry;
115381a2a9aSdr146992 	hook_t				hi_hook;
1167ddc9b1aSDarren Reed 	hook_hook_kstat_t		hi_kstats;
1177ddc9b1aSDarren Reed 	kstat_t				*hi_kstatp;
1187ddc9b1aSDarren Reed 	char				*hi_ksname;
1197ddc9b1aSDarren Reed 	cvwaitlock_t			hi_notify_lock;
120381a2a9aSdr146992 } hook_int_t;
121381a2a9aSdr146992 
122381a2a9aSdr146992 /*
1237ddc9b1aSDarren Reed  * hook_int_head: tail queue of hook_int
124381a2a9aSdr146992  */
125381a2a9aSdr146992 TAILQ_HEAD(hook_int_head, hook_int);
126381a2a9aSdr146992 typedef struct hook_int_head hook_int_head_t;
127381a2a9aSdr146992 
1287ddc9b1aSDarren Reed 
1297ddc9b1aSDarren Reed typedef struct hook_notify {
1307ddc9b1aSDarren Reed 	TAILQ_ENTRY(hook_notify)	hn_entry;
1317ddc9b1aSDarren Reed 	hook_notify_fn_t		hn_func;
1327ddc9b1aSDarren Reed 	void				*hn_arg;
1337ddc9b1aSDarren Reed 	uint32_t			hn_flags;
1347ddc9b1aSDarren Reed } hook_notify_t;
1357ddc9b1aSDarren Reed 
1367ddc9b1aSDarren Reed TAILQ_HEAD(hook_notify_head, hook_notify);
1377ddc9b1aSDarren Reed typedef struct hook_notify_head hook_notify_head_t;
1387ddc9b1aSDarren Reed 
1397ddc9b1aSDarren Reed 
1407ddc9b1aSDarren Reed typedef struct hook_event_kstat {
1417ddc9b1aSDarren Reed 	kstat_named_t			hooks_added;
1427ddc9b1aSDarren Reed 	kstat_named_t			hooks_removed;
1437ddc9b1aSDarren Reed 	kstat_named_t			events;
1447ddc9b1aSDarren Reed } hook_event_kstat_t;
1457ddc9b1aSDarren Reed 
146381a2a9aSdr146992 /*
147381a2a9aSdr146992  * hook_event_int: internal storage of hook_event
148381a2a9aSdr146992  */
149381a2a9aSdr146992 typedef struct hook_event_int {
150381a2a9aSdr146992 	cvwaitlock_t			hei_lock;
151381a2a9aSdr146992 	SLIST_ENTRY(hook_event_int)	hei_entry;
152381a2a9aSdr146992 	hook_event_t			*hei_event;
153381a2a9aSdr146992 	hook_int_head_t			hei_head;
1547ddc9b1aSDarren Reed 	kstat_t				*hei_kstatp;
1557ddc9b1aSDarren Reed 	hook_event_kstat_t		hei_kstats;
1567ddc9b1aSDarren Reed 	hook_notify_head_t		hei_nhead;
1577ddc9b1aSDarren Reed 	flagwait_t			hei_waiter;
1587ddc9b1aSDarren Reed 	boolean_t			hei_condemned;
1598ad74188SDarren Reed 	boolean_t			hei_shutdown;
160381a2a9aSdr146992 } hook_event_int_t;
161381a2a9aSdr146992 
162381a2a9aSdr146992 /*
163381a2a9aSdr146992  * hook_event_int_head: singly-linked list of hook_event_int
164381a2a9aSdr146992  */
165381a2a9aSdr146992 SLIST_HEAD(hook_event_int_head, hook_event_int);
166381a2a9aSdr146992 typedef struct hook_event_int_head hook_event_int_head_t;
167381a2a9aSdr146992 
168381a2a9aSdr146992 /*
169381a2a9aSdr146992  * hook_family_int: internal storage of hook_family
170381a2a9aSdr146992  */
171381a2a9aSdr146992 typedef struct hook_family_int {
1727ddc9b1aSDarren Reed 	cvwaitlock_t			hfi_lock;
173381a2a9aSdr146992 	SLIST_ENTRY(hook_family_int)	hfi_entry;
174381a2a9aSdr146992 	hook_event_int_head_t		hfi_head;
175381a2a9aSdr146992 	hook_family_t			hfi_family;
1767ddc9b1aSDarren Reed 	kstat_t				*hfi_kstat;
1777ddc9b1aSDarren Reed 	struct hook_stack		*hfi_stack;
1787ddc9b1aSDarren Reed 	hook_notify_head_t		hfi_nhead;
1797ddc9b1aSDarren Reed 	flagwait_t			hfi_waiter;
1807ddc9b1aSDarren Reed 	boolean_t			hfi_condemned;
1818ad74188SDarren Reed 	boolean_t			hfi_shutdown;
182381a2a9aSdr146992 } hook_family_int_t;
183381a2a9aSdr146992 
184381a2a9aSdr146992 /*
185381a2a9aSdr146992  * hook_family_int_head: singly-linked list of hook_family
186381a2a9aSdr146992  */
187381a2a9aSdr146992 SLIST_HEAD(hook_family_int_head, hook_family_int);
188381a2a9aSdr146992 typedef struct hook_family_int_head hook_family_int_head_t;
189381a2a9aSdr146992 
190381a2a9aSdr146992 /*
191f4b3ec61Sdh155122  * hook stack instances
192f4b3ec61Sdh155122  */
193f4b3ec61Sdh155122 struct hook_stack {
1947ddc9b1aSDarren Reed 	cvwaitlock_t			hks_lock;
1957ddc9b1aSDarren Reed 	SLIST_ENTRY(hook_stack)		hks_entry;
196f4b3ec61Sdh155122 	hook_family_int_head_t		hks_familylist;	/* family list head */
1977ddc9b1aSDarren Reed 	netstack_t			*hks_netstack;
1987ddc9b1aSDarren Reed 	netstackid_t			hks_netstackid;
1997ddc9b1aSDarren Reed 	hook_notify_head_t		hks_nhead;
2007ddc9b1aSDarren Reed 	int				hks_shutdown;
2017ddc9b1aSDarren Reed 	flagwait_t			hks_waiter;
202f4b3ec61Sdh155122 };
203f4b3ec61Sdh155122 typedef struct hook_stack hook_stack_t;
2047ddc9b1aSDarren Reed SLIST_HEAD(hook_stack_head, hook_stack);
2057ddc9b1aSDarren Reed typedef struct hook_stack_head hook_stack_head_t;
206f4b3ec61Sdh155122 
207f4b3ec61Sdh155122 /*
208381a2a9aSdr146992  * Names of hooks families currently defined by Solaris
209381a2a9aSdr146992  */
210381a2a9aSdr146992 #define	Hn_ARP	"arp"
211381a2a9aSdr146992 #define	Hn_IPV4	"inet"
212381a2a9aSdr146992 #define	Hn_IPV6	"inet6"
213*b22a70abSPatrick Mooney #define	Hn_VIONA "viona_inet"
214381a2a9aSdr146992 
2157ddc9b1aSDarren Reed extern int hook_run(hook_family_int_t *, hook_event_token_t, hook_data_t);
216381a2a9aSdr146992 extern int hook_register(hook_family_int_t *, char *, hook_t *);
2177ddc9b1aSDarren Reed 
218381a2a9aSdr146992 extern int hook_unregister(hook_family_int_t *, char *, hook_t *);
2197ddc9b1aSDarren Reed extern hook_event_int_t *hook_event_add(hook_family_int_t *, hook_event_t *);
2207ddc9b1aSDarren Reed extern int hook_event_notify_register(hook_family_int_t *, char *,
2217ddc9b1aSDarren Reed     hook_notify_fn_t, void *);
2227ddc9b1aSDarren Reed extern int hook_event_notify_unregister(hook_family_int_t *, char *,
2237ddc9b1aSDarren Reed     hook_notify_fn_t);
2247ddc9b1aSDarren Reed extern int hook_event_remove(hook_family_int_t *, hook_event_t *);
2258ad74188SDarren Reed extern int hook_event_shutdown(hook_family_int_t *, hook_event_t *);
2267ddc9b1aSDarren Reed 
2274a9b8375SDarren Reed extern hook_family_int_t *hook_family_add(hook_family_t *, hook_stack_t *,
2284a9b8375SDarren Reed     void **);
2297ddc9b1aSDarren Reed extern int hook_family_notify_register(hook_family_int_t *, hook_notify_fn_t,
2307ddc9b1aSDarren Reed     void *);
2317ddc9b1aSDarren Reed extern int hook_family_notify_unregister(hook_family_int_t *, hook_notify_fn_t);
2327ddc9b1aSDarren Reed extern int hook_family_remove(hook_family_int_t *);
2338ad74188SDarren Reed extern int hook_family_shutdown(hook_family_int_t *);
2347ddc9b1aSDarren Reed 
2357ddc9b1aSDarren Reed extern int hook_stack_notify_register(netstackid_t, hook_notify_fn_t, void *);
2367ddc9b1aSDarren Reed extern int hook_stack_notify_unregister(netstackid_t, hook_notify_fn_t);
2377ddc9b1aSDarren Reed 
238381a2a9aSdr146992 
239381a2a9aSdr146992 #ifdef	__cplusplus
240381a2a9aSdr146992 }
241381a2a9aSdr146992 #endif
242381a2a9aSdr146992 
243381a2a9aSdr146992 #endif /* _SYS_HOOK_IMPL_H */
244