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