Print this page
7388 Support DHCP Client FQDN. Allow IAID/DUID for all v4.
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/lib/libnwam/common/libnwam_ncp.c
+++ new/usr/src/lib/libnwam/common/libnwam_ncp.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
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
↓ open down ↓ |
14 lines elided |
↑ open up ↑ |
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 /*
23 23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 + * Copyright (c) 2016, Chris Fraire <cfraire@me.com>.
25 26 */
26 27
27 28 #include <assert.h>
28 29 #include <ctype.h>
29 30 #include <libgen.h>
30 31 #include <netdb.h>
31 32 #include <sys/param.h>
32 33 #include <sys/types.h>
33 34 #include <sys/stat.h>
34 35 #include <sys/socket.h>
35 36 #include <netinet/in.h>
36 37 #include <arpa/inet.h>
37 38 #include <stdio.h>
38 39 #include <stdlib.h>
39 40 #include <strings.h>
40 41 #include <unistd.h>
41 42 #include <libdladm.h>
43 +#include <libipadm.h>
42 44
43 45 #include "libnwam_impl.h"
44 46 #include <libnwam_priv.h>
45 47 #include <libnwam.h>
46 48
47 49 /*
48 50 * Functions to support creating, modifying, destroying, querying the
49 51 * state of and changing the state of NCP (Network Configuration Profiles)
50 52 * and the NCUs (Network Configuration Units) that are contained in those
51 53 * NCP objects. An NCP is simply a container for a set of NCUs which represent
52 54 * the datalink and interface configuration preferences for the system.
53 55 * An NCP can consist a set of prioritized link NCUs, e.g. wired links preferred
54 56 * over wireless, a set of manually enabled/diasbled NCUs, or a combination
55 57 * of both. Interface NCUs inherit activation from their underlying links,
56 58 * so if wired is preferred over wireless and a cable is plugged in,
57 59 * the wired link NCU will be active, as will the IP interface NCU above it.
58 60 */
59 61
60 62 /*
61 63 * The NCU property table is used to mapping property types to property name
62 64 * strings, their associated value types etc. The table is used for validation
63 65 * purposes, and for commit()ing and read()ing NCUs.
64 66 */
65 67
|
↓ open down ↓ |
14 lines elided |
↑ open up ↑ |
66 68 static nwam_error_t valid_type(nwam_value_t);
67 69 static nwam_error_t valid_class(nwam_value_t);
68 70 static nwam_error_t valid_ncp(nwam_value_t);
69 71 static nwam_error_t valid_priority_mode(nwam_value_t);
70 72 static nwam_error_t valid_ncu_activation_mode(nwam_value_t);
71 73 static nwam_error_t valid_link_autopush(nwam_value_t);
72 74 static nwam_error_t valid_link_mtu(nwam_value_t);
73 75 static nwam_error_t valid_ip_version(nwam_value_t);
74 76 static nwam_error_t valid_addrsrc_v4(nwam_value_t);
75 77 static nwam_error_t valid_addrsrc_v6(nwam_value_t);
78 +static nwam_error_t valid_reqhost(nwam_value_t);
76 79
77 80 struct nwam_prop_table_entry ncu_prop_table_entries[] = {
78 81 {NWAM_NCU_PROP_TYPE, NWAM_VALUE_TYPE_UINT64, B_FALSE, 1, 1, valid_type,
79 82 "specifies the NCU type - valid values are \'datalink\' and \'ip\'",
80 83 NWAM_FLAG_NCU_TYPE_ALL, NWAM_FLAG_NCU_CLASS_ALL},
81 84 {NWAM_NCU_PROP_CLASS, NWAM_VALUE_TYPE_UINT64, B_FALSE, 1, 1,
82 85 valid_class,
83 86 "specifies the NCU class - valid values are "
84 87 "\'phys\' and \'ip\'",
85 88 NWAM_FLAG_NCU_TYPE_ALL, NWAM_FLAG_NCU_CLASS_ALL},
86 89 {NWAM_NCU_PROP_PARENT_NCP, NWAM_VALUE_TYPE_STRING, B_FALSE, 1, 1,
87 90 valid_ncp,
88 91 "specifies the parent NCP name",
89 92 NWAM_FLAG_NCU_TYPE_ALL, NWAM_FLAG_NCU_CLASS_ALL},
90 93 {NWAM_NCU_PROP_ACTIVATION_MODE, NWAM_VALUE_TYPE_UINT64, B_FALSE, 1, 1,
91 94 valid_ncu_activation_mode,
92 95 "specifies the NCU activation mode - valid values are:\n"
93 96 "\'prioritized\' and \'manual\'",
94 97 NWAM_FLAG_NCU_TYPE_LINK, NWAM_FLAG_NCU_CLASS_ALL_LINK},
95 98 {NWAM_NCU_PROP_ENABLED, NWAM_VALUE_TYPE_BOOLEAN, B_TRUE, 0, 1,
96 99 nwam_valid_boolean,
97 100 "specifies if manual NCU is to be enabled",
98 101 NWAM_FLAG_NCU_TYPE_ALL, NWAM_FLAG_NCU_CLASS_ALL},
99 102 {NWAM_NCU_PROP_PRIORITY_GROUP, NWAM_VALUE_TYPE_UINT64, B_FALSE, 0, 1,
100 103 nwam_valid_uint64,
101 104 "specifies the priority grouping of NCUs - lower values are "
102 105 "prioritized, negative values are invalid",
103 106 NWAM_FLAG_NCU_TYPE_LINK, NWAM_FLAG_NCU_CLASS_ALL_LINK},
104 107 {NWAM_NCU_PROP_PRIORITY_MODE, NWAM_VALUE_TYPE_UINT64, B_FALSE, 0, 1,
105 108 valid_priority_mode,
106 109 "specifies the mode of prioritization - valid values are:\n"
107 110 "\'exclusive\', \'shared\' and \'all\'",
108 111 NWAM_FLAG_NCU_TYPE_LINK, NWAM_FLAG_NCU_CLASS_ALL_LINK},
109 112 {NWAM_NCU_PROP_LINK_MAC_ADDR, NWAM_VALUE_TYPE_STRING, B_FALSE, 0, 1,
110 113 nwam_valid_mac_addr,
111 114 "specifies MAC address of form aa:bb:cc:dd:ee:ff for the link",
112 115 NWAM_FLAG_NCU_TYPE_LINK, NWAM_FLAG_NCU_CLASS_ALL_LINK},
113 116 {NWAM_NCU_PROP_LINK_AUTOPUSH, NWAM_VALUE_TYPE_STRING, B_FALSE, 0,
114 117 NWAM_MAX_NUM_VALUES, valid_link_autopush,
115 118 "specifies modules to autopush on link",
116 119 NWAM_FLAG_NCU_TYPE_LINK, NWAM_FLAG_NCU_CLASS_ALL_LINK},
117 120 {NWAM_NCU_PROP_LINK_MTU, NWAM_VALUE_TYPE_UINT64, B_FALSE, 0, 1,
118 121 valid_link_mtu,
119 122 "specifies MTU for link",
120 123 NWAM_FLAG_NCU_TYPE_LINK, NWAM_FLAG_NCU_CLASS_ALL_LINK},
121 124 {NWAM_NCU_PROP_IP_VERSION, NWAM_VALUE_TYPE_UINT64, B_FALSE, 0,
122 125 NWAM_MAX_NUM_VALUES, valid_ip_version,
123 126 "specifies IP versions for IP NCU - valid values are:\n"
124 127 "\'ipv4\' and \'ipv6\'",
125 128 NWAM_FLAG_NCU_TYPE_INTERFACE, NWAM_FLAG_NCU_CLASS_ALL_INTERFACE},
126 129 {NWAM_NCU_PROP_IPV4_ADDRSRC, NWAM_VALUE_TYPE_UINT64, B_FALSE, 0,
127 130 NWAM_MAX_NUM_VALUES, valid_addrsrc_v4,
128 131 "specifies IPv4 address source(s) - valid values are:\n"
129 132 "\'dhcp\' and \'static\'",
130 133 NWAM_FLAG_NCU_TYPE_INTERFACE, NWAM_FLAG_NCU_CLASS_ALL_INTERFACE},
131 134 {NWAM_NCU_PROP_IPV4_ADDR, NWAM_VALUE_TYPE_STRING, B_FALSE, 0,
132 135 NWAM_MAX_NUM_VALUES, nwam_valid_host_v4,
133 136 "specifies static IPv4 host address(es)",
134 137 NWAM_FLAG_NCU_TYPE_INTERFACE, NWAM_FLAG_NCU_CLASS_ALL_INTERFACE},
135 138 {NWAM_NCU_PROP_IPV4_DEFAULT_ROUTE, NWAM_VALUE_TYPE_STRING, B_FALSE, 0,
136 139 1, nwam_valid_route_v4,
137 140 "specifies per-interface default IPv4 route",
138 141 NWAM_FLAG_NCU_TYPE_INTERFACE, NWAM_FLAG_NCU_CLASS_ALL_INTERFACE},
139 142 {NWAM_NCU_PROP_IPV6_ADDRSRC, NWAM_VALUE_TYPE_UINT64, B_FALSE, 0,
140 143 NWAM_MAX_NUM_VALUES, valid_addrsrc_v6,
141 144 "specifies IPv6 address source(s) - valid values are:\n"
|
↓ open down ↓ |
56 lines elided |
↑ open up ↑ |
142 145 "\'dhcp\', \'autoconf\' and \'static\'.\n"
143 146 "\'dhcp\' and \'autoconf\' are mandatory values.",
144 147 NWAM_FLAG_NCU_TYPE_INTERFACE, NWAM_FLAG_NCU_CLASS_ALL_INTERFACE},
145 148 {NWAM_NCU_PROP_IPV6_ADDR, NWAM_VALUE_TYPE_STRING, B_FALSE, 0,
146 149 NWAM_MAX_NUM_VALUES, nwam_valid_host_v6,
147 150 "specifies static IPv6 host address(es)",
148 151 NWAM_FLAG_NCU_TYPE_INTERFACE, NWAM_FLAG_NCU_CLASS_ALL_INTERFACE},
149 152 {NWAM_NCU_PROP_IPV6_DEFAULT_ROUTE, NWAM_VALUE_TYPE_STRING, B_FALSE, 0,
150 153 1, nwam_valid_route_v6,
151 154 "specifies per-interface default IPv6 route",
152 - NWAM_FLAG_NCU_TYPE_INTERFACE, NWAM_FLAG_NCU_CLASS_ALL_INTERFACE}
155 + NWAM_FLAG_NCU_TYPE_INTERFACE, NWAM_FLAG_NCU_CLASS_ALL_INTERFACE},
156 + {NWAM_NCU_PROP_IP_PRIMARY, NWAM_VALUE_TYPE_BOOLEAN, B_FALSE, 0,
157 + 1, nwam_valid_boolean,
158 + "specifies the status of an interface as primary for the delivery"
159 + " of client-wide configuration data",
160 + NWAM_FLAG_NCU_TYPE_INTERFACE, NWAM_FLAG_NCU_CLASS_ALL_INTERFACE},
161 + {NWAM_NCU_PROP_IP_REQHOST, NWAM_VALUE_TYPE_STRING, B_FALSE, 0,
162 + 1, valid_reqhost,
163 + "specifies a requested hostname for the interface",
164 + NWAM_FLAG_NCU_TYPE_INTERFACE, NWAM_FLAG_NCU_CLASS_ALL_INTERFACE},
153 165 };
154 166
155 167 #define NWAM_NUM_NCU_PROPS (sizeof (ncu_prop_table_entries) / \
156 168 sizeof (*ncu_prop_table_entries))
157 169
158 170 struct nwam_prop_table ncu_prop_table =
159 171 { NWAM_NUM_NCU_PROPS, ncu_prop_table_entries };
160 172
161 173 nwam_error_t
162 174 nwam_ncp_get_name(nwam_ncp_handle_t ncph, char **namep)
163 175 {
164 176 return (nwam_get_name(ncph, namep));
165 177 }
166 178
167 179 static nwam_error_t
168 180 nwam_ncp_name_to_file(const char *name, char **filename)
169 181 {
170 182 assert(name != NULL && filename != NULL);
171 183
172 184 if ((*filename = malloc(MAXPATHLEN)) == NULL)
173 185 return (NWAM_NO_MEMORY);
174 186
175 187 (void) snprintf(*filename, MAXPATHLEN, "%s%s%s%s", NWAM_CONF_DIR,
176 188 NWAM_NCP_CONF_FILE_PRE, name, NWAM_NCP_CONF_FILE_SUF);
177 189
178 190 return (NWAM_SUCCESS);
179 191 }
180 192
181 193 /* ARGSUSED1 */
182 194 nwam_error_t
183 195 nwam_ncp_create(const char *name, uint64_t flags, nwam_ncp_handle_t *ncphp)
184 196 {
185 197 nwam_error_t err;
186 198 char *ncpfile;
187 199
188 200 if ((err = nwam_handle_create(NWAM_OBJECT_TYPE_NCP, name, ncphp))
189 201 != NWAM_SUCCESS)
190 202 return (err);
191 203
192 204 /* Create empty container for NCUs */
193 205 if ((err = nwam_ncp_name_to_file(name, &ncpfile))
194 206 != NWAM_SUCCESS) {
195 207 nwam_free(*ncphp);
196 208 *ncphp = NULL;
197 209 return (err);
198 210 }
199 211
200 212 if ((err = nwam_commit(ncpfile, *ncphp, flags)) != NWAM_SUCCESS) {
201 213 nwam_free(*ncphp);
202 214 *ncphp = NULL;
203 215 }
204 216
205 217 free(ncpfile);
206 218
207 219 return (err);
208 220 }
209 221
210 222 /* Used by libnwam_files.c */
211 223 nwam_error_t
212 224 nwam_ncp_file_to_name(const char *path, char **name)
213 225 {
214 226 char path_copy[MAXPATHLEN];
215 227 char *filename, *suffix;
216 228
217 229 assert(path != NULL && name != NULL);
218 230
219 231 /* Make a copy as basename(3c) may modify string */
220 232 (void) strlcpy(path_copy, path, MAXPATHLEN);
221 233
222 234 if ((*name = malloc(NWAM_MAX_NAME_LEN)) == NULL)
223 235 return (NWAM_NO_MEMORY);
224 236
225 237 if ((filename = basename(path_copy)) == NULL) {
226 238 free(*name);
227 239 return (NWAM_ENTITY_INVALID);
228 240 }
229 241
230 242 /* Ensure filename begins/ends with right prefix/suffix */
231 243 if (sscanf(filename, NWAM_NCP_CONF_FILE_PRE "%256[^\n]s", *name) < 1) {
232 244 free(*name);
233 245 return (NWAM_ENTITY_INVALID);
234 246 }
235 247 suffix = *name + strlen(*name) - strlen(NWAM_NCP_CONF_FILE_SUF);
236 248 if (strstr(*name, NWAM_NCP_CONF_FILE_SUF) != suffix) {
237 249 free(*name);
238 250 return (NWAM_ENTITY_INVALID);
239 251 }
240 252 suffix[0] = '\0';
241 253
242 254 return (NWAM_SUCCESS);
243 255 }
244 256
245 257 /* ARGSUSED1 */
246 258 nwam_error_t
247 259 nwam_ncp_read(const char *name, uint64_t flags, nwam_ncp_handle_t *ncphp)
248 260 {
249 261 char *filename;
250 262 nwam_error_t err;
251 263
252 264 assert(name != NULL && ncphp != NULL);
253 265
254 266 /* try to read the associated ncp configuration */
255 267 if ((err = nwam_ncp_name_to_file(name, &filename)) != NWAM_SUCCESS) {
256 268 *ncphp = NULL;
257 269 return (err);
258 270 }
259 271
260 272 err = nwam_read(NWAM_OBJECT_TYPE_NCP, filename, name, flags, ncphp);
261 273 free(filename);
262 274 return (err);
263 275 }
264 276
265 277 static nwam_error_t
266 278 nwam_ncu_get_parent_ncp_name(nwam_ncu_handle_t ncuh, char **parentnamep)
267 279 {
268 280 nwam_value_t parentval = NULL;
269 281 char *parentname;
270 282 nwam_error_t err;
271 283
272 284 if ((err = nwam_ncu_get_prop_value(ncuh, NWAM_NCU_PROP_PARENT_NCP,
273 285 &parentval)) != NWAM_SUCCESS ||
274 286 (err = nwam_value_get_string(parentval, &parentname))
275 287 != NWAM_SUCCESS ||
276 288 (*parentnamep = strdup(parentname)) == NULL) {
277 289 if (parentval != NULL)
278 290 nwam_value_free(parentval);
279 291 *parentnamep = NULL;
280 292 return (err);
281 293 }
282 294 nwam_value_free(parentval);
283 295
284 296 return (NWAM_SUCCESS);
285 297 }
286 298
287 299 static int
288 300 nwam_ncp_copy_callback(nwam_ncu_handle_t oldncuh, void *arg)
289 301 {
290 302 nwam_error_t err;
291 303 nwam_ncu_handle_t newncuh = NULL;
292 304 char *oldparent;
293 305 char *oldfilename = NULL, *newfilename = NULL;
294 306 nwam_ncp_handle_t newncph = (nwam_ncp_handle_t)arg;
295 307 nwam_value_t newparentval;
296 308
297 309 /* Get filenames for the new and old NCU's */
298 310 if ((err = nwam_ncu_get_parent_ncp_name(oldncuh, &oldparent))
299 311 != NWAM_SUCCESS)
300 312 return (err);
301 313 err = nwam_ncp_name_to_file(oldparent, &oldfilename);
302 314 free(oldparent);
303 315 if (err != NWAM_SUCCESS)
304 316 return (err);
305 317 if ((err = nwam_ncp_name_to_file(newncph->nwh_name, &newfilename))
306 318 != NWAM_SUCCESS)
307 319 goto fail;
308 320
309 321 /* new NCU name (and typedname) is the same as the old name */
310 322 if ((err = nwam_handle_create(NWAM_OBJECT_TYPE_NCU, oldncuh->nwh_name,
311 323 &newncuh)) != NWAM_SUCCESS)
312 324 goto fail;
313 325 /* Duplicate the old NCU's data */
314 326 if ((err = nwam_dup_object_list(oldncuh->nwh_data,
315 327 &(newncuh->nwh_data))) != NWAM_SUCCESS)
316 328 goto fail;
317 329
318 330 /* Update the parent property for the new NCU */
319 331 if ((err = nwam_value_create_string(newncph->nwh_name, &newparentval))
320 332 != NWAM_SUCCESS)
321 333 goto fail;
322 334 err = nwam_set_prop_value(newncuh->nwh_data, NWAM_NCU_PROP_PARENT_NCP,
323 335 newparentval);
324 336 nwam_value_free(newparentval);
325 337 if (err != NWAM_SUCCESS)
326 338 goto fail;
327 339
328 340 /* Save the new NCU */
329 341 err = nwam_commit(newfilename, newncuh, 0);
330 342
331 343 fail:
332 344 free(oldfilename);
333 345 free(newfilename);
334 346 nwam_ncu_free(newncuh);
335 347 return (err);
336 348 }
337 349
338 350 nwam_error_t
339 351 nwam_ncp_copy(nwam_ncp_handle_t oldncph, const char *newname,
340 352 nwam_ncp_handle_t *newncphp)
341 353 {
342 354 nwam_ncp_handle_t ncph;
343 355 nwam_error_t err;
344 356 int cb_ret;
345 357
346 358 assert(oldncph != NULL && newname != NULL && newncphp != NULL);
347 359
348 360 /* check if newname NCP already exists */
349 361 if (nwam_ncp_read(newname, 0, &ncph) == NWAM_SUCCESS) {
350 362 nwam_ncp_free(ncph);
351 363 *newncphp = NULL;
352 364 return (NWAM_ENTITY_EXISTS);
353 365 }
354 366
355 367 /* create new handle */
356 368 if ((err = nwam_ncp_create(newname, 0, newncphp)) != NWAM_SUCCESS)
357 369 return (err);
358 370
359 371 err = nwam_ncp_walk_ncus(oldncph, nwam_ncp_copy_callback, *newncphp,
360 372 NWAM_FLAG_NCU_TYPE_CLASS_ALL, &cb_ret);
361 373 if (err != NWAM_SUCCESS) {
362 374 /* remove the NCP even if any NCU's had already been copied */
363 375 (void) nwam_ncp_destroy(*newncphp, 0);
364 376 *newncphp = NULL;
365 377 if (err == NWAM_WALK_HALTED)
366 378 return (cb_ret);
367 379 else
368 380 return (err);
369 381 }
370 382
371 383 return (NWAM_SUCCESS);
372 384 }
373 385
374 386 /*
375 387 * Convert type to flag
376 388 */
377 389 static uint64_t
378 390 nwam_ncu_type_to_flag(nwam_ncu_type_t type)
379 391 {
380 392 switch (type) {
381 393 case NWAM_NCU_TYPE_LINK:
382 394 return (NWAM_FLAG_NCU_TYPE_LINK);
383 395 case NWAM_NCU_TYPE_INTERFACE:
384 396 return (NWAM_FLAG_NCU_TYPE_INTERFACE);
385 397 case NWAM_NCU_TYPE_ANY:
386 398 return (NWAM_FLAG_NCU_TYPE_ALL);
387 399 default:
388 400 return (0);
389 401 }
390 402 }
391 403
392 404 /*
393 405 * Convert class to flag
394 406 */
395 407 uint64_t
396 408 nwam_ncu_class_to_flag(nwam_ncu_class_t class)
397 409 {
398 410 switch (class) {
399 411 case NWAM_NCU_CLASS_PHYS:
400 412 return (NWAM_FLAG_NCU_CLASS_PHYS);
401 413 case NWAM_NCU_CLASS_IP:
402 414 return (NWAM_FLAG_NCU_CLASS_IP);
403 415 case NWAM_NCU_CLASS_ANY:
404 416 return (NWAM_FLAG_NCU_CLASS_ALL);
405 417 default:
406 418 return (0);
407 419 }
408 420 }
409 421
410 422 /*
411 423 * Infer NCU type from NCU class
412 424 */
413 425 nwam_ncu_type_t
414 426 nwam_ncu_class_to_type(nwam_ncu_class_t class)
415 427 {
416 428 switch (class) {
417 429 case NWAM_NCU_CLASS_PHYS:
418 430 return (NWAM_NCU_TYPE_LINK);
419 431 case NWAM_NCU_CLASS_IP:
420 432 return (NWAM_NCU_TYPE_INTERFACE);
421 433 case NWAM_NCU_CLASS_ANY:
422 434 return (NWAM_NCU_TYPE_ANY);
423 435 default:
424 436 return (NWAM_NCU_TYPE_UNKNOWN);
425 437 }
426 438 }
427 439
428 440 /*
429 441 * Make ncp active, deactivating any other active ncp.
430 442 */
431 443 nwam_error_t
432 444 nwam_ncp_enable(nwam_ncp_handle_t ncph)
433 445 {
434 446 nwam_error_t err;
435 447 char *name;
436 448
437 449 assert(ncph != NULL);
438 450
439 451 err = nwam_enable(NULL, ncph);
440 452
441 453 if (err == NWAM_ERROR_BIND) {
442 454 /*
443 455 * nwamd is not running, set active_ncp property so when
444 456 * nwamd is next started, this NCP will be used.
445 457 */
446 458 if ((err = nwam_ncp_get_name(ncph, &name)) != NWAM_SUCCESS)
447 459 return (err);
448 460
449 461 err = nwam_set_smf_string_property(NWAM_FMRI, NWAM_PG,
450 462 NWAM_PROP_ACTIVE_NCP, name);
451 463 free(name);
452 464 }
453 465
454 466 return (err);
455 467 }
456 468
457 469 /* Compare NCP names c1 and c2 using strcasecmp() */
458 470 static int
459 471 ncpname_cmp(const void *c1, const void *c2)
460 472 {
461 473 return (strcasecmp(*(const char **)c1, *(const char **)c2));
462 474 }
463 475
464 476 /* ARGSUSED1 */
465 477 nwam_error_t
466 478 nwam_walk_ncps(int (*cb)(nwam_ncp_handle_t, void *), void *data,
467 479 uint64_t flags, int *retp)
468 480 {
469 481 char *ncpname, **ncpfiles;
470 482 nwam_ncp_handle_t ncph;
471 483 nwam_error_t err;
472 484 nwam_value_t value;
473 485 void *objlist;
474 486 uint_t i, num_ncpfiles;
475 487 int ret = 0;
476 488
477 489 assert(cb != NULL);
478 490
479 491 if ((err = nwam_valid_flags(flags, NWAM_FLAG_BLOCKING)) != NWAM_SUCCESS)
480 492 return (err);
481 493 /*
482 494 * To get list of NCP files, call nwam_read_object_from_backend()
483 495 * with "parent" argument set to NULL. We get back an object list
484 496 * consisting of string arrays for each object type - NCP, ENM
485 497 * and location. We retrieve the NCP list, which corresponds to
486 498 * the set of NCP backend parent objects (these are files at present).
487 499 */
488 500 if ((err = nwam_read_object_from_backend(NULL, NULL, flags,
489 501 &objlist)) != NWAM_SUCCESS)
490 502 return (err);
491 503
492 504 if ((err = nwam_get_prop_value(objlist, NWAM_NCP_OBJECT_STRING, &value))
493 505 != NWAM_SUCCESS) {
494 506 nwam_free_object_list(objlist);
495 507 return (err);
496 508 }
497 509 if ((err = nwam_value_get_string_array(value, &ncpfiles,
498 510 &num_ncpfiles)) != NWAM_SUCCESS) {
499 511 nwam_value_free(value);
500 512 nwam_free_object_list(objlist);
501 513 return (err);
502 514 }
503 515
504 516 /* sort the NCP names alphabetically */
505 517 qsort(ncpfiles, num_ncpfiles, sizeof (char *), ncpname_cmp);
506 518
507 519 for (i = 0; i < num_ncpfiles; i++) {
508 520 if (nwam_ncp_file_to_name(ncpfiles[i], &ncpname)
509 521 != NWAM_SUCCESS)
510 522 continue;
511 523 if ((err = nwam_handle_create(NWAM_OBJECT_TYPE_NCP, ncpname,
512 524 &ncph)) != NWAM_SUCCESS) {
513 525 free(ncpname);
514 526 break;
515 527 }
516 528 ret = cb(ncph, data);
517 529 free(ncph);
518 530 free(ncpname);
519 531 if (ret != 0) {
520 532 err = NWAM_WALK_HALTED;
521 533 break;
522 534 }
523 535 }
524 536 nwam_value_free(value);
525 537 nwam_free_object_list(objlist);
526 538
527 539 if (retp != NULL)
528 540 *retp = ret;
529 541 return (err);
530 542 }
531 543
532 544 /*
533 545 * Checks if NCP is read-only. Only NWAM_NCP_NAME_AUTOMATIC is read-only
534 546 * for all but the netadm user (which nwamd runs as).
535 547 */
536 548 nwam_error_t
537 549 nwam_ncp_get_read_only(nwam_ncp_handle_t ncph, boolean_t *readp)
538 550 {
539 551 nwam_error_t err;
540 552 char *name;
541 553
542 554 assert(ncph != NULL && readp != NULL);
543 555
544 556 if ((err = nwam_ncp_get_name(ncph, &name)) != NWAM_SUCCESS)
545 557 return (err);
546 558
547 559 if (NWAM_NCP_AUTOMATIC(name))
548 560 *readp = !nwam_uid_is_special();
549 561 else
550 562 *readp = B_FALSE;
551 563
552 564 free(name);
553 565 return (NWAM_SUCCESS);
554 566 }
555 567
556 568 /* Checks if NCU is writable depending on its parent */
557 569 nwam_error_t
558 570 nwam_ncu_get_read_only(nwam_ncu_handle_t ncuh, boolean_t *readp)
559 571 {
560 572 nwam_error_t err;
561 573 nwam_ncp_handle_t ncph;
562 574
563 575 assert(ncuh != NULL && readp != NULL);
564 576
565 577 if ((err = nwam_ncu_get_ncp(ncuh, &ncph)) != NWAM_SUCCESS)
566 578 return (err);
567 579
568 580 err = nwam_ncp_get_read_only(ncph, readp);
569 581 nwam_ncp_free(ncph);
570 582 return (err);
571 583 }
572 584
573 585 /* Returns true if the NCP is active */
574 586 static boolean_t
575 587 nwam_ncp_is_active(nwam_ncp_handle_t ncph)
576 588 {
577 589 char *active_ncp, *name;
578 590 boolean_t ret;
579 591
580 592 assert(ncph != NULL);
581 593
582 594 /*
583 595 * Determine which NCP is active via the nwamd/active_ncp property
584 596 * value. This allows us to determine which NCP is active even
585 597 * if nwamd is not running.
586 598 */
587 599 if (nwam_ncp_get_name(ncph, &name) != NWAM_SUCCESS ||
588 600 nwam_get_smf_string_property(NWAM_FMRI, NWAM_PG,
589 601 NWAM_PROP_ACTIVE_NCP, &active_ncp) != NWAM_SUCCESS)
590 602 return (B_FALSE);
591 603
592 604 ret = (strcmp(name, active_ncp) == 0);
593 605
594 606 free(active_ncp);
595 607 free(name);
596 608
597 609 return (ret);
598 610 }
599 611
600 612 nwam_error_t
601 613 nwam_ncp_destroy(nwam_ncp_handle_t ncph, uint64_t flags)
602 614 {
603 615 char *filename;
604 616 nwam_error_t err;
605 617 boolean_t read_only;
606 618
607 619 assert(ncph != NULL);
608 620
609 621 if ((err = nwam_ncp_get_read_only(ncph, &read_only)) != NWAM_SUCCESS)
610 622 return (err);
611 623 if (read_only)
612 624 return (NWAM_ENTITY_NOT_DESTROYABLE);
613 625
614 626 if (nwam_ncp_is_active(ncph))
615 627 return (NWAM_ENTITY_IN_USE);
616 628
617 629 if ((err = nwam_ncp_name_to_file(ncph->nwh_name, &filename))
618 630 != NWAM_SUCCESS)
619 631 return (err);
620 632
621 633 err = nwam_destroy(filename, ncph, flags);
622 634 free(filename);
623 635
624 636 return (NWAM_SUCCESS);
625 637 }
626 638
627 639 static nwam_error_t
628 640 nwam_ncu_internal_name_to_name(const char *internalname,
629 641 nwam_ncu_type_t *typep, char **namep)
630 642 {
631 643 char *prefixstr;
632 644
633 645 assert(internalname != NULL && namep != NULL);
634 646
635 647 if (strncasecmp(internalname, NWAM_NCU_LINK_NAME_PRE,
636 648 strlen(NWAM_NCU_LINK_NAME_PRE)) == 0) {
637 649 prefixstr = NWAM_NCU_LINK_NAME_PRE;
638 650 *typep = NWAM_NCU_TYPE_LINK;
639 651 } else if (strncasecmp(internalname, NWAM_NCU_INTERFACE_NAME_PRE,
640 652 strlen(NWAM_NCU_INTERFACE_NAME_PRE)) == 0) {
641 653 prefixstr = NWAM_NCU_INTERFACE_NAME_PRE;
642 654 *typep = NWAM_NCU_TYPE_INTERFACE;
643 655 } else {
644 656 return (NWAM_INVALID_ARG);
645 657 }
646 658
647 659 *namep = strdup(internalname + strlen(prefixstr));
648 660 if (*namep == NULL)
649 661 return (NWAM_NO_MEMORY);
650 662 return (NWAM_SUCCESS);
651 663 }
652 664
653 665 /* ARGSUSED2 */
654 666 static int
655 667 ncu_selectcb(struct nwam_handle *hp, uint64_t flags, void *data)
656 668 {
657 669 nwam_ncu_handle_t ncuh = hp;
658 670 nwam_value_t typeval = NULL, classval = NULL;
659 671 uint64_t type, class, matchflags, walkfilter;
660 672
661 673 if (nwam_ncu_get_prop_value(ncuh, NWAM_NCU_PROP_TYPE, &typeval)
662 674 != NWAM_SUCCESS ||
663 675 nwam_ncu_get_prop_value(ncuh, NWAM_NCU_PROP_CLASS, &classval)
664 676 != NWAM_SUCCESS) {
665 677 if (typeval != NULL)
666 678 nwam_value_free(typeval);
667 679 return (NWAM_INVALID_ARG);
668 680 }
669 681 if (nwam_value_get_uint64(typeval, &type) != NWAM_SUCCESS ||
670 682 nwam_value_get_uint64(classval, &class) != NWAM_SUCCESS) {
671 683 nwam_value_free(typeval);
672 684 nwam_value_free(classval);
673 685 return (NWAM_INVALID_ARG);
674 686 }
675 687
676 688 matchflags = nwam_ncu_type_to_flag(type) |
677 689 nwam_ncu_class_to_flag(class);
678 690 nwam_value_free(typeval);
679 691 nwam_value_free(classval);
680 692
681 693 if ((walkfilter = (flags & NWAM_WALK_FILTER_MASK)) == 0)
682 694 walkfilter = NWAM_FLAG_NCU_TYPE_CLASS_ALL;
683 695
684 696 if (matchflags & walkfilter)
685 697 return (NWAM_SUCCESS);
686 698 return (NWAM_INVALID_ARG);
687 699 }
688 700
689 701 nwam_error_t
690 702 nwam_ncp_walk_ncus(nwam_ncp_handle_t ncph,
691 703 int(*cb)(nwam_ncu_handle_t, void *), void *data, uint64_t flags, int *retp)
692 704 {
693 705 char *ncpfile;
694 706 nwam_error_t err;
695 707
696 708 assert(ncph != NULL && cb != NULL);
697 709
698 710 if ((err = nwam_valid_flags(flags,
699 711 NWAM_FLAG_NCU_TYPE_CLASS_ALL | NWAM_FLAG_BLOCKING)) != NWAM_SUCCESS)
700 712 return (err);
701 713
702 714 if ((err = nwam_ncp_name_to_file(ncph->nwh_name, &ncpfile))
703 715 != NWAM_SUCCESS)
704 716 return (err);
705 717
706 718 err = nwam_walk(NWAM_OBJECT_TYPE_NCU, ncpfile, cb, data, flags,
707 719 retp, ncu_selectcb);
708 720 free(ncpfile);
709 721
710 722 return (err);
711 723 }
712 724
713 725 void
714 726 nwam_ncp_free(nwam_ncp_handle_t ncph)
715 727 {
716 728 nwam_free(ncph);
717 729 }
718 730
719 731 /*
720 732 * Are ncu type and class compatible?
721 733 */
722 734 static boolean_t
723 735 nwam_ncu_type_class_compatible(nwam_ncu_type_t type, nwam_ncu_class_t class)
724 736 {
725 737 switch (type) {
726 738 case NWAM_NCU_TYPE_LINK:
727 739 return (class == NWAM_NCU_CLASS_PHYS);
728 740 case NWAM_NCU_TYPE_INTERFACE:
729 741 return (class == NWAM_NCU_CLASS_IP);
730 742 default:
731 743 return (B_FALSE);
732 744 }
733 745 }
734 746
735 747 /* Name to validate may be internal name. If so, convert it before validating */
736 748 static boolean_t
737 749 valid_ncu_name(const char *name)
738 750 {
739 751 char *n;
740 752 boolean_t ret;
741 753 nwam_ncu_type_t type;
742 754
743 755 if (nwam_ncu_internal_name_to_name(name, &type, &n) == NWAM_SUCCESS) {
744 756
745 757 ret = dladm_valid_linkname(n);
746 758 free(n);
747 759 } else {
748 760 ret = dladm_valid_linkname(name);
749 761 }
750 762
751 763 return (ret);
752 764 }
753 765
754 766 nwam_error_t
755 767 nwam_ncu_create(nwam_ncp_handle_t ncph, const char *name,
756 768 nwam_ncu_type_t type, nwam_ncu_class_t class, nwam_ncu_handle_t *ncuhp)
757 769 {
758 770 nwam_ncu_handle_t ncuh;
759 771 nwam_value_t typeval = NULL, classval = NULL, parentval = NULL;
760 772 nwam_value_t enabledval = NULL;
761 773 nwam_error_t err;
762 774 boolean_t read_only;
763 775 char *typedname;
764 776
765 777 assert(ncph != NULL && name != NULL && ncuhp != NULL);
766 778
767 779 if (!valid_ncu_name(name))
768 780 return (NWAM_INVALID_ARG);
769 781
770 782 if ((err = nwam_ncp_get_read_only(ncph, &read_only)) != NWAM_SUCCESS)
771 783 return (err);
772 784 if (read_only)
773 785 return (NWAM_ENTITY_READ_ONLY);
774 786
775 787 if (nwam_ncu_read(ncph, name, type, 0, &ncuh) == NWAM_SUCCESS) {
776 788 nwam_ncu_free(ncuh);
777 789 return (NWAM_ENTITY_EXISTS);
778 790 }
779 791
780 792 if (!valid_ncu_name(name) ||
781 793 !nwam_ncu_type_class_compatible(type, class))
782 794 return (NWAM_INVALID_ARG);
783 795
784 796 if ((err = nwam_ncu_name_to_typed_name(name, type, &typedname))
785 797 != NWAM_SUCCESS)
786 798 return (err);
787 799
788 800 /* Create handle */
789 801 if ((err = nwam_handle_create(NWAM_OBJECT_TYPE_NCU, typedname, ncuhp))
790 802 != NWAM_SUCCESS)
791 803 return (err);
792 804 free(typedname);
793 805
794 806 /*
795 807 * Create new object list for NCU. The new NCU is initialized with
796 808 * the appropriate type and class.
797 809 */
798 810 if ((err = nwam_alloc_object_list(&(*ncuhp)->nwh_data)) != NWAM_SUCCESS)
799 811 goto finish;
800 812
801 813 if ((err = nwam_value_create_uint64(type, &typeval))
802 814 != NWAM_SUCCESS ||
803 815 (err = nwam_value_create_uint64(class, &classval))
804 816 != NWAM_SUCCESS ||
805 817 (err = nwam_value_create_string(ncph->nwh_name, &parentval))
806 818 != NWAM_SUCCESS ||
807 819 (err = nwam_value_create_boolean(B_TRUE, &enabledval))
808 820 != NWAM_SUCCESS) {
809 821 goto finish;
810 822 }
811 823 if ((err = nwam_set_prop_value((*ncuhp)->nwh_data, NWAM_NCU_PROP_TYPE,
812 824 typeval)) != NWAM_SUCCESS ||
813 825 (err = nwam_set_prop_value((*ncuhp)->nwh_data, NWAM_NCU_PROP_CLASS,
814 826 classval)) != NWAM_SUCCESS ||
815 827 (err = nwam_set_prop_value((*ncuhp)->nwh_data,
816 828 NWAM_NCU_PROP_PARENT_NCP, parentval)) != NWAM_SUCCESS ||
817 829 (err = nwam_set_prop_value((*ncuhp)->nwh_data,
818 830 NWAM_NCU_PROP_ENABLED, enabledval)) != NWAM_SUCCESS) {
819 831 goto finish;
820 832 }
821 833
822 834 /* Set default IP, datalink properties */
823 835 if (type == NWAM_NCU_TYPE_INTERFACE && class == NWAM_NCU_CLASS_IP) {
824 836
825 837 uint64_t ver[] = { IPV4_VERSION, IPV6_VERSION };
826 838 uint64_t v6src[] = { NWAM_ADDRSRC_DHCP, NWAM_ADDRSRC_AUTOCONF };
827 839 uint_t vercnt = 2, v6srccnt = 2;
828 840 nwam_value_t ipver = NULL, v4addrsrc = NULL, v6addrsrc = NULL;
829 841
830 842 if ((err = nwam_value_create_uint64_array(ver, vercnt, &ipver))
831 843 != NWAM_SUCCESS ||
832 844 (err = nwam_value_create_uint64(NWAM_ADDRSRC_DHCP,
833 845 &v4addrsrc)) != NWAM_SUCCESS ||
834 846 (err = nwam_value_create_uint64_array(v6src, v6srccnt,
835 847 &v6addrsrc)) != NWAM_SUCCESS) {
836 848 nwam_value_free(ipver);
837 849 nwam_value_free(v4addrsrc);
838 850 goto finish;
839 851 }
840 852 if ((err = nwam_set_prop_value((*ncuhp)->nwh_data,
841 853 NWAM_NCU_PROP_IP_VERSION, ipver)) == NWAM_SUCCESS &&
842 854 (err = nwam_set_prop_value((*ncuhp)->nwh_data,
843 855 NWAM_NCU_PROP_IPV4_ADDRSRC, v4addrsrc)) == NWAM_SUCCESS) {
844 856 err = nwam_set_prop_value((*ncuhp)->nwh_data,
845 857 NWAM_NCU_PROP_IPV6_ADDRSRC, v6addrsrc);
846 858 }
847 859 nwam_value_free(ipver);
848 860 nwam_value_free(v4addrsrc);
849 861 nwam_value_free(v6addrsrc);
850 862 } else {
851 863 nwam_value_t actval = NULL;
852 864 if ((err = nwam_value_create_uint64(NWAM_ACTIVATION_MODE_MANUAL,
853 865 &actval)) != NWAM_SUCCESS)
854 866 goto finish;
855 867 err = nwam_set_prop_value((*ncuhp)->nwh_data,
856 868 NWAM_NCU_PROP_ACTIVATION_MODE, actval);
857 869 nwam_value_free(actval);
858 870 }
859 871
860 872 finish:
861 873 nwam_value_free(typeval);
862 874 nwam_value_free(classval);
863 875 nwam_value_free(parentval);
864 876 nwam_value_free(enabledval);
865 877 if (err != NWAM_SUCCESS) {
866 878 nwam_ncu_free(*ncuhp);
867 879 *ncuhp = NULL;
868 880 }
869 881 return (err);
870 882 }
871 883
872 884 nwam_error_t
873 885 nwam_ncu_read(nwam_ncp_handle_t ncph, const char *name,
874 886 nwam_ncu_type_t type, uint64_t flags, nwam_ncu_handle_t *ncuhp)
875 887 {
876 888 char *ncpfile, *typedname;
877 889 nwam_error_t err, err_ip, err_link;
878 890 nwam_ncu_handle_t ncuh_ip, ncuh_link;
879 891
880 892 assert(ncph != NULL && name != NULL && ncuhp != NULL);
881 893
882 894 if ((err = nwam_ncp_name_to_file(ncph->nwh_name, &ncpfile))
883 895 != NWAM_SUCCESS)
884 896 return (err);
885 897
886 898 if (type == NWAM_NCU_TYPE_ANY) {
887 899
888 900 free(ncpfile);
889 901
890 902 /*
891 903 * If we get to this point, we have discovered that no
892 904 * NCU type is discernable from name or type arguments.
893 905 * Either exactly one NCU called name must exist of either
894 906 * type, or the operation should fail.
895 907 */
896 908 err_ip = nwam_ncu_read(ncph, name, NWAM_NCU_TYPE_INTERFACE,
897 909 flags, &ncuh_ip);
898 910 err_link = nwam_ncu_read(ncph, name, NWAM_NCU_TYPE_LINK,
899 911 flags, &ncuh_link);
900 912
901 913 *ncuhp = NULL;
902 914
903 915 if (err_ip == NWAM_SUCCESS && err_link == NWAM_SUCCESS) {
904 916 nwam_ncu_free(ncuh_ip);
905 917 nwam_ncu_free(ncuh_link);
906 918 err = NWAM_ENTITY_MULTIPLE_VALUES;
907 919 } else if (err_ip != NWAM_SUCCESS && err_link != NWAM_SUCCESS) {
908 920 err = NWAM_ENTITY_NOT_FOUND;
909 921 } else {
910 922 if (err_ip == NWAM_SUCCESS) {
911 923 *ncuhp = ncuh_ip;
912 924 } else {
913 925 *ncuhp = ncuh_link;
914 926 }
915 927 err = NWAM_SUCCESS;
916 928 }
917 929
918 930 return (err);
919 931 }
920 932 if ((err = nwam_ncu_name_to_typed_name(name, type, &typedname)) !=
921 933 NWAM_SUCCESS) {
922 934 free(ncpfile);
923 935 return (err);
924 936 }
925 937 err = nwam_read(NWAM_OBJECT_TYPE_NCU, ncpfile, typedname, flags, ncuhp);
926 938
927 939 free(typedname);
928 940 free(ncpfile);
929 941
930 942 return (err);
931 943 }
932 944
933 945 nwam_error_t
934 946 nwam_ncu_get_name(nwam_ncu_handle_t ncuh, char **namep)
935 947 {
936 948 nwam_ncu_type_t type;
937 949
938 950 assert(ncuh != NULL && namep != NULL);
939 951
940 952 return (nwam_ncu_internal_name_to_name(ncuh->nwh_name, &type, namep));
941 953 }
942 954
943 955 nwam_error_t
944 956 nwam_ncu_name_to_typed_name(const char *name, nwam_ncu_type_t type,
945 957 char **typednamep)
946 958 {
947 959 char *prefixstr;
948 960 size_t typednamesz;
949 961
950 962 assert(name != NULL && typednamep != NULL);
951 963
952 964 switch (type) {
953 965 case NWAM_NCU_TYPE_INTERFACE:
954 966 prefixstr = NWAM_NCU_INTERFACE_NAME_PRE;
955 967 break;
956 968 case NWAM_NCU_TYPE_LINK:
957 969 prefixstr = NWAM_NCU_LINK_NAME_PRE;
958 970 break;
959 971 default:
960 972 return (NWAM_INVALID_ARG);
961 973 }
962 974 typednamesz = strlen(name) + strlen(prefixstr) + 1;
963 975 if ((*typednamep = malloc(typednamesz)) == NULL)
964 976 return (NWAM_NO_MEMORY);
965 977
966 978 /* Name may be already qualified by type */
967 979 if (strncasecmp(prefixstr, name, strlen(prefixstr)) == 0) {
968 980 (void) snprintf(*typednamep, typednamesz, "%s", name);
969 981 } else {
970 982 (void) snprintf(*typednamep, typednamesz, "%s%s",
971 983 prefixstr, name);
972 984 }
973 985
974 986 return (NWAM_SUCCESS);
975 987 }
976 988
977 989 nwam_error_t
978 990 nwam_ncu_typed_name_to_name(const char *typed_name, nwam_ncu_type_t *typep,
979 991 char **name)
980 992 {
981 993 return (nwam_ncu_internal_name_to_name(typed_name, typep, name));
982 994 }
983 995
984 996 void
985 997 nwam_ncu_free(nwam_ncu_handle_t ncuh)
986 998 {
987 999 nwam_free(ncuh);
988 1000 }
989 1001
990 1002 nwam_error_t
991 1003 nwam_ncu_copy(nwam_ncu_handle_t oldncuh, const char *newname,
992 1004 nwam_ncu_handle_t *newncuhp)
993 1005 {
994 1006 nwam_ncp_handle_t ncph;
995 1007 nwam_ncu_handle_t ncuh;
996 1008 nwam_error_t err;
997 1009 nwam_value_t typeval;
998 1010 uint64_t type;
999 1011 char *typednewname;
1000 1012
1001 1013 assert(oldncuh != NULL && newname != NULL && newncuhp != NULL);
1002 1014
1003 1015 if (nwam_ncu_get_prop_value(oldncuh, NWAM_NCU_PROP_TYPE,
1004 1016 &typeval) != NWAM_SUCCESS) {
1005 1017 return (NWAM_INVALID_ARG);
1006 1018 }
1007 1019 if (nwam_value_get_uint64(typeval, &type) != NWAM_SUCCESS) {
1008 1020 nwam_value_free(typeval);
1009 1021 return (NWAM_INVALID_ARG);
1010 1022 }
1011 1023 nwam_value_free(typeval);
1012 1024
1013 1025 /* check if newname NCU already exists */
1014 1026 if ((err = nwam_ncu_get_ncp(oldncuh, &ncph)) != NWAM_SUCCESS)
1015 1027 return (err);
1016 1028 if (nwam_ncu_read(ncph, newname, type, 0, &ncuh) == NWAM_SUCCESS) {
1017 1029 nwam_ncu_free(ncuh);
1018 1030 nwam_ncp_free(ncph);
1019 1031 return (NWAM_ENTITY_EXISTS);
1020 1032 }
1021 1033 nwam_ncp_free(ncph);
1022 1034
1023 1035 if ((err = nwam_ncu_name_to_typed_name(newname, type, &typednewname))
1024 1036 != NWAM_SUCCESS)
1025 1037 return (err);
1026 1038
1027 1039 err = nwam_handle_create(NWAM_OBJECT_TYPE_NCU, typednewname, newncuhp);
1028 1040 free(typednewname);
1029 1041 if (err != NWAM_SUCCESS)
1030 1042 return (err);
1031 1043 if ((err = nwam_dup_object_list(oldncuh->nwh_data,
1032 1044 &((*newncuhp)->nwh_data))) != NWAM_SUCCESS) {
1033 1045 free(*newncuhp);
1034 1046 *newncuhp = NULL;
1035 1047 return (err);
1036 1048 }
1037 1049
1038 1050 return (NWAM_SUCCESS);
1039 1051 }
1040 1052
1041 1053 nwam_error_t
1042 1054 nwam_ncu_delete_prop(nwam_ncu_handle_t ncuh, const char *propname)
1043 1055 {
1044 1056 boolean_t ro_ncu, ro_prop;
1045 1057 nwam_error_t err;
1046 1058 void *olddata;
1047 1059
1048 1060 assert(ncuh != NULL && propname != NULL);
1049 1061
1050 1062 if ((err = nwam_ncu_get_read_only(ncuh, &ro_ncu)) != NWAM_SUCCESS ||
1051 1063 (err = nwam_ncu_prop_read_only(propname, &ro_prop)) != NWAM_SUCCESS)
1052 1064 return (err);
1053 1065 if (ro_ncu || ro_prop)
1054 1066 return (NWAM_ENTITY_READ_ONLY);
1055 1067
1056 1068 /*
1057 1069 * Duplicate data, remove property and validate. If validation
1058 1070 * fails, revert to data duplicated prior to remove.
1059 1071 */
1060 1072 if ((err = nwam_dup_object_list(ncuh->nwh_data, &olddata))
1061 1073 != NWAM_SUCCESS)
1062 1074 return (err);
1063 1075 if ((err = nwam_delete_prop(ncuh->nwh_data, propname))
1064 1076 != NWAM_SUCCESS) {
1065 1077 nwam_free_object_list(ncuh->nwh_data);
1066 1078 ncuh->nwh_data = olddata;
1067 1079 return (err);
1068 1080 }
1069 1081 if ((err = nwam_ncu_validate(ncuh, NULL)) != NWAM_SUCCESS) {
1070 1082 nwam_free_object_list(ncuh->nwh_data);
1071 1083 ncuh->nwh_data = olddata;
1072 1084 return (err);
1073 1085 }
1074 1086 nwam_free_object_list(olddata);
1075 1087
1076 1088 return (NWAM_SUCCESS);
1077 1089 }
1078 1090
1079 1091 nwam_error_t
1080 1092 nwam_ncu_set_prop_value(nwam_ncu_handle_t ncuh, const char *propname,
1081 1093 nwam_value_t value)
1082 1094 {
1083 1095 boolean_t ro_ncu, ro_prop;
1084 1096 nwam_error_t err;
1085 1097 nwam_ncp_handle_t ncph;
1086 1098
1087 1099 assert(ncuh != NULL && propname != NULL && value != NULL);
1088 1100
1089 1101 if ((err = nwam_ncu_get_read_only(ncuh, &ro_ncu)) != NWAM_SUCCESS ||
1090 1102 (err = nwam_ncu_prop_read_only(propname, &ro_prop)) != NWAM_SUCCESS)
1091 1103 return (err);
1092 1104 if (ro_ncu || ro_prop)
1093 1105 return (NWAM_ENTITY_READ_ONLY);
1094 1106
1095 1107 err = nwam_ncu_get_ncp(ncuh, &ncph);
1096 1108 if (err != NWAM_SUCCESS && err != NWAM_INVALID_ARG) {
1097 1109 /*
1098 1110 * If "parent" property doesn't exist, NWAM_INVALID_ARG
1099 1111 * is returned. Allow the setting to continue.
1100 1112 */
1101 1113 return (err);
1102 1114 }
1103 1115 nwam_ncp_free(ncph);
1104 1116
1105 1117 /* Need to ensure property, type and value are valid */
1106 1118 if ((err = nwam_ncu_validate_prop(ncuh, propname, value))
1107 1119 != NWAM_SUCCESS)
1108 1120 return (err);
1109 1121
1110 1122 return (nwam_set_prop_value(ncuh->nwh_data, propname, value));
1111 1123 }
1112 1124
1113 1125 nwam_error_t
1114 1126 nwam_ncu_get_prop_value(nwam_ncu_handle_t ncuh, const char *propname,
1115 1127 nwam_value_t *valuep)
1116 1128 {
1117 1129 assert(ncuh != NULL && propname != NULL && valuep != NULL);
1118 1130
1119 1131 return (nwam_get_prop_value(ncuh->nwh_data, propname, valuep));
1120 1132 }
1121 1133
1122 1134 nwam_error_t
1123 1135 nwam_ncu_walk_props(nwam_ncu_handle_t ncuh,
1124 1136 int (*cb)(const char *, nwam_value_t, void *),
1125 1137 void *data, uint64_t flags, int *retp)
1126 1138 {
1127 1139 return (nwam_walk_props(ncuh, cb, data, flags, retp));
1128 1140 }
1129 1141
1130 1142 nwam_error_t
1131 1143 nwam_ncu_get_ncp(nwam_ncu_handle_t ncuh, nwam_ncp_handle_t *ncphp)
1132 1144 {
1133 1145 nwam_error_t err;
1134 1146 char *parentname = NULL;
1135 1147
1136 1148 if ((err = nwam_ncu_get_parent_ncp_name(ncuh, &parentname))
1137 1149 != NWAM_SUCCESS ||
1138 1150 (err = nwam_handle_create(NWAM_OBJECT_TYPE_NCP, parentname, ncphp))
1139 1151 != NWAM_SUCCESS) {
1140 1152 if (parentname != NULL)
1141 1153 free(parentname);
1142 1154 return (err);
1143 1155 }
1144 1156 free(parentname);
1145 1157
1146 1158 return (NWAM_SUCCESS);
1147 1159 }
1148 1160
1149 1161 nwam_error_t
1150 1162 nwam_ncu_commit(nwam_ncu_handle_t ncuh, uint64_t flags)
1151 1163 {
1152 1164 nwam_error_t err;
1153 1165 boolean_t read_only;
1154 1166 char *ncpfile, *ncpname;
1155 1167
1156 1168 assert(ncuh != NULL && ncuh->nwh_data != NULL);
1157 1169
1158 1170 if ((err = nwam_ncu_get_read_only(ncuh, &read_only)) != NWAM_SUCCESS)
1159 1171 return (err);
1160 1172 if (read_only)
1161 1173 return (NWAM_ENTITY_READ_ONLY);
1162 1174
1163 1175 if ((err = nwam_ncu_validate(ncuh, NULL)) != NWAM_SUCCESS ||
1164 1176 (err = nwam_ncu_get_parent_ncp_name(ncuh, &ncpname))
1165 1177 != NWAM_SUCCESS)
1166 1178 return (err);
1167 1179
1168 1180 if ((err = nwam_ncp_name_to_file(ncpname, &ncpfile)) != NWAM_SUCCESS) {
1169 1181 free(ncpname);
1170 1182 return (err);
1171 1183 }
1172 1184
1173 1185 err = nwam_commit(ncpfile, ncuh, flags);
1174 1186
1175 1187 free(ncpname);
1176 1188 free(ncpfile);
1177 1189
1178 1190 return (err);
1179 1191 }
1180 1192 /* Get the NCU type */
1181 1193 nwam_error_t
1182 1194 nwam_ncu_get_ncu_type(nwam_ncu_handle_t ncuh, nwam_ncu_type_t *typep)
1183 1195 {
1184 1196 nwam_error_t err;
1185 1197 nwam_value_t typeval;
1186 1198 uint64_t type;
1187 1199
1188 1200 if ((err = nwam_ncu_get_prop_value(ncuh, NWAM_NCU_PROP_TYPE, &typeval))
1189 1201 != NWAM_SUCCESS)
1190 1202 return (err);
1191 1203 err = nwam_value_get_uint64(typeval, &type);
1192 1204 nwam_value_free(typeval);
1193 1205 if (err != NWAM_SUCCESS)
1194 1206 return (err);
1195 1207
1196 1208 *typep = type;
1197 1209 return (NWAM_SUCCESS);
1198 1210 }
1199 1211
1200 1212 /* Get the NCU class */
1201 1213 nwam_error_t
1202 1214 nwam_ncu_get_ncu_class(nwam_ncu_handle_t ncuh, nwam_ncu_class_t *classp)
1203 1215 {
1204 1216 nwam_error_t err;
1205 1217 nwam_value_t classval;
1206 1218 uint64_t class;
1207 1219
1208 1220 if ((err = nwam_ncu_get_prop_value(ncuh, NWAM_NCU_PROP_CLASS,
1209 1221 &classval)) != NWAM_SUCCESS)
1210 1222 return (err);
1211 1223 err = nwam_value_get_uint64(classval, &class);
1212 1224 nwam_value_free(classval);
1213 1225 if (err != NWAM_SUCCESS)
1214 1226 return (err);
1215 1227
1216 1228 *classp = class;
1217 1229 return (NWAM_SUCCESS);
1218 1230 }
1219 1231
1220 1232 /*
1221 1233 * Determine if the NCU has manual activation-mode or not.
1222 1234 */
1223 1235 nwam_error_t
1224 1236 nwam_ncu_is_manual(nwam_ncu_handle_t ncuh, boolean_t *manualp)
1225 1237 {
1226 1238 nwam_error_t err;
1227 1239 nwam_value_t actval;
1228 1240 uint64_t activation;
1229 1241
1230 1242 assert(ncuh != NULL);
1231 1243
1232 1244 if ((err = nwam_ncu_get_prop_value(ncuh, NWAM_NCU_PROP_ACTIVATION_MODE,
1233 1245 &actval)) != NWAM_SUCCESS)
1234 1246 return (err);
1235 1247 err = nwam_value_get_uint64(actval, &activation);
1236 1248 nwam_value_free(actval);
1237 1249 if (err != NWAM_SUCCESS)
1238 1250 return (err);
1239 1251
1240 1252 if (activation == NWAM_ACTIVATION_MODE_MANUAL)
1241 1253 *manualp = B_TRUE;
1242 1254 else
1243 1255 *manualp = B_FALSE;
1244 1256 return (NWAM_SUCCESS);
1245 1257 }
1246 1258
1247 1259 /* Determine if NCU is enabled or not */
1248 1260 static nwam_error_t
1249 1261 nwam_ncu_is_enabled(nwam_ncu_handle_t ncuh, boolean_t *enabledp)
1250 1262 {
1251 1263 nwam_error_t err;
1252 1264 nwam_value_t enabledval;
1253 1265
1254 1266 assert(ncuh != NULL);
1255 1267
1256 1268 if ((err = nwam_ncu_get_prop_value(ncuh, NWAM_NCU_PROP_ENABLED,
1257 1269 &enabledval)) != NWAM_SUCCESS)
1258 1270 return (err);
1259 1271 err = nwam_value_get_boolean(enabledval, enabledp);
1260 1272 nwam_value_free(enabledval);
1261 1273 return (err);
1262 1274 }
1263 1275
1264 1276 /* Update the enabled property */
1265 1277 static nwam_error_t
1266 1278 nwam_ncu_update_enabled(nwam_ncu_handle_t ncuh, boolean_t enabled)
1267 1279 {
1268 1280 nwam_error_t err;
1269 1281 nwam_value_t enabledval;
1270 1282
1271 1283 if ((err = nwam_value_create_boolean(enabled, &enabledval))
1272 1284 != NWAM_SUCCESS)
1273 1285 return (err);
1274 1286 err = nwam_set_prop_value(ncuh->nwh_data, NWAM_NCU_PROP_ENABLED,
1275 1287 enabledval);
1276 1288 nwam_value_free(enabledval);
1277 1289 if (err != NWAM_SUCCESS)
1278 1290 return (err);
1279 1291 return (nwam_ncu_commit(ncuh, NWAM_FLAG_ENTITY_ENABLE));
1280 1292 }
1281 1293
1282 1294 /*
1283 1295 * Make ncu active; fails if the NCU's parent NCP is not active.
1284 1296 */
1285 1297 nwam_error_t
1286 1298 nwam_ncu_enable(nwam_ncu_handle_t ncuh)
1287 1299 {
1288 1300 char *ncpname = NULL;
1289 1301 nwam_error_t err;
1290 1302 nwam_ncu_type_t type;
1291 1303 boolean_t read_only, enabled, manual;
1292 1304
1293 1305 assert(ncuh != NULL);
1294 1306
1295 1307 /* Don't allow NCUs of Automatic NCP to be enabled */
1296 1308 if ((err = nwam_ncu_get_read_only(ncuh, &read_only)) != NWAM_SUCCESS)
1297 1309 return (err);
1298 1310 if (read_only)
1299 1311 return (NWAM_ENTITY_NOT_MANUAL);
1300 1312
1301 1313 /* Link NCUs with manual activation-mode or IP NCUs can be enabled */
1302 1314 if ((err = nwam_ncu_get_ncu_type(ncuh, &type)) != NWAM_SUCCESS)
1303 1315 return (err);
1304 1316
1305 1317 if (type == NWAM_NCU_TYPE_LINK) {
1306 1318 if ((err = nwam_ncu_is_manual(ncuh, &manual)) != NWAM_SUCCESS)
1307 1319 return (err);
1308 1320 if (!manual)
1309 1321 return (NWAM_ENTITY_NOT_MANUAL);
1310 1322 }
1311 1323
1312 1324 /* Make sure NCU is not enabled */
1313 1325 if ((err = nwam_ncu_is_enabled(ncuh, &enabled)) != NWAM_SUCCESS ||
1314 1326 (err = nwam_ncu_get_parent_ncp_name(ncuh, &ncpname))
1315 1327 != NWAM_SUCCESS)
1316 1328 return (err);
1317 1329
1318 1330 if (enabled) {
1319 1331 free(ncpname);
1320 1332 return (NWAM_SUCCESS);
1321 1333 }
1322 1334
1323 1335 if ((err = nwam_ncu_update_enabled(ncuh, B_TRUE)) != NWAM_SUCCESS) {
1324 1336 free(ncpname);
1325 1337 return (err);
1326 1338 }
1327 1339
1328 1340 err = nwam_enable(ncpname, ncuh);
1329 1341 free(ncpname);
1330 1342
1331 1343 /* nwamd may not be running, that's okay. */
1332 1344 if (err == NWAM_ERROR_BIND)
1333 1345 return (NWAM_SUCCESS);
1334 1346 else
1335 1347 return (err);
1336 1348 }
1337 1349
1338 1350 /*
1339 1351 * Disable ncu; fails if the NCU's parent NCP is not active, or if the
1340 1352 * NCU is not currently active.
1341 1353 */
1342 1354 nwam_error_t
1343 1355 nwam_ncu_disable(nwam_ncu_handle_t ncuh)
1344 1356 {
1345 1357 char *ncpname = NULL;
1346 1358 nwam_error_t err;
1347 1359 nwam_ncu_type_t type;
1348 1360 boolean_t read_only, enabled, manual;
1349 1361
1350 1362 assert(ncuh != NULL);
1351 1363
1352 1364 /* Don't allow NCUs of Automatic NCP to be disabled */
1353 1365 if ((err = nwam_ncu_get_read_only(ncuh, &read_only)) != NWAM_SUCCESS)
1354 1366 return (err);
1355 1367 if (read_only)
1356 1368 return (NWAM_ENTITY_NOT_MANUAL);
1357 1369
1358 1370 /* Link NCUs with manual activation-mode or IP NCUs can be disabled */
1359 1371 if ((err = nwam_ncu_get_ncu_type(ncuh, &type)) != NWAM_SUCCESS)
1360 1372 return (err);
1361 1373
1362 1374 if (type == NWAM_NCU_TYPE_LINK) {
1363 1375 if ((err = nwam_ncu_is_manual(ncuh, &manual)) != NWAM_SUCCESS)
1364 1376 return (err);
1365 1377 if (!manual)
1366 1378 return (NWAM_ENTITY_NOT_MANUAL);
1367 1379 }
1368 1380
1369 1381 /* Make sure NCU is enabled */
1370 1382 if ((err = nwam_ncu_is_enabled(ncuh, &enabled)) != NWAM_SUCCESS ||
1371 1383 (err = nwam_ncu_get_parent_ncp_name(ncuh, &ncpname))
1372 1384 != NWAM_SUCCESS)
1373 1385 return (err);
1374 1386
1375 1387 if (!enabled) {
1376 1388 free(ncpname);
1377 1389 return (NWAM_SUCCESS);
1378 1390 }
1379 1391
1380 1392 if ((err = nwam_ncu_update_enabled(ncuh, B_FALSE)) != NWAM_SUCCESS) {
1381 1393 free(ncpname);
1382 1394 return (err);
1383 1395 }
1384 1396
1385 1397 err = nwam_disable(ncpname, ncuh);
1386 1398 free(ncpname);
1387 1399
1388 1400 /* nwamd may not be running, that's okay. */
1389 1401 if (err == NWAM_ERROR_BIND)
1390 1402 return (NWAM_SUCCESS);
1391 1403 else
1392 1404 return (err);
1393 1405 }
1394 1406
1395 1407 nwam_error_t
1396 1408 nwam_ncu_destroy(nwam_ncu_handle_t ncuh, uint64_t flags)
1397 1409 {
1398 1410 char *ncpname, *ncpfile;
1399 1411 boolean_t read_only;
1400 1412 nwam_error_t err;
1401 1413
1402 1414 assert(ncuh != NULL);
1403 1415
1404 1416 if ((err = nwam_ncu_get_read_only(ncuh, &read_only)) != NWAM_SUCCESS)
1405 1417 return (err);
1406 1418 if (read_only)
1407 1419 return (NWAM_ENTITY_NOT_DESTROYABLE);
1408 1420
1409 1421 if ((err = nwam_ncu_get_parent_ncp_name(ncuh, &ncpname))
1410 1422 != NWAM_SUCCESS)
1411 1423 return (err);
1412 1424 if ((err = nwam_ncp_name_to_file(ncpname, &ncpfile))
1413 1425 != NWAM_SUCCESS) {
1414 1426 free(ncpname);
1415 1427 return (err);
1416 1428 }
1417 1429
1418 1430 err = nwam_destroy(ncpfile, ncuh, flags);
1419 1431
1420 1432 free(ncpname);
1421 1433 free(ncpfile);
1422 1434
1423 1435 return (err);
1424 1436 }
1425 1437
1426 1438 nwam_error_t
1427 1439 nwam_ncu_get_prop_description(const char *propname, const char **descriptionp)
1428 1440 {
1429 1441 return (nwam_get_prop_description(ncu_prop_table, propname,
1430 1442 descriptionp));
1431 1443 }
1432 1444
1433 1445 /* Get expected property data type */
1434 1446 nwam_error_t
1435 1447 nwam_ncu_get_prop_type(const char *propname, nwam_value_type_t *typep)
1436 1448 {
1437 1449 return (nwam_get_prop_type(ncu_prop_table, propname, typep));
1438 1450 }
1439 1451
1440 1452 nwam_error_t
1441 1453 nwam_ncu_prop_read_only(const char *propname, boolean_t *readp)
1442 1454 {
1443 1455 if ((*readp = NWAM_NCU_PROP_SETONCE(propname)) == B_TRUE)
1444 1456 return (NWAM_SUCCESS);
1445 1457
1446 1458 return (nwam_prop_read_only(ncu_prop_table, propname, readp));
1447 1459 }
1448 1460
1449 1461 nwam_error_t
1450 1462 nwam_ncu_prop_multivalued(const char *propname, boolean_t *multip)
1451 1463 {
1452 1464 return (nwam_prop_multivalued(ncu_prop_table, propname, multip));
1453 1465 }
1454 1466
1455 1467 /*
1456 1468 * Ensure that the properties in the ncu, determined by that ncu's
1457 1469 * type and class, belong there.
1458 1470 */
1459 1471 static nwam_error_t
1460 1472 nwam_ncu_validate_prop_membership(nwam_ncu_handle_t ncuh, const char *propname)
1461 1473 {
1462 1474 struct nwam_prop_table_entry *pte;
1463 1475 nwam_value_t typeval, classval;
1464 1476 uint64_t type, class;
1465 1477 uint64_t typeflags = 0, classflags = 0;
1466 1478
1467 1479 /* Get type/class from ncu */
1468 1480 if (nwam_ncu_get_prop_value(ncuh, NWAM_NCU_PROP_TYPE, &typeval)
1469 1481 != NWAM_SUCCESS)
1470 1482 return (NWAM_ENTITY_INVALID);
1471 1483 if (nwam_value_get_uint64(typeval, &type) != NWAM_SUCCESS) {
1472 1484 nwam_value_free(typeval);
1473 1485 return (NWAM_ENTITY_INVALID);
1474 1486 }
1475 1487 typeflags = nwam_ncu_type_to_flag((nwam_ncu_type_t)type);
1476 1488 nwam_value_free(typeval);
1477 1489
1478 1490 if (nwam_ncu_get_prop_value(ncuh, NWAM_NCU_PROP_CLASS, &classval)
1479 1491 != NWAM_SUCCESS)
1480 1492 return (NWAM_ENTITY_INVALID);
1481 1493 if (nwam_value_get_uint64(classval, &class) != NWAM_SUCCESS) {
1482 1494 nwam_value_free(classval);
1483 1495 return (NWAM_ENTITY_INVALID);
1484 1496 }
1485 1497 classflags = nwam_ncu_class_to_flag((nwam_ncu_class_t)class);
1486 1498 nwam_value_free(classval);
1487 1499
1488 1500 if ((pte = nwam_get_prop_table_entry(ncu_prop_table, propname)) == NULL)
1489 1501 return (NWAM_INVALID_ARG);
1490 1502
1491 1503 if (typeflags & pte->prop_type_membership &&
1492 1504 classflags & pte->prop_class_membership) {
1493 1505 return (NWAM_SUCCESS);
1494 1506 } else {
1495 1507 return (NWAM_ENTITY_INVALID_MEMBER);
1496 1508 }
1497 1509 }
1498 1510
1499 1511 /* Validate property's ncu membership and type, number and range of values */
1500 1512 nwam_error_t
1501 1513 nwam_ncu_validate_prop(nwam_ncu_handle_t ncuh, const char *propname,
1502 1514 nwam_value_t value)
1503 1515 {
1504 1516 nwam_error_t err;
1505 1517
1506 1518 assert(ncuh != NULL && propname != NULL);
1507 1519
1508 1520 /* First, determine if this property is valid for this ncu */
1509 1521 if ((err = nwam_ncu_validate_prop_membership(ncuh, propname))
1510 1522 != NWAM_SUCCESS)
1511 1523 return (err);
1512 1524
1513 1525 return (nwam_validate_prop(ncu_prop_table, ncuh, propname, value));
1514 1526 }
1515 1527
1516 1528 /* Property-specific value validation functions follow */
1517 1529
1518 1530 static nwam_error_t
1519 1531 valid_type(nwam_value_t value)
1520 1532 {
1521 1533 uint64_t type;
1522 1534
1523 1535 if (nwam_value_get_uint64(value, &type) != NWAM_SUCCESS ||
1524 1536 type > NWAM_NCU_TYPE_INTERFACE)
1525 1537 return (NWAM_ENTITY_INVALID_VALUE);
1526 1538 return (NWAM_SUCCESS);
1527 1539 }
1528 1540
1529 1541 static nwam_error_t
1530 1542 valid_class(nwam_value_t value)
1531 1543 {
1532 1544 uint64_t class;
1533 1545
1534 1546 if (nwam_value_get_uint64(value, &class) != NWAM_SUCCESS ||
1535 1547 class > NWAM_NCU_CLASS_IP)
1536 1548 return (NWAM_ENTITY_INVALID_VALUE);
1537 1549 return (NWAM_SUCCESS);
1538 1550 }
1539 1551
1540 1552 static nwam_error_t
1541 1553 valid_ncp(nwam_value_t value)
1542 1554 {
1543 1555 char *ncp;
1544 1556
1545 1557 if (nwam_value_get_string(value, &ncp) != NWAM_SUCCESS)
1546 1558 return (NWAM_ENTITY_INVALID_VALUE);
1547 1559 return (NWAM_SUCCESS);
1548 1560 }
1549 1561
1550 1562 static nwam_error_t
1551 1563 valid_priority_mode(nwam_value_t value)
1552 1564 {
1553 1565 uint64_t priority_mode;
1554 1566
1555 1567 if (nwam_value_get_uint64(value, &priority_mode) != NWAM_SUCCESS ||
1556 1568 priority_mode > NWAM_PRIORITY_MODE_ALL)
1557 1569 return (NWAM_ENTITY_INVALID_VALUE);
1558 1570 return (NWAM_SUCCESS);
1559 1571 }
1560 1572
1561 1573 static nwam_error_t
1562 1574 valid_ncu_activation_mode(nwam_value_t value)
1563 1575 {
1564 1576 uint64_t activation_mode;
1565 1577
1566 1578 if (nwam_value_get_uint64(value, &activation_mode) != NWAM_SUCCESS)
1567 1579 return (NWAM_ENTITY_INVALID_VALUE);
1568 1580
1569 1581 switch (activation_mode) {
1570 1582 case NWAM_ACTIVATION_MODE_MANUAL:
1571 1583 case NWAM_ACTIVATION_MODE_PRIORITIZED:
1572 1584 return (NWAM_SUCCESS);
1573 1585 }
1574 1586 return (NWAM_ENTITY_INVALID_VALUE);
1575 1587 }
1576 1588
1577 1589 /* ARGSUSED0 */
1578 1590 static nwam_error_t
1579 1591 valid_link_autopush(nwam_value_t value)
1580 1592 {
1581 1593 return (NWAM_SUCCESS);
1582 1594 }
1583 1595
1584 1596 static nwam_error_t
1585 1597 valid_ip_version(nwam_value_t value)
1586 1598 {
1587 1599 uint64_t *versions;
1588 1600 uint_t i, numvalues;
1589 1601
1590 1602 if (nwam_value_get_uint64_array(value, &versions, &numvalues)
1591 1603 != NWAM_SUCCESS)
1592 1604 return (NWAM_ENTITY_INVALID_VALUE);
1593 1605
1594 1606 for (i = 0; i < numvalues; i++) {
1595 1607 if (versions[i] != IPV4_VERSION &&
1596 1608 versions[i] != IPV6_VERSION)
1597 1609 return (NWAM_ENTITY_INVALID_VALUE);
1598 1610 }
1599 1611 return (NWAM_SUCCESS);
1600 1612 }
1601 1613
1602 1614 static nwam_error_t
1603 1615 valid_addrsrc_v4(nwam_value_t value)
1604 1616 {
1605 1617 uint64_t *addrsrc;
1606 1618 uint_t i, numvalues;
1607 1619
1608 1620 if (nwam_value_get_uint64_array(value, &addrsrc, &numvalues)
1609 1621 != NWAM_SUCCESS)
1610 1622 return (NWAM_ENTITY_INVALID_VALUE);
1611 1623
1612 1624 for (i = 0; i < numvalues; i++) {
1613 1625 if (addrsrc[i] != NWAM_ADDRSRC_DHCP &&
1614 1626 addrsrc[i] != NWAM_ADDRSRC_STATIC)
1615 1627 return (NWAM_ENTITY_INVALID_VALUE);
1616 1628 }
1617 1629 return (NWAM_SUCCESS);
1618 1630 }
1619 1631
1620 1632 static nwam_error_t
1621 1633 valid_addrsrc_v6(nwam_value_t value)
1622 1634 {
1623 1635 uint64_t *addrsrc;
1624 1636 uint_t i, numvalues;
1625 1637 boolean_t dhcp_found = B_FALSE, autoconf_found = B_FALSE;
1626 1638
1627 1639 if (nwam_value_get_uint64_array(value, &addrsrc, &numvalues)
1628 1640 != NWAM_SUCCESS)
1629 1641 return (NWAM_ENTITY_INVALID_VALUE);
1630 1642
1631 1643 for (i = 0; i < numvalues; i++) {
1632 1644 if (addrsrc[i] != NWAM_ADDRSRC_DHCP &&
1633 1645 addrsrc[i] != NWAM_ADDRSRC_STATIC &&
1634 1646 addrsrc[i] != NWAM_ADDRSRC_AUTOCONF)
1635 1647 return (NWAM_ENTITY_INVALID_VALUE);
1636 1648 if (addrsrc[i] == NWAM_ADDRSRC_DHCP)
1637 1649 dhcp_found = B_TRUE;
1638 1650 if (addrsrc[i] == NWAM_ADDRSRC_AUTOCONF)
1639 1651 autoconf_found = B_TRUE;
1640 1652 }
|
↓ open down ↓ |
1478 lines elided |
↑ open up ↑ |
1641 1653 /*
1642 1654 * DHCP and AUTOCONF need to be specified as v6 address sources
1643 1655 * since there is no way to switch them off in NWAM at present.
1644 1656 */
1645 1657 if (dhcp_found && autoconf_found)
1646 1658 return (NWAM_SUCCESS);
1647 1659 else
1648 1660 return (NWAM_ENTITY_INVALID_VALUE);
1649 1661 }
1650 1662
1663 +static nwam_error_t
1664 +valid_reqhost(nwam_value_t value)
1665 +{
1666 + char *hostname;
1667 +
1668 + if (nwam_value_get_string(value, &hostname) != NWAM_SUCCESS)
1669 + return (NWAM_ENTITY_INVALID_VALUE);
1670 + return (ipadm_is_valid_hostname(hostname) ? NWAM_SUCCESS
1671 + : NWAM_ENTITY_INVALID_VALUE);
1672 +}
1673 +
1651 1674 /* ARGSUSED0 */
1652 1675 static nwam_error_t
1653 1676 valid_link_mtu(nwam_value_t value)
1654 1677 {
1655 1678 return (NWAM_SUCCESS);
1656 1679 }
1657 1680
1658 1681 nwam_error_t
1659 1682 nwam_ncu_validate(nwam_ncu_handle_t ncuh, const char **errpropp)
1660 1683 {
1661 1684 return (nwam_validate(ncu_prop_table, ncuh, errpropp));
1662 1685 }
1663 1686
1664 1687 /*
1665 1688 * Given the ncu type and ncu class, return the list of properties that needs
1666 1689 * to be set. Note this list is a complete property list that includes both
1667 1690 * the required ones and the optional ones. Caller needs to free prop_list.
1668 1691 */
1669 1692 nwam_error_t
1670 1693 nwam_ncu_get_default_proplist(nwam_ncu_type_t type, nwam_ncu_class_t class,
1671 1694 const char ***prop_list, uint_t *numvalues)
1672 1695 {
1673 1696 uint64_t typeflags = nwam_ncu_type_to_flag(type);
1674 1697 uint64_t classflags = nwam_ncu_class_to_flag(class);
1675 1698
1676 1699 return (nwam_get_default_proplist(ncu_prop_table, typeflags,
1677 1700 classflags, prop_list, numvalues));
1678 1701 }
1679 1702
1680 1703 nwam_error_t
1681 1704 nwam_ncp_get_state(nwam_ncp_handle_t ncph, nwam_state_t *statep,
1682 1705 nwam_aux_state_t *auxp)
1683 1706 {
1684 1707 return (nwam_get_state(ncph->nwh_name, ncph, statep, auxp));
1685 1708 }
1686 1709
1687 1710 nwam_error_t
1688 1711 nwam_ncu_get_state(nwam_ncu_handle_t ncuh, nwam_state_t *statep,
1689 1712 nwam_aux_state_t *auxp)
1690 1713 {
1691 1714 nwam_ncp_handle_t ncph;
1692 1715 char *ncpname;
1693 1716 nwam_error_t err;
1694 1717
1695 1718 assert(ncuh != NULL);
1696 1719
1697 1720 if ((err = nwam_ncu_get_ncp(ncuh, &ncph)) != NWAM_SUCCESS)
1698 1721 return (err);
1699 1722 if (!nwam_ncp_is_active(ncph)) {
1700 1723 nwam_ncp_free(ncph);
1701 1724 return (NWAM_ENTITY_INVALID);
1702 1725 }
1703 1726 nwam_ncp_free(ncph);
1704 1727
1705 1728 if ((err = nwam_ncu_get_parent_ncp_name(ncuh, &ncpname))
1706 1729 != NWAM_SUCCESS)
1707 1730 return (err);
1708 1731
1709 1732 err = nwam_request_state(NWAM_OBJECT_TYPE_NCU, ncuh->nwh_name, ncpname,
1710 1733 statep, auxp);
1711 1734 free(ncpname);
1712 1735 return (err);
1713 1736 }
1714 1737
1715 1738 nwam_error_t
1716 1739 nwam_ncp_get_active_priority_group(int64_t *priorityp)
1717 1740 {
1718 1741 return (nwam_request_active_priority_group(priorityp));
1719 1742 }
|
↓ open down ↓ |
59 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX