Print this page
7388 Support DHCP Client FQDN. Allow IAID/DUID for all v4.
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/cmd/cmd-inet/sbin/dhcpagent/states.h
+++ new/usr/src/cmd/cmd-inet/sbin/dhcpagent/states.h
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
|
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 + * Copyright (c) 2016, Chris Fraire <cfraire@me.com>.
24 25 */
25 26
26 27 #ifndef STATES_H
27 28 #define STATES_H
28 29
29 30 #include <sys/types.h>
30 31 #include <netinet/in.h>
31 32 #include <netinet/dhcp.h>
32 33 #include <libinetutil.h>
33 34
34 35 #include "common.h"
35 36 #include "ipc_action.h"
36 37 #include "async.h"
37 38 #include "packet.h"
38 39 #include "util.h"
39 40
40 41 /*
41 42 * interfaces for state transition/action functions. these functions
42 43 * can be found in suitably named .c files, such as inform.c, select.c,
43 44 * renew.c, etc.
44 45 */
45 46
46 47 #ifdef __cplusplus
47 48 extern "C" {
48 49 #endif
49 50
50 51 /*
51 52 * DHCP state machine representation: includes all of the information used for
52 53 * a state machine instance. For IPv4, this represents a single logical
53 54 * interface and (usually) a leased address. For IPv6, it represents a
54 55 * DUID+IAID combination. Note that if multiple DUID+IAID instances are one
55 56 * day allowed per interface, this will need to become a list.
56 57 */
57 58 struct dhcp_smach_s {
58 59 dhcp_smach_t *dsm_next; /* Note: must be first */
59 60 dhcp_smach_t *dsm_prev;
60 61
61 62 /*
62 63 * The name of the state machine. This is currently just a pointer to
63 64 * the controlling LIF's name, but could be otherwise.
64 65 */
65 66 const char *dsm_name;
66 67 dhcp_lif_t *dsm_lif; /* Controlling LIF */
67 68 uint_t dsm_hold_count; /* reference count */
68 69
69 70 dhcp_lease_t *dsm_leases; /* List of leases */
70 71 uint_t dsm_lif_wait; /* LIFs waiting on DAD */
71 72 uint_t dsm_lif_down; /* LIFs failed */
72 73
73 74 /*
74 75 * each state machine can have at most one pending asynchronous
75 76 * action, which is represented in a `struct async_action'.
76 77 * if that asynchronous action was a result of a user request,
77 78 * then the `struct ipc_action' is used to hold information
78 79 * about the user request. these structures are opaque to
79 80 * users of the ifslist, and the functional interfaces
80 81 * provided in async.[ch] and ipc_action.[ch] should be used
81 82 * to maintain them.
82 83 */
83 84
84 85 ipc_action_t dsm_ia;
85 86 async_action_t dsm_async;
86 87
87 88 uchar_t *dsm_cid; /* client id */
88 89 uchar_t dsm_cidlen; /* client id len */
89 90
90 91 /*
91 92 * current state of the machine
92 93 */
93 94
94 95 DHCPSTATE dsm_state;
95 96 boolean_t dsm_droprelease; /* soon to call finished_smach */
96 97
97 98 uint16_t dsm_dflags; /* DHCP_IF_* (shared with IPC) */
98 99
99 100 uint16_t *dsm_prl; /* if non-NULL, param request list */
100 101 uint_t dsm_prllen; /* param request list len */
101 102 uint16_t *dsm_pil; /* if non-NULL, param ignore list */
102 103 uint_t dsm_pillen; /* param ignore list len */
103 104
104 105 uint_t dsm_nrouters; /* the number of default routers */
105 106 struct in_addr *dsm_routers; /* an array of default routers */
106 107
107 108 in6_addr_t dsm_server; /* our DHCP server */
108 109 uchar_t *dsm_serverid; /* server DUID for v6 */
109 110 uint_t dsm_serveridlen; /* DUID length */
110 111
111 112 /*
112 113 * We retain the very first ack obtained on the state machine to
113 114 * provide access to options which were originally assigned by
114 115 * the server but may not have been included in subsequent
115 116 * acks, as there are servers which do this and customers have
116 117 * had unsatisfactory results when using our agent with them.
117 118 * ipc_event() in agent.c provides a fallback to the original
118 119 * ack when the current ack doesn't have the information
119 120 * requested.
120 121 *
121 122 * Note that neither of these is actually a list of packets. There's
122 123 * exactly one packet here, so use free_pkt_entry.
123 124 */
124 125 PKT_LIST *dsm_ack;
125 126 PKT_LIST *dsm_orig_ack;
126 127
127 128 /*
128 129 * other miscellaneous variables set or needed in the process
129 130 * of acquiring a lease.
130 131 */
131 132
132 133 int dsm_offer_wait; /* seconds between sending offers */
133 134 iu_timer_id_t dsm_offer_timer; /* timer associated with offer wait */
134 135
135 136 /*
136 137 * time we sent the DISCOVER relative to dsm_neg_hrtime, so that the
137 138 * REQUEST can have the same pkt->secs.
138 139 */
139 140
140 141 uint16_t dsm_disc_secs;
141 142
142 143 /*
143 144 * this is a chain of packets which have been received on this
144 145 * state machine over some interval of time. the packets may have
145 146 * to meet some criteria in order to be put on this list. in
146 147 * general, packets are put on this list through recv_pkt()
147 148 */
148 149
149 150 PKT_LIST *dsm_recv_pkt_list;
150 151
151 152 /*
152 153 * these three fields are initially zero, and get incremented
153 154 * as the ifslist goes from INIT -> BOUND. if and when the
154 155 * ifslist moves to the RENEWING state, these fields are
155 156 * reset, so they always either indicate the number of packets
156 157 * sent, received, and declined while obtaining the current
157 158 * lease (if BOUND), or the number of packets sent, received,
158 159 * and declined while attempting to obtain a future lease
159 160 * (if any other state).
160 161 */
161 162
162 163 uint32_t dsm_sent;
163 164 uint32_t dsm_received;
164 165 uint32_t dsm_bad_offers;
165 166
166 167 /*
167 168 * dsm_send_pkt.pkt is dynamically allocated to be as big a
168 169 * packet as we can send out on this state machine. the remainder
169 170 * of this information is needed to make it easy to handle
170 171 * retransmissions. note that other than dsm_bad_offers, all
171 172 * of these fields are maintained internally in send_pkt(),
172 173 * and consequently should never need to be modified by any
173 174 * other functions.
174 175 */
175 176
176 177 dhcp_pkt_t dsm_send_pkt;
177 178 union {
178 179 struct sockaddr_in v4;
179 180 struct sockaddr_in6 v6;
180 181 } dsm_send_dest;
181 182
182 183 /*
183 184 * For v4, dsm_send_tcenter is used to track the central timer value in
184 185 * milliseconds (4000, 8000, 16000, 32000, 64000), and dsm_send_timeout
185 186 * is that value plus the +/- 1000 millisecond fuzz.
186 187 *
187 188 * For v6, dsm_send_tcenter is the MRT (maximum retransmit timer)
188 189 * value, and dsm_send_timeout must be set to the IRT (initial
189 190 * retransmit timer) value by the sender.
190 191 */
191 192 uint_t dsm_send_timeout;
192 193 uint_t dsm_send_tcenter;
193 194 stop_func_t *dsm_send_stop_func;
|
↓ open down ↓ |
160 lines elided |
↑ open up ↑ |
194 195 uint32_t dsm_packet_sent;
195 196 iu_timer_id_t dsm_retrans_timer;
196 197
197 198 /*
198 199 * The host name we've been asked to request is remembered
199 200 * here between the DISCOVER and the REQUEST. (v4 only)
200 201 */
201 202 char *dsm_reqhost;
202 203
203 204 /*
205 + * The host name we've been asked by IPC message (e.g.,
206 + * `ipadm -T dhcp -h ...') to request is remembered here until it is
207 + * reset by another external message.
208 + */
209 + char *dsm_msg_reqhost;
210 +
211 + /*
212 + * The determined FQDN is remembered here between the DISCOVER/SOLICIT
213 + * and the REQUEST.
214 + */
215 + char *dsm_reqfqdn;
216 +
217 + /*
204 218 * V4 and V6 use slightly different timers. For v4, we must count
205 219 * seconds from the point where we first try to configure the
206 220 * interface. For v6, only seconds while performing a transaction
207 221 * matter.
208 222 *
209 223 * In v4, `dsm_neg_hrtime' represents the time since DHCP started
210 224 * configuring the interface, and is used for computing the pkt->secs
211 225 * field in v4. In v6, it represents the time since the current
212 226 * transaction (if any) was started, and is used for the ELAPSED_TIME
213 227 * option.
214 228 *
215 229 * `dsm_newstart_monosec' represents the time the ACKed REQUEST was
216 230 * sent, which represents the start time of a new batch of leases.
217 231 * When the lease time actually begins (and thus becomes current),
218 232 * `dsm_curstart_monosec' is set to `dsm_newstart_monosec'.
219 233 */
220 234 hrtime_t dsm_neg_hrtime;
221 235 monosec_t dsm_newstart_monosec;
222 236 monosec_t dsm_curstart_monosec;
223 237
224 238 int dsm_script_fd;
225 239 pid_t dsm_script_pid;
226 240 pid_t dsm_script_helper_pid;
227 241 const char *dsm_script_event;
228 242 iu_event_id_t dsm_script_event_id;
229 243 void *dsm_callback_arg;
230 244 script_callback_t *dsm_script_callback;
231 245
232 246 iu_timer_id_t dsm_start_timer;
233 247 };
234 248
235 249 #define dsm_isv6 dsm_lif->lif_pif->pif_isv6
236 250 #define dsm_hwtype dsm_lif->lif_pif->pif_hwtype
237 251
238 252 struct dhcp_lease_s {
239 253 dhcp_lease_t *dl_next; /* Note: must be first */
240 254 dhcp_lease_t *dl_prev;
241 255
242 256 dhcp_smach_t *dl_smach; /* back pointer to state machine */
243 257 dhcp_lif_t *dl_lifs; /* LIFs configured by this lease */
244 258 uint_t dl_nlifs; /* Number of configured LIFs */
245 259 uint_t dl_hold_count; /* reference counter */
246 260 boolean_t dl_removed; /* Set if removed from list */
247 261 boolean_t dl_stale; /* not updated by Renew/bind */
248 262
249 263 /*
250 264 * the following fields are set when a lease is acquired, and
251 265 * may be updated over the lifetime of the lease. they are
252 266 * all reset by reset_smach().
253 267 */
254 268
255 269 dhcp_timer_t dl_t1; /* relative renewal start time, hbo */
256 270 dhcp_timer_t dl_t2; /* relative rebinding start time, hbo */
257 271 };
258 272
259 273 /* The IU event callback functions */
260 274 iu_eh_callback_t dhcp_acknak_global;
261 275 iu_eh_callback_t dhcp_packet_lif;
262 276
263 277 /* Common state-machine related routines throughout dhcpagent */
264 278 boolean_t dhcp_adopt(void);
265 279 void dhcp_adopt_complete(dhcp_smach_t *);
266 280 boolean_t dhcp_bound(dhcp_smach_t *, PKT_LIST *);
267 281 void dhcp_bound_complete(dhcp_smach_t *);
268 282 int dhcp_drop(dhcp_smach_t *, void *);
269 283 void dhcp_deprecate(iu_tq_t *, void *);
270 284 void dhcp_expire(iu_tq_t *, void *);
271 285 boolean_t dhcp_extending(dhcp_smach_t *);
272 286 void dhcp_inform(dhcp_smach_t *);
273 287 void dhcp_init_reboot(dhcp_smach_t *);
274 288 void dhcp_rebind(iu_tq_t *, void *);
275 289 int dhcp_release(dhcp_smach_t *, void *);
276 290 void dhcp_renew(iu_tq_t *, void *);
277 291 void dhcp_requesting(iu_tq_t *, void *);
278 292 void dhcp_restart(dhcp_smach_t *);
279 293 void dhcp_selecting(dhcp_smach_t *);
280 294 boolean_t set_start_timer(dhcp_smach_t *);
281 295 void send_declines(dhcp_smach_t *);
282 296 void send_v6_request(dhcp_smach_t *);
283 297 boolean_t save_server_id(dhcp_smach_t *, PKT_LIST *);
284 298 void server_unicast_option(dhcp_smach_t *, PKT_LIST *);
285 299
286 300 /* State machine support functions in states.c */
287 301 dhcp_smach_t *insert_smach(dhcp_lif_t *, int *);
288 302 void hold_smach(dhcp_smach_t *);
289 303 void release_smach(dhcp_smach_t *);
290 304 void remove_smach(dhcp_smach_t *);
291 305 dhcp_smach_t *next_smach(dhcp_smach_t *, boolean_t);
292 306 dhcp_smach_t *primary_smach(boolean_t);
293 307 dhcp_smach_t *info_primary_smach(boolean_t);
294 308 void make_primary(dhcp_smach_t *);
295 309 dhcp_smach_t *lookup_smach(const char *, boolean_t);
296 310 dhcp_smach_t *lookup_smach_by_uindex(uint16_t, dhcp_smach_t *, boolean_t);
297 311 dhcp_smach_t *lookup_smach_by_xid(uint32_t, dhcp_smach_t *, boolean_t);
298 312 dhcp_smach_t *lookup_smach_by_event(iu_event_id_t);
299 313 void finished_smach(dhcp_smach_t *, int);
300 314 boolean_t set_smach_state(dhcp_smach_t *, DHCPSTATE);
301 315 int get_smach_cid(dhcp_smach_t *);
302 316 boolean_t verify_smach(dhcp_smach_t *);
303 317 uint_t smach_count(void);
304 318 void reset_smach(dhcp_smach_t *);
305 319 void refresh_smachs(iu_eh_t *, int, void *);
306 320 void refresh_smach(dhcp_smach_t *);
307 321 void nuke_smach_list(void);
308 322 boolean_t schedule_smach_timer(dhcp_smach_t *, int, uint32_t,
309 323 iu_tq_callback_t *);
310 324 void cancel_offer_timer(dhcp_smach_t *);
311 325 void cancel_smach_timers(dhcp_smach_t *);
312 326 void discard_default_routes(dhcp_smach_t *);
313 327 void remove_default_routes(dhcp_smach_t *);
314 328 boolean_t is_bound_state(DHCPSTATE);
315 329
316 330 /* Lease-related support functions in states.c */
317 331 dhcp_lease_t *insert_lease(dhcp_smach_t *);
318 332 void hold_lease(dhcp_lease_t *);
319 333 void release_lease(dhcp_lease_t *);
320 334 void remove_lease(dhcp_lease_t *);
321 335 void deprecate_leases(dhcp_smach_t *);
322 336 void cancel_lease_timers(dhcp_lease_t *);
323 337 boolean_t schedule_lease_timer(dhcp_lease_t *, dhcp_timer_t *,
324 338 iu_tq_callback_t *);
325 339
326 340 #ifdef __cplusplus
327 341 }
328 342 #endif
329 343
330 344 #endif /* STATES_H */
|
↓ open down ↓ |
117 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX