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 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #ifndef _PER_DSTORE_H 28 #define _PER_DSTORE_H 29 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 #ifdef __cplusplus 33 extern "C" { 34 #endif 35 36 /* 37 * per_dnet.h -- DHCP-datastore database definitions. 38 */ 39 40 /* 41 * DHCP thread deferred work structure. One per deferred client thread. 42 * 43 * Track clients who cannot be immediately serviced due 44 * to a lack of available client threads. Locked by thr_mtx. 45 */ 46 typedef struct dsvc_pending { 47 uchar_t pnd_cid[DN_MAX_CID_LEN]; /* cid */ 48 uchar_t pnd_cid_len; /* cid length */ 49 struct dsvc_pending *pnd_next; /* next */ 50 } dsvc_pendclnt_t; 51 52 /* 53 * DHCP thread structure. One per client thread. 54 * 55 * Performance: create and track each client thread, using 56 * thr_suspend/thr_resume, rather than slower thread creation 57 * and deletion. Locked by thr_mtx. 58 */ 59 struct clnt; 60 typedef struct dsvc_free { 61 thread_t thr_tid; /* thread id */ 62 cond_t thr_cv; /* suspend/resume cv */ 63 mutex_t thr_mtx; /* suspend/resume mutex */ 64 uint_t thr_flags; /* suspend/resume flags */ 65 struct clnt *thr_pcd; /* per client data struct */ 66 struct dsvc_free *thr_next; /* next */ 67 } dsvc_thr_t; 68 69 /* 70 * DHCP thread structure flags 71 */ 72 #define DHCP_THR_LIST 0x1 /* Thread is on freelist */ 73 #define DHCP_THR_EXITING 0x2 /* Thread is exiting */ 74 75 /* 76 * DHCP datastore table. One per active network or dhcptab datastore. 77 * 78 * Timestamps are used to age the datastore structure, and any cached 79 * datastore free or lru records managed in select_offer(). 80 * The number of threads and clients can be controlled via MAX_THREADS 81 * and MAX_CLIENTS server parameters. 82 * 83 * Client and offer hashes provide fast lookup/reservation. 84 * Per-bucket rwlocks implemented in the hash routines reduce 85 * lock contention between clients. 86 * 87 * To minimize expensive datastore activity, threads synchronize to 88 * manage cached free and lru datastore records, which have the 89 * same lifetime as cached offers, which can be controlled via 90 * the OFFER_CACHE_TIMEOUT server parameter. 91 */ 92 typedef struct dnet { 93 hash_handle hand; /* hash insertion handle */ 94 time_t free_mtime; /* macro table purge time */ 95 time_t free_stamp; /* D_OFFER freerec purge time */ 96 time_t lru_mtime; /* macro table purge time */ 97 time_t lru_stamp; /* D_OFFER lrurec purge time */ 98 time_t clnt_stamp; /* D_OFFER client purge time */ 99 uint_t flags; /* dnet flags */ 100 struct in_addr net; /* network */ 101 struct in_addr subnet; /* subnet mask */ 102 int naddrs; /* # addrs owned by server */ 103 int nthreads; /* number of active threads */ 104 int nclients; /* number of active clients */ 105 hash_tbl *ctable; /* per client hash table */ 106 hash_tbl *itable; /* per ipaddr hash table */ 107 dsvc_thr_t *thrhead; /* free thread list */ 108 dsvc_thr_t *thrtail; /* free thread list tail */ 109 dsvc_pendclnt_t *workhead; /* head of thread work list */ 110 dsvc_pendclnt_t *worktail; /* tail of thread work list */ 111 dn_rec_list_t *freerec; /* free records head */ 112 dn_rec_list_t *lrurec; /* lru records head */ 113 dn_rec_list_t **lrupage; /* lru records sort area */ 114 size_t lrusize; 115 116 dsvc_handle_t dh; /* datastore handle */ 117 mutex_t pnd_mtx; /* open/close mutex */ 118 mutex_t free_mtx; /* lock for free records */ 119 mutex_t lru_mtx; /* lock for lru records */ 120 mutex_t lrupage_mtx; /* lock for lru page */ 121 mutex_t thr_mtx; /* lock for thread work list */ 122 cond_t thr_cv; /* cond var (nthreads == 0) */ 123 char network[INET_ADDRSTRLEN]; /* display buffer */ 124 } dsvc_dnet_t; 125 126 /* 127 * DHCP datastore table flags 128 */ 129 #define DHCP_PND_CLOSING 0x1 /* Dstore is closing */ 130 #define DHCP_PND_ERROR 0x2 /* Dstore experienced error */ 131 132 /* 133 * DHCP datastore table macros 134 */ 135 #define PND_FREE_TIMEOUT(pnd, now) ((pnd)->free_stamp < (now) || \ 136 (pnd)->free_mtime != reinit_time) 137 #define PND_LRU_TIMEOUT(pnd, now) ((pnd)->lru_stamp < (now) || \ 138 (pnd)->lru_mtime != reinit_time) 139 140 struct interfaces; 141 142 /* 143 * DHCP client. One per active client, per network. 144 * 145 * Timestamps are used to age the client structure, and any cached 146 * offer, which can be controlled via the OFFER_CACHE_TIMEOUT server 147 * parameter, and the -t option, and SIGHUP signal. 148 * 149 * The original datastore record is cached, along with offer information, 150 * for use if the datastore record is modified. 151 * 152 * The clnt struct may appear on the client hash table, and offer hash table, 153 * depending on the validity of the current offer. A different dsvc_clnt_t 154 * is used for each link, to allow independent aging of client and offer. 155 */ 156 typedef struct clnt { 157 hash_handle chand; /* hash insertion handle: client hash */ 158 hash_handle ihand; /* hash insertion handle: inet hash */ 159 time_t mtime; /* macro table offer purge time */ 160 uint_t flags; /* Client flags */ 161 uint_t state; /* Client DHCP state */ 162 struct in_addr off_ip; /* Offered address */ 163 struct interfaces *ifp; /* the ifp the packet arrived on */ 164 dsvc_dnet_t *pnd; /* the per network datastore */ 165 PKT_LIST *pkthead; /* head of client packet list */ 166 PKT_LIST *pkttail; /* tail of client packet list */ 167 uint_t pending; /* # of pkts on client packet list */ 168 lease_t lease; /* Offered lease time */ 169 dsvc_thr_t *clnt_thread; /* client thread */ 170 171 dn_rec_list_t *dnlp; /* Original datastore record */ 172 mutex_t pcd_mtx; /* overall struct lock */ 173 mutex_t pkt_mtx; /* lock for PKT_LIST */ 174 cond_t pcd_cv; /* cond var (clnt_thread == 0) */ 175 char cidbuf[DHCP_MAX_OPT_SIZE]; /* display buffer */ 176 uchar_t cid[DN_MAX_CID_LEN]; /* Offered cid */ 177 uchar_t cid_len; /* Offered cid length */ 178 } dsvc_clnt_t; 179 180 /* 181 * Per Client flags and indices 182 */ 183 #define DHCP_HDR_CLIENT 0x0 /* clnt dsvc_clnt_t */ 184 #define DHCP_HDR_OFFER 0x1 /* offer dsvc_clnt_t */ 185 186 #define DHCP_PCD_OFFER 0x1 /* Offered ip addr is valid */ 187 #define DHCP_PCD_WORK 0x2 /* Client is on deferred work list */ 188 #define DHCP_PCD_CLOSING 0x4 /* Client thread should exit */ 189 190 /* 191 * Per Client macros 192 */ 193 #define PCD_OFFER_TIMEOUT(pcd, now) (hash_Htime(pcd->ihand) < (now) || \ 194 (pcd)->mtime != reinit_time) 195 196 /* 197 * Datastore hash table dynamic data free timeout values 198 */ 199 #define DHCP_CLIENT_THRESHOLD 90 /* Time to free inactive clients */ 200 #define DHCP_NET_THRESHOLD 900 /* Time to free inactive nets */ 201 202 /* 203 * Datastore database access routines. 204 */ 205 extern int open_dnet(dsvc_dnet_t **, struct in_addr *, struct in_addr *); 206 extern void close_dnet(dsvc_dnet_t *, boolean_t); 207 208 /* 209 * Per Client hash and utility routines. 210 */ 211 extern int open_clnt(dsvc_dnet_t *, dsvc_clnt_t **, uchar_t *, uchar_t, 212 boolean_t); 213 extern void close_clnt(dsvc_clnt_t *, boolean_t); 214 extern int clnt_netcmp(dsvc_clnt_t *, dsvc_clnt_t *); 215 extern void close_clnts(void); 216 extern void purge_offer(dsvc_clnt_t *, boolean_t, boolean_t); 217 218 #ifdef __cplusplus 219 } 220 #endif 221 222 #endif /* _PER_DSTORE_H */