3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
24 */
25 #include <arpa/inet.h>
26 #include <errno.h>
27 #include <getopt.h>
28 #include <inet/ip.h>
29 #include <inet/iptun.h>
30 #include <inet/tunables.h>
31 #include <libdladm.h>
32 #include <libdliptun.h>
33 #include <libdllink.h>
34 #include <libinetutil.h>
35 #include <libipadm.h>
36 #include <locale.h>
37 #include <netdb.h>
38 #include <netinet/in.h>
39 #include <ofmt.h>
40 #include <stdarg.h>
41 #include <stddef.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <strings.h>
46 #include <sys/stat.h>
47 #include <sys/types.h>
48 #include <zone.h>
49
50 #define STR_UNKNOWN_VAL "?"
51 #define LIFC_DEFAULT (LIFC_NOXMIT | LIFC_TEMPORARY | LIFC_ALLZONES |\
52 LIFC_UNDER_IPMP)
53
54 typedef void cmdfunc_t(int, char **, const char *);
55 static cmdfunc_t do_create_if, do_delete_if, do_enable_if, do_disable_if;
56 static cmdfunc_t do_show_if;
57 static cmdfunc_t do_set_prop, do_show_prop, do_set_ifprop;
58 static cmdfunc_t do_show_ifprop, do_reset_ifprop, do_reset_prop;
59 static cmdfunc_t do_show_addrprop, do_set_addrprop, do_reset_addrprop;
60 static cmdfunc_t do_create_addr, do_delete_addr, do_show_addr;
61 static cmdfunc_t do_enable_addr, do_disable_addr;
62 static cmdfunc_t do_up_addr, do_down_addr, do_refresh_addr;
63
64 typedef struct cmd {
65 char *c_name;
66 cmdfunc_t *c_fn;
67 const char *c_usage;
68 } cmd_t;
69
70 static cmd_t cmds[] = {
71 /* interface management related sub-commands */
72 { "create-if", do_create_if, "\tcreate-if\t[-t] <interface>" },
73 { "disable-if", do_disable_if, "\tdisable-if\t-t <interface>" },
74 { "enable-if", do_enable_if, "\tenable-if\t-t <interface>" },
75 { "delete-if", do_delete_if, "\tdelete-if\t<interface>" },
76 { "show-if", do_show_if,
77 "\tshow-if\t\t[[-p] -o <field>,...] [<interface>]\n" },
78 { "set-ifprop", do_set_ifprop,
79 "\tset-ifprop\t[-t] -p <prop>=<value[,...]> -m <protocol> "
80 "<interface>" },
81 { "reset-ifprop", do_reset_ifprop,
82 "\treset-ifprop\t[-t] -p <prop> -m <protocol> <interface>" },
83 { "show-ifprop", do_show_ifprop,
84 "\tshow-ifprop\t[[-c] -o <field>,...] [-p <prop>,...]\n"
85 "\t\t\t[-m <protocol>] [interface]\n" },
86
87 /* address management related sub-commands */
88 { "create-addr", do_create_addr,
89 "\tcreate-addr\t[-t] -T static [-d] "
90 "-a{local|remote}=addr[/prefixlen]\n\t\t\t<addrobj>\n"
91 "\tcreate-addr\t[-t] -T dhcp [-w <seconds> | forever] <addrobj>\n"
267 show_addr_state_t *sa_state;
268 ipadm_addr_info_t *sa_info;
269 } show_addr_args_t;
270
271 typedef struct show_if_args_s {
272 show_if_state_t *si_state;
273 ipadm_if_info_t *si_info;
274 } show_if_args_t;
275
276 typedef enum {
277 SA_ADDROBJ,
278 SA_TYPE,
279 SA_STATE,
280 SA_CURRENT,
281 SA_PERSISTENT,
282 SA_ADDR
283 } sa_field_index_t;
284
285 typedef enum {
286 SI_IFNAME,
287 SI_STATE,
288 SI_CURRENT,
289 SI_PERSISTENT
290 } si_field_index_t;
291
292 static ofmt_field_t show_addr_fields[] = {
293 /* name, field width, id, callback */
294 { "ADDROBJ", 18, SA_ADDROBJ, print_sa_cb},
295 { "TYPE", 9, SA_TYPE, print_sa_cb},
296 { "STATE", 13, SA_STATE, print_sa_cb},
297 { "CURRENT", 8, SA_CURRENT, print_sa_cb},
298 { "PERSISTENT", 11, SA_PERSISTENT, print_sa_cb},
299 { "ADDR", 46, SA_ADDR, print_sa_cb},
300 { NULL, 0, 0, NULL}
301 };
302
303 static ofmt_field_t show_if_fields[] = {
304 /* name, field width, id, callback */
305 { "IFNAME", 11, SI_IFNAME, print_si_cb},
306 { "STATE", 9, SI_STATE, print_si_cb},
307 { "CURRENT", 13, SI_CURRENT, print_si_cb},
308 { "PERSISTENT", 11, SI_PERSISTENT, print_si_cb},
309 { NULL, 0, 0, NULL}
310 };
311
312 #define IPADM_ALL_BITS ((uint_t)-1)
313 typedef struct intf_mask {
314 char *name;
315 uint64_t bits;
316 uint64_t mask;
317 } fmask_t;
318
319 /*
320 * Handle to libipadm. Opened in main() before the sub-command specific
321 * function is called and is closed before the program exits.
322 */
323 ipadm_handle_t iph = NULL;
324
325 /*
326 * Opaque ipadm address object. Used by all the address management subcommands.
327 */
328 ipadm_addrobj_t ipaddr = NULL;
329
330 static char *progname;
331
332 static void die(const char *, ...);
333 static void die_opterr(int, int, const char *);
334 static void warn_ipadmerr(ipadm_status_t, const char *, ...);
335 static void ipadm_ofmt_check(ofmt_status_t, boolean_t, ofmt_handle_t);
336 static void ipadm_check_propstr(const char *, boolean_t, const char *);
337 static void process_misc_addrargs(int, char **, const char *, int *,
338 uint32_t *);
339
340 static void
341 usage(void)
342 {
343 int i;
344 cmd_t *cmdp;
345
346 (void) fprintf(stderr,
347 gettext("usage: ipadm <subcommand> <args> ...\n"));
348 for (i = 0; i < sizeof (cmds) / sizeof (cmds[0]); i++) {
349 cmdp = &cmds[i];
350 if (cmdp->c_usage != NULL)
351 (void) fprintf(stderr, "%s\n", gettext(cmdp->c_usage));
352 }
353
354 ipadm_destroy_addrobj(ipaddr);
355 ipadm_close(iph);
356 exit(1);
357 }
358
381 }
382
383 for (i = 0; i < sizeof (cmds) / sizeof (cmds[0]); i++) {
384 cmdp = &cmds[i];
385 if (strcmp(argv[1], cmdp->c_name) == 0) {
386 cmdp->c_fn(argc - 1, &argv[1], gettext(cmdp->c_usage));
387 ipadm_destroy_addrobj(ipaddr);
388 ipadm_close(iph);
389 exit(0);
390 }
391 }
392
393 (void) fprintf(stderr, gettext("%s: unknown subcommand '%s'\n"),
394 progname, argv[1]);
395 usage();
396
397 return (0);
398 }
399
400 /*
401 * Create an IP interface for which no saved configuration exists in the
402 * persistent store.
403 */
404 static void
405 do_create_if(int argc, char *argv[], const char *use)
406 {
407 ipadm_status_t status;
408 int option;
409 uint32_t flags = IPADM_OPT_PERSIST|IPADM_OPT_ACTIVE;
410
411 opterr = 0;
412 while ((option = getopt_long(argc, argv, ":t", if_longopts,
413 NULL)) != -1) {
414 switch (option) {
415 case 't':
416 /*
417 * "ifconfig" mode - plumb interface, but do not
418 * restore settings that may exist in db.
419 */
420 flags &= ~IPADM_OPT_PERSIST;
421 break;
422 default:
423 die_opterr(optopt, option, use);
424 }
425 }
426 if (optind != (argc - 1))
427 die("Usage: %s", use);
428 status = ipadm_create_if(iph, argv[optind], AF_UNSPEC, flags);
429 if (status != IPADM_SUCCESS) {
430 die("Could not create %s : %s",
431 argv[optind], ipadm_status2str(status));
432 }
433 }
434
435 /*
436 * Enable an IP interface based on the persistent configuration for
437 * that interface.
438 */
439 static void
440 do_enable_if(int argc, char *argv[], const char *use)
441 {
442 ipadm_status_t status;
443 int index;
444 uint32_t flags = IPADM_OPT_ACTIVE|IPADM_OPT_PERSIST;
445
446 process_misc_addrargs(argc, argv, use, &index, &flags);
447 if (flags & IPADM_OPT_PERSIST)
448 die("persistent operation not supported for enable-if");
449 status = ipadm_enable_if(iph, argv[index], flags);
450 if (status == IPADM_ALL_ADDRS_NOT_ENABLED) {
451 warn_ipadmerr(status, "");
452 } else if (status != IPADM_SUCCESS) {
453 die("Could not enable %s : %s",
454 argv[optind], ipadm_status2str(status));
455 }
1891 { "s", IFIF_STANDBY, IFIF_STANDBY },
1892 { "4", IFIF_IPV4, IFIF_IPV4 },
1893 { "6", IFIF_IPV6, IFIF_IPV6 },
1894 { NULL, 0, 0 }
1895 };
1896 fmask_t intf_cflags[] = {
1897 { "b", IFIF_BROADCAST, IFIF_BROADCAST },
1898 { "m", IFIF_MULTICAST, IFIF_MULTICAST },
1899 { "p", IFIF_POINTOPOINT, IFIF_POINTOPOINT},
1900 { "v", IFIF_VIRTUAL, IFIF_VIRTUAL },
1901 { "I", IFIF_IPMP, IFIF_IPMP },
1902 { "s", IFIF_STANDBY, IFIF_STANDBY },
1903 { "i", IFIF_INACTIVE, IFIF_INACTIVE },
1904 { "V", IFIF_VRRP, IFIF_VRRP },
1905 { "a", IFIF_NOACCEPT, IFIF_NOACCEPT },
1906 { "Z", IFIF_L3PROTECT, IFIF_L3PROTECT },
1907 { "4", IFIF_IPV4, IFIF_IPV4 },
1908 { "6", IFIF_IPV6, IFIF_IPV6 },
1909 { NULL, 0, 0 }
1910 };
1911
1912 buf[0] = '\0';
1913 switch (ofarg->ofmt_id) {
1914 case SI_IFNAME:
1915 (void) snprintf(buf, bufsize, "%s", ifname);
1916 break;
1917 case SI_STATE:
1918 flags2str(ifinfo->ifi_state, intf_state, _B_FALSE,
1919 buf, bufsize);
1920 break;
1921 case SI_CURRENT:
1922 flags2str(ifinfo->ifi_cflags, intf_cflags, _B_TRUE,
1923 buf, bufsize);
1924 break;
1925 case SI_PERSISTENT:
1926 flags2str(ifinfo->ifi_pflags, intf_pflags, _B_TRUE,
1927 buf, bufsize);
1928 break;
1929 default:
1930 die("invalid input");
1931 break;
1932 }
1933
1934 return (_B_TRUE);
1935 }
1936
|
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
24 */
25 #include <arpa/inet.h>
26 #include <errno.h>
27 #include <getopt.h>
28 #include <inet/ip.h>
29 #include <inet/iptun.h>
30 #include <inet/tunables.h>
31 #include <libdladm.h>
32 #include <libdliptun.h>
33 #include <libdllink.h>
34 #include <libinetutil.h>
35 #include <libipadm.h>
36 #include <ipmp.h>
37 #include <ipmp_admin.h>
38 #include <locale.h>
39 #include <netdb.h>
40 #include <netinet/in.h>
41 #include <ofmt.h>
42 #include <stdarg.h>
43 #include <stddef.h>
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <string.h>
47 #include <strings.h>
48 #include <sys/stat.h>
49 #include <sys/types.h>
50 #include <zone.h>
51 #include <sys/list.h>
52 #include <stddef.h>
53
54 #define STR_UNKNOWN_VAL "?"
55 #define LIFC_DEFAULT (LIFC_NOXMIT | LIFC_TEMPORARY | LIFC_ALLZONES |\
56 LIFC_UNDER_IPMP)
57
58 static void do_create_if_common(int, char **, const char *, uint32_t);
59
60 typedef void cmdfunc_t(int, char **, const char *);
61 static cmdfunc_t do_create_ipmp, do_add_ipmp, do_remove_ipmp;
62 static cmdfunc_t do_create_if, do_delete_if, do_enable_if, do_disable_if;
63 static cmdfunc_t do_show_if;
64 static cmdfunc_t do_set_prop, do_show_prop, do_set_ifprop;
65 static cmdfunc_t do_show_ifprop, do_reset_ifprop, do_reset_prop;
66 static cmdfunc_t do_show_addrprop, do_set_addrprop, do_reset_addrprop;
67 static cmdfunc_t do_create_addr, do_delete_addr, do_show_addr;
68 static cmdfunc_t do_enable_addr, do_disable_addr;
69 static cmdfunc_t do_up_addr, do_down_addr, do_refresh_addr;
70
71 typedef struct cmd {
72 char *c_name;
73 cmdfunc_t *c_fn;
74 const char *c_usage;
75 } cmd_t;
76
77 static cmd_t cmds[] = {
78 /* interface management related sub-commands */
79 { "create-ipmp", do_create_ipmp, "\tcreate-ipmp\t[-t] <ipmp-group>"},
80 { "delete-ipmp", do_delete_if, "\tdelete-ipmp\t[-t] <ipmp-group>"},
81 { "add-ipmp", do_add_ipmp, "\tadd-ipmp\t[-t] -i"
82 " <ipmp-member-interface> "
83 "[-i <ipmp-member-interface>] <ipmp-group-interface>"},
84 { "remove-ipmp", do_remove_ipmp, "\tremove-ipmp\t[-t] -i"
85 " <ipmp-member-interface> "
86 "[-i <ipmp-member-interface>] <ipmp-group-interface>"},
87 { "create-if", do_create_if, "\tcreate-if\t[-t] <interface>" },
88 { "disable-if", do_disable_if, "\tdisable-if\t-t <interface>" },
89 { "enable-if", do_enable_if, "\tenable-if\t-t <interface>" },
90 { "delete-if", do_delete_if, "\tdelete-if\t<interface>" },
91 { "show-if", do_show_if,
92 "\tshow-if\t\t[[-p] -o <field>,...] [<interface>]\n" },
93 { "set-ifprop", do_set_ifprop,
94 "\tset-ifprop\t[-t] -p <prop>=<value[,...]> -m <protocol> "
95 "<interface>" },
96 { "reset-ifprop", do_reset_ifprop,
97 "\treset-ifprop\t[-t] -p <prop> -m <protocol> <interface>" },
98 { "show-ifprop", do_show_ifprop,
99 "\tshow-ifprop\t[[-c] -o <field>,...] [-p <prop>,...]\n"
100 "\t\t\t[-m <protocol>] [interface]\n" },
101
102 /* address management related sub-commands */
103 { "create-addr", do_create_addr,
104 "\tcreate-addr\t[-t] -T static [-d] "
105 "-a{local|remote}=addr[/prefixlen]\n\t\t\t<addrobj>\n"
106 "\tcreate-addr\t[-t] -T dhcp [-w <seconds> | forever] <addrobj>\n"
282 show_addr_state_t *sa_state;
283 ipadm_addr_info_t *sa_info;
284 } show_addr_args_t;
285
286 typedef struct show_if_args_s {
287 show_if_state_t *si_state;
288 ipadm_if_info_t *si_info;
289 } show_if_args_t;
290
291 typedef enum {
292 SA_ADDROBJ,
293 SA_TYPE,
294 SA_STATE,
295 SA_CURRENT,
296 SA_PERSISTENT,
297 SA_ADDR
298 } sa_field_index_t;
299
300 typedef enum {
301 SI_IFNAME,
302 SI_IFCLASS,
303 SI_STATE,
304 SI_CURRENT,
305 SI_PERSISTENT
306 } si_field_index_t;
307
308 static ofmt_field_t show_addr_fields[] = {
309 /* name, field width, id, callback */
310 { "ADDROBJ", 18, SA_ADDROBJ, print_sa_cb},
311 { "TYPE", 9, SA_TYPE, print_sa_cb},
312 { "STATE", 13, SA_STATE, print_sa_cb},
313 { "CURRENT", 8, SA_CURRENT, print_sa_cb},
314 { "PERSISTENT", 11, SA_PERSISTENT, print_sa_cb},
315 { "ADDR", 46, SA_ADDR, print_sa_cb},
316 { NULL, 0, 0, NULL}
317 };
318
319 static ofmt_field_t show_if_fields[] = {
320 /* name, field width, id, callback */
321 { "IFNAME", 11, SI_IFNAME, print_si_cb},
322 { "CLASS", 10, SI_IFCLASS, print_si_cb},
323 { "STATE", 9, SI_STATE, print_si_cb},
324 { "CURRENT", 13, SI_CURRENT, print_si_cb},
325 { "PERSISTENT", 11, SI_PERSISTENT, print_si_cb},
326 { NULL, 0, 0, NULL}
327 };
328
329 #define IPADM_ALL_BITS ((uint_t)-1)
330 typedef struct intf_mask {
331 char *name;
332 uint64_t bits;
333 uint64_t mask;
334 } fmask_t;
335
336 typedef enum {
337 IPMP_ADD_MEMBER,
338 IPMP_REMOVE_MEMBER
339 } ipmp_action_t;
340
341 /*
342 * Handle to libipadm. Opened in main() before the sub-command specific
343 * function is called and is closed before the program exits.
344 */
345 ipadm_handle_t iph = NULL;
346
347 /*
348 * Opaque ipadm address object. Used by all the address management subcommands.
349 */
350 ipadm_addrobj_t ipaddr = NULL;
351
352 static char *progname;
353
354 static void die(const char *, ...);
355 static void die_opterr(int, int, const char *);
356 static void warn_ipadmerr(ipadm_status_t, const char *, ...);
357 static void ipadm_ofmt_check(ofmt_status_t, boolean_t, ofmt_handle_t);
358 static void ipadm_check_propstr(const char *, boolean_t, const char *);
359 static void process_misc_addrargs(int, char **, const char *, int *,
360 uint32_t *);
361 static void do_action_ipmp(int, char **, const char *, ipmp_action_t);
362
363 static void
364 usage(void)
365 {
366 int i;
367 cmd_t *cmdp;
368
369 (void) fprintf(stderr,
370 gettext("usage: ipadm <subcommand> <args> ...\n"));
371 for (i = 0; i < sizeof (cmds) / sizeof (cmds[0]); i++) {
372 cmdp = &cmds[i];
373 if (cmdp->c_usage != NULL)
374 (void) fprintf(stderr, "%s\n", gettext(cmdp->c_usage));
375 }
376
377 ipadm_destroy_addrobj(ipaddr);
378 ipadm_close(iph);
379 exit(1);
380 }
381
404 }
405
406 for (i = 0; i < sizeof (cmds) / sizeof (cmds[0]); i++) {
407 cmdp = &cmds[i];
408 if (strcmp(argv[1], cmdp->c_name) == 0) {
409 cmdp->c_fn(argc - 1, &argv[1], gettext(cmdp->c_usage));
410 ipadm_destroy_addrobj(ipaddr);
411 ipadm_close(iph);
412 exit(0);
413 }
414 }
415
416 (void) fprintf(stderr, gettext("%s: unknown subcommand '%s'\n"),
417 progname, argv[1]);
418 usage();
419
420 return (0);
421 }
422
423 /*
424 * Create regular IP interface or IPMP group interface
425 */
426 static void
427 do_create_if_common(int argc, char *argv[], const char *use, uint32_t flags)
428 {
429 ipadm_status_t status;
430 int option;
431
432 opterr = 0;
433 while ((option = getopt_long(argc, argv,
434 ":t", if_longopts, NULL)) != -1) {
435 switch (option) {
436 case 't':
437 /*
438 * "ifconfig" mode - plumb interface, but do not
439 * restore settings that may exist in db.
440 */
441 flags &= ~IPADM_OPT_PERSIST;
442 break;
443 default:
444 die_opterr(optopt, option, use);
445 }
446 }
447 if (optind != (argc - 1))
448 die("Usage: %s", use);
449 status = ipadm_create_if(iph, argv[optind], AF_UNSPEC, flags);
450 if (status != IPADM_SUCCESS) {
451 die("Could not create %s : %s",
452 argv[optind], ipadm_status2str(status));
453 }
454 }
455
456 /*
457 * Create an IPMP group interface for which no saved configuration
458 * exists in the persistent store.
459 */
460 static void
461 do_create_ipmp(int argc, char *argv[], const char *use)
462 {
463 ipmp_handle_t ipmp_handle;
464 int retval;
465 uint32_t flags = IPADM_OPT_PERSIST | IPADM_OPT_ACTIVE | IPADM_OPT_IPMP;
466
467 retval = ipmp_open(&ipmp_handle);
468 if (retval != IPMP_SUCCESS) {
469 die("Could not create IPMP handle: %s",
470 ipadm_status2str(retval));
471 }
472
473 retval = ipmp_ping_daemon(ipmp_handle);
474 ipmp_close(ipmp_handle);
475
476 if (retval != IPMP_SUCCESS) {
477 die("Cannot ping in.mpathd: %s", ipmp_errmsg(retval));
478 }
479
480 do_create_if_common(argc, argv, use, flags);
481 }
482
483 static void
484 do_add_ipmp(int argc, char *argv[], const char *use)
485 {
486 do_action_ipmp(argc, argv, use, IPMP_ADD_MEMBER);
487 }
488
489 static void
490 do_remove_ipmp(int argc, char *argv[], const char *use)
491 {
492 do_action_ipmp(argc, argv, use, IPMP_REMOVE_MEMBER);
493 }
494
495 static void
496 do_action_ipmp(int argc, char *argv[], const char *use,
497 ipmp_action_t action)
498 {
499 int option;
500 ipadm_status_t status;
501 ipadm_ipmp_members_t members;
502 ipadm_ipmp_member_t *ipmp_member;
503 uint32_t flags = IPADM_OPT_PERSIST | IPADM_OPT_ACTIVE;
504
505 list_create(&members, sizeof (ipadm_ipmp_member_t),
506 offsetof(ipadm_ipmp_member_t, node));
507
508 opterr = 0;
509 while ((option = getopt_long(argc, argv,
510 ":ti:", if_longopts, NULL)) != -1) {
511 switch (option) {
512 case 't':
513 flags &= ~IPADM_OPT_PERSIST;
514 break;
515 case 'i':
516 if ((ipmp_member = calloc(1,
517 sizeof (ipadm_ipmp_member_t))) == NULL)
518 die("insufficient memory");
519
520 if (strlcpy(ipmp_member->if_name,
521 optarg, sizeof (ipmp_member->if_name)) >= LIFNAMSIZ)
522 die("Incorrect length of interface"
523 "name: %s", optarg);
524
525 list_insert_tail(&members, ipmp_member);
526 break;
527 default:
528 die_opterr(optopt, option, use);
529 }
530 }
531
532 if (optind != (argc - 1))
533 die("Usage: %s", use);
534
535 while ((ipmp_member = list_remove_head(&members)) != NULL) {
536 switch (action) {
537 case IPMP_ADD_MEMBER:
538 if ((status = ipadm_add_ipmp_member(iph,
539 argv[optind], ipmp_member->if_name, flags))
540 != IPADM_SUCCESS)
541 die("Cannot add '%s' interface to"
542 "'%s': %s",
543 ipmp_member->if_name, argv[optind],
544 ipadm_status2str(status));
545 break;
546 case IPMP_REMOVE_MEMBER:
547 if ((status = ipadm_remove_ipmp_member(iph,
548 argv[optind], ipmp_member->if_name, flags))
549 != IPADM_SUCCESS)
550 die("Cannot remove '%s' interface from "
551 "'%s': %s",
552 ipmp_member->if_name, argv[optind],
553 ipadm_status2str(status));
554 break;
555 }
556
557 free(ipmp_member);
558 }
559
560 list_destroy(&members);
561 }
562
563 /*
564 * Create an IP interface for which no saved configuration exists in the
565 * persistent store.
566 */
567 static void
568 do_create_if(int argc, char *argv[], const char *use)
569 {
570 do_create_if_common(argc, argv, use,
571 IPADM_OPT_PERSIST | IPADM_OPT_ACTIVE);
572 }
573
574 /*
575 * Enable an IP interface based on the persistent configuration for
576 * that interface.
577 */
578 static void
579 do_enable_if(int argc, char *argv[], const char *use)
580 {
581 ipadm_status_t status;
582 int index;
583 uint32_t flags = IPADM_OPT_ACTIVE|IPADM_OPT_PERSIST;
584
585 process_misc_addrargs(argc, argv, use, &index, &flags);
586 if (flags & IPADM_OPT_PERSIST)
587 die("persistent operation not supported for enable-if");
588 status = ipadm_enable_if(iph, argv[index], flags);
589 if (status == IPADM_ALL_ADDRS_NOT_ENABLED) {
590 warn_ipadmerr(status, "");
591 } else if (status != IPADM_SUCCESS) {
592 die("Could not enable %s : %s",
593 argv[optind], ipadm_status2str(status));
594 }
2030 { "s", IFIF_STANDBY, IFIF_STANDBY },
2031 { "4", IFIF_IPV4, IFIF_IPV4 },
2032 { "6", IFIF_IPV6, IFIF_IPV6 },
2033 { NULL, 0, 0 }
2034 };
2035 fmask_t intf_cflags[] = {
2036 { "b", IFIF_BROADCAST, IFIF_BROADCAST },
2037 { "m", IFIF_MULTICAST, IFIF_MULTICAST },
2038 { "p", IFIF_POINTOPOINT, IFIF_POINTOPOINT},
2039 { "v", IFIF_VIRTUAL, IFIF_VIRTUAL },
2040 { "I", IFIF_IPMP, IFIF_IPMP },
2041 { "s", IFIF_STANDBY, IFIF_STANDBY },
2042 { "i", IFIF_INACTIVE, IFIF_INACTIVE },
2043 { "V", IFIF_VRRP, IFIF_VRRP },
2044 { "a", IFIF_NOACCEPT, IFIF_NOACCEPT },
2045 { "Z", IFIF_L3PROTECT, IFIF_L3PROTECT },
2046 { "4", IFIF_IPV4, IFIF_IPV4 },
2047 { "6", IFIF_IPV6, IFIF_IPV6 },
2048 { NULL, 0, 0 }
2049 };
2050 fmask_t intf_class[] = {
2051 { "IP", IPADM_IF_CLASS_REGULAR, IPADM_ALL_BITS},
2052 { "IPMP", IPADM_IF_CLASS_IPMP, IPADM_ALL_BITS},
2053 { "VIRTUAL", IPADM_IF_CLASS_VIRTUAL, IPADM_ALL_BITS},
2054 { "UNKNOWN", IPADM_IF_CLASS_UNKNOWN, IPADM_ALL_BITS},
2055 { NULL, 0, 0}
2056 };
2057
2058 buf[0] = '\0';
2059 switch (ofarg->ofmt_id) {
2060 case SI_IFNAME:
2061 (void) snprintf(buf, bufsize, "%s", ifname);
2062 break;
2063 case SI_IFCLASS:
2064 flags2str(ifinfo->ifi_class, intf_class, _B_FALSE,
2065 buf, bufsize);
2066 break;
2067 case SI_STATE:
2068 flags2str(ifinfo->ifi_state, intf_state, _B_FALSE,
2069 buf, bufsize);
2070 break;
2071 case SI_CURRENT:
2072 flags2str(ifinfo->ifi_cflags, intf_cflags, _B_TRUE,
2073 buf, bufsize);
2074 break;
2075 case SI_PERSISTENT:
2076 flags2str(ifinfo->ifi_pflags, intf_pflags, _B_TRUE,
2077 buf, bufsize);
2078 break;
2079 default:
2080 die("invalid input");
2081 break;
2082 }
2083
2084 return (_B_TRUE);
2085 }
2086
|