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. 24381a2a9aSdr146992 */ 25381a2a9aSdr146992 26381a2a9aSdr146992 /* 27381a2a9aSdr146992 * This file include internal used definition and data structure of hooks 28381a2a9aSdr146992 */ 29381a2a9aSdr146992 30381a2a9aSdr146992 #ifndef _SYS_HOOK_IMPL_H 31381a2a9aSdr146992 #define _SYS_HOOK_IMPL_H 32381a2a9aSdr146992 33381a2a9aSdr146992 #include <sys/hook.h> 34381a2a9aSdr146992 #include <sys/condvar_impl.h> 35f4b3ec61Sdh155122 #include <sys/netstack.h> 36381a2a9aSdr146992 37381a2a9aSdr146992 #ifdef __cplusplus 38381a2a9aSdr146992 extern "C" { 39381a2a9aSdr146992 #endif 40381a2a9aSdr146992 417ddc9b1aSDarren Reed typedef enum fwflag_e { 427ddc9b1aSDarren Reed FWF_NONE = 0x00, 437ddc9b1aSDarren Reed FWF_DESTROY_ACTIVE = 0x01, 447ddc9b1aSDarren Reed FWF_ADD_ACTIVE = 0x04, 457ddc9b1aSDarren Reed FWF_DEL_ACTIVE = 0x08, 467ddc9b1aSDarren Reed FWF_DESTROY_WANTED = 0x10, 477ddc9b1aSDarren Reed FWF_ADD_WANTED = 0x40, 487ddc9b1aSDarren Reed FWF_DEL_WANTED = 0x80, 497ddc9b1aSDarren Reed FWF_NOT_READY = 0x100 507ddc9b1aSDarren Reed } fwflag_t; 517ddc9b1aSDarren Reed 52*4a9b8375SDarren Reed #define FWF_ADD_WAIT_MASK (FWF_ADD_ACTIVE|FWF_DEL_ACTIVE|FWF_ADD_WANTED) 53*4a9b8375SDarren Reed #define FWF_DEL_WAIT_MASK (FWF_ADD_ACTIVE|FWF_DEL_ACTIVE|\ 547ddc9b1aSDarren Reed FWF_ADD_WANTED|FWF_DEL_WANTED) 557ddc9b1aSDarren Reed #define FWF_UNSAFE (FWF_DESTROY_ACTIVE|FWF_NOT_READY) 567ddc9b1aSDarren Reed #define FWF_DESTROY (FWF_DESTROY_ACTIVE|FWF_DESTROY_WANTED) 577ddc9b1aSDarren Reed #define FWF_DESTROY_OK(x) ((x)->fw_flags == FWF_DESTROY_WANTED) 587ddc9b1aSDarren Reed 597ddc9b1aSDarren Reed typedef struct flagwait_s { 607ddc9b1aSDarren Reed kcondvar_t fw_cv; 617ddc9b1aSDarren Reed kmutex_t fw_lock; 627ddc9b1aSDarren Reed uint32_t fw_flags; 637ddc9b1aSDarren Reed cvwaitlock_t *fw_owner; 647ddc9b1aSDarren Reed } flagwait_t; 657ddc9b1aSDarren Reed 667ddc9b1aSDarren Reed 67381a2a9aSdr146992 /* 68381a2a9aSdr146992 * The following diagram describes the linking together of data structures 69381a2a9aSdr146992 * used in this implementation of callback hooks. The start of it all is 70381a2a9aSdr146992 * the "familylist" variable in hook.c. The relationships between data 71381a2a9aSdr146992 * structures is: 72381a2a9aSdr146992 * - there is a list of hook families; 73381a2a9aSdr146992 * - each hook family can have a list of hook events; 74381a2a9aSdr146992 * - each hook_event_t must be uniquely associated with one family and event; 75381a2a9aSdr146992 * - each hook event can have a list of registered hooks to call. 76381a2a9aSdr146992 * 77381a2a9aSdr146992 * familylist +--------------+ 78381a2a9aSdr146992 * | | hook_event_t |<--\ 79381a2a9aSdr146992 * | +--------------+ | 80381a2a9aSdr146992 * V | 81381a2a9aSdr146992 * +-------------------+ ->+------------------+ | ->+--------------+ 82381a2a9aSdr146992 * | hook_family_int_t | / | hook_event_int_t | | / | hook_int_t | 83381a2a9aSdr146992 * | +---------------+ | / | | / / | +----------+ | 84381a2a9aSdr146992 * | | hook_family_t | | / | hei_event---------/ / | | hook_t | | 857ddc9b1aSDarren Reed * | +---------------+ | / | hei_nhead----------\ / | +----------+ | 867ddc9b1aSDarren Reed * | | / | | X | | 877ddc9b1aSDarren Reed * | hfi_head------------/ | hei_head-----------/ \ | hi_entry--\ | 887ddc9b1aSDarren Reed * | hfi_entry--\ | | hei_entry--\ | | +-----------|--+ 897ddc9b1aSDarren Reed * +------------|------+ +------------|-----+ | | 907ddc9b1aSDarren Reed * | | | | 917ddc9b1aSDarren Reed * V V | V 927ddc9b1aSDarren Reed * +-------------------+ +------------------+ | +--------------+ 937ddc9b1aSDarren Reed * | hook_family_int_t | | hook_event_int_t | | | hook_int_t | 947ddc9b1aSDarren Reed * V 957ddc9b1aSDarren Reed * +--------------+ 967ddc9b1aSDarren Reed * | 97381a2a9aSdr146992 * ... 98381a2a9aSdr146992 */ 99381a2a9aSdr146992 1007ddc9b1aSDarren Reed typedef struct hook_hook_kstat { 1017ddc9b1aSDarren Reed kstat_named_t hook_version; 1027ddc9b1aSDarren Reed kstat_named_t hook_flags; 1037ddc9b1aSDarren Reed kstat_named_t hook_hint; 1047ddc9b1aSDarren Reed kstat_named_t hook_hintvalue; 1057ddc9b1aSDarren Reed kstat_named_t hook_position; 1067ddc9b1aSDarren Reed kstat_named_t hook_hits; 1077ddc9b1aSDarren Reed } hook_hook_kstat_t; 1087ddc9b1aSDarren Reed 109381a2a9aSdr146992 /* 110381a2a9aSdr146992 * hook_int: internal storage of hook 111381a2a9aSdr146992 */ 112381a2a9aSdr146992 typedef struct hook_int { 113381a2a9aSdr146992 TAILQ_ENTRY(hook_int) hi_entry; 114381a2a9aSdr146992 hook_t hi_hook; 1157ddc9b1aSDarren Reed hook_hook_kstat_t hi_kstats; 1167ddc9b1aSDarren Reed kstat_t *hi_kstatp; 1177ddc9b1aSDarren Reed char *hi_ksname; 1187ddc9b1aSDarren Reed cvwaitlock_t hi_notify_lock; 119381a2a9aSdr146992 } hook_int_t; 120381a2a9aSdr146992 121381a2a9aSdr146992 /* 1227ddc9b1aSDarren Reed * hook_int_head: tail queue of hook_int 123381a2a9aSdr146992 */ 124381a2a9aSdr146992 TAILQ_HEAD(hook_int_head, hook_int); 125381a2a9aSdr146992 typedef struct hook_int_head hook_int_head_t; 126381a2a9aSdr146992 1277ddc9b1aSDarren Reed 1287ddc9b1aSDarren Reed typedef struct hook_notify { 1297ddc9b1aSDarren Reed TAILQ_ENTRY(hook_notify) hn_entry; 1307ddc9b1aSDarren Reed hook_notify_fn_t hn_func; 1317ddc9b1aSDarren Reed void *hn_arg; 1327ddc9b1aSDarren Reed uint32_t hn_flags; 1337ddc9b1aSDarren Reed } hook_notify_t; 1347ddc9b1aSDarren Reed 1357ddc9b1aSDarren Reed TAILQ_HEAD(hook_notify_head, hook_notify); 1367ddc9b1aSDarren Reed typedef struct hook_notify_head hook_notify_head_t; 1377ddc9b1aSDarren Reed 1387ddc9b1aSDarren Reed 1397ddc9b1aSDarren Reed typedef struct hook_event_kstat { 1407ddc9b1aSDarren Reed kstat_named_t hooks_added; 1417ddc9b1aSDarren Reed kstat_named_t hooks_removed; 1427ddc9b1aSDarren Reed kstat_named_t events; 1437ddc9b1aSDarren Reed } hook_event_kstat_t; 1447ddc9b1aSDarren Reed 145381a2a9aSdr146992 /* 146381a2a9aSdr146992 * hook_event_int: internal storage of hook_event 147381a2a9aSdr146992 */ 148381a2a9aSdr146992 typedef struct hook_event_int { 149381a2a9aSdr146992 cvwaitlock_t hei_lock; 150381a2a9aSdr146992 SLIST_ENTRY(hook_event_int) hei_entry; 151381a2a9aSdr146992 hook_event_t *hei_event; 152381a2a9aSdr146992 hook_int_head_t hei_head; 1537ddc9b1aSDarren Reed kstat_t *hei_kstatp; 1547ddc9b1aSDarren Reed hook_event_kstat_t hei_kstats; 1557ddc9b1aSDarren Reed hook_notify_head_t hei_nhead; 1567ddc9b1aSDarren Reed flagwait_t hei_waiter; 1577ddc9b1aSDarren Reed boolean_t hei_condemned; 1588ad74188SDarren Reed boolean_t hei_shutdown; 159381a2a9aSdr146992 } hook_event_int_t; 160381a2a9aSdr146992 161381a2a9aSdr146992 /* 162381a2a9aSdr146992 * hook_event_int_head: singly-linked list of hook_event_int 163381a2a9aSdr146992 */ 164381a2a9aSdr146992 SLIST_HEAD(hook_event_int_head, hook_event_int); 165381a2a9aSdr146992 typedef struct hook_event_int_head hook_event_int_head_t; 166381a2a9aSdr146992 167381a2a9aSdr146992 /* 168381a2a9aSdr146992 * hook_family_int: internal storage of hook_family 169381a2a9aSdr146992 */ 170381a2a9aSdr146992 typedef struct hook_family_int { 1717ddc9b1aSDarren Reed cvwaitlock_t hfi_lock; 172381a2a9aSdr146992 SLIST_ENTRY(hook_family_int) hfi_entry; 173381a2a9aSdr146992 hook_event_int_head_t hfi_head; 174381a2a9aSdr146992 hook_family_t hfi_family; 1757ddc9b1aSDarren Reed kstat_t *hfi_kstat; 1767ddc9b1aSDarren Reed struct hook_stack *hfi_stack; 1777ddc9b1aSDarren Reed hook_notify_head_t hfi_nhead; 1787ddc9b1aSDarren Reed flagwait_t hfi_waiter; 1797ddc9b1aSDarren Reed boolean_t hfi_condemned; 1808ad74188SDarren Reed boolean_t hfi_shutdown; 181381a2a9aSdr146992 } hook_family_int_t; 182381a2a9aSdr146992 183381a2a9aSdr146992 /* 184381a2a9aSdr146992 * hook_family_int_head: singly-linked list of hook_family 185381a2a9aSdr146992 */ 186381a2a9aSdr146992 SLIST_HEAD(hook_family_int_head, hook_family_int); 187381a2a9aSdr146992 typedef struct hook_family_int_head hook_family_int_head_t; 188381a2a9aSdr146992 189381a2a9aSdr146992 /* 190f4b3ec61Sdh155122 * hook stack instances 191f4b3ec61Sdh155122 */ 192f4b3ec61Sdh155122 struct hook_stack { 1937ddc9b1aSDarren Reed cvwaitlock_t hks_lock; 1947ddc9b1aSDarren Reed SLIST_ENTRY(hook_stack) hks_entry; 195f4b3ec61Sdh155122 hook_family_int_head_t hks_familylist; /* family list head */ 1967ddc9b1aSDarren Reed netstack_t *hks_netstack; 1977ddc9b1aSDarren Reed netstackid_t hks_netstackid; 1987ddc9b1aSDarren Reed hook_notify_head_t hks_nhead; 1997ddc9b1aSDarren Reed int hks_shutdown; 2007ddc9b1aSDarren Reed flagwait_t hks_waiter; 201f4b3ec61Sdh155122 }; 202f4b3ec61Sdh155122 typedef struct hook_stack hook_stack_t; 2037ddc9b1aSDarren Reed SLIST_HEAD(hook_stack_head, hook_stack); 2047ddc9b1aSDarren Reed typedef struct hook_stack_head hook_stack_head_t; 205f4b3ec61Sdh155122 206f4b3ec61Sdh155122 /* 207381a2a9aSdr146992 * Names of hooks families currently defined by Solaris 208381a2a9aSdr146992 */ 209381a2a9aSdr146992 #define Hn_ARP "arp" 210381a2a9aSdr146992 #define Hn_IPV4 "inet" 211381a2a9aSdr146992 #define Hn_IPV6 "inet6" 212381a2a9aSdr146992 2137ddc9b1aSDarren Reed extern int hook_run(hook_family_int_t *, hook_event_token_t, hook_data_t); 214381a2a9aSdr146992 extern int hook_register(hook_family_int_t *, char *, hook_t *); 2157ddc9b1aSDarren Reed 216381a2a9aSdr146992 extern int hook_unregister(hook_family_int_t *, char *, hook_t *); 2177ddc9b1aSDarren Reed extern hook_event_int_t *hook_event_add(hook_family_int_t *, hook_event_t *); 2187ddc9b1aSDarren Reed extern int hook_event_notify_register(hook_family_int_t *, char *, 2197ddc9b1aSDarren Reed hook_notify_fn_t, void *); 2207ddc9b1aSDarren Reed extern int hook_event_notify_unregister(hook_family_int_t *, char *, 2217ddc9b1aSDarren Reed hook_notify_fn_t); 2227ddc9b1aSDarren Reed extern int hook_event_remove(hook_family_int_t *, hook_event_t *); 2238ad74188SDarren Reed extern int hook_event_shutdown(hook_family_int_t *, hook_event_t *); 2247ddc9b1aSDarren Reed 225*4a9b8375SDarren Reed extern hook_family_int_t *hook_family_add(hook_family_t *, hook_stack_t *, 226*4a9b8375SDarren Reed void **); 2277ddc9b1aSDarren Reed extern int hook_family_notify_register(hook_family_int_t *, hook_notify_fn_t, 2287ddc9b1aSDarren Reed void *); 2297ddc9b1aSDarren Reed extern int hook_family_notify_unregister(hook_family_int_t *, hook_notify_fn_t); 2307ddc9b1aSDarren Reed extern int hook_family_remove(hook_family_int_t *); 2318ad74188SDarren Reed extern int hook_family_shutdown(hook_family_int_t *); 2327ddc9b1aSDarren Reed 2337ddc9b1aSDarren Reed extern int hook_stack_notify_register(netstackid_t, hook_notify_fn_t, void *); 2347ddc9b1aSDarren Reed extern int hook_stack_notify_unregister(netstackid_t, hook_notify_fn_t); 2357ddc9b1aSDarren Reed 236381a2a9aSdr146992 237381a2a9aSdr146992 #ifdef __cplusplus 238381a2a9aSdr146992 } 239381a2a9aSdr146992 #endif 240381a2a9aSdr146992 241381a2a9aSdr146992 #endif /* _SYS_HOOK_IMPL_H */ 242