Print this page
NEX-1785 Add IPMP related subcommands to ipadm(1M) man page
Reviewed by: Dan Fields <dan.fields@nexenta.com>
OS-161: Integrate IPMP changes
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/cmd/cmd-inet/usr.sbin/ipadm/ipadm.c
+++ new/usr/src/cmd/cmd-inet/usr.sbin/ipadm/ipadm.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.
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 (c) 2010, Oracle and/or its affiliates. All rights reserved.
24 24 * Copyright 2017 Nexenta Systems, Inc.
25 25 * Copyright 2017 Joyent, Inc.
26 26 * Copyright 2017 Gary Mills
27 27 * Copyright (c) 2016, Chris Fraire <cfraire@me.com>.
28 28 */
29 29
30 30 #include <arpa/inet.h>
|
↓ open down ↓ |
30 lines elided |
↑ open up ↑ |
31 31 #include <errno.h>
32 32 #include <getopt.h>
33 33 #include <inet/ip.h>
34 34 #include <inet/iptun.h>
35 35 #include <inet/tunables.h>
36 36 #include <libdladm.h>
37 37 #include <libdliptun.h>
38 38 #include <libdllink.h>
39 39 #include <libinetutil.h>
40 40 #include <libipadm.h>
41 +#include <ipmp.h>
42 +#include <ipmp_admin.h>
41 43 #include <locale.h>
42 44 #include <netdb.h>
43 45 #include <netinet/in.h>
44 46 #include <ofmt.h>
45 47 #include <stdarg.h>
46 48 #include <stddef.h>
47 49 #include <stdio.h>
48 50 #include <stdlib.h>
49 51 #include <string.h>
50 52 #include <strings.h>
51 53 #include <sys/stat.h>
52 54 #include <sys/types.h>
53 55 #include <zone.h>
56 +#include <sys/list.h>
57 +#include <stddef.h>
54 58
55 59 #define STR_UNKNOWN_VAL "?"
56 60 #define LIFC_DEFAULT (LIFC_NOXMIT | LIFC_TEMPORARY | LIFC_ALLZONES |\
57 61 LIFC_UNDER_IPMP)
58 62
63 +static void do_create_ip_common(int, char **, const char *, uint32_t);
64 +
59 65 typedef void cmdfunc_t(int, char **, const char *);
60 -static cmdfunc_t do_create_if, do_delete_if, do_enable_if, do_disable_if;
61 -static cmdfunc_t do_show_if;
62 -static cmdfunc_t do_set_prop, do_show_prop, do_set_ifprop;
63 -static cmdfunc_t do_show_ifprop, do_reset_ifprop, do_reset_prop;
64 -static cmdfunc_t do_show_addrprop, do_set_addrprop, do_reset_addrprop;
65 -static cmdfunc_t do_create_addr, do_delete_addr, do_show_addr;
66 -static cmdfunc_t do_enable_addr, do_disable_addr;
67 -static cmdfunc_t do_up_addr, do_down_addr, do_refresh_addr;
66 +static cmdfunc_t do_create_ip, do_delete_ip;
67 +static cmdfunc_t do_create_ipmp, do_add_ipmp, do_remove_ipmp;
68 +static cmdfunc_t do_disable_if, do_enable_if, do_show_if;
69 +static cmdfunc_t do_set_ifprop, do_reset_ifprop, do_show_ifprop;
70 +static cmdfunc_t do_create_addr, do_delete_addr, do_show_addr, do_refresh_addr;
71 +static cmdfunc_t do_disable_addr, do_enable_addr, do_down_addr, do_up_addr;
72 +static cmdfunc_t do_set_addrprop, do_reset_addrprop, do_show_addrprop;
73 +static cmdfunc_t do_set_prop, do_reset_prop, do_show_prop;
68 74
69 75 static void warn(const char *, ...);
70 76 static void die(const char *, ...);
71 77
72 78 typedef struct cmd {
73 79 char *c_name;
74 80 cmdfunc_t *c_fn;
75 81 const char *c_usage;
76 82 } cmd_t;
77 83
78 84 static cmd_t cmds[] = {
79 85 /* interface management related sub-commands */
80 - { "create-if", do_create_if, "\tcreate-if\t[-t] <interface>" },
81 - { "disable-if", do_disable_if, "\tdisable-if\t-t <interface>" },
82 - { "enable-if", do_enable_if, "\tenable-if\t-t <interface>" },
83 - { "delete-if", do_delete_if, "\tdelete-if\t<interface>" },
84 - { "show-if", do_show_if,
86 + { "create-ip", do_create_ip, "\tcreate-ip\t[-t] <interface>" },
87 + { "create-if", do_create_ip, NULL },
88 + { "delete-ip", do_delete_ip, "\tdelete-ip\t<interface>\n" },
89 + { "delete-if", do_delete_ip, NULL },
90 +
91 + { "create-ipmp", do_create_ipmp,
92 + "\tcreate-ipmp\t[-t] <ipmp-interface>" },
93 + { "delete-ipmp", do_delete_ip,
94 + "\tdelete-ipmp\t<ipmp-interface>" },
95 + { "add-ipmp", do_add_ipmp,
96 + "\tadd-ipmp\t[-t] -i <interface> ... "
97 + "<ipmp-interface>" },
98 + { "remove-ipmp", do_remove_ipmp,
99 + "\tremove-ipmp\t[-t] -i <interface> ... "
100 + "<ipmp-interface>\n" },
101 +
102 + { "disable-if", do_disable_if, "\tdisable-if\t-t <interface>" },
103 + { "enable-if", do_enable_if, "\tenable-if\t-t <interface>" },
104 + { "show-if", do_show_if,
85 105 "\tshow-if\t\t[[-p] -o <field>,...] [<interface>]\n" },
106 +
86 107 { "set-ifprop", do_set_ifprop,
87 108 "\tset-ifprop\t[-t] -p <prop>=<value[,...]> -m <protocol> "
88 109 "<interface>" },
89 110 { "reset-ifprop", do_reset_ifprop,
90 111 "\treset-ifprop\t[-t] -p <prop> -m <protocol> <interface>" },
91 112 { "show-ifprop", do_show_ifprop,
92 113 "\tshow-ifprop\t[[-c] -o <field>,...] [-p <prop>,...]\n"
93 - "\t\t\t[-m <protocol>] [interface]\n" },
114 + "\t\t\t[-m <protocol>] [interface]\n" },
94 115
95 116 /* address management related sub-commands */
96 117 { "create-addr", do_create_addr,
97 118 "\tcreate-addr\t[-t] -T static [-d] "
98 119 "-a{local|remote}=addr[/prefixlen]\n\t\t\t<addrobj>\n"
99 120 "\tcreate-addr\t[-t] -T dhcp [-w <seconds> | forever]\n"
100 121 "\t\t\t[-1] [-h <hostname>] <addrobj>\n"
101 122 "\tcreate-addr\t[-t] -T addrconf [-i interface-id]\n"
102 123 "\t\t\t[-p {stateful|stateless}={yes|no}] <addrobj>" },
103 - { "down-addr", do_down_addr, "\tdown-addr\t[-t] <addrobj>" },
104 - { "up-addr", do_up_addr, "\tup-addr\t\t[-t] <addrobj>" },
105 - { "disable-addr", do_disable_addr, "\tdisable-addr\t-t <addrobj>" },
106 - { "enable-addr", do_enable_addr, "\tenable-addr\t-t <addrobj>" },
107 - { "refresh-addr", do_refresh_addr, "\trefresh-addr\t[-i] <addrobj>" },
108 124 { "delete-addr", do_delete_addr, "\tdelete-addr\t[-r] <addrobj>" },
109 - { "show-addr", do_show_addr,
110 - "\tshow-addr\t[[-p] -o <field>,...] [<addrobj>]\n" },
125 + { "show-addr", do_show_addr,
126 + "\tshow-addr\t[[-p] -o <field>,...] [<addrobj>]" },
127 + { "refresh-addr", do_refresh_addr, "\trefresh-addr\t[-i] <addrobj>" },
128 + { "down-addr", do_down_addr, "\tdown-addr\t[-t] <addrobj>" },
129 + { "up-addr", do_up_addr, "\tup-addr\t\t[-t] <addrobj>" },
130 + { "disable-addr", do_disable_addr, "\tdisable-addr\t-t <addrobj>" },
131 + { "enable-addr", do_enable_addr, "\tenable-addr\t-t <addrobj>\n" },
132 +
111 133 { "set-addrprop", do_set_addrprop,
112 134 "\tset-addrprop\t[-t] -p <prop>=<value[,...]> <addrobj>" },
113 135 { "reset-addrprop", do_reset_addrprop,
114 136 "\treset-addrprop\t[-t] -p <prop> <addrobj>" },
115 137 { "show-addrprop", do_show_addrprop,
116 138 "\tshow-addrprop\t[[-c] -o <field>,...] [-p <prop>,...] "
117 139 "<addrobj>\n" },
118 140
119 141 /* protocol properties related sub-commands */
120 - { "set-prop", do_set_prop,
142 + { "set-prop", do_set_prop,
121 143 "\tset-prop\t[-t] -p <prop>[+|-]=<value[,...]> <protocol>" },
122 - { "reset-prop", do_reset_prop,
144 + { "reset-prop", do_reset_prop,
123 145 "\treset-prop\t[-t] -p <prop> <protocol>" },
124 - { "show-prop", do_show_prop,
146 + { "show-prop", do_show_prop,
125 147 "\tshow-prop\t[[-c] -o <field>,...] [-p <prop>,...]"
126 148 " [protocol]" }
127 149 };
128 150
129 151 static const struct option if_longopts[] = {
130 152 {"temporary", no_argument, 0, 't' },
131 153 { 0, 0, 0, 0 }
132 154 };
133 155
134 156 static const struct option show_prop_longopts[] = {
135 157 {"parsable", no_argument, 0, 'c' },
136 158 {"prop", required_argument, 0, 'p' },
137 159 {"output", required_argument, 0, 'o' },
138 160 { 0, 0, 0, 0 }
139 161 };
140 162
141 163 static const struct option show_ifprop_longopts[] = {
142 164 {"module", required_argument, 0, 'm' },
143 165 {"parsable", no_argument, 0, 'c' },
144 166 {"prop", required_argument, 0, 'p' },
145 167 {"output", required_argument, 0, 'o' },
146 168 { 0, 0, 0, 0 }
147 169 };
148 170
149 171 static const struct option set_prop_longopts[] = {
150 172 {"prop", required_argument, 0, 'p' },
151 173 {"temporary", no_argument, 0, 't' },
152 174 { 0, 0, 0, 0 }
153 175 };
154 176
155 177 static const struct option set_ifprop_longopts[] = {
156 178 {"module", required_argument, 0, 'm' },
157 179 {"prop", required_argument, 0, 'p' },
158 180 {"temporary", no_argument, 0, 't' },
159 181 { 0, 0, 0, 0 }
160 182 };
161 183
162 184 static const struct option addr_misc_longopts[] = {
163 185 {"inform", no_argument, 0, 'i' },
164 186 {"release", no_argument, 0, 'r' },
165 187 {"temporary", no_argument, 0, 't' },
166 188 { 0, 0, 0, 0 }
167 189 };
168 190
169 191 static const struct option addr_longopts[] = {
170 192 {"address", required_argument, 0, 'a' },
171 193 {"down", no_argument, 0, 'd' },
172 194 {"interface-id", required_argument, 0, 'i' },
173 195 {"primary", no_argument, 0, '1' },
174 196 {"prop", required_argument, 0, 'p' },
175 197 {"reqhost", required_argument, 0, 'h' },
176 198 {"temporary", no_argument, 0, 't' },
177 199 {"type", required_argument, 0, 'T' },
178 200 {"wait", required_argument, 0, 'w' },
179 201 { 0, 0, 0, 0 }
180 202 };
181 203
182 204 static const struct option show_addr_longopts[] = {
183 205 {"parsable", no_argument, 0, 'p' },
184 206 {"output", required_argument, 0, 'o' },
185 207 { 0, 0, 0, 0 }
186 208 };
187 209
188 210 static const struct option show_if_longopts[] = {
189 211 {"parsable", no_argument, 0, 'p' },
190 212 {"output", required_argument, 0, 'o' },
191 213 { 0, 0, 0, 0 }
192 214 };
193 215
194 216 /* callback functions to print show-* subcommands output */
195 217 static ofmt_cb_t print_prop_cb;
196 218 static ofmt_cb_t print_sa_cb;
197 219 static ofmt_cb_t print_si_cb;
198 220
199 221 /* structures for 'ipadm show-*' subcommands */
200 222 typedef enum {
201 223 IPADM_PROPFIELD_IFNAME,
202 224 IPADM_PROPFIELD_PROTO,
203 225 IPADM_PROPFIELD_ADDROBJ,
204 226 IPADM_PROPFIELD_PROPERTY,
205 227 IPADM_PROPFIELD_PERM,
206 228 IPADM_PROPFIELD_CURRENT,
207 229 IPADM_PROPFIELD_PERSISTENT,
208 230 IPADM_PROPFIELD_DEFAULT,
209 231 IPADM_PROPFIELD_POSSIBLE
210 232 } ipadm_propfield_index_t;
211 233
212 234 static ofmt_field_t intfprop_fields[] = {
213 235 /* name, field width, index, callback */
214 236 { "IFNAME", 12, IPADM_PROPFIELD_IFNAME, print_prop_cb},
215 237 { "PROPERTY", 16, IPADM_PROPFIELD_PROPERTY, print_prop_cb},
216 238 { "PROTO", 6, IPADM_PROPFIELD_PROTO, print_prop_cb},
217 239 { "PERM", 5, IPADM_PROPFIELD_PERM, print_prop_cb},
218 240 { "CURRENT", 11, IPADM_PROPFIELD_CURRENT, print_prop_cb},
219 241 { "PERSISTENT", 11, IPADM_PROPFIELD_PERSISTENT, print_prop_cb},
220 242 { "DEFAULT", 11, IPADM_PROPFIELD_DEFAULT, print_prop_cb},
221 243 { "POSSIBLE", 16, IPADM_PROPFIELD_POSSIBLE, print_prop_cb},
222 244 { NULL, 0, 0, NULL}
223 245 };
224 246
225 247
226 248 static ofmt_field_t modprop_fields[] = {
227 249 /* name, field width, index, callback */
228 250 { "PROTO", 6, IPADM_PROPFIELD_PROTO, print_prop_cb},
229 251 { "PROPERTY", 22, IPADM_PROPFIELD_PROPERTY, print_prop_cb},
230 252 { "PERM", 5, IPADM_PROPFIELD_PERM, print_prop_cb},
231 253 { "CURRENT", 13, IPADM_PROPFIELD_CURRENT, print_prop_cb},
232 254 { "PERSISTENT", 13, IPADM_PROPFIELD_PERSISTENT, print_prop_cb},
233 255 { "DEFAULT", 13, IPADM_PROPFIELD_DEFAULT, print_prop_cb},
234 256 { "POSSIBLE", 15, IPADM_PROPFIELD_POSSIBLE, print_prop_cb},
235 257 { NULL, 0, 0, NULL}
236 258 };
237 259
238 260 static ofmt_field_t addrprop_fields[] = {
239 261 /* name, field width, index, callback */
240 262 { "ADDROBJ", 18, IPADM_PROPFIELD_ADDROBJ, print_prop_cb},
241 263 { "PROPERTY", 11, IPADM_PROPFIELD_PROPERTY, print_prop_cb},
242 264 { "PERM", 5, IPADM_PROPFIELD_PERM, print_prop_cb},
243 265 { "CURRENT", 16, IPADM_PROPFIELD_CURRENT, print_prop_cb},
244 266 { "PERSISTENT", 16, IPADM_PROPFIELD_PERSISTENT, print_prop_cb},
245 267 { "DEFAULT", 16, IPADM_PROPFIELD_DEFAULT, print_prop_cb},
246 268 { "POSSIBLE", 15, IPADM_PROPFIELD_POSSIBLE, print_prop_cb},
247 269 { NULL, 0, 0, NULL}
248 270 };
249 271
250 272 typedef struct show_prop_state {
251 273 char sps_ifname[LIFNAMSIZ];
252 274 char sps_aobjname[IPADM_AOBJSIZ];
253 275 const char *sps_pname;
254 276 uint_t sps_proto;
255 277 char *sps_propval;
256 278 nvlist_t *sps_proplist;
257 279 boolean_t sps_parsable;
258 280 boolean_t sps_addrprop;
259 281 boolean_t sps_ifprop;
260 282 boolean_t sps_modprop;
261 283 ipadm_status_t sps_status;
262 284 ipadm_status_t sps_retstatus;
263 285 ofmt_handle_t sps_ofmt;
264 286 } show_prop_state_t;
265 287
266 288 typedef struct show_addr_state {
267 289 boolean_t sa_parsable;
268 290 boolean_t sa_persist;
269 291 ofmt_handle_t sa_ofmt;
270 292 } show_addr_state_t;
271 293
272 294 typedef struct show_if_state {
273 295 boolean_t si_parsable;
274 296 ofmt_handle_t si_ofmt;
275 297 } show_if_state_t;
276 298
277 299 typedef struct show_addr_args_s {
278 300 show_addr_state_t *sa_state;
279 301 ipadm_addr_info_t *sa_info;
280 302 } show_addr_args_t;
281 303
282 304 typedef struct show_if_args_s {
283 305 show_if_state_t *si_state;
284 306 ipadm_if_info_t *si_info;
285 307 } show_if_args_t;
286 308
287 309 typedef enum {
|
↓ open down ↓ |
153 lines elided |
↑ open up ↑ |
288 310 SA_ADDROBJ,
289 311 SA_TYPE,
290 312 SA_STATE,
291 313 SA_CURRENT,
292 314 SA_PERSISTENT,
293 315 SA_ADDR
294 316 } sa_field_index_t;
295 317
296 318 typedef enum {
297 319 SI_IFNAME,
320 + SI_IFCLASS,
298 321 SI_STATE,
299 322 SI_CURRENT,
300 323 SI_PERSISTENT
301 324 } si_field_index_t;
302 325
303 326 static ofmt_field_t show_addr_fields[] = {
304 327 /* name, field width, id, callback */
305 328 { "ADDROBJ", 18, SA_ADDROBJ, print_sa_cb},
306 329 { "TYPE", 9, SA_TYPE, print_sa_cb},
307 330 { "STATE", 13, SA_STATE, print_sa_cb},
308 331 { "CURRENT", 8, SA_CURRENT, print_sa_cb},
309 332 { "PERSISTENT", 11, SA_PERSISTENT, print_sa_cb},
310 333 { "ADDR", 46, SA_ADDR, print_sa_cb},
311 334 { NULL, 0, 0, NULL}
312 335 };
313 336
314 337 static ofmt_field_t show_if_fields[] = {
315 338 /* name, field width, id, callback */
316 339 { "IFNAME", 11, SI_IFNAME, print_si_cb},
340 +{ "CLASS", 10, SI_IFCLASS, print_si_cb},
317 341 { "STATE", 9, SI_STATE, print_si_cb},
318 342 { "CURRENT", 13, SI_CURRENT, print_si_cb},
319 343 { "PERSISTENT", 11, SI_PERSISTENT, print_si_cb},
320 344 { NULL, 0, 0, NULL}
321 345 };
322 346
323 347 #define IPADM_ALL_BITS ((uint_t)-1)
324 348 typedef struct intf_mask {
325 349 char *name;
326 350 uint64_t bits;
327 351 uint64_t mask;
328 352 } fmask_t;
329 353
354 +typedef enum {
355 + IPMP_ADD_MEMBER,
356 + IPMP_REMOVE_MEMBER
357 +} ipmp_action_t;
358 +
330 359 /*
331 360 * Handle to libipadm. Opened in main() before the sub-command specific
332 361 * function is called and is closed before the program exits.
333 362 */
334 363 ipadm_handle_t iph = NULL;
335 364
336 365 /*
337 366 * Opaque ipadm address object. Used by all the address management subcommands.
338 367 */
339 368 ipadm_addrobj_t ipaddr = NULL;
340 369
341 370 static char *progname;
342 371
343 372 static void die(const char *, ...);
344 373 static void die_opterr(int, int, const char *);
345 374 static void warn_ipadmerr(ipadm_status_t, const char *, ...);
346 375 static void ipadm_check_propstr(const char *, boolean_t, const char *);
347 376 static void process_misc_addrargs(int, char **, const char *, int *,
348 377 uint32_t *);
378 +static void do_action_ipmp(int, char **, const char *, ipmp_action_t);
349 379
350 380 static void
351 381 usage(void)
352 382 {
353 383 int i;
354 384 cmd_t *cmdp;
355 385
356 386 (void) fprintf(stderr,
357 387 gettext("usage: ipadm <subcommand> <args> ...\n"));
358 388 for (i = 0; i < sizeof (cmds) / sizeof (cmds[0]); i++) {
359 389 cmdp = &cmds[i];
360 390 if (cmdp->c_usage != NULL)
361 391 (void) fprintf(stderr, "%s\n", gettext(cmdp->c_usage));
362 392 }
363 393
364 394 ipadm_destroy_addrobj(ipaddr);
365 395 ipadm_close(iph);
366 396 exit(1);
367 397 }
368 398
369 399 int
370 400 main(int argc, char *argv[])
371 401 {
372 402 int i;
373 403 cmd_t *cmdp;
374 404 ipadm_status_t status;
375 405
376 406 (void) setlocale(LC_ALL, "");
377 407 (void) textdomain(TEXT_DOMAIN);
378 408
379 409 if ((progname = strrchr(argv[0], '/')) == NULL)
380 410 progname = argv[0];
381 411 else
382 412 progname++;
383 413
384 414 if (argc < 2)
385 415 usage();
386 416
387 417 status = ipadm_open(&iph, 0);
388 418 if (status != IPADM_SUCCESS) {
389 419 die("Could not open handle to library - %s",
390 420 ipadm_status2str(status));
391 421 }
392 422
393 423 for (i = 0; i < sizeof (cmds) / sizeof (cmds[0]); i++) {
394 424 cmdp = &cmds[i];
395 425 if (strcmp(argv[1], cmdp->c_name) == 0) {
396 426 cmdp->c_fn(argc - 1, &argv[1], gettext(cmdp->c_usage));
397 427 ipadm_destroy_addrobj(ipaddr);
398 428 ipadm_close(iph);
399 429 exit(0);
400 430 }
|
↓ open down ↓ |
42 lines elided |
↑ open up ↑ |
401 431 }
402 432
403 433 (void) fprintf(stderr, gettext("%s: unknown subcommand '%s'\n"),
404 434 progname, argv[1]);
405 435 usage();
406 436
407 437 return (0);
408 438 }
409 439
410 440 /*
411 - * Create an IP interface for which no saved configuration exists in the
412 - * persistent store.
441 + * Create regular IP interface or IPMP group interface
413 442 */
414 443 static void
415 -do_create_if(int argc, char *argv[], const char *use)
444 +do_create_ip_common(int argc, char *argv[], const char *use, uint32_t flags)
416 445 {
417 446 ipadm_status_t status;
418 447 int option;
419 - uint32_t flags = IPADM_OPT_PERSIST|IPADM_OPT_ACTIVE;
420 448
421 449 opterr = 0;
422 - while ((option = getopt_long(argc, argv, ":t", if_longopts,
423 - NULL)) != -1) {
450 + while ((option = getopt_long(argc, argv,
451 + ":t", if_longopts, NULL)) != -1) {
424 452 switch (option) {
425 453 case 't':
426 454 /*
427 455 * "ifconfig" mode - plumb interface, but do not
428 456 * restore settings that may exist in db.
429 457 */
430 458 flags &= ~IPADM_OPT_PERSIST;
431 459 break;
432 460 default:
433 461 die_opterr(optopt, option, use);
434 462 }
435 463 }
436 - if (optind != (argc - 1))
437 - die("Usage: %s", use);
464 + if (optind != (argc - 1)) {
465 + if (use != NULL)
466 + die("usage: %s", use);
467 + else
468 + die(NULL);
469 + }
438 470 status = ipadm_create_if(iph, argv[optind], AF_UNSPEC, flags);
439 471 if (status != IPADM_SUCCESS) {
440 472 die("Could not create %s : %s",
441 473 argv[optind], ipadm_status2str(status));
442 474 }
443 475 }
444 476
445 477 /*
478 + * Create an IPMP group interface for which no saved configuration
479 + * exists in the persistent store.
480 + */
481 +static void
482 +do_create_ipmp(int argc, char *argv[], const char *use)
483 +{
484 + ipmp_handle_t ipmp_handle;
485 + int retval;
486 + uint32_t flags = IPADM_OPT_PERSIST | IPADM_OPT_ACTIVE | IPADM_OPT_IPMP;
487 +
488 + retval = ipmp_open(&ipmp_handle);
489 + if (retval != IPMP_SUCCESS) {
490 + die("Could not create IPMP handle: %s",
491 + ipadm_status2str(retval));
492 + }
493 +
494 + retval = ipmp_ping_daemon(ipmp_handle);
495 + ipmp_close(ipmp_handle);
496 +
497 + if (retval != IPMP_SUCCESS) {
498 + die("Cannot ping in.mpathd: %s", ipmp_errmsg(retval));
499 + }
500 +
501 + do_create_ip_common(argc, argv, use, flags);
502 +}
503 +
504 +static void
505 +do_add_ipmp(int argc, char *argv[], const char *use)
506 +{
507 + do_action_ipmp(argc, argv, use, IPMP_ADD_MEMBER);
508 +}
509 +
510 +static void
511 +do_remove_ipmp(int argc, char *argv[], const char *use)
512 +{
513 + do_action_ipmp(argc, argv, use, IPMP_REMOVE_MEMBER);
514 +}
515 +
516 +static void
517 +do_action_ipmp(int argc, char *argv[], const char *use,
518 + ipmp_action_t action)
519 +{
520 + int option;
521 + ipadm_status_t status;
522 + ipadm_ipmp_members_t members;
523 + ipadm_ipmp_member_t *ipmp_member;
524 + uint32_t flags = IPADM_OPT_PERSIST | IPADM_OPT_ACTIVE;
525 +
526 + list_create(&members, sizeof (ipadm_ipmp_member_t),
527 + offsetof(ipadm_ipmp_member_t, node));
528 +
529 + opterr = 0;
530 + while ((option = getopt_long(argc, argv,
531 + ":ti:", if_longopts, NULL)) != -1) {
532 + switch (option) {
533 + case 't':
534 + flags &= ~IPADM_OPT_PERSIST;
535 + break;
536 + case 'i':
537 + if ((ipmp_member = calloc(1,
538 + sizeof (ipadm_ipmp_member_t))) == NULL)
539 + die("insufficient memory");
540 +
541 + if (strlcpy(ipmp_member->if_name,
542 + optarg, sizeof (ipmp_member->if_name)) >= LIFNAMSIZ)
543 + die("Incorrect length of interface"
544 + "name: %s", optarg);
545 +
546 + list_insert_tail(&members, ipmp_member);
547 + break;
548 + default:
549 + die_opterr(optopt, option, use);
550 + }
551 + }
552 +
553 + if (optind != (argc - 1))
554 + die("Usage: %s", use);
555 +
556 + while ((ipmp_member = list_remove_head(&members)) != NULL) {
557 + switch (action) {
558 + case IPMP_ADD_MEMBER:
559 + if ((status = ipadm_add_ipmp_member(iph,
560 + argv[optind], ipmp_member->if_name, flags))
561 + != IPADM_SUCCESS)
562 + die("Cannot add interface '%s' to "
563 + "IPMP interface '%s': %s",
564 + ipmp_member->if_name, argv[optind],
565 + ipadm_status2str(status));
566 + break;
567 + case IPMP_REMOVE_MEMBER:
568 + if ((status = ipadm_remove_ipmp_member(iph,
569 + argv[optind], ipmp_member->if_name, flags))
570 + != IPADM_SUCCESS)
571 + die("Cannot remove interface '%s' from "
572 + "IPMP interface '%s': %s",
573 + ipmp_member->if_name, argv[optind],
574 + ipadm_status2str(status));
575 + break;
576 + }
577 +
578 + free(ipmp_member);
579 + }
580 +
581 + list_destroy(&members);
582 +}
583 +
584 +/*
585 + * Create an IP interface for which no saved configuration exists in the
586 + * persistent store.
587 + */
588 +static void
589 +do_create_ip(int argc, char *argv[], const char *use)
590 +{
591 + do_create_ip_common(argc, argv, use,
592 + IPADM_OPT_PERSIST | IPADM_OPT_ACTIVE);
593 +}
594 +
595 +/*
446 596 * Enable an IP interface based on the persistent configuration for
447 597 * that interface.
448 598 */
449 599 static void
450 600 do_enable_if(int argc, char *argv[], const char *use)
451 601 {
452 602 ipadm_status_t status;
453 603 int index;
454 604 uint32_t flags = IPADM_OPT_ACTIVE|IPADM_OPT_PERSIST;
455 605
456 606 process_misc_addrargs(argc, argv, use, &index, &flags);
457 607 if (flags & IPADM_OPT_PERSIST)
458 608 die("persistent operation not supported for enable-if");
459 609 status = ipadm_enable_if(iph, argv[index], flags);
460 610 if (status == IPADM_ALL_ADDRS_NOT_ENABLED) {
461 611 warn_ipadmerr(status, "");
|
↓ open down ↓ |
6 lines elided |
↑ open up ↑ |
462 612 } else if (status != IPADM_SUCCESS) {
463 613 die("Could not enable %s : %s",
464 614 argv[optind], ipadm_status2str(status));
465 615 }
466 616 }
467 617
468 618 /*
469 619 * Remove an IP interface from both active and persistent configuration.
470 620 */
471 621 static void
472 -do_delete_if(int argc, char *argv[], const char *use)
622 +do_delete_ip(int argc, char *argv[], const char *use)
473 623 {
474 624 ipadm_status_t status;
475 625 uint32_t flags = IPADM_OPT_ACTIVE|IPADM_OPT_PERSIST;
476 626
477 627 if (argc != 2)
478 628 die("Usage: %s", use);
479 629
480 630 status = ipadm_delete_if(iph, argv[1], AF_UNSPEC, flags);
481 631 if (status != IPADM_SUCCESS) {
482 632 die("Could not delete %s: %s",
483 633 argv[optind], ipadm_status2str(status));
484 634 }
485 635 }
486 636
487 637 /*
488 638 * Disable an IP interface by removing it from active configuration.
489 639 */
490 640 static void
491 641 do_disable_if(int argc, char *argv[], const char *use)
492 642 {
493 643 ipadm_status_t status;
494 644 int index;
495 645 uint32_t flags = IPADM_OPT_ACTIVE|IPADM_OPT_PERSIST;
496 646
497 647 process_misc_addrargs(argc, argv, use, &index, &flags);
498 648 if (flags & IPADM_OPT_PERSIST)
499 649 die("persistent operation not supported for disable-if");
500 650 status = ipadm_disable_if(iph, argv[index], flags);
501 651 if (status != IPADM_SUCCESS) {
502 652 die("Could not disable %s: %s",
503 653 argv[optind], ipadm_status2str(status));
504 654 }
505 655 }
506 656
507 657 /*
508 658 * Print individual columns for the show-*prop subcommands.
509 659 */
510 660 static void
511 661 print_prop(show_prop_state_t *statep, uint_t flags, char *buf, size_t bufsize)
512 662 {
513 663 const char *prop_name = statep->sps_pname;
514 664 char *ifname = statep->sps_ifname;
515 665 char *propval = statep->sps_propval;
516 666 uint_t proto = statep->sps_proto;
517 667 size_t propsize = MAXPROPVALLEN;
518 668 ipadm_status_t status;
519 669
520 670 if (statep->sps_ifprop) {
521 671 status = ipadm_get_ifprop(iph, ifname, prop_name, propval,
522 672 &propsize, proto, flags);
523 673 } else if (statep->sps_modprop) {
524 674 status = ipadm_get_prop(iph, prop_name, propval, &propsize,
525 675 proto, flags);
526 676 } else {
527 677 status = ipadm_get_addrprop(iph, prop_name, propval, &propsize,
528 678 statep->sps_aobjname, flags);
529 679 }
530 680
531 681 if (status != IPADM_SUCCESS) {
532 682 if ((status == IPADM_NOTFOUND && (flags & IPADM_OPT_PERSIST)) ||
533 683 status == IPADM_ENXIO) {
534 684 propval[0] = '\0';
535 685 goto cont;
536 686 }
537 687 statep->sps_status = status;
538 688 statep->sps_retstatus = status;
539 689 return;
540 690 }
541 691 cont:
542 692 statep->sps_status = IPADM_SUCCESS;
543 693 (void) snprintf(buf, bufsize, "%s", propval);
544 694 }
545 695
546 696 /*
547 697 * Callback function for show-*prop subcommands.
548 698 */
549 699 static boolean_t
550 700 print_prop_cb(ofmt_arg_t *ofarg, char *buf, size_t bufsize)
551 701 {
552 702 show_prop_state_t *statep = ofarg->ofmt_cbarg;
553 703 const char *propname = statep->sps_pname;
554 704 uint_t proto = statep->sps_proto;
555 705 boolean_t cont = _B_TRUE;
556 706
557 707 /*
558 708 * Fail retrieving remaining fields, if you fail
559 709 * to retrieve a field.
560 710 */
561 711 if (statep->sps_status != IPADM_SUCCESS)
562 712 return (_B_FALSE);
563 713
564 714 switch (ofarg->ofmt_id) {
565 715 case IPADM_PROPFIELD_IFNAME:
566 716 (void) snprintf(buf, bufsize, "%s", statep->sps_ifname);
567 717 break;
568 718 case IPADM_PROPFIELD_PROTO:
569 719 (void) snprintf(buf, bufsize, "%s", ipadm_proto2str(proto));
570 720 break;
571 721 case IPADM_PROPFIELD_ADDROBJ:
572 722 (void) snprintf(buf, bufsize, "%s", statep->sps_aobjname);
573 723 break;
574 724 case IPADM_PROPFIELD_PROPERTY:
575 725 (void) snprintf(buf, bufsize, "%s", propname);
576 726 break;
577 727 case IPADM_PROPFIELD_PERM:
578 728 print_prop(statep, IPADM_OPT_PERM, buf, bufsize);
579 729 break;
580 730 case IPADM_PROPFIELD_CURRENT:
581 731 print_prop(statep, IPADM_OPT_ACTIVE, buf, bufsize);
582 732 break;
583 733 case IPADM_PROPFIELD_PERSISTENT:
584 734 print_prop(statep, IPADM_OPT_PERSIST, buf, bufsize);
585 735 break;
586 736 case IPADM_PROPFIELD_DEFAULT:
587 737 print_prop(statep, IPADM_OPT_DEFAULT, buf, bufsize);
588 738 break;
589 739 case IPADM_PROPFIELD_POSSIBLE:
590 740 print_prop(statep, IPADM_OPT_POSSIBLE, buf, bufsize);
591 741 break;
592 742 }
593 743 if (statep->sps_status != IPADM_SUCCESS)
594 744 cont = _B_FALSE;
595 745 return (cont);
596 746 }
597 747
598 748 /*
599 749 * Callback function called by the property walker (ipadm_walk_prop() or
600 750 * ipadm_walk_proptbl()), for every matched property. This function in turn
601 751 * calls ofmt_print() to print property information.
602 752 */
603 753 boolean_t
604 754 show_property(void *arg, const char *pname, uint_t proto)
605 755 {
606 756 show_prop_state_t *statep = arg;
607 757
608 758 statep->sps_pname = pname;
609 759 statep->sps_proto = proto;
610 760 statep->sps_status = IPADM_SUCCESS;
611 761 ofmt_print(statep->sps_ofmt, arg);
612 762
613 763 /*
614 764 * if an object is not found or operation is not supported then
615 765 * stop the walker.
616 766 */
617 767 if (statep->sps_status == IPADM_NOTFOUND ||
618 768 statep->sps_status == IPADM_NOTSUP)
619 769 return (_B_FALSE);
620 770 return (_B_TRUE);
621 771 }
622 772
623 773 /*
624 774 * Properties to be displayed is in `statep->sps_proplist'. If it is NULL,
625 775 * for all the properties for the specified object, display relevant
626 776 * information. Otherwise, for the selected property set, display relevant
627 777 * information
628 778 */
629 779 static void
630 780 show_properties(void *arg, int prop_class)
631 781 {
632 782 show_prop_state_t *statep = arg;
633 783 nvlist_t *nvl = statep->sps_proplist;
634 784 uint_t proto = statep->sps_proto;
635 785 nvpair_t *curr_nvp;
636 786 char *buf, *name;
637 787 ipadm_status_t status;
638 788
639 789 /* allocate sufficient buffer to hold a property value */
640 790 if ((buf = malloc(MAXPROPVALLEN)) == NULL)
641 791 die("insufficient memory");
642 792 statep->sps_propval = buf;
643 793
644 794 /* if no properties were specified, display all the properties */
645 795 if (nvl == NULL) {
646 796 (void) ipadm_walk_proptbl(proto, prop_class, show_property,
647 797 statep);
648 798 } else {
649 799 for (curr_nvp = nvlist_next_nvpair(nvl, NULL); curr_nvp;
650 800 curr_nvp = nvlist_next_nvpair(nvl, curr_nvp)) {
651 801 name = nvpair_name(curr_nvp);
652 802 status = ipadm_walk_prop(name, proto, prop_class,
653 803 show_property, statep);
654 804 if (status == IPADM_PROP_UNKNOWN)
655 805 (void) show_property(statep, name, proto);
656 806 }
657 807 }
658 808
659 809 free(buf);
660 810 }
661 811
662 812 /*
663 813 * Display information for all or specific interface properties, either for a
664 814 * given interface or for all the interfaces in the system.
665 815 */
666 816 static void
667 817 do_show_ifprop(int argc, char **argv, const char *use)
668 818 {
669 819 int option;
670 820 nvlist_t *proplist = NULL;
671 821 char *fields_str = NULL;
672 822 char *ifname;
673 823 ofmt_handle_t ofmt;
674 824 ofmt_status_t oferr;
675 825 uint_t ofmtflags = 0;
676 826 uint_t proto;
677 827 boolean_t m_arg = _B_FALSE;
678 828 char *protostr;
679 829 ipadm_if_info_t *ifinfo, *ifp;
680 830 ipadm_status_t status;
681 831 show_prop_state_t state;
682 832
683 833 opterr = 0;
684 834 bzero(&state, sizeof (state));
685 835 state.sps_propval = NULL;
686 836 state.sps_parsable = _B_FALSE;
687 837 state.sps_ifprop = _B_TRUE;
688 838 state.sps_status = state.sps_retstatus = IPADM_SUCCESS;
689 839 while ((option = getopt_long(argc, argv, ":p:m:co:",
690 840 show_ifprop_longopts, NULL)) != -1) {
691 841 switch (option) {
692 842 case 'p':
693 843 if (ipadm_str2nvlist(optarg, &proplist,
694 844 IPADM_NORVAL) != 0)
695 845 die("invalid interface properties specified");
696 846 break;
697 847 case 'c':
698 848 state.sps_parsable = _B_TRUE;
699 849 break;
700 850 case 'o':
701 851 fields_str = optarg;
702 852 break;
703 853 case 'm':
704 854 if (m_arg)
705 855 die("cannot specify more than one -m");
706 856 m_arg = _B_TRUE;
707 857 protostr = optarg;
708 858 break;
709 859 default:
710 860 die_opterr(optopt, option, use);
711 861 break;
712 862 }
713 863 }
714 864
715 865 if (optind == argc - 1)
716 866 ifname = argv[optind];
717 867 else if (optind != argc)
718 868 die("Usage: %s", use);
719 869 else
720 870 ifname = NULL;
721 871
722 872 if (!m_arg)
723 873 protostr = "ip";
724 874 if ((proto = ipadm_str2proto(protostr)) == MOD_PROTO_NONE)
725 875 die("invalid protocol '%s' specified", protostr);
726 876
727 877 state.sps_proto = proto;
728 878 state.sps_proplist = proplist;
729 879
730 880 if (state.sps_parsable)
731 881 ofmtflags |= OFMT_PARSABLE;
732 882 oferr = ofmt_open(fields_str, intfprop_fields, ofmtflags, 0, &ofmt);
733 883 ofmt_check(oferr, state.sps_parsable, ofmt, die, warn);
734 884 state.sps_ofmt = ofmt;
735 885
736 886 /* retrieve interface(s) and print the properties */
737 887 status = ipadm_if_info(iph, ifname, &ifinfo, 0, LIFC_DEFAULT);
738 888 if (ifname != NULL && status == IPADM_ENXIO)
739 889 die("no such object '%s': %s", ifname,
740 890 ipadm_status2str(status));
741 891 if (status != IPADM_SUCCESS)
742 892 die("Error retrieving interface(s): %s",
743 893 ipadm_status2str(status));
744 894 for (ifp = ifinfo; ifp; ifp = ifp->ifi_next) {
745 895 (void) strlcpy(state.sps_ifname, ifp->ifi_name, LIFNAMSIZ);
746 896 state.sps_proto = proto;
747 897 show_properties(&state, IPADMPROP_CLASS_IF);
748 898 }
749 899 if (ifinfo)
750 900 ipadm_free_if_info(ifinfo);
751 901
752 902 nvlist_free(proplist);
753 903 ofmt_close(ofmt);
754 904
755 905 if (state.sps_retstatus != IPADM_SUCCESS) {
756 906 ipadm_close(iph);
757 907 exit(EXIT_FAILURE);
758 908 }
759 909 }
760 910
761 911 /*
762 912 * set/reset the interface property for a given interface.
763 913 */
764 914 static void
765 915 set_ifprop(int argc, char **argv, boolean_t reset, const char *use)
766 916 {
767 917 int option;
768 918 ipadm_status_t status = IPADM_SUCCESS;
769 919 boolean_t p_arg = _B_FALSE;
770 920 boolean_t m_arg = _B_FALSE;
771 921 char *ifname, *nv, *protostr;
772 922 char *prop_name, *prop_val;
773 923 uint_t flags = IPADM_OPT_PERSIST;
774 924 uint_t proto;
775 925
776 926 opterr = 0;
777 927 while ((option = getopt_long(argc, argv, ":m:p:t",
778 928 set_ifprop_longopts, NULL)) != -1) {
779 929 switch (option) {
780 930 case 'p':
781 931 if (p_arg)
782 932 die("-p must be specified once only");
783 933 p_arg = _B_TRUE;
784 934
785 935 ipadm_check_propstr(optarg, reset, use);
786 936 nv = optarg;
787 937 break;
788 938 case 'm':
789 939 if (m_arg)
790 940 die("-m must be specified once only");
791 941 m_arg = _B_TRUE;
792 942 protostr = optarg;
793 943 break;
794 944 case 't':
795 945 flags &= ~IPADM_OPT_PERSIST;
796 946 break;
797 947 default:
798 948 die_opterr(optopt, option, use);
799 949 }
800 950 }
801 951
802 952 if (!m_arg || !p_arg || optind != argc - 1)
803 953 die("Usage: %s", use);
804 954
805 955 ifname = argv[optind];
806 956
807 957 prop_name = nv;
808 958 prop_val = strchr(nv, '=');
809 959 if (prop_val != NULL)
810 960 *prop_val++ = '\0';
811 961
812 962 if ((proto = ipadm_str2proto(protostr)) == MOD_PROTO_NONE)
813 963 die("invalid protocol '%s' specified", protostr);
814 964
815 965 if (reset)
816 966 flags |= IPADM_OPT_DEFAULT;
817 967 else
818 968 flags |= IPADM_OPT_ACTIVE;
819 969 status = ipadm_set_ifprop(iph, ifname, prop_name, prop_val, proto,
820 970 flags);
821 971
822 972 done:
823 973 if (status != IPADM_SUCCESS) {
824 974 if (reset)
825 975 die("reset-ifprop: %s: %s",
826 976 prop_name, ipadm_status2str(status));
827 977 else
828 978 die("set-ifprop: %s: %s",
829 979 prop_name, ipadm_status2str(status));
830 980 }
831 981 }
832 982
833 983 static void
834 984 do_set_ifprop(int argc, char **argv, const char *use)
835 985 {
836 986 set_ifprop(argc, argv, _B_FALSE, use);
837 987 }
838 988
839 989 static void
840 990 do_reset_ifprop(int argc, char **argv, const char *use)
841 991 {
842 992 set_ifprop(argc, argv, _B_TRUE, use);
843 993 }
844 994
845 995 /*
846 996 * Display information for all or specific protocol properties, either for a
847 997 * given protocol or for supported protocols (IP/IPv4/IPv6/TCP/UDP/SCTP)
848 998 */
849 999 static void
850 1000 do_show_prop(int argc, char **argv, const char *use)
851 1001 {
852 1002 char option;
853 1003 nvlist_t *proplist = NULL;
854 1004 char *fields_str = NULL;
855 1005 char *protostr;
856 1006 show_prop_state_t state;
857 1007 ofmt_handle_t ofmt;
858 1008 ofmt_status_t oferr;
859 1009 uint_t ofmtflags = 0;
860 1010 uint_t proto;
861 1011 boolean_t p_arg = _B_FALSE;
862 1012
863 1013 opterr = 0;
864 1014 bzero(&state, sizeof (state));
865 1015 state.sps_propval = NULL;
866 1016 state.sps_parsable = _B_FALSE;
867 1017 state.sps_modprop = _B_TRUE;
868 1018 state.sps_status = state.sps_retstatus = IPADM_SUCCESS;
869 1019 while ((option = getopt_long(argc, argv, ":p:co:", show_prop_longopts,
870 1020 NULL)) != -1) {
871 1021 switch (option) {
872 1022 case 'p':
873 1023 if (p_arg)
874 1024 die("-p must be specified once only");
875 1025 p_arg = _B_TRUE;
876 1026 if (ipadm_str2nvlist(optarg, &proplist,
877 1027 IPADM_NORVAL) != 0)
878 1028 die("invalid protocol properties specified");
879 1029 break;
880 1030 case 'c':
881 1031 state.sps_parsable = _B_TRUE;
882 1032 break;
883 1033 case 'o':
884 1034 fields_str = optarg;
885 1035 break;
886 1036 default:
887 1037 die_opterr(optopt, option, use);
888 1038 break;
889 1039 }
890 1040 }
891 1041 if (optind == argc - 1) {
892 1042 protostr = argv[optind];
893 1043 if ((proto = ipadm_str2proto(protostr)) == MOD_PROTO_NONE)
894 1044 die("invalid protocol '%s' specified", protostr);
895 1045 state.sps_proto = proto;
896 1046 } else if (optind != argc) {
897 1047 die("Usage: %s", use);
898 1048 } else {
899 1049 if (p_arg)
900 1050 die("protocol must be specified when "
901 1051 "property name is used");
902 1052 state.sps_proto = MOD_PROTO_NONE;
903 1053 }
904 1054
905 1055 state.sps_proplist = proplist;
906 1056
907 1057 if (state.sps_parsable)
908 1058 ofmtflags |= OFMT_PARSABLE;
909 1059 else
910 1060 ofmtflags |= OFMT_WRAP;
911 1061 oferr = ofmt_open(fields_str, modprop_fields, ofmtflags, 0, &ofmt);
912 1062 ofmt_check(oferr, state.sps_parsable, ofmt, die, warn);
913 1063 state.sps_ofmt = ofmt;
914 1064
915 1065 /* handles all the errors */
916 1066 show_properties(&state, IPADMPROP_CLASS_MODULE);
917 1067
918 1068 nvlist_free(proplist);
919 1069 ofmt_close(ofmt);
920 1070
921 1071 if (state.sps_retstatus != IPADM_SUCCESS) {
922 1072 ipadm_close(iph);
923 1073 exit(EXIT_FAILURE);
924 1074 }
925 1075 }
926 1076
927 1077 /*
928 1078 * Checks to see if there are any modifiers, + or -. If there are modifiers
929 1079 * then sets IPADM_OPT_APPEND or IPADM_OPT_REMOVE, accordingly.
930 1080 */
931 1081 static void
932 1082 parse_modifiers(const char *pstr, uint_t *flags, const char *use)
933 1083 {
934 1084 char *p;
935 1085
936 1086 if ((p = strchr(pstr, '=')) == NULL)
937 1087 return;
938 1088
939 1089 if (p == pstr)
940 1090 die("Invalid prop=val specified\n%s", use);
941 1091
942 1092 --p;
943 1093 if (*p == '+')
944 1094 *flags |= IPADM_OPT_APPEND;
945 1095 else if (*p == '-')
946 1096 *flags |= IPADM_OPT_REMOVE;
947 1097 }
948 1098
949 1099 /*
950 1100 * set/reset the protocol property for a given protocol.
951 1101 */
952 1102 static void
953 1103 set_prop(int argc, char **argv, boolean_t reset, const char *use)
954 1104 {
955 1105 int option;
956 1106 ipadm_status_t status = IPADM_SUCCESS;
957 1107 char *protostr, *nv, *prop_name, *prop_val;
958 1108 boolean_t p_arg = _B_FALSE;
959 1109 uint_t proto;
960 1110 uint_t flags = IPADM_OPT_PERSIST;
961 1111
962 1112 opterr = 0;
963 1113 while ((option = getopt_long(argc, argv, ":p:t", set_prop_longopts,
964 1114 NULL)) != -1) {
965 1115 switch (option) {
966 1116 case 'p':
967 1117 if (p_arg)
968 1118 die("-p must be specified once only");
969 1119 p_arg = _B_TRUE;
970 1120
971 1121 ipadm_check_propstr(optarg, reset, use);
972 1122 nv = optarg;
973 1123 break;
974 1124 case 't':
975 1125 flags &= ~IPADM_OPT_PERSIST;
976 1126 break;
977 1127 default:
978 1128 die_opterr(optopt, option, use);
979 1129 }
980 1130 }
981 1131
982 1132 if (!p_arg || optind != argc - 1)
983 1133 die("Usage: %s", use);
984 1134
985 1135 parse_modifiers(nv, &flags, use);
986 1136 prop_name = nv;
987 1137 prop_val = strchr(nv, '=');
988 1138 if (prop_val != NULL) {
989 1139 if (flags & (IPADM_OPT_APPEND|IPADM_OPT_REMOVE))
990 1140 *(prop_val - 1) = '\0';
991 1141 *prop_val++ = '\0';
992 1142 }
993 1143 protostr = argv[optind];
994 1144 if ((proto = ipadm_str2proto(protostr)) == MOD_PROTO_NONE)
995 1145 die("invalid protocol '%s' specified", protostr);
996 1146
997 1147 if (reset)
998 1148 flags |= IPADM_OPT_DEFAULT;
999 1149 else
1000 1150 flags |= IPADM_OPT_ACTIVE;
1001 1151 status = ipadm_set_prop(iph, prop_name, prop_val, proto, flags);
1002 1152 done:
1003 1153 if (status != IPADM_SUCCESS) {
1004 1154 if (reset)
1005 1155 die("reset-prop: %s: %s",
1006 1156 prop_name, ipadm_status2str(status));
1007 1157 else
1008 1158 die("set-prop: %s: %s",
1009 1159 prop_name, ipadm_status2str(status));
1010 1160 }
1011 1161 }
1012 1162
1013 1163 static void
1014 1164 do_set_prop(int argc, char **argv, const char *use)
1015 1165 {
1016 1166 set_prop(argc, argv, _B_FALSE, use);
1017 1167 }
1018 1168
1019 1169 static void
1020 1170 do_reset_prop(int argc, char **argv, const char *use)
1021 1171 {
1022 1172 set_prop(argc, argv, _B_TRUE, use);
1023 1173 }
1024 1174
1025 1175 /* PRINTFLIKE1 */
1026 1176 static void
1027 1177 warn(const char *format, ...)
1028 1178 {
1029 1179 va_list alist;
1030 1180
1031 1181 format = gettext(format);
1032 1182 (void) fprintf(stderr, gettext("%s: warning: "), progname);
1033 1183
1034 1184 va_start(alist, format);
1035 1185 (void) vfprintf(stderr, format, alist);
1036 1186 va_end(alist);
|
↓ open down ↓ |
554 lines elided |
↑ open up ↑ |
1037 1187
1038 1188 (void) fprintf(stderr, "\n");
1039 1189 }
1040 1190
1041 1191 /* PRINTFLIKE1 */
1042 1192 static void
1043 1193 die(const char *format, ...)
1044 1194 {
1045 1195 va_list alist;
1046 1196
1047 - format = gettext(format);
1048 - (void) fprintf(stderr, "%s: ", progname);
1197 + if (format != NULL) {
1198 + format = gettext(format);
1199 + (void) fprintf(stderr, "%s: ", progname);
1049 1200
1050 - va_start(alist, format);
1051 - (void) vfprintf(stderr, format, alist);
1052 - va_end(alist);
1201 + va_start(alist, format);
1202 + (void) vfprintf(stderr, format, alist);
1203 + va_end(alist);
1053 1204
1054 - (void) putchar('\n');
1205 + (void) putchar('\n');
1206 + }
1055 1207
1056 1208 ipadm_destroy_addrobj(ipaddr);
1057 1209 ipadm_close(iph);
1058 1210 exit(EXIT_FAILURE);
1059 1211 }
1060 1212
1061 1213 static void
1062 1214 die_opterr(int opt, int opterr, const char *usage)
1063 1215 {
1064 1216 switch (opterr) {
1065 1217 case ':':
1066 1218 die("option '-%c' requires a value\nusage: %s", opt,
1067 1219 gettext(usage));
1068 1220 break;
1069 1221 case '?':
1070 1222 default:
1071 1223 die("unrecognized option '-%c'\nusage: %s", opt,
1072 1224 gettext(usage));
1073 1225 break;
1074 1226 }
1075 1227 }
1076 1228
1077 1229 /* PRINTFLIKE2 */
1078 1230 static void
1079 1231 warn_ipadmerr(ipadm_status_t err, const char *format, ...)
1080 1232 {
1081 1233 va_list alist;
1082 1234
1083 1235 format = gettext(format);
1084 1236 (void) fprintf(stderr, gettext("%s: warning: "), progname);
1085 1237
1086 1238 va_start(alist, format);
1087 1239 (void) vfprintf(stderr, format, alist);
1088 1240 va_end(alist);
1089 1241
1090 1242 (void) fprintf(stderr, "%s\n", ipadm_status2str(err));
1091 1243 }
1092 1244
1093 1245 static void
1094 1246 process_static_addrargs(const char *use, char *addrarg, const char *aobjname)
1095 1247 {
1096 1248 int option;
1097 1249 char *val;
1098 1250 char *laddr = NULL;
1099 1251 char *raddr = NULL;
1100 1252 char *save_input_arg = addrarg;
1101 1253 boolean_t found_mismatch = _B_FALSE;
1102 1254 ipadm_status_t status;
1103 1255 enum { A_LOCAL, A_REMOTE };
1104 1256 static char *addr_optstr[] = {
1105 1257 "local",
1106 1258 "remote",
1107 1259 NULL,
1108 1260 };
1109 1261
1110 1262 while (*addrarg != '\0') {
1111 1263 option = getsubopt(&addrarg, addr_optstr, &val);
1112 1264 switch (option) {
1113 1265 case A_LOCAL:
1114 1266 if (laddr != NULL)
1115 1267 die("Multiple local addresses provided");
1116 1268 laddr = val;
1117 1269 break;
1118 1270 case A_REMOTE:
1119 1271 if (raddr != NULL)
1120 1272 die("Multiple remote addresses provided");
1121 1273 raddr = val;
1122 1274 break;
1123 1275 default:
1124 1276 if (found_mismatch)
1125 1277 die("Invalid address provided\nusage: %s", use);
1126 1278 found_mismatch = _B_TRUE;
1127 1279 break;
1128 1280 }
1129 1281 }
1130 1282 if (raddr != NULL && laddr == NULL)
1131 1283 die("Missing local address\nusage: %s", use);
1132 1284
1133 1285 /* If only one address is provided, it is assumed a local address. */
1134 1286 if (laddr == NULL) {
1135 1287 if (found_mismatch)
1136 1288 laddr = save_input_arg;
1137 1289 else
1138 1290 die("Missing local address\nusage: %s", use);
1139 1291 }
1140 1292
1141 1293 /* Initialize the addrobj for static addresses. */
1142 1294 status = ipadm_create_addrobj(IPADM_ADDR_STATIC, aobjname, &ipaddr);
1143 1295 if (status != IPADM_SUCCESS) {
1144 1296 die("Error in creating address object: %s",
1145 1297 ipadm_status2str(status));
1146 1298 }
1147 1299
1148 1300 /* Set the local and remote addresses */
1149 1301 status = ipadm_set_addr(ipaddr, laddr, AF_UNSPEC);
1150 1302 if (status != IPADM_SUCCESS) {
1151 1303 die("Error in setting local address: %s",
1152 1304 ipadm_status2str(status));
1153 1305 }
1154 1306 if (raddr != NULL) {
1155 1307 status = ipadm_set_dst_addr(ipaddr, raddr, AF_UNSPEC);
1156 1308 if (status != IPADM_SUCCESS) {
1157 1309 die("Error in setting remote address: %s",
1158 1310 ipadm_status2str(status));
1159 1311 }
1160 1312 }
1161 1313 }
1162 1314
1163 1315 static void
1164 1316 process_addrconf_addrargs(const char *use, char *addrarg)
1165 1317 {
1166 1318 int option;
1167 1319 char *val;
1168 1320 enum { P_STATELESS, P_STATEFUL };
1169 1321 static char *addr_optstr[] = {
1170 1322 "stateless",
1171 1323 "stateful",
1172 1324 NULL,
1173 1325 };
1174 1326 boolean_t stateless;
1175 1327 boolean_t stateless_arg = _B_FALSE;
1176 1328 boolean_t stateful;
1177 1329 boolean_t stateful_arg = _B_FALSE;
1178 1330 ipadm_status_t status;
1179 1331
1180 1332 while (*addrarg != '\0') {
1181 1333 option = getsubopt(&addrarg, addr_optstr, &val);
1182 1334 switch (option) {
1183 1335 case P_STATELESS:
1184 1336 if (stateless_arg)
1185 1337 die("Duplicate option");
1186 1338 if (val == NULL)
1187 1339 die("Invalid argument");
1188 1340 if (strcmp(val, "yes") == 0)
1189 1341 stateless = _B_TRUE;
1190 1342 else if (strcmp(val, "no") == 0)
1191 1343 stateless = _B_FALSE;
1192 1344 else
1193 1345 die("Invalid argument");
1194 1346 stateless_arg = _B_TRUE;
1195 1347 break;
1196 1348 case P_STATEFUL:
1197 1349 if (stateful_arg)
1198 1350 die("Duplicate option");
1199 1351 if (val == NULL)
1200 1352 die("Invalid argument");
1201 1353 if (strcmp(val, "yes") == 0)
1202 1354 stateful = _B_TRUE;
1203 1355 else if (strcmp(val, "no") == 0)
1204 1356 stateful = _B_FALSE;
1205 1357 else
1206 1358 die("Invalid argument");
1207 1359 stateful_arg = _B_TRUE;
1208 1360 break;
1209 1361 default:
1210 1362 die_opterr(optopt, option, use);
1211 1363 }
1212 1364 }
1213 1365
1214 1366 if (!stateless_arg && !stateful_arg)
1215 1367 die("Invalid arguments for option -p");
1216 1368
1217 1369 /* Set the addrobj fields for addrconf */
1218 1370 if (stateless_arg) {
1219 1371 status = ipadm_set_stateless(ipaddr, stateless);
1220 1372 if (status != IPADM_SUCCESS) {
1221 1373 die("Error in setting stateless option: %s",
1222 1374 ipadm_status2str(status));
1223 1375 }
1224 1376 }
1225 1377 if (stateful_arg) {
1226 1378 status = ipadm_set_stateful(ipaddr, stateful);
1227 1379 if (status != IPADM_SUCCESS) {
1228 1380 die("Error in setting stateful option: %s",
1229 1381 ipadm_status2str(status));
1230 1382 }
1231 1383 }
1232 1384 }
1233 1385
1234 1386 /*
1235 1387 * Creates static, dhcp or addrconf addresses and associates the created
1236 1388 * addresses with the specified address object name.
1237 1389 */
1238 1390 static void
1239 1391 do_create_addr(int argc, char *argv[], const char *use)
1240 1392 {
1241 1393 ipadm_status_t status;
1242 1394 int option;
1243 1395 uint32_t flags =
1244 1396 IPADM_OPT_PERSIST|IPADM_OPT_ACTIVE|IPADM_OPT_UP|IPADM_OPT_V46;
1245 1397 char *cp;
1246 1398 char *atype = NULL;
1247 1399 char *static_arg = NULL;
1248 1400 char *addrconf_arg = NULL;
1249 1401 char *interface_id = NULL;
1250 1402 char *wait = NULL;
1251 1403 char *reqhost = NULL;
1252 1404 boolean_t s_opt = _B_FALSE; /* static addr options */
1253 1405 boolean_t auto_opt = _B_FALSE; /* Addrconf options */
1254 1406 boolean_t dhcp_opt = _B_FALSE; /* dhcp options */
1255 1407 boolean_t primary_opt = _B_FALSE; /* dhcp primary option */
1256 1408
1257 1409 opterr = 0;
1258 1410 while ((option = getopt_long(argc, argv, ":1T:a:dh:i:p:w:t",
1259 1411 addr_longopts, NULL)) != -1) {
1260 1412 switch (option) {
1261 1413 case '1':
1262 1414 primary_opt = _B_TRUE;
1263 1415 break;
1264 1416 case 'T':
1265 1417 atype = optarg;
1266 1418 break;
1267 1419 case 'a':
1268 1420 static_arg = optarg;
1269 1421 s_opt = _B_TRUE;
1270 1422 break;
1271 1423 case 'd':
1272 1424 flags &= ~IPADM_OPT_UP;
1273 1425 s_opt = _B_TRUE;
1274 1426 break;
1275 1427 case 'h':
1276 1428 reqhost = optarg;
1277 1429 break;
1278 1430 case 'i':
1279 1431 interface_id = optarg;
1280 1432 auto_opt = _B_TRUE;
1281 1433 break;
1282 1434 case 'p':
1283 1435 addrconf_arg = optarg;
1284 1436 auto_opt = _B_TRUE;
1285 1437 break;
1286 1438 case 'w':
1287 1439 wait = optarg;
1288 1440 dhcp_opt = _B_TRUE;
1289 1441 break;
1290 1442 case 't':
1291 1443 flags &= ~IPADM_OPT_PERSIST;
1292 1444 break;
1293 1445 default:
1294 1446 die_opterr(optopt, option, use);
1295 1447 }
1296 1448 }
1297 1449 if (atype == NULL || optind != (argc - 1)) {
1298 1450 die("Invalid arguments\nusage: %s", use);
1299 1451 } else if ((cp = strchr(argv[optind], '/')) == NULL ||
1300 1452 strlen(++cp) == 0) {
1301 1453 die("invalid address object name: %s\nusage: %s",
1302 1454 argv[optind], use);
1303 1455 }
1304 1456
1305 1457 /*
1306 1458 * Allocate and initialize the addrobj based on the address type.
1307 1459 */
1308 1460 if (strcmp(atype, "static") == 0) {
1309 1461 if (static_arg == NULL || auto_opt || dhcp_opt ||
1310 1462 reqhost != NULL || primary_opt) {
1311 1463 die("Invalid arguments for type %s\nusage: %s",
1312 1464 atype, use);
1313 1465 }
1314 1466 process_static_addrargs(use, static_arg, argv[optind]);
1315 1467 } else if (strcmp(atype, "dhcp") == 0) {
1316 1468 if (auto_opt || s_opt) {
1317 1469 die("Invalid arguments for type %s\nusage: %s",
1318 1470 atype, use);
1319 1471 }
1320 1472
1321 1473 /* Initialize the addrobj for dhcp addresses. */
1322 1474 status = ipadm_create_addrobj(IPADM_ADDR_DHCP, argv[optind],
1323 1475 &ipaddr);
1324 1476 if (status != IPADM_SUCCESS) {
1325 1477 die("Error in creating address object: %s",
1326 1478 ipadm_status2str(status));
1327 1479 }
1328 1480 if (wait != NULL) {
1329 1481 int32_t ipadm_wait;
1330 1482
1331 1483 if (strcmp(wait, "forever") == 0) {
1332 1484 ipadm_wait = IPADM_DHCP_WAIT_FOREVER;
1333 1485 } else {
1334 1486 char *end;
1335 1487 long timeout = strtol(wait, &end, 10);
1336 1488
1337 1489 if (*end != '\0' || timeout < 0)
1338 1490 die("Invalid argument");
1339 1491 ipadm_wait = (int32_t)timeout;
1340 1492 }
1341 1493 status = ipadm_set_wait_time(ipaddr, ipadm_wait);
1342 1494 if (status != IPADM_SUCCESS) {
1343 1495 die("Error in setting wait time: %s",
1344 1496 ipadm_status2str(status));
1345 1497 }
1346 1498 }
1347 1499 if (primary_opt) {
1348 1500 status = ipadm_set_primary(ipaddr, _B_TRUE);
1349 1501 if (status != IPADM_SUCCESS) {
1350 1502 die("Error in setting primary flag: %s",
1351 1503 ipadm_status2str(status));
1352 1504 }
1353 1505 }
1354 1506 if (reqhost != NULL) {
1355 1507 status = ipadm_set_reqhost(ipaddr, reqhost);
1356 1508 if (status != IPADM_SUCCESS) {
1357 1509 die("Error in setting reqhost: %s",
1358 1510 ipadm_status2str(status));
1359 1511 }
1360 1512 }
1361 1513 } else if (strcmp(atype, "addrconf") == 0) {
1362 1514 if (dhcp_opt || s_opt || reqhost != NULL || primary_opt) {
1363 1515 die("Invalid arguments for type %s\nusage: %s",
1364 1516 atype, use);
1365 1517 }
1366 1518
1367 1519 /* Initialize the addrobj for ipv6-addrconf addresses. */
1368 1520 status = ipadm_create_addrobj(IPADM_ADDR_IPV6_ADDRCONF,
1369 1521 argv[optind], &ipaddr);
1370 1522 if (status != IPADM_SUCCESS) {
1371 1523 die("Error in creating address object: %s",
1372 1524 ipadm_status2str(status));
1373 1525 }
1374 1526 if (interface_id != NULL) {
1375 1527 status = ipadm_set_interface_id(ipaddr, interface_id);
1376 1528 if (status != IPADM_SUCCESS) {
1377 1529 die("Error in setting interface ID: %s",
1378 1530 ipadm_status2str(status));
1379 1531 }
1380 1532 }
1381 1533 if (addrconf_arg)
1382 1534 process_addrconf_addrargs(use, addrconf_arg);
1383 1535 } else {
1384 1536 die("Invalid address type %s", atype);
1385 1537 }
1386 1538
1387 1539 status = ipadm_create_addr(iph, ipaddr, flags);
1388 1540 if (status == IPADM_DHCP_IPC_TIMEOUT)
1389 1541 warn_ipadmerr(status, "");
1390 1542 else if (status != IPADM_SUCCESS)
1391 1543 die("Could not create address: %s", ipadm_status2str(status));
1392 1544 }
1393 1545
1394 1546 /*
1395 1547 * Used by some address management functions to parse the command line
1396 1548 * arguments and create `ipaddr' address object.
1397 1549 */
1398 1550 static void
1399 1551 process_misc_addrargs(int argc, char *argv[], const char *use, int *index,
1400 1552 uint32_t *flags)
1401 1553 {
1402 1554 int option;
1403 1555
1404 1556 opterr = 0;
1405 1557 while ((option = getopt_long(argc, argv, ":t", addr_misc_longopts,
1406 1558 NULL)) != -1) {
1407 1559 switch (option) {
1408 1560 case 't':
1409 1561 *flags &= ~IPADM_OPT_PERSIST;
1410 1562 break;
1411 1563 default:
1412 1564 die_opterr(optopt, option, use);
1413 1565 }
1414 1566 }
1415 1567 if (optind != (argc - 1))
1416 1568 die("Usage: %s", use);
1417 1569
1418 1570 *index = optind;
1419 1571 }
1420 1572
1421 1573 /*
1422 1574 * Remove an addrobj from both active and persistent configuration.
1423 1575 */
1424 1576 static void
1425 1577 do_delete_addr(int argc, char *argv[], const char *use)
1426 1578 {
1427 1579 ipadm_status_t status;
1428 1580 uint32_t flags = IPADM_OPT_ACTIVE|IPADM_OPT_PERSIST;
1429 1581 int option;
1430 1582
1431 1583 opterr = 0;
1432 1584 while ((option = getopt_long(argc, argv, ":r", addr_misc_longopts,
1433 1585 NULL)) != -1) {
1434 1586 switch (option) {
1435 1587 case 'r':
1436 1588 flags |= IPADM_OPT_RELEASE;
1437 1589 break;
1438 1590 default:
1439 1591 die_opterr(optopt, option, use);
1440 1592 }
1441 1593 }
1442 1594 if (optind != (argc - 1))
1443 1595 die("Usage: %s", use);
1444 1596
1445 1597 status = ipadm_delete_addr(iph, argv[optind], flags);
1446 1598 if (status != IPADM_SUCCESS) {
1447 1599 die("could not delete address: %s",
1448 1600 ipadm_status2str(status));
1449 1601 }
1450 1602 }
1451 1603
1452 1604 /*
1453 1605 * Enable an IP address based on the persistent configuration for that
1454 1606 * IP address
1455 1607 */
1456 1608 static void
1457 1609 do_enable_addr(int argc, char *argv[], const char *use)
1458 1610 {
1459 1611 ipadm_status_t status;
1460 1612 int index;
1461 1613 uint32_t flags = IPADM_OPT_ACTIVE|IPADM_OPT_PERSIST;
1462 1614
1463 1615 process_misc_addrargs(argc, argv, use, &index, &flags);
1464 1616 if (flags & IPADM_OPT_PERSIST)
1465 1617 die("persistent operation not supported for enable-addr");
1466 1618
1467 1619 status = ipadm_enable_addr(iph, argv[index], flags);
1468 1620 if (status != IPADM_SUCCESS)
1469 1621 die("could not enable address: %s", ipadm_status2str(status));
1470 1622 }
1471 1623
1472 1624 /*
1473 1625 * Mark the address identified by addrobj 'up'
1474 1626 */
1475 1627 static void
1476 1628 do_up_addr(int argc, char *argv[], const char *use)
1477 1629 {
1478 1630 ipadm_status_t status;
1479 1631 int index;
1480 1632 uint32_t flags = IPADM_OPT_ACTIVE|IPADM_OPT_PERSIST;
1481 1633
1482 1634 process_misc_addrargs(argc, argv, use, &index, &flags);
1483 1635 status = ipadm_up_addr(iph, argv[index], flags);
1484 1636 if (status != IPADM_SUCCESS) {
1485 1637 die("Could not mark the address up: %s",
1486 1638 ipadm_status2str(status));
1487 1639 }
1488 1640 }
1489 1641
1490 1642 /*
1491 1643 * Disable the specified addrobj by removing it from active cofiguration
1492 1644 */
1493 1645 static void
1494 1646 do_disable_addr(int argc, char *argv[], const char *use)
1495 1647 {
1496 1648 ipadm_status_t status;
1497 1649 int index;
1498 1650 uint32_t flags = IPADM_OPT_ACTIVE|IPADM_OPT_PERSIST;
1499 1651
1500 1652 process_misc_addrargs(argc, argv, use, &index, &flags);
1501 1653 if (flags & IPADM_OPT_PERSIST)
1502 1654 die("persistent operation not supported for disable-addr");
1503 1655
1504 1656 status = ipadm_disable_addr(iph, argv[index], flags);
1505 1657 if (status != IPADM_SUCCESS) {
1506 1658 die("could not disable address: %s",
1507 1659 ipadm_status2str(status));
1508 1660 }
1509 1661 }
1510 1662
1511 1663 /*
1512 1664 * Mark the address identified by addrobj 'down'
1513 1665 */
1514 1666 static void
1515 1667 do_down_addr(int argc, char *argv[], const char *use)
1516 1668 {
1517 1669 ipadm_status_t status;
1518 1670 int index;
1519 1671 uint32_t flags = IPADM_OPT_ACTIVE|IPADM_OPT_PERSIST;
1520 1672
1521 1673 process_misc_addrargs(argc, argv, use, &index, &flags);
1522 1674 status = ipadm_down_addr(iph, argv[index], flags);
1523 1675 if (status != IPADM_SUCCESS)
1524 1676 die("Could not mark the address down: %s",
1525 1677 ipadm_status2str(status));
1526 1678 }
1527 1679
1528 1680 /*
1529 1681 * Restart DAD for static address. Extend lease duration for DHCP addresses
1530 1682 */
1531 1683 static void
1532 1684 do_refresh_addr(int argc, char *argv[], const char *use)
1533 1685 {
1534 1686 ipadm_status_t status;
1535 1687 int option;
1536 1688 uint32_t flags = 0;
1537 1689
1538 1690 opterr = 0;
1539 1691 while ((option = getopt_long(argc, argv, ":i", addr_misc_longopts,
1540 1692 NULL)) != -1) {
1541 1693 switch (option) {
1542 1694 case 'i':
1543 1695 flags |= IPADM_OPT_INFORM;
1544 1696 break;
1545 1697 default:
1546 1698 die_opterr(optopt, option, use);
1547 1699 }
1548 1700 }
1549 1701 if (optind != (argc - 1))
1550 1702 die("Usage: %s", use);
1551 1703
1552 1704 status = ipadm_refresh_addr(iph, argv[optind], flags);
1553 1705 if (status == IPADM_DHCP_IPC_TIMEOUT)
1554 1706 warn_ipadmerr(status, "");
1555 1707 else if (status != IPADM_SUCCESS)
1556 1708 die("could not refresh address %s", ipadm_status2str(status));
1557 1709 }
1558 1710
1559 1711 static void
1560 1712 sockaddr2str(const struct sockaddr_storage *ssp, char *buf, uint_t bufsize)
1561 1713 {
1562 1714 socklen_t socklen;
1563 1715 struct sockaddr *sp = (struct sockaddr *)ssp;
1564 1716
1565 1717 switch (ssp->ss_family) {
1566 1718 case AF_INET:
1567 1719 socklen = sizeof (struct sockaddr_in);
1568 1720 break;
1569 1721 case AF_INET6:
1570 1722 socklen = sizeof (struct sockaddr_in6);
1571 1723 break;
1572 1724 default:
1573 1725 (void) strlcpy(buf, STR_UNKNOWN_VAL, bufsize);
1574 1726 return;
1575 1727 }
1576 1728
1577 1729 (void) getnameinfo(sp, socklen, buf, bufsize, NULL, 0,
1578 1730 (NI_NOFQDN | NI_NUMERICHOST));
1579 1731 }
1580 1732
1581 1733 static void
1582 1734 flags2str(uint64_t flags, fmask_t *tbl, boolean_t is_bits,
1583 1735 char *buf, uint_t bufsize)
1584 1736 {
1585 1737 int i;
1586 1738 boolean_t first = _B_TRUE;
1587 1739
1588 1740 if (is_bits) {
1589 1741 for (i = 0; tbl[i].name; i++) {
1590 1742 if ((flags & tbl[i].mask) == tbl[i].bits)
1591 1743 (void) strlcat(buf, tbl[i].name, bufsize);
1592 1744 else
1593 1745 (void) strlcat(buf, "-", bufsize);
1594 1746 }
1595 1747 } else {
1596 1748 for (i = 0; tbl[i].name; i++) {
1597 1749 if ((flags & tbl[i].mask) == tbl[i].bits) {
1598 1750 if (!first)
1599 1751 (void) strlcat(buf, ",", bufsize);
1600 1752 (void) strlcat(buf, tbl[i].name, bufsize);
1601 1753 first = _B_FALSE;
1602 1754 }
1603 1755 }
1604 1756 }
1605 1757 }
1606 1758
1607 1759 /*
1608 1760 * return true if the address for lifname comes to us from the global zone
1609 1761 * with 'allowed-ips' constraints.
1610 1762 */
1611 1763 static boolean_t
1612 1764 is_from_gz(const char *lifname)
1613 1765 {
1614 1766 ipadm_if_info_t *if_info;
1615 1767 char phyname[LIFNAMSIZ], *cp;
1616 1768 boolean_t ret = _B_FALSE;
1617 1769 ipadm_status_t status;
1618 1770 zoneid_t zoneid;
1619 1771 ushort_t zflags;
1620 1772
1621 1773 if ((zoneid = getzoneid()) == GLOBAL_ZONEID)
1622 1774 return (_B_FALSE); /* from-gz only makes sense in a NGZ */
1623 1775
1624 1776 if (zone_getattr(zoneid, ZONE_ATTR_FLAGS, &zflags, sizeof (zflags)) < 0)
1625 1777 return (_B_FALSE);
1626 1778
1627 1779 if (!(zflags & ZF_NET_EXCL))
1628 1780 return (_B_TRUE); /* everything is from the GZ for shared-ip */
1629 1781
1630 1782 (void) strncpy(phyname, lifname, sizeof (phyname));
1631 1783 if ((cp = strchr(phyname, ':')) != NULL)
1632 1784 *cp = '\0';
1633 1785 status = ipadm_if_info(iph, phyname, &if_info, 0, LIFC_DEFAULT);
1634 1786 if (status != IPADM_SUCCESS)
1635 1787 return (ret);
1636 1788
1637 1789 if (if_info->ifi_cflags & IFIF_L3PROTECT)
1638 1790 ret = _B_TRUE;
1639 1791 if (if_info)
1640 1792 ipadm_free_if_info(if_info);
1641 1793 return (ret);
1642 1794 }
1643 1795
1644 1796 static boolean_t
1645 1797 print_sa_cb(ofmt_arg_t *ofarg, char *buf, uint_t bufsize)
1646 1798 {
1647 1799 show_addr_args_t *arg = ofarg->ofmt_cbarg;
1648 1800 ipadm_addr_info_t *ainfo = arg->sa_info;
1649 1801 char interface[LIFNAMSIZ];
1650 1802 char addrbuf[MAXPROPVALLEN];
1651 1803 char dstbuf[MAXPROPVALLEN];
1652 1804 char prefixlenstr[MAXPROPVALLEN];
1653 1805 int prefixlen;
1654 1806 struct sockaddr_in *sin;
1655 1807 struct sockaddr_in6 *sin6;
1656 1808 sa_family_t af;
1657 1809 char *phyname = NULL;
1658 1810 struct ifaddrs *ifa = &ainfo->ia_ifa;
1659 1811 fmask_t cflags_mask[] = {
1660 1812 { "U", IA_UP, IA_UP },
1661 1813 { "u", IA_UNNUMBERED, IA_UNNUMBERED },
1662 1814 { "p", IA_PRIVATE, IA_PRIVATE },
1663 1815 { "t", IA_TEMPORARY, IA_TEMPORARY },
1664 1816 { "d", IA_DEPRECATED, IA_DEPRECATED },
1665 1817 { NULL, 0, 0 }
1666 1818 };
1667 1819 fmask_t pflags_mask[] = {
1668 1820 { "U", IA_UP, IA_UP },
1669 1821 { "p", IA_PRIVATE, IA_PRIVATE },
1670 1822 { "d", IA_DEPRECATED, IA_DEPRECATED },
1671 1823 { NULL, 0, 0 }
1672 1824 };
1673 1825 fmask_t type[] = {
1674 1826 { "static", IPADM_ADDR_STATIC, IPADM_ALL_BITS},
1675 1827 { "addrconf", IPADM_ADDR_IPV6_ADDRCONF, IPADM_ALL_BITS},
1676 1828 { "dhcp", IPADM_ADDR_DHCP, IPADM_ALL_BITS},
1677 1829 { NULL, 0, 0 }
1678 1830 };
1679 1831 fmask_t addr_state[] = {
1680 1832 { "disabled", IFA_DISABLED, IPADM_ALL_BITS},
1681 1833 { "duplicate", IFA_DUPLICATE, IPADM_ALL_BITS},
1682 1834 { "down", IFA_DOWN, IPADM_ALL_BITS},
1683 1835 { "tentative", IFA_TENTATIVE, IPADM_ALL_BITS},
1684 1836 { "ok", IFA_OK, IPADM_ALL_BITS},
1685 1837 { "inaccessible", IFA_INACCESSIBLE, IPADM_ALL_BITS},
1686 1838 { NULL, 0, 0 }
1687 1839 };
1688 1840
1689 1841 buf[0] = '\0';
1690 1842 switch (ofarg->ofmt_id) {
1691 1843 case SA_ADDROBJ:
1692 1844 if (ainfo->ia_aobjname[0] == '\0') {
1693 1845 (void) strncpy(interface, ifa->ifa_name, LIFNAMSIZ);
1694 1846 phyname = strrchr(interface, ':');
1695 1847 if (phyname)
1696 1848 *phyname = '\0';
1697 1849 (void) snprintf(buf, bufsize, "%s/%s", interface,
1698 1850 STR_UNKNOWN_VAL);
1699 1851 } else {
1700 1852 (void) snprintf(buf, bufsize, "%s", ainfo->ia_aobjname);
1701 1853 }
1702 1854 break;
1703 1855 case SA_STATE:
1704 1856 flags2str(ainfo->ia_state, addr_state, _B_FALSE,
1705 1857 buf, bufsize);
1706 1858 break;
1707 1859 case SA_TYPE:
1708 1860 if (is_from_gz(ifa->ifa_name))
1709 1861 (void) snprintf(buf, bufsize, "from-gz");
1710 1862 else
1711 1863 flags2str(ainfo->ia_atype, type, _B_FALSE, buf,
1712 1864 bufsize);
1713 1865 break;
1714 1866 case SA_CURRENT:
1715 1867 flags2str(ainfo->ia_cflags, cflags_mask, _B_TRUE, buf, bufsize);
1716 1868 break;
1717 1869 case SA_PERSISTENT:
1718 1870 flags2str(ainfo->ia_pflags, pflags_mask, _B_TRUE, buf, bufsize);
1719 1871 break;
1720 1872 case SA_ADDR:
1721 1873 af = ifa->ifa_addr->sa_family;
1722 1874 /*
1723 1875 * If the address is 0.0.0.0 or :: and the origin is DHCP,
1724 1876 * print STR_UNKNOWN_VAL.
1725 1877 */
1726 1878 if (ainfo->ia_atype == IPADM_ADDR_DHCP) {
1727 1879 sin = (struct sockaddr_in *)ifa->ifa_addr;
1728 1880 sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
1729 1881 if ((af == AF_INET &&
1730 1882 sin->sin_addr.s_addr == INADDR_ANY) ||
1731 1883 (af == AF_INET6 &&
1732 1884 IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))) {
1733 1885 (void) snprintf(buf, bufsize, STR_UNKNOWN_VAL);
1734 1886 break;
1735 1887 }
1736 1888 }
1737 1889 if (ifa->ifa_netmask == NULL)
1738 1890 prefixlen = 0;
1739 1891 else
1740 1892 prefixlen = mask2plen(ifa->ifa_netmask);
1741 1893 bzero(prefixlenstr, sizeof (prefixlenstr));
1742 1894 if (prefixlen > 0) {
1743 1895 (void) snprintf(prefixlenstr, sizeof (prefixlenstr),
1744 1896 "/%d", prefixlen);
1745 1897 }
1746 1898 bzero(addrbuf, sizeof (addrbuf));
1747 1899 bzero(dstbuf, sizeof (dstbuf));
1748 1900 if (ainfo->ia_atype == IPADM_ADDR_STATIC) {
1749 1901 /*
1750 1902 * Print the hostname fields if the address is not
1751 1903 * in active configuration.
1752 1904 */
1753 1905 if (ainfo->ia_state == IFA_DISABLED) {
1754 1906 (void) snprintf(buf, bufsize, "%s",
1755 1907 ainfo->ia_sname);
1756 1908 if (ainfo->ia_dname[0] != '\0') {
1757 1909 (void) snprintf(dstbuf, sizeof (dstbuf),
1758 1910 "->%s", ainfo->ia_dname);
1759 1911 (void) strlcat(buf, dstbuf, bufsize);
1760 1912 } else {
1761 1913 (void) strlcat(buf, prefixlenstr,
1762 1914 bufsize);
1763 1915 }
1764 1916 break;
1765 1917 }
1766 1918 }
1767 1919 /*
1768 1920 * For the non-persistent case, we need to show the
1769 1921 * currently configured addresses for source and
1770 1922 * destination.
1771 1923 */
1772 1924 sockaddr2str((struct sockaddr_storage *)ifa->ifa_addr,
1773 1925 addrbuf, sizeof (addrbuf));
1774 1926 if (ifa->ifa_flags & IFF_POINTOPOINT) {
1775 1927 sockaddr2str(
1776 1928 (struct sockaddr_storage *)ifa->ifa_dstaddr,
1777 1929 dstbuf, sizeof (dstbuf));
1778 1930 (void) snprintf(buf, bufsize, "%s->%s", addrbuf,
1779 1931 dstbuf);
1780 1932 } else {
1781 1933 (void) snprintf(buf, bufsize, "%s%s", addrbuf,
1782 1934 prefixlenstr);
1783 1935 }
1784 1936 break;
1785 1937 default:
1786 1938 die("invalid input");
1787 1939 break;
1788 1940 }
1789 1941
1790 1942 return (_B_TRUE);
1791 1943 }
1792 1944
1793 1945 /*
1794 1946 * Display address information, either for the given address or
1795 1947 * for all the addresses managed by ipadm.
1796 1948 */
1797 1949 static void
1798 1950 do_show_addr(int argc, char *argv[], const char *use)
1799 1951 {
1800 1952 ipadm_status_t status;
1801 1953 show_addr_state_t state;
1802 1954 char *def_fields_str = "addrobj,type,state,addr";
1803 1955 char *fields_str = NULL;
1804 1956 ipadm_addr_info_t *ainfo;
1805 1957 ipadm_addr_info_t *ptr;
1806 1958 show_addr_args_t sargs;
1807 1959 int option;
1808 1960 ofmt_handle_t ofmt;
1809 1961 ofmt_status_t oferr;
1810 1962 uint_t ofmtflags = 0;
1811 1963 char *aname;
1812 1964 char *ifname = NULL;
1813 1965 char *cp;
1814 1966 boolean_t found = _B_FALSE;
1815 1967
1816 1968 opterr = 0;
1817 1969 state.sa_parsable = _B_FALSE;
1818 1970 state.sa_persist = _B_FALSE;
1819 1971 while ((option = getopt_long(argc, argv, "po:", show_addr_longopts,
1820 1972 NULL)) != -1) {
1821 1973 switch (option) {
1822 1974 case 'p':
1823 1975 state.sa_parsable = _B_TRUE;
1824 1976 break;
1825 1977 case 'o':
1826 1978 fields_str = optarg;
1827 1979 break;
1828 1980 default:
1829 1981 die_opterr(optopt, option, use);
1830 1982 break;
1831 1983 }
1832 1984 }
1833 1985 if (state.sa_parsable && fields_str == NULL)
1834 1986 die("-p requires -o");
1835 1987
1836 1988 if (optind == argc - 1) {
1837 1989 aname = argv[optind];
1838 1990 if ((cp = strchr(aname, '/')) == NULL)
1839 1991 die("Invalid address object name provided");
1840 1992 if (*(cp + 1) == '\0') {
1841 1993 ifname = aname;
1842 1994 *cp = '\0';
1843 1995 aname = NULL;
1844 1996 }
1845 1997 } else if (optind == argc) {
1846 1998 aname = NULL;
1847 1999 } else {
1848 2000 die("Usage: %s", use);
1849 2001 }
1850 2002
1851 2003 if (state.sa_parsable)
1852 2004 ofmtflags |= OFMT_PARSABLE;
1853 2005 if (fields_str == NULL)
1854 2006 fields_str = def_fields_str;
1855 2007 oferr = ofmt_open(fields_str, show_addr_fields, ofmtflags, 0, &ofmt);
1856 2008
1857 2009 ofmt_check(oferr, state.sa_parsable, ofmt, die, warn);
1858 2010 state.sa_ofmt = ofmt;
1859 2011
1860 2012 status = ipadm_addr_info(iph, ifname, &ainfo, 0, LIFC_DEFAULT);
1861 2013 /*
1862 2014 * Return without printing any error, if no addresses were found,
1863 2015 * for the case where all addresses are requested.
1864 2016 */
1865 2017 if (status != IPADM_SUCCESS)
1866 2018 die("Could not get address: %s", ipadm_status2str(status));
1867 2019 if (ainfo == NULL) {
1868 2020 ofmt_close(ofmt);
1869 2021 return;
1870 2022 }
1871 2023
1872 2024 bzero(&sargs, sizeof (sargs));
1873 2025 sargs.sa_state = &state;
1874 2026 for (ptr = ainfo; ptr != NULL; ptr = IA_NEXT(ptr)) {
1875 2027 sargs.sa_info = ptr;
1876 2028 if (aname != NULL) {
1877 2029 if (strcmp(sargs.sa_info->ia_aobjname, aname) != 0)
1878 2030 continue;
1879 2031 found = _B_TRUE;
1880 2032 }
1881 2033 ofmt_print(state.sa_ofmt, &sargs);
1882 2034 }
1883 2035 if (ainfo)
1884 2036 ipadm_free_addr_info(ainfo);
1885 2037 if (aname != NULL && !found)
1886 2038 die("Address object not found");
1887 2039 }
1888 2040
1889 2041 static boolean_t
1890 2042 print_si_cb(ofmt_arg_t *ofarg, char *buf, uint_t bufsize)
1891 2043 {
1892 2044 show_if_args_t *arg = ofarg->ofmt_cbarg;
1893 2045 ipadm_if_info_t *ifinfo = arg->si_info;
1894 2046 char *ifname = ifinfo->ifi_name;
1895 2047 fmask_t intf_state[] = {
1896 2048 { "ok", IFIS_OK, IPADM_ALL_BITS},
1897 2049 { "down", IFIS_DOWN, IPADM_ALL_BITS},
1898 2050 { "disabled", IFIS_DISABLED, IPADM_ALL_BITS},
1899 2051 { "failed", IFIS_FAILED, IPADM_ALL_BITS},
1900 2052 { "offline", IFIS_OFFLINE, IPADM_ALL_BITS},
1901 2053 { NULL, 0, 0 }
1902 2054 };
1903 2055 fmask_t intf_pflags[] = {
1904 2056 { "s", IFIF_STANDBY, IFIF_STANDBY },
1905 2057 { "4", IFIF_IPV4, IFIF_IPV4 },
1906 2058 { "6", IFIF_IPV6, IFIF_IPV6 },
1907 2059 { NULL, 0, 0 }
1908 2060 };
1909 2061 fmask_t intf_cflags[] = {
1910 2062 { "b", IFIF_BROADCAST, IFIF_BROADCAST },
1911 2063 { "m", IFIF_MULTICAST, IFIF_MULTICAST },
1912 2064 { "p", IFIF_POINTOPOINT, IFIF_POINTOPOINT},
1913 2065 { "v", IFIF_VIRTUAL, IFIF_VIRTUAL },
|
↓ open down ↓ |
849 lines elided |
↑ open up ↑ |
1914 2066 { "I", IFIF_IPMP, IFIF_IPMP },
1915 2067 { "s", IFIF_STANDBY, IFIF_STANDBY },
1916 2068 { "i", IFIF_INACTIVE, IFIF_INACTIVE },
1917 2069 { "V", IFIF_VRRP, IFIF_VRRP },
1918 2070 { "a", IFIF_NOACCEPT, IFIF_NOACCEPT },
1919 2071 { "Z", IFIF_L3PROTECT, IFIF_L3PROTECT },
1920 2072 { "4", IFIF_IPV4, IFIF_IPV4 },
1921 2073 { "6", IFIF_IPV6, IFIF_IPV6 },
1922 2074 { NULL, 0, 0 }
1923 2075 };
2076 + fmask_t intf_class[] = {
2077 + { "IP", IPADM_IF_CLASS_REGULAR, IPADM_ALL_BITS},
2078 + { "IPMP", IPADM_IF_CLASS_IPMP, IPADM_ALL_BITS},
2079 + { "VIRTUAL", IPADM_IF_CLASS_VIRTUAL, IPADM_ALL_BITS},
2080 + { "UNKNOWN", IPADM_IF_CLASS_UNKNOWN, IPADM_ALL_BITS},
2081 + { NULL, 0, 0}
2082 + };
1924 2083
1925 2084 buf[0] = '\0';
1926 2085 switch (ofarg->ofmt_id) {
1927 2086 case SI_IFNAME:
1928 2087 (void) snprintf(buf, bufsize, "%s", ifname);
1929 2088 break;
2089 + case SI_IFCLASS:
2090 + flags2str(ifinfo->ifi_class, intf_class, _B_FALSE,
2091 + buf, bufsize);
2092 + break;
1930 2093 case SI_STATE:
1931 2094 flags2str(ifinfo->ifi_state, intf_state, _B_FALSE,
1932 2095 buf, bufsize);
1933 2096 break;
1934 2097 case SI_CURRENT:
1935 2098 flags2str(ifinfo->ifi_cflags, intf_cflags, _B_TRUE,
1936 2099 buf, bufsize);
1937 2100 break;
1938 2101 case SI_PERSISTENT:
1939 2102 flags2str(ifinfo->ifi_pflags, intf_pflags, _B_TRUE,
1940 2103 buf, bufsize);
1941 2104 break;
1942 2105 default:
1943 2106 die("invalid input");
1944 2107 break;
1945 2108 }
1946 2109
1947 2110 return (_B_TRUE);
1948 2111 }
1949 2112
1950 2113 /*
1951 2114 * Display interface information, either for the given interface or
1952 2115 * for all the interfaces in the system.
1953 2116 */
1954 2117 static void
1955 2118 do_show_if(int argc, char *argv[], const char *use)
1956 2119 {
1957 2120 ipadm_status_t status;
1958 2121 show_if_state_t state;
1959 2122 char *fields_str = NULL;
1960 2123 ipadm_if_info_t *if_info, *ptr;
1961 2124 show_if_args_t sargs;
1962 2125 int option;
1963 2126 ofmt_handle_t ofmt;
1964 2127 ofmt_status_t oferr;
1965 2128 uint_t ofmtflags = 0;
1966 2129 char *ifname = NULL;
1967 2130
1968 2131 opterr = 0;
1969 2132 state.si_parsable = _B_FALSE;
1970 2133
1971 2134 while ((option = getopt_long(argc, argv, "po:", show_if_longopts,
1972 2135 NULL)) != -1) {
1973 2136 switch (option) {
1974 2137 case 'p':
1975 2138 state.si_parsable = _B_TRUE;
1976 2139 break;
1977 2140 case 'o':
1978 2141 fields_str = optarg;
1979 2142 break;
1980 2143 default:
1981 2144 die_opterr(optopt, option, use);
1982 2145 break;
1983 2146 }
1984 2147 }
1985 2148 if (optind == argc - 1)
1986 2149 ifname = argv[optind];
1987 2150 else if (optind != argc)
1988 2151 die("Usage: %s", use);
1989 2152 if (state.si_parsable)
1990 2153 ofmtflags |= OFMT_PARSABLE;
1991 2154 oferr = ofmt_open(fields_str, show_if_fields, ofmtflags, 0, &ofmt);
1992 2155 ofmt_check(oferr, state.si_parsable, ofmt, die, warn);
1993 2156 state.si_ofmt = ofmt;
1994 2157 bzero(&sargs, sizeof (sargs));
1995 2158 sargs.si_state = &state;
1996 2159 status = ipadm_if_info(iph, ifname, &if_info, 0, LIFC_DEFAULT);
1997 2160 /*
1998 2161 * Return without printing any error, if no addresses were found.
1999 2162 */
2000 2163 if (status != IPADM_SUCCESS) {
2001 2164 die("Could not get interface(s): %s",
2002 2165 ipadm_status2str(status));
2003 2166 }
2004 2167
2005 2168 for (ptr = if_info; ptr; ptr = ptr->ifi_next) {
2006 2169 sargs.si_info = ptr;
2007 2170 ofmt_print(state.si_ofmt, &sargs);
2008 2171 }
2009 2172 if (if_info)
2010 2173 ipadm_free_if_info(if_info);
2011 2174 }
2012 2175
2013 2176 /*
2014 2177 * set/reset the address property for a given address
2015 2178 */
2016 2179 static void
2017 2180 set_addrprop(int argc, char **argv, boolean_t reset, const char *use)
2018 2181 {
2019 2182 int option;
2020 2183 ipadm_status_t status = IPADM_SUCCESS;
2021 2184 boolean_t p_arg = _B_FALSE;
2022 2185 char *nv, *aobjname;
2023 2186 char *prop_name, *prop_val;
2024 2187 uint_t flags = IPADM_OPT_ACTIVE|IPADM_OPT_PERSIST;
2025 2188
2026 2189 opterr = 0;
2027 2190 while ((option = getopt_long(argc, argv, ":i:p:t", set_ifprop_longopts,
2028 2191 NULL)) != -1) {
2029 2192 switch (option) {
2030 2193 case 'p':
2031 2194 if (p_arg)
2032 2195 die("-p must be specified once only");
2033 2196 p_arg = _B_TRUE;
2034 2197
2035 2198 ipadm_check_propstr(optarg, reset, use);
2036 2199 nv = optarg;
2037 2200 break;
2038 2201 case 't':
2039 2202 flags &= ~IPADM_OPT_PERSIST;
2040 2203 break;
2041 2204 default:
2042 2205 die_opterr(optopt, option, use);
2043 2206 }
2044 2207 }
2045 2208
2046 2209 if (!p_arg || optind != (argc - 1))
2047 2210 die("Usage: %s", use);
2048 2211
2049 2212 prop_name = nv;
2050 2213 prop_val = strchr(nv, '=');
2051 2214 if (prop_val != NULL)
2052 2215 *prop_val++ = '\0';
2053 2216 aobjname = argv[optind];
2054 2217 if (reset)
2055 2218 flags |= IPADM_OPT_DEFAULT;
2056 2219 status = ipadm_set_addrprop(iph, prop_name, prop_val, aobjname, flags);
2057 2220 if (status != IPADM_SUCCESS) {
2058 2221 if (reset)
2059 2222 die("reset-addrprop: %s: %s", prop_name,
2060 2223 ipadm_status2str(status));
2061 2224 else
2062 2225 die("set-addrprop: %s: %s", prop_name,
2063 2226 ipadm_status2str(status));
2064 2227 }
2065 2228 }
2066 2229
2067 2230 /*
2068 2231 * Sets a property on an address object.
2069 2232 */
2070 2233 static void
2071 2234 do_set_addrprop(int argc, char **argv, const char *use)
2072 2235 {
2073 2236 set_addrprop(argc, argv, _B_FALSE, use);
2074 2237 }
2075 2238
2076 2239 /*
2077 2240 * Resets a property to its default value on an address object.
2078 2241 */
2079 2242 static void
2080 2243 do_reset_addrprop(int argc, char **argv, const char *use)
2081 2244 {
2082 2245 set_addrprop(argc, argv, _B_TRUE, use);
2083 2246 }
2084 2247
2085 2248 /*
2086 2249 * Display information for all or specific address properties, either for a
2087 2250 * given address or for all the addresses in the system.
2088 2251 */
2089 2252 static void
2090 2253 do_show_addrprop(int argc, char *argv[], const char *use)
2091 2254 {
2092 2255 int option;
2093 2256 nvlist_t *proplist = NULL;
2094 2257 char *fields_str = NULL;
2095 2258 show_prop_state_t state;
2096 2259 ofmt_handle_t ofmt;
2097 2260 ofmt_status_t oferr;
2098 2261 uint_t ofmtflags = 0;
2099 2262 char *aobjname = NULL;
2100 2263 char *ifname = NULL;
2101 2264 char *cp;
2102 2265 ipadm_addr_info_t *ainfop = NULL;
2103 2266 ipadm_addr_info_t *ptr;
2104 2267 ipadm_status_t status;
2105 2268 boolean_t found = _B_FALSE;
2106 2269
2107 2270 opterr = 0;
2108 2271 bzero(&state, sizeof (state));
2109 2272 state.sps_propval = NULL;
2110 2273 state.sps_parsable = _B_FALSE;
2111 2274 state.sps_addrprop = _B_TRUE;
2112 2275 state.sps_proto = MOD_PROTO_NONE;
2113 2276 state.sps_status = state.sps_retstatus = IPADM_SUCCESS;
2114 2277 while ((option = getopt_long(argc, argv, ":p:i:cPo:",
2115 2278 show_prop_longopts, NULL)) != -1) {
2116 2279 switch (option) {
2117 2280 case 'p':
2118 2281 if (ipadm_str2nvlist(optarg, &proplist,
2119 2282 IPADM_NORVAL) != 0)
2120 2283 die("invalid addrobj properties specified");
2121 2284 break;
2122 2285 case 'c':
2123 2286 state.sps_parsable = _B_TRUE;
2124 2287 break;
2125 2288 case 'o':
2126 2289 fields_str = optarg;
2127 2290 break;
2128 2291 default:
2129 2292 die_opterr(optopt, option, use);
2130 2293 break;
2131 2294 }
2132 2295 }
2133 2296 if (optind == argc - 1) {
2134 2297 aobjname = argv[optind];
2135 2298 cp = strchr(aobjname, '/');
2136 2299 if (cp == NULL)
2137 2300 die("invalid addrobj name provided");
2138 2301 if (*(cp + 1) == '\0') {
2139 2302 ifname = aobjname;
2140 2303 *cp = '\0';
2141 2304 aobjname = NULL;
2142 2305 }
2143 2306 } else if (optind != argc) {
2144 2307 die("Usage: %s", use);
2145 2308 }
2146 2309 state.sps_proplist = proplist;
2147 2310 if (state.sps_parsable)
2148 2311 ofmtflags |= OFMT_PARSABLE;
2149 2312 oferr = ofmt_open(fields_str, addrprop_fields, ofmtflags, 0, &ofmt);
2150 2313 ofmt_check(oferr, state.sps_parsable, ofmt, die, warn);
2151 2314 state.sps_ofmt = ofmt;
2152 2315
2153 2316 status = ipadm_addr_info(iph, ifname, &ainfop, 0, LIFC_DEFAULT);
2154 2317 /* Return without printing any error, if no addresses were found */
2155 2318 if (status == IPADM_NOTFOUND)
2156 2319 return;
2157 2320 if (status != IPADM_SUCCESS)
2158 2321 die("error retrieving address: %s", ipadm_status2str(status));
2159 2322
2160 2323 for (ptr = ainfop; ptr != NULL; ptr = IA_NEXT(ptr)) {
2161 2324 char *taobjname = ptr->ia_aobjname;
2162 2325
2163 2326 if (taobjname[0] == '\0')
2164 2327 continue;
2165 2328 if (aobjname != NULL) {
2166 2329 if (strcmp(aobjname, taobjname) == 0)
2167 2330 found = _B_TRUE;
2168 2331 else
2169 2332 continue;
2170 2333 }
2171 2334 if (ptr->ia_atype == IPADM_ADDR_IPV6_ADDRCONF) {
2172 2335 if (found)
2173 2336 break;
2174 2337 else
2175 2338 continue;
2176 2339 }
2177 2340 (void) strlcpy(state.sps_aobjname, taobjname,
2178 2341 sizeof (state.sps_aobjname));
2179 2342 show_properties(&state, IPADMPROP_CLASS_ADDR);
2180 2343 if (found)
2181 2344 break;
2182 2345 }
2183 2346 ipadm_free_addr_info(ainfop);
2184 2347
2185 2348 if (aobjname != NULL && !found)
2186 2349 die("addrobj not found: %s", aobjname);
2187 2350
2188 2351 nvlist_free(proplist);
2189 2352 ofmt_close(ofmt);
2190 2353 if (state.sps_retstatus != IPADM_SUCCESS) {
2191 2354 ipadm_close(iph);
2192 2355 exit(EXIT_FAILURE);
2193 2356 }
2194 2357 }
2195 2358
2196 2359 /*
2197 2360 * check if the `pstr' adheres to following syntax
2198 2361 * - prop=<value[,...]> (for set)
2199 2362 * - prop (for reset)
2200 2363 */
2201 2364 static void
2202 2365 ipadm_check_propstr(const char *pstr, boolean_t reset, const char *use)
2203 2366 {
2204 2367 char *nv;
2205 2368
2206 2369 nv = strchr(pstr, '=');
2207 2370 if (reset) {
2208 2371 if (nv != NULL)
2209 2372 die("incorrect syntax used for -p.\n%s", use);
2210 2373 } else {
2211 2374 if (nv == NULL || *++nv == '\0')
2212 2375 die("please specify the value to be set.\n%s", use);
2213 2376 nv = strchr(nv, '=');
2214 2377 /* cannot have multiple 'prop=val' for single -p */
2215 2378 if (nv != NULL)
2216 2379 die("cannot specify more than one prop=val at "
2217 2380 "a time.\n%s", use);
2218 2381 }
2219 2382 }
|
↓ open down ↓ |
280 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX