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