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