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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2002-2003 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #ifndef _IPP_IPP_IMPL_H 28 #define _IPP_IPP_IMPL_H 29 30 /* 31 * IP Policy Framework (IPPF) implementation detail. 32 * 33 * WARNING: Everything in this file is private, belonging to the IPPF 34 * subsystem. The interfaces and declarations made here are subject 35 * to change. 36 */ 37 38 #include <sys/stream.h> 39 #include <sys/thread.h> 40 #include <ipp/ipp.h> 41 42 #ifdef __cplusplus 43 extern "C" { 44 #endif 45 46 #ifdef _KERNEL 47 48 #define IPP_ALIGN 64 49 50 #define IPP_NBUCKET 23 51 52 #define IPP_LOG2NACTION 16 53 #define IPP_NACTION (1 << IPP_LOG2NACTION) 54 55 #define IPP_LOG2NMOD 6 56 #define IPP_NMOD (1 << IPP_LOG2NMOD) 57 58 #define IPP_NCLASS 5 59 #define IPP_NLOG IPP_NMOD 60 61 typedef struct ipp_ref ipp_ref_t; 62 63 struct ipp_ref { 64 ipp_ref_t *ippr_nextp; 65 uint_t ippr_count; 66 union { 67 ipp_mod_t *u_mod; 68 ipp_action_t *u_action; 69 void *u_ptr; 70 } ippr_u; 71 }; 72 73 #define ippr_action ippr_u.u_action 74 #define ippr_mod ippr_u.u_mod 75 #define ippr_ptr ippr_u.u_ptr 76 77 typedef enum { 78 IPP_MODSTATE_PROTO = 0x10, 79 IPP_MODSTATE_AVAILABLE 80 } ipp_modstate_t; 81 82 struct ipp_mod { 83 ipp_mod_id_t ippm_id; 84 ipp_ops_t *ippm_ops; 85 ipp_ref_t *ippm_action; 86 ipp_modstate_t ippm_state; 87 krwlock_t ippm_lock[1]; 88 uint32_t ippm_hold_count; 89 boolean_t ippm_destruct_pending; 90 char ippm_name[MAXNAMELEN]; 91 }; 92 93 typedef enum { 94 IPP_ASTATE_PROTO = 0x20, 95 IPP_ASTATE_CONFIG_PENDING, 96 IPP_ASTATE_AVAILABLE 97 } ipp_astate_t; 98 99 typedef struct cfglock { 100 kmutex_t cl_mutex[1]; 101 kcondvar_t cl_cv[1]; 102 uint_t cl_writers; 103 boolean_t cl_reader; 104 kthread_id_t cl_owner; 105 } cfglock_t; 106 107 #ifndef __lint 108 109 #define CL_READ 0 110 #define CL_WRITE 1 111 112 #define CONFIG_LOCK_INIT(_clp) \ 113 { \ 114 mutex_init((_clp)->cl_mutex, NULL, MUTEX_DEFAULT, \ 115 (void *)ipltospl(LOCK_LEVEL)); \ 116 cv_init((_clp)->cl_cv, NULL, CV_DEFAULT, NULL); \ 117 } 118 119 #define CONFIG_LOCK_FINI(_clp) \ 120 { \ 121 mutex_destroy((_clp)->cl_mutex); \ 122 cv_destroy((_clp)->cl_cv); \ 123 } 124 125 #define CONFIG_LOCK_ENTER(_clp, _rw) \ 126 { \ 127 mutex_enter((_clp)->cl_mutex); \ 128 if ((_rw) == CL_WRITE) { \ 129 while ((_clp)->cl_reader || \ 130 ((_clp)->cl_owner != NULL && \ 131 (_clp)->cl_owner != curthread)) \ 132 cv_wait((_clp)->cl_cv, \ 133 (_clp)->cl_mutex); \ 134 (_clp)->cl_owner = curthread; \ 135 (_clp)->cl_writers++; \ 136 } \ 137 else if ((_rw) == CL_READ) { \ 138 while ((_clp)->cl_reader || \ 139 (_clp)->cl_writers > 0) { \ 140 ASSERT((_clp)->cl_owner != curthread); \ 141 cv_wait((_clp)->cl_cv, \ 142 (_clp)->cl_mutex); \ 143 } \ 144 (_clp)->cl_owner = curthread; \ 145 (_clp)->cl_reader = B_TRUE; \ 146 } \ 147 mutex_exit((_clp)->cl_mutex); \ 148 } 149 150 #define CONFIG_LOCK_EXIT(_clp) \ 151 { \ 152 mutex_enter((_clp)->cl_mutex); \ 153 if ((_clp)->cl_reader) { \ 154 (_clp)->cl_reader = B_FALSE; \ 155 (_clp)->cl_owner = NULL; \ 156 cv_broadcast((_clp)->cl_cv); \ 157 } else { \ 158 ASSERT((_clp)->cl_writers != 0); \ 159 (_clp)->cl_writers--; \ 160 if ((_clp)->cl_writers == 0) { \ 161 (_clp)->cl_owner = NULL; \ 162 cv_broadcast((_clp)->cl_cv); \ 163 } \ 164 } \ 165 mutex_exit((_clp)->cl_mutex); \ 166 } 167 168 #else /* __lint */ 169 170 #define CONFIG_LOCK_INIT(_clp) 171 #define CONFIG_LOCK_FINI(_clp) 172 #define CONFIG_LOCK_ENTER(_clp, _rw) 173 #define CONFIG_LOCK_EXIT(_clp) 174 175 #endif /* __lint */ 176 177 struct ipp_action { 178 ipp_action_id_t ippa_id; 179 ipp_mod_t *ippa_mod; 180 ipp_ref_t *ippa_ref; 181 ipp_ref_t *ippa_refby; 182 void *ippa_ptr; 183 uint32_t ippa_packets; 184 ipp_astate_t ippa_state; 185 krwlock_t ippa_lock[1]; 186 uint32_t ippa_hold_count; 187 boolean_t ippa_destruct_pending; 188 cfglock_t ippa_config_lock[1]; 189 boolean_t ippa_nameless; 190 char ippa_name[MAXNAMELEN]; 191 ipp_ref_t **ippa_condemned; 192 }; 193 194 struct ipp_class { 195 ipp_action_id_t ippc_aid; 196 char ippc_name[MAXNAMELEN]; 197 }; 198 199 struct ipp_log { 200 ipp_action_id_t ippl_aid; 201 timespec_t ippl_begin; 202 timespec_t ippl_end; 203 char ippl_name[MAXNAMELEN]; 204 }; 205 206 typedef struct ipp_stat_impl ipp_stat_impl_t; 207 208 struct ipp_stat_impl { 209 void *ippsi_data; 210 kstat_t *ippsi_ksp; 211 int ippsi_limit; 212 int ippsi_count; 213 int (*ippsi_update)(ipp_stat_t *, void *, int); 214 void *ippsi_arg; 215 kmutex_t ippsi_lock[1]; 216 char ippsi_name[MAXNAMELEN]; 217 }; 218 219 struct ipp_packet { 220 mblk_t *ippp_data; 221 ipp_class_t *ippp_class_array; 222 uint_t ippp_class_limit; 223 uint_t ippp_class_rindex; 224 uint_t ippp_class_windex; 225 ipp_log_t *ippp_log; 226 uint_t ippp_log_limit; 227 uint_t ippp_log_windex; 228 void *ippp_private; 229 void (*ippp_private_free)(void *); 230 }; 231 232 extern void ipp_init(void); 233 234 #endif /* _KERNEL */ 235 236 #ifdef __cplusplus 237 } 238 #endif 239 240 #endif /* _IPP_IPP_IMPL_H */ 241