Print this page
OS-792 dladm show-linkprop -z zonename doesn't restrict output to that zone, unless you also specify the vnic name
OS-406
OS-249


   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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.

  23  */
  24 
  25 #include <stdio.h>
  26 #include <ctype.h>
  27 #include <dlfcn.h>
  28 #include <locale.h>
  29 #include <signal.h>
  30 #include <stdarg.h>
  31 #include <stdlib.h>
  32 #include <fcntl.h>
  33 #include <string.h>
  34 #include <stropts.h>
  35 #include <sys/stat.h>
  36 #include <errno.h>
  37 #include <kstat.h>
  38 #include <strings.h>
  39 #include <getopt.h>
  40 #include <unistd.h>
  41 #include <priv.h>
  42 #include <limits.h>


 137         ofmt_handle_t   gs_ofmt;
 138 } show_grp_state_t;
 139 
 140 typedef struct show_vnic_state {
 141         datalink_id_t   vs_vnic_id;
 142         datalink_id_t   vs_link_id;
 143         char            vs_vnic[MAXLINKNAMELEN];
 144         char            vs_link[MAXLINKNAMELEN];
 145         boolean_t       vs_parsable;
 146         boolean_t       vs_found;
 147         boolean_t       vs_firstonly;
 148         boolean_t       vs_donefirst;
 149         boolean_t       vs_stats;
 150         boolean_t       vs_printstats;
 151         pktsum_t        vs_totalstats;
 152         pktsum_t        vs_prevstats[MAXVNIC];
 153         boolean_t       vs_etherstub;
 154         dladm_status_t  vs_status;
 155         uint32_t        vs_flags;
 156         ofmt_handle_t   vs_ofmt;

 157 } show_vnic_state_t;
 158 
 159 typedef struct show_part_state {
 160         datalink_id_t   ps_over_id;
 161         char            ps_part[MAXLINKNAMELEN];
 162         boolean_t       ps_parsable;
 163         boolean_t       ps_found;
 164         dladm_status_t  ps_status;
 165         uint32_t        ps_flags;
 166         ofmt_handle_t   ps_ofmt;
 167 } show_part_state_t;
 168 
 169 typedef struct show_ib_state {
 170         datalink_id_t   is_link_id;
 171         char            is_link[MAXLINKNAMELEN];
 172         boolean_t       is_parsable;
 173         dladm_status_t  is_status;
 174         uint32_t        is_flags;
 175         ofmt_handle_t   is_ofmt;
 176 } show_ib_state_t;


 248 static int      show_etherprop(dladm_handle_t, datalink_id_t, void *);
 249 static void     show_ether_xprop(void *, dladm_ether_info_t *);
 250 static boolean_t        link_is_ether(const char *, datalink_id_t *);
 251 
 252 static boolean_t str2int(const char *, int *);
 253 static void     die(const char *, ...);
 254 static void     die_optdup(int);
 255 static void     die_opterr(int, int, const char *);
 256 static void     die_dlerr(dladm_status_t, const char *, ...);
 257 static void     warn(const char *, ...);
 258 static void     warn_dlerr(dladm_status_t, const char *, ...);
 259 
 260 typedef struct  cmd {
 261         char            *c_name;
 262         cmdfunc_t       *c_fn;
 263         const char      *c_usage;
 264 } cmd_t;
 265 
 266 static cmd_t    cmds[] = {
 267         { "rename-link",        do_rename_link,
 268             "    rename-link      <oldlink> <newlink>"                      },
 269         { "show-link",          do_show_link,
 270             "    show-link        [-pP] [-o <field>,..] [-s [-i <interval>]] "
 271             "[<link>]\n"                                          },
 272         { "create-aggr",        do_create_aggr,
 273             "    create-aggr      [-t] [-P <policy>] [-L <mode>] [-T <time>] "
 274             "[-u <address>]\n"
 275             "\t\t     -l <link> [-l <link>...] <link>"                        },
 276         { "delete-aggr",        do_delete_aggr,
 277             "    delete-aggr      [-t] <link>"                            },
 278         { "add-aggr",           do_add_aggr,
 279             "    add-aggr         [-t] -l <link> [-l <link>...] <link>" },
 280         { "remove-aggr",        do_remove_aggr,
 281             "    remove-aggr      [-t] -l <link> [-l <link>...] <link>" },
 282         { "modify-aggr",        do_modify_aggr,
 283             "    modify-aggr      [-t] [-P <policy>] [-L <mode>] [-T <time>] "
 284             "[-u <address>]\n"
 285             "\t\t     <link>"                                             },
 286         { "show-aggr",          do_show_aggr,
 287             "    show-aggr        [-pPLx] [-o <field>,..] [-s [-i <interval>]] "
 288             "[<link>]\n"                                          },
 289         { "up-aggr",            do_up_aggr,     NULL                    },
 290         { "scan-wifi",          do_scan_wifi,
 291             "    scan-wifi        [-p] [-o <field>,...] [<link>]"   },
 292         { "connect-wifi",       do_connect_wifi,
 293             "    connect-wifi     [-e <essid>] [-i <bssid>] [-k <key>,...] "
 294             "[-s wep|wpa]\n"
 295             "\t\t     [-a open|shared] [-b bss|ibss] [-c] [-m a|b|g] "
 296             "[-T <time>]\n"
 297             "\t\t     [<link>]"                                           },
 298         { "disconnect-wifi",    do_disconnect_wifi,
 299             "    disconnect-wifi  [-a] [<link>]"                  },
 300         { "show-wifi",          do_show_wifi,
 301             "    show-wifi        [-p] [-o <field>,...] [<link>]\n" },
 302         { "set-linkprop",       do_set_linkprop,
 303             "    set-linkprop     [-t] -p <prop>=<value>[,...] <name>"        },

 304         { "reset-linkprop",     do_reset_linkprop,
 305             "    reset-linkprop   [-t] [-p <prop>,...] <name>"              },
 306         { "show-linkprop",      do_show_linkprop,
 307             "    show-linkprop    [-cP] [-o <field>,...] [-p <prop>,...] "
 308             "<name>\n"                                                    },
 309         { "show-ether",         do_show_ether,
 310             "    show-ether       [-px][-o <field>,...] <link>\n"   },
 311         { "create-secobj",      do_create_secobj,
 312             "    create-secobj    [-t] [-f <file>] -c <class> <secobj>"       },
 313         { "delete-secobj",      do_delete_secobj,
 314             "    delete-secobj    [-t] <secobj>[,...]"                    },
 315         { "show-secobj",        do_show_secobj,
 316             "    show-secobj      [-pP] [-o <field>,...] [<secobj>,...]\n" },
 317         { "init-linkprop",      do_init_linkprop,       NULL            },
 318         { "init-secobj",        do_init_secobj,         NULL            },
 319         { "create-vlan",        do_create_vlan,
 320             "    create-vlan      [-ft] -l <link> -v <vid> [link]"  },
 321         { "delete-vlan",        do_delete_vlan,
 322             "    delete-vlan      [-t] <link>"                            },
 323         { "show-vlan",          do_show_vlan,
 324             "    show-vlan        [-pP] [-o <field>,..] [<link>]\n" },
 325         { "up-vlan",            do_up_vlan,             NULL            },
 326         { "create-iptun",       do_create_iptun,
 327             "    create-iptun     [-t] -T <type> "
 328             "[-a {local|remote}=<addr>,...] <link>]" },


 330             "    delete-iptun     [-t] <link>"                            },
 331         { "modify-iptun",       do_modify_iptun,
 332             "    modify-iptun     [-t] -a {local|remote}=<addr>,... <link>" },
 333         { "show-iptun",         do_show_iptun,
 334             "    show-iptun       [-pP] [-o <field>,..] [<link>]\n" },
 335         { "up-iptun",           do_up_iptun,            NULL            },
 336         { "down-iptun",         do_down_iptun,          NULL            },
 337         { "delete-phys",        do_delete_phys,
 338             "    delete-phys      <link>"                         },
 339         { "show-phys",          do_show_phys,
 340             "    show-phys        [-m | -H | -P] [[-p] [-o <field>[,...]] "
 341             "[<link>]\n"                                          },
 342         { "init-phys",          do_init_phys,           NULL            },
 343         { "show-linkmap",       do_show_linkmap,        NULL            },
 344         { "create-vnic",        do_create_vnic,
 345             "    create-vnic      [-t] -l <link> [-m <value> | auto |\n"
 346             "\t\t     {factory [-n <slot-id>]} | {random [-r <prefix>]} |\n"
 347             "\t\t     {vrrp -V <vrid> -A {inet | inet6}} [-v <vid> [-f]]\n"
 348             "\t\t     [-p <prop>=<value>[,...]] <vnic-link>"  },
 349         { "delete-vnic",        do_delete_vnic,
 350             "    delete-vnic      [-t] <vnic-link>"                       },
 351         { "show-vnic",          do_show_vnic,
 352             "    show-vnic        [-pP] [-l <link>] [-s [-i <interval>]] "
 353             "[<link>]\n"                                          },
 354         { "up-vnic",            do_up_vnic,             NULL            },
 355         { "create-part",        do_create_part,
 356             "    create-part      [-t] [-f] -l <link> [-P <pkey>]\n"
 357             "\t\t     [-R <root-dir>] <part-link>"                  },
 358         { "delete-part",        do_delete_part,
 359             "    delete-part      [-t] [-R <root-dir>] <part-link>"},
 360         { "show-part",          do_show_part,
 361             "    show-part        [-pP] [-o <field>,...][-l <linkover>]\n"
 362             "\t\t     [<part-link>]"              },
 363         { "show-ib",            do_show_ib,
 364             "    show-ib          [-p] [-o <field>,...] [<link>]\n" },
 365         { "up-part",            do_up_part,             NULL            },
 366         { "create-etherstub",   do_create_etherstub,
 367             "    create-etherstub [-t] <link>"                            },
 368         { "delete-etherstub",   do_delete_etherstub,
 369             "    delete-etherstub [-t] <link>"                            },
 370         { "show-etherstub",     do_show_etherstub,
 371             "    show-etherstub   [-t] [<link>]\n"                        },
 372         { "create-simnet",      do_create_simnet,       NULL            },
 373         { "modify-simnet",      do_modify_simnet,       NULL            },


 942         LINKPROP_POSSIBLE
 943 } linkprop_field_index_t;
 944 
 945 static const ofmt_field_t linkprop_fields[] = {
 946 /* name,        field width,  index */
 947 { "LINK",       13,     LINKPROP_LINK,          print_linkprop_cb},
 948 { "PROPERTY",   16,     LINKPROP_PROPERTY,      print_linkprop_cb},
 949 { "PERM",       5,      LINKPROP_PERM,          print_linkprop_cb},
 950 { "VALUE",      15,     LINKPROP_VALUE,         print_linkprop_cb},
 951 { "DEFAULT",    15,     LINKPROP_DEFAULT,       print_linkprop_cb},
 952 { "POSSIBLE",   20,     LINKPROP_POSSIBLE,      print_linkprop_cb},
 953 { NULL,         0,      0,                      NULL}}
 954 ;
 955 
 956 #define MAX_PROP_LINE           512
 957 
 958 typedef struct show_linkprop_state {
 959         char                    ls_link[MAXLINKNAMELEN];
 960         char                    *ls_line;
 961         char                    **ls_propvals;

 962         dladm_arg_list_t        *ls_proplist;
 963         boolean_t               ls_parsable;
 964         boolean_t               ls_persist;
 965         boolean_t               ls_header;
 966         dladm_status_t          ls_status;
 967         dladm_status_t          ls_retstatus;
 968         ofmt_handle_t           ls_ofmt;
 969 } show_linkprop_state_t;
 970 
 971 typedef struct set_linkprop_state {
 972         const char              *ls_name;
 973         boolean_t               ls_reset;
 974         boolean_t               ls_temp;
 975         dladm_status_t          ls_status;
 976 } set_linkprop_state_t;
 977 
 978 typedef struct linkprop_args_s {
 979         show_linkprop_state_t   *ls_state;
 980         char                    *ls_propname;
 981         datalink_id_t           ls_linkid;


 994 { "OBJECT",     21,
 995         offsetof(secobj_fields_buf_t, ss_obj_name), print_default_cb},
 996 { "CLASS",      21,
 997         offsetof(secobj_fields_buf_t, ss_class), print_default_cb},
 998 { "VALUE",      31,
 999         offsetof(secobj_fields_buf_t, ss_val), print_default_cb},
1000 { NULL,         0, 0, NULL}}
1001 ;
1002 
1003 /*
1004  * structures for 'dladm show-vnic'
1005  */
1006 typedef struct vnic_fields_buf_s
1007 {
1008         char vnic_link[DLPI_LINKNAME_MAX];
1009         char vnic_over[DLPI_LINKNAME_MAX];
1010         char vnic_speed[6];
1011         char vnic_macaddr[18];
1012         char vnic_macaddrtype[19];
1013         char vnic_vid[6];

1014 } vnic_fields_buf_t;
1015 
1016 static const ofmt_field_t vnic_fields[] = {
1017 { "LINK",               13,
1018         offsetof(vnic_fields_buf_t, vnic_link), print_default_cb},
1019 { "OVER",               13,
1020         offsetof(vnic_fields_buf_t, vnic_over), print_default_cb},
1021 { "SPEED",              7,
1022         offsetof(vnic_fields_buf_t, vnic_speed), print_default_cb},
1023 { "MACADDRESS",         18,
1024         offsetof(vnic_fields_buf_t, vnic_macaddr), print_default_cb},
1025 { "MACADDRTYPE",        20,
1026         offsetof(vnic_fields_buf_t, vnic_macaddrtype), print_default_cb},
1027 { "VID",                7,
1028         offsetof(vnic_fields_buf_t, vnic_vid), print_default_cb},


1029 { NULL,                 0, 0, NULL}}
1030 ;
1031 
1032 /*
1033  * structures for 'dladm show-ib'
1034  */
1035 typedef struct ib_fields_buf_s
1036 {
1037         char ib_link[DLPI_LINKNAME_MAX];
1038         char ib_hcaguid[17];
1039         char ib_portguid[17];
1040         char ib_portnum[4];
1041         char ib_state[6];
1042         char ib_pkeys[MAXPKEYSTRSZ];
1043 } ib_fields_buf_t;
1044 
1045 static const ofmt_field_t ib_fields[] = {
1046 { "LINK",               13,
1047         offsetof(ib_fields_buf_t, ib_link),     print_default_cb},
1048 { "HCAGUID",            IBGUIDSTRLEN,


2478         status = dladm_vlan_delete(handle, linkid, flags);
2479 done:
2480         if (status != DLADM_STATUS_OK)
2481                 die_dlerr(status, "delete operation failed");
2482 }
2483 
2484 /*ARGSUSED*/
2485 static void
2486 do_up_vlan(int argc, char *argv[], const char *use)
2487 {
2488         do_up_vnic_common(argc, argv, use, B_TRUE);
2489 }
2490 
2491 static void
2492 do_rename_link(int argc, char *argv[], const char *use)
2493 {
2494         int             option;
2495         char            *link1, *link2;
2496         char            *altroot = NULL;
2497         dladm_status_t  status;

2498 
2499         opterr = 0;
2500         while ((option = getopt_long(argc, argv, ":R:", lopts, NULL)) != -1) {
2501                 switch (option) {
2502                 case 'R':
2503                         altroot = optarg;
2504                         break;



2505                 default:
2506                         die_opterr(optopt, option, use);
2507                         break;
2508                 }
2509         }
2510 
2511         /* get link1 and link2 name (required the last 2 arguments) */
2512         if (optind != (argc - 2))
2513                 usage();
2514 
2515         if (altroot != NULL)
2516                 altroot_cmd(altroot, argc, argv);
2517 
2518         link1 = argv[optind++];
2519         link2 = argv[optind];
2520         if ((status = dladm_rename_link(handle, link1, link2)) !=
2521             DLADM_STATUS_OK)
2522                 die_dlerr(status, "rename operation failed");
2523 }
2524 
2525 /*ARGSUSED*/
2526 static void
2527 do_delete_phys(int argc, char *argv[], const char *use)
2528 {
2529         datalink_id_t   linkid = DATALINK_ALL_LINKID;
2530         dladm_status_t  status;
2531 
2532         /* get link name (required the last argument) */
2533         if (argc > 2)
2534                 usage();
2535 
2536         if (argc == 2) {
2537                 if ((status = dladm_name2info(handle, argv[1], &linkid, NULL,
2538                     NULL, NULL)) != DLADM_STATUS_OK)
2539                         die_dlerr(status, "cannot delete '%s'", argv[1]);
2540         }


3390         int             option;
3391         boolean_t       s_arg = B_FALSE;
3392         boolean_t       S_arg = B_FALSE;
3393         boolean_t       i_arg = B_FALSE;
3394         uint32_t        flags = DLADM_OPT_ACTIVE;
3395         boolean_t       p_arg = B_FALSE;
3396         datalink_id_t   linkid = DATALINK_ALL_LINKID;
3397         char            linkname[MAXLINKNAMELEN];
3398         uint32_t        interval = 0;
3399         show_state_t    state;
3400         dladm_status_t  status;
3401         boolean_t       o_arg = B_FALSE;
3402         char            *fields_str = NULL;
3403         char            *all_active_fields = "link,class,mtu,state,bridge,over";
3404         char            *all_inactive_fields = "link,class,bridge,over";
3405         char            *allstat_fields =
3406             "link,ipackets,rbytes,ierrors,opackets,obytes,oerrors";
3407         ofmt_handle_t   ofmt;
3408         ofmt_status_t   oferr;
3409         uint_t          ofmtflags = 0;

3410 
3411         bzero(&state, sizeof (state));
3412 
3413         opterr = 0;
3414         while ((option = getopt_long(argc, argv, ":pPsSi:o:",
3415             show_lopts, NULL)) != -1) {
3416                 switch (option) {
3417                 case 'p':
3418                         if (p_arg)
3419                                 die_optdup(option);
3420 
3421                         p_arg = B_TRUE;
3422                         break;
3423                 case 's':
3424                         if (s_arg)
3425                                 die_optdup(option);
3426 
3427                         s_arg = B_TRUE;
3428                         break;
3429                 case 'P':
3430                         if (flags != DLADM_OPT_ACTIVE)
3431                                 die_optdup(option);
3432 
3433                         flags = DLADM_OPT_PERSIST;
3434                         break;
3435                 case 'S':
3436                         if (S_arg)
3437                                 die_optdup(option);
3438 
3439                         S_arg = B_TRUE;
3440                         break;
3441                 case 'o':
3442                         o_arg = B_TRUE;
3443                         fields_str = optarg;
3444                         break;
3445                 case 'i':
3446                         if (i_arg)
3447                                 die_optdup(option);
3448 
3449                         i_arg = B_TRUE;
3450                         if (!dladm_str2interval(optarg, &interval))
3451                                 die("invalid interval value '%s'", optarg);
3452                         break;



3453                 default:
3454                         die_opterr(optopt, option, use);
3455                         break;
3456                 }
3457         }
3458 
3459         if (i_arg && !(s_arg || S_arg))
3460                 die("the option -i can be used only with -s or -S");
3461 
3462         if (s_arg && S_arg)
3463                 die("the -s option cannot be used with -S");
3464 
3465         if (s_arg && flags != DLADM_OPT_ACTIVE)
3466                 die("the option -P cannot be used with -s");
3467 
3468         if (S_arg && (p_arg || flags != DLADM_OPT_ACTIVE))
3469                 die("the option -%c cannot be used with -S", p_arg ? 'p' : 'P');
3470 
3471         /* get link name (optional last argument) */
3472         if (optind == (argc-1)) {
3473                 uint32_t        f;
3474 
3475                 if (strlcpy(linkname, argv[optind], MAXLINKNAMELEN) >=
3476                     MAXLINKNAMELEN)
3477                         die("link name too long");
3478                 if ((status = dladm_name2info(handle, linkname, &linkid, &f,
3479                     NULL, NULL)) != DLADM_STATUS_OK) {
3480                         die_dlerr(status, "link %s is not valid", linkname);
3481                 }
3482 
3483                 if (!(f & flags)) {
3484                         die_dlerr(DLADM_STATUS_BADARG, "link %s is %s",
3485                             argv[optind], flags == DLADM_OPT_PERSIST ?
3486                             "a temporary link" : "temporarily removed");
3487                 }
3488         } else if (optind != argc) {
3489                 usage();
3490         }
3491 
3492         if (p_arg && !o_arg)
3493                 die("-p requires -o");
3494 
3495         if (S_arg) {
3496                 dladm_continuous(handle, linkid, NULL, interval, LINK_REPORT);
3497                 return;
3498         }
3499 


4724                                 die("invalid VLAN identifier '%s'", optarg);
4725 
4726                         break;
4727                 case 'f':
4728                         flags |= DLADM_OPT_FORCE;
4729                         break;
4730                 default:
4731                         die_opterr(optopt, option, use);
4732                 }
4733         }
4734 
4735         if (mac_addr_type == VNIC_MAC_ADDR_TYPE_UNKNOWN)
4736                 mac_addr_type = VNIC_MAC_ADDR_TYPE_AUTO;
4737 
4738         /*
4739          * 'f' - force, flag can be specified only with 'v' - vlan.
4740          */
4741         if ((flags & DLADM_OPT_FORCE) != 0 && vid == 0)
4742                 die("-f option can only be used with -v");
4743 






4744         if (mac_prefix_len != 0 && mac_addr_type != VNIC_MAC_ADDR_TYPE_RANDOM &&
4745             mac_addr_type != VNIC_MAC_ADDR_TYPE_FIXED)
4746                 usage();
4747 
4748         if (mac_addr_type == VNIC_MAC_ADDR_TYPE_VRID) {
4749                 if (vrid == VRRP_VRID_NONE || af == AF_UNSPEC ||
4750                     mac_addr != NULL || maclen != 0 || mac_slot != -1 ||
4751                     mac_prefix_len != 0) {
4752                         usage();
4753                 }
4754         } else if ((af != AF_UNSPEC || vrid != VRRP_VRID_NONE)) {
4755                 usage();
4756         }
4757 
4758         /* check required options */
4759         if (!l_arg)
4760                 usage();
4761 
4762         if (mac_slot != -1 && mac_addr_type != VNIC_MAC_ADDR_TYPE_FACTORY)
4763                 usage();


4815                  * Let the delete continue anyway.
4816                  */
4817                 return;
4818         }
4819         is_etherstub = (attr.va_link_id == DATALINK_INVALID_LINKID);
4820         if (is_etherstub != etherstub) {
4821                 die("'%s' is not %s", name,
4822                     (is_etherstub ? "a vnic" : "an etherstub"));
4823         }
4824 }
4825 
4826 static void
4827 do_delete_vnic_common(int argc, char *argv[], const char *use,
4828     boolean_t etherstub)
4829 {
4830         int option;
4831         uint32_t flags = DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST;
4832         datalink_id_t linkid;
4833         char *altroot = NULL;
4834         dladm_status_t status;

4835 
4836         opterr = 0;
4837         while ((option = getopt_long(argc, argv, ":R:t", lopts,
4838             NULL)) != -1) {
4839                 switch (option) {
4840                 case 't':
4841                         flags &= ~DLADM_OPT_PERSIST;
4842                         break;
4843                 case 'R':
4844                         altroot = optarg;
4845                         break;



4846                 default:
4847                         die_opterr(optopt, option, use);
4848                 }
4849         }
4850 
4851         /* get vnic name (required last argument) */
4852         if (optind != (argc - 1))
4853                 usage();
4854 
4855         if (altroot != NULL)
4856                 altroot_cmd(altroot, argc, argv);
4857 
4858         status = dladm_name2info(handle, argv[optind], &linkid, NULL, NULL,
4859             NULL);
4860         if (status != DLADM_STATUS_OK)
4861                 die("invalid link name '%s'", argv[optind]);
4862 
4863         if ((flags & DLADM_OPT_ACTIVE) != 0) {
4864                 do_etherstub_check(argv[optind], linkid, etherstub,
4865                     DLADM_OPT_ACTIVE);
4866         }
4867         if ((flags & DLADM_OPT_PERSIST) != 0) {
4868                 do_etherstub_check(argv[optind], linkid, etherstub,
4869                     DLADM_OPT_PERSIST);
4870         }
4871 
4872         status = dladm_vnic_delete(handle, linkid, flags);
4873         if (status != DLADM_STATUS_OK)
4874                 die_dlerr(status, "vnic deletion failed");
4875 }
4876 
4877 static void
4878 do_delete_vnic(int argc, char *argv[], const char *use)
4879 {


4971         }
4972         (void) printf("\n");
4973 
4974         *old_stats = *vnic_stats;
4975 }
4976 
4977 /*
4978  * Called from the walker dladm_vnic_walk_sys() for each vnic to display
4979  * vnic information or statistics.
4980  */
4981 static dladm_status_t
4982 print_vnic(show_vnic_state_t *state, datalink_id_t linkid)
4983 {
4984         dladm_vnic_attr_t       attr, *vnic = &attr;
4985         dladm_status_t          status;
4986         boolean_t               is_etherstub;
4987         char                    devname[MAXLINKNAMELEN];
4988         char                    vnic_name[MAXLINKNAMELEN];
4989         char                    mstr[MAXMACADDRLEN * 3];
4990         vnic_fields_buf_t       vbuf;



4991 
4992         if ((status = dladm_vnic_info(handle, linkid, vnic, state->vs_flags)) !=
4993             DLADM_STATUS_OK)
4994                 return (status);
4995 
4996         is_etherstub = (vnic->va_link_id == DATALINK_INVALID_LINKID);
4997         if (state->vs_etherstub != is_etherstub) {
4998                 /*
4999                  * Want all etherstub but it's not one, or want
5000                  * non-etherstub and it's one.
5001                  */
5002                 return (DLADM_STATUS_OK);
5003         }
5004 
5005         if (state->vs_link_id != DATALINK_ALL_LINKID) {
5006                 if (state->vs_link_id != vnic->va_link_id)
5007                         return (DLADM_STATUS_OK);
5008         }
5009 
5010         if (dladm_datalink_id2info(handle, linkid, NULL, NULL,
5011             NULL, vnic_name, sizeof (vnic_name)) != DLADM_STATUS_OK)
5012                 return (DLADM_STATUS_BADARG);
5013 
5014         bzero(devname, sizeof (devname));
5015         if (!is_etherstub &&
5016             dladm_datalink_id2info(handle, vnic->va_link_id, NULL, NULL,
5017             NULL, devname, sizeof (devname)) != DLADM_STATUS_OK)
5018                 (void) sprintf(devname, "?");
5019 












5020         state->vs_found = B_TRUE;
5021         if (state->vs_stats) {
5022                 /* print vnic statistics */
5023                 pktsum_t vnic_stats;
5024 
5025                 if (state->vs_firstonly) {
5026                         if (state->vs_donefirst)
5027                                 return (0);
5028                         state->vs_donefirst = B_TRUE;
5029                 }
5030 
5031                 if (!state->vs_printstats) {
5032                         /*
5033                          * get vnic statistics and add to the sum for the
5034                          * named device.
5035                          */
5036                         get_link_stats(vnic_name, &vnic_stats);
5037                         dladm_stats_total(&state->vs_totalstats, &vnic_stats,
5038                             &state->vs_prevstats[vnic->va_vnic_id]);
5039                 } else {


5075                                     vnic->va_mac_slot);
5076                                 break;
5077                         case VNIC_MAC_ADDR_TYPE_VRID:
5078                                 (void) snprintf(vbuf.vnic_macaddrtype,
5079                                     sizeof (vbuf.vnic_macaddrtype),
5080                                     gettext("vrrp, %d/%s"),
5081                                     vnic->va_vrid, vnic->va_af == AF_INET ?
5082                                     "inet" : "inet6");
5083                                 break;
5084                         }
5085 
5086                         if (strlen(vbuf.vnic_macaddrtype) > 0) {
5087                                 (void) snprintf(vbuf.vnic_macaddr,
5088                                     sizeof (vbuf.vnic_macaddr), "%s",
5089                                     dladm_aggr_macaddr2str(vnic->va_mac_addr,
5090                                     mstr));
5091                         }
5092 
5093                         (void) snprintf(vbuf.vnic_vid, sizeof (vbuf.vnic_vid),
5094                             "%d", vnic->va_vid);







5095                 }
5096 
5097                 ofmt_print(state->vs_ofmt, &vbuf);
5098 
5099                 return (DLADM_STATUS_OK);
5100         }
5101 }
5102 
5103 /* ARGSUSED */
5104 static int
5105 show_vnic(dladm_handle_t dh, datalink_id_t linkid, void *arg)
5106 {
5107         show_vnic_state_t       *state = arg;
5108 
5109         state->vs_status = print_vnic(state, linkid);
5110         return (DLADM_WALK_CONTINUE);
5111 }
5112 
5113 static void
5114 do_show_vnic_common(int argc, char *argv[], const char *use,
5115     boolean_t etherstub)
5116 {
5117         int                     option;
5118         boolean_t               s_arg = B_FALSE;
5119         boolean_t               i_arg = B_FALSE;
5120         boolean_t               l_arg = B_FALSE;
5121         uint32_t                interval = 0, flags = DLADM_OPT_ACTIVE;
5122         datalink_id_t           linkid = DATALINK_ALL_LINKID;
5123         datalink_id_t           dev_linkid = DATALINK_ALL_LINKID;
5124         show_vnic_state_t       state;
5125         dladm_status_t          status;
5126         boolean_t               o_arg = B_FALSE;
5127         char                    *fields_str = NULL;
5128         const ofmt_field_t      *pf;
5129         char                    *all_e_fields = "link";
5130         ofmt_handle_t           ofmt;
5131         ofmt_status_t           oferr;
5132         uint_t                  ofmtflags = 0;

5133 
5134         bzero(&state, sizeof (state));
5135         opterr = 0;
5136         while ((option = getopt_long(argc, argv, ":pPl:si:o:", lopts,
5137             NULL)) != -1) {
5138                 switch (option) {
5139                 case 'p':
5140                         state.vs_parsable = B_TRUE;
5141                         break;
5142                 case 'P':
5143                         flags = DLADM_OPT_PERSIST;
5144                         break;
5145                 case 'l':
5146                         if (etherstub)
5147                                 die("option not supported for this command");
5148 
5149                         if (strlcpy(state.vs_link, optarg, MAXLINKNAMELEN) >=
5150                             MAXLINKNAMELEN)
5151                                 die("link name too long");
5152 
5153                         l_arg = B_TRUE;
5154                         break;
5155                 case 's':
5156                         if (s_arg) {
5157                                 die("the option -s cannot be specified "
5158                                     "more than once");
5159                         }
5160                         s_arg = B_TRUE;
5161                         break;
5162                 case 'i':
5163                         if (i_arg) {
5164                                 die("the option -i cannot be specified "
5165                                     "more than once");
5166                         }
5167                         i_arg = B_TRUE;
5168                         if (!dladm_str2interval(optarg, &interval))
5169                                 die("invalid interval value '%s'", optarg);
5170                         break;
5171                 case 'o':
5172                         o_arg = B_TRUE;
5173                         fields_str = optarg;
5174                         break;



5175                 default:
5176                         die_opterr(optopt, option, use);
5177                 }
5178         }
5179 
5180         if (i_arg && !s_arg)
5181                 die("the option -i can be used only with -s");
5182 
5183         /* get vnic ID (optional last argument) */
5184         if (optind == (argc - 1)) {
5185                 status = dladm_name2info(handle, argv[optind], &linkid, NULL,
5186                     NULL, NULL);
5187                 if (status != DLADM_STATUS_OK) {
5188                         die_dlerr(status, "invalid vnic name '%s'",
5189                             argv[optind]);
5190                 }
5191                 (void) strlcpy(state.vs_vnic, argv[optind], MAXLINKNAMELEN);
5192         } else if (optind != argc) {
5193                 usage();
5194         }
5195 
5196         if (l_arg) {
5197                 status = dladm_name2info(handle, state.vs_link, &dev_linkid,
5198                     NULL, NULL, NULL);
5199                 if (status != DLADM_STATUS_OK) {
5200                         die_dlerr(status, "invalid link name '%s'",
5201                             state.vs_link);
5202                 }
5203         }
5204 
5205         state.vs_vnic_id = linkid;
5206         state.vs_link_id = dev_linkid;
5207         state.vs_etherstub = etherstub;
5208         state.vs_found = B_FALSE;
5209         state.vs_flags = flags;

5210 
5211         if (!o_arg || (o_arg && strcasecmp(fields_str, "all") == 0)) {
5212                 if (etherstub)
5213                         fields_str = all_e_fields;
5214         }
5215         pf = vnic_fields;
5216 
5217         if (state.vs_parsable)
5218                 ofmtflags |= OFMT_PARSABLE;
5219         oferr = ofmt_open(fields_str, pf, ofmtflags, 0, &ofmt);
5220         dladm_ofmt_check(oferr, state.vs_parsable, ofmt);
5221         state.vs_ofmt = ofmt;
5222 
5223         if (s_arg) {
5224                 /* Display vnic statistics */
5225                 vnic_stats(&state, interval);
5226                 ofmt_close(ofmt);
5227                 return;
5228         }
5229 


6678 
6679         ofmt_print(statep->ls_ofmt, &ls_arg);
6680 
6681         return (DLADM_WALK_CONTINUE);
6682 }
6683 
6684 static void
6685 do_show_linkprop(int argc, char **argv, const char *use)
6686 {
6687         int                     option;
6688         char                    propstr[DLADM_STRSIZE];
6689         dladm_arg_list_t        *proplist = NULL;
6690         datalink_id_t           linkid = DATALINK_ALL_LINKID;
6691         show_linkprop_state_t   state;
6692         uint32_t                flags = DLADM_OPT_ACTIVE;
6693         dladm_status_t          status;
6694         char                    *fields_str = NULL;
6695         ofmt_handle_t           ofmt;
6696         ofmt_status_t           oferr;
6697         uint_t                  ofmtflags = 0;

6698 
6699         bzero(propstr, DLADM_STRSIZE);
6700         opterr = 0;
6701         state.ls_propvals = NULL;
6702         state.ls_line = NULL;
6703         state.ls_parsable = B_FALSE;
6704         state.ls_persist = B_FALSE;
6705         state.ls_header = B_TRUE;
6706         state.ls_retstatus = DLADM_STATUS_OK;
6707 
6708         while ((option = getopt_long(argc, argv, ":p:cPo:",
6709             prop_longopts, NULL)) != -1) {
6710                 switch (option) {
6711                 case 'p':
6712                         (void) strlcat(propstr, optarg, DLADM_STRSIZE);
6713                         if (strlcat(propstr, ",", DLADM_STRSIZE) >=
6714                             DLADM_STRSIZE)
6715                                 die("property list too long '%s'", propstr);
6716                         break;
6717                 case 'c':
6718                         state.ls_parsable = B_TRUE;
6719                         break;
6720                 case 'P':
6721                         state.ls_persist = B_TRUE;
6722                         flags = DLADM_OPT_PERSIST;
6723                         break;
6724                 case 'o':
6725                         fields_str = optarg;
6726                         break;



6727                 default:
6728                         die_opterr(optopt, option, use);
6729                         break;
6730                 }
6731         }
6732 
6733         if (optind == (argc - 1)) {
6734                 if ((status = dladm_name2info(handle, argv[optind], &linkid,
6735                     NULL, NULL, NULL)) != DLADM_STATUS_OK) {
6736                         die_dlerr(status, "link %s is not valid", argv[optind]);
6737                 }
6738         } else if (optind != argc) {
6739                 usage();
6740         }
6741 
6742         if (dladm_parse_link_props(propstr, &proplist, B_TRUE)
6743             != DLADM_STATUS_OK)
6744                 die("invalid link properties specified");
6745         state.ls_proplist = proplist;

6746         state.ls_status = DLADM_STATUS_OK;
6747 
6748         if (state.ls_parsable)
6749                 ofmtflags |= OFMT_PARSABLE;
6750         else
6751                 ofmtflags |= OFMT_WRAP;
6752 
6753         oferr = ofmt_open(fields_str, linkprop_fields, ofmtflags, 0, &ofmt);
6754         dladm_ofmt_check(oferr, state.ls_parsable, ofmt);
6755         state.ls_ofmt = ofmt;
6756 
6757         if (linkid == DATALINK_ALL_LINKID) {
6758                 (void) dladm_walk_datalink_id(show_linkprop_onelink, handle,
6759                     &state, DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE, flags);
6760         } else {
6761                 (void) show_linkprop_onelink(handle, linkid, &state);
6762         }
6763         ofmt_close(ofmt);
6764         dladm_free_props(proplist);
6765 


6770 }
6771 
6772 static int
6773 show_linkprop_onelink(dladm_handle_t hdl, datalink_id_t linkid, void *arg)
6774 {
6775         int                     i;
6776         char                    *buf;
6777         uint32_t                flags;
6778         dladm_arg_list_t        *proplist = NULL;
6779         show_linkprop_state_t   *statep = arg;
6780         dlpi_handle_t           dh = NULL;
6781 
6782         statep->ls_status = DLADM_STATUS_OK;
6783 
6784         if (dladm_datalink_id2info(hdl, linkid, &flags, NULL, NULL,
6785             statep->ls_link, MAXLINKNAMELEN) != DLADM_STATUS_OK) {
6786                 statep->ls_status = DLADM_STATUS_NOTFOUND;
6787                 return (DLADM_WALK_CONTINUE);
6788         }
6789 











6790         if ((statep->ls_persist && !(flags & DLADM_OPT_PERSIST)) ||
6791             (!statep->ls_persist && !(flags & DLADM_OPT_ACTIVE))) {
6792                 statep->ls_status = DLADM_STATUS_BADARG;
6793                 return (DLADM_WALK_CONTINUE);
6794         }
6795 
6796         proplist = statep->ls_proplist;
6797 
6798         /*
6799          * When some WiFi links are opened for the first time, their hardware
6800          * automatically scans for APs and does other slow operations.  Thus,
6801          * if there are no open links, the retrieval of link properties
6802          * (below) will proceed slowly unless we hold the link open.
6803          *
6804          * Note that failure of dlpi_open() does not necessarily mean invalid
6805          * link properties, because dlpi_open() may fail because of incorrect
6806          * autopush configuration. Therefore, we ingore the return value of
6807          * dlpi_open().
6808          */
6809         if (!statep->ls_persist)


6852             status != DLADM_STATUS_NOTSUP) {
6853                 warn_dlerr(status, "cannot reset link property '%s' on '%s'",
6854                     propname, statep->ls_name);
6855                 statep->ls_status = status;
6856         }
6857 
6858         return (DLADM_WALK_CONTINUE);
6859 }
6860 
6861 static void
6862 set_linkprop(int argc, char **argv, boolean_t reset, const char *use)
6863 {
6864         int                     i, option;
6865         char                    errmsg[DLADM_STRSIZE];
6866         char                    *altroot = NULL;
6867         datalink_id_t           linkid;
6868         boolean_t               temp = B_FALSE;
6869         dladm_status_t          status = DLADM_STATUS_OK;
6870         char                    propstr[DLADM_STRSIZE];
6871         dladm_arg_list_t        *proplist = NULL;

6872 
6873         opterr = 0;
6874         bzero(propstr, DLADM_STRSIZE);
6875 
6876         while ((option = getopt_long(argc, argv, ":p:R:t",
6877             prop_longopts, NULL)) != -1) {
6878                 switch (option) {
6879                 case 'p':
6880                         (void) strlcat(propstr, optarg, DLADM_STRSIZE);
6881                         if (strlcat(propstr, ",", DLADM_STRSIZE) >=
6882                             DLADM_STRSIZE)
6883                                 die("property list too long '%s'", propstr);
6884                         break;
6885                 case 't':
6886                         temp = B_TRUE;
6887                         break;
6888                 case 'R':
6889                         altroot = optarg;
6890                         break;



6891                 default:
6892                         die_opterr(optopt, option, use);
6893 
6894                 }
6895         }
6896 
6897         /* get link name (required last argument) */
6898         if (optind != (argc - 1))
6899                 usage();
6900 
6901         if (dladm_parse_link_props(propstr, &proplist, reset) !=
6902             DLADM_STATUS_OK)
6903                 die("invalid link properties specified");
6904 
6905         if (proplist == NULL && !reset)
6906                 die("link property must be specified");
6907 
6908         if (altroot != NULL) {
6909                 dladm_free_props(proplist);
6910                 altroot_cmd(altroot, argc, argv);
6911         }
6912 
6913         status = dladm_name2info(handle, argv[optind], &linkid, NULL, NULL,
6914             NULL);
6915         if (status != DLADM_STATUS_OK)
6916                 die_dlerr(status, "link %s is not valid", argv[optind]);
6917 
6918         if (proplist == NULL) {
6919                 set_linkprop_state_t    state;
6920 
6921                 state.ls_name = argv[optind];
6922                 state.ls_reset = reset;
6923                 state.ls_temp = temp;
6924                 state.ls_status = DLADM_STATUS_OK;
6925 
6926                 (void) dladm_walk_linkprop(handle, linkid, &state,
6927                     reset_one_linkprop);
6928 
6929                 status = state.ls_status;
6930                 goto done;
6931         }
6932 
6933         for (i = 0; i < proplist->al_count; i++) {
6934                 dladm_arg_info_t        *aip = &proplist->al_info[i];




   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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright (c) 2012 Joyent, Inc. All rights reserved.
  24  */
  25 
  26 #include <stdio.h>
  27 #include <ctype.h>
  28 #include <dlfcn.h>
  29 #include <locale.h>
  30 #include <signal.h>
  31 #include <stdarg.h>
  32 #include <stdlib.h>
  33 #include <fcntl.h>
  34 #include <string.h>
  35 #include <stropts.h>
  36 #include <sys/stat.h>
  37 #include <errno.h>
  38 #include <kstat.h>
  39 #include <strings.h>
  40 #include <getopt.h>
  41 #include <unistd.h>
  42 #include <priv.h>
  43 #include <limits.h>


 138         ofmt_handle_t   gs_ofmt;
 139 } show_grp_state_t;
 140 
 141 typedef struct show_vnic_state {
 142         datalink_id_t   vs_vnic_id;
 143         datalink_id_t   vs_link_id;
 144         char            vs_vnic[MAXLINKNAMELEN];
 145         char            vs_link[MAXLINKNAMELEN];
 146         boolean_t       vs_parsable;
 147         boolean_t       vs_found;
 148         boolean_t       vs_firstonly;
 149         boolean_t       vs_donefirst;
 150         boolean_t       vs_stats;
 151         boolean_t       vs_printstats;
 152         pktsum_t        vs_totalstats;
 153         pktsum_t        vs_prevstats[MAXVNIC];
 154         boolean_t       vs_etherstub;
 155         dladm_status_t  vs_status;
 156         uint32_t        vs_flags;
 157         ofmt_handle_t   vs_ofmt;
 158         char            *vs_zonename;
 159 } show_vnic_state_t;
 160 
 161 typedef struct show_part_state {
 162         datalink_id_t   ps_over_id;
 163         char            ps_part[MAXLINKNAMELEN];
 164         boolean_t       ps_parsable;
 165         boolean_t       ps_found;
 166         dladm_status_t  ps_status;
 167         uint32_t        ps_flags;
 168         ofmt_handle_t   ps_ofmt;
 169 } show_part_state_t;
 170 
 171 typedef struct show_ib_state {
 172         datalink_id_t   is_link_id;
 173         char            is_link[MAXLINKNAMELEN];
 174         boolean_t       is_parsable;
 175         dladm_status_t  is_status;
 176         uint32_t        is_flags;
 177         ofmt_handle_t   is_ofmt;
 178 } show_ib_state_t;


 250 static int      show_etherprop(dladm_handle_t, datalink_id_t, void *);
 251 static void     show_ether_xprop(void *, dladm_ether_info_t *);
 252 static boolean_t        link_is_ether(const char *, datalink_id_t *);
 253 
 254 static boolean_t str2int(const char *, int *);
 255 static void     die(const char *, ...);
 256 static void     die_optdup(int);
 257 static void     die_opterr(int, int, const char *);
 258 static void     die_dlerr(dladm_status_t, const char *, ...);
 259 static void     warn(const char *, ...);
 260 static void     warn_dlerr(dladm_status_t, const char *, ...);
 261 
 262 typedef struct  cmd {
 263         char            *c_name;
 264         cmdfunc_t       *c_fn;
 265         const char      *c_usage;
 266 } cmd_t;
 267 
 268 static cmd_t    cmds[] = {
 269         { "rename-link",        do_rename_link,
 270             "    rename-link      [-z zonename] <oldlink> <newlink>"        },
 271         { "show-link",          do_show_link,
 272             "    show-link        [-pP] [-o <field>,..] [-s [-i <interval>]] "
 273             "[<link>]\n"                                          },
 274         { "create-aggr",        do_create_aggr,
 275             "    create-aggr      [-t] [-P <policy>] [-L <mode>] [-T <time>] "
 276             "[-u <address>]\n"
 277             "\t\t     -l <link> [-l <link>...] <link>"                        },
 278         { "delete-aggr",        do_delete_aggr,
 279             "    delete-aggr      [-t] <link>"                            },
 280         { "add-aggr",           do_add_aggr,
 281             "    add-aggr         [-t] -l <link> [-l <link>...] <link>" },
 282         { "remove-aggr",        do_remove_aggr,
 283             "    remove-aggr      [-t] -l <link> [-l <link>...] <link>" },
 284         { "modify-aggr",        do_modify_aggr,
 285             "    modify-aggr      [-t] [-P <policy>] [-L <mode>] [-T <time>] "
 286             "[-u <address>]\n"
 287             "\t\t     <link>"                                             },
 288         { "show-aggr",          do_show_aggr,
 289             "    show-aggr        [-pPLx] [-o <field>,..] [-s [-i <interval>]] "
 290             "[<link>]\n"                                          },
 291         { "up-aggr",            do_up_aggr,     NULL                    },
 292         { "scan-wifi",          do_scan_wifi,
 293             "    scan-wifi        [-p] [-o <field>,...] [<link>]"   },
 294         { "connect-wifi",       do_connect_wifi,
 295             "    connect-wifi     [-e <essid>] [-i <bssid>] [-k <key>,...] "
 296             "[-s wep|wpa]\n"
 297             "\t\t     [-a open|shared] [-b bss|ibss] [-c] [-m a|b|g] "
 298             "[-T <time>]\n"
 299             "\t\t     [<link>]"                                           },
 300         { "disconnect-wifi",    do_disconnect_wifi,
 301             "    disconnect-wifi  [-a] [<link>]"                  },
 302         { "show-wifi",          do_show_wifi,
 303             "    show-wifi        [-p] [-o <field>,...] [<link>]\n" },
 304         { "set-linkprop",       do_set_linkprop,
 305             "    set-linkprop     [-t] [-z zonename] -p <prop>=<value>[,...] "
 306             "<name>"                                                      },
 307         { "reset-linkprop",     do_reset_linkprop,
 308             "    reset-linkprop   [-t] [-z zonename] [-p <prop>,...] <name>"},
 309         { "show-linkprop",      do_show_linkprop,
 310             "    show-linkprop    [-cP] [-o <field>,...] [-z zonename] "
 311             "[-p <prop>,...] <name>\n"                                      },
 312         { "show-ether",         do_show_ether,
 313             "    show-ether       [-px][-o <field>,...] <link>\n"   },
 314         { "create-secobj",      do_create_secobj,
 315             "    create-secobj    [-t] [-f <file>] -c <class> <secobj>"       },
 316         { "delete-secobj",      do_delete_secobj,
 317             "    delete-secobj    [-t] <secobj>[,...]"                    },
 318         { "show-secobj",        do_show_secobj,
 319             "    show-secobj      [-pP] [-o <field>,...] [<secobj>,...]\n" },
 320         { "init-linkprop",      do_init_linkprop,       NULL            },
 321         { "init-secobj",        do_init_secobj,         NULL            },
 322         { "create-vlan",        do_create_vlan,
 323             "    create-vlan      [-ft] -l <link> -v <vid> [link]"  },
 324         { "delete-vlan",        do_delete_vlan,
 325             "    delete-vlan      [-t] <link>"                            },
 326         { "show-vlan",          do_show_vlan,
 327             "    show-vlan        [-pP] [-o <field>,..] [<link>]\n" },
 328         { "up-vlan",            do_up_vlan,             NULL            },
 329         { "create-iptun",       do_create_iptun,
 330             "    create-iptun     [-t] -T <type> "
 331             "[-a {local|remote}=<addr>,...] <link>]" },


 333             "    delete-iptun     [-t] <link>"                            },
 334         { "modify-iptun",       do_modify_iptun,
 335             "    modify-iptun     [-t] -a {local|remote}=<addr>,... <link>" },
 336         { "show-iptun",         do_show_iptun,
 337             "    show-iptun       [-pP] [-o <field>,..] [<link>]\n" },
 338         { "up-iptun",           do_up_iptun,            NULL            },
 339         { "down-iptun",         do_down_iptun,          NULL            },
 340         { "delete-phys",        do_delete_phys,
 341             "    delete-phys      <link>"                         },
 342         { "show-phys",          do_show_phys,
 343             "    show-phys        [-m | -H | -P] [[-p] [-o <field>[,...]] "
 344             "[<link>]\n"                                          },
 345         { "init-phys",          do_init_phys,           NULL            },
 346         { "show-linkmap",       do_show_linkmap,        NULL            },
 347         { "create-vnic",        do_create_vnic,
 348             "    create-vnic      [-t] -l <link> [-m <value> | auto |\n"
 349             "\t\t     {factory [-n <slot-id>]} | {random [-r <prefix>]} |\n"
 350             "\t\t     {vrrp -V <vrid> -A {inet | inet6}} [-v <vid> [-f]]\n"
 351             "\t\t     [-p <prop>=<value>[,...]] <vnic-link>"  },
 352         { "delete-vnic",        do_delete_vnic,
 353             "    delete-vnic      [-t] [-z zonename] <vnic-link>" },
 354         { "show-vnic",          do_show_vnic,
 355             "    show-vnic        [-pP] [-l <link>] [-z zonename] "
 356             "[-s [-i <interval>]] [<link>]\n"                                               },
 357         { "up-vnic",            do_up_vnic,             NULL            },
 358         { "create-part",        do_create_part,
 359             "    create-part      [-t] [-f] -l <link> [-P <pkey>]\n"
 360             "\t\t     [-R <root-dir>] <part-link>"                  },
 361         { "delete-part",        do_delete_part,
 362             "    delete-part      [-t] [-R <root-dir>] <part-link>"},
 363         { "show-part",          do_show_part,
 364             "    show-part        [-pP] [-o <field>,...][-l <linkover>]\n"
 365             "\t\t     [<part-link>]"              },
 366         { "show-ib",            do_show_ib,
 367             "    show-ib          [-p] [-o <field>,...] [<link>]\n" },
 368         { "up-part",            do_up_part,             NULL            },
 369         { "create-etherstub",   do_create_etherstub,
 370             "    create-etherstub [-t] <link>"                            },
 371         { "delete-etherstub",   do_delete_etherstub,
 372             "    delete-etherstub [-t] <link>"                            },
 373         { "show-etherstub",     do_show_etherstub,
 374             "    show-etherstub   [-t] [<link>]\n"                        },
 375         { "create-simnet",      do_create_simnet,       NULL            },
 376         { "modify-simnet",      do_modify_simnet,       NULL            },


 945         LINKPROP_POSSIBLE
 946 } linkprop_field_index_t;
 947 
 948 static const ofmt_field_t linkprop_fields[] = {
 949 /* name,        field width,  index */
 950 { "LINK",       13,     LINKPROP_LINK,          print_linkprop_cb},
 951 { "PROPERTY",   16,     LINKPROP_PROPERTY,      print_linkprop_cb},
 952 { "PERM",       5,      LINKPROP_PERM,          print_linkprop_cb},
 953 { "VALUE",      15,     LINKPROP_VALUE,         print_linkprop_cb},
 954 { "DEFAULT",    15,     LINKPROP_DEFAULT,       print_linkprop_cb},
 955 { "POSSIBLE",   20,     LINKPROP_POSSIBLE,      print_linkprop_cb},
 956 { NULL,         0,      0,                      NULL}}
 957 ;
 958 
 959 #define MAX_PROP_LINE           512
 960 
 961 typedef struct show_linkprop_state {
 962         char                    ls_link[MAXLINKNAMELEN];
 963         char                    *ls_line;
 964         char                    **ls_propvals;
 965         char                    *ls_zonename;
 966         dladm_arg_list_t        *ls_proplist;
 967         boolean_t               ls_parsable;
 968         boolean_t               ls_persist;
 969         boolean_t               ls_header;
 970         dladm_status_t          ls_status;
 971         dladm_status_t          ls_retstatus;
 972         ofmt_handle_t           ls_ofmt;
 973 } show_linkprop_state_t;
 974 
 975 typedef struct set_linkprop_state {
 976         const char              *ls_name;
 977         boolean_t               ls_reset;
 978         boolean_t               ls_temp;
 979         dladm_status_t          ls_status;
 980 } set_linkprop_state_t;
 981 
 982 typedef struct linkprop_args_s {
 983         show_linkprop_state_t   *ls_state;
 984         char                    *ls_propname;
 985         datalink_id_t           ls_linkid;


 998 { "OBJECT",     21,
 999         offsetof(secobj_fields_buf_t, ss_obj_name), print_default_cb},
1000 { "CLASS",      21,
1001         offsetof(secobj_fields_buf_t, ss_class), print_default_cb},
1002 { "VALUE",      31,
1003         offsetof(secobj_fields_buf_t, ss_val), print_default_cb},
1004 { NULL,         0, 0, NULL}}
1005 ;
1006 
1007 /*
1008  * structures for 'dladm show-vnic'
1009  */
1010 typedef struct vnic_fields_buf_s
1011 {
1012         char vnic_link[DLPI_LINKNAME_MAX];
1013         char vnic_over[DLPI_LINKNAME_MAX];
1014         char vnic_speed[6];
1015         char vnic_macaddr[18];
1016         char vnic_macaddrtype[19];
1017         char vnic_vid[6];
1018         char vnic_zone[ZONENAME_MAX];
1019 } vnic_fields_buf_t;
1020 
1021 static const ofmt_field_t vnic_fields[] = {
1022 { "LINK",               13,
1023         offsetof(vnic_fields_buf_t, vnic_link), print_default_cb},
1024 { "OVER",               11,
1025         offsetof(vnic_fields_buf_t, vnic_over), print_default_cb},
1026 { "SPEED",              6,
1027         offsetof(vnic_fields_buf_t, vnic_speed), print_default_cb},
1028 { "MACADDRESS",         18,
1029         offsetof(vnic_fields_buf_t, vnic_macaddr), print_default_cb},
1030 { "MACADDRTYPE",        12,
1031         offsetof(vnic_fields_buf_t, vnic_macaddrtype), print_default_cb},
1032 { "VID",                5,
1033         offsetof(vnic_fields_buf_t, vnic_vid), print_default_cb},
1034 { "ZONE",               20,
1035         offsetof(vnic_fields_buf_t, vnic_zone), print_default_cb},
1036 { NULL,                 0, 0, NULL}}
1037 ;
1038 
1039 /*
1040  * structures for 'dladm show-ib'
1041  */
1042 typedef struct ib_fields_buf_s
1043 {
1044         char ib_link[DLPI_LINKNAME_MAX];
1045         char ib_hcaguid[17];
1046         char ib_portguid[17];
1047         char ib_portnum[4];
1048         char ib_state[6];
1049         char ib_pkeys[MAXPKEYSTRSZ];
1050 } ib_fields_buf_t;
1051 
1052 static const ofmt_field_t ib_fields[] = {
1053 { "LINK",               13,
1054         offsetof(ib_fields_buf_t, ib_link),     print_default_cb},
1055 { "HCAGUID",            IBGUIDSTRLEN,


2485         status = dladm_vlan_delete(handle, linkid, flags);
2486 done:
2487         if (status != DLADM_STATUS_OK)
2488                 die_dlerr(status, "delete operation failed");
2489 }
2490 
2491 /*ARGSUSED*/
2492 static void
2493 do_up_vlan(int argc, char *argv[], const char *use)
2494 {
2495         do_up_vnic_common(argc, argv, use, B_TRUE);
2496 }
2497 
2498 static void
2499 do_rename_link(int argc, char *argv[], const char *use)
2500 {
2501         int             option;
2502         char            *link1, *link2;
2503         char            *altroot = NULL;
2504         dladm_status_t  status;
2505         char            *zonename = NULL;
2506 
2507         opterr = 0;
2508         while ((option = getopt_long(argc, argv, ":R:z:", lopts, NULL)) != -1) {
2509                 switch (option) {
2510                 case 'R':
2511                         altroot = optarg;
2512                         break;
2513                 case 'z':
2514                         zonename = optarg;
2515                         break;
2516                 default:
2517                         die_opterr(optopt, option, use);
2518                         break;
2519                 }
2520         }
2521 
2522         /* get link1 and link2 name (required the last 2 arguments) */
2523         if (optind != (argc - 2))
2524                 usage();
2525 
2526         if (altroot != NULL)
2527                 altroot_cmd(altroot, argc, argv);
2528 
2529         link1 = argv[optind++];
2530         link2 = argv[optind];
2531         if ((status = dladm_rename_link(handle, zonename, link1, link2)) !=
2532             DLADM_STATUS_OK)
2533                 die_dlerr(status, "rename operation failed");
2534 }
2535 
2536 /*ARGSUSED*/
2537 static void
2538 do_delete_phys(int argc, char *argv[], const char *use)
2539 {
2540         datalink_id_t   linkid = DATALINK_ALL_LINKID;
2541         dladm_status_t  status;
2542 
2543         /* get link name (required the last argument) */
2544         if (argc > 2)
2545                 usage();
2546 
2547         if (argc == 2) {
2548                 if ((status = dladm_name2info(handle, argv[1], &linkid, NULL,
2549                     NULL, NULL)) != DLADM_STATUS_OK)
2550                         die_dlerr(status, "cannot delete '%s'", argv[1]);
2551         }


3401         int             option;
3402         boolean_t       s_arg = B_FALSE;
3403         boolean_t       S_arg = B_FALSE;
3404         boolean_t       i_arg = B_FALSE;
3405         uint32_t        flags = DLADM_OPT_ACTIVE;
3406         boolean_t       p_arg = B_FALSE;
3407         datalink_id_t   linkid = DATALINK_ALL_LINKID;
3408         char            linkname[MAXLINKNAMELEN];
3409         uint32_t        interval = 0;
3410         show_state_t    state;
3411         dladm_status_t  status;
3412         boolean_t       o_arg = B_FALSE;
3413         char            *fields_str = NULL;
3414         char            *all_active_fields = "link,class,mtu,state,bridge,over";
3415         char            *all_inactive_fields = "link,class,bridge,over";
3416         char            *allstat_fields =
3417             "link,ipackets,rbytes,ierrors,opackets,obytes,oerrors";
3418         ofmt_handle_t   ofmt;
3419         ofmt_status_t   oferr;
3420         uint_t          ofmtflags = 0;
3421         char            *zonename = NULL;
3422 
3423         bzero(&state, sizeof (state));
3424 
3425         opterr = 0;
3426         while ((option = getopt_long(argc, argv, ":pPsSi:o:z:",
3427             show_lopts, NULL)) != -1) {
3428                 switch (option) {
3429                 case 'p':
3430                         if (p_arg)
3431                                 die_optdup(option);
3432 
3433                         p_arg = B_TRUE;
3434                         break;
3435                 case 's':
3436                         if (s_arg)
3437                                 die_optdup(option);
3438 
3439                         s_arg = B_TRUE;
3440                         break;
3441                 case 'P':
3442                         if (flags != DLADM_OPT_ACTIVE)
3443                                 die_optdup(option);
3444 
3445                         flags = DLADM_OPT_PERSIST;
3446                         break;
3447                 case 'S':
3448                         if (S_arg)
3449                                 die_optdup(option);
3450 
3451                         S_arg = B_TRUE;
3452                         break;
3453                 case 'o':
3454                         o_arg = B_TRUE;
3455                         fields_str = optarg;
3456                         break;
3457                 case 'i':
3458                         if (i_arg)
3459                                 die_optdup(option);
3460 
3461                         i_arg = B_TRUE;
3462                         if (!dladm_str2interval(optarg, &interval))
3463                                 die("invalid interval value '%s'", optarg);
3464                         break;
3465                 case 'z':
3466                         zonename = optarg;
3467                         break;
3468                 default:
3469                         die_opterr(optopt, option, use);
3470                         break;
3471                 }
3472         }
3473 
3474         if (i_arg && !(s_arg || S_arg))
3475                 die("the option -i can be used only with -s or -S");
3476 
3477         if (s_arg && S_arg)
3478                 die("the -s option cannot be used with -S");
3479 
3480         if (s_arg && flags != DLADM_OPT_ACTIVE)
3481                 die("the option -P cannot be used with -s");
3482 
3483         if (S_arg && (p_arg || flags != DLADM_OPT_ACTIVE))
3484                 die("the option -%c cannot be used with -S", p_arg ? 'p' : 'P');
3485 
3486         /* get link name (optional last argument) */
3487         if (optind == (argc-1)) {
3488                 uint32_t        f;
3489 
3490                 if (strlcpy(linkname, argv[optind], MAXLINKNAMELEN) >=
3491                     MAXLINKNAMELEN)
3492                         die("link name too long");
3493                 if ((status = dladm_zname2info(handle, zonename, linkname,
3494                     &linkid, &f, NULL, NULL)) != DLADM_STATUS_OK) {
3495                         die_dlerr(status, "link %s is not valid", linkname);
3496                 }
3497 
3498                 if (!(f & flags)) {
3499                         die_dlerr(DLADM_STATUS_BADARG, "link %s is %s",
3500                             argv[optind], flags == DLADM_OPT_PERSIST ?
3501                             "a temporary link" : "temporarily removed");
3502                 }
3503         } else if (optind != argc) {
3504                 usage();
3505         }
3506 
3507         if (p_arg && !o_arg)
3508                 die("-p requires -o");
3509 
3510         if (S_arg) {
3511                 dladm_continuous(handle, linkid, NULL, interval, LINK_REPORT);
3512                 return;
3513         }
3514 


4739                                 die("invalid VLAN identifier '%s'", optarg);
4740 
4741                         break;
4742                 case 'f':
4743                         flags |= DLADM_OPT_FORCE;
4744                         break;
4745                 default:
4746                         die_opterr(optopt, option, use);
4747                 }
4748         }
4749 
4750         if (mac_addr_type == VNIC_MAC_ADDR_TYPE_UNKNOWN)
4751                 mac_addr_type = VNIC_MAC_ADDR_TYPE_AUTO;
4752 
4753         /*
4754          * 'f' - force, flag can be specified only with 'v' - vlan.
4755          */
4756         if ((flags & DLADM_OPT_FORCE) != 0 && vid == 0)
4757                 die("-f option can only be used with -v");
4758 
4759         /*
4760          * If creating a transient VNIC for a zone, mark it in the kernel.
4761          */
4762         if (strstr(propstr, "zone=") != NULL && !(flags & DLADM_OPT_PERSIST))
4763                 flags |= DLADM_OPT_TRANSIENT;
4764 
4765         if (mac_prefix_len != 0 && mac_addr_type != VNIC_MAC_ADDR_TYPE_RANDOM &&
4766             mac_addr_type != VNIC_MAC_ADDR_TYPE_FIXED)
4767                 usage();
4768 
4769         if (mac_addr_type == VNIC_MAC_ADDR_TYPE_VRID) {
4770                 if (vrid == VRRP_VRID_NONE || af == AF_UNSPEC ||
4771                     mac_addr != NULL || maclen != 0 || mac_slot != -1 ||
4772                     mac_prefix_len != 0) {
4773                         usage();
4774                 }
4775         } else if ((af != AF_UNSPEC || vrid != VRRP_VRID_NONE)) {
4776                 usage();
4777         }
4778 
4779         /* check required options */
4780         if (!l_arg)
4781                 usage();
4782 
4783         if (mac_slot != -1 && mac_addr_type != VNIC_MAC_ADDR_TYPE_FACTORY)
4784                 usage();


4836                  * Let the delete continue anyway.
4837                  */
4838                 return;
4839         }
4840         is_etherstub = (attr.va_link_id == DATALINK_INVALID_LINKID);
4841         if (is_etherstub != etherstub) {
4842                 die("'%s' is not %s", name,
4843                     (is_etherstub ? "a vnic" : "an etherstub"));
4844         }
4845 }
4846 
4847 static void
4848 do_delete_vnic_common(int argc, char *argv[], const char *use,
4849     boolean_t etherstub)
4850 {
4851         int option;
4852         uint32_t flags = DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST;
4853         datalink_id_t linkid;
4854         char *altroot = NULL;
4855         dladm_status_t status;
4856         char    *zonename = NULL;
4857 
4858         opterr = 0;
4859         while ((option = getopt_long(argc, argv, ":R:tz:", lopts,
4860             NULL)) != -1) {
4861                 switch (option) {
4862                 case 't':
4863                         flags &= ~DLADM_OPT_PERSIST;
4864                         break;
4865                 case 'R':
4866                         altroot = optarg;
4867                         break;
4868                 case 'z':
4869                         zonename = optarg;
4870                         break;
4871                 default:
4872                         die_opterr(optopt, option, use);
4873                 }
4874         }
4875 
4876         /* get vnic name (required last argument) */
4877         if (optind != (argc - 1))
4878                 usage();
4879 
4880         if (altroot != NULL)
4881                 altroot_cmd(altroot, argc, argv);
4882 
4883         status = dladm_zname2info(handle, zonename, argv[optind], &linkid, NULL,
4884             NULL, NULL);
4885         if (status != DLADM_STATUS_OK)
4886                 die("invalid link name '%s'", argv[optind]);
4887 
4888         if ((flags & DLADM_OPT_ACTIVE) != 0) {
4889                 do_etherstub_check(argv[optind], linkid, etherstub,
4890                     DLADM_OPT_ACTIVE);
4891         }
4892         if ((flags & DLADM_OPT_PERSIST) != 0) {
4893                 do_etherstub_check(argv[optind], linkid, etherstub,
4894                     DLADM_OPT_PERSIST);
4895         }
4896 
4897         status = dladm_vnic_delete(handle, linkid, flags);
4898         if (status != DLADM_STATUS_OK)
4899                 die_dlerr(status, "vnic deletion failed");
4900 }
4901 
4902 static void
4903 do_delete_vnic(int argc, char *argv[], const char *use)
4904 {


4996         }
4997         (void) printf("\n");
4998 
4999         *old_stats = *vnic_stats;
5000 }
5001 
5002 /*
5003  * Called from the walker dladm_vnic_walk_sys() for each vnic to display
5004  * vnic information or statistics.
5005  */
5006 static dladm_status_t
5007 print_vnic(show_vnic_state_t *state, datalink_id_t linkid)
5008 {
5009         dladm_vnic_attr_t       attr, *vnic = &attr;
5010         dladm_status_t          status;
5011         boolean_t               is_etherstub;
5012         char                    devname[MAXLINKNAMELEN];
5013         char                    vnic_name[MAXLINKNAMELEN];
5014         char                    mstr[MAXMACADDRLEN * 3];
5015         vnic_fields_buf_t       vbuf;
5016         uint_t                  valcnt = 1;
5017         char                    zonename[DLADM_PROP_VAL_MAX + 1];
5018         char                    *valptr[1];
5019 
5020         if ((status = dladm_vnic_info(handle, linkid, vnic, state->vs_flags)) !=
5021             DLADM_STATUS_OK)
5022                 return (status);
5023 
5024         is_etherstub = (vnic->va_link_id == DATALINK_INVALID_LINKID);
5025         if (state->vs_etherstub != is_etherstub) {
5026                 /*
5027                  * Want all etherstub but it's not one, or want
5028                  * non-etherstub and it's one.
5029                  */
5030                 return (DLADM_STATUS_OK);
5031         }
5032 
5033         if (state->vs_link_id != DATALINK_ALL_LINKID) {
5034                 if (state->vs_link_id != vnic->va_link_id)
5035                         return (DLADM_STATUS_OK);
5036         }
5037 
5038         if (dladm_datalink_id2info(handle, linkid, NULL, NULL,
5039             NULL, vnic_name, sizeof (vnic_name)) != DLADM_STATUS_OK)
5040                 return (DLADM_STATUS_BADARG);
5041 
5042         bzero(devname, sizeof (devname));
5043         if (!is_etherstub &&
5044             dladm_datalink_id2info(handle, vnic->va_link_id, NULL, NULL,
5045             NULL, devname, sizeof (devname)) != DLADM_STATUS_OK)
5046                 (void) sprintf(devname, "?");
5047 
5048         
5049         zonename[0] = '\0';
5050         if (!is_etherstub) {
5051                 valptr[0] = zonename;
5052                 (void) dladm_get_linkprop(handle, linkid,
5053                     DLADM_PROP_VAL_CURRENT, "zone", (char **)valptr, &valcnt);
5054         }
5055 
5056         if (state->vs_zonename != NULL &&
5057              strcmp(state->vs_zonename, zonename) != 0)
5058                 return (DLADM_STATUS_OK);
5059 
5060         state->vs_found = B_TRUE;
5061         if (state->vs_stats) {
5062                 /* print vnic statistics */
5063                 pktsum_t vnic_stats;
5064 
5065                 if (state->vs_firstonly) {
5066                         if (state->vs_donefirst)
5067                                 return (0);
5068                         state->vs_donefirst = B_TRUE;
5069                 }
5070 
5071                 if (!state->vs_printstats) {
5072                         /*
5073                          * get vnic statistics and add to the sum for the
5074                          * named device.
5075                          */
5076                         get_link_stats(vnic_name, &vnic_stats);
5077                         dladm_stats_total(&state->vs_totalstats, &vnic_stats,
5078                             &state->vs_prevstats[vnic->va_vnic_id]);
5079                 } else {


5115                                     vnic->va_mac_slot);
5116                                 break;
5117                         case VNIC_MAC_ADDR_TYPE_VRID:
5118                                 (void) snprintf(vbuf.vnic_macaddrtype,
5119                                     sizeof (vbuf.vnic_macaddrtype),
5120                                     gettext("vrrp, %d/%s"),
5121                                     vnic->va_vrid, vnic->va_af == AF_INET ?
5122                                     "inet" : "inet6");
5123                                 break;
5124                         }
5125 
5126                         if (strlen(vbuf.vnic_macaddrtype) > 0) {
5127                                 (void) snprintf(vbuf.vnic_macaddr,
5128                                     sizeof (vbuf.vnic_macaddr), "%s",
5129                                     dladm_aggr_macaddr2str(vnic->va_mac_addr,
5130                                     mstr));
5131                         }
5132 
5133                         (void) snprintf(vbuf.vnic_vid, sizeof (vbuf.vnic_vid),
5134                             "%d", vnic->va_vid);
5135 
5136                         if (zonename[0] != '\0')
5137                                 (void) snprintf(vbuf.vnic_zone,
5138                                     sizeof (vbuf.vnic_zone), "%s", zonename);
5139                         else
5140                                 (void) strlcpy(vbuf.vnic_zone, "--",
5141                                      sizeof (vbuf.vnic_zone));
5142                 }
5143 
5144                 ofmt_print(state->vs_ofmt, &vbuf);
5145 
5146                 return (DLADM_STATUS_OK);
5147         }
5148 }
5149 
5150 /* ARGSUSED */
5151 static int
5152 show_vnic(dladm_handle_t dh, datalink_id_t linkid, void *arg)
5153 {
5154         show_vnic_state_t       *state = arg;
5155 
5156         state->vs_status = print_vnic(state, linkid);
5157         return (DLADM_WALK_CONTINUE);
5158 }
5159 
5160 static void
5161 do_show_vnic_common(int argc, char *argv[], const char *use,
5162     boolean_t etherstub)
5163 {
5164         int                     option;
5165         boolean_t               s_arg = B_FALSE;
5166         boolean_t               i_arg = B_FALSE;
5167         boolean_t               l_arg = B_FALSE;
5168         uint32_t                interval = 0, flags = DLADM_OPT_ACTIVE;
5169         datalink_id_t           linkid = DATALINK_ALL_LINKID;
5170         datalink_id_t           dev_linkid = DATALINK_ALL_LINKID;
5171         show_vnic_state_t       state;
5172         dladm_status_t          status;
5173         boolean_t               o_arg = B_FALSE;
5174         char                    *fields_str = NULL;
5175         const ofmt_field_t      *pf;
5176         char                    *all_e_fields = "link";
5177         ofmt_handle_t           ofmt;
5178         ofmt_status_t           oferr;
5179         uint_t                  ofmtflags = 0;
5180         char                    *zonename = NULL;
5181 
5182         bzero(&state, sizeof (state));
5183         opterr = 0;
5184         while ((option = getopt_long(argc, argv, ":pPl:si:o:z:", lopts,
5185             NULL)) != -1) {
5186                 switch (option) {
5187                 case 'p':
5188                         state.vs_parsable = B_TRUE;
5189                         break;
5190                 case 'P':
5191                         flags = DLADM_OPT_PERSIST;
5192                         break;
5193                 case 'l':
5194                         if (etherstub)
5195                                 die("option not supported for this command");
5196 
5197                         if (strlcpy(state.vs_link, optarg, MAXLINKNAMELEN) >=
5198                             MAXLINKNAMELEN)
5199                                 die("link name too long");
5200 
5201                         l_arg = B_TRUE;
5202                         break;
5203                 case 's':
5204                         if (s_arg) {
5205                                 die("the option -s cannot be specified "
5206                                     "more than once");
5207                         }
5208                         s_arg = B_TRUE;
5209                         break;
5210                 case 'i':
5211                         if (i_arg) {
5212                                 die("the option -i cannot be specified "
5213                                     "more than once");
5214                         }
5215                         i_arg = B_TRUE;
5216                         if (!dladm_str2interval(optarg, &interval))
5217                                 die("invalid interval value '%s'", optarg);
5218                         break;
5219                 case 'o':
5220                         o_arg = B_TRUE;
5221                         fields_str = optarg;
5222                         break;
5223                 case 'z':
5224                         zonename = optarg;
5225                         break;
5226                 default:
5227                         die_opterr(optopt, option, use);
5228                 }
5229         }
5230 
5231         if (i_arg && !s_arg)
5232                 die("the option -i can be used only with -s");
5233 
5234         /* get vnic ID (optional last argument) */
5235         if (optind == (argc - 1)) {
5236                 status = dladm_zname2info(handle, zonename, argv[optind],
5237                     &linkid, NULL, NULL, NULL);
5238                 if (status != DLADM_STATUS_OK) {
5239                         die_dlerr(status, "invalid vnic name '%s'",
5240                             argv[optind]);
5241                 }
5242                 (void) strlcpy(state.vs_vnic, argv[optind], MAXLINKNAMELEN);
5243         } else if (optind != argc) {
5244                 usage();
5245         }
5246 
5247         if (l_arg) {
5248                 status = dladm_zname2info(handle, zonename, state.vs_link,
5249                     &dev_linkid, NULL, NULL, NULL);
5250                 if (status != DLADM_STATUS_OK) {
5251                         die_dlerr(status, "invalid link name '%s'",
5252                             state.vs_link);
5253                 }
5254         }
5255 
5256         state.vs_vnic_id = linkid;
5257         state.vs_link_id = dev_linkid;
5258         state.vs_etherstub = etherstub;
5259         state.vs_found = B_FALSE;
5260         state.vs_flags = flags;
5261         state.vs_zonename = zonename;
5262 
5263         if (!o_arg || (o_arg && strcasecmp(fields_str, "all") == 0)) {
5264                 if (etherstub)
5265                         fields_str = all_e_fields;
5266         }
5267         pf = vnic_fields;
5268 
5269         if (state.vs_parsable)
5270                 ofmtflags |= OFMT_PARSABLE;
5271         oferr = ofmt_open(fields_str, pf, ofmtflags, 0, &ofmt);
5272         dladm_ofmt_check(oferr, state.vs_parsable, ofmt);
5273         state.vs_ofmt = ofmt;
5274 
5275         if (s_arg) {
5276                 /* Display vnic statistics */
5277                 vnic_stats(&state, interval);
5278                 ofmt_close(ofmt);
5279                 return;
5280         }
5281 


6730 
6731         ofmt_print(statep->ls_ofmt, &ls_arg);
6732 
6733         return (DLADM_WALK_CONTINUE);
6734 }
6735 
6736 static void
6737 do_show_linkprop(int argc, char **argv, const char *use)
6738 {
6739         int                     option;
6740         char                    propstr[DLADM_STRSIZE];
6741         dladm_arg_list_t        *proplist = NULL;
6742         datalink_id_t           linkid = DATALINK_ALL_LINKID;
6743         show_linkprop_state_t   state;
6744         uint32_t                flags = DLADM_OPT_ACTIVE;
6745         dladm_status_t          status;
6746         char                    *fields_str = NULL;
6747         ofmt_handle_t           ofmt;
6748         ofmt_status_t           oferr;
6749         uint_t                  ofmtflags = 0;
6750         char                    *zonename = NULL;
6751 
6752         bzero(propstr, DLADM_STRSIZE);
6753         opterr = 0;
6754         state.ls_propvals = NULL;
6755         state.ls_line = NULL;
6756         state.ls_parsable = B_FALSE;
6757         state.ls_persist = B_FALSE;
6758         state.ls_header = B_TRUE;
6759         state.ls_retstatus = DLADM_STATUS_OK;
6760 
6761         while ((option = getopt_long(argc, argv, ":p:cPo:z:",
6762             prop_longopts, NULL)) != -1) {
6763                 switch (option) {
6764                 case 'p':
6765                         (void) strlcat(propstr, optarg, DLADM_STRSIZE);
6766                         if (strlcat(propstr, ",", DLADM_STRSIZE) >=
6767                             DLADM_STRSIZE)
6768                                 die("property list too long '%s'", propstr);
6769                         break;
6770                 case 'c':
6771                         state.ls_parsable = B_TRUE;
6772                         break;
6773                 case 'P':
6774                         state.ls_persist = B_TRUE;
6775                         flags = DLADM_OPT_PERSIST;
6776                         break;
6777                 case 'o':
6778                         fields_str = optarg;
6779                         break;
6780                 case 'z':
6781                         zonename = optarg;
6782                         break;
6783                 default:
6784                         die_opterr(optopt, option, use);
6785                         break;
6786                 }
6787         }
6788 
6789         if (optind == (argc - 1)) {
6790                 if ((status = dladm_zname2info(handle, zonename, argv[optind],
6791                     &linkid, NULL, NULL, NULL)) != DLADM_STATUS_OK) {
6792                         die_dlerr(status, "link %s is not valid", argv[optind]);
6793                 }
6794         } else if (optind != argc) {
6795                 usage();
6796         }
6797 
6798         if (dladm_parse_link_props(propstr, &proplist, B_TRUE)
6799             != DLADM_STATUS_OK)
6800                 die("invalid link properties specified");
6801         state.ls_proplist = proplist;
6802         state.ls_zonename = zonename;
6803         state.ls_status = DLADM_STATUS_OK;
6804 
6805         if (state.ls_parsable)
6806                 ofmtflags |= OFMT_PARSABLE;
6807         else
6808                 ofmtflags |= OFMT_WRAP;
6809 
6810         oferr = ofmt_open(fields_str, linkprop_fields, ofmtflags, 0, &ofmt);
6811         dladm_ofmt_check(oferr, state.ls_parsable, ofmt);
6812         state.ls_ofmt = ofmt;
6813 
6814         if (linkid == DATALINK_ALL_LINKID) {
6815                 (void) dladm_walk_datalink_id(show_linkprop_onelink, handle,
6816                     &state, DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE, flags);
6817         } else {
6818                 (void) show_linkprop_onelink(handle, linkid, &state);
6819         }
6820         ofmt_close(ofmt);
6821         dladm_free_props(proplist);
6822 


6827 }
6828 
6829 static int
6830 show_linkprop_onelink(dladm_handle_t hdl, datalink_id_t linkid, void *arg)
6831 {
6832         int                     i;
6833         char                    *buf;
6834         uint32_t                flags;
6835         dladm_arg_list_t        *proplist = NULL;
6836         show_linkprop_state_t   *statep = arg;
6837         dlpi_handle_t           dh = NULL;
6838 
6839         statep->ls_status = DLADM_STATUS_OK;
6840 
6841         if (dladm_datalink_id2info(hdl, linkid, &flags, NULL, NULL,
6842             statep->ls_link, MAXLINKNAMELEN) != DLADM_STATUS_OK) {
6843                 statep->ls_status = DLADM_STATUS_NOTFOUND;
6844                 return (DLADM_WALK_CONTINUE);
6845         }
6846 
6847         if (statep->ls_zonename != NULL) {
6848                 datalink_id_t   tlinkid;
6849 
6850                 if (dladm_zname2info(hdl, statep->ls_zonename, statep->ls_link,
6851                     &tlinkid, NULL, NULL, NULL) != DLADM_STATUS_OK ||
6852                     linkid != tlinkid) {
6853                         statep->ls_status = DLADM_STATUS_NOTFOUND;
6854                         return (DLADM_WALK_CONTINUE);
6855                 }
6856         }
6857 
6858         if ((statep->ls_persist && !(flags & DLADM_OPT_PERSIST)) ||
6859             (!statep->ls_persist && !(flags & DLADM_OPT_ACTIVE))) {
6860                 statep->ls_status = DLADM_STATUS_BADARG;
6861                 return (DLADM_WALK_CONTINUE);
6862         }
6863 
6864         proplist = statep->ls_proplist;
6865 
6866         /*
6867          * When some WiFi links are opened for the first time, their hardware
6868          * automatically scans for APs and does other slow operations.  Thus,
6869          * if there are no open links, the retrieval of link properties
6870          * (below) will proceed slowly unless we hold the link open.
6871          *
6872          * Note that failure of dlpi_open() does not necessarily mean invalid
6873          * link properties, because dlpi_open() may fail because of incorrect
6874          * autopush configuration. Therefore, we ingore the return value of
6875          * dlpi_open().
6876          */
6877         if (!statep->ls_persist)


6920             status != DLADM_STATUS_NOTSUP) {
6921                 warn_dlerr(status, "cannot reset link property '%s' on '%s'",
6922                     propname, statep->ls_name);
6923                 statep->ls_status = status;
6924         }
6925 
6926         return (DLADM_WALK_CONTINUE);
6927 }
6928 
6929 static void
6930 set_linkprop(int argc, char **argv, boolean_t reset, const char *use)
6931 {
6932         int                     i, option;
6933         char                    errmsg[DLADM_STRSIZE];
6934         char                    *altroot = NULL;
6935         datalink_id_t           linkid;
6936         boolean_t               temp = B_FALSE;
6937         dladm_status_t          status = DLADM_STATUS_OK;
6938         char                    propstr[DLADM_STRSIZE];
6939         dladm_arg_list_t        *proplist = NULL;
6940         char                    *zonename = NULL;
6941 
6942         opterr = 0;
6943         bzero(propstr, DLADM_STRSIZE);
6944 
6945         while ((option = getopt_long(argc, argv, ":p:R:tz:",
6946             prop_longopts, NULL)) != -1) {
6947                 switch (option) {
6948                 case 'p':
6949                         (void) strlcat(propstr, optarg, DLADM_STRSIZE);
6950                         if (strlcat(propstr, ",", DLADM_STRSIZE) >=
6951                             DLADM_STRSIZE)
6952                                 die("property list too long '%s'", propstr);
6953                         break;
6954                 case 't':
6955                         temp = B_TRUE;
6956                         break;
6957                 case 'R':
6958                         altroot = optarg;
6959                         break;
6960                 case 'z':
6961                         zonename = optarg;
6962                         break;
6963                 default:
6964                         die_opterr(optopt, option, use);
6965 
6966                 }
6967         }
6968 
6969         /* get link name (required last argument) */
6970         if (optind != (argc - 1))
6971                 usage();
6972 
6973         if (dladm_parse_link_props(propstr, &proplist, reset) !=
6974             DLADM_STATUS_OK)
6975                 die("invalid link properties specified");
6976 
6977         if (proplist == NULL && !reset)
6978                 die("link property must be specified");
6979 
6980         if (altroot != NULL) {
6981                 dladm_free_props(proplist);
6982                 altroot_cmd(altroot, argc, argv);
6983         }
6984 
6985         status = dladm_zname2info(handle, zonename, argv[optind], &linkid,
6986             NULL, NULL, NULL);
6987         if (status != DLADM_STATUS_OK)
6988                 die_dlerr(status, "link %s is not valid", argv[optind]);
6989 
6990         if (proplist == NULL) {
6991                 set_linkprop_state_t    state;
6992 
6993                 state.ls_name = argv[optind];
6994                 state.ls_reset = reset;
6995                 state.ls_temp = temp;
6996                 state.ls_status = DLADM_STATUS_OK;
6997 
6998                 (void) dladm_walk_linkprop(handle, linkid, &state,
6999                     reset_one_linkprop);
7000 
7001                 status = state.ls_status;
7002                 goto done;
7003         }
7004 
7005         for (i = 0; i < proplist->al_count; i++) {
7006                 dladm_arg_info_t        *aip = &proplist->al_info[i];