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/ipc_action.c
+++ new/usr/src/cmd/cmd-inet/sbin/dhcpagent/ipc_action.c
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 2007 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 #pragma ident "%Z%%M% %I% %E% SMI"
27 28
28 29 #include <stdlib.h>
29 30 #include <sys/types.h>
30 31 #include <dhcpmsg.h>
31 32 #include <dhcpagent_ipc.h>
32 33
33 34 #include "agent.h"
34 35 #include "states.h"
35 36 #include "interface.h"
36 37 #include "ipc_action.h"
37 38 #include "util.h"
38 39
39 40 static iu_tq_callback_t ipc_action_timeout;
40 41
41 42 /*
42 43 * ipc_action_init(): initializes the ipc_action structure
43 44 *
44 45 * input: ipc_action_t *: the structure to initialize
45 46 * output: void
46 47 */
47 48
48 49 void
49 50 ipc_action_init(ipc_action_t *ia)
50 51 {
51 52 ia->ia_cmd = 0;
52 53 ia->ia_fd = -1;
53 54 ia->ia_tid = -1;
54 55 ia->ia_eid = -1;
55 56 ia->ia_request = NULL;
56 57 }
57 58
58 59 /*
59 60 * ipc_action_start(): starts an ipc_action request on a DHCP state machine
60 61 *
61 62 * input: dhcp_smach_t *: the state machine to start the action on
62 63 * ipc_action_t *: request structure
63 64 * output: B_TRUE if the request is started successfully, B_FALSE otherwise
64 65 * original request is still valid on failure, consumed otherwise.
65 66 */
66 67
67 68 boolean_t
68 69 ipc_action_start(dhcp_smach_t *dsmp, ipc_action_t *iareq)
69 70 {
70 71 struct ipc_action *ia = &dsmp->dsm_ia;
71 72
72 73 if (ia->ia_fd != -1 || ia->ia_tid != -1 || iareq->ia_fd == -1) {
73 74 dhcpmsg(MSG_CRIT, "ipc_action_start: attempted restart on %s",
74 75 dsmp->dsm_name);
75 76 return (B_FALSE);
76 77 }
77 78
78 79 if (!async_cancel(dsmp)) {
79 80 dhcpmsg(MSG_WARNING, "ipc_action_start: unable to cancel "
80 81 "action on %s", dsmp->dsm_name);
81 82 return (B_FALSE);
82 83 }
83 84
84 85 if (iareq->ia_request->timeout == DHCP_IPC_WAIT_DEFAULT)
85 86 iareq->ia_request->timeout = DHCP_IPC_DEFAULT_WAIT;
86 87
87 88 if (iareq->ia_request->timeout == DHCP_IPC_WAIT_FOREVER) {
88 89 iareq->ia_tid = -1;
89 90 } else {
90 91 iareq->ia_tid = iu_schedule_timer(tq,
91 92 iareq->ia_request->timeout, ipc_action_timeout, dsmp);
92 93
93 94 if (iareq->ia_tid == -1) {
94 95 dhcpmsg(MSG_ERROR, "ipc_action_start: failed to set "
95 96 "timer for %s on %s",
96 97 dhcp_ipc_type_to_string(iareq->ia_cmd),
97 98 dsmp->dsm_name);
98 99 return (B_FALSE);
|
↓ open down ↓ |
65 lines elided |
↑ open up ↑ |
99 100 }
100 101
101 102 hold_smach(dsmp);
102 103 }
103 104
104 105 *ia = *iareq;
105 106
106 107 /* We've taken ownership, so the input request is now invalid */
107 108 ipc_action_init(iareq);
108 109
109 - dhcpmsg(MSG_DEBUG, "ipc_action_start: started %s (command %d) on %s",
110 - dhcp_ipc_type_to_string(ia->ia_cmd), ia->ia_cmd, dsmp->dsm_name);
110 + dhcpmsg(MSG_DEBUG, "ipc_action_start: started %s (command %d) on %s,"
111 + " buffer length %u",
112 + dhcp_ipc_type_to_string(ia->ia_cmd), ia->ia_cmd, dsmp->dsm_name,
113 + ia->ia_request == NULL ? 0 : ia->ia_request->data_length);
111 114
112 115 dsmp->dsm_dflags |= DHCP_IF_BUSY;
113 116
114 117 /* This cannot fail due to the async_cancel above */
115 118 (void) async_start(dsmp, ia->ia_cmd, B_TRUE);
116 119
117 120 return (B_TRUE);
118 121 }
119 122
120 123 /*
121 124 * ipc_action_finish(): completes an ipc_action request on an interface
122 125 *
123 126 * input: dhcp_smach_t *: the state machine to complete the action on
124 127 * int: the reason why the action finished (nonzero on error)
125 128 * output: void
126 129 */
127 130
128 131 void
129 132 ipc_action_finish(dhcp_smach_t *dsmp, int reason)
130 133 {
131 134 struct ipc_action *ia = &dsmp->dsm_ia;
132 135
133 136 dsmp->dsm_dflags &= ~DHCP_IF_BUSY;
134 137
135 138 if (dsmp->dsm_ia.ia_fd == -1) {
136 139 dhcpmsg(MSG_ERROR,
137 140 "ipc_action_finish: attempted to finish unknown action "
138 141 "on %s", dsmp->dsm_name);
139 142 return;
140 143 }
141 144
142 145 dhcpmsg(MSG_DEBUG,
143 146 "ipc_action_finish: finished %s (command %d) on %s: %d",
144 147 dhcp_ipc_type_to_string(ia->ia_cmd), (int)ia->ia_cmd,
145 148 dsmp->dsm_name, reason);
146 149
147 150 /*
148 151 * if we can't cancel this timer, we're really in the
149 152 * twilight zone. however, as long as we don't drop the
150 153 * reference to the state machine, it shouldn't hurt us
151 154 */
152 155
153 156 if (dsmp->dsm_ia.ia_tid != -1 &&
154 157 iu_cancel_timer(tq, dsmp->dsm_ia.ia_tid, NULL) == 1) {
155 158 dsmp->dsm_ia.ia_tid = -1;
156 159 release_smach(dsmp);
157 160 }
158 161
159 162 if (reason == 0)
160 163 send_ok_reply(ia);
161 164 else
162 165 send_error_reply(ia, reason);
163 166
164 167 async_finish(dsmp);
165 168 }
166 169
167 170 /*
168 171 * ipc_action_timeout(): times out an ipc_action on a state machine (the
169 172 * request continues asynchronously, however)
170 173 *
171 174 * input: iu_tq_t *: unused
172 175 * void *: the dhcp_smach_t * the ipc_action was pending on
173 176 * output: void
174 177 */
175 178
176 179 /* ARGSUSED */
177 180 static void
178 181 ipc_action_timeout(iu_tq_t *tq, void *arg)
179 182 {
180 183 dhcp_smach_t *dsmp = arg;
181 184 struct ipc_action *ia = &dsmp->dsm_ia;
182 185
183 186 dsmp->dsm_dflags &= ~DHCP_IF_BUSY;
184 187
185 188 ia->ia_tid = -1;
186 189
187 190 dhcpmsg(MSG_VERBOSE, "ipc timeout waiting for agent to complete "
188 191 "%s (command %d) for %s", dhcp_ipc_type_to_string(ia->ia_cmd),
189 192 ia->ia_cmd, dsmp->dsm_name);
190 193
191 194 send_error_reply(ia, DHCP_IPC_E_TIMEOUT);
192 195
193 196 async_finish(dsmp);
194 197 release_smach(dsmp);
195 198 }
196 199
197 200 /*
198 201 * send_ok_reply(): sends an "ok" reply to a request and closes the ipc
199 202 * connection
200 203 *
201 204 * input: ipc_action_t *: the request to reply to
202 205 * output: void
203 206 * note: the request is freed (thus the request must be on the heap).
204 207 */
205 208
206 209 void
207 210 send_ok_reply(ipc_action_t *ia)
208 211 {
209 212 send_error_reply(ia, 0);
210 213 }
211 214
212 215 /*
213 216 * send_error_reply(): sends an "error" reply to a request and closes the ipc
214 217 * connection
215 218 *
216 219 * input: ipc_action_t *: the request to reply to
217 220 * int: the error to send back on the ipc connection
218 221 * output: void
219 222 * note: the request is freed (thus the request must be on the heap).
220 223 */
221 224
222 225 void
223 226 send_error_reply(ipc_action_t *ia, int error)
224 227 {
225 228 send_data_reply(ia, error, DHCP_TYPE_NONE, NULL, 0);
226 229 }
227 230
228 231 /*
229 232 * send_data_reply(): sends a reply to a request and closes the ipc connection
230 233 *
231 234 * input: ipc_action_t *: the request to reply to
232 235 * int: the status to send back on the ipc connection (zero for
233 236 * success, DHCP_IPC_E_* otherwise).
234 237 * dhcp_data_type_t: the type of the payload in the reply
235 238 * const void *: the payload for the reply, or NULL if there is no
236 239 * payload
237 240 * size_t: the size of the payload
238 241 * output: void
239 242 * note: the request is freed (thus the request must be on the heap).
240 243 */
241 244
242 245 void
243 246 send_data_reply(ipc_action_t *ia, int error, dhcp_data_type_t type,
244 247 const void *buffer, size_t size)
245 248 {
246 249 dhcp_ipc_reply_t *reply;
247 250 int retval;
248 251
249 252 if (ia->ia_fd == -1 || ia->ia_request == NULL)
250 253 return;
251 254
252 255 reply = dhcp_ipc_alloc_reply(ia->ia_request, error, buffer, size,
253 256 type);
254 257 if (reply == NULL) {
255 258 dhcpmsg(MSG_ERR, "send_data_reply: cannot allocate reply");
256 259
257 260 } else if ((retval = dhcp_ipc_send_reply(ia->ia_fd, reply)) != 0) {
258 261 dhcpmsg(MSG_ERROR, "send_data_reply: dhcp_ipc_send_reply: %s",
259 262 dhcp_ipc_strerror(retval));
260 263 }
261 264
262 265 /*
263 266 * free the request since we've now used it to send our reply.
264 267 * we can also close the socket since the reply has been sent.
265 268 */
266 269
267 270 free(reply);
268 271 free(ia->ia_request);
269 272 if (ia->ia_eid != -1)
270 273 (void) iu_unregister_event(eh, ia->ia_eid, NULL);
271 274 (void) dhcp_ipc_close(ia->ia_fd);
272 275 ia->ia_request = NULL;
273 276 ia->ia_fd = -1;
274 277 ia->ia_eid = -1;
275 278 }
|
↓ open down ↓ |
155 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX