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