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