17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5219a2a31Shl157128 * Common Development and Distribution License (the "License"). 6219a2a31Shl157128 * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22ad091ee1SMichael Lim * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #include <stdio.h> 270ba2cbe9Sxc151355 #include <ctype.h> 28*4eaa4710SRishi Srivatsavai #include <dlfcn.h> 297c478bd9Sstevel@tonic-gate #include <locale.h> 300ba2cbe9Sxc151355 #include <signal.h> 317c478bd9Sstevel@tonic-gate #include <stdarg.h> 327c478bd9Sstevel@tonic-gate #include <stdlib.h> 337c478bd9Sstevel@tonic-gate #include <fcntl.h> 347c478bd9Sstevel@tonic-gate #include <string.h> 357c478bd9Sstevel@tonic-gate #include <stropts.h> 36d62bc4baSyz147064 #include <sys/stat.h> 377c478bd9Sstevel@tonic-gate #include <errno.h> 387c478bd9Sstevel@tonic-gate #include <kstat.h> 397c478bd9Sstevel@tonic-gate #include <strings.h> 407c478bd9Sstevel@tonic-gate #include <getopt.h> 417c478bd9Sstevel@tonic-gate #include <unistd.h> 42cd93090eSericheng #include <priv.h> 430ba2cbe9Sxc151355 #include <termios.h> 440ba2cbe9Sxc151355 #include <pwd.h> 450ba2cbe9Sxc151355 #include <auth_attr.h> 460ba2cbe9Sxc151355 #include <auth_list.h> 477c478bd9Sstevel@tonic-gate #include <libintl.h> 48d62bc4baSyz147064 #include <libdevinfo.h> 497c478bd9Sstevel@tonic-gate #include <libdlpi.h> 50da14cebeSEric Cheng #include <libdladm.h> 51f595a68aSyz147064 #include <libdllink.h> 52da14cebeSEric Cheng #include <libdlstat.h> 53f595a68aSyz147064 #include <libdlaggr.h> 54f595a68aSyz147064 #include <libdlwlan.h> 55d62bc4baSyz147064 #include <libdlvlan.h> 56d62bc4baSyz147064 #include <libdlvnic.h> 574784fcbdSSowmini Varadhan #include <libdlether.h> 58b509e89bSRishi Srivatsavai #include <libdlsim.h> 59*4eaa4710SRishi Srivatsavai #include <libdlbridge.h> 600ba2cbe9Sxc151355 #include <libinetutil.h> 610ba2cbe9Sxc151355 #include <bsm/adt.h> 620ba2cbe9Sxc151355 #include <bsm/adt_event.h> 63da14cebeSEric Cheng #include <libdlvnic.h> 64da14cebeSEric Cheng #include <sys/types.h> 65da14cebeSEric Cheng #include <sys/socket.h> 66da14cebeSEric Cheng #include <sys/processor.h> 67da14cebeSEric Cheng #include <netinet/in.h> 68da14cebeSEric Cheng #include <arpa/inet.h> 69da14cebeSEric Cheng #include <net/if_types.h> 70e7801d59Ssowmini #include <stddef.h> 71*4eaa4710SRishi Srivatsavai #include <stp_in.h> 728002d411SSowmini Varadhan #include <ofmt.h> 737c478bd9Sstevel@tonic-gate 747c478bd9Sstevel@tonic-gate #define MAXPORT 256 75da14cebeSEric Cheng #define MAXVNIC 256 76d62bc4baSyz147064 #define BUFLEN(lim, ptr) (((lim) > (ptr)) ? ((lim) - (ptr)) : 0) 77d62bc4baSyz147064 #define MAXLINELEN 1024 78d62bc4baSyz147064 #define SMF_UPGRADE_FILE "/var/svc/profile/upgrade" 79d62bc4baSyz147064 #define SMF_UPGRADEDATALINK_FILE "/var/svc/profile/upgrade_datalink" 80d62bc4baSyz147064 #define SMF_DLADM_UPGRADE_MSG " # added by dladm(1M)" 818002d411SSowmini Varadhan #define DLADM_DEFAULT_COL 80 827c478bd9Sstevel@tonic-gate 838002d411SSowmini Varadhan /* 848002d411SSowmini Varadhan * used by the wifi show-* commands to set up ofmt_field_t structures. 858002d411SSowmini Varadhan */ 86e7801d59Ssowmini #define WIFI_CMD_SCAN 0x00000001 87e7801d59Ssowmini #define WIFI_CMD_SHOW 0x00000002 88e7801d59Ssowmini #define WIFI_CMD_ALL (WIFI_CMD_SCAN | WIFI_CMD_SHOW) 89e7801d59Ssowmini 90*4eaa4710SRishi Srivatsavai /* No larger than pktsum_t */ 91*4eaa4710SRishi Srivatsavai typedef struct brsum_s { 92*4eaa4710SRishi Srivatsavai uint64_t drops; 93*4eaa4710SRishi Srivatsavai uint64_t forward_dir; 94*4eaa4710SRishi Srivatsavai uint64_t forward_mb; 95*4eaa4710SRishi Srivatsavai uint64_t forward_unk; 96*4eaa4710SRishi Srivatsavai uint64_t recv; 97*4eaa4710SRishi Srivatsavai uint64_t sent; 98*4eaa4710SRishi Srivatsavai } brsum_t; 99*4eaa4710SRishi Srivatsavai 100*4eaa4710SRishi Srivatsavai /* No larger than pktsum_t */ 101*4eaa4710SRishi Srivatsavai typedef struct brlsum_s { 102*4eaa4710SRishi Srivatsavai uint32_t cfgbpdu; 103*4eaa4710SRishi Srivatsavai uint32_t tcnbpdu; 104*4eaa4710SRishi Srivatsavai uint32_t rstpbpdu; 105*4eaa4710SRishi Srivatsavai uint32_t txbpdu; 106*4eaa4710SRishi Srivatsavai uint64_t drops; 107*4eaa4710SRishi Srivatsavai uint64_t recv; 108*4eaa4710SRishi Srivatsavai uint64_t xmit; 109*4eaa4710SRishi Srivatsavai } brlsum_t; 110*4eaa4710SRishi Srivatsavai 111d62bc4baSyz147064 typedef struct show_state { 1127c478bd9Sstevel@tonic-gate boolean_t ls_firstonly; 1137c478bd9Sstevel@tonic-gate boolean_t ls_donefirst; 1147c478bd9Sstevel@tonic-gate pktsum_t ls_prevstats; 115d62bc4baSyz147064 uint32_t ls_flags; 116d62bc4baSyz147064 dladm_status_t ls_status; 1178002d411SSowmini Varadhan ofmt_handle_t ls_ofmt; 1188002d411SSowmini Varadhan boolean_t ls_parsable; 119da14cebeSEric Cheng boolean_t ls_mac; 120da14cebeSEric Cheng boolean_t ls_hwgrp; 121d62bc4baSyz147064 } show_state_t; 1227c478bd9Sstevel@tonic-gate 1237c478bd9Sstevel@tonic-gate typedef struct show_grp_state { 124e7801d59Ssowmini pktsum_t gs_prevstats[MAXPORT]; 125e7801d59Ssowmini uint32_t gs_flags; 126e7801d59Ssowmini dladm_status_t gs_status; 1278002d411SSowmini Varadhan boolean_t gs_parsable; 1287c478bd9Sstevel@tonic-gate boolean_t gs_lacp; 129d62bc4baSyz147064 boolean_t gs_extended; 1307c478bd9Sstevel@tonic-gate boolean_t gs_stats; 1317c478bd9Sstevel@tonic-gate boolean_t gs_firstonly; 132d62bc4baSyz147064 boolean_t gs_donefirst; 1338002d411SSowmini Varadhan ofmt_handle_t gs_ofmt; 1347c478bd9Sstevel@tonic-gate } show_grp_state_t; 1357c478bd9Sstevel@tonic-gate 136da14cebeSEric Cheng typedef struct show_vnic_state { 137da14cebeSEric Cheng datalink_id_t vs_vnic_id; 138da14cebeSEric Cheng datalink_id_t vs_link_id; 139da14cebeSEric Cheng char vs_vnic[MAXLINKNAMELEN]; 140da14cebeSEric Cheng char vs_link[MAXLINKNAMELEN]; 1418002d411SSowmini Varadhan boolean_t vs_parsable; 142da14cebeSEric Cheng boolean_t vs_found; 143da14cebeSEric Cheng boolean_t vs_firstonly; 144da14cebeSEric Cheng boolean_t vs_donefirst; 145da14cebeSEric Cheng boolean_t vs_stats; 146da14cebeSEric Cheng boolean_t vs_printstats; 147da14cebeSEric Cheng pktsum_t vs_totalstats; 148da14cebeSEric Cheng pktsum_t vs_prevstats[MAXVNIC]; 149da14cebeSEric Cheng boolean_t vs_etherstub; 150da14cebeSEric Cheng dladm_status_t vs_status; 151da14cebeSEric Cheng uint32_t vs_flags; 1528002d411SSowmini Varadhan ofmt_handle_t vs_ofmt; 153da14cebeSEric Cheng } show_vnic_state_t; 154da14cebeSEric Cheng 155da14cebeSEric Cheng typedef struct show_usage_state_s { 156da14cebeSEric Cheng boolean_t us_plot; 1578002d411SSowmini Varadhan boolean_t us_parsable; 158da14cebeSEric Cheng boolean_t us_printheader; 159da14cebeSEric Cheng boolean_t us_first; 160ae6aa22aSVenugopal Iyer boolean_t us_showall; 1618002d411SSowmini Varadhan ofmt_handle_t us_ofmt; 162da14cebeSEric Cheng } show_usage_state_t; 163da14cebeSEric Cheng 1648002d411SSowmini Varadhan /* 1658002d411SSowmini Varadhan * callback functions for printing output and error diagnostics. 1668002d411SSowmini Varadhan */ 1678002d411SSowmini Varadhan static ofmt_cb_t print_default_cb, print_link_stats_cb, print_linkprop_cb; 1688002d411SSowmini Varadhan static ofmt_cb_t print_lacp_cb, print_phys_one_mac_cb; 1698002d411SSowmini Varadhan static ofmt_cb_t print_xaggr_cb, print_aggr_stats_cb; 1708002d411SSowmini Varadhan static ofmt_cb_t print_phys_one_hwgrp_cb, print_wlan_attr_cb; 1718002d411SSowmini Varadhan static ofmt_cb_t print_wifi_status_cb, print_link_attr_cb; 1728002d411SSowmini Varadhan static void dladm_ofmt_check(ofmt_status_t, boolean_t, ofmt_handle_t); 1738002d411SSowmini Varadhan 1748d5c46e6Sam223141 typedef void cmdfunc_t(int, char **, const char *); 1750ba2cbe9Sxc151355 176da14cebeSEric Cheng static cmdfunc_t do_show_link, do_show_wifi, do_show_phys; 1770ba2cbe9Sxc151355 static cmdfunc_t do_create_aggr, do_delete_aggr, do_add_aggr, do_remove_aggr; 178d62bc4baSyz147064 static cmdfunc_t do_modify_aggr, do_show_aggr, do_up_aggr; 1790ba2cbe9Sxc151355 static cmdfunc_t do_scan_wifi, do_connect_wifi, do_disconnect_wifi; 1800ba2cbe9Sxc151355 static cmdfunc_t do_show_linkprop, do_set_linkprop, do_reset_linkprop; 1810ba2cbe9Sxc151355 static cmdfunc_t do_create_secobj, do_delete_secobj, do_show_secobj; 1820ba2cbe9Sxc151355 static cmdfunc_t do_init_linkprop, do_init_secobj; 183d62bc4baSyz147064 static cmdfunc_t do_create_vlan, do_delete_vlan, do_up_vlan, do_show_vlan; 184d62bc4baSyz147064 static cmdfunc_t do_rename_link, do_delete_phys, do_init_phys; 185d62bc4baSyz147064 static cmdfunc_t do_show_linkmap; 186e7801d59Ssowmini static cmdfunc_t do_show_ether; 187da14cebeSEric Cheng static cmdfunc_t do_create_vnic, do_delete_vnic, do_show_vnic; 188da14cebeSEric Cheng static cmdfunc_t do_up_vnic; 189da14cebeSEric Cheng static cmdfunc_t do_create_etherstub, do_delete_etherstub, do_show_etherstub; 190b509e89bSRishi Srivatsavai static cmdfunc_t do_create_simnet, do_modify_simnet; 191b509e89bSRishi Srivatsavai static cmdfunc_t do_delete_simnet, do_show_simnet, do_up_simnet; 192da14cebeSEric Cheng static cmdfunc_t do_show_usage; 193*4eaa4710SRishi Srivatsavai static cmdfunc_t do_create_bridge, do_modify_bridge, do_delete_bridge; 194*4eaa4710SRishi Srivatsavai static cmdfunc_t do_add_bridge, do_remove_bridge, do_show_bridge; 195da14cebeSEric Cheng 196da14cebeSEric Cheng static void do_up_vnic_common(int, char **, const char *, boolean_t); 1977c478bd9Sstevel@tonic-gate 198d62bc4baSyz147064 static void altroot_cmd(char *, int, char **); 1994ac67f02SAnurag S. Maskey static int show_linkprop_onelink(dladm_handle_t, datalink_id_t, void *); 200f4b3ec61Sdh155122 2016be03d0bSVasumathi Sundaram - Sun Microsystems static void link_stats(datalink_id_t, uint_t, char *, show_state_t *); 202d62bc4baSyz147064 static void aggr_stats(datalink_id_t, show_grp_state_t *, uint_t); 203da14cebeSEric Cheng static void vnic_stats(show_vnic_state_t *, uint32_t); 2047c478bd9Sstevel@tonic-gate 205d62bc4baSyz147064 static int get_one_kstat(const char *, const char *, uint8_t, 206d62bc4baSyz147064 void *, boolean_t); 207ba2e4443Sseb static void get_mac_stats(const char *, pktsum_t *); 2087c478bd9Sstevel@tonic-gate static void get_link_stats(const char *, pktsum_t *); 209d62bc4baSyz147064 static uint64_t get_ifspeed(const char *, boolean_t); 210d62bc4baSyz147064 static const char *get_linkstate(const char *, boolean_t, char *); 211d62bc4baSyz147064 static const char *get_linkduplex(const char *, boolean_t, char *); 2127c478bd9Sstevel@tonic-gate 2134ac67f02SAnurag S. Maskey static int show_etherprop(dladm_handle_t, datalink_id_t, void *); 2144784fcbdSSowmini Varadhan static void show_ether_xprop(void *, dladm_ether_info_t *); 215e7801d59Ssowmini static boolean_t link_is_ether(const char *, datalink_id_t *); 216e7801d59Ssowmini 21733343a97Smeem static boolean_t str2int(const char *, int *); 21833343a97Smeem static void die(const char *, ...); 21933343a97Smeem static void die_optdup(int); 2208d5c46e6Sam223141 static void die_opterr(int, int, const char *); 22133343a97Smeem static void die_dlerr(dladm_status_t, const char *, ...); 22233343a97Smeem static void warn(const char *, ...); 22333343a97Smeem static void warn_dlerr(dladm_status_t, const char *, ...); 22433343a97Smeem 2257c478bd9Sstevel@tonic-gate typedef struct cmd { 2267c478bd9Sstevel@tonic-gate char *c_name; 2270ba2cbe9Sxc151355 cmdfunc_t *c_fn; 2288d5c46e6Sam223141 const char *c_usage; 2297c478bd9Sstevel@tonic-gate } cmd_t; 2307c478bd9Sstevel@tonic-gate 2317c478bd9Sstevel@tonic-gate static cmd_t cmds[] = { 2328d5c46e6Sam223141 { "rename-link", do_rename_link, 2330790b6dcSAnurag S. Maskey " rename-link <oldlink> <newlink>" }, 2340790b6dcSAnurag S. Maskey { "show-link", do_show_link, 2350790b6dcSAnurag S. Maskey " show-link [-pP] [-o <field>,..] [-s [-i <interval>]] " 2360790b6dcSAnurag S. Maskey "[<link>]\n" }, 2378d5c46e6Sam223141 { "create-aggr", do_create_aggr, 2380790b6dcSAnurag S. Maskey " create-aggr [-t] [-P <policy>] [-L <mode>] [-T <time>] " 2390790b6dcSAnurag S. Maskey "[-u <address>]\n" 2400790b6dcSAnurag S. Maskey "\t\t -l <link> [-l <link>...] <link>" }, 2418d5c46e6Sam223141 { "delete-aggr", do_delete_aggr, 2420790b6dcSAnurag S. Maskey " delete-aggr [-t] <link>" }, 2438d5c46e6Sam223141 { "add-aggr", do_add_aggr, 2440790b6dcSAnurag S. Maskey " add-aggr [-t] -l <link> [-l <link>...] <link>" }, 2458d5c46e6Sam223141 { "remove-aggr", do_remove_aggr, 2460790b6dcSAnurag S. Maskey " remove-aggr [-t] -l <link> [-l <link>...] <link>" }, 2478d5c46e6Sam223141 { "modify-aggr", do_modify_aggr, 2480790b6dcSAnurag S. Maskey " modify-aggr [-t] [-P <policy>] [-L <mode>] [-T <time>] " 2490790b6dcSAnurag S. Maskey "[-u <address>]\n" 2500790b6dcSAnurag S. Maskey "\t\t <link>" }, 2518d5c46e6Sam223141 { "show-aggr", do_show_aggr, 2520790b6dcSAnurag S. Maskey " show-aggr [-pPLx] [-o <field>,..] [-s [-i <interval>]] " 2538d5c46e6Sam223141 "[<link>]\n" }, 2548d5c46e6Sam223141 { "up-aggr", do_up_aggr, NULL }, 2558d5c46e6Sam223141 { "scan-wifi", do_scan_wifi, 2560790b6dcSAnurag S. Maskey " scan-wifi [-p] [-o <field>,...] [<link>]" }, 2578d5c46e6Sam223141 { "connect-wifi", do_connect_wifi, 2580790b6dcSAnurag S. Maskey " connect-wifi [-e <essid>] [-i <bssid>] [-k <key>,...] " 2598d5c46e6Sam223141 "[-s wep|wpa]\n" 2600790b6dcSAnurag S. Maskey "\t\t [-a open|shared] [-b bss|ibss] [-c] [-m a|b|g] " 2610790b6dcSAnurag S. Maskey "[-T <time>]\n" 2620790b6dcSAnurag S. Maskey "\t\t [<link>]" }, 2638d5c46e6Sam223141 { "disconnect-wifi", do_disconnect_wifi, 2640790b6dcSAnurag S. Maskey " disconnect-wifi [-a] [<link>]" }, 2658d5c46e6Sam223141 { "show-wifi", do_show_wifi, 2660790b6dcSAnurag S. Maskey " show-wifi [-p] [-o <field>,...] [<link>]\n" }, 2678d5c46e6Sam223141 { "set-linkprop", do_set_linkprop, 2680790b6dcSAnurag S. Maskey " set-linkprop [-t] -p <prop>=<value>[,...] <name>" }, 2698d5c46e6Sam223141 { "reset-linkprop", do_reset_linkprop, 2700790b6dcSAnurag S. Maskey " reset-linkprop [-t] [-p <prop>,...] <name>" }, 2710790b6dcSAnurag S. Maskey { "show-linkprop", do_show_linkprop, 2720790b6dcSAnurag S. Maskey " show-linkprop [-cP] [-o <field>,...] [-p <prop>,...] " 2730790b6dcSAnurag S. Maskey "<name>\n" }, 2748d5c46e6Sam223141 { "show-ether", do_show_ether, 2750790b6dcSAnurag S. Maskey " show-ether [-px][-o <field>,...] <link>\n" }, 2768d5c46e6Sam223141 { "create-secobj", do_create_secobj, 2770790b6dcSAnurag S. Maskey " create-secobj [-t] [-f <file>] -c <class> <secobj>" }, 2788d5c46e6Sam223141 { "delete-secobj", do_delete_secobj, 2790790b6dcSAnurag S. Maskey " delete-secobj [-t] <secobj>[,...]" }, 2808d5c46e6Sam223141 { "show-secobj", do_show_secobj, 2810790b6dcSAnurag S. Maskey " show-secobj [-pP] [-o <field>,...] [<secobj>,...]\n" }, 2828d5c46e6Sam223141 { "init-linkprop", do_init_linkprop, NULL }, 2838d5c46e6Sam223141 { "init-secobj", do_init_secobj, NULL }, 2848d5c46e6Sam223141 { "create-vlan", do_create_vlan, 2850790b6dcSAnurag S. Maskey " create-vlan [-ft] -l <link> -v <vid> [link]" }, 2868d5c46e6Sam223141 { "delete-vlan", do_delete_vlan, 2870790b6dcSAnurag S. Maskey " delete-vlan [-t] <link>" }, 2888d5c46e6Sam223141 { "show-vlan", do_show_vlan, 2890790b6dcSAnurag S. Maskey " show-vlan [-pP] [-o <field>,..] [<link>]\n" }, 2908d5c46e6Sam223141 { "up-vlan", do_up_vlan, NULL }, 2918d5c46e6Sam223141 { "delete-phys", do_delete_phys, 2920790b6dcSAnurag S. Maskey " delete-phys <link>" }, 2938d5c46e6Sam223141 { "show-phys", do_show_phys, 2940790b6dcSAnurag S. Maskey " show-phys [-pP] [-o <field>,..] [-H] [<link>]\n"}, 2958d5c46e6Sam223141 { "init-phys", do_init_phys, NULL }, 296da14cebeSEric Cheng { "show-linkmap", do_show_linkmap, NULL }, 297da14cebeSEric Cheng { "create-vnic", do_create_vnic, 2980790b6dcSAnurag S. Maskey " create-vnic [-t] -l <link> [-m <value> | auto |\n" 2990790b6dcSAnurag S. Maskey "\t\t {factory [-n <slot-id>]} | {random [-r <prefix>]}]\n" 3000790b6dcSAnurag S. Maskey "\t\t [-v <vid> [-f]] [-p <prop>=<value>[,...]] [-H] " 3010790b6dcSAnurag S. Maskey "<vnic-link>" }, 302da14cebeSEric Cheng { "delete-vnic", do_delete_vnic, 3030790b6dcSAnurag S. Maskey " delete-vnic [-t] <vnic-link>" }, 304da14cebeSEric Cheng { "show-vnic", do_show_vnic, 3050790b6dcSAnurag S. Maskey " show-vnic [-pP] [-l <link>] [-s [-i <interval>]] " 3060790b6dcSAnurag S. Maskey "[<link>]\n" }, 307da14cebeSEric Cheng { "up-vnic", do_up_vnic, NULL }, 308da14cebeSEric Cheng { "create-etherstub", do_create_etherstub, 3090790b6dcSAnurag S. Maskey " create-etherstub [-t] <link>" }, 310da14cebeSEric Cheng { "delete-etherstub", do_delete_etherstub, 3110790b6dcSAnurag S. Maskey " delete-etherstub [-t] <link>" }, 312da14cebeSEric Cheng { "show-etherstub", do_show_etherstub, 3130790b6dcSAnurag S. Maskey " show-etherstub [-t] [<link>]\n" }, 3140f83d385SRishi Srivatsavai { "create-simnet", do_create_simnet, NULL }, 3150f83d385SRishi Srivatsavai { "modify-simnet", do_modify_simnet, NULL }, 3160f83d385SRishi Srivatsavai { "delete-simnet", do_delete_simnet, NULL }, 3170f83d385SRishi Srivatsavai { "show-simnet", do_show_simnet, NULL }, 318b509e89bSRishi Srivatsavai { "up-simnet", do_up_simnet, NULL }, 319*4eaa4710SRishi Srivatsavai { "create-bridge", do_create_bridge, 320*4eaa4710SRishi Srivatsavai " create-bridge [-R <root-dir>] [-P <protect>] " 321*4eaa4710SRishi Srivatsavai "[-p <priority>]\n" 322*4eaa4710SRishi Srivatsavai "\t\t [-m <max-age>] [-h <hello-time>] [-d <forward-delay>]\n" 323*4eaa4710SRishi Srivatsavai "\t\t [-f <force-protocol>] [-l <link>]... <bridge>" }, 324*4eaa4710SRishi Srivatsavai { "modify-bridge", do_modify_bridge, 325*4eaa4710SRishi Srivatsavai " modify-bridge [-R <root-dir>] [-P <protect>] " 326*4eaa4710SRishi Srivatsavai "[-p <priority>]\n" 327*4eaa4710SRishi Srivatsavai "\t\t [-m <max-age>] [-h <hello-time>] [-d <forward-delay>]\n" 328*4eaa4710SRishi Srivatsavai "\t\t [-f <force-protocol>] <bridge>" }, 329*4eaa4710SRishi Srivatsavai { "delete-bridge", do_delete_bridge, 330*4eaa4710SRishi Srivatsavai " delete-bridge [-R <root-dir>] <bridge>" }, 331*4eaa4710SRishi Srivatsavai { "add-bridge", do_add_bridge, 332*4eaa4710SRishi Srivatsavai " add-bridge [-R <root-dir>] -l <link> [-l <link>]... " 333*4eaa4710SRishi Srivatsavai "<bridge>" }, 334*4eaa4710SRishi Srivatsavai { "remove-bridge", do_remove_bridge, 335*4eaa4710SRishi Srivatsavai " remove-bridge [-R <root-dir>] -l <link> [-l <link>]... " 336*4eaa4710SRishi Srivatsavai "<bridge>" }, 337*4eaa4710SRishi Srivatsavai { "show-bridge", do_show_bridge, 338*4eaa4710SRishi Srivatsavai " show-bridge [-p] [-o <field>,...] [-s [-i <interval>]] " 339*4eaa4710SRishi Srivatsavai "[<bridge>]\n" 340*4eaa4710SRishi Srivatsavai " show-bridge -l [-p] [-o <field>,...] [-s [-i <interval>]]" 341*4eaa4710SRishi Srivatsavai " <bridge>\n" 342*4eaa4710SRishi Srivatsavai " show-bridge -f [-p] [-o <field>,...] [-s [-i <interval>]]" 343*4eaa4710SRishi Srivatsavai " <bridge>\n" 344*4eaa4710SRishi Srivatsavai " show-bridge -t [-p] [-o <field>,...] [-s [-i <interval>]]" 345*4eaa4710SRishi Srivatsavai " <bridge>\n" }, 346da14cebeSEric Cheng { "show-usage", do_show_usage, 347ae6aa22aSVenugopal Iyer " show-usage [-a] [-d | -F <format>] " 3480790b6dcSAnurag S. Maskey "[-s <DD/MM/YYYY,HH:MM:SS>]\n" 3490790b6dcSAnurag S. Maskey "\t\t [-e <DD/MM/YYYY,HH:MM:SS>] -f <logfile> [<link>]" } 3507c478bd9Sstevel@tonic-gate }; 3517c478bd9Sstevel@tonic-gate 352d62bc4baSyz147064 static const struct option lopts[] = { 3537c478bd9Sstevel@tonic-gate {"vlan-id", required_argument, 0, 'v'}, 354e7801d59Ssowmini {"output", required_argument, 0, 'o'}, 3557c478bd9Sstevel@tonic-gate {"dev", required_argument, 0, 'd'}, 3567c478bd9Sstevel@tonic-gate {"policy", required_argument, 0, 'P'}, 357d62bc4baSyz147064 {"lacp-mode", required_argument, 0, 'L'}, 3587c478bd9Sstevel@tonic-gate {"lacp-timer", required_argument, 0, 'T'}, 3597c478bd9Sstevel@tonic-gate {"unicast", required_argument, 0, 'u'}, 360d62bc4baSyz147064 {"temporary", no_argument, 0, 't'}, 361d62bc4baSyz147064 {"root-dir", required_argument, 0, 'R'}, 362d62bc4baSyz147064 {"link", required_argument, 0, 'l'}, 363d62bc4baSyz147064 {"forcible", no_argument, 0, 'f'}, 364da14cebeSEric Cheng {"bw-limit", required_argument, 0, 'b'}, 365da14cebeSEric Cheng {"mac-address", required_argument, 0, 'm'}, 366da14cebeSEric Cheng {"slot", required_argument, 0, 'n'}, 367d62bc4baSyz147064 { 0, 0, 0, 0 } 368d62bc4baSyz147064 }; 369d62bc4baSyz147064 370d62bc4baSyz147064 static const struct option show_lopts[] = { 3717c478bd9Sstevel@tonic-gate {"statistics", no_argument, 0, 's'}, 372da14cebeSEric Cheng {"continuous", no_argument, 0, 'S'}, 3737c478bd9Sstevel@tonic-gate {"interval", required_argument, 0, 'i'}, 3748002d411SSowmini Varadhan {"parsable", no_argument, 0, 'p'}, 3757c478bd9Sstevel@tonic-gate {"parseable", no_argument, 0, 'p'}, 376d62bc4baSyz147064 {"extended", no_argument, 0, 'x'}, 377e7801d59Ssowmini {"output", required_argument, 0, 'o'}, 378d62bc4baSyz147064 {"persistent", no_argument, 0, 'P'}, 379d62bc4baSyz147064 {"lacp", no_argument, 0, 'L'}, 3807c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 } 3817c478bd9Sstevel@tonic-gate }; 3827c478bd9Sstevel@tonic-gate 3830ba2cbe9Sxc151355 static const struct option prop_longopts[] = { 3840ba2cbe9Sxc151355 {"temporary", no_argument, 0, 't' }, 385e7801d59Ssowmini {"output", required_argument, 0, 'o' }, 3860ba2cbe9Sxc151355 {"root-dir", required_argument, 0, 'R' }, 3870ba2cbe9Sxc151355 {"prop", required_argument, 0, 'p' }, 3888002d411SSowmini Varadhan {"parsable", no_argument, 0, 'c' }, 3890ba2cbe9Sxc151355 {"parseable", no_argument, 0, 'c' }, 3900ba2cbe9Sxc151355 {"persistent", no_argument, 0, 'P' }, 3910ba2cbe9Sxc151355 { 0, 0, 0, 0 } 3920ba2cbe9Sxc151355 }; 3930ba2cbe9Sxc151355 3940ba2cbe9Sxc151355 static const struct option wifi_longopts[] = { 3958002d411SSowmini Varadhan {"parsable", no_argument, 0, 'p' }, 3960ba2cbe9Sxc151355 {"parseable", no_argument, 0, 'p' }, 3970ba2cbe9Sxc151355 {"output", required_argument, 0, 'o' }, 3980ba2cbe9Sxc151355 {"essid", required_argument, 0, 'e' }, 3990ba2cbe9Sxc151355 {"bsstype", required_argument, 0, 'b' }, 4000ba2cbe9Sxc151355 {"mode", required_argument, 0, 'm' }, 4010ba2cbe9Sxc151355 {"key", required_argument, 0, 'k' }, 4020ba2cbe9Sxc151355 {"sec", required_argument, 0, 's' }, 4030ba2cbe9Sxc151355 {"auth", required_argument, 0, 'a' }, 4040ba2cbe9Sxc151355 {"create-ibss", required_argument, 0, 'c' }, 4050ba2cbe9Sxc151355 {"timeout", required_argument, 0, 'T' }, 4060ba2cbe9Sxc151355 {"all-links", no_argument, 0, 'a' }, 4070ba2cbe9Sxc151355 {"temporary", no_argument, 0, 't' }, 4080ba2cbe9Sxc151355 {"root-dir", required_argument, 0, 'R' }, 4090ba2cbe9Sxc151355 {"persistent", no_argument, 0, 'P' }, 4100ba2cbe9Sxc151355 {"file", required_argument, 0, 'f' }, 4110ba2cbe9Sxc151355 { 0, 0, 0, 0 } 4120ba2cbe9Sxc151355 }; 413e7801d59Ssowmini static const struct option showeth_lopts[] = { 4148002d411SSowmini Varadhan {"parsable", no_argument, 0, 'p' }, 415e7801d59Ssowmini {"parseable", no_argument, 0, 'p' }, 416e7801d59Ssowmini {"extended", no_argument, 0, 'x' }, 417e7801d59Ssowmini {"output", required_argument, 0, 'o' }, 418e7801d59Ssowmini { 0, 0, 0, 0 } 419e7801d59Ssowmini }; 420e7801d59Ssowmini 421da14cebeSEric Cheng static const struct option vnic_lopts[] = { 422da14cebeSEric Cheng {"temporary", no_argument, 0, 't' }, 423da14cebeSEric Cheng {"root-dir", required_argument, 0, 'R' }, 424da14cebeSEric Cheng {"dev", required_argument, 0, 'd' }, 425da14cebeSEric Cheng {"mac-address", required_argument, 0, 'm' }, 426da14cebeSEric Cheng {"cpus", required_argument, 0, 'c' }, 427da14cebeSEric Cheng {"bw-limit", required_argument, 0, 'b' }, 428da14cebeSEric Cheng {"slot", required_argument, 0, 'n' }, 429da14cebeSEric Cheng {"mac-prefix", required_argument, 0, 'r' }, 430da14cebeSEric Cheng { 0, 0, 0, 0 } 431da14cebeSEric Cheng }; 432da14cebeSEric Cheng 433da14cebeSEric Cheng static const struct option etherstub_lopts[] = { 434da14cebeSEric Cheng {"temporary", no_argument, 0, 't' }, 435da14cebeSEric Cheng {"root-dir", required_argument, 0, 'R' }, 436da14cebeSEric Cheng { 0, 0, 0, 0 } 437da14cebeSEric Cheng }; 438da14cebeSEric Cheng 439ae6aa22aSVenugopal Iyer static const struct option usage_opts[] = { 440ae6aa22aSVenugopal Iyer {"file", required_argument, 0, 'f' }, 441ae6aa22aSVenugopal Iyer {"format", required_argument, 0, 'F' }, 442ae6aa22aSVenugopal Iyer {"start", required_argument, 0, 's' }, 443ae6aa22aSVenugopal Iyer {"stop", required_argument, 0, 'e' }, 444ae6aa22aSVenugopal Iyer { 0, 0, 0, 0 } 445ae6aa22aSVenugopal Iyer }; 446ae6aa22aSVenugopal Iyer 447b509e89bSRishi Srivatsavai static const struct option simnet_lopts[] = { 448b509e89bSRishi Srivatsavai {"temporary", no_argument, 0, 't' }, 449b509e89bSRishi Srivatsavai {"root-dir", required_argument, 0, 'R' }, 450b509e89bSRishi Srivatsavai {"media", required_argument, 0, 'm' }, 451b509e89bSRishi Srivatsavai {"peer", required_argument, 0, 'p' }, 452b509e89bSRishi Srivatsavai { 0, 0, 0, 0 } 453b509e89bSRishi Srivatsavai }; 454b509e89bSRishi Srivatsavai 455*4eaa4710SRishi Srivatsavai static const struct option bridge_lopts[] = { 456*4eaa4710SRishi Srivatsavai { "protect", required_argument, 0, 'P' }, 457*4eaa4710SRishi Srivatsavai { "root-dir", required_argument, 0, 'R' }, 458*4eaa4710SRishi Srivatsavai { "forward-delay", required_argument, 0, 'd' }, 459*4eaa4710SRishi Srivatsavai { "force-protocol", required_argument, 0, 'f' }, 460*4eaa4710SRishi Srivatsavai { "hello-time", required_argument, 0, 'h' }, 461*4eaa4710SRishi Srivatsavai { "link", required_argument, 0, 'l' }, 462*4eaa4710SRishi Srivatsavai { "max-age", required_argument, 0, 'm' }, 463*4eaa4710SRishi Srivatsavai { "priority", required_argument, 0, 'p' }, 464*4eaa4710SRishi Srivatsavai { NULL, NULL, 0, 0 } 465*4eaa4710SRishi Srivatsavai }; 466*4eaa4710SRishi Srivatsavai 467*4eaa4710SRishi Srivatsavai static const struct option bridge_show_lopts[] = { 468*4eaa4710SRishi Srivatsavai { "forwarding", no_argument, 0, 'f' }, 469*4eaa4710SRishi Srivatsavai { "interval", required_argument, 0, 'i' }, 470*4eaa4710SRishi Srivatsavai { "link", no_argument, 0, 'l' }, 471*4eaa4710SRishi Srivatsavai { "output", required_argument, 0, 'o' }, 472*4eaa4710SRishi Srivatsavai { "parsable", no_argument, 0, 'p' }, 473*4eaa4710SRishi Srivatsavai { "parseable", no_argument, 0, 'p' }, 474*4eaa4710SRishi Srivatsavai { "statistics", no_argument, 0, 's' }, 475*4eaa4710SRishi Srivatsavai { "trill", no_argument, 0, 't' }, 476*4eaa4710SRishi Srivatsavai { 0, 0, 0, 0 } 477*4eaa4710SRishi Srivatsavai }; 478*4eaa4710SRishi Srivatsavai 479e7801d59Ssowmini /* 480e7801d59Ssowmini * structures for 'dladm show-ether' 481e7801d59Ssowmini */ 4824784fcbdSSowmini Varadhan static const char *ptype[] = {LEI_ATTR_NAMES}; 4834784fcbdSSowmini Varadhan 484e7801d59Ssowmini typedef struct ether_fields_buf_s 485e7801d59Ssowmini { 486e7801d59Ssowmini char eth_link[15]; 487e7801d59Ssowmini char eth_ptype[8]; 488e7801d59Ssowmini char eth_state[8]; 489e7801d59Ssowmini char eth_autoneg[5]; 490e7801d59Ssowmini char eth_spdx[31]; 491e7801d59Ssowmini char eth_pause[6]; 492e7801d59Ssowmini char eth_rem_fault[16]; 493e7801d59Ssowmini } ether_fields_buf_t; 494e7801d59Ssowmini 4958002d411SSowmini Varadhan static ofmt_field_t ether_fields[] = { 4968002d411SSowmini Varadhan /* name, field width, offset callback */ 4978002d411SSowmini Varadhan { "LINK", 16, 4988002d411SSowmini Varadhan offsetof(ether_fields_buf_t, eth_link), print_default_cb}, 4998002d411SSowmini Varadhan { "PTYPE", 9, 5008002d411SSowmini Varadhan offsetof(ether_fields_buf_t, eth_ptype), print_default_cb}, 5018002d411SSowmini Varadhan { "STATE", 9, 5028002d411SSowmini Varadhan offsetof(ether_fields_buf_t, eth_state), 5038002d411SSowmini Varadhan print_default_cb}, 5048002d411SSowmini Varadhan { "AUTO", 6, 5058002d411SSowmini Varadhan offsetof(ether_fields_buf_t, eth_autoneg), print_default_cb}, 5068002d411SSowmini Varadhan { "SPEED-DUPLEX", 32, 5078002d411SSowmini Varadhan offsetof(ether_fields_buf_t, eth_spdx), print_default_cb}, 5088002d411SSowmini Varadhan { "PAUSE", 7, 5098002d411SSowmini Varadhan offsetof(ether_fields_buf_t, eth_pause), print_default_cb}, 5108002d411SSowmini Varadhan { "REM_FAULT", 17, 5118002d411SSowmini Varadhan offsetof(ether_fields_buf_t, eth_rem_fault), print_default_cb}, 5128002d411SSowmini Varadhan {NULL, 0, 5138002d411SSowmini Varadhan 0, NULL}} 514e7801d59Ssowmini ; 515e7801d59Ssowmini 516e7801d59Ssowmini typedef struct print_ether_state { 517e7801d59Ssowmini const char *es_link; 5188002d411SSowmini Varadhan boolean_t es_parsable; 519e7801d59Ssowmini boolean_t es_header; 520e7801d59Ssowmini boolean_t es_extended; 5218002d411SSowmini Varadhan ofmt_handle_t es_ofmt; 522e7801d59Ssowmini } print_ether_state_t; 523e7801d59Ssowmini 524e7801d59Ssowmini /* 525da14cebeSEric Cheng * structures for 'dladm show-link -s' (print statistics) 526e7801d59Ssowmini */ 527e7801d59Ssowmini typedef enum { 528ae6aa22aSVenugopal Iyer LINK_S_LINK, 529ae6aa22aSVenugopal Iyer LINK_S_IPKTS, 530ae6aa22aSVenugopal Iyer LINK_S_RBYTES, 531ae6aa22aSVenugopal Iyer LINK_S_IERRORS, 532ae6aa22aSVenugopal Iyer LINK_S_OPKTS, 533ae6aa22aSVenugopal Iyer LINK_S_OBYTES, 534ae6aa22aSVenugopal Iyer LINK_S_OERRORS 535ae6aa22aSVenugopal Iyer } link_s_field_index_t; 536e7801d59Ssowmini 5378002d411SSowmini Varadhan static ofmt_field_t link_s_fields[] = { 5388002d411SSowmini Varadhan /* name, field width, index, callback */ 5398002d411SSowmini Varadhan { "LINK", 15, LINK_S_LINK, print_link_stats_cb}, 5408002d411SSowmini Varadhan { "IPACKETS", 10, LINK_S_IPKTS, print_link_stats_cb}, 5418002d411SSowmini Varadhan { "RBYTES", 8, LINK_S_RBYTES, print_link_stats_cb}, 5428002d411SSowmini Varadhan { "IERRORS", 10, LINK_S_IERRORS, print_link_stats_cb}, 5438002d411SSowmini Varadhan { "OPACKETS", 12, LINK_S_OPKTS, print_link_stats_cb}, 5448002d411SSowmini Varadhan { "OBYTES", 12, LINK_S_OBYTES, print_link_stats_cb}, 5458002d411SSowmini Varadhan { "OERRORS", 8, LINK_S_OERRORS, print_link_stats_cb}} 546e7801d59Ssowmini ; 547ae6aa22aSVenugopal Iyer 548ae6aa22aSVenugopal Iyer typedef struct link_args_s { 549ae6aa22aSVenugopal Iyer char *link_s_link; 550ae6aa22aSVenugopal Iyer pktsum_t *link_s_psum; 551ae6aa22aSVenugopal Iyer } link_args_t; 552e7801d59Ssowmini 553e7801d59Ssowmini /* 554e7801d59Ssowmini * buffer used by print functions for show-{link,phys,vlan} commands. 555e7801d59Ssowmini */ 556e7801d59Ssowmini typedef struct link_fields_buf_s { 557e7801d59Ssowmini char link_name[MAXLINKNAMELEN]; 558e7801d59Ssowmini char link_class[DLADM_STRSIZE]; 559c08e5e1aSdr146992 char link_mtu[11]; 560e7801d59Ssowmini char link_state[DLADM_STRSIZE]; 561*4eaa4710SRishi Srivatsavai char link_bridge[MAXLINKNAMELEN]; 562e7801d59Ssowmini char link_over[MAXLINKNAMELEN]; 5634045d941Ssowmini char link_phys_state[DLADM_STRSIZE]; 564e7801d59Ssowmini char link_phys_media[DLADM_STRSIZE]; 565e7801d59Ssowmini char link_phys_speed[DLADM_STRSIZE]; 566e7801d59Ssowmini char link_phys_duplex[DLPI_LINKNAME_MAX]; 567e7801d59Ssowmini char link_phys_device[DLPI_LINKNAME_MAX]; 568e7801d59Ssowmini char link_flags[6]; 569e7801d59Ssowmini char link_vlan_vid[6]; 570e7801d59Ssowmini } link_fields_buf_t; 571e7801d59Ssowmini 572e7801d59Ssowmini /* 573e7801d59Ssowmini * structures for 'dladm show-link' 574e7801d59Ssowmini */ 5758002d411SSowmini Varadhan static ofmt_field_t link_fields[] = { 5768002d411SSowmini Varadhan /* name, field width, index, callback */ 5778002d411SSowmini Varadhan { "LINK", 12, 5788002d411SSowmini Varadhan offsetof(link_fields_buf_t, link_name), print_default_cb}, 5794fd5d067Smeem { "CLASS", 10, 5808002d411SSowmini Varadhan offsetof(link_fields_buf_t, link_class), print_default_cb}, 5818002d411SSowmini Varadhan { "MTU", 7, 5828002d411SSowmini Varadhan offsetof(link_fields_buf_t, link_mtu), print_default_cb}, 5838002d411SSowmini Varadhan { "STATE", 9, 5848002d411SSowmini Varadhan offsetof(link_fields_buf_t, link_state), print_default_cb}, 585*4eaa4710SRishi Srivatsavai { "BRIDGE", 11, 586*4eaa4710SRishi Srivatsavai offsetof(link_fields_buf_t, link_bridge), print_default_cb}, 5878002d411SSowmini Varadhan { "OVER", DLPI_LINKNAME_MAX, 5888002d411SSowmini Varadhan offsetof(link_fields_buf_t, link_over), print_default_cb}, 5898002d411SSowmini Varadhan { NULL, 0, 0, NULL}} 590e7801d59Ssowmini ; 591e7801d59Ssowmini 592e7801d59Ssowmini /* 593e7801d59Ssowmini * structures for 'dladm show-aggr' 594e7801d59Ssowmini */ 595e7801d59Ssowmini typedef struct laggr_fields_buf_s { 596e7801d59Ssowmini char laggr_name[DLPI_LINKNAME_MAX]; 597e7801d59Ssowmini char laggr_policy[9]; 598e7801d59Ssowmini char laggr_addrpolicy[ETHERADDRL * 3 + 3]; 599e7801d59Ssowmini char laggr_lacpactivity[14]; 600e7801d59Ssowmini char laggr_lacptimer[DLADM_STRSIZE]; 601e7801d59Ssowmini char laggr_flags[7]; 602e7801d59Ssowmini } laggr_fields_buf_t; 603e7801d59Ssowmini 604e7801d59Ssowmini typedef struct laggr_args_s { 605e7801d59Ssowmini int laggr_lport; /* -1 indicates the aggr itself */ 606e7801d59Ssowmini const char *laggr_link; 607e7801d59Ssowmini dladm_aggr_grp_attr_t *laggr_ginfop; 608e7801d59Ssowmini dladm_status_t *laggr_status; 609e7801d59Ssowmini pktsum_t *laggr_pktsumtot; /* -s only */ 6102d40c3b2SPrakash Jalan pktsum_t *laggr_diffstats; /* -s only */ 6118002d411SSowmini Varadhan boolean_t laggr_parsable; 612e7801d59Ssowmini } laggr_args_t; 613e7801d59Ssowmini 6148002d411SSowmini Varadhan static ofmt_field_t laggr_fields[] = { 6158002d411SSowmini Varadhan /* name, field width, offset, callback */ 6168002d411SSowmini Varadhan { "LINK", 16, 6178002d411SSowmini Varadhan offsetof(laggr_fields_buf_t, laggr_name), print_default_cb}, 6188002d411SSowmini Varadhan { "POLICY", 9, 6198002d411SSowmini Varadhan offsetof(laggr_fields_buf_t, laggr_policy), print_default_cb}, 6208002d411SSowmini Varadhan { "ADDRPOLICY", ETHERADDRL * 3 + 3, 6218002d411SSowmini Varadhan offsetof(laggr_fields_buf_t, laggr_addrpolicy), print_default_cb}, 6228002d411SSowmini Varadhan { "LACPACTIVITY", 14, 6238002d411SSowmini Varadhan offsetof(laggr_fields_buf_t, laggr_lacpactivity), print_default_cb}, 6248002d411SSowmini Varadhan { "LACPTIMER", 12, 6258002d411SSowmini Varadhan offsetof(laggr_fields_buf_t, laggr_lacptimer), print_default_cb}, 6268002d411SSowmini Varadhan { "FLAGS", 8, 6278002d411SSowmini Varadhan offsetof(laggr_fields_buf_t, laggr_flags), print_default_cb}, 6288002d411SSowmini Varadhan { NULL, 0, 0, NULL}} 629e7801d59Ssowmini ; 630e7801d59Ssowmini 631e7801d59Ssowmini /* 632e7801d59Ssowmini * structures for 'dladm show-aggr -x'. 633e7801d59Ssowmini */ 634e7801d59Ssowmini typedef enum { 635e7801d59Ssowmini AGGR_X_LINK, 636e7801d59Ssowmini AGGR_X_PORT, 637e7801d59Ssowmini AGGR_X_SPEED, 638e7801d59Ssowmini AGGR_X_DUPLEX, 639e7801d59Ssowmini AGGR_X_STATE, 640e7801d59Ssowmini AGGR_X_ADDRESS, 641e7801d59Ssowmini AGGR_X_PORTSTATE 642e7801d59Ssowmini } aggr_x_field_index_t; 643e7801d59Ssowmini 6448002d411SSowmini Varadhan static ofmt_field_t aggr_x_fields[] = { 6458002d411SSowmini Varadhan /* name, field width, index callback */ 6468002d411SSowmini Varadhan { "LINK", 12, AGGR_X_LINK, print_xaggr_cb}, 6478002d411SSowmini Varadhan { "PORT", 15, AGGR_X_PORT, print_xaggr_cb}, 6488002d411SSowmini Varadhan { "SPEED", 5, AGGR_X_SPEED, print_xaggr_cb}, 6498002d411SSowmini Varadhan { "DUPLEX", 10, AGGR_X_DUPLEX, print_xaggr_cb}, 6508002d411SSowmini Varadhan { "STATE", 10, AGGR_X_STATE, print_xaggr_cb}, 6518002d411SSowmini Varadhan { "ADDRESS", 19, AGGR_X_ADDRESS, print_xaggr_cb}, 6528002d411SSowmini Varadhan { "PORTSTATE", 16, AGGR_X_PORTSTATE, print_xaggr_cb}, 6538002d411SSowmini Varadhan { NULL, 0, 0, NULL}} 654e7801d59Ssowmini ; 655e7801d59Ssowmini 656e7801d59Ssowmini /* 657e7801d59Ssowmini * structures for 'dladm show-aggr -s'. 658e7801d59Ssowmini */ 659e7801d59Ssowmini typedef enum { 660e7801d59Ssowmini AGGR_S_LINK, 661e7801d59Ssowmini AGGR_S_PORT, 662e7801d59Ssowmini AGGR_S_IPKTS, 663e7801d59Ssowmini AGGR_S_RBYTES, 664e7801d59Ssowmini AGGR_S_OPKTS, 665e7801d59Ssowmini AGGR_S_OBYTES, 666e7801d59Ssowmini AGGR_S_IPKTDIST, 667e7801d59Ssowmini AGGR_S_OPKTDIST 668e7801d59Ssowmini } aggr_s_field_index_t; 669e7801d59Ssowmini 6708002d411SSowmini Varadhan static ofmt_field_t aggr_s_fields[] = { 6718002d411SSowmini Varadhan { "LINK", 12, AGGR_S_LINK, print_aggr_stats_cb}, 6728002d411SSowmini Varadhan { "PORT", 10, AGGR_S_PORT, print_aggr_stats_cb}, 6738002d411SSowmini Varadhan { "IPACKETS", 8, AGGR_S_IPKTS, print_aggr_stats_cb}, 6748002d411SSowmini Varadhan { "RBYTES", 8, AGGR_S_RBYTES, print_aggr_stats_cb}, 6758002d411SSowmini Varadhan { "OPACKETS", 8, AGGR_S_OPKTS, print_aggr_stats_cb}, 6768002d411SSowmini Varadhan { "OBYTES", 8, AGGR_S_OBYTES, print_aggr_stats_cb}, 6778002d411SSowmini Varadhan { "IPKTDIST", 9, AGGR_S_IPKTDIST, print_aggr_stats_cb}, 6788002d411SSowmini Varadhan { "OPKTDIST", 15, AGGR_S_OPKTDIST, print_aggr_stats_cb}, 6798002d411SSowmini Varadhan { NULL, 0, 0, NULL}} 680e7801d59Ssowmini ; 681e7801d59Ssowmini 682e7801d59Ssowmini /* 683da14cebeSEric Cheng * structures for 'dladm show-aggr -L'. 684e7801d59Ssowmini */ 685e7801d59Ssowmini typedef enum { 686e7801d59Ssowmini AGGR_L_LINK, 687e7801d59Ssowmini AGGR_L_PORT, 688e7801d59Ssowmini AGGR_L_AGGREGATABLE, 689e7801d59Ssowmini AGGR_L_SYNC, 690e7801d59Ssowmini AGGR_L_COLL, 691e7801d59Ssowmini AGGR_L_DIST, 692e7801d59Ssowmini AGGR_L_DEFAULTED, 693e7801d59Ssowmini AGGR_L_EXPIRED 694e7801d59Ssowmini } aggr_l_field_index_t; 695e7801d59Ssowmini 6968002d411SSowmini Varadhan static ofmt_field_t aggr_l_fields[] = { 6978002d411SSowmini Varadhan /* name, field width, index */ 6988002d411SSowmini Varadhan { "LINK", 12, AGGR_L_LINK, print_lacp_cb}, 6998002d411SSowmini Varadhan { "PORT", 13, AGGR_L_PORT, print_lacp_cb}, 7008002d411SSowmini Varadhan { "AGGREGATABLE", 13, AGGR_L_AGGREGATABLE, print_lacp_cb}, 7018002d411SSowmini Varadhan { "SYNC", 5, AGGR_L_SYNC, print_lacp_cb}, 7028002d411SSowmini Varadhan { "COLL", 5, AGGR_L_COLL, print_lacp_cb}, 7038002d411SSowmini Varadhan { "DIST", 5, AGGR_L_DIST, print_lacp_cb}, 7048002d411SSowmini Varadhan { "DEFAULTED", 10, AGGR_L_DEFAULTED, print_lacp_cb}, 7058002d411SSowmini Varadhan { "EXPIRED", 15, AGGR_L_EXPIRED, print_lacp_cb}, 7068002d411SSowmini Varadhan { NULL, 0, 0, NULL}} 707e7801d59Ssowmini ; 708e7801d59Ssowmini 709e7801d59Ssowmini /* 710e7801d59Ssowmini * structures for 'dladm show-phys' 711e7801d59Ssowmini */ 712e7801d59Ssowmini 7138002d411SSowmini Varadhan static ofmt_field_t phys_fields[] = { 7148002d411SSowmini Varadhan /* name, field width, offset */ 7158002d411SSowmini Varadhan { "LINK", 13, 7168002d411SSowmini Varadhan offsetof(link_fields_buf_t, link_name), print_default_cb}, 7178002d411SSowmini Varadhan { "MEDIA", 21, 7188002d411SSowmini Varadhan offsetof(link_fields_buf_t, link_phys_media), print_default_cb}, 7198002d411SSowmini Varadhan { "STATE", 11, 7208002d411SSowmini Varadhan offsetof(link_fields_buf_t, link_phys_state), print_default_cb}, 7218002d411SSowmini Varadhan { "SPEED", 7, 7228002d411SSowmini Varadhan offsetof(link_fields_buf_t, link_phys_speed), print_default_cb}, 7238002d411SSowmini Varadhan { "DUPLEX", 10, 7248002d411SSowmini Varadhan offsetof(link_fields_buf_t, link_phys_duplex), print_default_cb}, 7258002d411SSowmini Varadhan { "DEVICE", 13, 7268002d411SSowmini Varadhan offsetof(link_fields_buf_t, link_phys_device), print_default_cb}, 7278002d411SSowmini Varadhan { "FLAGS", 7, 7288002d411SSowmini Varadhan offsetof(link_fields_buf_t, link_flags), print_default_cb}, 7298002d411SSowmini Varadhan { NULL, 0, NULL, 0}} 730e7801d59Ssowmini ; 731e7801d59Ssowmini 732e7801d59Ssowmini /* 733da14cebeSEric Cheng * structures for 'dladm show-phys -m' 734da14cebeSEric Cheng */ 735da14cebeSEric Cheng 736da14cebeSEric Cheng typedef enum { 737da14cebeSEric Cheng PHYS_M_LINK, 738da14cebeSEric Cheng PHYS_M_SLOT, 739da14cebeSEric Cheng PHYS_M_ADDRESS, 740da14cebeSEric Cheng PHYS_M_INUSE, 741da14cebeSEric Cheng PHYS_M_CLIENT 742da14cebeSEric Cheng } phys_m_field_index_t; 743da14cebeSEric Cheng 7448002d411SSowmini Varadhan static ofmt_field_t phys_m_fields[] = { 7458002d411SSowmini Varadhan /* name, field width, offset */ 7468002d411SSowmini Varadhan { "LINK", 13, PHYS_M_LINK, print_phys_one_mac_cb}, 7478002d411SSowmini Varadhan { "SLOT", 9, PHYS_M_SLOT, print_phys_one_mac_cb}, 7488002d411SSowmini Varadhan { "ADDRESS", 19, PHYS_M_ADDRESS, print_phys_one_mac_cb}, 7498002d411SSowmini Varadhan { "INUSE", 5, PHYS_M_INUSE, print_phys_one_mac_cb}, 7508002d411SSowmini Varadhan { "CLIENT", 13, PHYS_M_CLIENT, print_phys_one_mac_cb}, 7518002d411SSowmini Varadhan { NULL, 0, 0, NULL}} 752da14cebeSEric Cheng ; 753da14cebeSEric Cheng 754da14cebeSEric Cheng /* 755da14cebeSEric Cheng * structures for 'dladm show-phys -H' 756da14cebeSEric Cheng */ 757da14cebeSEric Cheng 758da14cebeSEric Cheng typedef enum { 759da14cebeSEric Cheng PHYS_H_LINK, 760da14cebeSEric Cheng PHYS_H_GROUP, 761da14cebeSEric Cheng PHYS_H_GRPTYPE, 762da14cebeSEric Cheng PHYS_H_RINGS, 763da14cebeSEric Cheng PHYS_H_CLIENTS 764da14cebeSEric Cheng } phys_h_field_index_t; 765da14cebeSEric Cheng 7668002d411SSowmini Varadhan static ofmt_field_t phys_h_fields[] = { 7678002d411SSowmini Varadhan { "LINK", 13, PHYS_H_LINK, print_phys_one_hwgrp_cb}, 7688002d411SSowmini Varadhan { "GROUP", 9, PHYS_H_GROUP, print_phys_one_hwgrp_cb}, 7698002d411SSowmini Varadhan { "GROUPTYPE", 7, PHYS_H_GRPTYPE, print_phys_one_hwgrp_cb}, 7708002d411SSowmini Varadhan { "RINGS", 17, PHYS_H_RINGS, print_phys_one_hwgrp_cb}, 7718002d411SSowmini Varadhan { "CLIENTS", 21, PHYS_H_CLIENTS, print_phys_one_hwgrp_cb}, 7728002d411SSowmini Varadhan { NULL, 0, 0, NULL}} 773da14cebeSEric Cheng ; 774da14cebeSEric Cheng 775da14cebeSEric Cheng /* 776e7801d59Ssowmini * structures for 'dladm show-vlan' 777e7801d59Ssowmini */ 7788002d411SSowmini Varadhan static ofmt_field_t vlan_fields[] = { 7798002d411SSowmini Varadhan { "LINK", 16, 7808002d411SSowmini Varadhan offsetof(link_fields_buf_t, link_name), print_default_cb}, 7818002d411SSowmini Varadhan { "VID", 9, 7828002d411SSowmini Varadhan offsetof(link_fields_buf_t, link_vlan_vid), print_default_cb}, 7838002d411SSowmini Varadhan { "OVER", 13, 7848002d411SSowmini Varadhan offsetof(link_fields_buf_t, link_over), print_default_cb}, 7858002d411SSowmini Varadhan { "FLAGS", 7, 7868002d411SSowmini Varadhan offsetof(link_fields_buf_t, link_flags), print_default_cb}, 7878002d411SSowmini Varadhan { NULL, 0, 0, NULL}} 788e7801d59Ssowmini ; 789da14cebeSEric Cheng 790e7801d59Ssowmini /* 7918002d411SSowmini Varadhan * structures common to 'dladm scan-wifi' and 'dladm show-wifi' 7928002d411SSowmini Varadhan * callback will be determined in parse_wifi_fields. 793e7801d59Ssowmini */ 7948002d411SSowmini Varadhan static ofmt_field_t wifi_common_fields[] = { 7958002d411SSowmini Varadhan { "LINK", 11, 0, NULL}, 7968002d411SSowmini Varadhan { "ESSID", 20, DLADM_WLAN_ATTR_ESSID, NULL}, 7978002d411SSowmini Varadhan { "BSSID", 18, DLADM_WLAN_ATTR_BSSID, NULL}, 7988002d411SSowmini Varadhan { "IBSSID", 18, DLADM_WLAN_ATTR_BSSID, NULL}, 7998002d411SSowmini Varadhan { "MODE", 7, DLADM_WLAN_ATTR_MODE, NULL}, 8008002d411SSowmini Varadhan { "SPEED", 7, DLADM_WLAN_ATTR_SPEED, NULL}, 8018002d411SSowmini Varadhan { "BSSTYPE", 9, DLADM_WLAN_ATTR_BSSTYPE, NULL}, 8028002d411SSowmini Varadhan { "SEC", 7, DLADM_WLAN_ATTR_SECMODE, NULL}, 8038002d411SSowmini Varadhan { "STRENGTH", 11, DLADM_WLAN_ATTR_STRENGTH, NULL}, 8048002d411SSowmini Varadhan { NULL, 0, 0, NULL}}; 8058002d411SSowmini Varadhan 8068002d411SSowmini Varadhan /* 8078002d411SSowmini Varadhan * the 'show-wifi' command supports all the fields in wifi_common_fields 8088002d411SSowmini Varadhan * plus the AUTH and STATUS fields. 8098002d411SSowmini Varadhan */ 8108002d411SSowmini Varadhan static ofmt_field_t wifi_show_fields[A_CNT(wifi_common_fields) + 2] = { 8118002d411SSowmini Varadhan { "AUTH", 9, DLADM_WLAN_ATTR_AUTH, NULL}, 8128002d411SSowmini Varadhan { "STATUS", 18, DLADM_WLAN_LINKATTR_STATUS, print_wifi_status_cb}, 8138002d411SSowmini Varadhan /* copy wifi_common_fields here */ 8148002d411SSowmini Varadhan }; 815e7801d59Ssowmini 816e7801d59Ssowmini static char *all_scan_wifi_fields = 817e7801d59Ssowmini "link,essid,bssid,sec,strength,mode,speed,bsstype"; 818e7801d59Ssowmini static char *all_show_wifi_fields = 819e7801d59Ssowmini "link,status,essid,sec,strength,mode,speed,auth,bssid,bsstype"; 820e7801d59Ssowmini static char *def_scan_wifi_fields = 821e7801d59Ssowmini "link,essid,bssid,sec,strength,mode,speed"; 822e7801d59Ssowmini static char *def_show_wifi_fields = 823e7801d59Ssowmini "link,status,essid,sec,strength,mode,speed"; 824e7801d59Ssowmini 825e7801d59Ssowmini /* 826e7801d59Ssowmini * structures for 'dladm show-linkprop' 827e7801d59Ssowmini */ 828e7801d59Ssowmini typedef enum { 829e7801d59Ssowmini LINKPROP_LINK, 830e7801d59Ssowmini LINKPROP_PROPERTY, 831afdda45fSVasumathi Sundaram - Sun Microsystems LINKPROP_PERM, 832e7801d59Ssowmini LINKPROP_VALUE, 833e7801d59Ssowmini LINKPROP_DEFAULT, 834e7801d59Ssowmini LINKPROP_POSSIBLE 835e7801d59Ssowmini } linkprop_field_index_t; 836e7801d59Ssowmini 8378002d411SSowmini Varadhan static ofmt_field_t linkprop_fields[] = { 8388002d411SSowmini Varadhan /* name, field width, index */ 8398002d411SSowmini Varadhan { "LINK", 13, LINKPROP_LINK, print_linkprop_cb}, 8408002d411SSowmini Varadhan { "PROPERTY", 16, LINKPROP_PROPERTY, print_linkprop_cb}, 8418002d411SSowmini Varadhan { "PERM", 5, LINKPROP_PERM, print_linkprop_cb}, 8428002d411SSowmini Varadhan { "VALUE", 15, LINKPROP_VALUE, print_linkprop_cb}, 8438002d411SSowmini Varadhan { "DEFAULT", 15, LINKPROP_DEFAULT, print_linkprop_cb}, 8448002d411SSowmini Varadhan { "POSSIBLE", 21, LINKPROP_POSSIBLE, print_linkprop_cb}, 8458002d411SSowmini Varadhan { NULL, 0, 0, NULL}} 846e7801d59Ssowmini ; 847e7801d59Ssowmini 848e7801d59Ssowmini #define MAX_PROP_LINE 512 849e7801d59Ssowmini 850e7801d59Ssowmini typedef struct show_linkprop_state { 851e7801d59Ssowmini char ls_link[MAXLINKNAMELEN]; 852e7801d59Ssowmini char *ls_line; 853e7801d59Ssowmini char **ls_propvals; 854da14cebeSEric Cheng dladm_arg_list_t *ls_proplist; 8558002d411SSowmini Varadhan boolean_t ls_parsable; 856e7801d59Ssowmini boolean_t ls_persist; 857e7801d59Ssowmini boolean_t ls_header; 858e7801d59Ssowmini dladm_status_t ls_status; 859e7801d59Ssowmini dladm_status_t ls_retstatus; 8608002d411SSowmini Varadhan ofmt_handle_t ls_ofmt; 861e7801d59Ssowmini } show_linkprop_state_t; 862e7801d59Ssowmini 863da14cebeSEric Cheng typedef struct set_linkprop_state { 864da14cebeSEric Cheng const char *ls_name; 865da14cebeSEric Cheng boolean_t ls_reset; 866da14cebeSEric Cheng boolean_t ls_temp; 867da14cebeSEric Cheng dladm_status_t ls_status; 868da14cebeSEric Cheng } set_linkprop_state_t; 869da14cebeSEric Cheng 870e7801d59Ssowmini typedef struct linkprop_args_s { 871e7801d59Ssowmini show_linkprop_state_t *ls_state; 872e7801d59Ssowmini char *ls_propname; 873e7801d59Ssowmini datalink_id_t ls_linkid; 874e7801d59Ssowmini } linkprop_args_t; 875e7801d59Ssowmini 876e7801d59Ssowmini /* 877e7801d59Ssowmini * structures for 'dladm show-secobj' 878e7801d59Ssowmini */ 879e7801d59Ssowmini typedef struct secobj_fields_buf_s { 880e7801d59Ssowmini char ss_obj_name[DLADM_SECOBJ_VAL_MAX]; 881e7801d59Ssowmini char ss_class[20]; 882e7801d59Ssowmini char ss_val[30]; 883e7801d59Ssowmini } secobj_fields_buf_t; 8848002d411SSowmini Varadhan 8858002d411SSowmini Varadhan static ofmt_field_t secobj_fields[] = { 8868002d411SSowmini Varadhan { "OBJECT", 21, 8878002d411SSowmini Varadhan offsetof(secobj_fields_buf_t, ss_obj_name), print_default_cb}, 8888002d411SSowmini Varadhan { "CLASS", 21, 8898002d411SSowmini Varadhan offsetof(secobj_fields_buf_t, ss_class), print_default_cb}, 8908002d411SSowmini Varadhan { "VALUE", 31, 8918002d411SSowmini Varadhan offsetof(secobj_fields_buf_t, ss_val), print_default_cb}, 8928002d411SSowmini Varadhan { NULL, 0, 0, NULL}} 893e7801d59Ssowmini ; 8940ba2cbe9Sxc151355 895da14cebeSEric Cheng /* 896da14cebeSEric Cheng * structures for 'dladm show-vnic' 897da14cebeSEric Cheng */ 898da14cebeSEric Cheng typedef struct vnic_fields_buf_s 899da14cebeSEric Cheng { 900da14cebeSEric Cheng char vnic_link[DLPI_LINKNAME_MAX]; 901da14cebeSEric Cheng char vnic_over[DLPI_LINKNAME_MAX]; 902da14cebeSEric Cheng char vnic_speed[6]; 903b509e89bSRishi Srivatsavai char vnic_macaddr[18]; 904da14cebeSEric Cheng char vnic_macaddrtype[19]; 905da14cebeSEric Cheng char vnic_vid[6]; 906da14cebeSEric Cheng } vnic_fields_buf_t; 907da14cebeSEric Cheng 9088002d411SSowmini Varadhan static ofmt_field_t vnic_fields[] = { 9098002d411SSowmini Varadhan { "LINK", 13, 9108002d411SSowmini Varadhan offsetof(vnic_fields_buf_t, vnic_link), print_default_cb}, 9118002d411SSowmini Varadhan { "OVER", 13, 9128002d411SSowmini Varadhan offsetof(vnic_fields_buf_t, vnic_over), print_default_cb}, 9138002d411SSowmini Varadhan { "SPEED", 7, 9148002d411SSowmini Varadhan offsetof(vnic_fields_buf_t, vnic_speed), print_default_cb}, 915b509e89bSRishi Srivatsavai { "MACADDRESS", 18, 9168002d411SSowmini Varadhan offsetof(vnic_fields_buf_t, vnic_macaddr), print_default_cb}, 9178002d411SSowmini Varadhan { "MACADDRTYPE", 20, 9188002d411SSowmini Varadhan offsetof(vnic_fields_buf_t, vnic_macaddrtype), print_default_cb}, 9198002d411SSowmini Varadhan { "VID", 7, 9208002d411SSowmini Varadhan offsetof(vnic_fields_buf_t, vnic_vid), print_default_cb}, 9218002d411SSowmini Varadhan { NULL, 0, 0, NULL}} 922da14cebeSEric Cheng ; 923da14cebeSEric Cheng 924da14cebeSEric Cheng /* 925b509e89bSRishi Srivatsavai * structures for 'dladm show-simnet' 926b509e89bSRishi Srivatsavai */ 927b509e89bSRishi Srivatsavai typedef struct simnet_fields_buf_s 928b509e89bSRishi Srivatsavai { 929b509e89bSRishi Srivatsavai char simnet_name[DLPI_LINKNAME_MAX]; 930b509e89bSRishi Srivatsavai char simnet_media[DLADM_STRSIZE]; 931b509e89bSRishi Srivatsavai char simnet_macaddr[18]; 932b509e89bSRishi Srivatsavai char simnet_otherlink[DLPI_LINKNAME_MAX]; 933b509e89bSRishi Srivatsavai } simnet_fields_buf_t; 934b509e89bSRishi Srivatsavai 935b509e89bSRishi Srivatsavai static ofmt_field_t simnet_fields[] = { 936b509e89bSRishi Srivatsavai { "LINK", 12, 937b509e89bSRishi Srivatsavai offsetof(simnet_fields_buf_t, simnet_name), print_default_cb}, 938b509e89bSRishi Srivatsavai { "MEDIA", 20, 939b509e89bSRishi Srivatsavai offsetof(simnet_fields_buf_t, simnet_media), print_default_cb}, 940b509e89bSRishi Srivatsavai { "MACADDRESS", 18, 941b509e89bSRishi Srivatsavai offsetof(simnet_fields_buf_t, simnet_macaddr), print_default_cb}, 942b509e89bSRishi Srivatsavai { "OTHERLINK", 12, 943b509e89bSRishi Srivatsavai offsetof(simnet_fields_buf_t, simnet_otherlink), print_default_cb}, 944b509e89bSRishi Srivatsavai { NULL, 0, 0, NULL}} 945b509e89bSRishi Srivatsavai ; 946b509e89bSRishi Srivatsavai 947b509e89bSRishi Srivatsavai /* 948da14cebeSEric Cheng * structures for 'dladm show-usage' 949da14cebeSEric Cheng */ 950da14cebeSEric Cheng 951da14cebeSEric Cheng typedef struct usage_fields_buf_s { 952da14cebeSEric Cheng char usage_link[12]; 953da14cebeSEric Cheng char usage_duration[10]; 954da14cebeSEric Cheng char usage_ipackets[9]; 955da14cebeSEric Cheng char usage_rbytes[10]; 956da14cebeSEric Cheng char usage_opackets[9]; 957da14cebeSEric Cheng char usage_obytes[10]; 958da14cebeSEric Cheng char usage_bandwidth[14]; 959da14cebeSEric Cheng } usage_fields_buf_t; 960da14cebeSEric Cheng 9618002d411SSowmini Varadhan static ofmt_field_t usage_fields[] = { 9628002d411SSowmini Varadhan { "LINK", 13, 9638002d411SSowmini Varadhan offsetof(usage_fields_buf_t, usage_link), print_default_cb}, 9648002d411SSowmini Varadhan { "DURATION", 11, 9658002d411SSowmini Varadhan offsetof(usage_fields_buf_t, usage_duration), print_default_cb}, 9668002d411SSowmini Varadhan { "IPACKETS", 10, 9678002d411SSowmini Varadhan offsetof(usage_fields_buf_t, usage_ipackets), print_default_cb}, 9688002d411SSowmini Varadhan { "RBYTES", 11, 9698002d411SSowmini Varadhan offsetof(usage_fields_buf_t, usage_rbytes), print_default_cb}, 9708002d411SSowmini Varadhan { "OPACKETS", 10, 9718002d411SSowmini Varadhan offsetof(usage_fields_buf_t, usage_opackets), print_default_cb}, 9728002d411SSowmini Varadhan { "OBYTES", 11, 9738002d411SSowmini Varadhan offsetof(usage_fields_buf_t, usage_obytes), print_default_cb}, 9748002d411SSowmini Varadhan { "BANDWIDTH", 15, 9758002d411SSowmini Varadhan offsetof(usage_fields_buf_t, usage_bandwidth), print_default_cb}, 9768002d411SSowmini Varadhan { NULL, 0, 0, NULL}} 977da14cebeSEric Cheng ; 978da14cebeSEric Cheng 979da14cebeSEric Cheng 980da14cebeSEric Cheng /* 981da14cebeSEric Cheng * structures for 'dladm show-usage link' 982da14cebeSEric Cheng */ 983da14cebeSEric Cheng 984da14cebeSEric Cheng typedef struct usage_l_fields_buf_s { 985da14cebeSEric Cheng char usage_l_link[12]; 986da14cebeSEric Cheng char usage_l_stime[13]; 987da14cebeSEric Cheng char usage_l_etime[13]; 988da14cebeSEric Cheng char usage_l_rbytes[8]; 989da14cebeSEric Cheng char usage_l_obytes[8]; 990da14cebeSEric Cheng char usage_l_bandwidth[14]; 991da14cebeSEric Cheng } usage_l_fields_buf_t; 992da14cebeSEric Cheng 9938002d411SSowmini Varadhan static ofmt_field_t usage_l_fields[] = { 9948002d411SSowmini Varadhan /* name, field width, offset */ 9958002d411SSowmini Varadhan { "LINK", 13, 9968002d411SSowmini Varadhan offsetof(usage_l_fields_buf_t, usage_l_link), print_default_cb}, 9978002d411SSowmini Varadhan { "START", 14, 9988002d411SSowmini Varadhan offsetof(usage_l_fields_buf_t, usage_l_stime), print_default_cb}, 9998002d411SSowmini Varadhan { "END", 14, 10008002d411SSowmini Varadhan offsetof(usage_l_fields_buf_t, usage_l_etime), print_default_cb}, 10018002d411SSowmini Varadhan { "RBYTES", 9, 10028002d411SSowmini Varadhan offsetof(usage_l_fields_buf_t, usage_l_rbytes), print_default_cb}, 10038002d411SSowmini Varadhan { "OBYTES", 9, 10048002d411SSowmini Varadhan offsetof(usage_l_fields_buf_t, usage_l_obytes), print_default_cb}, 10058002d411SSowmini Varadhan { "BANDWIDTH", 15, 10068002d411SSowmini Varadhan offsetof(usage_l_fields_buf_t, usage_l_bandwidth), print_default_cb}, 10078002d411SSowmini Varadhan { NULL, 0, 0, NULL}} 1008da14cebeSEric Cheng ; 1009da14cebeSEric Cheng 1010*4eaa4710SRishi Srivatsavai /* 1011*4eaa4710SRishi Srivatsavai * structures for 'dladm show-bridge'. These are based on sections 14.8.1.1.3 1012*4eaa4710SRishi Srivatsavai * and 14.8.1.2.2 of IEEE 802.1D-2004. 1013*4eaa4710SRishi Srivatsavai */ 1014*4eaa4710SRishi Srivatsavai typedef struct bridge_fields_buf_s { 1015*4eaa4710SRishi Srivatsavai char bridge_name[MAXLINKNAMELEN]; /* 14.4.1.2.3(b) */ 1016*4eaa4710SRishi Srivatsavai char bridge_protect[7]; /* stp or trill */ 1017*4eaa4710SRishi Srivatsavai char bridge_address[24]; /* 17.18.3, 7.12.5, 14.4.1.2.3(a) */ 1018*4eaa4710SRishi Srivatsavai char bridge_priority[7]; /* 17.18.3 9.2.5 - only upper 4 bits */ 1019*4eaa4710SRishi Srivatsavai char bridge_bmaxage[7]; /* 17.18.4 configured */ 1020*4eaa4710SRishi Srivatsavai char bridge_bhellotime[7]; /* 17.18.4 configured */ 1021*4eaa4710SRishi Srivatsavai char bridge_bfwddelay[7]; /* 17.18.4 configured */ 1022*4eaa4710SRishi Srivatsavai char bridge_forceproto[3]; /* 17.13.4 configured */ 1023*4eaa4710SRishi Srivatsavai char bridge_tctime[12]; /* 14.8.1.1.3(b) */ 1024*4eaa4710SRishi Srivatsavai char bridge_tccount[12]; /* 17.17.8 */ 1025*4eaa4710SRishi Srivatsavai char bridge_tchange[12]; /* 17.17.8 */ 1026*4eaa4710SRishi Srivatsavai char bridge_desroot[24]; /* 17.18.6 priority "/" MAC */ 1027*4eaa4710SRishi Srivatsavai char bridge_rootcost[12]; /* 17.18.6 */ 1028*4eaa4710SRishi Srivatsavai char bridge_rootport[12]; /* 17.18.6 */ 1029*4eaa4710SRishi Srivatsavai char bridge_maxage[7]; /* 17.18.7 for root */ 1030*4eaa4710SRishi Srivatsavai char bridge_hellotime[7]; /* 17.13.6 for root */ 1031*4eaa4710SRishi Srivatsavai char bridge_fwddelay[7]; /* 17.13.5 for root */ 1032*4eaa4710SRishi Srivatsavai char bridge_holdtime[12]; /* 17.13.12 for root */ 1033*4eaa4710SRishi Srivatsavai } bridge_fields_buf_t; 1034*4eaa4710SRishi Srivatsavai 1035*4eaa4710SRishi Srivatsavai static ofmt_field_t bridge_fields[] = { 1036*4eaa4710SRishi Srivatsavai /* name, field width, offset, callback */ 1037*4eaa4710SRishi Srivatsavai { "BRIDGE", 12, 1038*4eaa4710SRishi Srivatsavai offsetof(bridge_fields_buf_t, bridge_name), print_default_cb }, 1039*4eaa4710SRishi Srivatsavai { "PROTECT", 8, 1040*4eaa4710SRishi Srivatsavai offsetof(bridge_fields_buf_t, bridge_protect), print_default_cb }, 1041*4eaa4710SRishi Srivatsavai { "ADDRESS", 19, 1042*4eaa4710SRishi Srivatsavai offsetof(bridge_fields_buf_t, bridge_address), print_default_cb }, 1043*4eaa4710SRishi Srivatsavai { "PRIORITY", 9, 1044*4eaa4710SRishi Srivatsavai offsetof(bridge_fields_buf_t, bridge_priority), print_default_cb }, 1045*4eaa4710SRishi Srivatsavai { "BMAXAGE", 8, 1046*4eaa4710SRishi Srivatsavai offsetof(bridge_fields_buf_t, bridge_bmaxage), print_default_cb }, 1047*4eaa4710SRishi Srivatsavai { "BHELLOTIME", 11, 1048*4eaa4710SRishi Srivatsavai offsetof(bridge_fields_buf_t, bridge_bhellotime), print_default_cb }, 1049*4eaa4710SRishi Srivatsavai { "BFWDDELAY", 10, 1050*4eaa4710SRishi Srivatsavai offsetof(bridge_fields_buf_t, bridge_bfwddelay), print_default_cb }, 1051*4eaa4710SRishi Srivatsavai { "FORCEPROTO", 11, 1052*4eaa4710SRishi Srivatsavai offsetof(bridge_fields_buf_t, bridge_forceproto), print_default_cb }, 1053*4eaa4710SRishi Srivatsavai { "TCTIME", 10, 1054*4eaa4710SRishi Srivatsavai offsetof(bridge_fields_buf_t, bridge_tctime), print_default_cb }, 1055*4eaa4710SRishi Srivatsavai { "TCCOUNT", 10, 1056*4eaa4710SRishi Srivatsavai offsetof(bridge_fields_buf_t, bridge_tccount), print_default_cb }, 1057*4eaa4710SRishi Srivatsavai { "TCHANGE", 10, 1058*4eaa4710SRishi Srivatsavai offsetof(bridge_fields_buf_t, bridge_tchange), print_default_cb }, 1059*4eaa4710SRishi Srivatsavai { "DESROOT", 23, 1060*4eaa4710SRishi Srivatsavai offsetof(bridge_fields_buf_t, bridge_desroot), print_default_cb }, 1061*4eaa4710SRishi Srivatsavai { "ROOTCOST", 11, 1062*4eaa4710SRishi Srivatsavai offsetof(bridge_fields_buf_t, bridge_rootcost), print_default_cb }, 1063*4eaa4710SRishi Srivatsavai { "ROOTPORT", 11, 1064*4eaa4710SRishi Srivatsavai offsetof(bridge_fields_buf_t, bridge_rootport), print_default_cb }, 1065*4eaa4710SRishi Srivatsavai { "MAXAGE", 8, 1066*4eaa4710SRishi Srivatsavai offsetof(bridge_fields_buf_t, bridge_maxage), print_default_cb }, 1067*4eaa4710SRishi Srivatsavai { "HELLOTIME", 10, 1068*4eaa4710SRishi Srivatsavai offsetof(bridge_fields_buf_t, bridge_hellotime), print_default_cb }, 1069*4eaa4710SRishi Srivatsavai { "FWDDELAY", 9, 1070*4eaa4710SRishi Srivatsavai offsetof(bridge_fields_buf_t, bridge_fwddelay), print_default_cb }, 1071*4eaa4710SRishi Srivatsavai { "HOLDTIME", 9, 1072*4eaa4710SRishi Srivatsavai offsetof(bridge_fields_buf_t, bridge_holdtime), print_default_cb }, 1073*4eaa4710SRishi Srivatsavai { NULL, 0, 0, NULL}}; 1074*4eaa4710SRishi Srivatsavai 1075*4eaa4710SRishi Srivatsavai /* 1076*4eaa4710SRishi Srivatsavai * structures for 'dladm show-bridge -l'. These are based on 14.4.1.2.3 and 1077*4eaa4710SRishi Srivatsavai * 14.8.2.1.3 of IEEE 802.1D-2004. 1078*4eaa4710SRishi Srivatsavai */ 1079*4eaa4710SRishi Srivatsavai typedef struct bridge_link_fields_buf_s { 1080*4eaa4710SRishi Srivatsavai char bridgel_link[MAXLINKNAMELEN]; 1081*4eaa4710SRishi Srivatsavai char bridgel_index[7]; /* 14.4.1.2.3(d1) */ 1082*4eaa4710SRishi Srivatsavai char bridgel_state[11]; /* 14.8.2.1.3(b) */ 1083*4eaa4710SRishi Srivatsavai char bridgel_uptime[7]; /* 14.8.2.1.3(a) */ 1084*4eaa4710SRishi Srivatsavai char bridgel_opercost[7] /* 14.8.2.1.3(d) */; 1085*4eaa4710SRishi Srivatsavai char bridgel_operp2p[4]; /* 14.8.2.1.3(p) */ 1086*4eaa4710SRishi Srivatsavai char bridgel_operedge[4]; /* 14.8.2.1.3(k) */ 1087*4eaa4710SRishi Srivatsavai char bridgel_desroot[23]; /* 14.8.2.1.3(e) */ 1088*4eaa4710SRishi Srivatsavai char bridgel_descost[12]; /* 14.8.2.1.3(f) */ 1089*4eaa4710SRishi Srivatsavai char bridgel_desbridge[23]; /* 14.8.2.1.3(g) */ 1090*4eaa4710SRishi Srivatsavai char bridgel_desport[7]; /* 14.8.2.1.3(h) */ 1091*4eaa4710SRishi Srivatsavai char bridgel_tcack[4]; /* 14.8.2.1.3(i) */ 1092*4eaa4710SRishi Srivatsavai } bridge_link_fields_buf_t; 1093*4eaa4710SRishi Srivatsavai 1094*4eaa4710SRishi Srivatsavai static ofmt_field_t bridge_link_fields[] = { 1095*4eaa4710SRishi Srivatsavai /* name, field width, offset, callback */ 1096*4eaa4710SRishi Srivatsavai { "LINK", 12, 1097*4eaa4710SRishi Srivatsavai offsetof(bridge_link_fields_buf_t, bridgel_link), print_default_cb }, 1098*4eaa4710SRishi Srivatsavai { "INDEX", 8, 1099*4eaa4710SRishi Srivatsavai offsetof(bridge_link_fields_buf_t, bridgel_index), print_default_cb }, 1100*4eaa4710SRishi Srivatsavai { "STATE", 12, 1101*4eaa4710SRishi Srivatsavai offsetof(bridge_link_fields_buf_t, bridgel_state), print_default_cb }, 1102*4eaa4710SRishi Srivatsavai { "UPTIME", 8, 1103*4eaa4710SRishi Srivatsavai offsetof(bridge_link_fields_buf_t, bridgel_uptime), print_default_cb }, 1104*4eaa4710SRishi Srivatsavai { "OPERCOST", 9, 1105*4eaa4710SRishi Srivatsavai offsetof(bridge_link_fields_buf_t, bridgel_opercost), print_default_cb }, 1106*4eaa4710SRishi Srivatsavai { "OPERP2P", 8, 1107*4eaa4710SRishi Srivatsavai offsetof(bridge_link_fields_buf_t, bridgel_operp2p), print_default_cb }, 1108*4eaa4710SRishi Srivatsavai { "OPEREDGE", 9, 1109*4eaa4710SRishi Srivatsavai offsetof(bridge_link_fields_buf_t, bridgel_operedge), print_default_cb }, 1110*4eaa4710SRishi Srivatsavai { "DESROOT", 22, 1111*4eaa4710SRishi Srivatsavai offsetof(bridge_link_fields_buf_t, bridgel_desroot), print_default_cb }, 1112*4eaa4710SRishi Srivatsavai { "DESCOST", 11, 1113*4eaa4710SRishi Srivatsavai offsetof(bridge_link_fields_buf_t, bridgel_descost), print_default_cb }, 1114*4eaa4710SRishi Srivatsavai { "DESBRIDGE", 22, 1115*4eaa4710SRishi Srivatsavai offsetof(bridge_link_fields_buf_t, bridgel_desbridge), print_default_cb }, 1116*4eaa4710SRishi Srivatsavai { "DESPORT", 8, 1117*4eaa4710SRishi Srivatsavai offsetof(bridge_link_fields_buf_t, bridgel_desport), print_default_cb }, 1118*4eaa4710SRishi Srivatsavai { "TCACK", 6, 1119*4eaa4710SRishi Srivatsavai offsetof(bridge_link_fields_buf_t, bridgel_tcack), print_default_cb }, 1120*4eaa4710SRishi Srivatsavai { NULL, 0, 0, NULL}}; 1121*4eaa4710SRishi Srivatsavai 1122*4eaa4710SRishi Srivatsavai /* 1123*4eaa4710SRishi Srivatsavai * structures for 'dladm show-bridge -s'. These are not based on IEEE 1124*4eaa4710SRishi Srivatsavai * 802.1D-2004. 1125*4eaa4710SRishi Srivatsavai */ 1126*4eaa4710SRishi Srivatsavai #define ULONG_DIG (((sizeof (ulong_t) * NBBY) * 3 / 10) + 1) 1127*4eaa4710SRishi Srivatsavai #define UINT64_DIG (((sizeof (uint64_t) * NBBY) * 3 / 10) + 1) 1128*4eaa4710SRishi Srivatsavai typedef struct bridge_statfields_buf_s { 1129*4eaa4710SRishi Srivatsavai char bridges_name[MAXLINKNAMELEN]; 1130*4eaa4710SRishi Srivatsavai char bridges_drops[UINT64_DIG]; 1131*4eaa4710SRishi Srivatsavai char bridges_forwards[UINT64_DIG]; 1132*4eaa4710SRishi Srivatsavai char bridges_mbcast[UINT64_DIG]; 1133*4eaa4710SRishi Srivatsavai char bridges_unknown[UINT64_DIG]; 1134*4eaa4710SRishi Srivatsavai char bridges_recv[UINT64_DIG]; 1135*4eaa4710SRishi Srivatsavai char bridges_sent[UINT64_DIG]; 1136*4eaa4710SRishi Srivatsavai } bridge_statfields_buf_t; 1137*4eaa4710SRishi Srivatsavai 1138*4eaa4710SRishi Srivatsavai static ofmt_field_t bridge_statfields[] = { 1139*4eaa4710SRishi Srivatsavai /* name, field width, offset, callback */ 1140*4eaa4710SRishi Srivatsavai { "BRIDGE", 12, 1141*4eaa4710SRishi Srivatsavai offsetof(bridge_statfields_buf_t, bridges_name), print_default_cb }, 1142*4eaa4710SRishi Srivatsavai { "DROPS", 12, 1143*4eaa4710SRishi Srivatsavai offsetof(bridge_statfields_buf_t, bridges_drops), print_default_cb }, 1144*4eaa4710SRishi Srivatsavai { "FORWARDS", 12, 1145*4eaa4710SRishi Srivatsavai offsetof(bridge_statfields_buf_t, bridges_forwards), print_default_cb }, 1146*4eaa4710SRishi Srivatsavai { "MBCAST", 12, 1147*4eaa4710SRishi Srivatsavai offsetof(bridge_statfields_buf_t, bridges_mbcast), print_default_cb }, 1148*4eaa4710SRishi Srivatsavai { "UNKNOWN", 12, 1149*4eaa4710SRishi Srivatsavai offsetof(bridge_statfields_buf_t, bridges_unknown), print_default_cb }, 1150*4eaa4710SRishi Srivatsavai { "RECV", 12, 1151*4eaa4710SRishi Srivatsavai offsetof(bridge_statfields_buf_t, bridges_recv), print_default_cb }, 1152*4eaa4710SRishi Srivatsavai { "SENT", 12, 1153*4eaa4710SRishi Srivatsavai offsetof(bridge_statfields_buf_t, bridges_sent), print_default_cb }, 1154*4eaa4710SRishi Srivatsavai { NULL, 0, 0, NULL}}; 1155*4eaa4710SRishi Srivatsavai 1156*4eaa4710SRishi Srivatsavai /* 1157*4eaa4710SRishi Srivatsavai * structures for 'dladm show-bridge -s -l'. These are based in part on 1158*4eaa4710SRishi Srivatsavai * section 14.6.1.1.3 of IEEE 802.1D-2004. 1159*4eaa4710SRishi Srivatsavai */ 1160*4eaa4710SRishi Srivatsavai typedef struct bridge_link_statfields_buf_s { 1161*4eaa4710SRishi Srivatsavai char bridgels_link[MAXLINKNAMELEN]; 1162*4eaa4710SRishi Srivatsavai char bridgels_cfgbpdu[ULONG_DIG]; 1163*4eaa4710SRishi Srivatsavai char bridgels_tcnbpdu[ULONG_DIG]; 1164*4eaa4710SRishi Srivatsavai char bridgels_rstpbpdu[ULONG_DIG]; 1165*4eaa4710SRishi Srivatsavai char bridgels_txbpdu[ULONG_DIG]; 1166*4eaa4710SRishi Srivatsavai char bridgels_drops[UINT64_DIG]; /* 14.6.1.1.3(d) */ 1167*4eaa4710SRishi Srivatsavai char bridgels_recv[UINT64_DIG]; /* 14.6.1.1.3(a) */ 1168*4eaa4710SRishi Srivatsavai char bridgels_xmit[UINT64_DIG]; /* 14.6.1.1.3(c) */ 1169*4eaa4710SRishi Srivatsavai } bridge_link_statfields_buf_t; 1170*4eaa4710SRishi Srivatsavai 1171*4eaa4710SRishi Srivatsavai static ofmt_field_t bridge_link_statfields[] = { 1172*4eaa4710SRishi Srivatsavai /* name, field width, offset, callback */ 1173*4eaa4710SRishi Srivatsavai { "LINK", 12, 1174*4eaa4710SRishi Srivatsavai offsetof(bridge_link_statfields_buf_t, bridgels_link), print_default_cb }, 1175*4eaa4710SRishi Srivatsavai { "CFGBPDU", 9, 1176*4eaa4710SRishi Srivatsavai offsetof(bridge_link_statfields_buf_t, bridgels_cfgbpdu), 1177*4eaa4710SRishi Srivatsavai print_default_cb }, 1178*4eaa4710SRishi Srivatsavai { "TCNBPDU", 9, 1179*4eaa4710SRishi Srivatsavai offsetof(bridge_link_statfields_buf_t, bridgels_tcnbpdu), 1180*4eaa4710SRishi Srivatsavai print_default_cb }, 1181*4eaa4710SRishi Srivatsavai { "RSTPBPDU", 9, 1182*4eaa4710SRishi Srivatsavai offsetof(bridge_link_statfields_buf_t, bridgels_rstpbpdu), 1183*4eaa4710SRishi Srivatsavai print_default_cb }, 1184*4eaa4710SRishi Srivatsavai { "TXBPDU", 9, 1185*4eaa4710SRishi Srivatsavai offsetof(bridge_link_statfields_buf_t, bridgels_txbpdu), print_default_cb }, 1186*4eaa4710SRishi Srivatsavai { "DROPS", 9, 1187*4eaa4710SRishi Srivatsavai offsetof(bridge_link_statfields_buf_t, bridgels_drops), print_default_cb }, 1188*4eaa4710SRishi Srivatsavai { "RECV", 9, 1189*4eaa4710SRishi Srivatsavai offsetof(bridge_link_statfields_buf_t, bridgels_recv), print_default_cb }, 1190*4eaa4710SRishi Srivatsavai { "XMIT", 9, 1191*4eaa4710SRishi Srivatsavai offsetof(bridge_link_statfields_buf_t, bridgels_xmit), print_default_cb }, 1192*4eaa4710SRishi Srivatsavai { NULL, 0, 0, NULL}}; 1193*4eaa4710SRishi Srivatsavai 1194*4eaa4710SRishi Srivatsavai /* 1195*4eaa4710SRishi Srivatsavai * structures for 'dladm show-bridge -f'. These are based in part on 1196*4eaa4710SRishi Srivatsavai * section 14.7.6.3.3 of IEEE 802.1D-2004. 1197*4eaa4710SRishi Srivatsavai */ 1198*4eaa4710SRishi Srivatsavai typedef struct bridge_fwd_fields_buf_s { 1199*4eaa4710SRishi Srivatsavai char bridgef_dest[18]; /* 14.7.6.3.3(a) */ 1200*4eaa4710SRishi Srivatsavai char bridgef_age[8]; 1201*4eaa4710SRishi Srivatsavai char bridgef_flags[6]; 1202*4eaa4710SRishi Srivatsavai char bridgef_output[MAXLINKNAMELEN]; /* 14.7.6.3.3(c) */ 1203*4eaa4710SRishi Srivatsavai } bridge_fwd_fields_buf_t; 1204*4eaa4710SRishi Srivatsavai 1205*4eaa4710SRishi Srivatsavai static ofmt_field_t bridge_fwd_fields[] = { 1206*4eaa4710SRishi Srivatsavai /* name, field width, offset, callback */ 1207*4eaa4710SRishi Srivatsavai { "DEST", 17, 1208*4eaa4710SRishi Srivatsavai offsetof(bridge_fwd_fields_buf_t, bridgef_dest), print_default_cb }, 1209*4eaa4710SRishi Srivatsavai { "AGE", 7, 1210*4eaa4710SRishi Srivatsavai offsetof(bridge_fwd_fields_buf_t, bridgef_age), print_default_cb }, 1211*4eaa4710SRishi Srivatsavai { "FLAGS", 6, 1212*4eaa4710SRishi Srivatsavai offsetof(bridge_fwd_fields_buf_t, bridgef_flags), print_default_cb }, 1213*4eaa4710SRishi Srivatsavai { "OUTPUT", 12, 1214*4eaa4710SRishi Srivatsavai offsetof(bridge_fwd_fields_buf_t, bridgef_output), print_default_cb }, 1215*4eaa4710SRishi Srivatsavai { NULL, 0, 0, NULL}}; 1216*4eaa4710SRishi Srivatsavai 1217*4eaa4710SRishi Srivatsavai /* 1218*4eaa4710SRishi Srivatsavai * structures for 'dladm show-bridge -t'. 1219*4eaa4710SRishi Srivatsavai */ 1220*4eaa4710SRishi Srivatsavai typedef struct bridge_trill_fields_buf_s { 1221*4eaa4710SRishi Srivatsavai char bridget_nick[6]; 1222*4eaa4710SRishi Srivatsavai char bridget_flags[6]; 1223*4eaa4710SRishi Srivatsavai char bridget_link[MAXLINKNAMELEN]; 1224*4eaa4710SRishi Srivatsavai char bridget_nexthop[18]; 1225*4eaa4710SRishi Srivatsavai } bridge_trill_fields_buf_t; 1226*4eaa4710SRishi Srivatsavai 1227*4eaa4710SRishi Srivatsavai static ofmt_field_t bridge_trill_fields[] = { 1228*4eaa4710SRishi Srivatsavai /* name, field width, offset, callback */ 1229*4eaa4710SRishi Srivatsavai { "NICK", 5, 1230*4eaa4710SRishi Srivatsavai offsetof(bridge_trill_fields_buf_t, bridget_nick), print_default_cb }, 1231*4eaa4710SRishi Srivatsavai { "FLAGS", 6, 1232*4eaa4710SRishi Srivatsavai offsetof(bridge_trill_fields_buf_t, bridget_flags), print_default_cb }, 1233*4eaa4710SRishi Srivatsavai { "LINK", 12, 1234*4eaa4710SRishi Srivatsavai offsetof(bridge_trill_fields_buf_t, bridget_link), print_default_cb }, 1235*4eaa4710SRishi Srivatsavai { "NEXTHOP", 17, 1236*4eaa4710SRishi Srivatsavai offsetof(bridge_trill_fields_buf_t, bridget_nexthop), print_default_cb }, 1237*4eaa4710SRishi Srivatsavai { NULL, 0, 0, NULL}}; 1238*4eaa4710SRishi Srivatsavai 12397c478bd9Sstevel@tonic-gate static char *progname; 12400ba2cbe9Sxc151355 static sig_atomic_t signalled; 12417c478bd9Sstevel@tonic-gate 12424ac67f02SAnurag S. Maskey /* 12434ac67f02SAnurag S. Maskey * Handle to libdladm. Opened in main() before the sub-command 12444ac67f02SAnurag S. Maskey * specific function is called. 12454ac67f02SAnurag S. Maskey */ 12464ac67f02SAnurag S. Maskey static dladm_handle_t handle = NULL; 12474ac67f02SAnurag S. Maskey 1248da14cebeSEric Cheng #define DLADM_ETHERSTUB_NAME "etherstub" 1249da14cebeSEric Cheng #define DLADM_IS_ETHERSTUB(id) (id == DATALINK_INVALID_LINKID) 1250da14cebeSEric Cheng 12517c478bd9Sstevel@tonic-gate static void 12527c478bd9Sstevel@tonic-gate usage(void) 12537c478bd9Sstevel@tonic-gate { 12548d5c46e6Sam223141 int i; 12558d5c46e6Sam223141 cmd_t *cmdp; 12568d5c46e6Sam223141 (void) fprintf(stderr, gettext("usage: dladm <subcommand> <args> ..." 12578d5c46e6Sam223141 "\n")); 12588d5c46e6Sam223141 for (i = 0; i < sizeof (cmds) / sizeof (cmds[0]); i++) { 12598d5c46e6Sam223141 cmdp = &cmds[i]; 12608d5c46e6Sam223141 if (cmdp->c_usage != NULL) 12618d5c46e6Sam223141 (void) fprintf(stderr, "%s\n", gettext(cmdp->c_usage)); 12628d5c46e6Sam223141 } 12634ac67f02SAnurag S. Maskey 12644ac67f02SAnurag S. Maskey /* close dladm handle if it was opened */ 12654ac67f02SAnurag S. Maskey if (handle != NULL) 12664ac67f02SAnurag S. Maskey dladm_close(handle); 12674ac67f02SAnurag S. Maskey 12687c478bd9Sstevel@tonic-gate exit(1); 12697c478bd9Sstevel@tonic-gate } 12707c478bd9Sstevel@tonic-gate 12717c478bd9Sstevel@tonic-gate int 12727c478bd9Sstevel@tonic-gate main(int argc, char *argv[]) 12737c478bd9Sstevel@tonic-gate { 12747c478bd9Sstevel@tonic-gate int i; 12757c478bd9Sstevel@tonic-gate cmd_t *cmdp; 12764ac67f02SAnurag S. Maskey dladm_status_t status; 12777c478bd9Sstevel@tonic-gate 12787c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 12797c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) 12807c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" 12817c478bd9Sstevel@tonic-gate #endif 12827c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 12837c478bd9Sstevel@tonic-gate 12847c478bd9Sstevel@tonic-gate progname = argv[0]; 12857c478bd9Sstevel@tonic-gate 12867c478bd9Sstevel@tonic-gate if (argc < 2) 12877c478bd9Sstevel@tonic-gate usage(); 12887c478bd9Sstevel@tonic-gate 12897c478bd9Sstevel@tonic-gate for (i = 0; i < sizeof (cmds) / sizeof (cmds[0]); i++) { 12907c478bd9Sstevel@tonic-gate cmdp = &cmds[i]; 12917c478bd9Sstevel@tonic-gate if (strcmp(argv[1], cmdp->c_name) == 0) { 12924ac67f02SAnurag S. Maskey /* Open the libdladm handle */ 12934ac67f02SAnurag S. Maskey if ((status = dladm_open(&handle)) != DLADM_STATUS_OK) { 12944ac67f02SAnurag S. Maskey die_dlerr(status, 12954ac67f02SAnurag S. Maskey "could not open /dev/dld"); 12964ac67f02SAnurag S. Maskey } 12974ac67f02SAnurag S. Maskey 12988d5c46e6Sam223141 cmdp->c_fn(argc - 1, &argv[1], cmdp->c_usage); 12994ac67f02SAnurag S. Maskey 13004ac67f02SAnurag S. Maskey dladm_close(handle); 13017c478bd9Sstevel@tonic-gate exit(0); 13027c478bd9Sstevel@tonic-gate } 13037c478bd9Sstevel@tonic-gate } 13047c478bd9Sstevel@tonic-gate 13057c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("%s: unknown subcommand '%s'\n"), 13067c478bd9Sstevel@tonic-gate progname, argv[1]); 13077c478bd9Sstevel@tonic-gate usage(); 13087c478bd9Sstevel@tonic-gate 13097c478bd9Sstevel@tonic-gate return (0); 13107c478bd9Sstevel@tonic-gate } 13117c478bd9Sstevel@tonic-gate 1312da14cebeSEric Cheng /*ARGSUSED*/ 1313da14cebeSEric Cheng static int 1314da14cebeSEric Cheng show_usage_date(dladm_usage_t *usage, void *arg) 1315da14cebeSEric Cheng { 1316ae6aa22aSVenugopal Iyer show_usage_state_t *state = (show_usage_state_t *)arg; 1317da14cebeSEric Cheng time_t stime; 1318da14cebeSEric Cheng char timebuf[20]; 1319ae6aa22aSVenugopal Iyer dladm_status_t status; 1320ae6aa22aSVenugopal Iyer uint32_t flags; 1321ae6aa22aSVenugopal Iyer 1322ae6aa22aSVenugopal Iyer /* 1323ae6aa22aSVenugopal Iyer * Only show usage information for existing links unless '-a' 1324ae6aa22aSVenugopal Iyer * is specified. 1325ae6aa22aSVenugopal Iyer */ 1326ae6aa22aSVenugopal Iyer if (!state->us_showall) { 1327ae6aa22aSVenugopal Iyer if ((status = dladm_name2info(handle, usage->du_name, 1328ae6aa22aSVenugopal Iyer NULL, &flags, NULL, NULL)) != DLADM_STATUS_OK) { 1329ae6aa22aSVenugopal Iyer return (status); 1330ae6aa22aSVenugopal Iyer } 1331ae6aa22aSVenugopal Iyer if ((flags & DLADM_OPT_ACTIVE) == 0) 1332ae6aa22aSVenugopal Iyer return (DLADM_STATUS_LINKINVAL); 1333ae6aa22aSVenugopal Iyer } 1334da14cebeSEric Cheng 1335da14cebeSEric Cheng stime = usage->du_stime; 1336da14cebeSEric Cheng (void) strftime(timebuf, sizeof (timebuf), "%m/%d/%Y", 1337da14cebeSEric Cheng localtime(&stime)); 1338da14cebeSEric Cheng (void) printf("%s\n", timebuf); 1339da14cebeSEric Cheng 1340da14cebeSEric Cheng return (DLADM_STATUS_OK); 1341da14cebeSEric Cheng } 1342da14cebeSEric Cheng 1343da14cebeSEric Cheng static int 1344da14cebeSEric Cheng show_usage_time(dladm_usage_t *usage, void *arg) 1345da14cebeSEric Cheng { 1346da14cebeSEric Cheng show_usage_state_t *state = (show_usage_state_t *)arg; 1347da14cebeSEric Cheng char buf[DLADM_STRSIZE]; 1348da14cebeSEric Cheng usage_l_fields_buf_t ubuf; 1349da14cebeSEric Cheng time_t time; 1350da14cebeSEric Cheng double bw; 1351ae6aa22aSVenugopal Iyer dladm_status_t status; 1352ae6aa22aSVenugopal Iyer uint32_t flags; 1353ae6aa22aSVenugopal Iyer 1354ae6aa22aSVenugopal Iyer /* 1355ae6aa22aSVenugopal Iyer * Only show usage information for existing links unless '-a' 1356ae6aa22aSVenugopal Iyer * is specified. 1357ae6aa22aSVenugopal Iyer */ 1358ae6aa22aSVenugopal Iyer if (!state->us_showall) { 1359ae6aa22aSVenugopal Iyer if ((status = dladm_name2info(handle, usage->du_name, 1360ae6aa22aSVenugopal Iyer NULL, &flags, NULL, NULL)) != DLADM_STATUS_OK) { 1361ae6aa22aSVenugopal Iyer return (status); 1362ae6aa22aSVenugopal Iyer } 1363ae6aa22aSVenugopal Iyer if ((flags & DLADM_OPT_ACTIVE) == 0) 1364ae6aa22aSVenugopal Iyer return (DLADM_STATUS_LINKINVAL); 1365ae6aa22aSVenugopal Iyer } 1366da14cebeSEric Cheng 1367da14cebeSEric Cheng if (state->us_plot) { 1368da14cebeSEric Cheng if (!state->us_printheader) { 1369da14cebeSEric Cheng if (state->us_first) { 1370da14cebeSEric Cheng (void) printf("# Time"); 1371da14cebeSEric Cheng state->us_first = B_FALSE; 1372da14cebeSEric Cheng } 1373da14cebeSEric Cheng (void) printf(" %s", usage->du_name); 1374da14cebeSEric Cheng if (usage->du_last) { 1375da14cebeSEric Cheng (void) printf("\n"); 1376da14cebeSEric Cheng state->us_first = B_TRUE; 1377da14cebeSEric Cheng state->us_printheader = B_TRUE; 1378da14cebeSEric Cheng } 1379da14cebeSEric Cheng } else { 1380da14cebeSEric Cheng if (state->us_first) { 1381da14cebeSEric Cheng time = usage->du_etime; 1382da14cebeSEric Cheng (void) strftime(buf, sizeof (buf), "%T", 1383da14cebeSEric Cheng localtime(&time)); 1384da14cebeSEric Cheng state->us_first = B_FALSE; 1385da14cebeSEric Cheng (void) printf("%s", buf); 1386da14cebeSEric Cheng } 1387da14cebeSEric Cheng bw = (double)usage->du_bandwidth/1000; 1388da14cebeSEric Cheng (void) printf(" %.2f", bw); 1389da14cebeSEric Cheng if (usage->du_last) { 1390da14cebeSEric Cheng (void) printf("\n"); 1391da14cebeSEric Cheng state->us_first = B_TRUE; 1392da14cebeSEric Cheng } 1393da14cebeSEric Cheng } 1394da14cebeSEric Cheng return (DLADM_STATUS_OK); 1395da14cebeSEric Cheng } 1396da14cebeSEric Cheng 1397da14cebeSEric Cheng bzero(&ubuf, sizeof (ubuf)); 1398da14cebeSEric Cheng 1399da14cebeSEric Cheng (void) snprintf(ubuf.usage_l_link, sizeof (ubuf.usage_l_link), "%s", 1400da14cebeSEric Cheng usage->du_name); 1401da14cebeSEric Cheng time = usage->du_stime; 1402da14cebeSEric Cheng (void) strftime(buf, sizeof (buf), "%T", localtime(&time)); 1403da14cebeSEric Cheng (void) snprintf(ubuf.usage_l_stime, sizeof (ubuf.usage_l_stime), "%s", 1404da14cebeSEric Cheng buf); 1405da14cebeSEric Cheng time = usage->du_etime; 1406da14cebeSEric Cheng (void) strftime(buf, sizeof (buf), "%T", localtime(&time)); 1407da14cebeSEric Cheng (void) snprintf(ubuf.usage_l_etime, sizeof (ubuf.usage_l_etime), "%s", 1408da14cebeSEric Cheng buf); 1409da14cebeSEric Cheng (void) snprintf(ubuf.usage_l_rbytes, sizeof (ubuf.usage_l_rbytes), 1410da14cebeSEric Cheng "%llu", usage->du_rbytes); 1411da14cebeSEric Cheng (void) snprintf(ubuf.usage_l_obytes, sizeof (ubuf.usage_l_obytes), 1412da14cebeSEric Cheng "%llu", usage->du_obytes); 1413da14cebeSEric Cheng (void) snprintf(ubuf.usage_l_bandwidth, sizeof (ubuf.usage_l_bandwidth), 1414da14cebeSEric Cheng "%s Mbps", dladm_bw2str(usage->du_bandwidth, buf)); 1415da14cebeSEric Cheng 14168002d411SSowmini Varadhan ofmt_print(state->us_ofmt, &ubuf); 1417da14cebeSEric Cheng return (DLADM_STATUS_OK); 1418da14cebeSEric Cheng } 1419da14cebeSEric Cheng 1420da14cebeSEric Cheng static int 1421da14cebeSEric Cheng show_usage_res(dladm_usage_t *usage, void *arg) 1422da14cebeSEric Cheng { 1423da14cebeSEric Cheng show_usage_state_t *state = (show_usage_state_t *)arg; 1424da14cebeSEric Cheng char buf[DLADM_STRSIZE]; 1425da14cebeSEric Cheng usage_fields_buf_t ubuf; 1426ae6aa22aSVenugopal Iyer dladm_status_t status; 1427ae6aa22aSVenugopal Iyer uint32_t flags; 1428ae6aa22aSVenugopal Iyer 1429ae6aa22aSVenugopal Iyer /* 1430ae6aa22aSVenugopal Iyer * Only show usage information for existing links unless '-a' 1431ae6aa22aSVenugopal Iyer * is specified. 1432ae6aa22aSVenugopal Iyer */ 1433ae6aa22aSVenugopal Iyer if (!state->us_showall) { 1434ae6aa22aSVenugopal Iyer if ((status = dladm_name2info(handle, usage->du_name, 1435ae6aa22aSVenugopal Iyer NULL, &flags, NULL, NULL)) != DLADM_STATUS_OK) { 1436ae6aa22aSVenugopal Iyer return (status); 1437ae6aa22aSVenugopal Iyer } 1438ae6aa22aSVenugopal Iyer if ((flags & DLADM_OPT_ACTIVE) == 0) 1439ae6aa22aSVenugopal Iyer return (DLADM_STATUS_LINKINVAL); 1440ae6aa22aSVenugopal Iyer } 1441da14cebeSEric Cheng 1442da14cebeSEric Cheng bzero(&ubuf, sizeof (ubuf)); 1443da14cebeSEric Cheng 1444da14cebeSEric Cheng (void) snprintf(ubuf.usage_link, sizeof (ubuf.usage_link), "%s", 1445da14cebeSEric Cheng usage->du_name); 1446da14cebeSEric Cheng (void) snprintf(ubuf.usage_duration, sizeof (ubuf.usage_duration), 1447da14cebeSEric Cheng "%llu", usage->du_duration); 1448da14cebeSEric Cheng (void) snprintf(ubuf.usage_ipackets, sizeof (ubuf.usage_ipackets), 1449da14cebeSEric Cheng "%llu", usage->du_ipackets); 1450da14cebeSEric Cheng (void) snprintf(ubuf.usage_rbytes, sizeof (ubuf.usage_rbytes), 1451da14cebeSEric Cheng "%llu", usage->du_rbytes); 1452da14cebeSEric Cheng (void) snprintf(ubuf.usage_opackets, sizeof (ubuf.usage_opackets), 1453da14cebeSEric Cheng "%llu", usage->du_opackets); 1454da14cebeSEric Cheng (void) snprintf(ubuf.usage_obytes, sizeof (ubuf.usage_obytes), 1455da14cebeSEric Cheng "%llu", usage->du_obytes); 1456da14cebeSEric Cheng (void) snprintf(ubuf.usage_bandwidth, sizeof (ubuf.usage_bandwidth), 1457da14cebeSEric Cheng "%s Mbps", dladm_bw2str(usage->du_bandwidth, buf)); 1458da14cebeSEric Cheng 14598002d411SSowmini Varadhan ofmt_print(state->us_ofmt, &ubuf); 1460da14cebeSEric Cheng 1461da14cebeSEric Cheng return (DLADM_STATUS_OK); 1462da14cebeSEric Cheng } 1463da14cebeSEric Cheng 1464da14cebeSEric Cheng static boolean_t 1465da14cebeSEric Cheng valid_formatspec(char *formatspec_str) 1466da14cebeSEric Cheng { 1467da14cebeSEric Cheng if (strcmp(formatspec_str, "gnuplot") == 0) 1468da14cebeSEric Cheng return (B_TRUE); 1469da14cebeSEric Cheng return (B_FALSE); 1470da14cebeSEric Cheng 1471da14cebeSEric Cheng } 1472da14cebeSEric Cheng 1473da14cebeSEric Cheng /*ARGSUSED*/ 1474da14cebeSEric Cheng static void 1475da14cebeSEric Cheng do_show_usage(int argc, char *argv[], const char *use) 1476da14cebeSEric Cheng { 1477da14cebeSEric Cheng char *file = NULL; 1478da14cebeSEric Cheng int opt; 1479da14cebeSEric Cheng dladm_status_t status; 1480da14cebeSEric Cheng boolean_t d_arg = B_FALSE; 1481da14cebeSEric Cheng char *stime = NULL; 1482da14cebeSEric Cheng char *etime = NULL; 1483da14cebeSEric Cheng char *resource = NULL; 1484da14cebeSEric Cheng show_usage_state_t state; 1485da14cebeSEric Cheng boolean_t o_arg = B_FALSE; 1486da14cebeSEric Cheng boolean_t F_arg = B_FALSE; 1487da14cebeSEric Cheng char *fields_str = NULL; 1488da14cebeSEric Cheng char *formatspec_str = NULL; 1489da14cebeSEric Cheng char *all_l_fields = 1490da14cebeSEric Cheng "link,start,end,rbytes,obytes,bandwidth"; 14918002d411SSowmini Varadhan ofmt_handle_t ofmt; 14928002d411SSowmini Varadhan ofmt_status_t oferr; 14938002d411SSowmini Varadhan uint_t ofmtflags = 0; 1494da14cebeSEric Cheng 1495da14cebeSEric Cheng bzero(&state, sizeof (show_usage_state_t)); 14968002d411SSowmini Varadhan state.us_parsable = B_FALSE; 1497da14cebeSEric Cheng state.us_printheader = B_FALSE; 1498da14cebeSEric Cheng state.us_plot = B_FALSE; 1499da14cebeSEric Cheng state.us_first = B_TRUE; 1500da14cebeSEric Cheng 1501ae6aa22aSVenugopal Iyer while ((opt = getopt_long(argc, argv, "das:e:o:f:F:", 1502ae6aa22aSVenugopal Iyer usage_opts, NULL)) != -1) { 1503da14cebeSEric Cheng switch (opt) { 1504da14cebeSEric Cheng case 'd': 1505da14cebeSEric Cheng d_arg = B_TRUE; 1506da14cebeSEric Cheng break; 1507ae6aa22aSVenugopal Iyer case 'a': 1508ae6aa22aSVenugopal Iyer state.us_showall = B_TRUE; 1509da14cebeSEric Cheng break; 1510da14cebeSEric Cheng case 'f': 1511da14cebeSEric Cheng file = optarg; 1512da14cebeSEric Cheng break; 1513da14cebeSEric Cheng case 's': 1514da14cebeSEric Cheng stime = optarg; 1515da14cebeSEric Cheng break; 1516da14cebeSEric Cheng case 'e': 1517da14cebeSEric Cheng etime = optarg; 1518da14cebeSEric Cheng break; 1519da14cebeSEric Cheng case 'o': 1520da14cebeSEric Cheng o_arg = B_TRUE; 1521da14cebeSEric Cheng fields_str = optarg; 1522da14cebeSEric Cheng break; 1523da14cebeSEric Cheng case 'F': 1524ae6aa22aSVenugopal Iyer state.us_plot = F_arg = B_TRUE; 1525da14cebeSEric Cheng formatspec_str = optarg; 1526da14cebeSEric Cheng break; 1527da14cebeSEric Cheng default: 1528da14cebeSEric Cheng die_opterr(optopt, opt, use); 1529da14cebeSEric Cheng break; 1530da14cebeSEric Cheng } 1531da14cebeSEric Cheng } 1532da14cebeSEric Cheng 1533da14cebeSEric Cheng if (file == NULL) 1534da14cebeSEric Cheng die("show-usage requires a file"); 1535da14cebeSEric Cheng 1536da14cebeSEric Cheng if (optind == (argc-1)) { 1537ae6aa22aSVenugopal Iyer uint32_t flags; 1538ae6aa22aSVenugopal Iyer 1539da14cebeSEric Cheng resource = argv[optind]; 1540ae6aa22aSVenugopal Iyer if (!state.us_showall && 1541ae6aa22aSVenugopal Iyer (((status = dladm_name2info(handle, resource, NULL, &flags, 1542ae6aa22aSVenugopal Iyer NULL, NULL)) != DLADM_STATUS_OK) || 1543ae6aa22aSVenugopal Iyer ((flags & DLADM_OPT_ACTIVE) == 0))) { 1544ae6aa22aSVenugopal Iyer die("invalid link: '%s'", resource); 1545ae6aa22aSVenugopal Iyer } 1546da14cebeSEric Cheng } 1547da14cebeSEric Cheng 1548ae6aa22aSVenugopal Iyer if (F_arg && d_arg) 1549ae6aa22aSVenugopal Iyer die("incompatible -d and -F options"); 1550da14cebeSEric Cheng 1551da14cebeSEric Cheng if (F_arg && valid_formatspec(formatspec_str) == B_FALSE) 1552da14cebeSEric Cheng die("Format specifier %s not supported", formatspec_str); 1553da14cebeSEric Cheng 15548002d411SSowmini Varadhan if (state.us_parsable) 15558002d411SSowmini Varadhan ofmtflags |= OFMT_PARSABLE; 15568002d411SSowmini Varadhan 15578002d411SSowmini Varadhan if (resource == NULL && stime == NULL && etime == NULL) { 15588002d411SSowmini Varadhan oferr = ofmt_open(fields_str, usage_fields, ofmtflags, 0, 15598002d411SSowmini Varadhan &ofmt); 15608002d411SSowmini Varadhan } else { 15618002d411SSowmini Varadhan if (!o_arg || (o_arg && strcasecmp(fields_str, "all") == 0)) 15628002d411SSowmini Varadhan fields_str = all_l_fields; 15638002d411SSowmini Varadhan oferr = ofmt_open(fields_str, usage_l_fields, ofmtflags, 0, 15648002d411SSowmini Varadhan &ofmt); 15658002d411SSowmini Varadhan 15668002d411SSowmini Varadhan } 15678002d411SSowmini Varadhan dladm_ofmt_check(oferr, state.us_parsable, ofmt); 15688002d411SSowmini Varadhan state.us_ofmt = ofmt; 15698002d411SSowmini Varadhan 1570da14cebeSEric Cheng if (d_arg) { 1571da14cebeSEric Cheng /* Print log dates */ 1572da14cebeSEric Cheng status = dladm_usage_dates(show_usage_date, 1573da14cebeSEric Cheng DLADM_LOGTYPE_LINK, file, resource, &state); 1574da14cebeSEric Cheng } else if (resource == NULL && stime == NULL && etime == NULL && 1575ae6aa22aSVenugopal Iyer !F_arg) { 1576da14cebeSEric Cheng /* Print summary */ 1577da14cebeSEric Cheng status = dladm_usage_summary(show_usage_res, 1578da14cebeSEric Cheng DLADM_LOGTYPE_LINK, file, &state); 1579da14cebeSEric Cheng } else if (resource != NULL) { 1580da14cebeSEric Cheng /* Print log entries for named resource */ 1581da14cebeSEric Cheng status = dladm_walk_usage_res(show_usage_time, 1582da14cebeSEric Cheng DLADM_LOGTYPE_LINK, file, resource, stime, etime, &state); 1583da14cebeSEric Cheng } else { 1584da14cebeSEric Cheng /* Print time and information for each link */ 1585da14cebeSEric Cheng status = dladm_walk_usage_time(show_usage_time, 1586da14cebeSEric Cheng DLADM_LOGTYPE_LINK, file, stime, etime, &state); 1587da14cebeSEric Cheng } 1588da14cebeSEric Cheng 1589da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 1590da14cebeSEric Cheng die_dlerr(status, "show-usage"); 15918002d411SSowmini Varadhan ofmt_close(ofmt); 1592da14cebeSEric Cheng } 1593da14cebeSEric Cheng 15947c478bd9Sstevel@tonic-gate static void 15958d5c46e6Sam223141 do_create_aggr(int argc, char *argv[], const char *use) 15967c478bd9Sstevel@tonic-gate { 1597b509e89bSRishi Srivatsavai int option; 1598d62bc4baSyz147064 int key = 0; 15997c478bd9Sstevel@tonic-gate uint32_t policy = AGGR_POLICY_L4; 16007c478bd9Sstevel@tonic-gate aggr_lacp_mode_t lacp_mode = AGGR_LACP_OFF; 16017c478bd9Sstevel@tonic-gate aggr_lacp_timer_t lacp_timer = AGGR_LACP_TIMER_SHORT; 1602f595a68aSyz147064 dladm_aggr_port_attr_db_t port[MAXPORT]; 1603d62bc4baSyz147064 uint_t n, ndev, nlink; 16047c478bd9Sstevel@tonic-gate uint8_t mac_addr[ETHERADDRL]; 16057c478bd9Sstevel@tonic-gate boolean_t mac_addr_fixed = B_FALSE; 16067c478bd9Sstevel@tonic-gate boolean_t P_arg = B_FALSE; 16077c478bd9Sstevel@tonic-gate boolean_t l_arg = B_FALSE; 16087c478bd9Sstevel@tonic-gate boolean_t u_arg = B_FALSE; 16097c478bd9Sstevel@tonic-gate boolean_t T_arg = B_FALSE; 1610d62bc4baSyz147064 uint32_t flags = DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST; 16117c478bd9Sstevel@tonic-gate char *altroot = NULL; 1612d62bc4baSyz147064 char name[MAXLINKNAMELEN]; 1613d62bc4baSyz147064 char *devs[MAXPORT]; 1614d62bc4baSyz147064 char *links[MAXPORT]; 1615f595a68aSyz147064 dladm_status_t status; 1616da14cebeSEric Cheng dladm_status_t pstatus; 161763a6526dSMichael Lim char propstr[DLADM_STRSIZE]; 1618da14cebeSEric Cheng dladm_arg_list_t *proplist = NULL; 1619da14cebeSEric Cheng int i; 1620da14cebeSEric Cheng datalink_id_t linkid; 16217c478bd9Sstevel@tonic-gate 1622d62bc4baSyz147064 ndev = nlink = opterr = 0; 162363a6526dSMichael Lim bzero(propstr, DLADM_STRSIZE); 162463a6526dSMichael Lim 1625da14cebeSEric Cheng while ((option = getopt_long(argc, argv, ":d:l:L:P:R:tfu:T:p:", 1626d62bc4baSyz147064 lopts, NULL)) != -1) { 16277c478bd9Sstevel@tonic-gate switch (option) { 16287c478bd9Sstevel@tonic-gate case 'd': 1629d62bc4baSyz147064 if (ndev + nlink >= MAXPORT) 1630d62bc4baSyz147064 die("too many ports specified"); 16317c478bd9Sstevel@tonic-gate 1632d62bc4baSyz147064 devs[ndev++] = optarg; 16337c478bd9Sstevel@tonic-gate break; 16347c478bd9Sstevel@tonic-gate case 'P': 163533343a97Smeem if (P_arg) 163633343a97Smeem die_optdup(option); 16377c478bd9Sstevel@tonic-gate 16387c478bd9Sstevel@tonic-gate P_arg = B_TRUE; 1639f595a68aSyz147064 if (!dladm_aggr_str2policy(optarg, &policy)) 164033343a97Smeem die("invalid policy '%s'", optarg); 16417c478bd9Sstevel@tonic-gate break; 16427c478bd9Sstevel@tonic-gate case 'u': 164333343a97Smeem if (u_arg) 164433343a97Smeem die_optdup(option); 16457c478bd9Sstevel@tonic-gate 16467c478bd9Sstevel@tonic-gate u_arg = B_TRUE; 1647f595a68aSyz147064 if (!dladm_aggr_str2macaddr(optarg, &mac_addr_fixed, 164833343a97Smeem mac_addr)) 164933343a97Smeem die("invalid MAC address '%s'", optarg); 16507c478bd9Sstevel@tonic-gate break; 16517c478bd9Sstevel@tonic-gate case 'l': 1652d62bc4baSyz147064 if (isdigit(optarg[strlen(optarg) - 1])) { 1653d62bc4baSyz147064 1654d62bc4baSyz147064 /* 1655d62bc4baSyz147064 * Ended with digit, possibly a link name. 1656d62bc4baSyz147064 */ 1657d62bc4baSyz147064 if (ndev + nlink >= MAXPORT) 1658d62bc4baSyz147064 die("too many ports specified"); 1659d62bc4baSyz147064 1660d62bc4baSyz147064 links[nlink++] = optarg; 1661d62bc4baSyz147064 break; 1662d62bc4baSyz147064 } 1663d62bc4baSyz147064 /* FALLTHROUGH */ 1664d62bc4baSyz147064 case 'L': 166533343a97Smeem if (l_arg) 166633343a97Smeem die_optdup(option); 16677c478bd9Sstevel@tonic-gate 16687c478bd9Sstevel@tonic-gate l_arg = B_TRUE; 1669f595a68aSyz147064 if (!dladm_aggr_str2lacpmode(optarg, &lacp_mode)) 167033343a97Smeem die("invalid LACP mode '%s'", optarg); 16717c478bd9Sstevel@tonic-gate break; 16727c478bd9Sstevel@tonic-gate case 'T': 167333343a97Smeem if (T_arg) 167433343a97Smeem die_optdup(option); 16757c478bd9Sstevel@tonic-gate 16767c478bd9Sstevel@tonic-gate T_arg = B_TRUE; 1677f595a68aSyz147064 if (!dladm_aggr_str2lacptimer(optarg, &lacp_timer)) 167833343a97Smeem die("invalid LACP timer value '%s'", optarg); 16797c478bd9Sstevel@tonic-gate break; 16807c478bd9Sstevel@tonic-gate case 't': 1681d62bc4baSyz147064 flags &= ~DLADM_OPT_PERSIST; 1682d62bc4baSyz147064 break; 1683d62bc4baSyz147064 case 'f': 1684d62bc4baSyz147064 flags |= DLADM_OPT_FORCE; 16857c478bd9Sstevel@tonic-gate break; 16867c478bd9Sstevel@tonic-gate case 'R': 16877c478bd9Sstevel@tonic-gate altroot = optarg; 16887c478bd9Sstevel@tonic-gate break; 1689da14cebeSEric Cheng case 'p': 169063a6526dSMichael Lim (void) strlcat(propstr, optarg, DLADM_STRSIZE); 169163a6526dSMichael Lim if (strlcat(propstr, ",", DLADM_STRSIZE) >= 169263a6526dSMichael Lim DLADM_STRSIZE) 169363a6526dSMichael Lim die("property list too long '%s'", propstr); 1694da14cebeSEric Cheng break; 169563a6526dSMichael Lim 16967c478bd9Sstevel@tonic-gate default: 16978d5c46e6Sam223141 die_opterr(optopt, option, use); 169833343a97Smeem break; 16997c478bd9Sstevel@tonic-gate } 17007c478bd9Sstevel@tonic-gate } 17017c478bd9Sstevel@tonic-gate 1702d62bc4baSyz147064 if (ndev + nlink == 0) 17037c478bd9Sstevel@tonic-gate usage(); 17047c478bd9Sstevel@tonic-gate 1705d62bc4baSyz147064 /* get key value or the aggregation name (required last argument) */ 17067c478bd9Sstevel@tonic-gate if (optind != (argc-1)) 17077c478bd9Sstevel@tonic-gate usage(); 17087c478bd9Sstevel@tonic-gate 1709d62bc4baSyz147064 if (!str2int(argv[optind], &key)) { 1710d62bc4baSyz147064 if (strlcpy(name, argv[optind], MAXLINKNAMELEN) >= 1711d62bc4baSyz147064 MAXLINKNAMELEN) { 1712d62bc4baSyz147064 die("link name too long '%s'", argv[optind]); 1713d62bc4baSyz147064 } 17147c478bd9Sstevel@tonic-gate 1715d62bc4baSyz147064 if (!dladm_valid_linkname(name)) 1716d62bc4baSyz147064 die("invalid link name '%s'", argv[optind]); 1717d62bc4baSyz147064 } else { 1718d62bc4baSyz147064 (void) snprintf(name, MAXLINKNAMELEN, "aggr%d", key); 1719d62bc4baSyz147064 } 1720d62bc4baSyz147064 1721d62bc4baSyz147064 if (altroot != NULL) 1722d62bc4baSyz147064 altroot_cmd(altroot, argc, argv); 1723d62bc4baSyz147064 1724d62bc4baSyz147064 for (n = 0; n < ndev; n++) { 17254ac67f02SAnurag S. Maskey if ((status = dladm_dev2linkid(handle, devs[n], 17264ac67f02SAnurag S. Maskey &port[n].lp_linkid)) != DLADM_STATUS_OK) { 17274ac67f02SAnurag S. Maskey die_dlerr(status, "invalid dev name '%s'", devs[n]); 1728d62bc4baSyz147064 } 1729d62bc4baSyz147064 } 1730d62bc4baSyz147064 1731d62bc4baSyz147064 for (n = 0; n < nlink; n++) { 17324ac67f02SAnurag S. Maskey if ((status = dladm_name2info(handle, links[n], 17334ac67f02SAnurag S. Maskey &port[ndev + n].lp_linkid, NULL, NULL, NULL)) != 17344ac67f02SAnurag S. Maskey DLADM_STATUS_OK) { 17354ac67f02SAnurag S. Maskey die_dlerr(status, "invalid link name '%s'", links[n]); 1736d62bc4baSyz147064 } 1737d62bc4baSyz147064 } 1738d62bc4baSyz147064 17394ac67f02SAnurag S. Maskey status = dladm_aggr_create(handle, name, key, ndev + nlink, port, 17404ac67f02SAnurag S. Maskey policy, mac_addr_fixed, (const uchar_t *)mac_addr, lacp_mode, 1741d62bc4baSyz147064 lacp_timer, flags); 1742da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 1743da14cebeSEric Cheng goto done; 1744da14cebeSEric Cheng 174563a6526dSMichael Lim if (dladm_parse_link_props(propstr, &proplist, B_FALSE) 174663a6526dSMichael Lim != DLADM_STATUS_OK) 174763a6526dSMichael Lim die("invalid aggregation property"); 174863a6526dSMichael Lim 1749da14cebeSEric Cheng if (proplist == NULL) 1750da14cebeSEric Cheng return; 1751da14cebeSEric Cheng 17524ac67f02SAnurag S. Maskey status = dladm_name2info(handle, name, &linkid, NULL, NULL, NULL); 1753da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 1754da14cebeSEric Cheng goto done; 1755da14cebeSEric Cheng 1756da14cebeSEric Cheng for (i = 0; i < proplist->al_count; i++) { 1757da14cebeSEric Cheng dladm_arg_info_t *aip = &proplist->al_info[i]; 1758da14cebeSEric Cheng 17594ac67f02SAnurag S. Maskey pstatus = dladm_set_linkprop(handle, linkid, aip->ai_name, 1760da14cebeSEric Cheng aip->ai_val, aip->ai_count, flags); 1761da14cebeSEric Cheng 1762da14cebeSEric Cheng if (pstatus != DLADM_STATUS_OK) { 1763da14cebeSEric Cheng die_dlerr(pstatus, 1764da14cebeSEric Cheng "aggr creation succeeded but " 1765da14cebeSEric Cheng "could not set property '%s'", aip->ai_name); 1766da14cebeSEric Cheng } 1767da14cebeSEric Cheng } 1768d62bc4baSyz147064 done: 1769da14cebeSEric Cheng dladm_free_props(proplist); 1770d62bc4baSyz147064 if (status != DLADM_STATUS_OK) { 1771d62bc4baSyz147064 if (status == DLADM_STATUS_NONOTIF) { 1772*4eaa4710SRishi Srivatsavai die("not all links have link up/down detection; must " 1773*4eaa4710SRishi Srivatsavai "use -f (see dladm(1M))"); 1774d62bc4baSyz147064 } else { 1775f595a68aSyz147064 die_dlerr(status, "create operation failed"); 17767c478bd9Sstevel@tonic-gate } 1777d62bc4baSyz147064 } 1778d62bc4baSyz147064 } 1779d62bc4baSyz147064 1780d62bc4baSyz147064 /* 1781d62bc4baSyz147064 * arg is either the key or the aggr name. Validate it and convert it to 1782d62bc4baSyz147064 * the linkid if altroot is NULL. 1783d62bc4baSyz147064 */ 1784d62bc4baSyz147064 static dladm_status_t 1785d62bc4baSyz147064 i_dladm_aggr_get_linkid(const char *altroot, const char *arg, 1786d62bc4baSyz147064 datalink_id_t *linkidp, uint32_t flags) 1787d62bc4baSyz147064 { 1788d62bc4baSyz147064 int key = 0; 1789d62bc4baSyz147064 char *aggr = NULL; 1790d62bc4baSyz147064 dladm_status_t status; 1791d62bc4baSyz147064 1792d62bc4baSyz147064 if (!str2int(arg, &key)) 1793d62bc4baSyz147064 aggr = (char *)arg; 1794d62bc4baSyz147064 1795d62bc4baSyz147064 if (aggr == NULL && key == 0) 1796d62bc4baSyz147064 return (DLADM_STATUS_LINKINVAL); 1797d62bc4baSyz147064 1798d62bc4baSyz147064 if (altroot != NULL) 1799d62bc4baSyz147064 return (DLADM_STATUS_OK); 1800d62bc4baSyz147064 1801d62bc4baSyz147064 if (aggr != NULL) { 18024ac67f02SAnurag S. Maskey status = dladm_name2info(handle, aggr, linkidp, NULL, NULL, 18034ac67f02SAnurag S. Maskey NULL); 1804d62bc4baSyz147064 } else { 18054ac67f02SAnurag S. Maskey status = dladm_key2linkid(handle, key, linkidp, flags); 1806d62bc4baSyz147064 } 1807d62bc4baSyz147064 1808d62bc4baSyz147064 return (status); 1809d62bc4baSyz147064 } 18107c478bd9Sstevel@tonic-gate 18117c478bd9Sstevel@tonic-gate static void 18128d5c46e6Sam223141 do_delete_aggr(int argc, char *argv[], const char *use) 18137c478bd9Sstevel@tonic-gate { 1814b509e89bSRishi Srivatsavai int option; 18157c478bd9Sstevel@tonic-gate char *altroot = NULL; 1816d62bc4baSyz147064 uint32_t flags = DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST; 1817f595a68aSyz147064 dladm_status_t status; 1818d62bc4baSyz147064 datalink_id_t linkid; 18197c478bd9Sstevel@tonic-gate 18207c478bd9Sstevel@tonic-gate opterr = 0; 1821d62bc4baSyz147064 while ((option = getopt_long(argc, argv, ":R:t", lopts, NULL)) != -1) { 18227c478bd9Sstevel@tonic-gate switch (option) { 18237c478bd9Sstevel@tonic-gate case 't': 1824d62bc4baSyz147064 flags &= ~DLADM_OPT_PERSIST; 18257c478bd9Sstevel@tonic-gate break; 18267c478bd9Sstevel@tonic-gate case 'R': 18277c478bd9Sstevel@tonic-gate altroot = optarg; 18287c478bd9Sstevel@tonic-gate break; 18297c478bd9Sstevel@tonic-gate default: 18308d5c46e6Sam223141 die_opterr(optopt, option, use); 18317c478bd9Sstevel@tonic-gate break; 18327c478bd9Sstevel@tonic-gate } 18337c478bd9Sstevel@tonic-gate } 18347c478bd9Sstevel@tonic-gate 1835d62bc4baSyz147064 /* get key value or the aggregation name (required last argument) */ 18367c478bd9Sstevel@tonic-gate if (optind != (argc-1)) 18377c478bd9Sstevel@tonic-gate usage(); 18387c478bd9Sstevel@tonic-gate 1839d62bc4baSyz147064 status = i_dladm_aggr_get_linkid(altroot, argv[optind], &linkid, flags); 1840d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 1841d62bc4baSyz147064 goto done; 18427c478bd9Sstevel@tonic-gate 1843d62bc4baSyz147064 if (altroot != NULL) 1844d62bc4baSyz147064 altroot_cmd(altroot, argc, argv); 1845d62bc4baSyz147064 18464ac67f02SAnurag S. Maskey status = dladm_aggr_delete(handle, linkid, flags); 1847d62bc4baSyz147064 done: 1848f595a68aSyz147064 if (status != DLADM_STATUS_OK) 1849f595a68aSyz147064 die_dlerr(status, "delete operation failed"); 18507c478bd9Sstevel@tonic-gate } 18517c478bd9Sstevel@tonic-gate 18527c478bd9Sstevel@tonic-gate static void 18538d5c46e6Sam223141 do_add_aggr(int argc, char *argv[], const char *use) 18547c478bd9Sstevel@tonic-gate { 1855b509e89bSRishi Srivatsavai int option; 1856d62bc4baSyz147064 uint_t n, ndev, nlink; 18577c478bd9Sstevel@tonic-gate char *altroot = NULL; 1858d62bc4baSyz147064 uint32_t flags = DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST; 1859d62bc4baSyz147064 datalink_id_t linkid; 1860f595a68aSyz147064 dladm_status_t status; 1861d62bc4baSyz147064 dladm_aggr_port_attr_db_t port[MAXPORT]; 1862d62bc4baSyz147064 char *devs[MAXPORT]; 1863d62bc4baSyz147064 char *links[MAXPORT]; 18647c478bd9Sstevel@tonic-gate 1865d62bc4baSyz147064 ndev = nlink = opterr = 0; 1866d62bc4baSyz147064 while ((option = getopt_long(argc, argv, ":d:l:R:tf", lopts, 18677c478bd9Sstevel@tonic-gate NULL)) != -1) { 18687c478bd9Sstevel@tonic-gate switch (option) { 18697c478bd9Sstevel@tonic-gate case 'd': 1870d62bc4baSyz147064 if (ndev + nlink >= MAXPORT) 1871d62bc4baSyz147064 die("too many ports specified"); 18727c478bd9Sstevel@tonic-gate 1873d62bc4baSyz147064 devs[ndev++] = optarg; 1874d62bc4baSyz147064 break; 1875d62bc4baSyz147064 case 'l': 1876d62bc4baSyz147064 if (ndev + nlink >= MAXPORT) 1877d62bc4baSyz147064 die("too many ports specified"); 187833343a97Smeem 1879d62bc4baSyz147064 links[nlink++] = optarg; 18807c478bd9Sstevel@tonic-gate break; 18817c478bd9Sstevel@tonic-gate case 't': 1882d62bc4baSyz147064 flags &= ~DLADM_OPT_PERSIST; 1883d62bc4baSyz147064 break; 1884d62bc4baSyz147064 case 'f': 1885d62bc4baSyz147064 flags |= DLADM_OPT_FORCE; 18867c478bd9Sstevel@tonic-gate break; 18877c478bd9Sstevel@tonic-gate case 'R': 18887c478bd9Sstevel@tonic-gate altroot = optarg; 18897c478bd9Sstevel@tonic-gate break; 18907c478bd9Sstevel@tonic-gate default: 18918d5c46e6Sam223141 die_opterr(optopt, option, use); 189233343a97Smeem break; 18937c478bd9Sstevel@tonic-gate } 18947c478bd9Sstevel@tonic-gate } 18957c478bd9Sstevel@tonic-gate 1896d62bc4baSyz147064 if (ndev + nlink == 0) 18977c478bd9Sstevel@tonic-gate usage(); 18987c478bd9Sstevel@tonic-gate 1899d62bc4baSyz147064 /* get key value or the aggregation name (required last argument) */ 19007c478bd9Sstevel@tonic-gate if (optind != (argc-1)) 19017c478bd9Sstevel@tonic-gate usage(); 19027c478bd9Sstevel@tonic-gate 1903d62bc4baSyz147064 if ((status = i_dladm_aggr_get_linkid(altroot, argv[optind], &linkid, 1904d62bc4baSyz147064 flags & (DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST))) != 1905d62bc4baSyz147064 DLADM_STATUS_OK) { 1906d62bc4baSyz147064 goto done; 1907d62bc4baSyz147064 } 19087c478bd9Sstevel@tonic-gate 1909d62bc4baSyz147064 if (altroot != NULL) 1910d62bc4baSyz147064 altroot_cmd(altroot, argc, argv); 1911d62bc4baSyz147064 1912d62bc4baSyz147064 for (n = 0; n < ndev; n++) { 19134ac67f02SAnurag S. Maskey if ((status = dladm_dev2linkid(handle, devs[n], 19144ac67f02SAnurag S. Maskey &(port[n].lp_linkid))) != DLADM_STATUS_OK) { 19154ac67f02SAnurag S. Maskey die_dlerr(status, "invalid <dev> '%s'", devs[n]); 1916d62bc4baSyz147064 } 1917d62bc4baSyz147064 } 1918d62bc4baSyz147064 1919d62bc4baSyz147064 for (n = 0; n < nlink; n++) { 19204ac67f02SAnurag S. Maskey if ((status = dladm_name2info(handle, links[n], 19214ac67f02SAnurag S. Maskey &port[n + ndev].lp_linkid, NULL, NULL, NULL)) != 19224ac67f02SAnurag S. Maskey DLADM_STATUS_OK) { 19234ac67f02SAnurag S. Maskey die_dlerr(status, "invalid <link> '%s'", links[n]); 1924d62bc4baSyz147064 } 1925d62bc4baSyz147064 } 1926d62bc4baSyz147064 19274ac67f02SAnurag S. Maskey status = dladm_aggr_add(handle, linkid, ndev + nlink, port, flags); 1928d62bc4baSyz147064 done: 1929f595a68aSyz147064 if (status != DLADM_STATUS_OK) { 1930219a2a31Shl157128 /* 1931f595a68aSyz147064 * checking DLADM_STATUS_NOTSUP is a temporary workaround 1932219a2a31Shl157128 * and should be removed once 6399681 is fixed. 1933219a2a31Shl157128 */ 1934f595a68aSyz147064 if (status == DLADM_STATUS_NOTSUP) { 1935219a2a31Shl157128 (void) fprintf(stderr, 1936219a2a31Shl157128 gettext("%s: add operation failed: %s\n"), 1937219a2a31Shl157128 progname, 1938d62bc4baSyz147064 gettext("link capabilities don't match")); 19394ac67f02SAnurag S. Maskey dladm_close(handle); 1940219a2a31Shl157128 exit(ENOTSUP); 1941d62bc4baSyz147064 } else if (status == DLADM_STATUS_NONOTIF) { 1942*4eaa4710SRishi Srivatsavai die("not all links have link up/down detection; must " 1943*4eaa4710SRishi Srivatsavai "use -f (see dladm(1M))"); 1944d62bc4baSyz147064 } else { 1945f595a68aSyz147064 die_dlerr(status, "add operation failed"); 19467c478bd9Sstevel@tonic-gate } 19477c478bd9Sstevel@tonic-gate } 1948d62bc4baSyz147064 } 19497c478bd9Sstevel@tonic-gate 19507c478bd9Sstevel@tonic-gate static void 19518d5c46e6Sam223141 do_remove_aggr(int argc, char *argv[], const char *use) 19527c478bd9Sstevel@tonic-gate { 1953b509e89bSRishi Srivatsavai int option; 1954f595a68aSyz147064 dladm_aggr_port_attr_db_t port[MAXPORT]; 1955d62bc4baSyz147064 uint_t n, ndev, nlink; 1956d62bc4baSyz147064 char *devs[MAXPORT]; 1957d62bc4baSyz147064 char *links[MAXPORT]; 19587c478bd9Sstevel@tonic-gate char *altroot = NULL; 1959d62bc4baSyz147064 uint32_t flags; 1960d62bc4baSyz147064 datalink_id_t linkid; 1961f595a68aSyz147064 dladm_status_t status; 19627c478bd9Sstevel@tonic-gate 1963d62bc4baSyz147064 flags = DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST; 1964d62bc4baSyz147064 ndev = nlink = opterr = 0; 1965d62bc4baSyz147064 while ((option = getopt_long(argc, argv, ":d:l:R:t", 1966d62bc4baSyz147064 lopts, NULL)) != -1) { 19677c478bd9Sstevel@tonic-gate switch (option) { 19687c478bd9Sstevel@tonic-gate case 'd': 1969d62bc4baSyz147064 if (ndev + nlink >= MAXPORT) 1970d62bc4baSyz147064 die("too many ports specified"); 19717c478bd9Sstevel@tonic-gate 1972d62bc4baSyz147064 devs[ndev++] = optarg; 1973d62bc4baSyz147064 break; 1974d62bc4baSyz147064 case 'l': 1975d62bc4baSyz147064 if (ndev + nlink >= MAXPORT) 1976d62bc4baSyz147064 die("too many ports specified"); 197733343a97Smeem 1978d62bc4baSyz147064 links[nlink++] = optarg; 19797c478bd9Sstevel@tonic-gate break; 19807c478bd9Sstevel@tonic-gate case 't': 1981d62bc4baSyz147064 flags &= ~DLADM_OPT_PERSIST; 19827c478bd9Sstevel@tonic-gate break; 19837c478bd9Sstevel@tonic-gate case 'R': 19847c478bd9Sstevel@tonic-gate altroot = optarg; 19857c478bd9Sstevel@tonic-gate break; 19867c478bd9Sstevel@tonic-gate default: 19878d5c46e6Sam223141 die_opterr(optopt, option, use); 198833343a97Smeem break; 19897c478bd9Sstevel@tonic-gate } 19907c478bd9Sstevel@tonic-gate } 19917c478bd9Sstevel@tonic-gate 1992d62bc4baSyz147064 if (ndev + nlink == 0) 19937c478bd9Sstevel@tonic-gate usage(); 19947c478bd9Sstevel@tonic-gate 1995d62bc4baSyz147064 /* get key value or the aggregation name (required last argument) */ 19967c478bd9Sstevel@tonic-gate if (optind != (argc-1)) 19977c478bd9Sstevel@tonic-gate usage(); 19987c478bd9Sstevel@tonic-gate 1999d62bc4baSyz147064 status = i_dladm_aggr_get_linkid(altroot, argv[optind], &linkid, flags); 2000d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 2001d62bc4baSyz147064 goto done; 20027c478bd9Sstevel@tonic-gate 2003d62bc4baSyz147064 if (altroot != NULL) 2004d62bc4baSyz147064 altroot_cmd(altroot, argc, argv); 2005d62bc4baSyz147064 2006d62bc4baSyz147064 for (n = 0; n < ndev; n++) { 20074ac67f02SAnurag S. Maskey if ((status = dladm_dev2linkid(handle, devs[n], 20084ac67f02SAnurag S. Maskey &(port[n].lp_linkid))) != DLADM_STATUS_OK) { 20094ac67f02SAnurag S. Maskey die_dlerr(status, "invalid <dev> '%s'", devs[n]); 2010d62bc4baSyz147064 } 2011d62bc4baSyz147064 } 2012d62bc4baSyz147064 2013d62bc4baSyz147064 for (n = 0; n < nlink; n++) { 20144ac67f02SAnurag S. Maskey if ((status = dladm_name2info(handle, links[n], 20154ac67f02SAnurag S. Maskey &port[n + ndev].lp_linkid, NULL, NULL, NULL)) != 20164ac67f02SAnurag S. Maskey DLADM_STATUS_OK) { 20174ac67f02SAnurag S. Maskey die_dlerr(status, "invalid <link> '%s'", links[n]); 2018d62bc4baSyz147064 } 2019d62bc4baSyz147064 } 2020d62bc4baSyz147064 20214ac67f02SAnurag S. Maskey status = dladm_aggr_remove(handle, linkid, ndev + nlink, port, flags); 2022d62bc4baSyz147064 done: 2023f595a68aSyz147064 if (status != DLADM_STATUS_OK) 2024f595a68aSyz147064 die_dlerr(status, "remove operation failed"); 20257c478bd9Sstevel@tonic-gate } 20267c478bd9Sstevel@tonic-gate 20277c478bd9Sstevel@tonic-gate static void 20288d5c46e6Sam223141 do_modify_aggr(int argc, char *argv[], const char *use) 20297c478bd9Sstevel@tonic-gate { 2030b509e89bSRishi Srivatsavai int option; 20317c478bd9Sstevel@tonic-gate uint32_t policy = AGGR_POLICY_L4; 20327c478bd9Sstevel@tonic-gate aggr_lacp_mode_t lacp_mode = AGGR_LACP_OFF; 20337c478bd9Sstevel@tonic-gate aggr_lacp_timer_t lacp_timer = AGGR_LACP_TIMER_SHORT; 20347c478bd9Sstevel@tonic-gate uint8_t mac_addr[ETHERADDRL]; 20357c478bd9Sstevel@tonic-gate boolean_t mac_addr_fixed = B_FALSE; 20367c478bd9Sstevel@tonic-gate uint8_t modify_mask = 0; 20377c478bd9Sstevel@tonic-gate char *altroot = NULL; 2038d62bc4baSyz147064 uint32_t flags = DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST; 2039d62bc4baSyz147064 datalink_id_t linkid; 2040f595a68aSyz147064 dladm_status_t status; 20417c478bd9Sstevel@tonic-gate 20427c478bd9Sstevel@tonic-gate opterr = 0; 2043d62bc4baSyz147064 while ((option = getopt_long(argc, argv, ":L:l:P:R:tu:T:", lopts, 20447c478bd9Sstevel@tonic-gate NULL)) != -1) { 20457c478bd9Sstevel@tonic-gate switch (option) { 20467c478bd9Sstevel@tonic-gate case 'P': 2047f595a68aSyz147064 if (modify_mask & DLADM_AGGR_MODIFY_POLICY) 204833343a97Smeem die_optdup(option); 20497c478bd9Sstevel@tonic-gate 2050f595a68aSyz147064 modify_mask |= DLADM_AGGR_MODIFY_POLICY; 20517c478bd9Sstevel@tonic-gate 2052f595a68aSyz147064 if (!dladm_aggr_str2policy(optarg, &policy)) 205333343a97Smeem die("invalid policy '%s'", optarg); 20547c478bd9Sstevel@tonic-gate break; 20557c478bd9Sstevel@tonic-gate case 'u': 2056f595a68aSyz147064 if (modify_mask & DLADM_AGGR_MODIFY_MAC) 205733343a97Smeem die_optdup(option); 20587c478bd9Sstevel@tonic-gate 2059f595a68aSyz147064 modify_mask |= DLADM_AGGR_MODIFY_MAC; 20607c478bd9Sstevel@tonic-gate 2061f595a68aSyz147064 if (!dladm_aggr_str2macaddr(optarg, &mac_addr_fixed, 206233343a97Smeem mac_addr)) 206333343a97Smeem die("invalid MAC address '%s'", optarg); 20647c478bd9Sstevel@tonic-gate break; 20657c478bd9Sstevel@tonic-gate case 'l': 2066d62bc4baSyz147064 case 'L': 2067f595a68aSyz147064 if (modify_mask & DLADM_AGGR_MODIFY_LACP_MODE) 206833343a97Smeem die_optdup(option); 20697c478bd9Sstevel@tonic-gate 2070f595a68aSyz147064 modify_mask |= DLADM_AGGR_MODIFY_LACP_MODE; 20717c478bd9Sstevel@tonic-gate 2072f595a68aSyz147064 if (!dladm_aggr_str2lacpmode(optarg, &lacp_mode)) 207333343a97Smeem die("invalid LACP mode '%s'", optarg); 20747c478bd9Sstevel@tonic-gate break; 20757c478bd9Sstevel@tonic-gate case 'T': 2076f595a68aSyz147064 if (modify_mask & DLADM_AGGR_MODIFY_LACP_TIMER) 207733343a97Smeem die_optdup(option); 20787c478bd9Sstevel@tonic-gate 2079f595a68aSyz147064 modify_mask |= DLADM_AGGR_MODIFY_LACP_TIMER; 20807c478bd9Sstevel@tonic-gate 2081f595a68aSyz147064 if (!dladm_aggr_str2lacptimer(optarg, &lacp_timer)) 208233343a97Smeem die("invalid LACP timer value '%s'", optarg); 20837c478bd9Sstevel@tonic-gate break; 20847c478bd9Sstevel@tonic-gate case 't': 2085d62bc4baSyz147064 flags &= ~DLADM_OPT_PERSIST; 20867c478bd9Sstevel@tonic-gate break; 20877c478bd9Sstevel@tonic-gate case 'R': 20887c478bd9Sstevel@tonic-gate altroot = optarg; 20897c478bd9Sstevel@tonic-gate break; 20907c478bd9Sstevel@tonic-gate default: 20918d5c46e6Sam223141 die_opterr(optopt, option, use); 209233343a97Smeem break; 20937c478bd9Sstevel@tonic-gate } 20947c478bd9Sstevel@tonic-gate } 20957c478bd9Sstevel@tonic-gate 209633343a97Smeem if (modify_mask == 0) 209733343a97Smeem die("at least one of the -PulT options must be specified"); 20987c478bd9Sstevel@tonic-gate 2099d62bc4baSyz147064 /* get key value or the aggregation name (required last argument) */ 21007c478bd9Sstevel@tonic-gate if (optind != (argc-1)) 21017c478bd9Sstevel@tonic-gate usage(); 21027c478bd9Sstevel@tonic-gate 2103d62bc4baSyz147064 status = i_dladm_aggr_get_linkid(altroot, argv[optind], &linkid, flags); 2104d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 2105d62bc4baSyz147064 goto done; 21067c478bd9Sstevel@tonic-gate 2107d62bc4baSyz147064 if (altroot != NULL) 2108d62bc4baSyz147064 altroot_cmd(altroot, argc, argv); 2109d62bc4baSyz147064 21104ac67f02SAnurag S. Maskey status = dladm_aggr_modify(handle, linkid, modify_mask, policy, 21114ac67f02SAnurag S. Maskey mac_addr_fixed, (const uchar_t *)mac_addr, lacp_mode, lacp_timer, 21124ac67f02SAnurag S. Maskey flags); 2113d62bc4baSyz147064 2114d62bc4baSyz147064 done: 2115f595a68aSyz147064 if (status != DLADM_STATUS_OK) 2116f595a68aSyz147064 die_dlerr(status, "modify operation failed"); 21177c478bd9Sstevel@tonic-gate } 21187c478bd9Sstevel@tonic-gate 21198d5c46e6Sam223141 /*ARGSUSED*/ 21207c478bd9Sstevel@tonic-gate static void 21218d5c46e6Sam223141 do_up_aggr(int argc, char *argv[], const char *use) 21227c478bd9Sstevel@tonic-gate { 2123d62bc4baSyz147064 datalink_id_t linkid = DATALINK_ALL_LINKID; 2124f595a68aSyz147064 dladm_status_t status; 21257c478bd9Sstevel@tonic-gate 2126d62bc4baSyz147064 /* 2127d62bc4baSyz147064 * get the key or the name of the aggregation (optional last argument) 2128d62bc4baSyz147064 */ 21297c478bd9Sstevel@tonic-gate if (argc == 2) { 2130d62bc4baSyz147064 if ((status = i_dladm_aggr_get_linkid(NULL, argv[1], &linkid, 21314ac67f02SAnurag S. Maskey DLADM_OPT_PERSIST)) != DLADM_STATUS_OK) 2132d62bc4baSyz147064 goto done; 21337c478bd9Sstevel@tonic-gate } else if (argc > 2) { 21347c478bd9Sstevel@tonic-gate usage(); 21357c478bd9Sstevel@tonic-gate } 21367c478bd9Sstevel@tonic-gate 21374ac67f02SAnurag S. Maskey status = dladm_aggr_up(handle, linkid); 2138d62bc4baSyz147064 done: 2139d62bc4baSyz147064 if (status != DLADM_STATUS_OK) { 2140d62bc4baSyz147064 if (argc == 2) { 2141d62bc4baSyz147064 die_dlerr(status, 2142d62bc4baSyz147064 "could not bring up aggregation '%s'", argv[1]); 21437c478bd9Sstevel@tonic-gate } else { 2144f595a68aSyz147064 die_dlerr(status, "could not bring aggregations up"); 21457c478bd9Sstevel@tonic-gate } 21467c478bd9Sstevel@tonic-gate } 21477c478bd9Sstevel@tonic-gate } 21487c478bd9Sstevel@tonic-gate 21497c478bd9Sstevel@tonic-gate static void 21508d5c46e6Sam223141 do_create_vlan(int argc, char *argv[], const char *use) 21517c478bd9Sstevel@tonic-gate { 2152d62bc4baSyz147064 char *link = NULL; 2153d62bc4baSyz147064 char drv[DLPI_LINKNAME_MAX]; 2154d62bc4baSyz147064 uint_t ppa; 2155d62bc4baSyz147064 datalink_id_t linkid; 2156da14cebeSEric Cheng datalink_id_t dev_linkid; 2157d62bc4baSyz147064 int vid = 0; 2158b509e89bSRishi Srivatsavai int option; 2159d62bc4baSyz147064 uint32_t flags = (DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST); 2160d62bc4baSyz147064 char *altroot = NULL; 2161d62bc4baSyz147064 char vlan[MAXLINKNAMELEN]; 216263a6526dSMichael Lim char propstr[DLADM_STRSIZE]; 2163da14cebeSEric Cheng dladm_arg_list_t *proplist = NULL; 2164f595a68aSyz147064 dladm_status_t status; 21657c478bd9Sstevel@tonic-gate 2166d62bc4baSyz147064 opterr = 0; 216763a6526dSMichael Lim bzero(propstr, DLADM_STRSIZE); 216863a6526dSMichael Lim 2169da14cebeSEric Cheng while ((option = getopt_long(argc, argv, ":tfR:l:v:p:", 2170d62bc4baSyz147064 lopts, NULL)) != -1) { 2171d62bc4baSyz147064 switch (option) { 2172d62bc4baSyz147064 case 'v': 2173d62bc4baSyz147064 if (vid != 0) 2174d62bc4baSyz147064 die_optdup(option); 2175d62bc4baSyz147064 2176d62bc4baSyz147064 if (!str2int(optarg, &vid) || vid < 1 || vid > 4094) 2177d62bc4baSyz147064 die("invalid VLAN identifier '%s'", optarg); 2178d62bc4baSyz147064 2179d62bc4baSyz147064 break; 2180d62bc4baSyz147064 case 'l': 2181d62bc4baSyz147064 if (link != NULL) 2182d62bc4baSyz147064 die_optdup(option); 2183d62bc4baSyz147064 2184d62bc4baSyz147064 link = optarg; 2185d62bc4baSyz147064 break; 2186d62bc4baSyz147064 case 't': 2187d62bc4baSyz147064 flags &= ~DLADM_OPT_PERSIST; 2188d62bc4baSyz147064 break; 2189d62bc4baSyz147064 case 'R': 2190d62bc4baSyz147064 altroot = optarg; 2191d62bc4baSyz147064 break; 2192da14cebeSEric Cheng case 'p': 219363a6526dSMichael Lim (void) strlcat(propstr, optarg, DLADM_STRSIZE); 219463a6526dSMichael Lim if (strlcat(propstr, ",", DLADM_STRSIZE) >= 219563a6526dSMichael Lim DLADM_STRSIZE) 219663a6526dSMichael Lim die("property list too long '%s'", propstr); 2197da14cebeSEric Cheng break; 2198da14cebeSEric Cheng case 'f': 2199da14cebeSEric Cheng flags |= DLADM_OPT_FORCE; 2200da14cebeSEric Cheng break; 2201d62bc4baSyz147064 default: 22028d5c46e6Sam223141 die_opterr(optopt, option, use); 2203d62bc4baSyz147064 break; 2204d62bc4baSyz147064 } 2205d62bc4baSyz147064 } 2206d62bc4baSyz147064 2207d62bc4baSyz147064 /* get vlan name if there is any */ 2208d62bc4baSyz147064 if ((vid == 0) || (link == NULL) || (argc - optind > 1)) 22097c478bd9Sstevel@tonic-gate usage(); 2210d62bc4baSyz147064 2211d62bc4baSyz147064 if (optind == (argc - 1)) { 2212d62bc4baSyz147064 if (strlcpy(vlan, argv[optind], MAXLINKNAMELEN) >= 2213d62bc4baSyz147064 MAXLINKNAMELEN) { 2214d62bc4baSyz147064 die("vlan name too long '%s'", argv[optind]); 2215d62bc4baSyz147064 } 2216d62bc4baSyz147064 } else { 2217d62bc4baSyz147064 if ((dlpi_parselink(link, drv, &ppa) != DLPI_SUCCESS) || 2218d62bc4baSyz147064 (ppa >= 1000) || 2219d62bc4baSyz147064 (dlpi_makelink(vlan, drv, vid * 1000 + ppa) != 2220d62bc4baSyz147064 DLPI_SUCCESS)) { 2221d62bc4baSyz147064 die("invalid link name '%s'", link); 2222d62bc4baSyz147064 } 22237c478bd9Sstevel@tonic-gate } 22247c478bd9Sstevel@tonic-gate 2225d62bc4baSyz147064 if (altroot != NULL) 2226d62bc4baSyz147064 altroot_cmd(altroot, argc, argv); 2227d62bc4baSyz147064 22284ac67f02SAnurag S. Maskey if (dladm_name2info(handle, link, &dev_linkid, NULL, NULL, NULL) != 2229d62bc4baSyz147064 DLADM_STATUS_OK) { 2230d62bc4baSyz147064 die("invalid link name '%s'", link); 2231d62bc4baSyz147064 } 2232d62bc4baSyz147064 223363a6526dSMichael Lim if (dladm_parse_link_props(propstr, &proplist, B_FALSE) 223463a6526dSMichael Lim != DLADM_STATUS_OK) 223563a6526dSMichael Lim die("invalid vlan property"); 223663a6526dSMichael Lim 2237*4eaa4710SRishi Srivatsavai status = dladm_vlan_create(handle, vlan, dev_linkid, vid, proplist, 2238*4eaa4710SRishi Srivatsavai flags, &linkid); 2239*4eaa4710SRishi Srivatsavai switch (status) { 2240*4eaa4710SRishi Srivatsavai case DLADM_STATUS_OK: 2241*4eaa4710SRishi Srivatsavai break; 2242*4eaa4710SRishi Srivatsavai 2243*4eaa4710SRishi Srivatsavai case DLADM_STATUS_NOTSUP: 2244*4eaa4710SRishi Srivatsavai die("VLAN over '%s' may require lowered MTU; must use -f (see " 2245*4eaa4710SRishi Srivatsavai "dladm(1M))", link); 2246*4eaa4710SRishi Srivatsavai break; 2247*4eaa4710SRishi Srivatsavai 2248*4eaa4710SRishi Srivatsavai case DLADM_STATUS_LINKBUSY: 2249*4eaa4710SRishi Srivatsavai die("VLAN over '%s' may not use default_tag ID", link); 2250*4eaa4710SRishi Srivatsavai break; 2251*4eaa4710SRishi Srivatsavai 2252*4eaa4710SRishi Srivatsavai default: 2253*4eaa4710SRishi Srivatsavai die_dlerr(status, "create operation failed"); 2254d62bc4baSyz147064 } 2255d62bc4baSyz147064 } 2256d62bc4baSyz147064 2257d62bc4baSyz147064 static void 22588d5c46e6Sam223141 do_delete_vlan(int argc, char *argv[], const char *use) 2259d62bc4baSyz147064 { 2260b509e89bSRishi Srivatsavai int option; 2261d62bc4baSyz147064 uint32_t flags = (DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST); 2262d62bc4baSyz147064 char *altroot = NULL; 2263d62bc4baSyz147064 datalink_id_t linkid; 2264d62bc4baSyz147064 dladm_status_t status; 2265d62bc4baSyz147064 2266d62bc4baSyz147064 opterr = 0; 2267d62bc4baSyz147064 while ((option = getopt_long(argc, argv, ":R:t", lopts, NULL)) != -1) { 2268d62bc4baSyz147064 switch (option) { 2269d62bc4baSyz147064 case 't': 2270d62bc4baSyz147064 flags &= ~DLADM_OPT_PERSIST; 2271d62bc4baSyz147064 break; 2272d62bc4baSyz147064 case 'R': 2273d62bc4baSyz147064 altroot = optarg; 2274d62bc4baSyz147064 break; 2275d62bc4baSyz147064 default: 22768d5c46e6Sam223141 die_opterr(optopt, option, use); 2277d62bc4baSyz147064 break; 2278d62bc4baSyz147064 } 2279d62bc4baSyz147064 } 2280d62bc4baSyz147064 2281d62bc4baSyz147064 /* get VLAN link name (required last argument) */ 2282d62bc4baSyz147064 if (optind != (argc - 1)) 2283d62bc4baSyz147064 usage(); 2284d62bc4baSyz147064 2285d62bc4baSyz147064 if (altroot != NULL) 2286d62bc4baSyz147064 altroot_cmd(altroot, argc, argv); 2287d62bc4baSyz147064 22884ac67f02SAnurag S. Maskey status = dladm_name2info(handle, argv[optind], &linkid, NULL, NULL, 22894ac67f02SAnurag S. Maskey NULL); 2290d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 2291d62bc4baSyz147064 goto done; 2292d62bc4baSyz147064 22934ac67f02SAnurag S. Maskey status = dladm_vlan_delete(handle, linkid, flags); 2294d62bc4baSyz147064 done: 2295d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 2296d62bc4baSyz147064 die_dlerr(status, "delete operation failed"); 2297d62bc4baSyz147064 } 2298d62bc4baSyz147064 22998d5c46e6Sam223141 /*ARGSUSED*/ 2300d62bc4baSyz147064 static void 23018d5c46e6Sam223141 do_up_vlan(int argc, char *argv[], const char *use) 2302d62bc4baSyz147064 { 2303da14cebeSEric Cheng do_up_vnic_common(argc, argv, use, B_TRUE); 23047c478bd9Sstevel@tonic-gate } 23057c478bd9Sstevel@tonic-gate 2306210db224Sericheng static void 23078d5c46e6Sam223141 do_rename_link(int argc, char *argv[], const char *use) 2308210db224Sericheng { 2309b509e89bSRishi Srivatsavai int option; 2310d62bc4baSyz147064 char *link1, *link2; 2311d62bc4baSyz147064 char *altroot = NULL; 2312d62bc4baSyz147064 dladm_status_t status; 2313210db224Sericheng 2314d62bc4baSyz147064 opterr = 0; 2315d62bc4baSyz147064 while ((option = getopt_long(argc, argv, ":R:", lopts, NULL)) != -1) { 2316d62bc4baSyz147064 switch (option) { 2317d62bc4baSyz147064 case 'R': 2318d62bc4baSyz147064 altroot = optarg; 2319d62bc4baSyz147064 break; 2320d62bc4baSyz147064 default: 23218d5c46e6Sam223141 die_opterr(optopt, option, use); 2322d62bc4baSyz147064 break; 2323210db224Sericheng } 2324210db224Sericheng } 2325210db224Sericheng 2326d62bc4baSyz147064 /* get link1 and link2 name (required the last 2 arguments) */ 2327d62bc4baSyz147064 if (optind != (argc - 2)) 2328d62bc4baSyz147064 usage(); 2329d62bc4baSyz147064 2330d62bc4baSyz147064 if (altroot != NULL) 2331d62bc4baSyz147064 altroot_cmd(altroot, argc, argv); 2332d62bc4baSyz147064 2333d62bc4baSyz147064 link1 = argv[optind++]; 2334d62bc4baSyz147064 link2 = argv[optind]; 23354ac67f02SAnurag S. Maskey if ((status = dladm_rename_link(handle, link1, link2)) != 23364ac67f02SAnurag S. Maskey DLADM_STATUS_OK) 2337d62bc4baSyz147064 die_dlerr(status, "rename operation failed"); 2338d62bc4baSyz147064 } 2339d62bc4baSyz147064 23408d5c46e6Sam223141 /*ARGSUSED*/ 2341d62bc4baSyz147064 static void 23428d5c46e6Sam223141 do_delete_phys(int argc, char *argv[], const char *use) 2343d62bc4baSyz147064 { 2344d62bc4baSyz147064 datalink_id_t linkid = DATALINK_ALL_LINKID; 2345d62bc4baSyz147064 dladm_status_t status; 2346d62bc4baSyz147064 2347d62bc4baSyz147064 /* get link name (required the last argument) */ 2348d62bc4baSyz147064 if (argc > 2) 2349d62bc4baSyz147064 usage(); 2350d62bc4baSyz147064 2351d62bc4baSyz147064 if (argc == 2) { 23524ac67f02SAnurag S. Maskey if ((status = dladm_name2info(handle, argv[1], &linkid, NULL, 23534ac67f02SAnurag S. Maskey NULL, NULL)) != DLADM_STATUS_OK) 2354d62bc4baSyz147064 die_dlerr(status, "cannot delete '%s'", argv[1]); 2355d62bc4baSyz147064 } 2356d62bc4baSyz147064 23574ac67f02SAnurag S. Maskey if ((status = dladm_phys_delete(handle, linkid)) != DLADM_STATUS_OK) { 2358d62bc4baSyz147064 if (argc == 2) 2359d62bc4baSyz147064 die_dlerr(status, "cannot delete '%s'", argv[1]); 2360d62bc4baSyz147064 else 2361d62bc4baSyz147064 die_dlerr(status, "delete operation failed"); 2362d62bc4baSyz147064 } 2363d62bc4baSyz147064 } 2364d62bc4baSyz147064 2365d62bc4baSyz147064 /*ARGSUSED*/ 2366210db224Sericheng static int 23674ac67f02SAnurag S. Maskey i_dladm_walk_linkmap(dladm_handle_t dh, datalink_id_t linkid, void *arg) 2368210db224Sericheng { 2369d62bc4baSyz147064 char name[MAXLINKNAMELEN]; 2370d62bc4baSyz147064 char mediabuf[DLADM_STRSIZE]; 2371d62bc4baSyz147064 char classbuf[DLADM_STRSIZE]; 2372d62bc4baSyz147064 datalink_class_t class; 2373d62bc4baSyz147064 uint32_t media; 2374d62bc4baSyz147064 uint32_t flags; 2375210db224Sericheng 23764ac67f02SAnurag S. Maskey if (dladm_datalink_id2info(dh, linkid, &flags, &class, &media, name, 2377d62bc4baSyz147064 MAXLINKNAMELEN) == DLADM_STATUS_OK) { 2378d62bc4baSyz147064 (void) dladm_class2str(class, classbuf); 2379d62bc4baSyz147064 (void) dladm_media2str(media, mediabuf); 2380d62bc4baSyz147064 (void) printf("%-12s%8d %-12s%-20s %6d\n", name, 2381d62bc4baSyz147064 linkid, classbuf, mediabuf, flags); 2382210db224Sericheng } 2383d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 2384210db224Sericheng } 23857c478bd9Sstevel@tonic-gate 23867c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 23877c478bd9Sstevel@tonic-gate static void 23888d5c46e6Sam223141 do_show_linkmap(int argc, char *argv[], const char *use) 23897c478bd9Sstevel@tonic-gate { 2390d62bc4baSyz147064 if (argc != 1) 2391d62bc4baSyz147064 die("invalid arguments"); 23927c478bd9Sstevel@tonic-gate 2393d62bc4baSyz147064 (void) printf("%-12s%8s %-12s%-20s %6s\n", "NAME", "LINKID", 2394d62bc4baSyz147064 "CLASS", "MEDIA", "FLAGS"); 23954ac67f02SAnurag S. Maskey 23964ac67f02SAnurag S. Maskey (void) dladm_walk_datalink_id(i_dladm_walk_linkmap, handle, NULL, 2397d62bc4baSyz147064 DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE, 2398d62bc4baSyz147064 DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST); 23997c478bd9Sstevel@tonic-gate } 2400d62bc4baSyz147064 2401d62bc4baSyz147064 /* 2402d62bc4baSyz147064 * Delete inactive physical links. 2403d62bc4baSyz147064 */ 2404d62bc4baSyz147064 /*ARGSUSED*/ 2405d62bc4baSyz147064 static int 24064ac67f02SAnurag S. Maskey purge_phys(dladm_handle_t dh, datalink_id_t linkid, void *arg) 2407d62bc4baSyz147064 { 2408d62bc4baSyz147064 datalink_class_t class; 2409d62bc4baSyz147064 uint32_t flags; 2410d62bc4baSyz147064 24114ac67f02SAnurag S. Maskey if (dladm_datalink_id2info(dh, linkid, &flags, &class, NULL, NULL, 0) 24124ac67f02SAnurag S. Maskey != DLADM_STATUS_OK) { 2413d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 2414d62bc4baSyz147064 } 2415d62bc4baSyz147064 2416d62bc4baSyz147064 if (class == DATALINK_CLASS_PHYS && !(flags & DLADM_OPT_ACTIVE)) 24174ac67f02SAnurag S. Maskey (void) dladm_phys_delete(dh, linkid); 2418d62bc4baSyz147064 2419d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 2420d62bc4baSyz147064 } 2421d62bc4baSyz147064 2422d62bc4baSyz147064 /*ARGSUSED*/ 2423d62bc4baSyz147064 static void 24248d5c46e6Sam223141 do_init_phys(int argc, char *argv[], const char *use) 2425d62bc4baSyz147064 { 2426d62bc4baSyz147064 di_node_t devtree; 2427d62bc4baSyz147064 2428d62bc4baSyz147064 if (argc > 1) 2429d62bc4baSyz147064 usage(); 2430d62bc4baSyz147064 2431d62bc4baSyz147064 /* 2432d62bc4baSyz147064 * Force all the devices to attach, therefore all the network physical 2433d62bc4baSyz147064 * devices can be known to the dlmgmtd daemon. 2434d62bc4baSyz147064 */ 2435d62bc4baSyz147064 if ((devtree = di_init("/", DINFOFORCE | DINFOSUBTREE)) != DI_NODE_NIL) 2436d62bc4baSyz147064 di_fini(devtree); 2437d62bc4baSyz147064 24384ac67f02SAnurag S. Maskey (void) dladm_walk_datalink_id(purge_phys, handle, NULL, 2439d62bc4baSyz147064 DATALINK_CLASS_PHYS, DATALINK_ANY_MEDIATYPE, DLADM_OPT_PERSIST); 24407c478bd9Sstevel@tonic-gate } 24417c478bd9Sstevel@tonic-gate 2442d62bc4baSyz147064 2443d62bc4baSyz147064 /* 2444d62bc4baSyz147064 * Print the active topology information. 2445d62bc4baSyz147064 */ 2446d62bc4baSyz147064 static dladm_status_t 2447d62bc4baSyz147064 print_link_topology(show_state_t *state, datalink_id_t linkid, 2448e7801d59Ssowmini datalink_class_t class, link_fields_buf_t *lbuf) 2449d62bc4baSyz147064 { 2450d62bc4baSyz147064 uint32_t flags = state->ls_flags; 2451*4eaa4710SRishi Srivatsavai dladm_status_t status; 24526b9e797cSsowmini char tmpbuf[MAXLINKNAMELEN]; 2453d62bc4baSyz147064 2454b509e89bSRishi Srivatsavai lbuf->link_over[0] = '\0'; 2455*4eaa4710SRishi Srivatsavai lbuf->link_bridge[0] = '\0'; 2456b509e89bSRishi Srivatsavai 2457b509e89bSRishi Srivatsavai switch (class) { 2458*4eaa4710SRishi Srivatsavai case DATALINK_CLASS_AGGR: 2459*4eaa4710SRishi Srivatsavai case DATALINK_CLASS_PHYS: 2460*4eaa4710SRishi Srivatsavai case DATALINK_CLASS_ETHERSTUB: 2461*4eaa4710SRishi Srivatsavai status = dladm_bridge_getlink(handle, linkid, lbuf->link_bridge, 2462*4eaa4710SRishi Srivatsavai sizeof (lbuf->link_bridge)); 2463*4eaa4710SRishi Srivatsavai if (status == DLADM_STATUS_OK) 2464*4eaa4710SRishi Srivatsavai break; 2465*4eaa4710SRishi Srivatsavai if (status != DLADM_STATUS_NOTFOUND) 2466*4eaa4710SRishi Srivatsavai return (status); 2467*4eaa4710SRishi Srivatsavai break; 2468*4eaa4710SRishi Srivatsavai } 2469*4eaa4710SRishi Srivatsavai 2470*4eaa4710SRishi Srivatsavai status = DLADM_STATUS_OK; 2471*4eaa4710SRishi Srivatsavai switch (class) { 2472b509e89bSRishi Srivatsavai case DATALINK_CLASS_VLAN: { 2473d62bc4baSyz147064 dladm_vlan_attr_t vinfo; 2474d62bc4baSyz147064 24754ac67f02SAnurag S. Maskey status = dladm_vlan_info(handle, linkid, &vinfo, flags); 2476d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 2477b509e89bSRishi Srivatsavai break; 24784ac67f02SAnurag S. Maskey status = dladm_datalink_id2info(handle, vinfo.dv_linkid, NULL, 24794ac67f02SAnurag S. Maskey NULL, NULL, lbuf->link_over, sizeof (lbuf->link_over)); 2480b509e89bSRishi Srivatsavai break; 2481b509e89bSRishi Srivatsavai } 2482b509e89bSRishi Srivatsavai 2483b509e89bSRishi Srivatsavai case DATALINK_CLASS_AGGR: { 2484d62bc4baSyz147064 dladm_aggr_grp_attr_t ginfo; 2485d62bc4baSyz147064 int i; 2486d62bc4baSyz147064 2487*4eaa4710SRishi Srivatsavai lbuf->link_over[0] = '\0'; 2488*4eaa4710SRishi Srivatsavai 24894ac67f02SAnurag S. Maskey status = dladm_aggr_info(handle, linkid, &ginfo, flags); 2490d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 2491b509e89bSRishi Srivatsavai break; 2492d62bc4baSyz147064 2493d62bc4baSyz147064 if (ginfo.lg_nports == 0) { 2494d62bc4baSyz147064 status = DLADM_STATUS_BADVAL; 2495b509e89bSRishi Srivatsavai break; 2496d62bc4baSyz147064 } 2497d62bc4baSyz147064 for (i = 0; i < ginfo.lg_nports; i++) { 24984ac67f02SAnurag S. Maskey status = dladm_datalink_id2info(handle, 2499e7801d59Ssowmini ginfo.lg_ports[i].lp_linkid, NULL, NULL, NULL, 25006b9e797cSsowmini tmpbuf, sizeof (tmpbuf)); 2501*4eaa4710SRishi Srivatsavai if (status != DLADM_STATUS_OK) 2502b509e89bSRishi Srivatsavai break; 25036b9e797cSsowmini (void) strlcat(lbuf->link_over, tmpbuf, 25046b9e797cSsowmini sizeof (lbuf->link_over)); 25056b9e797cSsowmini if (i != (ginfo.lg_nports - 1)) { 25066b9e797cSsowmini (void) strlcat(lbuf->link_over, " ", 25076b9e797cSsowmini sizeof (lbuf->link_over)); 25086b9e797cSsowmini } 2509d62bc4baSyz147064 } 2510d62bc4baSyz147064 free(ginfo.lg_ports); 2511b509e89bSRishi Srivatsavai break; 2512b509e89bSRishi Srivatsavai } 2513b509e89bSRishi Srivatsavai 2514b509e89bSRishi Srivatsavai case DATALINK_CLASS_VNIC: { 2515da14cebeSEric Cheng dladm_vnic_attr_t vinfo; 2516d62bc4baSyz147064 2517b509e89bSRishi Srivatsavai status = dladm_vnic_info(handle, linkid, &vinfo, flags); 2518b509e89bSRishi Srivatsavai if (status == DLADM_STATUS_OK) 2519b509e89bSRishi Srivatsavai status = dladm_datalink_id2info(handle, 2520b509e89bSRishi Srivatsavai vinfo.va_link_id, NULL, NULL, NULL, lbuf->link_over, 2521b509e89bSRishi Srivatsavai sizeof (lbuf->link_over)); 2522b509e89bSRishi Srivatsavai break; 2523b509e89bSRishi Srivatsavai } 2524b509e89bSRishi Srivatsavai 2525*4eaa4710SRishi Srivatsavai case DATALINK_CLASS_BRIDGE: { 2526*4eaa4710SRishi Srivatsavai datalink_id_t *dlp; 2527*4eaa4710SRishi Srivatsavai uint_t i, nports; 2528*4eaa4710SRishi Srivatsavai 2529*4eaa4710SRishi Srivatsavai status = dladm_datalink_id2info(handle, linkid, NULL, NULL, 2530*4eaa4710SRishi Srivatsavai NULL, tmpbuf, sizeof (tmpbuf)); 2531*4eaa4710SRishi Srivatsavai if (status != DLADM_STATUS_OK) 2532*4eaa4710SRishi Srivatsavai break; 2533*4eaa4710SRishi Srivatsavai if (tmpbuf[0] != '\0') 2534*4eaa4710SRishi Srivatsavai tmpbuf[strlen(tmpbuf) - 1] = '\0'; 2535*4eaa4710SRishi Srivatsavai dlp = dladm_bridge_get_portlist(tmpbuf, &nports); 2536*4eaa4710SRishi Srivatsavai if (dlp == NULL) { 2537*4eaa4710SRishi Srivatsavai status = DLADM_STATUS_BADVAL; 2538*4eaa4710SRishi Srivatsavai break; 2539*4eaa4710SRishi Srivatsavai } 2540*4eaa4710SRishi Srivatsavai lbuf->link_over[0] = '\0'; 2541*4eaa4710SRishi Srivatsavai for (i = 0; i < nports; i++) { 2542*4eaa4710SRishi Srivatsavai status = dladm_datalink_id2info(handle, dlp[i], NULL, 2543*4eaa4710SRishi Srivatsavai NULL, NULL, tmpbuf, sizeof (tmpbuf)); 2544*4eaa4710SRishi Srivatsavai if (status != DLADM_STATUS_OK) 2545*4eaa4710SRishi Srivatsavai break; 2546*4eaa4710SRishi Srivatsavai (void) strlcat(lbuf->link_over, tmpbuf, 2547*4eaa4710SRishi Srivatsavai sizeof (lbuf->link_over)); 2548*4eaa4710SRishi Srivatsavai if (i != nports - 1) { 2549*4eaa4710SRishi Srivatsavai (void) strlcat(lbuf->link_over, " ", 2550*4eaa4710SRishi Srivatsavai sizeof (lbuf->link_over)); 2551*4eaa4710SRishi Srivatsavai } 2552*4eaa4710SRishi Srivatsavai } 2553*4eaa4710SRishi Srivatsavai dladm_bridge_free_portlist(dlp); 2554*4eaa4710SRishi Srivatsavai break; 2555*4eaa4710SRishi Srivatsavai } 2556*4eaa4710SRishi Srivatsavai 2557b509e89bSRishi Srivatsavai case DATALINK_CLASS_SIMNET: { 2558b509e89bSRishi Srivatsavai dladm_simnet_attr_t slinfo; 2559b509e89bSRishi Srivatsavai 2560b509e89bSRishi Srivatsavai status = dladm_simnet_info(handle, linkid, &slinfo, flags); 2561b509e89bSRishi Srivatsavai if (status == DLADM_STATUS_OK && 2562b509e89bSRishi Srivatsavai slinfo.sna_peer_link_id != DATALINK_INVALID_LINKID) 2563b509e89bSRishi Srivatsavai status = dladm_datalink_id2info(handle, 2564b509e89bSRishi Srivatsavai slinfo.sna_peer_link_id, NULL, NULL, NULL, 2565b509e89bSRishi Srivatsavai lbuf->link_over, sizeof (lbuf->link_over)); 2566b509e89bSRishi Srivatsavai break; 2567d62bc4baSyz147064 } 2568d62bc4baSyz147064 } 2569b509e89bSRishi Srivatsavai 2570d62bc4baSyz147064 return (status); 2571d62bc4baSyz147064 } 2572d62bc4baSyz147064 2573d62bc4baSyz147064 static dladm_status_t 2574e7801d59Ssowmini print_link(show_state_t *state, datalink_id_t linkid, link_fields_buf_t *lbuf) 2575d62bc4baSyz147064 { 2576d62bc4baSyz147064 char link[MAXLINKNAMELEN]; 2577d62bc4baSyz147064 datalink_class_t class; 2578d62bc4baSyz147064 uint_t mtu; 2579d62bc4baSyz147064 uint32_t flags; 2580d62bc4baSyz147064 dladm_status_t status; 2581d62bc4baSyz147064 25824ac67f02SAnurag S. Maskey if ((status = dladm_datalink_id2info(handle, linkid, &flags, &class, 25834ac67f02SAnurag S. Maskey NULL, link, sizeof (link))) != DLADM_STATUS_OK) { 2584d62bc4baSyz147064 goto done; 2585d62bc4baSyz147064 } 2586d62bc4baSyz147064 2587d62bc4baSyz147064 if (!(state->ls_flags & flags)) { 2588d62bc4baSyz147064 status = DLADM_STATUS_NOTFOUND; 2589d62bc4baSyz147064 goto done; 2590d62bc4baSyz147064 } 2591d62bc4baSyz147064 2592d62bc4baSyz147064 if (state->ls_flags == DLADM_OPT_ACTIVE) { 2593d62bc4baSyz147064 dladm_attr_t dlattr; 2594d62bc4baSyz147064 2595d62bc4baSyz147064 if (class == DATALINK_CLASS_PHYS) { 2596d62bc4baSyz147064 dladm_phys_attr_t dpa; 2597d62bc4baSyz147064 dlpi_handle_t dh; 2598d62bc4baSyz147064 dlpi_info_t dlinfo; 2599d62bc4baSyz147064 26004ac67f02SAnurag S. Maskey if ((status = dladm_phys_info(handle, linkid, &dpa, 2601d62bc4baSyz147064 DLADM_OPT_ACTIVE)) != DLADM_STATUS_OK) { 2602d62bc4baSyz147064 goto done; 2603d62bc4baSyz147064 } 2604d62bc4baSyz147064 2605d62bc4baSyz147064 if (!dpa.dp_novanity) 2606d62bc4baSyz147064 goto link_mtu; 2607d62bc4baSyz147064 2608d62bc4baSyz147064 /* 2609d62bc4baSyz147064 * This is a physical link that does not have 2610d62bc4baSyz147064 * vanity naming support. 2611d62bc4baSyz147064 */ 2612d62bc4baSyz147064 if (dlpi_open(dpa.dp_dev, &dh, DLPI_DEVONLY) != 2613d62bc4baSyz147064 DLPI_SUCCESS) { 2614d62bc4baSyz147064 status = DLADM_STATUS_NOTFOUND; 2615d62bc4baSyz147064 goto done; 2616d62bc4baSyz147064 } 2617d62bc4baSyz147064 2618d62bc4baSyz147064 if (dlpi_info(dh, &dlinfo, 0) != DLPI_SUCCESS) { 2619d62bc4baSyz147064 dlpi_close(dh); 2620d62bc4baSyz147064 status = DLADM_STATUS_BADARG; 2621d62bc4baSyz147064 goto done; 2622d62bc4baSyz147064 } 2623d62bc4baSyz147064 2624d62bc4baSyz147064 dlpi_close(dh); 2625d62bc4baSyz147064 mtu = dlinfo.di_max_sdu; 2626d62bc4baSyz147064 } else { 2627d62bc4baSyz147064 link_mtu: 26284ac67f02SAnurag S. Maskey status = dladm_info(handle, linkid, &dlattr); 2629d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 2630d62bc4baSyz147064 goto done; 2631d62bc4baSyz147064 mtu = dlattr.da_max_sdu; 2632d62bc4baSyz147064 } 2633d62bc4baSyz147064 } 2634d62bc4baSyz147064 2635e7801d59Ssowmini (void) snprintf(lbuf->link_name, sizeof (lbuf->link_name), 2636e7801d59Ssowmini "%s", link); 2637e7801d59Ssowmini (void) dladm_class2str(class, lbuf->link_class); 2638d62bc4baSyz147064 if (state->ls_flags == DLADM_OPT_ACTIVE) { 2639e7801d59Ssowmini (void) snprintf(lbuf->link_mtu, sizeof (lbuf->link_mtu), 2640c08e5e1aSdr146992 "%u", mtu); 2641e7801d59Ssowmini (void) get_linkstate(link, B_TRUE, lbuf->link_state); 2642d62bc4baSyz147064 } 2643d62bc4baSyz147064 2644e7801d59Ssowmini status = print_link_topology(state, linkid, class, lbuf); 2645d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 2646d62bc4baSyz147064 goto done; 2647d62bc4baSyz147064 2648d62bc4baSyz147064 done: 2649d62bc4baSyz147064 return (status); 2650d62bc4baSyz147064 } 2651d62bc4baSyz147064 26524ac67f02SAnurag S. Maskey /* ARGSUSED */ 2653d62bc4baSyz147064 static int 26544ac67f02SAnurag S. Maskey show_link(dladm_handle_t dh, datalink_id_t linkid, void *arg) 2655d62bc4baSyz147064 { 2656e7801d59Ssowmini show_state_t *state = (show_state_t *)arg; 2657d62bc4baSyz147064 dladm_status_t status; 2658e7801d59Ssowmini link_fields_buf_t lbuf; 2659d62bc4baSyz147064 2660e7801d59Ssowmini /* 2661e7801d59Ssowmini * first get all the link attributes into lbuf; 2662e7801d59Ssowmini */ 26635f5c9f54SAnurag S. Maskey bzero(&lbuf, sizeof (link_fields_buf_t)); 2664e7801d59Ssowmini status = print_link(state, linkid, &lbuf); 2665e7801d59Ssowmini 2666d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 2667d62bc4baSyz147064 goto done; 2668e7801d59Ssowmini 26698002d411SSowmini Varadhan ofmt_print(state->ls_ofmt, &lbuf); 2670d62bc4baSyz147064 2671d62bc4baSyz147064 done: 2672d62bc4baSyz147064 state->ls_status = status; 2673d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 2674d62bc4baSyz147064 } 2675d62bc4baSyz147064 26768002d411SSowmini Varadhan static boolean_t 26778002d411SSowmini Varadhan print_link_stats_cb(ofmt_arg_t *ofarg, char *buf, uint_t bufsize) 2678ae6aa22aSVenugopal Iyer { 26798002d411SSowmini Varadhan link_args_t *largs = ofarg->ofmt_cbarg; 2680ae6aa22aSVenugopal Iyer pktsum_t *diff_stats = largs->link_s_psum; 2681ae6aa22aSVenugopal Iyer 26828002d411SSowmini Varadhan switch (ofarg->ofmt_id) { 2683ae6aa22aSVenugopal Iyer case LINK_S_LINK: 26848002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%s", largs->link_s_link); 2685ae6aa22aSVenugopal Iyer break; 2686ae6aa22aSVenugopal Iyer case LINK_S_IPKTS: 26878002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%llu", diff_stats->ipackets); 2688ae6aa22aSVenugopal Iyer break; 2689ae6aa22aSVenugopal Iyer case LINK_S_RBYTES: 26908002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%llu", diff_stats->rbytes); 2691ae6aa22aSVenugopal Iyer break; 2692ae6aa22aSVenugopal Iyer case LINK_S_IERRORS: 26938002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%u", diff_stats->ierrors); 2694ae6aa22aSVenugopal Iyer break; 2695ae6aa22aSVenugopal Iyer case LINK_S_OPKTS: 26968002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%llu", diff_stats->opackets); 2697ae6aa22aSVenugopal Iyer break; 2698ae6aa22aSVenugopal Iyer case LINK_S_OBYTES: 26998002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%llu", diff_stats->obytes); 2700ae6aa22aSVenugopal Iyer break; 2701ae6aa22aSVenugopal Iyer case LINK_S_OERRORS: 27028002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%u", diff_stats->oerrors); 2703ae6aa22aSVenugopal Iyer break; 2704ae6aa22aSVenugopal Iyer default: 2705ae6aa22aSVenugopal Iyer die("invalid input"); 2706ae6aa22aSVenugopal Iyer break; 2707ae6aa22aSVenugopal Iyer } 27088002d411SSowmini Varadhan return (B_TRUE); 2709ae6aa22aSVenugopal Iyer } 2710ae6aa22aSVenugopal Iyer 2711d62bc4baSyz147064 static int 27124ac67f02SAnurag S. Maskey show_link_stats(dladm_handle_t dh, datalink_id_t linkid, void *arg) 2713d62bc4baSyz147064 { 2714e7801d59Ssowmini char link[DLPI_LINKNAME_MAX]; 2715d62bc4baSyz147064 datalink_class_t class; 2716e7801d59Ssowmini show_state_t *state = (show_state_t *)arg; 27177c478bd9Sstevel@tonic-gate pktsum_t stats, diff_stats; 2718d62bc4baSyz147064 dladm_phys_attr_t dpa; 2719ae6aa22aSVenugopal Iyer link_args_t largs; 27207c478bd9Sstevel@tonic-gate 27217c478bd9Sstevel@tonic-gate if (state->ls_firstonly) { 27227c478bd9Sstevel@tonic-gate if (state->ls_donefirst) 2723d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 27247c478bd9Sstevel@tonic-gate state->ls_donefirst = B_TRUE; 27257c478bd9Sstevel@tonic-gate } else { 27267c478bd9Sstevel@tonic-gate bzero(&state->ls_prevstats, sizeof (state->ls_prevstats)); 27277c478bd9Sstevel@tonic-gate } 27287c478bd9Sstevel@tonic-gate 27294ac67f02SAnurag S. Maskey if (dladm_datalink_id2info(dh, linkid, NULL, &class, NULL, link, 2730e7801d59Ssowmini DLPI_LINKNAME_MAX) != DLADM_STATUS_OK) { 2731d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 2732d62bc4baSyz147064 } 2733d62bc4baSyz147064 2734d62bc4baSyz147064 if (class == DATALINK_CLASS_PHYS) { 27354ac67f02SAnurag S. Maskey if (dladm_phys_info(dh, linkid, &dpa, DLADM_OPT_ACTIVE) != 2736d62bc4baSyz147064 DLADM_STATUS_OK) { 2737d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 2738d62bc4baSyz147064 } 2739d62bc4baSyz147064 if (dpa.dp_novanity) 2740d62bc4baSyz147064 get_mac_stats(dpa.dp_dev, &stats); 2741d62bc4baSyz147064 else 2742d62bc4baSyz147064 get_link_stats(link, &stats); 2743d62bc4baSyz147064 } else { 2744d62bc4baSyz147064 get_link_stats(link, &stats); 2745d62bc4baSyz147064 } 2746da14cebeSEric Cheng dladm_stats_diff(&diff_stats, &stats, &state->ls_prevstats); 27477c478bd9Sstevel@tonic-gate 2748ae6aa22aSVenugopal Iyer largs.link_s_link = link; 2749ae6aa22aSVenugopal Iyer largs.link_s_psum = &diff_stats; 27508002d411SSowmini Varadhan ofmt_print(state->ls_ofmt, &largs); 27517c478bd9Sstevel@tonic-gate 27527c478bd9Sstevel@tonic-gate state->ls_prevstats = stats; 2753d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 27547c478bd9Sstevel@tonic-gate } 27557c478bd9Sstevel@tonic-gate 2756d62bc4baSyz147064 2757d62bc4baSyz147064 static dladm_status_t 2758d62bc4baSyz147064 print_aggr_info(show_grp_state_t *state, const char *link, 2759e7801d59Ssowmini dladm_aggr_grp_attr_t *ginfop) 2760d62bc4baSyz147064 { 2761d62bc4baSyz147064 char addr_str[ETHERADDRL * 3]; 2762e7801d59Ssowmini laggr_fields_buf_t lbuf; 2763d62bc4baSyz147064 2764e7801d59Ssowmini (void) snprintf(lbuf.laggr_name, sizeof (lbuf.laggr_name), 2765e7801d59Ssowmini "%s", link); 2766e7801d59Ssowmini 2767e7801d59Ssowmini (void) dladm_aggr_policy2str(ginfop->lg_policy, 2768e7801d59Ssowmini lbuf.laggr_policy); 2769d62bc4baSyz147064 2770d62bc4baSyz147064 if (ginfop->lg_mac_fixed) { 2771d62bc4baSyz147064 (void) dladm_aggr_macaddr2str(ginfop->lg_mac, addr_str); 2772e7801d59Ssowmini (void) snprintf(lbuf.laggr_addrpolicy, 2773e7801d59Ssowmini sizeof (lbuf.laggr_addrpolicy), "fixed (%s)", addr_str); 2774d62bc4baSyz147064 } else { 2775e7801d59Ssowmini (void) snprintf(lbuf.laggr_addrpolicy, 2776e7801d59Ssowmini sizeof (lbuf.laggr_addrpolicy), "auto"); 2777d62bc4baSyz147064 } 2778d62bc4baSyz147064 2779d62bc4baSyz147064 2780e7801d59Ssowmini (void) dladm_aggr_lacpmode2str(ginfop->lg_lacp_mode, 2781e7801d59Ssowmini lbuf.laggr_lacpactivity); 2782e7801d59Ssowmini (void) dladm_aggr_lacptimer2str(ginfop->lg_lacp_timer, 2783e7801d59Ssowmini lbuf.laggr_lacptimer); 2784e7801d59Ssowmini (void) snprintf(lbuf.laggr_flags, sizeof (lbuf.laggr_flags), "%c----", 2785d62bc4baSyz147064 ginfop->lg_force ? 'f' : '-'); 2786e7801d59Ssowmini 27878002d411SSowmini Varadhan ofmt_print(state->gs_ofmt, &lbuf); 2788e7801d59Ssowmini 2789d62bc4baSyz147064 return (DLADM_STATUS_OK); 2790d62bc4baSyz147064 } 2791d62bc4baSyz147064 27928002d411SSowmini Varadhan static boolean_t 27938002d411SSowmini Varadhan print_xaggr_cb(ofmt_arg_t *ofarg, char *buf, uint_t bufsize) 2794d62bc4baSyz147064 { 27958002d411SSowmini Varadhan const laggr_args_t *l = ofarg->ofmt_cbarg; 2796e7801d59Ssowmini int portnum; 2797e7801d59Ssowmini boolean_t is_port = (l->laggr_lport >= 0); 27988002d411SSowmini Varadhan static char tmpbuf[DLADM_STRSIZE]; 2799e7801d59Ssowmini dladm_aggr_port_attr_t *portp; 2800d62bc4baSyz147064 dladm_phys_attr_t dpa; 28018002d411SSowmini Varadhan dladm_status_t *stat, status = DLADM_STATUS_OK; 2802d62bc4baSyz147064 2803e7801d59Ssowmini stat = l->laggr_status; 2804d62bc4baSyz147064 2805e7801d59Ssowmini if (is_port) { 2806e7801d59Ssowmini portnum = l->laggr_lport; 2807e7801d59Ssowmini portp = &(l->laggr_ginfop->lg_ports[portnum]); 28084ac67f02SAnurag S. Maskey if ((status = dladm_datalink_id2info(handle, 28098002d411SSowmini Varadhan portp->lp_linkid, NULL, NULL, NULL, buf, bufsize)) != 2810e7801d59Ssowmini DLADM_STATUS_OK) { 2811e7801d59Ssowmini goto err; 2812d62bc4baSyz147064 } 28134ac67f02SAnurag S. Maskey 28144ac67f02SAnurag S. Maskey if ((status = dladm_phys_info(handle, portp->lp_linkid, 28154ac67f02SAnurag S. Maskey &dpa, DLADM_OPT_ACTIVE)) != DLADM_STATUS_OK) { 2816e7801d59Ssowmini goto err; 2817e7801d59Ssowmini } 2818d62bc4baSyz147064 } 2819d62bc4baSyz147064 28208002d411SSowmini Varadhan switch (ofarg->ofmt_id) { 2821e7801d59Ssowmini case AGGR_X_LINK: 28228002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%s", 28238002d411SSowmini Varadhan (is_port && !l->laggr_parsable ? " " : l->laggr_link)); 2824e7801d59Ssowmini break; 2825e7801d59Ssowmini case AGGR_X_PORT: 2826e7801d59Ssowmini if (is_port) 2827e7801d59Ssowmini break; 28288002d411SSowmini Varadhan *stat = DLADM_STATUS_OK; 28298002d411SSowmini Varadhan return (B_TRUE); 2830d62bc4baSyz147064 2831e7801d59Ssowmini case AGGR_X_SPEED: 2832e7801d59Ssowmini if (is_port) { 28338002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%uMb", 2834e7801d59Ssowmini (uint_t)((get_ifspeed(dpa.dp_dev, 2835e7801d59Ssowmini B_FALSE)) / 1000000ull)); 2836e7801d59Ssowmini } else { 28378002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%uMb", 2838e7801d59Ssowmini (uint_t)((get_ifspeed(l->laggr_link, 2839e7801d59Ssowmini B_TRUE)) / 1000000ull)); 2840e7801d59Ssowmini } 2841e7801d59Ssowmini break; 2842e7801d59Ssowmini 2843e7801d59Ssowmini case AGGR_X_DUPLEX: 2844e7801d59Ssowmini if (is_port) 28458002d411SSowmini Varadhan (void) get_linkduplex(dpa.dp_dev, B_FALSE, tmpbuf); 2846d62bc4baSyz147064 else 28478002d411SSowmini Varadhan (void) get_linkduplex(l->laggr_link, B_TRUE, tmpbuf); 28488002d411SSowmini Varadhan (void) strlcpy(buf, tmpbuf, bufsize); 2849e7801d59Ssowmini break; 2850d62bc4baSyz147064 2851e7801d59Ssowmini case AGGR_X_STATE: 28521a1811a0Svs226613 if (is_port) 28538002d411SSowmini Varadhan (void) get_linkstate(dpa.dp_dev, B_FALSE, tmpbuf); 28541a1811a0Svs226613 else 28558002d411SSowmini Varadhan (void) get_linkstate(l->laggr_link, B_TRUE, tmpbuf); 28568002d411SSowmini Varadhan (void) strlcpy(buf, tmpbuf, bufsize); 2857e7801d59Ssowmini break; 2858e7801d59Ssowmini case AGGR_X_ADDRESS: 2859e7801d59Ssowmini (void) dladm_aggr_macaddr2str( 2860e7801d59Ssowmini (is_port ? portp->lp_mac : l->laggr_ginfop->lg_mac), 28618002d411SSowmini Varadhan tmpbuf); 28628002d411SSowmini Varadhan (void) strlcpy(buf, tmpbuf, bufsize); 2863e7801d59Ssowmini break; 2864e7801d59Ssowmini case AGGR_X_PORTSTATE: 28658002d411SSowmini Varadhan if (is_port) { 28668002d411SSowmini Varadhan (void) dladm_aggr_portstate2str(portp->lp_state, 28678002d411SSowmini Varadhan tmpbuf); 28688002d411SSowmini Varadhan (void) strlcpy(buf, tmpbuf, bufsize); 28698002d411SSowmini Varadhan } 2870e7801d59Ssowmini break; 2871e7801d59Ssowmini } 2872e7801d59Ssowmini err: 2873e7801d59Ssowmini *stat = status; 28748002d411SSowmini Varadhan return (B_TRUE); 2875e7801d59Ssowmini } 2876e7801d59Ssowmini 2877e7801d59Ssowmini static dladm_status_t 2878e7801d59Ssowmini print_aggr_extended(show_grp_state_t *state, const char *link, 2879e7801d59Ssowmini dladm_aggr_grp_attr_t *ginfop) 2880e7801d59Ssowmini { 2881e7801d59Ssowmini int i; 2882e7801d59Ssowmini dladm_status_t status; 2883e7801d59Ssowmini laggr_args_t largs; 2884e7801d59Ssowmini 2885e7801d59Ssowmini largs.laggr_lport = -1; 2886e7801d59Ssowmini largs.laggr_link = link; 2887e7801d59Ssowmini largs.laggr_ginfop = ginfop; 2888e7801d59Ssowmini largs.laggr_status = &status; 28898002d411SSowmini Varadhan largs.laggr_parsable = state->gs_parsable; 2890e7801d59Ssowmini 28918002d411SSowmini Varadhan ofmt_print(state->gs_ofmt, &largs); 2892e7801d59Ssowmini 2893e7801d59Ssowmini if (status != DLADM_STATUS_OK) 2894e7801d59Ssowmini goto done; 2895e7801d59Ssowmini 2896e7801d59Ssowmini for (i = 0; i < ginfop->lg_nports; i++) { 2897e7801d59Ssowmini largs.laggr_lport = i; 28988002d411SSowmini Varadhan ofmt_print(state->gs_ofmt, &largs); 2899e7801d59Ssowmini if (status != DLADM_STATUS_OK) 2900e7801d59Ssowmini goto done; 2901d62bc4baSyz147064 } 2902d62bc4baSyz147064 2903d62bc4baSyz147064 status = DLADM_STATUS_OK; 2904d62bc4baSyz147064 done: 2905d62bc4baSyz147064 return (status); 2906d62bc4baSyz147064 } 2907d62bc4baSyz147064 29088002d411SSowmini Varadhan static boolean_t 29098002d411SSowmini Varadhan print_lacp_cb(ofmt_arg_t *ofarg, char *buf, uint_t bufsize) 2910e7801d59Ssowmini { 29118002d411SSowmini Varadhan const laggr_args_t *l = ofarg->ofmt_cbarg; 2912e7801d59Ssowmini int portnum; 2913e7801d59Ssowmini boolean_t is_port = (l->laggr_lport >= 0); 2914e7801d59Ssowmini dladm_aggr_port_attr_t *portp; 2915e7801d59Ssowmini dladm_status_t *stat, status; 2916e7801d59Ssowmini aggr_lacp_state_t *lstate; 2917e7801d59Ssowmini 2918e7801d59Ssowmini if (!is_port) { 29198002d411SSowmini Varadhan return (B_FALSE); /* cannot happen! */ 2920e7801d59Ssowmini } 2921e7801d59Ssowmini 2922e7801d59Ssowmini stat = l->laggr_status; 2923e7801d59Ssowmini 2924e7801d59Ssowmini portnum = l->laggr_lport; 2925e7801d59Ssowmini portp = &(l->laggr_ginfop->lg_ports[portnum]); 29264ac67f02SAnurag S. Maskey 29274ac67f02SAnurag S. Maskey if ((status = dladm_datalink_id2info(handle, portp->lp_linkid, 29288002d411SSowmini Varadhan NULL, NULL, NULL, buf, bufsize)) != DLADM_STATUS_OK) { 2929e7801d59Ssowmini goto err; 2930e7801d59Ssowmini } 2931e7801d59Ssowmini lstate = &(portp->lp_lacp_state); 2932e7801d59Ssowmini 29338002d411SSowmini Varadhan switch (ofarg->ofmt_id) { 2934e7801d59Ssowmini case AGGR_L_LINK: 29358002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%s", 2936e7801d59Ssowmini (portnum > 0 ? "" : l->laggr_link)); 2937e7801d59Ssowmini break; 2938e7801d59Ssowmini 2939e7801d59Ssowmini case AGGR_L_PORT: 29408002d411SSowmini Varadhan /* 29418002d411SSowmini Varadhan * buf already contains portname as a result of the 29428002d411SSowmini Varadhan * earlier call to dladm_datalink_id2info(). 29438002d411SSowmini Varadhan */ 2944e7801d59Ssowmini break; 2945e7801d59Ssowmini 2946e7801d59Ssowmini case AGGR_L_AGGREGATABLE: 29478002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%s", 2948e7801d59Ssowmini (lstate->bit.aggregation ? "yes" : "no")); 2949e7801d59Ssowmini break; 2950e7801d59Ssowmini 2951e7801d59Ssowmini case AGGR_L_SYNC: 29528002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%s", 2953e7801d59Ssowmini (lstate->bit.sync ? "yes" : "no")); 2954e7801d59Ssowmini break; 2955e7801d59Ssowmini 2956e7801d59Ssowmini case AGGR_L_COLL: 29578002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%s", 2958e7801d59Ssowmini (lstate->bit.collecting ? "yes" : "no")); 2959e7801d59Ssowmini break; 2960e7801d59Ssowmini 2961e7801d59Ssowmini case AGGR_L_DIST: 29628002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%s", 2963e7801d59Ssowmini (lstate->bit.distributing ? "yes" : "no")); 2964e7801d59Ssowmini break; 2965e7801d59Ssowmini 2966e7801d59Ssowmini case AGGR_L_DEFAULTED: 29678002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%s", 2968e7801d59Ssowmini (lstate->bit.defaulted ? "yes" : "no")); 2969e7801d59Ssowmini break; 2970e7801d59Ssowmini 2971e7801d59Ssowmini case AGGR_L_EXPIRED: 29728002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%s", 2973e7801d59Ssowmini (lstate->bit.expired ? "yes" : "no")); 2974e7801d59Ssowmini break; 2975e7801d59Ssowmini } 2976e7801d59Ssowmini 2977e7801d59Ssowmini *stat = DLADM_STATUS_OK; 29788002d411SSowmini Varadhan return (B_TRUE); 2979e7801d59Ssowmini 2980e7801d59Ssowmini err: 2981e7801d59Ssowmini *stat = status; 29828002d411SSowmini Varadhan return (B_TRUE); 2983e7801d59Ssowmini } 2984e7801d59Ssowmini 2985d62bc4baSyz147064 static dladm_status_t 2986d62bc4baSyz147064 print_aggr_lacp(show_grp_state_t *state, const char *link, 2987e7801d59Ssowmini dladm_aggr_grp_attr_t *ginfop) 2988d62bc4baSyz147064 { 2989d62bc4baSyz147064 int i; 2990d62bc4baSyz147064 dladm_status_t status; 2991e7801d59Ssowmini laggr_args_t largs; 2992d62bc4baSyz147064 2993e7801d59Ssowmini largs.laggr_link = link; 2994e7801d59Ssowmini largs.laggr_ginfop = ginfop; 2995e7801d59Ssowmini largs.laggr_status = &status; 2996d62bc4baSyz147064 2997e7801d59Ssowmini for (i = 0; i < ginfop->lg_nports; i++) { 2998e7801d59Ssowmini largs.laggr_lport = i; 29998002d411SSowmini Varadhan ofmt_print(state->gs_ofmt, &largs); 3000d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 3001d62bc4baSyz147064 goto done; 3002d62bc4baSyz147064 } 3003d62bc4baSyz147064 3004d62bc4baSyz147064 status = DLADM_STATUS_OK; 3005d62bc4baSyz147064 done: 3006d62bc4baSyz147064 return (status); 3007d62bc4baSyz147064 } 3008d62bc4baSyz147064 30098002d411SSowmini Varadhan static boolean_t 30108002d411SSowmini Varadhan print_aggr_stats_cb(ofmt_arg_t *ofarg, char *buf, uint_t bufsize) 3011e7801d59Ssowmini { 30128002d411SSowmini Varadhan const laggr_args_t *l = ofarg->ofmt_cbarg; 3013e7801d59Ssowmini int portnum; 3014e7801d59Ssowmini boolean_t is_port = (l->laggr_lport >= 0); 3015e7801d59Ssowmini dladm_aggr_port_attr_t *portp; 3016e7801d59Ssowmini dladm_status_t *stat, status; 30172d40c3b2SPrakash Jalan pktsum_t *diff_stats; 3018e7801d59Ssowmini 3019e7801d59Ssowmini stat = l->laggr_status; 3020e7801d59Ssowmini *stat = DLADM_STATUS_OK; 3021e7801d59Ssowmini 3022e7801d59Ssowmini if (is_port) { 3023e7801d59Ssowmini portnum = l->laggr_lport; 3024e7801d59Ssowmini portp = &(l->laggr_ginfop->lg_ports[portnum]); 3025e7801d59Ssowmini 30264ac67f02SAnurag S. Maskey if ((status = dladm_datalink_id2info(handle, 30278002d411SSowmini Varadhan portp->lp_linkid, NULL, NULL, NULL, buf, bufsize)) != 30284ac67f02SAnurag S. Maskey DLADM_STATUS_OK) { 3029e7801d59Ssowmini goto err; 3030e7801d59Ssowmini } 30312d40c3b2SPrakash Jalan diff_stats = l->laggr_diffstats; 3032e7801d59Ssowmini } 3033e7801d59Ssowmini 30348002d411SSowmini Varadhan switch (ofarg->ofmt_id) { 3035e7801d59Ssowmini case AGGR_S_LINK: 30368002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%s", 3037e7801d59Ssowmini (is_port ? "" : l->laggr_link)); 3038e7801d59Ssowmini break; 3039e7801d59Ssowmini case AGGR_S_PORT: 30408002d411SSowmini Varadhan /* 30418002d411SSowmini Varadhan * if (is_port), buf has port name. Otherwise we print 30428002d411SSowmini Varadhan * STR_UNDEF_VAL 30438002d411SSowmini Varadhan */ 3044e7801d59Ssowmini break; 3045e7801d59Ssowmini 3046e7801d59Ssowmini case AGGR_S_IPKTS: 3047e7801d59Ssowmini if (is_port) { 30488002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%llu", 30492d40c3b2SPrakash Jalan diff_stats->ipackets); 3050e7801d59Ssowmini } else { 30518002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%llu", 3052e7801d59Ssowmini l->laggr_pktsumtot->ipackets); 3053e7801d59Ssowmini } 3054e7801d59Ssowmini break; 3055e7801d59Ssowmini 3056e7801d59Ssowmini case AGGR_S_RBYTES: 3057e7801d59Ssowmini if (is_port) { 30588002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%llu", 30592d40c3b2SPrakash Jalan diff_stats->rbytes); 3060e7801d59Ssowmini } else { 30618002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%llu", 3062e7801d59Ssowmini l->laggr_pktsumtot->rbytes); 3063e7801d59Ssowmini } 3064e7801d59Ssowmini break; 3065e7801d59Ssowmini 3066e7801d59Ssowmini case AGGR_S_OPKTS: 3067e7801d59Ssowmini if (is_port) { 30688002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%llu", 30692d40c3b2SPrakash Jalan diff_stats->opackets); 3070e7801d59Ssowmini } else { 30718002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%llu", 3072e7801d59Ssowmini l->laggr_pktsumtot->opackets); 3073e7801d59Ssowmini } 3074e7801d59Ssowmini break; 3075e7801d59Ssowmini case AGGR_S_OBYTES: 3076e7801d59Ssowmini if (is_port) { 30778002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%llu", 30782d40c3b2SPrakash Jalan diff_stats->obytes); 3079e7801d59Ssowmini } else { 30808002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%llu", 3081e7801d59Ssowmini l->laggr_pktsumtot->obytes); 3082e7801d59Ssowmini } 3083e7801d59Ssowmini break; 3084e7801d59Ssowmini 3085e7801d59Ssowmini case AGGR_S_IPKTDIST: 3086e7801d59Ssowmini if (is_port) { 30878002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%-6.1f", 30882d40c3b2SPrakash Jalan (double)diff_stats->ipackets/ 3089e7801d59Ssowmini (double)l->laggr_pktsumtot->ipackets * 100); 3090e7801d59Ssowmini } 3091e7801d59Ssowmini break; 3092e7801d59Ssowmini case AGGR_S_OPKTDIST: 3093e7801d59Ssowmini if (is_port) { 30948002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%-6.1f", 30952d40c3b2SPrakash Jalan (double)diff_stats->opackets/ 3096e7801d59Ssowmini (double)l->laggr_pktsumtot->opackets * 100); 3097e7801d59Ssowmini } 3098e7801d59Ssowmini break; 3099e7801d59Ssowmini } 31008002d411SSowmini Varadhan return (B_TRUE); 3101e7801d59Ssowmini 3102e7801d59Ssowmini err: 3103e7801d59Ssowmini *stat = status; 31048002d411SSowmini Varadhan return (B_TRUE); 3105e7801d59Ssowmini } 3106e7801d59Ssowmini 3107d62bc4baSyz147064 static dladm_status_t 3108d62bc4baSyz147064 print_aggr_stats(show_grp_state_t *state, const char *link, 3109e7801d59Ssowmini dladm_aggr_grp_attr_t *ginfop) 3110d62bc4baSyz147064 { 3111d62bc4baSyz147064 dladm_phys_attr_t dpa; 3112d62bc4baSyz147064 dladm_aggr_port_attr_t *portp; 31132d40c3b2SPrakash Jalan pktsum_t pktsumtot, *port_stat; 3114d62bc4baSyz147064 dladm_status_t status; 3115d62bc4baSyz147064 int i; 3116e7801d59Ssowmini laggr_args_t largs; 31177c478bd9Sstevel@tonic-gate 31187c478bd9Sstevel@tonic-gate /* sum the ports statistics */ 31197c478bd9Sstevel@tonic-gate bzero(&pktsumtot, sizeof (pktsumtot)); 3120d62bc4baSyz147064 31212d40c3b2SPrakash Jalan /* Allocate memory to keep stats of each port */ 31222d40c3b2SPrakash Jalan port_stat = malloc(ginfop->lg_nports * sizeof (pktsum_t)); 31232d40c3b2SPrakash Jalan if (port_stat == NULL) { 31242d40c3b2SPrakash Jalan /* Bail out; no memory */ 31252d40c3b2SPrakash Jalan return (DLADM_STATUS_NOMEM); 31262d40c3b2SPrakash Jalan } 31272d40c3b2SPrakash Jalan 31282d40c3b2SPrakash Jalan 3129d62bc4baSyz147064 for (i = 0; i < ginfop->lg_nports; i++) { 3130d62bc4baSyz147064 3131d62bc4baSyz147064 portp = &(ginfop->lg_ports[i]); 31324ac67f02SAnurag S. Maskey if ((status = dladm_phys_info(handle, portp->lp_linkid, &dpa, 3133d62bc4baSyz147064 DLADM_OPT_ACTIVE)) != DLADM_STATUS_OK) { 3134d62bc4baSyz147064 goto done; 31357c478bd9Sstevel@tonic-gate } 31367c478bd9Sstevel@tonic-gate 31372d40c3b2SPrakash Jalan get_mac_stats(dpa.dp_dev, &port_stat[i]); 31382d40c3b2SPrakash Jalan 31392d40c3b2SPrakash Jalan /* 31402d40c3b2SPrakash Jalan * Let's re-use gs_prevstats[] to store the difference of the 31412d40c3b2SPrakash Jalan * counters since last use. We will store the new stats from 31422d40c3b2SPrakash Jalan * port_stat[] once we have the stats displayed. 31432d40c3b2SPrakash Jalan */ 31442d40c3b2SPrakash Jalan 31452d40c3b2SPrakash Jalan dladm_stats_diff(&state->gs_prevstats[i], &port_stat[i], 31462d40c3b2SPrakash Jalan &state->gs_prevstats[i]); 31472d40c3b2SPrakash Jalan dladm_stats_total(&pktsumtot, &pktsumtot, 3148da14cebeSEric Cheng &state->gs_prevstats[i]); 31497c478bd9Sstevel@tonic-gate } 31507c478bd9Sstevel@tonic-gate 3151e7801d59Ssowmini largs.laggr_lport = -1; 3152e7801d59Ssowmini largs.laggr_link = link; 3153e7801d59Ssowmini largs.laggr_ginfop = ginfop; 3154e7801d59Ssowmini largs.laggr_status = &status; 3155e7801d59Ssowmini largs.laggr_pktsumtot = &pktsumtot; 3156e7801d59Ssowmini 31578002d411SSowmini Varadhan ofmt_print(state->gs_ofmt, &largs); 3158e7801d59Ssowmini 3159e7801d59Ssowmini if (status != DLADM_STATUS_OK) 3160e7801d59Ssowmini goto done; 3161d62bc4baSyz147064 3162d62bc4baSyz147064 for (i = 0; i < ginfop->lg_nports; i++) { 3163e7801d59Ssowmini largs.laggr_lport = i; 31642d40c3b2SPrakash Jalan largs.laggr_diffstats = &state->gs_prevstats[i]; 31658002d411SSowmini Varadhan ofmt_print(state->gs_ofmt, &largs); 3166e7801d59Ssowmini if (status != DLADM_STATUS_OK) 3167d62bc4baSyz147064 goto done; 3168d62bc4baSyz147064 } 3169d62bc4baSyz147064 3170d62bc4baSyz147064 status = DLADM_STATUS_OK; 31712d40c3b2SPrakash Jalan for (i = 0; i < ginfop->lg_nports; i++) 31722d40c3b2SPrakash Jalan state->gs_prevstats[i] = port_stat[i]; 31732d40c3b2SPrakash Jalan 3174d62bc4baSyz147064 done: 31752d40c3b2SPrakash Jalan free(port_stat); 3176d62bc4baSyz147064 return (status); 3177d62bc4baSyz147064 } 3178d62bc4baSyz147064 3179d62bc4baSyz147064 static dladm_status_t 3180e7801d59Ssowmini print_aggr(show_grp_state_t *state, datalink_id_t linkid) 3181d62bc4baSyz147064 { 3182d62bc4baSyz147064 char link[MAXLINKNAMELEN]; 3183d62bc4baSyz147064 dladm_aggr_grp_attr_t ginfo; 3184d62bc4baSyz147064 uint32_t flags; 3185d62bc4baSyz147064 dladm_status_t status; 3186d62bc4baSyz147064 31875f5c9f54SAnurag S. Maskey bzero(&ginfo, sizeof (dladm_aggr_grp_attr_t)); 31884ac67f02SAnurag S. Maskey if ((status = dladm_datalink_id2info(handle, linkid, &flags, NULL, 31894ac67f02SAnurag S. Maskey NULL, link, MAXLINKNAMELEN)) != DLADM_STATUS_OK) { 3190d62bc4baSyz147064 return (status); 3191d62bc4baSyz147064 } 3192d62bc4baSyz147064 3193d62bc4baSyz147064 if (!(state->gs_flags & flags)) 3194d62bc4baSyz147064 return (DLADM_STATUS_NOTFOUND); 3195d62bc4baSyz147064 31964ac67f02SAnurag S. Maskey status = dladm_aggr_info(handle, linkid, &ginfo, state->gs_flags); 3197d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 3198d62bc4baSyz147064 return (status); 3199d62bc4baSyz147064 3200d62bc4baSyz147064 if (state->gs_lacp) 3201e7801d59Ssowmini status = print_aggr_lacp(state, link, &ginfo); 3202d62bc4baSyz147064 else if (state->gs_extended) 3203e7801d59Ssowmini status = print_aggr_extended(state, link, &ginfo); 3204d62bc4baSyz147064 else if (state->gs_stats) 3205e7801d59Ssowmini status = print_aggr_stats(state, link, &ginfo); 32064ac67f02SAnurag S. Maskey else 3207e7801d59Ssowmini status = print_aggr_info(state, link, &ginfo); 3208d62bc4baSyz147064 3209d62bc4baSyz147064 done: 3210d62bc4baSyz147064 free(ginfo.lg_ports); 3211d62bc4baSyz147064 return (status); 3212d62bc4baSyz147064 } 3213d62bc4baSyz147064 32144ac67f02SAnurag S. Maskey /* ARGSUSED */ 3215d62bc4baSyz147064 static int 32164ac67f02SAnurag S. Maskey show_aggr(dladm_handle_t dh, datalink_id_t linkid, void *arg) 3217d62bc4baSyz147064 { 3218d62bc4baSyz147064 show_grp_state_t *state = arg; 3219d62bc4baSyz147064 32208002d411SSowmini Varadhan state->gs_status = print_aggr(state, linkid); 3221d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 32227c478bd9Sstevel@tonic-gate } 32237c478bd9Sstevel@tonic-gate 32247c478bd9Sstevel@tonic-gate static void 32258d5c46e6Sam223141 do_show_link(int argc, char *argv[], const char *use) 32267c478bd9Sstevel@tonic-gate { 32277c478bd9Sstevel@tonic-gate int option; 32287c478bd9Sstevel@tonic-gate boolean_t s_arg = B_FALSE; 3229da14cebeSEric Cheng boolean_t S_arg = B_FALSE; 32307c478bd9Sstevel@tonic-gate boolean_t i_arg = B_FALSE; 3231d62bc4baSyz147064 uint32_t flags = DLADM_OPT_ACTIVE; 3232d62bc4baSyz147064 boolean_t p_arg = B_FALSE; 3233d62bc4baSyz147064 datalink_id_t linkid = DATALINK_ALL_LINKID; 3234da14cebeSEric Cheng char linkname[MAXLINKNAMELEN]; 323563a6526dSMichael Lim uint32_t interval = 0; 3236d62bc4baSyz147064 show_state_t state; 3237d62bc4baSyz147064 dladm_status_t status; 3238e7801d59Ssowmini boolean_t o_arg = B_FALSE; 3239e7801d59Ssowmini char *fields_str = NULL; 3240*4eaa4710SRishi Srivatsavai char *all_active_fields = "link,class,mtu,state,bridge,over"; 3241*4eaa4710SRishi Srivatsavai char *all_inactive_fields = "link,class,bridge,over"; 32426be03d0bSVasumathi Sundaram - Sun Microsystems char *allstat_fields = 32436be03d0bSVasumathi Sundaram - Sun Microsystems "link,ipackets,rbytes,ierrors,opackets,obytes,oerrors"; 32448002d411SSowmini Varadhan ofmt_handle_t ofmt; 32458002d411SSowmini Varadhan ofmt_status_t oferr; 32468002d411SSowmini Varadhan uint_t ofmtflags = 0; 3247e7801d59Ssowmini 3248e7801d59Ssowmini bzero(&state, sizeof (state)); 32497c478bd9Sstevel@tonic-gate 32507c478bd9Sstevel@tonic-gate opterr = 0; 3251da14cebeSEric Cheng while ((option = getopt_long(argc, argv, ":pPsSi:o:", 3252d62bc4baSyz147064 show_lopts, NULL)) != -1) { 32537c478bd9Sstevel@tonic-gate switch (option) { 32547c478bd9Sstevel@tonic-gate case 'p': 3255d62bc4baSyz147064 if (p_arg) 3256d62bc4baSyz147064 die_optdup(option); 3257d62bc4baSyz147064 3258d62bc4baSyz147064 p_arg = B_TRUE; 32597c478bd9Sstevel@tonic-gate break; 32607c478bd9Sstevel@tonic-gate case 's': 326133343a97Smeem if (s_arg) 326233343a97Smeem die_optdup(option); 32637c478bd9Sstevel@tonic-gate 32647c478bd9Sstevel@tonic-gate s_arg = B_TRUE; 32657c478bd9Sstevel@tonic-gate break; 3266d62bc4baSyz147064 case 'P': 3267d62bc4baSyz147064 if (flags != DLADM_OPT_ACTIVE) 3268d62bc4baSyz147064 die_optdup(option); 3269d62bc4baSyz147064 3270d62bc4baSyz147064 flags = DLADM_OPT_PERSIST; 3271d62bc4baSyz147064 break; 3272da14cebeSEric Cheng case 'S': 3273da14cebeSEric Cheng if (S_arg) 3274da14cebeSEric Cheng die_optdup(option); 3275da14cebeSEric Cheng 3276da14cebeSEric Cheng S_arg = B_TRUE; 3277da14cebeSEric Cheng break; 3278e7801d59Ssowmini case 'o': 3279e7801d59Ssowmini o_arg = B_TRUE; 3280e7801d59Ssowmini fields_str = optarg; 3281e7801d59Ssowmini break; 32827c478bd9Sstevel@tonic-gate case 'i': 328333343a97Smeem if (i_arg) 328433343a97Smeem die_optdup(option); 32857c478bd9Sstevel@tonic-gate 32867c478bd9Sstevel@tonic-gate i_arg = B_TRUE; 328763a6526dSMichael Lim if (!dladm_str2interval(optarg, &interval)) 328833343a97Smeem die("invalid interval value '%s'", optarg); 32897c478bd9Sstevel@tonic-gate break; 32907c478bd9Sstevel@tonic-gate default: 32918d5c46e6Sam223141 die_opterr(optopt, option, use); 329233343a97Smeem break; 32937c478bd9Sstevel@tonic-gate } 32947c478bd9Sstevel@tonic-gate } 32957c478bd9Sstevel@tonic-gate 3296da14cebeSEric Cheng if (i_arg && !(s_arg || S_arg)) 3297da14cebeSEric Cheng die("the option -i can be used only with -s or -S"); 3298da14cebeSEric Cheng 3299da14cebeSEric Cheng if (s_arg && S_arg) 3300da14cebeSEric Cheng die("the -s option cannot be used with -S"); 33017c478bd9Sstevel@tonic-gate 33026be03d0bSVasumathi Sundaram - Sun Microsystems if (s_arg && flags != DLADM_OPT_ACTIVE) 33036be03d0bSVasumathi Sundaram - Sun Microsystems die("the option -P cannot be used with -s"); 3304d62bc4baSyz147064 3305da14cebeSEric Cheng if (S_arg && (p_arg || flags != DLADM_OPT_ACTIVE)) 3306da14cebeSEric Cheng die("the option -%c cannot be used with -S", p_arg ? 'p' : 'P'); 3307da14cebeSEric Cheng 33087c478bd9Sstevel@tonic-gate /* get link name (optional last argument) */ 3309d62bc4baSyz147064 if (optind == (argc-1)) { 3310d62bc4baSyz147064 uint32_t f; 3311d62bc4baSyz147064 3312da14cebeSEric Cheng if (strlcpy(linkname, argv[optind], MAXLINKNAMELEN) 3313da14cebeSEric Cheng >= MAXLINKNAMELEN) { 3314da14cebeSEric Cheng (void) fprintf(stderr, 3315da14cebeSEric Cheng gettext("%s: link name too long\n"), 3316da14cebeSEric Cheng progname); 33174ac67f02SAnurag S. Maskey dladm_close(handle); 3318da14cebeSEric Cheng exit(1); 3319da14cebeSEric Cheng } 33204ac67f02SAnurag S. Maskey if ((status = dladm_name2info(handle, linkname, &linkid, &f, 3321d62bc4baSyz147064 NULL, NULL)) != DLADM_STATUS_OK) { 3322da14cebeSEric Cheng die_dlerr(status, "link %s is not valid", linkname); 3323d62bc4baSyz147064 } 3324d62bc4baSyz147064 3325d62bc4baSyz147064 if (!(f & flags)) { 3326d62bc4baSyz147064 die_dlerr(DLADM_STATUS_BADARG, "link %s is %s", 3327d62bc4baSyz147064 argv[optind], flags == DLADM_OPT_PERSIST ? 3328d62bc4baSyz147064 "a temporary link" : "temporarily removed"); 3329d62bc4baSyz147064 } 3330d62bc4baSyz147064 } else if (optind != argc) { 33317c478bd9Sstevel@tonic-gate usage(); 3332d62bc4baSyz147064 } 33337c478bd9Sstevel@tonic-gate 33340d365605Sschuster if (p_arg && !o_arg) 33350d365605Sschuster die("-p requires -o"); 33360d365605Sschuster 3337da14cebeSEric Cheng if (S_arg) { 33384ac67f02SAnurag S. Maskey dladm_continuous(handle, linkid, NULL, interval, LINK_REPORT); 3339da14cebeSEric Cheng return; 3340da14cebeSEric Cheng } 3341da14cebeSEric Cheng 33420d365605Sschuster if (p_arg && strcasecmp(fields_str, "all") == 0) 33430d365605Sschuster die("\"-o all\" is invalid with -p"); 33440d365605Sschuster 3345e7801d59Ssowmini if (!o_arg || (o_arg && strcasecmp(fields_str, "all") == 0)) { 33466be03d0bSVasumathi Sundaram - Sun Microsystems if (s_arg) 33476be03d0bSVasumathi Sundaram - Sun Microsystems fields_str = allstat_fields; 33486be03d0bSVasumathi Sundaram - Sun Microsystems else if (flags & DLADM_OPT_ACTIVE) 3349e7801d59Ssowmini fields_str = all_active_fields; 3350e7801d59Ssowmini else 3351e7801d59Ssowmini fields_str = all_inactive_fields; 3352e7801d59Ssowmini } 3353e7801d59Ssowmini 33548002d411SSowmini Varadhan state.ls_parsable = p_arg; 33556be03d0bSVasumathi Sundaram - Sun Microsystems state.ls_flags = flags; 33566be03d0bSVasumathi Sundaram - Sun Microsystems state.ls_donefirst = B_FALSE; 33576be03d0bSVasumathi Sundaram - Sun Microsystems 33586be03d0bSVasumathi Sundaram - Sun Microsystems if (s_arg) { 33596be03d0bSVasumathi Sundaram - Sun Microsystems link_stats(linkid, interval, fields_str, &state); 33606be03d0bSVasumathi Sundaram - Sun Microsystems return; 33616be03d0bSVasumathi Sundaram - Sun Microsystems } 33628002d411SSowmini Varadhan if (state.ls_parsable) 33638002d411SSowmini Varadhan ofmtflags |= OFMT_PARSABLE; 33648002d411SSowmini Varadhan oferr = ofmt_open(fields_str, link_fields, ofmtflags, 0, &ofmt); 33658002d411SSowmini Varadhan dladm_ofmt_check(oferr, state.ls_parsable, ofmt); 33668002d411SSowmini Varadhan state.ls_ofmt = ofmt; 3367e7801d59Ssowmini 3368d62bc4baSyz147064 if (linkid == DATALINK_ALL_LINKID) { 33694ac67f02SAnurag S. Maskey (void) dladm_walk_datalink_id(show_link, handle, &state, 3370d62bc4baSyz147064 DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE, flags); 3371210db224Sericheng } else { 33724ac67f02SAnurag S. Maskey (void) show_link(handle, linkid, &state); 3373d62bc4baSyz147064 if (state.ls_status != DLADM_STATUS_OK) { 3374d62bc4baSyz147064 die_dlerr(state.ls_status, "failed to show link %s", 3375d62bc4baSyz147064 argv[optind]); 3376d62bc4baSyz147064 } 33777c478bd9Sstevel@tonic-gate } 33788002d411SSowmini Varadhan ofmt_close(ofmt); 3379210db224Sericheng } 33807c478bd9Sstevel@tonic-gate 33817c478bd9Sstevel@tonic-gate static void 33828d5c46e6Sam223141 do_show_aggr(int argc, char *argv[], const char *use) 33837c478bd9Sstevel@tonic-gate { 33847c478bd9Sstevel@tonic-gate boolean_t L_arg = B_FALSE; 33857c478bd9Sstevel@tonic-gate boolean_t s_arg = B_FALSE; 33867c478bd9Sstevel@tonic-gate boolean_t i_arg = B_FALSE; 3387d62bc4baSyz147064 boolean_t p_arg = B_FALSE; 3388d62bc4baSyz147064 boolean_t x_arg = B_FALSE; 33897c478bd9Sstevel@tonic-gate show_grp_state_t state; 3390d62bc4baSyz147064 uint32_t flags = DLADM_OPT_ACTIVE; 3391d62bc4baSyz147064 datalink_id_t linkid = DATALINK_ALL_LINKID; 3392d62bc4baSyz147064 int option; 339363a6526dSMichael Lim uint32_t interval = 0; 3394d62bc4baSyz147064 int key; 3395d62bc4baSyz147064 dladm_status_t status; 3396e7801d59Ssowmini boolean_t o_arg = B_FALSE; 3397e7801d59Ssowmini char *fields_str = NULL; 3398e7801d59Ssowmini char *all_fields = 3399e7801d59Ssowmini "link,policy,addrpolicy,lacpactivity,lacptimer,flags"; 3400e7801d59Ssowmini char *all_lacp_fields = 3401e7801d59Ssowmini "link,port,aggregatable,sync,coll,dist,defaulted,expired"; 3402e7801d59Ssowmini char *all_stats_fields = 3403e7801d59Ssowmini "link,port,ipackets,rbytes,opackets,obytes,ipktdist,opktdist"; 3404e7801d59Ssowmini char *all_extended_fields = 3405e7801d59Ssowmini "link,port,speed,duplex,state,address,portstate"; 34068002d411SSowmini Varadhan ofmt_field_t *pf; 34078002d411SSowmini Varadhan ofmt_handle_t ofmt; 34088002d411SSowmini Varadhan ofmt_status_t oferr; 34098002d411SSowmini Varadhan uint_t ofmtflags = 0; 3410e7801d59Ssowmini 34117c478bd9Sstevel@tonic-gate opterr = 0; 3412e7801d59Ssowmini while ((option = getopt_long(argc, argv, ":LpPxsi:o:", 3413d62bc4baSyz147064 show_lopts, NULL)) != -1) { 34147c478bd9Sstevel@tonic-gate switch (option) { 34157c478bd9Sstevel@tonic-gate case 'L': 341633343a97Smeem if (L_arg) 341733343a97Smeem die_optdup(option); 34187c478bd9Sstevel@tonic-gate 34197c478bd9Sstevel@tonic-gate L_arg = B_TRUE; 34207c478bd9Sstevel@tonic-gate break; 34217c478bd9Sstevel@tonic-gate case 'p': 3422d62bc4baSyz147064 if (p_arg) 3423d62bc4baSyz147064 die_optdup(option); 3424d62bc4baSyz147064 3425d62bc4baSyz147064 p_arg = B_TRUE; 3426d62bc4baSyz147064 break; 3427d62bc4baSyz147064 case 'x': 3428d62bc4baSyz147064 if (x_arg) 3429d62bc4baSyz147064 die_optdup(option); 3430d62bc4baSyz147064 3431d62bc4baSyz147064 x_arg = B_TRUE; 3432d62bc4baSyz147064 break; 3433d62bc4baSyz147064 case 'P': 3434d62bc4baSyz147064 if (flags != DLADM_OPT_ACTIVE) 3435d62bc4baSyz147064 die_optdup(option); 3436d62bc4baSyz147064 3437d62bc4baSyz147064 flags = DLADM_OPT_PERSIST; 34387c478bd9Sstevel@tonic-gate break; 34397c478bd9Sstevel@tonic-gate case 's': 344033343a97Smeem if (s_arg) 344133343a97Smeem die_optdup(option); 34427c478bd9Sstevel@tonic-gate 34437c478bd9Sstevel@tonic-gate s_arg = B_TRUE; 34447c478bd9Sstevel@tonic-gate break; 3445e7801d59Ssowmini case 'o': 3446e7801d59Ssowmini o_arg = B_TRUE; 3447e7801d59Ssowmini fields_str = optarg; 3448e7801d59Ssowmini break; 34497c478bd9Sstevel@tonic-gate case 'i': 345033343a97Smeem if (i_arg) 345133343a97Smeem die_optdup(option); 34527c478bd9Sstevel@tonic-gate 34537c478bd9Sstevel@tonic-gate i_arg = B_TRUE; 345463a6526dSMichael Lim if (!dladm_str2interval(optarg, &interval)) 345533343a97Smeem die("invalid interval value '%s'", optarg); 34567c478bd9Sstevel@tonic-gate break; 34577c478bd9Sstevel@tonic-gate default: 34588d5c46e6Sam223141 die_opterr(optopt, option, use); 345933343a97Smeem break; 34607c478bd9Sstevel@tonic-gate } 34617c478bd9Sstevel@tonic-gate } 34627c478bd9Sstevel@tonic-gate 34630d365605Sschuster if (p_arg && !o_arg) 34640d365605Sschuster die("-p requires -o"); 34650d365605Sschuster 34660d365605Sschuster if (p_arg && strcasecmp(fields_str, "all") == 0) 34670d365605Sschuster die("\"-o all\" is invalid with -p"); 34680d365605Sschuster 346933343a97Smeem if (i_arg && !s_arg) 347033343a97Smeem die("the option -i can be used only with -s"); 34717c478bd9Sstevel@tonic-gate 3472d62bc4baSyz147064 if (s_arg && (L_arg || p_arg || x_arg || flags != DLADM_OPT_ACTIVE)) { 3473d62bc4baSyz147064 die("the option -%c cannot be used with -s", 3474d62bc4baSyz147064 L_arg ? 'L' : (p_arg ? 'p' : (x_arg ? 'x' : 'P'))); 3475d62bc4baSyz147064 } 3476d62bc4baSyz147064 3477d62bc4baSyz147064 if (L_arg && flags != DLADM_OPT_ACTIVE) 3478d62bc4baSyz147064 die("the option -P cannot be used with -L"); 3479d62bc4baSyz147064 3480d62bc4baSyz147064 if (x_arg && (L_arg || flags != DLADM_OPT_ACTIVE)) 3481d62bc4baSyz147064 die("the option -%c cannot be used with -x", L_arg ? 'L' : 'P'); 3482d62bc4baSyz147064 3483d62bc4baSyz147064 /* get aggregation key or aggrname (optional last argument) */ 34847c478bd9Sstevel@tonic-gate if (optind == (argc-1)) { 3485d62bc4baSyz147064 if (!str2int(argv[optind], &key)) { 34864ac67f02SAnurag S. Maskey status = dladm_name2info(handle, argv[optind], 34874ac67f02SAnurag S. Maskey &linkid, NULL, NULL, NULL); 3488d62bc4baSyz147064 } else { 34894ac67f02SAnurag S. Maskey status = dladm_key2linkid(handle, (uint16_t)key, 3490d62bc4baSyz147064 &linkid, DLADM_OPT_ACTIVE); 3491d62bc4baSyz147064 } 3492d62bc4baSyz147064 3493d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 3494d62bc4baSyz147064 die("non-existent aggregation '%s'", argv[optind]); 3495d62bc4baSyz147064 34967c478bd9Sstevel@tonic-gate } else if (optind != argc) { 34977c478bd9Sstevel@tonic-gate usage(); 34987c478bd9Sstevel@tonic-gate } 34997c478bd9Sstevel@tonic-gate 3500d62bc4baSyz147064 bzero(&state, sizeof (state)); 3501d62bc4baSyz147064 state.gs_lacp = L_arg; 3502d62bc4baSyz147064 state.gs_stats = s_arg; 3503d62bc4baSyz147064 state.gs_flags = flags; 35048002d411SSowmini Varadhan state.gs_parsable = p_arg; 3505d62bc4baSyz147064 state.gs_extended = x_arg; 3506d62bc4baSyz147064 3507e7801d59Ssowmini if (!o_arg || (o_arg && strcasecmp(fields_str, "all") == 0)) { 3508e7801d59Ssowmini if (state.gs_lacp) 3509e7801d59Ssowmini fields_str = all_lacp_fields; 3510e7801d59Ssowmini else if (state.gs_stats) 3511e7801d59Ssowmini fields_str = all_stats_fields; 3512e7801d59Ssowmini else if (state.gs_extended) 3513e7801d59Ssowmini fields_str = all_extended_fields; 3514e7801d59Ssowmini else 3515e7801d59Ssowmini fields_str = all_fields; 3516e7801d59Ssowmini } 3517e7801d59Ssowmini 3518e7801d59Ssowmini if (state.gs_lacp) { 3519e7801d59Ssowmini pf = aggr_l_fields; 3520e7801d59Ssowmini } else if (state.gs_stats) { 3521e7801d59Ssowmini pf = aggr_s_fields; 3522e7801d59Ssowmini } else if (state.gs_extended) { 3523e7801d59Ssowmini pf = aggr_x_fields; 3524e7801d59Ssowmini } else { 3525e7801d59Ssowmini pf = laggr_fields; 3526e7801d59Ssowmini } 3527e7801d59Ssowmini 35288002d411SSowmini Varadhan if (state.gs_parsable) 35298002d411SSowmini Varadhan ofmtflags |= OFMT_PARSABLE; 35308002d411SSowmini Varadhan oferr = ofmt_open(fields_str, pf, ofmtflags, 0, &ofmt); 35318002d411SSowmini Varadhan dladm_ofmt_check(oferr, state.gs_parsable, ofmt); 35328002d411SSowmini Varadhan state.gs_ofmt = ofmt; 3533e7801d59Ssowmini 35347c478bd9Sstevel@tonic-gate if (s_arg) { 3535d62bc4baSyz147064 aggr_stats(linkid, &state, interval); 35368002d411SSowmini Varadhan ofmt_close(ofmt); 35377c478bd9Sstevel@tonic-gate return; 35387c478bd9Sstevel@tonic-gate } 35397c478bd9Sstevel@tonic-gate 3540d62bc4baSyz147064 if (linkid == DATALINK_ALL_LINKID) { 35414ac67f02SAnurag S. Maskey (void) dladm_walk_datalink_id(show_aggr, handle, &state, 3542d62bc4baSyz147064 DATALINK_CLASS_AGGR, DATALINK_ANY_MEDIATYPE, flags); 3543d62bc4baSyz147064 } else { 35444ac67f02SAnurag S. Maskey (void) show_aggr(handle, linkid, &state); 3545d62bc4baSyz147064 if (state.gs_status != DLADM_STATUS_OK) { 3546d62bc4baSyz147064 die_dlerr(state.gs_status, "failed to show aggr %s", 3547d62bc4baSyz147064 argv[optind]); 3548d62bc4baSyz147064 } 3549d62bc4baSyz147064 } 35508002d411SSowmini Varadhan ofmt_close(ofmt); 35517c478bd9Sstevel@tonic-gate } 35527c478bd9Sstevel@tonic-gate 3553da14cebeSEric Cheng static dladm_status_t 3554da14cebeSEric Cheng print_phys_default(show_state_t *state, datalink_id_t linkid, 3555da14cebeSEric Cheng const char *link, uint32_t flags, uint32_t media) 35567c478bd9Sstevel@tonic-gate { 3557da14cebeSEric Cheng dladm_phys_attr_t dpa; 3558da14cebeSEric Cheng dladm_status_t status; 3559da14cebeSEric Cheng link_fields_buf_t pattr; 3560e7801d59Ssowmini 35614ac67f02SAnurag S. Maskey status = dladm_phys_info(handle, linkid, &dpa, state->ls_flags); 3562da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 3563da14cebeSEric Cheng goto done; 35647c478bd9Sstevel@tonic-gate 3565da14cebeSEric Cheng (void) snprintf(pattr.link_phys_device, 3566da14cebeSEric Cheng sizeof (pattr.link_phys_device), "%s", dpa.dp_dev); 3567da14cebeSEric Cheng (void) dladm_media2str(media, pattr.link_phys_media); 3568da14cebeSEric Cheng if (state->ls_flags == DLADM_OPT_ACTIVE) { 3569da14cebeSEric Cheng boolean_t islink; 3570d62bc4baSyz147064 3571da14cebeSEric Cheng if (!dpa.dp_novanity) { 3572da14cebeSEric Cheng (void) strlcpy(pattr.link_name, link, 3573da14cebeSEric Cheng sizeof (pattr.link_name)); 3574da14cebeSEric Cheng islink = B_TRUE; 3575d62bc4baSyz147064 } else { 3576da14cebeSEric Cheng /* 3577da14cebeSEric Cheng * This is a physical link that does not have 3578da14cebeSEric Cheng * vanity naming support. 3579da14cebeSEric Cheng */ 3580da14cebeSEric Cheng (void) strlcpy(pattr.link_name, dpa.dp_dev, 3581da14cebeSEric Cheng sizeof (pattr.link_name)); 3582da14cebeSEric Cheng islink = B_FALSE; 35837c478bd9Sstevel@tonic-gate } 35847c478bd9Sstevel@tonic-gate 3585da14cebeSEric Cheng (void) get_linkstate(pattr.link_name, islink, 3586da14cebeSEric Cheng pattr.link_phys_state); 3587da14cebeSEric Cheng (void) snprintf(pattr.link_phys_speed, 3588da14cebeSEric Cheng sizeof (pattr.link_phys_speed), "%u", 3589da14cebeSEric Cheng (uint_t)((get_ifspeed(pattr.link_name, 3590da14cebeSEric Cheng islink)) / 1000000ull)); 3591da14cebeSEric Cheng (void) get_linkduplex(pattr.link_name, islink, 3592da14cebeSEric Cheng pattr.link_phys_duplex); 3593da14cebeSEric Cheng } else { 3594da14cebeSEric Cheng (void) snprintf(pattr.link_name, sizeof (pattr.link_name), 3595da14cebeSEric Cheng "%s", link); 3596da14cebeSEric Cheng (void) snprintf(pattr.link_flags, sizeof (pattr.link_flags), 3597da14cebeSEric Cheng "%c----", flags & DLADM_OPT_ACTIVE ? '-' : 'r'); 3598da14cebeSEric Cheng } 3599da14cebeSEric Cheng 36008002d411SSowmini Varadhan ofmt_print(state->ls_ofmt, &pattr); 3601da14cebeSEric Cheng 3602da14cebeSEric Cheng done: 3603da14cebeSEric Cheng return (status); 3604da14cebeSEric Cheng } 3605da14cebeSEric Cheng 3606da14cebeSEric Cheng typedef struct { 3607da14cebeSEric Cheng show_state_t *ms_state; 3608da14cebeSEric Cheng char *ms_link; 3609da14cebeSEric Cheng dladm_macaddr_attr_t *ms_mac_attr; 3610da14cebeSEric Cheng } print_phys_mac_state_t; 3611da14cebeSEric Cheng 36128002d411SSowmini Varadhan /* 36138002d411SSowmini Varadhan * callback for ofmt_print() 36148002d411SSowmini Varadhan */ 36158002d411SSowmini Varadhan static boolean_t 36168002d411SSowmini Varadhan print_phys_one_mac_cb(ofmt_arg_t *ofarg, char *buf, uint_t bufsize) 3617da14cebeSEric Cheng { 36188002d411SSowmini Varadhan print_phys_mac_state_t *mac_state = ofarg->ofmt_cbarg; 3619da14cebeSEric Cheng dladm_macaddr_attr_t *attr = mac_state->ms_mac_attr; 3620da14cebeSEric Cheng boolean_t is_primary = (attr->ma_slot == 0); 36218002d411SSowmini Varadhan boolean_t is_parsable = mac_state->ms_state->ls_parsable; 3622da14cebeSEric Cheng 36238002d411SSowmini Varadhan switch (ofarg->ofmt_id) { 3624da14cebeSEric Cheng case PHYS_M_LINK: 36258002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%s", 36268002d411SSowmini Varadhan (is_primary || is_parsable) ? mac_state->ms_link : " "); 3627da14cebeSEric Cheng break; 3628da14cebeSEric Cheng case PHYS_M_SLOT: 3629da14cebeSEric Cheng if (is_primary) 36308002d411SSowmini Varadhan (void) snprintf(buf, bufsize, gettext("primary")); 3631da14cebeSEric Cheng else 36328002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%d", attr->ma_slot); 3633da14cebeSEric Cheng break; 3634da14cebeSEric Cheng case PHYS_M_ADDRESS: 3635da14cebeSEric Cheng (void) dladm_aggr_macaddr2str(attr->ma_addr, buf); 3636da14cebeSEric Cheng break; 3637da14cebeSEric Cheng case PHYS_M_INUSE: 36388002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%s", 3639da14cebeSEric Cheng attr->ma_flags & DLADM_MACADDR_USED ? gettext("yes") : 3640da14cebeSEric Cheng gettext("no")); 3641da14cebeSEric Cheng break; 3642da14cebeSEric Cheng case PHYS_M_CLIENT: 3643da14cebeSEric Cheng /* 3644da14cebeSEric Cheng * CR 6678526: resolve link id to actual link name if 3645da14cebeSEric Cheng * it is valid. 3646da14cebeSEric Cheng */ 36478002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%s", attr->ma_client_name); 3648da14cebeSEric Cheng break; 3649da14cebeSEric Cheng } 3650da14cebeSEric Cheng 36518002d411SSowmini Varadhan return (B_TRUE); 3652da14cebeSEric Cheng } 3653da14cebeSEric Cheng 3654da14cebeSEric Cheng typedef struct { 3655da14cebeSEric Cheng show_state_t *hs_state; 3656da14cebeSEric Cheng char *hs_link; 3657da14cebeSEric Cheng dladm_hwgrp_attr_t *hs_grp_attr; 3658da14cebeSEric Cheng } print_phys_hwgrp_state_t; 3659da14cebeSEric Cheng 36608002d411SSowmini Varadhan static boolean_t 36618002d411SSowmini Varadhan print_phys_one_hwgrp_cb(ofmt_arg_t *ofarg, char *buf, uint_t bufsize) 3662da14cebeSEric Cheng { 36638002d411SSowmini Varadhan print_phys_hwgrp_state_t *hg_state = ofarg->ofmt_cbarg; 3664da14cebeSEric Cheng dladm_hwgrp_attr_t *attr = hg_state->hs_grp_attr; 3665da14cebeSEric Cheng 36668002d411SSowmini Varadhan switch (ofarg->ofmt_id) { 3667da14cebeSEric Cheng case PHYS_H_LINK: 36688002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%s", attr->hg_link_name); 3669da14cebeSEric Cheng break; 3670da14cebeSEric Cheng case PHYS_H_GROUP: 36718002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%d", attr->hg_grp_num); 3672da14cebeSEric Cheng break; 3673da14cebeSEric Cheng case PHYS_H_GRPTYPE: 36748002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%s", 3675da14cebeSEric Cheng attr->hg_grp_type == DLADM_HWGRP_TYPE_RX ? "RX" : "TX"); 3676da14cebeSEric Cheng break; 3677da14cebeSEric Cheng case PHYS_H_RINGS: 36788002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%d", attr->hg_n_rings); 3679da14cebeSEric Cheng break; 3680da14cebeSEric Cheng case PHYS_H_CLIENTS: 3681da14cebeSEric Cheng if (attr->hg_client_names[0] == '\0') { 36828002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "--"); 3683da14cebeSEric Cheng } else { 36848002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%s ", 3685da14cebeSEric Cheng attr->hg_client_names); 3686da14cebeSEric Cheng } 3687da14cebeSEric Cheng break; 3688da14cebeSEric Cheng } 3689da14cebeSEric Cheng 36908002d411SSowmini Varadhan return (B_TRUE); 3691da14cebeSEric Cheng } 3692da14cebeSEric Cheng 36938002d411SSowmini Varadhan /* 36948002d411SSowmini Varadhan * callback for dladm_walk_macaddr, invoked for each MAC address slot 36958002d411SSowmini Varadhan */ 3696da14cebeSEric Cheng static boolean_t 3697da14cebeSEric Cheng print_phys_mac_callback(void *arg, dladm_macaddr_attr_t *attr) 3698da14cebeSEric Cheng { 3699da14cebeSEric Cheng print_phys_mac_state_t *mac_state = arg; 3700da14cebeSEric Cheng show_state_t *state = mac_state->ms_state; 3701da14cebeSEric Cheng 3702da14cebeSEric Cheng mac_state->ms_mac_attr = attr; 37038002d411SSowmini Varadhan ofmt_print(state->ls_ofmt, mac_state); 3704da14cebeSEric Cheng 3705da14cebeSEric Cheng return (B_TRUE); 3706da14cebeSEric Cheng } 3707da14cebeSEric Cheng 37088002d411SSowmini Varadhan /* 37098002d411SSowmini Varadhan * invoked by show-phys -m for each physical data-link 37108002d411SSowmini Varadhan */ 3711da14cebeSEric Cheng static dladm_status_t 3712da14cebeSEric Cheng print_phys_mac(show_state_t *state, datalink_id_t linkid, char *link) 3713da14cebeSEric Cheng { 3714da14cebeSEric Cheng print_phys_mac_state_t mac_state; 3715da14cebeSEric Cheng 3716da14cebeSEric Cheng mac_state.ms_state = state; 3717da14cebeSEric Cheng mac_state.ms_link = link; 3718da14cebeSEric Cheng 37194ac67f02SAnurag S. Maskey return (dladm_walk_macaddr(handle, linkid, &mac_state, 3720da14cebeSEric Cheng print_phys_mac_callback)); 3721da14cebeSEric Cheng } 3722da14cebeSEric Cheng 37238002d411SSowmini Varadhan /* 37248002d411SSowmini Varadhan * callback for dladm_walk_hwgrp, invoked for each MAC hwgrp 37258002d411SSowmini Varadhan */ 3726da14cebeSEric Cheng static boolean_t 3727da14cebeSEric Cheng print_phys_hwgrp_callback(void *arg, dladm_hwgrp_attr_t *attr) 3728da14cebeSEric Cheng { 3729da14cebeSEric Cheng print_phys_hwgrp_state_t *hwgrp_state = arg; 3730da14cebeSEric Cheng show_state_t *state = hwgrp_state->hs_state; 3731da14cebeSEric Cheng 3732da14cebeSEric Cheng hwgrp_state->hs_grp_attr = attr; 37338002d411SSowmini Varadhan ofmt_print(state->ls_ofmt, hwgrp_state); 3734da14cebeSEric Cheng 3735da14cebeSEric Cheng return (B_TRUE); 3736da14cebeSEric Cheng } 3737da14cebeSEric Cheng 3738da14cebeSEric Cheng /* invoked by show-phys -H for each physical data-link */ 3739da14cebeSEric Cheng static dladm_status_t 3740da14cebeSEric Cheng print_phys_hwgrp(show_state_t *state, datalink_id_t linkid, char *link) 3741da14cebeSEric Cheng { 3742da14cebeSEric Cheng print_phys_hwgrp_state_t hwgrp_state; 3743da14cebeSEric Cheng 3744da14cebeSEric Cheng hwgrp_state.hs_state = state; 3745da14cebeSEric Cheng hwgrp_state.hs_link = link; 37464ac67f02SAnurag S. Maskey return (dladm_walk_hwgrp(handle, linkid, &hwgrp_state, 3747da14cebeSEric Cheng print_phys_hwgrp_callback)); 3748da14cebeSEric Cheng } 3749d62bc4baSyz147064 3750d62bc4baSyz147064 static dladm_status_t 3751da14cebeSEric Cheng print_phys(show_state_t *state, datalink_id_t linkid) 3752d62bc4baSyz147064 { 3753d62bc4baSyz147064 char link[MAXLINKNAMELEN]; 3754d62bc4baSyz147064 uint32_t flags; 3755da14cebeSEric Cheng dladm_status_t status; 3756d62bc4baSyz147064 datalink_class_t class; 3757d62bc4baSyz147064 uint32_t media; 3758d62bc4baSyz147064 37594ac67f02SAnurag S. Maskey if ((status = dladm_datalink_id2info(handle, linkid, &flags, &class, 37604ac67f02SAnurag S. Maskey &media, link, MAXLINKNAMELEN)) != DLADM_STATUS_OK) { 3761d62bc4baSyz147064 goto done; 3762d62bc4baSyz147064 } 3763d62bc4baSyz147064 3764d62bc4baSyz147064 if (class != DATALINK_CLASS_PHYS) { 3765d62bc4baSyz147064 status = DLADM_STATUS_BADARG; 3766d62bc4baSyz147064 goto done; 3767d62bc4baSyz147064 } 3768d62bc4baSyz147064 3769d62bc4baSyz147064 if (!(state->ls_flags & flags)) { 3770d62bc4baSyz147064 status = DLADM_STATUS_NOTFOUND; 3771d62bc4baSyz147064 goto done; 3772d62bc4baSyz147064 } 3773d62bc4baSyz147064 3774da14cebeSEric Cheng if (state->ls_mac) 3775da14cebeSEric Cheng status = print_phys_mac(state, linkid, link); 3776da14cebeSEric Cheng else if (state->ls_hwgrp) 3777da14cebeSEric Cheng status = print_phys_hwgrp(state, linkid, link); 3778da14cebeSEric Cheng else 3779da14cebeSEric Cheng status = print_phys_default(state, linkid, link, flags, media); 3780d62bc4baSyz147064 3781d62bc4baSyz147064 done: 3782d62bc4baSyz147064 return (status); 3783d62bc4baSyz147064 } 3784d62bc4baSyz147064 37854ac67f02SAnurag S. Maskey /* ARGSUSED */ 3786d62bc4baSyz147064 static int 37874ac67f02SAnurag S. Maskey show_phys(dladm_handle_t dh, datalink_id_t linkid, void *arg) 3788d62bc4baSyz147064 { 3789d62bc4baSyz147064 show_state_t *state = arg; 3790d62bc4baSyz147064 3791da14cebeSEric Cheng state->ls_status = print_phys(state, linkid); 3792d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 3793d62bc4baSyz147064 } 3794d62bc4baSyz147064 3795d62bc4baSyz147064 /* 3796d62bc4baSyz147064 * Print the active topology information. 3797d62bc4baSyz147064 */ 3798d62bc4baSyz147064 static dladm_status_t 3799e7801d59Ssowmini print_vlan(show_state_t *state, datalink_id_t linkid, link_fields_buf_t *l) 3800d62bc4baSyz147064 { 3801d62bc4baSyz147064 dladm_vlan_attr_t vinfo; 3802d62bc4baSyz147064 uint32_t flags; 3803d62bc4baSyz147064 dladm_status_t status; 3804d62bc4baSyz147064 38054ac67f02SAnurag S. Maskey if ((status = dladm_datalink_id2info(handle, linkid, &flags, NULL, NULL, 3806e7801d59Ssowmini l->link_name, sizeof (l->link_name))) != DLADM_STATUS_OK) { 3807d62bc4baSyz147064 goto done; 3808d62bc4baSyz147064 } 3809d62bc4baSyz147064 3810d62bc4baSyz147064 if (!(state->ls_flags & flags)) { 3811d62bc4baSyz147064 status = DLADM_STATUS_NOTFOUND; 3812d62bc4baSyz147064 goto done; 3813d62bc4baSyz147064 } 3814d62bc4baSyz147064 38154ac67f02SAnurag S. Maskey if ((status = dladm_vlan_info(handle, linkid, &vinfo, 38164ac67f02SAnurag S. Maskey state->ls_flags)) != DLADM_STATUS_OK || 38174ac67f02SAnurag S. Maskey (status = dladm_datalink_id2info(handle, vinfo.dv_linkid, NULL, 38184ac67f02SAnurag S. Maskey NULL, NULL, l->link_over, sizeof (l->link_over))) != 38194ac67f02SAnurag S. Maskey DLADM_STATUS_OK) { 3820d62bc4baSyz147064 goto done; 3821d62bc4baSyz147064 } 3822d62bc4baSyz147064 3823e7801d59Ssowmini (void) snprintf(l->link_vlan_vid, sizeof (l->link_vlan_vid), "%d", 3824e7801d59Ssowmini vinfo.dv_vid); 3825da14cebeSEric Cheng (void) snprintf(l->link_flags, sizeof (l->link_flags), "%c----", 3826da14cebeSEric Cheng vinfo.dv_force ? 'f' : '-'); 3827d62bc4baSyz147064 3828d62bc4baSyz147064 done: 3829d62bc4baSyz147064 return (status); 3830d62bc4baSyz147064 } 3831d62bc4baSyz147064 38324ac67f02SAnurag S. Maskey /* ARGSUSED */ 3833d62bc4baSyz147064 static int 38344ac67f02SAnurag S. Maskey show_vlan(dladm_handle_t dh, datalink_id_t linkid, void *arg) 3835d62bc4baSyz147064 { 3836d62bc4baSyz147064 show_state_t *state = arg; 3837d62bc4baSyz147064 dladm_status_t status; 3838e7801d59Ssowmini link_fields_buf_t lbuf; 3839d62bc4baSyz147064 38405f5c9f54SAnurag S. Maskey bzero(&lbuf, sizeof (link_fields_buf_t)); 3841e7801d59Ssowmini status = print_vlan(state, linkid, &lbuf); 3842d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 3843d62bc4baSyz147064 goto done; 3844e7801d59Ssowmini 38458002d411SSowmini Varadhan ofmt_print(state->ls_ofmt, &lbuf); 3846d62bc4baSyz147064 3847d62bc4baSyz147064 done: 3848d62bc4baSyz147064 state->ls_status = status; 3849d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 3850d62bc4baSyz147064 } 3851d62bc4baSyz147064 3852d62bc4baSyz147064 static void 38538d5c46e6Sam223141 do_show_phys(int argc, char *argv[], const char *use) 3854d62bc4baSyz147064 { 3855d62bc4baSyz147064 int option; 3856d62bc4baSyz147064 uint32_t flags = DLADM_OPT_ACTIVE; 3857d62bc4baSyz147064 boolean_t p_arg = B_FALSE; 3858e7801d59Ssowmini boolean_t o_arg = B_FALSE; 3859da14cebeSEric Cheng boolean_t m_arg = B_FALSE; 3860da14cebeSEric Cheng boolean_t H_arg = B_FALSE; 3861d62bc4baSyz147064 datalink_id_t linkid = DATALINK_ALL_LINKID; 3862d62bc4baSyz147064 show_state_t state; 3863d62bc4baSyz147064 dladm_status_t status; 3864e7801d59Ssowmini char *fields_str = NULL; 3865e7801d59Ssowmini char *all_active_fields = 3866e7801d59Ssowmini "link,media,state,speed,duplex,device"; 38675f5c9f54SAnurag S. Maskey char *all_inactive_fields = "link,device,media,flags"; 3868da14cebeSEric Cheng char *all_mac_fields = "link,slot,address,inuse,client"; 3869da14cebeSEric Cheng char *all_hwgrp_fields = 3870da14cebeSEric Cheng "link,group,grouptype,rings,clients"; 38718002d411SSowmini Varadhan ofmt_field_t *pf; 38728002d411SSowmini Varadhan ofmt_handle_t ofmt; 38738002d411SSowmini Varadhan ofmt_status_t oferr; 38748002d411SSowmini Varadhan uint_t ofmtflags = 0; 3875d62bc4baSyz147064 3876e7801d59Ssowmini bzero(&state, sizeof (state)); 3877d62bc4baSyz147064 opterr = 0; 3878da14cebeSEric Cheng while ((option = getopt_long(argc, argv, ":pPo:mH", 3879d62bc4baSyz147064 show_lopts, NULL)) != -1) { 3880d62bc4baSyz147064 switch (option) { 3881d62bc4baSyz147064 case 'p': 3882d62bc4baSyz147064 if (p_arg) 3883d62bc4baSyz147064 die_optdup(option); 3884d62bc4baSyz147064 3885d62bc4baSyz147064 p_arg = B_TRUE; 3886d62bc4baSyz147064 break; 3887d62bc4baSyz147064 case 'P': 3888d62bc4baSyz147064 if (flags != DLADM_OPT_ACTIVE) 3889d62bc4baSyz147064 die_optdup(option); 3890d62bc4baSyz147064 3891d62bc4baSyz147064 flags = DLADM_OPT_PERSIST; 3892d62bc4baSyz147064 break; 3893e7801d59Ssowmini case 'o': 3894e7801d59Ssowmini o_arg = B_TRUE; 3895e7801d59Ssowmini fields_str = optarg; 3896e7801d59Ssowmini break; 3897da14cebeSEric Cheng case 'm': 3898da14cebeSEric Cheng m_arg = B_TRUE; 3899da14cebeSEric Cheng break; 3900da14cebeSEric Cheng case 'H': 3901da14cebeSEric Cheng H_arg = B_TRUE; 3902da14cebeSEric Cheng break; 3903d62bc4baSyz147064 default: 39048d5c46e6Sam223141 die_opterr(optopt, option, use); 3905d62bc4baSyz147064 break; 3906d62bc4baSyz147064 } 3907d62bc4baSyz147064 } 3908d62bc4baSyz147064 39090d365605Sschuster if (p_arg && !o_arg) 39100d365605Sschuster die("-p requires -o"); 39110d365605Sschuster 3912da14cebeSEric Cheng if (m_arg && H_arg) 3913da14cebeSEric Cheng die("-m cannot combine with -H"); 3914da14cebeSEric Cheng 39150d365605Sschuster if (p_arg && strcasecmp(fields_str, "all") == 0) 39160d365605Sschuster die("\"-o all\" is invalid with -p"); 39170d365605Sschuster 3918d62bc4baSyz147064 /* get link name (optional last argument) */ 3919d62bc4baSyz147064 if (optind == (argc-1)) { 39204ac67f02SAnurag S. Maskey if ((status = dladm_name2info(handle, argv[optind], &linkid, 39214ac67f02SAnurag S. Maskey NULL, NULL, NULL)) != DLADM_STATUS_OK) { 3922d62bc4baSyz147064 die_dlerr(status, "link %s is not valid", argv[optind]); 3923d62bc4baSyz147064 } 3924d62bc4baSyz147064 } else if (optind != argc) { 3925d62bc4baSyz147064 usage(); 3926d62bc4baSyz147064 } 3927d62bc4baSyz147064 39288002d411SSowmini Varadhan state.ls_parsable = p_arg; 3929d62bc4baSyz147064 state.ls_flags = flags; 3930d62bc4baSyz147064 state.ls_donefirst = B_FALSE; 3931da14cebeSEric Cheng state.ls_mac = m_arg; 3932da14cebeSEric Cheng state.ls_hwgrp = H_arg; 3933d62bc4baSyz147064 3934da14cebeSEric Cheng if (m_arg && !(flags & DLADM_OPT_ACTIVE)) { 3935da14cebeSEric Cheng /* 3936da14cebeSEric Cheng * We can only display the factory MAC addresses of 3937da14cebeSEric Cheng * active data-links. 3938da14cebeSEric Cheng */ 3939da14cebeSEric Cheng die("-m not compatible with -P"); 3940e7801d59Ssowmini } 3941e7801d59Ssowmini 3942da14cebeSEric Cheng if (!o_arg || (o_arg && strcasecmp(fields_str, "all") == 0)) { 3943da14cebeSEric Cheng if (state.ls_mac) 3944da14cebeSEric Cheng fields_str = all_mac_fields; 3945da14cebeSEric Cheng else if (state.ls_hwgrp) 3946da14cebeSEric Cheng fields_str = all_hwgrp_fields; 3947da14cebeSEric Cheng else if (state.ls_flags & DLADM_OPT_ACTIVE) { 3948da14cebeSEric Cheng fields_str = all_active_fields; 3949da14cebeSEric Cheng } else { 3950da14cebeSEric Cheng fields_str = all_inactive_fields; 3951da14cebeSEric Cheng } 3952da14cebeSEric Cheng } 3953da14cebeSEric Cheng 3954da14cebeSEric Cheng if (state.ls_mac) { 3955da14cebeSEric Cheng pf = phys_m_fields; 3956da14cebeSEric Cheng } else if (state.ls_hwgrp) { 3957da14cebeSEric Cheng pf = phys_h_fields; 3958da14cebeSEric Cheng } else { 3959da14cebeSEric Cheng pf = phys_fields; 3960da14cebeSEric Cheng } 3961da14cebeSEric Cheng 39628002d411SSowmini Varadhan if (state.ls_parsable) 39638002d411SSowmini Varadhan ofmtflags |= OFMT_PARSABLE; 39648002d411SSowmini Varadhan oferr = ofmt_open(fields_str, pf, ofmtflags, 0, &ofmt); 39658002d411SSowmini Varadhan dladm_ofmt_check(oferr, state.ls_parsable, ofmt); 39668002d411SSowmini Varadhan state.ls_ofmt = ofmt; 3967e7801d59Ssowmini 3968d62bc4baSyz147064 if (linkid == DATALINK_ALL_LINKID) { 39694ac67f02SAnurag S. Maskey (void) dladm_walk_datalink_id(show_phys, handle, &state, 3970d62bc4baSyz147064 DATALINK_CLASS_PHYS, DATALINK_ANY_MEDIATYPE, flags); 3971d62bc4baSyz147064 } else { 39724ac67f02SAnurag S. Maskey (void) show_phys(handle, linkid, &state); 3973d62bc4baSyz147064 if (state.ls_status != DLADM_STATUS_OK) { 3974d62bc4baSyz147064 die_dlerr(state.ls_status, 3975d62bc4baSyz147064 "failed to show physical link %s", argv[optind]); 3976d62bc4baSyz147064 } 3977d62bc4baSyz147064 } 39788002d411SSowmini Varadhan ofmt_close(ofmt); 3979d62bc4baSyz147064 } 3980d62bc4baSyz147064 3981d62bc4baSyz147064 static void 39828d5c46e6Sam223141 do_show_vlan(int argc, char *argv[], const char *use) 3983d62bc4baSyz147064 { 3984d62bc4baSyz147064 int option; 3985d62bc4baSyz147064 uint32_t flags = DLADM_OPT_ACTIVE; 3986d62bc4baSyz147064 boolean_t p_arg = B_FALSE; 3987d62bc4baSyz147064 datalink_id_t linkid = DATALINK_ALL_LINKID; 3988d62bc4baSyz147064 show_state_t state; 3989d62bc4baSyz147064 dladm_status_t status; 3990e7801d59Ssowmini boolean_t o_arg = B_FALSE; 3991e7801d59Ssowmini char *fields_str = NULL; 39928002d411SSowmini Varadhan ofmt_handle_t ofmt; 39938002d411SSowmini Varadhan ofmt_status_t oferr; 39948002d411SSowmini Varadhan uint_t ofmtflags = 0; 3995e7801d59Ssowmini 3996e7801d59Ssowmini bzero(&state, sizeof (state)); 3997d62bc4baSyz147064 3998d62bc4baSyz147064 opterr = 0; 3999e7801d59Ssowmini while ((option = getopt_long(argc, argv, ":pPo:", 4000d62bc4baSyz147064 show_lopts, NULL)) != -1) { 4001d62bc4baSyz147064 switch (option) { 4002d62bc4baSyz147064 case 'p': 4003d62bc4baSyz147064 if (p_arg) 4004d62bc4baSyz147064 die_optdup(option); 4005d62bc4baSyz147064 4006d62bc4baSyz147064 p_arg = B_TRUE; 4007d62bc4baSyz147064 break; 4008d62bc4baSyz147064 case 'P': 4009d62bc4baSyz147064 if (flags != DLADM_OPT_ACTIVE) 4010d62bc4baSyz147064 die_optdup(option); 4011d62bc4baSyz147064 4012d62bc4baSyz147064 flags = DLADM_OPT_PERSIST; 4013d62bc4baSyz147064 break; 4014e7801d59Ssowmini case 'o': 4015e7801d59Ssowmini o_arg = B_TRUE; 4016e7801d59Ssowmini fields_str = optarg; 4017e7801d59Ssowmini break; 4018d62bc4baSyz147064 default: 40198d5c46e6Sam223141 die_opterr(optopt, option, use); 4020d62bc4baSyz147064 break; 4021d62bc4baSyz147064 } 4022d62bc4baSyz147064 } 4023d62bc4baSyz147064 4024d62bc4baSyz147064 /* get link name (optional last argument) */ 4025d62bc4baSyz147064 if (optind == (argc-1)) { 40264ac67f02SAnurag S. Maskey if ((status = dladm_name2info(handle, argv[optind], &linkid, 40274ac67f02SAnurag S. Maskey NULL, NULL, NULL)) != DLADM_STATUS_OK) { 4028d62bc4baSyz147064 die_dlerr(status, "link %s is not valid", argv[optind]); 4029d62bc4baSyz147064 } 4030d62bc4baSyz147064 } else if (optind != argc) { 4031d62bc4baSyz147064 usage(); 4032d62bc4baSyz147064 } 4033d62bc4baSyz147064 40348002d411SSowmini Varadhan state.ls_parsable = p_arg; 4035d62bc4baSyz147064 state.ls_flags = flags; 4036d62bc4baSyz147064 state.ls_donefirst = B_FALSE; 4037d62bc4baSyz147064 4038e7801d59Ssowmini if (!o_arg || (o_arg && strcasecmp(fields_str, "all") == 0)) 40398002d411SSowmini Varadhan fields_str = NULL; 4040e7801d59Ssowmini 40418002d411SSowmini Varadhan if (state.ls_parsable) 40428002d411SSowmini Varadhan ofmtflags |= OFMT_PARSABLE; 40438002d411SSowmini Varadhan oferr = ofmt_open(fields_str, vlan_fields, ofmtflags, 0, &ofmt); 40448002d411SSowmini Varadhan dladm_ofmt_check(oferr, state.ls_parsable, ofmt); 40458002d411SSowmini Varadhan state.ls_ofmt = ofmt; 4046e7801d59Ssowmini 4047d62bc4baSyz147064 if (linkid == DATALINK_ALL_LINKID) { 40484ac67f02SAnurag S. Maskey (void) dladm_walk_datalink_id(show_vlan, handle, &state, 4049d62bc4baSyz147064 DATALINK_CLASS_VLAN, DATALINK_ANY_MEDIATYPE, flags); 4050d62bc4baSyz147064 } else { 40514ac67f02SAnurag S. Maskey (void) show_vlan(handle, linkid, &state); 4052d62bc4baSyz147064 if (state.ls_status != DLADM_STATUS_OK) { 4053d62bc4baSyz147064 die_dlerr(state.ls_status, "failed to show vlan %s", 4054d62bc4baSyz147064 argv[optind]); 4055d62bc4baSyz147064 } 4056d62bc4baSyz147064 } 40578002d411SSowmini Varadhan ofmt_close(ofmt); 4058d62bc4baSyz147064 } 4059d62bc4baSyz147064 4060d62bc4baSyz147064 static void 4061da14cebeSEric Cheng do_create_vnic(int argc, char *argv[], const char *use) 4062da14cebeSEric Cheng { 4063da14cebeSEric Cheng datalink_id_t linkid, dev_linkid; 4064da14cebeSEric Cheng char devname[MAXLINKNAMELEN]; 4065da14cebeSEric Cheng char name[MAXLINKNAMELEN]; 4066da14cebeSEric Cheng boolean_t l_arg = B_FALSE; 4067da14cebeSEric Cheng uint32_t flags = DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST; 4068da14cebeSEric Cheng char *altroot = NULL; 4069b509e89bSRishi Srivatsavai int option; 4070da14cebeSEric Cheng char *endp = NULL; 4071da14cebeSEric Cheng dladm_status_t status; 4072da14cebeSEric Cheng vnic_mac_addr_type_t mac_addr_type = VNIC_MAC_ADDR_TYPE_AUTO; 4073da14cebeSEric Cheng uchar_t *mac_addr; 4074da14cebeSEric Cheng int mac_slot = -1, maclen = 0, mac_prefix_len = 0; 407563a6526dSMichael Lim char propstr[DLADM_STRSIZE]; 4076da14cebeSEric Cheng dladm_arg_list_t *proplist = NULL; 4077285e94f9SMichael Lim int vid = 0; 4078da14cebeSEric Cheng 4079da14cebeSEric Cheng opterr = 0; 408063a6526dSMichael Lim bzero(propstr, DLADM_STRSIZE); 408163a6526dSMichael Lim 4082da14cebeSEric Cheng while ((option = getopt_long(argc, argv, ":tfR:l:m:n:p:r:v:H", 4083da14cebeSEric Cheng vnic_lopts, NULL)) != -1) { 4084da14cebeSEric Cheng switch (option) { 4085da14cebeSEric Cheng case 't': 4086da14cebeSEric Cheng flags &= ~DLADM_OPT_PERSIST; 4087da14cebeSEric Cheng break; 4088da14cebeSEric Cheng case 'R': 4089da14cebeSEric Cheng altroot = optarg; 4090da14cebeSEric Cheng break; 4091da14cebeSEric Cheng case 'l': 4092da14cebeSEric Cheng if (strlcpy(devname, optarg, MAXLINKNAMELEN) >= 4093da14cebeSEric Cheng MAXLINKNAMELEN) 4094da14cebeSEric Cheng die("link name too long"); 4095da14cebeSEric Cheng l_arg = B_TRUE; 4096da14cebeSEric Cheng break; 4097da14cebeSEric Cheng case 'm': 4098da14cebeSEric Cheng if (strcmp(optarg, "fixed") == 0) { 4099da14cebeSEric Cheng /* 4100da14cebeSEric Cheng * A fixed MAC address must be specified 4101da14cebeSEric Cheng * by its value, not by the keyword 'fixed'. 4102da14cebeSEric Cheng */ 4103da14cebeSEric Cheng die("'fixed' is not a valid MAC address"); 4104da14cebeSEric Cheng } 4105da14cebeSEric Cheng if (dladm_vnic_str2macaddrtype(optarg, 4106da14cebeSEric Cheng &mac_addr_type) != DLADM_STATUS_OK) { 4107da14cebeSEric Cheng mac_addr_type = VNIC_MAC_ADDR_TYPE_FIXED; 4108da14cebeSEric Cheng /* MAC address specified by value */ 4109da14cebeSEric Cheng mac_addr = _link_aton(optarg, &maclen); 4110da14cebeSEric Cheng if (mac_addr == NULL) { 4111da14cebeSEric Cheng if (maclen == -1) 4112da14cebeSEric Cheng die("invalid MAC address"); 4113da14cebeSEric Cheng else 4114da14cebeSEric Cheng die("out of memory"); 4115da14cebeSEric Cheng } 4116da14cebeSEric Cheng } 4117da14cebeSEric Cheng break; 4118da14cebeSEric Cheng case 'n': 4119da14cebeSEric Cheng errno = 0; 4120da14cebeSEric Cheng mac_slot = (int)strtol(optarg, &endp, 10); 4121da14cebeSEric Cheng if (errno != 0 || *endp != '\0') 4122da14cebeSEric Cheng die("invalid slot number"); 4123da14cebeSEric Cheng break; 4124da14cebeSEric Cheng case 'p': 412563a6526dSMichael Lim (void) strlcat(propstr, optarg, DLADM_STRSIZE); 412663a6526dSMichael Lim if (strlcat(propstr, ",", DLADM_STRSIZE) >= 412763a6526dSMichael Lim DLADM_STRSIZE) 412863a6526dSMichael Lim die("property list too long '%s'", propstr); 4129da14cebeSEric Cheng break; 4130da14cebeSEric Cheng case 'r': 4131da14cebeSEric Cheng mac_addr = _link_aton(optarg, &mac_prefix_len); 4132da14cebeSEric Cheng if (mac_addr == NULL) { 4133da14cebeSEric Cheng if (mac_prefix_len == -1) 4134da14cebeSEric Cheng die("invalid MAC address"); 4135da14cebeSEric Cheng else 4136da14cebeSEric Cheng die("out of memory"); 4137da14cebeSEric Cheng } 4138da14cebeSEric Cheng break; 4139da14cebeSEric Cheng case 'v': 4140285e94f9SMichael Lim if (vid != 0) 4141285e94f9SMichael Lim die_optdup(option); 4142285e94f9SMichael Lim 4143285e94f9SMichael Lim if (!str2int(optarg, &vid) || vid < 1 || vid > 4094) 4144285e94f9SMichael Lim die("invalid VLAN identifier '%s'", optarg); 4145285e94f9SMichael Lim 4146da14cebeSEric Cheng break; 4147da14cebeSEric Cheng case 'f': 4148da14cebeSEric Cheng flags |= DLADM_OPT_FORCE; 4149da14cebeSEric Cheng break; 4150da14cebeSEric Cheng case 'H': 4151da14cebeSEric Cheng flags |= DLADM_OPT_HWRINGS; 4152da14cebeSEric Cheng break; 4153da14cebeSEric Cheng default: 4154da14cebeSEric Cheng die_opterr(optopt, option, use); 4155da14cebeSEric Cheng } 4156da14cebeSEric Cheng } 4157da14cebeSEric Cheng 4158da14cebeSEric Cheng /* 4159da14cebeSEric Cheng * 'f' - force, flag can be specified only with 'v' - vlan. 4160da14cebeSEric Cheng */ 4161da14cebeSEric Cheng if ((flags & DLADM_OPT_FORCE) != 0 && vid == 0) 4162da14cebeSEric Cheng die("-f option can only be used with -v"); 4163da14cebeSEric Cheng 4164da14cebeSEric Cheng if (mac_prefix_len != 0 && mac_addr_type != VNIC_MAC_ADDR_TYPE_RANDOM && 4165da14cebeSEric Cheng mac_addr_type != VNIC_MAC_ADDR_TYPE_FIXED) 4166da14cebeSEric Cheng usage(); 4167da14cebeSEric Cheng 4168da14cebeSEric Cheng /* check required options */ 4169da14cebeSEric Cheng if (!l_arg) 4170da14cebeSEric Cheng usage(); 4171da14cebeSEric Cheng 4172da14cebeSEric Cheng if (mac_slot != -1 && mac_addr_type != VNIC_MAC_ADDR_TYPE_FACTORY) 4173da14cebeSEric Cheng usage(); 4174da14cebeSEric Cheng 4175da14cebeSEric Cheng /* the VNIC id is the required operand */ 4176da14cebeSEric Cheng if (optind != (argc - 1)) 4177da14cebeSEric Cheng usage(); 4178da14cebeSEric Cheng 4179da14cebeSEric Cheng if (strlcpy(name, argv[optind], MAXLINKNAMELEN) >= MAXLINKNAMELEN) 4180da14cebeSEric Cheng die("link name too long '%s'", argv[optind]); 4181da14cebeSEric Cheng 4182da14cebeSEric Cheng if (!dladm_valid_linkname(name)) 4183da14cebeSEric Cheng die("invalid link name '%s'", argv[optind]); 4184da14cebeSEric Cheng 4185da14cebeSEric Cheng if (altroot != NULL) 4186da14cebeSEric Cheng altroot_cmd(altroot, argc, argv); 4187da14cebeSEric Cheng 41884ac67f02SAnurag S. Maskey if (dladm_name2info(handle, devname, &dev_linkid, NULL, NULL, NULL) != 4189da14cebeSEric Cheng DLADM_STATUS_OK) 4190da14cebeSEric Cheng die("invalid link name '%s'", devname); 4191da14cebeSEric Cheng 419263a6526dSMichael Lim if (dladm_parse_link_props(propstr, &proplist, B_FALSE) 419363a6526dSMichael Lim != DLADM_STATUS_OK) 419463a6526dSMichael Lim die("invalid vnic property"); 419563a6526dSMichael Lim 41964ac67f02SAnurag S. Maskey status = dladm_vnic_create(handle, name, dev_linkid, mac_addr_type, 41974ac67f02SAnurag S. Maskey mac_addr, maclen, &mac_slot, mac_prefix_len, vid, &linkid, proplist, 41984ac67f02SAnurag S. Maskey flags); 4199da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 4200da14cebeSEric Cheng die_dlerr(status, "vnic creation over %s failed", devname); 4201da14cebeSEric Cheng 4202da14cebeSEric Cheng dladm_free_props(proplist); 4203da14cebeSEric Cheng } 4204da14cebeSEric Cheng 4205da14cebeSEric Cheng static void 4206da14cebeSEric Cheng do_etherstub_check(const char *name, datalink_id_t linkid, boolean_t etherstub, 4207da14cebeSEric Cheng uint32_t flags) 4208da14cebeSEric Cheng { 4209da14cebeSEric Cheng boolean_t is_etherstub; 4210da14cebeSEric Cheng dladm_vnic_attr_t attr; 4211da14cebeSEric Cheng 42124ac67f02SAnurag S. Maskey if (dladm_vnic_info(handle, linkid, &attr, flags) != DLADM_STATUS_OK) { 4213da14cebeSEric Cheng /* 4214da14cebeSEric Cheng * Let the delete continue anyway. 4215da14cebeSEric Cheng */ 4216da14cebeSEric Cheng return; 4217da14cebeSEric Cheng } 4218da14cebeSEric Cheng is_etherstub = (attr.va_link_id == DATALINK_INVALID_LINKID); 4219da14cebeSEric Cheng if (is_etherstub != etherstub) { 4220da14cebeSEric Cheng die("'%s' is not %s", name, 4221da14cebeSEric Cheng (is_etherstub ? "a vnic" : "an etherstub")); 4222da14cebeSEric Cheng } 4223da14cebeSEric Cheng } 4224da14cebeSEric Cheng 4225da14cebeSEric Cheng static void 4226da14cebeSEric Cheng do_delete_vnic_common(int argc, char *argv[], const char *use, 4227da14cebeSEric Cheng boolean_t etherstub) 4228da14cebeSEric Cheng { 4229b509e89bSRishi Srivatsavai int option; 4230da14cebeSEric Cheng uint32_t flags = DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST; 4231da14cebeSEric Cheng datalink_id_t linkid; 4232da14cebeSEric Cheng char *altroot = NULL; 4233da14cebeSEric Cheng dladm_status_t status; 4234da14cebeSEric Cheng 4235da14cebeSEric Cheng opterr = 0; 4236da14cebeSEric Cheng while ((option = getopt_long(argc, argv, ":R:t", lopts, 4237da14cebeSEric Cheng NULL)) != -1) { 4238da14cebeSEric Cheng switch (option) { 4239da14cebeSEric Cheng case 't': 4240da14cebeSEric Cheng flags &= ~DLADM_OPT_PERSIST; 4241da14cebeSEric Cheng break; 4242da14cebeSEric Cheng case 'R': 4243da14cebeSEric Cheng altroot = optarg; 4244da14cebeSEric Cheng break; 4245da14cebeSEric Cheng default: 4246da14cebeSEric Cheng die_opterr(optopt, option, use); 4247da14cebeSEric Cheng } 4248da14cebeSEric Cheng } 4249da14cebeSEric Cheng 4250da14cebeSEric Cheng /* get vnic name (required last argument) */ 4251da14cebeSEric Cheng if (optind != (argc - 1)) 4252da14cebeSEric Cheng usage(); 4253da14cebeSEric Cheng 4254da14cebeSEric Cheng if (altroot != NULL) 4255da14cebeSEric Cheng altroot_cmd(altroot, argc, argv); 4256da14cebeSEric Cheng 42574ac67f02SAnurag S. Maskey status = dladm_name2info(handle, argv[optind], &linkid, NULL, NULL, 42584ac67f02SAnurag S. Maskey NULL); 4259da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 4260da14cebeSEric Cheng die("invalid link name '%s'", argv[optind]); 4261da14cebeSEric Cheng 4262da14cebeSEric Cheng if ((flags & DLADM_OPT_ACTIVE) != 0) { 4263da14cebeSEric Cheng do_etherstub_check(argv[optind], linkid, etherstub, 4264da14cebeSEric Cheng DLADM_OPT_ACTIVE); 4265da14cebeSEric Cheng } 4266da14cebeSEric Cheng if ((flags & DLADM_OPT_PERSIST) != 0) { 4267da14cebeSEric Cheng do_etherstub_check(argv[optind], linkid, etherstub, 4268da14cebeSEric Cheng DLADM_OPT_PERSIST); 4269da14cebeSEric Cheng } 4270da14cebeSEric Cheng 42714ac67f02SAnurag S. Maskey status = dladm_vnic_delete(handle, linkid, flags); 4272da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 4273da14cebeSEric Cheng die_dlerr(status, "vnic deletion failed"); 4274da14cebeSEric Cheng } 4275da14cebeSEric Cheng 4276da14cebeSEric Cheng static void 4277da14cebeSEric Cheng do_delete_vnic(int argc, char *argv[], const char *use) 4278da14cebeSEric Cheng { 4279da14cebeSEric Cheng do_delete_vnic_common(argc, argv, use, B_FALSE); 4280da14cebeSEric Cheng } 4281da14cebeSEric Cheng 4282da14cebeSEric Cheng /* ARGSUSED */ 4283da14cebeSEric Cheng static void 4284da14cebeSEric Cheng do_up_vnic_common(int argc, char *argv[], const char *use, boolean_t vlan) 4285da14cebeSEric Cheng { 4286da14cebeSEric Cheng datalink_id_t linkid = DATALINK_ALL_LINKID; 4287da14cebeSEric Cheng dladm_status_t status; 4288da14cebeSEric Cheng char *type; 4289da14cebeSEric Cheng 4290da14cebeSEric Cheng type = vlan ? "vlan" : "vnic"; 4291da14cebeSEric Cheng 4292da14cebeSEric Cheng /* 4293da14cebeSEric Cheng * get the id or the name of the vnic/vlan (optional last argument) 4294da14cebeSEric Cheng */ 4295da14cebeSEric Cheng if (argc == 2) { 42964ac67f02SAnurag S. Maskey status = dladm_name2info(handle, argv[1], &linkid, NULL, NULL, 42974ac67f02SAnurag S. Maskey NULL); 4298da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 4299da14cebeSEric Cheng goto done; 4300da14cebeSEric Cheng 4301da14cebeSEric Cheng } else if (argc > 2) { 4302da14cebeSEric Cheng usage(); 4303da14cebeSEric Cheng } 4304da14cebeSEric Cheng 4305da14cebeSEric Cheng if (vlan) 43064ac67f02SAnurag S. Maskey status = dladm_vlan_up(handle, linkid); 4307da14cebeSEric Cheng else 43084ac67f02SAnurag S. Maskey status = dladm_vnic_up(handle, linkid, 0); 4309da14cebeSEric Cheng 4310da14cebeSEric Cheng done: 4311da14cebeSEric Cheng if (status != DLADM_STATUS_OK) { 4312da14cebeSEric Cheng if (argc == 2) { 4313da14cebeSEric Cheng die_dlerr(status, 4314da14cebeSEric Cheng "could not bring up %s '%s'", type, argv[1]); 4315da14cebeSEric Cheng } else { 4316da14cebeSEric Cheng die_dlerr(status, "could not bring %ss up", type); 4317da14cebeSEric Cheng } 4318da14cebeSEric Cheng } 4319da14cebeSEric Cheng } 4320da14cebeSEric Cheng 4321da14cebeSEric Cheng static void 4322da14cebeSEric Cheng do_up_vnic(int argc, char *argv[], const char *use) 4323da14cebeSEric Cheng { 4324da14cebeSEric Cheng do_up_vnic_common(argc, argv, use, B_FALSE); 4325da14cebeSEric Cheng } 4326da14cebeSEric Cheng 4327da14cebeSEric Cheng static void 4328da14cebeSEric Cheng dump_vnics_head(const char *dev) 4329da14cebeSEric Cheng { 4330da14cebeSEric Cheng if (strlen(dev)) 4331da14cebeSEric Cheng (void) printf("%s", dev); 4332da14cebeSEric Cheng 4333da14cebeSEric Cheng (void) printf("\tipackets rbytes opackets obytes "); 4334da14cebeSEric Cheng 4335da14cebeSEric Cheng if (strlen(dev)) 4336da14cebeSEric Cheng (void) printf("%%ipkts %%opkts\n"); 4337da14cebeSEric Cheng else 4338da14cebeSEric Cheng (void) printf("\n"); 4339da14cebeSEric Cheng } 4340da14cebeSEric Cheng 4341da14cebeSEric Cheng static void 4342da14cebeSEric Cheng dump_vnic_stat(const char *name, datalink_id_t vnic_id, 4343da14cebeSEric Cheng show_vnic_state_t *state, pktsum_t *vnic_stats, pktsum_t *tot_stats) 4344da14cebeSEric Cheng { 4345da14cebeSEric Cheng pktsum_t diff_stats; 4346da14cebeSEric Cheng pktsum_t *old_stats = &state->vs_prevstats[vnic_id]; 4347da14cebeSEric Cheng 4348da14cebeSEric Cheng dladm_stats_diff(&diff_stats, vnic_stats, old_stats); 4349da14cebeSEric Cheng 4350da14cebeSEric Cheng (void) printf("%s", name); 4351da14cebeSEric Cheng 4352da14cebeSEric Cheng (void) printf("\t%-10llu", diff_stats.ipackets); 4353da14cebeSEric Cheng (void) printf("%-12llu", diff_stats.rbytes); 4354da14cebeSEric Cheng (void) printf("%-10llu", diff_stats.opackets); 4355da14cebeSEric Cheng (void) printf("%-12llu", diff_stats.obytes); 4356da14cebeSEric Cheng 4357da14cebeSEric Cheng if (tot_stats) { 4358da14cebeSEric Cheng if (tot_stats->ipackets == 0) { 4359da14cebeSEric Cheng (void) printf("\t-"); 4360da14cebeSEric Cheng } else { 4361da14cebeSEric Cheng (void) printf("\t%-6.1f", (double)diff_stats.ipackets/ 4362da14cebeSEric Cheng (double)tot_stats->ipackets * 100); 4363da14cebeSEric Cheng } 4364da14cebeSEric Cheng if (tot_stats->opackets == 0) { 4365da14cebeSEric Cheng (void) printf("\t-"); 4366da14cebeSEric Cheng } else { 4367da14cebeSEric Cheng (void) printf("\t%-6.1f", (double)diff_stats.opackets/ 4368da14cebeSEric Cheng (double)tot_stats->opackets * 100); 4369da14cebeSEric Cheng } 4370da14cebeSEric Cheng } 4371da14cebeSEric Cheng (void) printf("\n"); 4372da14cebeSEric Cheng 4373da14cebeSEric Cheng *old_stats = *vnic_stats; 4374da14cebeSEric Cheng } 4375da14cebeSEric Cheng 4376da14cebeSEric Cheng /* 4377da14cebeSEric Cheng * Called from the walker dladm_vnic_walk_sys() for each vnic to display 4378da14cebeSEric Cheng * vnic information or statistics. 4379da14cebeSEric Cheng */ 4380da14cebeSEric Cheng static dladm_status_t 4381da14cebeSEric Cheng print_vnic(show_vnic_state_t *state, datalink_id_t linkid) 4382da14cebeSEric Cheng { 4383da14cebeSEric Cheng dladm_vnic_attr_t attr, *vnic = &attr; 4384da14cebeSEric Cheng dladm_status_t status; 4385da14cebeSEric Cheng boolean_t is_etherstub; 4386da14cebeSEric Cheng char devname[MAXLINKNAMELEN]; 4387da14cebeSEric Cheng char vnic_name[MAXLINKNAMELEN]; 4388da14cebeSEric Cheng char mstr[MAXMACADDRLEN * 3]; 4389da14cebeSEric Cheng vnic_fields_buf_t vbuf; 4390da14cebeSEric Cheng 43914ac67f02SAnurag S. Maskey if ((status = dladm_vnic_info(handle, linkid, vnic, state->vs_flags)) != 4392da14cebeSEric Cheng DLADM_STATUS_OK) 4393da14cebeSEric Cheng return (status); 4394da14cebeSEric Cheng 4395da14cebeSEric Cheng is_etherstub = (vnic->va_link_id == DATALINK_INVALID_LINKID); 4396da14cebeSEric Cheng if (state->vs_etherstub != is_etherstub) { 4397da14cebeSEric Cheng /* 4398da14cebeSEric Cheng * Want all etherstub but it's not one, or want 4399da14cebeSEric Cheng * non-etherstub and it's one. 4400da14cebeSEric Cheng */ 4401da14cebeSEric Cheng return (DLADM_STATUS_OK); 4402da14cebeSEric Cheng } 4403da14cebeSEric Cheng 4404da14cebeSEric Cheng if (state->vs_link_id != DATALINK_ALL_LINKID) { 4405da14cebeSEric Cheng if (state->vs_link_id != vnic->va_link_id) 4406da14cebeSEric Cheng return (DLADM_STATUS_OK); 4407da14cebeSEric Cheng } 4408da14cebeSEric Cheng 44094ac67f02SAnurag S. Maskey if (dladm_datalink_id2info(handle, linkid, NULL, NULL, 4410da14cebeSEric Cheng NULL, vnic_name, sizeof (vnic_name)) != DLADM_STATUS_OK) 4411da14cebeSEric Cheng return (DLADM_STATUS_BADARG); 4412da14cebeSEric Cheng 4413da14cebeSEric Cheng bzero(devname, sizeof (devname)); 4414da14cebeSEric Cheng if (!is_etherstub && 44154ac67f02SAnurag S. Maskey dladm_datalink_id2info(handle, vnic->va_link_id, NULL, NULL, 4416da14cebeSEric Cheng NULL, devname, sizeof (devname)) != DLADM_STATUS_OK) 4417da14cebeSEric Cheng return (DLADM_STATUS_BADARG); 4418da14cebeSEric Cheng 4419da14cebeSEric Cheng state->vs_found = B_TRUE; 4420da14cebeSEric Cheng if (state->vs_stats) { 4421da14cebeSEric Cheng /* print vnic statistics */ 4422da14cebeSEric Cheng pktsum_t vnic_stats; 4423da14cebeSEric Cheng 4424da14cebeSEric Cheng if (state->vs_firstonly) { 4425da14cebeSEric Cheng if (state->vs_donefirst) 4426da14cebeSEric Cheng return (0); 4427da14cebeSEric Cheng state->vs_donefirst = B_TRUE; 4428da14cebeSEric Cheng } 4429da14cebeSEric Cheng 4430da14cebeSEric Cheng if (!state->vs_printstats) { 4431da14cebeSEric Cheng /* 4432da14cebeSEric Cheng * get vnic statistics and add to the sum for the 4433da14cebeSEric Cheng * named device. 4434da14cebeSEric Cheng */ 4435da14cebeSEric Cheng get_link_stats(vnic_name, &vnic_stats); 4436da14cebeSEric Cheng dladm_stats_total(&state->vs_totalstats, &vnic_stats, 4437da14cebeSEric Cheng &state->vs_prevstats[vnic->va_vnic_id]); 4438da14cebeSEric Cheng } else { 4439da14cebeSEric Cheng /* get and print vnic statistics */ 4440da14cebeSEric Cheng get_link_stats(vnic_name, &vnic_stats); 4441da14cebeSEric Cheng dump_vnic_stat(vnic_name, linkid, state, &vnic_stats, 4442da14cebeSEric Cheng &state->vs_totalstats); 4443da14cebeSEric Cheng } 4444da14cebeSEric Cheng return (DLADM_STATUS_OK); 4445da14cebeSEric Cheng } else { 4446da14cebeSEric Cheng (void) snprintf(vbuf.vnic_link, sizeof (vbuf.vnic_link), 4447da14cebeSEric Cheng "%s", vnic_name); 4448da14cebeSEric Cheng 4449da14cebeSEric Cheng if (!is_etherstub) { 4450da14cebeSEric Cheng 4451da14cebeSEric Cheng (void) snprintf(vbuf.vnic_over, sizeof (vbuf.vnic_over), 4452da14cebeSEric Cheng "%s", devname); 4453da14cebeSEric Cheng (void) snprintf(vbuf.vnic_speed, 4454da14cebeSEric Cheng sizeof (vbuf.vnic_speed), "%u", 4455da14cebeSEric Cheng (uint_t)((get_ifspeed(vnic_name, B_TRUE)) 4456da14cebeSEric Cheng / 1000000ull)); 4457da14cebeSEric Cheng 4458da14cebeSEric Cheng switch (vnic->va_mac_addr_type) { 4459da14cebeSEric Cheng case VNIC_MAC_ADDR_TYPE_FIXED: 4460da14cebeSEric Cheng case VNIC_MAC_ADDR_TYPE_PRIMARY: 4461da14cebeSEric Cheng (void) snprintf(vbuf.vnic_macaddrtype, 4462da14cebeSEric Cheng sizeof (vbuf.vnic_macaddrtype), 4463da14cebeSEric Cheng gettext("fixed")); 4464da14cebeSEric Cheng break; 4465da14cebeSEric Cheng case VNIC_MAC_ADDR_TYPE_RANDOM: 4466da14cebeSEric Cheng (void) snprintf(vbuf.vnic_macaddrtype, 4467da14cebeSEric Cheng sizeof (vbuf.vnic_macaddrtype), 4468da14cebeSEric Cheng gettext("random")); 4469da14cebeSEric Cheng break; 4470da14cebeSEric Cheng case VNIC_MAC_ADDR_TYPE_FACTORY: 4471da14cebeSEric Cheng (void) snprintf(vbuf.vnic_macaddrtype, 4472da14cebeSEric Cheng sizeof (vbuf.vnic_macaddrtype), 4473da14cebeSEric Cheng gettext("factory, slot %d"), 4474da14cebeSEric Cheng vnic->va_mac_slot); 4475da14cebeSEric Cheng break; 4476da14cebeSEric Cheng } 4477da14cebeSEric Cheng 4478da14cebeSEric Cheng if (strlen(vbuf.vnic_macaddrtype) > 0) { 4479da14cebeSEric Cheng (void) snprintf(vbuf.vnic_macaddr, 4480da14cebeSEric Cheng sizeof (vbuf.vnic_macaddr), "%s", 4481da14cebeSEric Cheng dladm_aggr_macaddr2str(vnic->va_mac_addr, 4482da14cebeSEric Cheng mstr)); 4483da14cebeSEric Cheng } 4484da14cebeSEric Cheng 4485da14cebeSEric Cheng (void) snprintf(vbuf.vnic_vid, sizeof (vbuf.vnic_vid), 4486da14cebeSEric Cheng "%d", vnic->va_vid); 4487da14cebeSEric Cheng } 4488da14cebeSEric Cheng 44898002d411SSowmini Varadhan ofmt_print(state->vs_ofmt, &vbuf); 4490da14cebeSEric Cheng 4491da14cebeSEric Cheng return (DLADM_STATUS_OK); 4492da14cebeSEric Cheng } 4493da14cebeSEric Cheng } 4494da14cebeSEric Cheng 44954ac67f02SAnurag S. Maskey /* ARGSUSED */ 4496da14cebeSEric Cheng static int 44974ac67f02SAnurag S. Maskey show_vnic(dladm_handle_t dh, datalink_id_t linkid, void *arg) 4498da14cebeSEric Cheng { 4499da14cebeSEric Cheng show_vnic_state_t *state = arg; 4500da14cebeSEric Cheng 4501da14cebeSEric Cheng state->vs_status = print_vnic(state, linkid); 4502da14cebeSEric Cheng return (DLADM_WALK_CONTINUE); 4503da14cebeSEric Cheng } 4504da14cebeSEric Cheng 4505da14cebeSEric Cheng static void 4506da14cebeSEric Cheng do_show_vnic_common(int argc, char *argv[], const char *use, 4507da14cebeSEric Cheng boolean_t etherstub) 4508da14cebeSEric Cheng { 4509da14cebeSEric Cheng int option; 4510da14cebeSEric Cheng boolean_t s_arg = B_FALSE; 4511da14cebeSEric Cheng boolean_t i_arg = B_FALSE; 4512da14cebeSEric Cheng boolean_t l_arg = B_FALSE; 4513da14cebeSEric Cheng uint32_t interval = 0, flags = DLADM_OPT_ACTIVE; 4514da14cebeSEric Cheng datalink_id_t linkid = DATALINK_ALL_LINKID; 4515da14cebeSEric Cheng datalink_id_t dev_linkid = DATALINK_ALL_LINKID; 4516da14cebeSEric Cheng show_vnic_state_t state; 4517da14cebeSEric Cheng dladm_status_t status; 4518da14cebeSEric Cheng boolean_t o_arg = B_FALSE; 4519da14cebeSEric Cheng char *fields_str = NULL; 45208002d411SSowmini Varadhan ofmt_field_t *pf; 45218002d411SSowmini Varadhan char *all_e_fields = "link"; 45228002d411SSowmini Varadhan ofmt_handle_t ofmt; 45238002d411SSowmini Varadhan ofmt_status_t oferr; 45248002d411SSowmini Varadhan uint_t ofmtflags = 0; 4525da14cebeSEric Cheng 4526da14cebeSEric Cheng bzero(&state, sizeof (state)); 4527da14cebeSEric Cheng opterr = 0; 4528da14cebeSEric Cheng while ((option = getopt_long(argc, argv, ":pPl:si:o:", lopts, 4529da14cebeSEric Cheng NULL)) != -1) { 4530da14cebeSEric Cheng switch (option) { 4531da14cebeSEric Cheng case 'p': 45328002d411SSowmini Varadhan state.vs_parsable = B_TRUE; 4533da14cebeSEric Cheng break; 4534da14cebeSEric Cheng case 'P': 4535da14cebeSEric Cheng flags = DLADM_OPT_PERSIST; 4536da14cebeSEric Cheng break; 4537da14cebeSEric Cheng case 'l': 4538da14cebeSEric Cheng if (etherstub) 4539da14cebeSEric Cheng die("option not supported for this command"); 4540da14cebeSEric Cheng 4541da14cebeSEric Cheng if (strlcpy(state.vs_link, optarg, MAXLINKNAMELEN) >= 4542da14cebeSEric Cheng MAXLINKNAMELEN) 4543da14cebeSEric Cheng die("link name too long"); 4544da14cebeSEric Cheng 4545da14cebeSEric Cheng l_arg = B_TRUE; 4546da14cebeSEric Cheng break; 4547da14cebeSEric Cheng case 's': 4548da14cebeSEric Cheng if (s_arg) { 4549da14cebeSEric Cheng die("the option -s cannot be specified " 4550da14cebeSEric Cheng "more than once"); 4551da14cebeSEric Cheng } 4552da14cebeSEric Cheng s_arg = B_TRUE; 4553da14cebeSEric Cheng break; 4554da14cebeSEric Cheng case 'i': 4555da14cebeSEric Cheng if (i_arg) { 4556da14cebeSEric Cheng die("the option -i cannot be specified " 4557da14cebeSEric Cheng "more than once"); 4558da14cebeSEric Cheng } 4559da14cebeSEric Cheng i_arg = B_TRUE; 456063a6526dSMichael Lim if (!dladm_str2interval(optarg, &interval)) 4561da14cebeSEric Cheng die("invalid interval value '%s'", optarg); 4562da14cebeSEric Cheng break; 4563da14cebeSEric Cheng case 'o': 4564da14cebeSEric Cheng o_arg = B_TRUE; 4565da14cebeSEric Cheng fields_str = optarg; 4566da14cebeSEric Cheng break; 4567da14cebeSEric Cheng default: 4568da14cebeSEric Cheng die_opterr(optopt, option, use); 4569da14cebeSEric Cheng } 4570da14cebeSEric Cheng } 4571da14cebeSEric Cheng 4572da14cebeSEric Cheng if (i_arg && !s_arg) 4573da14cebeSEric Cheng die("the option -i can be used only with -s"); 4574da14cebeSEric Cheng 4575da14cebeSEric Cheng /* get vnic ID (optional last argument) */ 4576da14cebeSEric Cheng if (optind == (argc - 1)) { 45774ac67f02SAnurag S. Maskey status = dladm_name2info(handle, argv[optind], &linkid, NULL, 4578da14cebeSEric Cheng NULL, NULL); 4579da14cebeSEric Cheng if (status != DLADM_STATUS_OK) { 4580da14cebeSEric Cheng die_dlerr(status, "invalid vnic name '%s'", 4581da14cebeSEric Cheng argv[optind]); 4582da14cebeSEric Cheng } 4583da14cebeSEric Cheng (void) strlcpy(state.vs_vnic, argv[optind], MAXLINKNAMELEN); 4584da14cebeSEric Cheng } else if (optind != argc) { 4585da14cebeSEric Cheng usage(); 4586da14cebeSEric Cheng } 4587da14cebeSEric Cheng 4588da14cebeSEric Cheng if (l_arg) { 45894ac67f02SAnurag S. Maskey status = dladm_name2info(handle, state.vs_link, &dev_linkid, 45904ac67f02SAnurag S. Maskey NULL, NULL, NULL); 4591da14cebeSEric Cheng if (status != DLADM_STATUS_OK) { 4592da14cebeSEric Cheng die_dlerr(status, "invalid link name '%s'", 4593da14cebeSEric Cheng state.vs_link); 4594da14cebeSEric Cheng } 4595da14cebeSEric Cheng } 4596da14cebeSEric Cheng 4597da14cebeSEric Cheng state.vs_vnic_id = linkid; 4598da14cebeSEric Cheng state.vs_link_id = dev_linkid; 4599da14cebeSEric Cheng state.vs_etherstub = etherstub; 4600da14cebeSEric Cheng state.vs_found = B_FALSE; 4601da14cebeSEric Cheng state.vs_flags = flags; 4602da14cebeSEric Cheng 4603da14cebeSEric Cheng if (!o_arg || (o_arg && strcasecmp(fields_str, "all") == 0)) { 4604da14cebeSEric Cheng if (etherstub) 4605da14cebeSEric Cheng fields_str = all_e_fields; 4606da14cebeSEric Cheng } 4607da14cebeSEric Cheng pf = vnic_fields; 4608da14cebeSEric Cheng 46098002d411SSowmini Varadhan if (state.vs_parsable) 46108002d411SSowmini Varadhan ofmtflags |= OFMT_PARSABLE; 46118002d411SSowmini Varadhan oferr = ofmt_open(fields_str, pf, ofmtflags, 0, &ofmt); 46128002d411SSowmini Varadhan dladm_ofmt_check(oferr, state.vs_parsable, ofmt); 46138002d411SSowmini Varadhan state.vs_ofmt = ofmt; 4614da14cebeSEric Cheng 4615da14cebeSEric Cheng if (s_arg) { 4616da14cebeSEric Cheng /* Display vnic statistics */ 4617da14cebeSEric Cheng vnic_stats(&state, interval); 46188002d411SSowmini Varadhan ofmt_close(ofmt); 4619da14cebeSEric Cheng return; 4620da14cebeSEric Cheng } 4621da14cebeSEric Cheng 4622da14cebeSEric Cheng /* Display vnic information */ 4623da14cebeSEric Cheng state.vs_donefirst = B_FALSE; 4624da14cebeSEric Cheng 4625da14cebeSEric Cheng if (linkid == DATALINK_ALL_LINKID) { 46264ac67f02SAnurag S. Maskey (void) dladm_walk_datalink_id(show_vnic, handle, &state, 4627da14cebeSEric Cheng DATALINK_CLASS_VNIC | DATALINK_CLASS_ETHERSTUB, 4628c3affd82SMichael Lim DATALINK_ANY_MEDIATYPE, flags); 4629da14cebeSEric Cheng } else { 46304ac67f02SAnurag S. Maskey (void) show_vnic(handle, linkid, &state); 4631da14cebeSEric Cheng if (state.vs_status != DLADM_STATUS_OK) { 46328002d411SSowmini Varadhan ofmt_close(ofmt); 4633da14cebeSEric Cheng die_dlerr(state.vs_status, "failed to show vnic '%s'", 4634da14cebeSEric Cheng state.vs_vnic); 4635da14cebeSEric Cheng } 4636da14cebeSEric Cheng } 46378002d411SSowmini Varadhan ofmt_close(ofmt); 4638da14cebeSEric Cheng } 4639da14cebeSEric Cheng 4640da14cebeSEric Cheng static void 4641da14cebeSEric Cheng do_show_vnic(int argc, char *argv[], const char *use) 4642da14cebeSEric Cheng { 4643da14cebeSEric Cheng do_show_vnic_common(argc, argv, use, B_FALSE); 4644da14cebeSEric Cheng } 4645da14cebeSEric Cheng 4646da14cebeSEric Cheng static void 4647da14cebeSEric Cheng do_create_etherstub(int argc, char *argv[], const char *use) 4648da14cebeSEric Cheng { 4649da14cebeSEric Cheng uint32_t flags; 4650da14cebeSEric Cheng char *altroot = NULL; 4651b509e89bSRishi Srivatsavai int option; 4652da14cebeSEric Cheng dladm_status_t status; 4653da14cebeSEric Cheng char name[MAXLINKNAMELEN]; 4654da14cebeSEric Cheng uchar_t mac_addr[ETHERADDRL]; 4655da14cebeSEric Cheng 4656da14cebeSEric Cheng name[0] = '\0'; 4657da14cebeSEric Cheng bzero(mac_addr, sizeof (mac_addr)); 4658da14cebeSEric Cheng flags = DLADM_OPT_ANCHOR | DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST; 4659da14cebeSEric Cheng 4660da14cebeSEric Cheng opterr = 0; 4661da14cebeSEric Cheng while ((option = getopt_long(argc, argv, "tR:", 4662da14cebeSEric Cheng etherstub_lopts, NULL)) != -1) { 4663da14cebeSEric Cheng switch (option) { 4664da14cebeSEric Cheng case 't': 4665da14cebeSEric Cheng flags &= ~DLADM_OPT_PERSIST; 4666da14cebeSEric Cheng break; 4667da14cebeSEric Cheng case 'R': 4668da14cebeSEric Cheng altroot = optarg; 4669da14cebeSEric Cheng break; 4670da14cebeSEric Cheng default: 4671da14cebeSEric Cheng die_opterr(optopt, option, use); 4672da14cebeSEric Cheng } 4673da14cebeSEric Cheng } 4674da14cebeSEric Cheng 4675da14cebeSEric Cheng /* the etherstub id is the required operand */ 4676da14cebeSEric Cheng if (optind != (argc - 1)) 4677da14cebeSEric Cheng usage(); 4678da14cebeSEric Cheng 4679da14cebeSEric Cheng if (strlcpy(name, argv[optind], MAXLINKNAMELEN) >= MAXLINKNAMELEN) 4680da14cebeSEric Cheng die("link name too long '%s'", argv[optind]); 4681da14cebeSEric Cheng 4682da14cebeSEric Cheng if (!dladm_valid_linkname(name)) 4683da14cebeSEric Cheng die("invalid link name '%s'", argv[optind]); 4684da14cebeSEric Cheng 4685da14cebeSEric Cheng if (altroot != NULL) 4686da14cebeSEric Cheng altroot_cmd(altroot, argc, argv); 4687da14cebeSEric Cheng 46884ac67f02SAnurag S. Maskey status = dladm_vnic_create(handle, name, DATALINK_INVALID_LINKID, 4689da14cebeSEric Cheng VNIC_MAC_ADDR_TYPE_AUTO, mac_addr, ETHERADDRL, NULL, 0, 0, NULL, 4690da14cebeSEric Cheng NULL, flags); 4691da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 4692da14cebeSEric Cheng die_dlerr(status, "etherstub creation failed"); 4693da14cebeSEric Cheng } 4694da14cebeSEric Cheng 4695da14cebeSEric Cheng static void 4696da14cebeSEric Cheng do_delete_etherstub(int argc, char *argv[], const char *use) 4697da14cebeSEric Cheng { 4698da14cebeSEric Cheng do_delete_vnic_common(argc, argv, use, B_TRUE); 4699da14cebeSEric Cheng } 4700da14cebeSEric Cheng 4701da14cebeSEric Cheng /* ARGSUSED */ 4702da14cebeSEric Cheng static void 4703da14cebeSEric Cheng do_show_etherstub(int argc, char *argv[], const char *use) 4704da14cebeSEric Cheng { 4705da14cebeSEric Cheng do_show_vnic_common(argc, argv, use, B_TRUE); 4706da14cebeSEric Cheng } 4707da14cebeSEric Cheng 4708b509e89bSRishi Srivatsavai /* ARGSUSED */ 4709b509e89bSRishi Srivatsavai static void 4710b509e89bSRishi Srivatsavai do_up_simnet(int argc, char *argv[], const char *use) 4711b509e89bSRishi Srivatsavai { 4712b509e89bSRishi Srivatsavai (void) dladm_simnet_up(handle, DATALINK_ALL_LINKID, 0); 4713b509e89bSRishi Srivatsavai } 4714b509e89bSRishi Srivatsavai 4715b509e89bSRishi Srivatsavai static void 4716b509e89bSRishi Srivatsavai do_create_simnet(int argc, char *argv[], const char *use) 4717b509e89bSRishi Srivatsavai { 4718b509e89bSRishi Srivatsavai uint32_t flags; 4719b509e89bSRishi Srivatsavai char *altroot = NULL; 4720b509e89bSRishi Srivatsavai char *media = NULL; 4721b509e89bSRishi Srivatsavai uint32_t mtype = DL_ETHER; 4722b509e89bSRishi Srivatsavai int option; 4723b509e89bSRishi Srivatsavai dladm_status_t status; 4724b509e89bSRishi Srivatsavai char name[MAXLINKNAMELEN]; 4725b509e89bSRishi Srivatsavai 4726b509e89bSRishi Srivatsavai name[0] = '\0'; 4727b509e89bSRishi Srivatsavai flags = DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST; 4728b509e89bSRishi Srivatsavai 4729b509e89bSRishi Srivatsavai opterr = 0; 4730b509e89bSRishi Srivatsavai while ((option = getopt_long(argc, argv, ":tR:m:", 4731b509e89bSRishi Srivatsavai simnet_lopts, NULL)) != -1) { 4732b509e89bSRishi Srivatsavai switch (option) { 4733b509e89bSRishi Srivatsavai case 't': 4734b509e89bSRishi Srivatsavai flags &= ~DLADM_OPT_PERSIST; 4735b509e89bSRishi Srivatsavai break; 4736b509e89bSRishi Srivatsavai case 'R': 4737b509e89bSRishi Srivatsavai altroot = optarg; 4738b509e89bSRishi Srivatsavai break; 4739b509e89bSRishi Srivatsavai case 'm': 4740b509e89bSRishi Srivatsavai media = optarg; 4741b509e89bSRishi Srivatsavai break; 4742b509e89bSRishi Srivatsavai default: 4743b509e89bSRishi Srivatsavai die_opterr(optopt, option, use); 4744b509e89bSRishi Srivatsavai } 4745b509e89bSRishi Srivatsavai } 4746b509e89bSRishi Srivatsavai 4747b509e89bSRishi Srivatsavai /* the simnet id is the required operand */ 4748b509e89bSRishi Srivatsavai if (optind != (argc - 1)) 4749b509e89bSRishi Srivatsavai usage(); 4750b509e89bSRishi Srivatsavai 4751b509e89bSRishi Srivatsavai if (strlcpy(name, argv[optind], MAXLINKNAMELEN) >= MAXLINKNAMELEN) 4752b509e89bSRishi Srivatsavai die("link name too long '%s'", argv[optind]); 4753b509e89bSRishi Srivatsavai 4754b509e89bSRishi Srivatsavai if (!dladm_valid_linkname(name)) 4755b509e89bSRishi Srivatsavai die("invalid link name '%s'", name); 4756b509e89bSRishi Srivatsavai 4757b509e89bSRishi Srivatsavai if (media != NULL) { 4758b509e89bSRishi Srivatsavai mtype = dladm_str2media(media); 4759b509e89bSRishi Srivatsavai if (mtype != DL_ETHER && mtype != DL_WIFI) 4760b509e89bSRishi Srivatsavai die("media type '%s' is not supported", media); 4761b509e89bSRishi Srivatsavai } 4762b509e89bSRishi Srivatsavai 4763b509e89bSRishi Srivatsavai if (altroot != NULL) 4764b509e89bSRishi Srivatsavai altroot_cmd(altroot, argc, argv); 4765b509e89bSRishi Srivatsavai 4766b509e89bSRishi Srivatsavai status = dladm_simnet_create(handle, name, mtype, flags); 4767b509e89bSRishi Srivatsavai if (status != DLADM_STATUS_OK) 4768b509e89bSRishi Srivatsavai die_dlerr(status, "simnet creation failed"); 4769b509e89bSRishi Srivatsavai } 4770b509e89bSRishi Srivatsavai 4771b509e89bSRishi Srivatsavai static void 4772b509e89bSRishi Srivatsavai do_delete_simnet(int argc, char *argv[], const char *use) 4773b509e89bSRishi Srivatsavai { 4774b509e89bSRishi Srivatsavai int option; 4775b509e89bSRishi Srivatsavai uint32_t flags = DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST; 4776b509e89bSRishi Srivatsavai datalink_id_t linkid; 4777b509e89bSRishi Srivatsavai char *altroot = NULL; 4778b509e89bSRishi Srivatsavai dladm_status_t status; 4779b509e89bSRishi Srivatsavai dladm_simnet_attr_t slinfo; 4780b509e89bSRishi Srivatsavai 4781b509e89bSRishi Srivatsavai opterr = 0; 4782b509e89bSRishi Srivatsavai while ((option = getopt_long(argc, argv, ":tR:", simnet_lopts, 4783b509e89bSRishi Srivatsavai NULL)) != -1) { 4784b509e89bSRishi Srivatsavai switch (option) { 4785b509e89bSRishi Srivatsavai case 't': 4786b509e89bSRishi Srivatsavai flags &= ~DLADM_OPT_PERSIST; 4787b509e89bSRishi Srivatsavai break; 4788b509e89bSRishi Srivatsavai case 'R': 4789b509e89bSRishi Srivatsavai altroot = optarg; 4790b509e89bSRishi Srivatsavai break; 4791b509e89bSRishi Srivatsavai default: 4792b509e89bSRishi Srivatsavai die_opterr(optopt, option, use); 4793b509e89bSRishi Srivatsavai } 4794b509e89bSRishi Srivatsavai } 4795b509e89bSRishi Srivatsavai 4796b509e89bSRishi Srivatsavai /* get simnet name (required last argument) */ 4797b509e89bSRishi Srivatsavai if (optind != (argc - 1)) 4798b509e89bSRishi Srivatsavai usage(); 4799b509e89bSRishi Srivatsavai 4800b509e89bSRishi Srivatsavai if (!dladm_valid_linkname(argv[optind])) 4801b509e89bSRishi Srivatsavai die("invalid link name '%s'", argv[optind]); 4802b509e89bSRishi Srivatsavai 4803b509e89bSRishi Srivatsavai if (altroot != NULL) 4804b509e89bSRishi Srivatsavai altroot_cmd(altroot, argc, argv); 4805b509e89bSRishi Srivatsavai 4806b509e89bSRishi Srivatsavai status = dladm_name2info(handle, argv[optind], &linkid, NULL, NULL, 4807b509e89bSRishi Srivatsavai NULL); 4808b509e89bSRishi Srivatsavai if (status != DLADM_STATUS_OK) 4809b509e89bSRishi Srivatsavai die("simnet '%s' not found", argv[optind]); 4810b509e89bSRishi Srivatsavai 4811b509e89bSRishi Srivatsavai if ((status = dladm_simnet_info(handle, linkid, &slinfo, 4812b509e89bSRishi Srivatsavai flags)) != DLADM_STATUS_OK) 4813b509e89bSRishi Srivatsavai die_dlerr(status, "failed to retrieve simnet information"); 4814b509e89bSRishi Srivatsavai 4815b509e89bSRishi Srivatsavai status = dladm_simnet_delete(handle, linkid, flags); 4816b509e89bSRishi Srivatsavai if (status != DLADM_STATUS_OK) 4817b509e89bSRishi Srivatsavai die_dlerr(status, "simnet deletion failed"); 4818b509e89bSRishi Srivatsavai } 4819b509e89bSRishi Srivatsavai 4820b509e89bSRishi Srivatsavai static void 4821b509e89bSRishi Srivatsavai do_modify_simnet(int argc, char *argv[], const char *use) 4822b509e89bSRishi Srivatsavai { 4823b509e89bSRishi Srivatsavai int option; 4824b509e89bSRishi Srivatsavai uint32_t flags = DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST; 4825b509e89bSRishi Srivatsavai datalink_id_t linkid; 4826b509e89bSRishi Srivatsavai datalink_id_t peer_linkid; 4827b509e89bSRishi Srivatsavai char *altroot = NULL; 4828b509e89bSRishi Srivatsavai dladm_status_t status; 4829b509e89bSRishi Srivatsavai boolean_t p_arg = B_FALSE; 4830b509e89bSRishi Srivatsavai 4831b509e89bSRishi Srivatsavai opterr = 0; 4832b509e89bSRishi Srivatsavai while ((option = getopt_long(argc, argv, ":tR:p:", simnet_lopts, 4833b509e89bSRishi Srivatsavai NULL)) != -1) { 4834b509e89bSRishi Srivatsavai switch (option) { 4835b509e89bSRishi Srivatsavai case 't': 4836b509e89bSRishi Srivatsavai flags &= ~DLADM_OPT_PERSIST; 4837b509e89bSRishi Srivatsavai break; 4838b509e89bSRishi Srivatsavai case 'R': 4839b509e89bSRishi Srivatsavai altroot = optarg; 4840b509e89bSRishi Srivatsavai break; 4841b509e89bSRishi Srivatsavai case 'p': 4842b509e89bSRishi Srivatsavai if (p_arg) 4843b509e89bSRishi Srivatsavai die_optdup(option); 4844b509e89bSRishi Srivatsavai p_arg = B_TRUE; 4845b509e89bSRishi Srivatsavai if (strcasecmp(optarg, "none") == 0) 4846b509e89bSRishi Srivatsavai peer_linkid = DATALINK_INVALID_LINKID; 4847b509e89bSRishi Srivatsavai else if (dladm_name2info(handle, optarg, &peer_linkid, 4848b509e89bSRishi Srivatsavai NULL, NULL, NULL) != DLADM_STATUS_OK) 4849b509e89bSRishi Srivatsavai die("invalid peer link name '%s'", optarg); 4850b509e89bSRishi Srivatsavai break; 4851b509e89bSRishi Srivatsavai default: 4852b509e89bSRishi Srivatsavai die_opterr(optopt, option, use); 4853b509e89bSRishi Srivatsavai } 4854b509e89bSRishi Srivatsavai } 4855b509e89bSRishi Srivatsavai 4856b509e89bSRishi Srivatsavai /* get simnet name (required last argument) */ 4857b509e89bSRishi Srivatsavai if (optind != (argc - 1)) 4858b509e89bSRishi Srivatsavai usage(); 4859b509e89bSRishi Srivatsavai 4860b509e89bSRishi Srivatsavai /* Nothing to do if no peer link argument */ 4861b509e89bSRishi Srivatsavai if (!p_arg) 4862b509e89bSRishi Srivatsavai return; 4863b509e89bSRishi Srivatsavai 4864b509e89bSRishi Srivatsavai if (altroot != NULL) 4865b509e89bSRishi Srivatsavai altroot_cmd(altroot, argc, argv); 4866b509e89bSRishi Srivatsavai 4867b509e89bSRishi Srivatsavai status = dladm_name2info(handle, argv[optind], &linkid, NULL, NULL, 4868b509e89bSRishi Srivatsavai NULL); 4869b509e89bSRishi Srivatsavai if (status != DLADM_STATUS_OK) 4870b509e89bSRishi Srivatsavai die("invalid link name '%s'", argv[optind]); 4871b509e89bSRishi Srivatsavai 4872b509e89bSRishi Srivatsavai status = dladm_simnet_modify(handle, linkid, peer_linkid, flags); 4873b509e89bSRishi Srivatsavai if (status != DLADM_STATUS_OK) 4874b509e89bSRishi Srivatsavai die_dlerr(status, "simnet modification failed"); 4875b509e89bSRishi Srivatsavai } 4876b509e89bSRishi Srivatsavai 4877b509e89bSRishi Srivatsavai static dladm_status_t 4878b509e89bSRishi Srivatsavai print_simnet(show_state_t *state, datalink_id_t linkid) 4879b509e89bSRishi Srivatsavai { 4880b509e89bSRishi Srivatsavai dladm_simnet_attr_t slinfo; 4881b509e89bSRishi Srivatsavai uint32_t flags; 4882b509e89bSRishi Srivatsavai dladm_status_t status; 4883b509e89bSRishi Srivatsavai simnet_fields_buf_t slbuf; 4884b509e89bSRishi Srivatsavai char mstr[ETHERADDRL * 3]; 4885b509e89bSRishi Srivatsavai 4886b509e89bSRishi Srivatsavai bzero(&slbuf, sizeof (slbuf)); 4887b509e89bSRishi Srivatsavai if ((status = dladm_datalink_id2info(handle, linkid, &flags, NULL, NULL, 4888b509e89bSRishi Srivatsavai slbuf.simnet_name, sizeof (slbuf.simnet_name))) 4889b509e89bSRishi Srivatsavai != DLADM_STATUS_OK) 4890b509e89bSRishi Srivatsavai return (status); 4891b509e89bSRishi Srivatsavai 4892b509e89bSRishi Srivatsavai if (!(state->ls_flags & flags)) 4893b509e89bSRishi Srivatsavai return (DLADM_STATUS_NOTFOUND); 4894b509e89bSRishi Srivatsavai 4895b509e89bSRishi Srivatsavai if ((status = dladm_simnet_info(handle, linkid, &slinfo, 4896b509e89bSRishi Srivatsavai state->ls_flags)) != DLADM_STATUS_OK) 4897b509e89bSRishi Srivatsavai return (status); 4898b509e89bSRishi Srivatsavai 4899b509e89bSRishi Srivatsavai if (slinfo.sna_peer_link_id != DATALINK_INVALID_LINKID && 4900b509e89bSRishi Srivatsavai (status = dladm_datalink_id2info(handle, slinfo.sna_peer_link_id, 4901b509e89bSRishi Srivatsavai NULL, NULL, NULL, slbuf.simnet_otherlink, 4902b509e89bSRishi Srivatsavai sizeof (slbuf.simnet_otherlink))) != 4903b509e89bSRishi Srivatsavai DLADM_STATUS_OK) 4904b509e89bSRishi Srivatsavai return (status); 4905b509e89bSRishi Srivatsavai 4906b509e89bSRishi Srivatsavai if (slinfo.sna_mac_len > sizeof (slbuf.simnet_macaddr)) 4907b509e89bSRishi Srivatsavai return (DLADM_STATUS_BADVAL); 4908b509e89bSRishi Srivatsavai 4909b509e89bSRishi Srivatsavai (void) strlcpy(slbuf.simnet_macaddr, 4910b509e89bSRishi Srivatsavai dladm_aggr_macaddr2str(slinfo.sna_mac_addr, mstr), 4911b509e89bSRishi Srivatsavai sizeof (slbuf.simnet_macaddr)); 4912b509e89bSRishi Srivatsavai (void) dladm_media2str(slinfo.sna_type, slbuf.simnet_media); 4913b509e89bSRishi Srivatsavai 4914b509e89bSRishi Srivatsavai ofmt_print(state->ls_ofmt, &slbuf); 4915b509e89bSRishi Srivatsavai return (status); 4916b509e89bSRishi Srivatsavai } 4917b509e89bSRishi Srivatsavai 4918b509e89bSRishi Srivatsavai /* ARGSUSED */ 4919b509e89bSRishi Srivatsavai static int 4920b509e89bSRishi Srivatsavai show_simnet(dladm_handle_t dh, datalink_id_t linkid, void *arg) 4921b509e89bSRishi Srivatsavai { 4922b509e89bSRishi Srivatsavai show_state_t *state = arg; 4923b509e89bSRishi Srivatsavai 4924b509e89bSRishi Srivatsavai state->ls_status = print_simnet(state, linkid); 4925b509e89bSRishi Srivatsavai return (DLADM_WALK_CONTINUE); 4926b509e89bSRishi Srivatsavai } 4927b509e89bSRishi Srivatsavai 4928b509e89bSRishi Srivatsavai static void 4929b509e89bSRishi Srivatsavai do_show_simnet(int argc, char *argv[], const char *use) 4930b509e89bSRishi Srivatsavai { 4931b509e89bSRishi Srivatsavai int option; 4932b509e89bSRishi Srivatsavai uint32_t flags = DLADM_OPT_ACTIVE; 4933b509e89bSRishi Srivatsavai boolean_t p_arg = B_FALSE; 4934b509e89bSRishi Srivatsavai datalink_id_t linkid = DATALINK_ALL_LINKID; 4935b509e89bSRishi Srivatsavai show_state_t state; 4936b509e89bSRishi Srivatsavai dladm_status_t status; 4937b509e89bSRishi Srivatsavai boolean_t o_arg = B_FALSE; 4938b509e89bSRishi Srivatsavai ofmt_handle_t ofmt; 4939b509e89bSRishi Srivatsavai ofmt_status_t oferr; 4940b509e89bSRishi Srivatsavai char *all_fields = "link,media,macaddress,otherlink"; 4941b509e89bSRishi Srivatsavai char *fields_str = all_fields; 4942b509e89bSRishi Srivatsavai uint_t ofmtflags = 0; 4943b509e89bSRishi Srivatsavai 4944b509e89bSRishi Srivatsavai bzero(&state, sizeof (state)); 4945b509e89bSRishi Srivatsavai 4946b509e89bSRishi Srivatsavai opterr = 0; 4947b509e89bSRishi Srivatsavai while ((option = getopt_long(argc, argv, ":pPo:", 4948b509e89bSRishi Srivatsavai show_lopts, NULL)) != -1) { 4949b509e89bSRishi Srivatsavai switch (option) { 4950b509e89bSRishi Srivatsavai case 'p': 4951b509e89bSRishi Srivatsavai if (p_arg) 4952b509e89bSRishi Srivatsavai die_optdup(option); 4953b509e89bSRishi Srivatsavai 4954b509e89bSRishi Srivatsavai p_arg = B_TRUE; 4955b509e89bSRishi Srivatsavai state.ls_parsable = p_arg; 4956b509e89bSRishi Srivatsavai break; 4957b509e89bSRishi Srivatsavai case 'P': 4958b509e89bSRishi Srivatsavai if (flags != DLADM_OPT_ACTIVE) 4959b509e89bSRishi Srivatsavai die_optdup(option); 4960b509e89bSRishi Srivatsavai 4961b509e89bSRishi Srivatsavai flags = DLADM_OPT_PERSIST; 4962b509e89bSRishi Srivatsavai break; 4963b509e89bSRishi Srivatsavai case 'o': 4964b509e89bSRishi Srivatsavai o_arg = B_TRUE; 4965b509e89bSRishi Srivatsavai fields_str = optarg; 4966b509e89bSRishi Srivatsavai break; 4967b509e89bSRishi Srivatsavai default: 4968b509e89bSRishi Srivatsavai die_opterr(optopt, option, use); 4969b509e89bSRishi Srivatsavai break; 4970b509e89bSRishi Srivatsavai } 4971b509e89bSRishi Srivatsavai } 4972b509e89bSRishi Srivatsavai 4973b509e89bSRishi Srivatsavai if (p_arg && !o_arg) 4974b509e89bSRishi Srivatsavai die("-p requires -o"); 4975b509e89bSRishi Srivatsavai 4976b509e89bSRishi Srivatsavai if (strcasecmp(fields_str, "all") == 0) { 4977b509e89bSRishi Srivatsavai if (p_arg) 4978b509e89bSRishi Srivatsavai die("\"-o all\" is invalid with -p"); 4979b509e89bSRishi Srivatsavai fields_str = all_fields; 4980b509e89bSRishi Srivatsavai } 4981b509e89bSRishi Srivatsavai 4982b509e89bSRishi Srivatsavai /* get link name (optional last argument) */ 4983b509e89bSRishi Srivatsavai if (optind == (argc-1)) { 4984b509e89bSRishi Srivatsavai if ((status = dladm_name2info(handle, argv[optind], &linkid, 4985b509e89bSRishi Srivatsavai NULL, NULL, NULL)) != DLADM_STATUS_OK) { 4986b509e89bSRishi Srivatsavai die_dlerr(status, "link %s is not valid", argv[optind]); 4987b509e89bSRishi Srivatsavai } 4988b509e89bSRishi Srivatsavai } else if (optind != argc) { 4989b509e89bSRishi Srivatsavai usage(); 4990b509e89bSRishi Srivatsavai } 4991b509e89bSRishi Srivatsavai 4992b509e89bSRishi Srivatsavai state.ls_flags = flags; 4993b509e89bSRishi Srivatsavai state.ls_donefirst = B_FALSE; 4994b509e89bSRishi Srivatsavai if (state.ls_parsable) 4995b509e89bSRishi Srivatsavai ofmtflags |= OFMT_PARSABLE; 4996b509e89bSRishi Srivatsavai oferr = ofmt_open(fields_str, simnet_fields, ofmtflags, 0, &ofmt); 4997b509e89bSRishi Srivatsavai dladm_ofmt_check(oferr, state.ls_parsable, ofmt); 4998b509e89bSRishi Srivatsavai state.ls_ofmt = ofmt; 4999b509e89bSRishi Srivatsavai 5000b509e89bSRishi Srivatsavai if (linkid == DATALINK_ALL_LINKID) { 5001b509e89bSRishi Srivatsavai (void) dladm_walk_datalink_id(show_simnet, handle, &state, 5002b509e89bSRishi Srivatsavai DATALINK_CLASS_SIMNET, DATALINK_ANY_MEDIATYPE, flags); 5003b509e89bSRishi Srivatsavai } else { 5004b509e89bSRishi Srivatsavai (void) show_simnet(handle, linkid, &state); 5005b509e89bSRishi Srivatsavai if (state.ls_status != DLADM_STATUS_OK) { 5006b509e89bSRishi Srivatsavai ofmt_close(ofmt); 5007b509e89bSRishi Srivatsavai die_dlerr(state.ls_status, "failed to show simnet %s", 5008b509e89bSRishi Srivatsavai argv[optind]); 5009b509e89bSRishi Srivatsavai } 5010b509e89bSRishi Srivatsavai } 5011b509e89bSRishi Srivatsavai ofmt_close(ofmt); 5012b509e89bSRishi Srivatsavai } 5013b509e89bSRishi Srivatsavai 5014da14cebeSEric Cheng static void 50156be03d0bSVasumathi Sundaram - Sun Microsystems link_stats(datalink_id_t linkid, uint_t interval, char *fields_str, 50166be03d0bSVasumathi Sundaram - Sun Microsystems show_state_t *state) 5017d62bc4baSyz147064 { 50188002d411SSowmini Varadhan ofmt_handle_t ofmt; 50198002d411SSowmini Varadhan ofmt_status_t oferr; 50208002d411SSowmini Varadhan uint_t ofmtflags = 0; 502133343a97Smeem 50228002d411SSowmini Varadhan if (state->ls_parsable) 50238002d411SSowmini Varadhan ofmtflags |= OFMT_PARSABLE; 50248002d411SSowmini Varadhan oferr = ofmt_open(fields_str, link_s_fields, ofmtflags, 0, &ofmt); 50258002d411SSowmini Varadhan dladm_ofmt_check(oferr, state->ls_parsable, ofmt); 50268002d411SSowmini Varadhan state->ls_ofmt = ofmt; 50277c478bd9Sstevel@tonic-gate 50287c478bd9Sstevel@tonic-gate /* 50297c478bd9Sstevel@tonic-gate * If an interval is specified, continuously show the stats 50307c478bd9Sstevel@tonic-gate * only for the first MAC port. 50317c478bd9Sstevel@tonic-gate */ 50326be03d0bSVasumathi Sundaram - Sun Microsystems state->ls_firstonly = (interval != 0); 50337c478bd9Sstevel@tonic-gate 50347c478bd9Sstevel@tonic-gate for (;;) { 50356be03d0bSVasumathi Sundaram - Sun Microsystems state->ls_donefirst = B_FALSE; 5036d62bc4baSyz147064 if (linkid == DATALINK_ALL_LINKID) { 50374ac67f02SAnurag S. Maskey (void) dladm_walk_datalink_id(show_link_stats, handle, 50384ac67f02SAnurag S. Maskey state, DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE, 5039d62bc4baSyz147064 DLADM_OPT_ACTIVE); 5040d62bc4baSyz147064 } else { 50414ac67f02SAnurag S. Maskey (void) show_link_stats(handle, linkid, state); 5042d62bc4baSyz147064 } 50437c478bd9Sstevel@tonic-gate 50447c478bd9Sstevel@tonic-gate if (interval == 0) 50457c478bd9Sstevel@tonic-gate break; 50467c478bd9Sstevel@tonic-gate 5047c3affd82SMichael Lim (void) fflush(stdout); 50487c478bd9Sstevel@tonic-gate (void) sleep(interval); 50497c478bd9Sstevel@tonic-gate } 50508002d411SSowmini Varadhan ofmt_close(ofmt); 50517c478bd9Sstevel@tonic-gate } 50527c478bd9Sstevel@tonic-gate 50537c478bd9Sstevel@tonic-gate static void 5054d62bc4baSyz147064 aggr_stats(datalink_id_t linkid, show_grp_state_t *state, uint_t interval) 50557c478bd9Sstevel@tonic-gate { 50567c478bd9Sstevel@tonic-gate /* 50577c478bd9Sstevel@tonic-gate * If an interval is specified, continuously show the stats 50587c478bd9Sstevel@tonic-gate * only for the first group. 50597c478bd9Sstevel@tonic-gate */ 5060d62bc4baSyz147064 state->gs_firstonly = (interval != 0); 50617c478bd9Sstevel@tonic-gate 50627c478bd9Sstevel@tonic-gate for (;;) { 5063d62bc4baSyz147064 state->gs_donefirst = B_FALSE; 5064d62bc4baSyz147064 if (linkid == DATALINK_ALL_LINKID) 50654ac67f02SAnurag S. Maskey (void) dladm_walk_datalink_id(show_aggr, handle, state, 5066d62bc4baSyz147064 DATALINK_CLASS_AGGR, DATALINK_ANY_MEDIATYPE, 5067d62bc4baSyz147064 DLADM_OPT_ACTIVE); 5068d62bc4baSyz147064 else 50694ac67f02SAnurag S. Maskey (void) show_aggr(handle, linkid, state); 50707c478bd9Sstevel@tonic-gate 50717c478bd9Sstevel@tonic-gate if (interval == 0) 50727c478bd9Sstevel@tonic-gate break; 50737c478bd9Sstevel@tonic-gate 5074c3affd82SMichael Lim (void) fflush(stdout); 50757c478bd9Sstevel@tonic-gate (void) sleep(interval); 50767c478bd9Sstevel@tonic-gate } 50777c478bd9Sstevel@tonic-gate } 50787c478bd9Sstevel@tonic-gate 5079da14cebeSEric Cheng /* ARGSUSED */ 50807c478bd9Sstevel@tonic-gate static void 5081da14cebeSEric Cheng vnic_stats(show_vnic_state_t *sp, uint32_t interval) 50827c478bd9Sstevel@tonic-gate { 5083da14cebeSEric Cheng show_vnic_state_t state; 5084da14cebeSEric Cheng boolean_t specific_link, specific_dev; 50857c478bd9Sstevel@tonic-gate 5086da14cebeSEric Cheng /* Display vnic statistics */ 5087da14cebeSEric Cheng dump_vnics_head(sp->vs_link); 5088e7801d59Ssowmini 5089da14cebeSEric Cheng bzero(&state, sizeof (state)); 5090da14cebeSEric Cheng state.vs_stats = B_TRUE; 5091da14cebeSEric Cheng state.vs_vnic_id = sp->vs_vnic_id; 5092da14cebeSEric Cheng state.vs_link_id = sp->vs_link_id; 50937c478bd9Sstevel@tonic-gate 50947c478bd9Sstevel@tonic-gate /* 5095da14cebeSEric Cheng * If an interval is specified, and a vnic ID is not specified, 5096da14cebeSEric Cheng * continuously show the stats only for the first vnic. 50977c478bd9Sstevel@tonic-gate */ 5098da14cebeSEric Cheng specific_link = (sp->vs_vnic_id != DATALINK_ALL_LINKID); 5099da14cebeSEric Cheng specific_dev = (sp->vs_link_id != DATALINK_ALL_LINKID); 51007c478bd9Sstevel@tonic-gate 51017c478bd9Sstevel@tonic-gate for (;;) { 5102da14cebeSEric Cheng /* Get stats for each vnic */ 5103da14cebeSEric Cheng state.vs_found = B_FALSE; 5104da14cebeSEric Cheng state.vs_donefirst = B_FALSE; 5105da14cebeSEric Cheng state.vs_printstats = B_FALSE; 5106da14cebeSEric Cheng state.vs_flags = DLADM_OPT_ACTIVE; 51077c478bd9Sstevel@tonic-gate 5108da14cebeSEric Cheng if (!specific_link) { 51094ac67f02SAnurag S. Maskey (void) dladm_walk_datalink_id(show_vnic, handle, &state, 5110da14cebeSEric Cheng DATALINK_CLASS_VNIC, DATALINK_ANY_MEDIATYPE, 5111da14cebeSEric Cheng DLADM_OPT_ACTIVE); 5112da14cebeSEric Cheng } else { 51134ac67f02SAnurag S. Maskey (void) show_vnic(handle, sp->vs_vnic_id, &state); 5114da14cebeSEric Cheng if (state.vs_status != DLADM_STATUS_OK) { 5115da14cebeSEric Cheng die_dlerr(state.vs_status, 5116da14cebeSEric Cheng "failed to show vnic '%s'", sp->vs_vnic); 5117da14cebeSEric Cheng } 5118da14cebeSEric Cheng } 51197c478bd9Sstevel@tonic-gate 5120da14cebeSEric Cheng if (specific_link && !state.vs_found) 5121da14cebeSEric Cheng die("non-existent vnic '%s'", sp->vs_vnic); 5122da14cebeSEric Cheng if (specific_dev && !state.vs_found) 5123da14cebeSEric Cheng die("device %s has no vnics", sp->vs_link); 5124da14cebeSEric Cheng 5125da14cebeSEric Cheng /* Show totals */ 5126da14cebeSEric Cheng if ((specific_link | specific_dev) && !interval) { 5127da14cebeSEric Cheng (void) printf("Total"); 5128da14cebeSEric Cheng (void) printf("\t%-10llu", 5129da14cebeSEric Cheng state.vs_totalstats.ipackets); 5130da14cebeSEric Cheng (void) printf("%-12llu", 5131da14cebeSEric Cheng state.vs_totalstats.rbytes); 5132da14cebeSEric Cheng (void) printf("%-10llu", 5133da14cebeSEric Cheng state.vs_totalstats.opackets); 5134da14cebeSEric Cheng (void) printf("%-12llu\n", 5135da14cebeSEric Cheng state.vs_totalstats.obytes); 5136da14cebeSEric Cheng } 5137da14cebeSEric Cheng 5138da14cebeSEric Cheng /* Show stats for each vnic */ 5139da14cebeSEric Cheng state.vs_donefirst = B_FALSE; 5140da14cebeSEric Cheng state.vs_printstats = B_TRUE; 5141da14cebeSEric Cheng 5142da14cebeSEric Cheng if (!specific_link) { 51434ac67f02SAnurag S. Maskey (void) dladm_walk_datalink_id(show_vnic, handle, &state, 5144da14cebeSEric Cheng DATALINK_CLASS_VNIC, DATALINK_ANY_MEDIATYPE, 5145da14cebeSEric Cheng DLADM_OPT_ACTIVE); 5146da14cebeSEric Cheng } else { 51474ac67f02SAnurag S. Maskey (void) show_vnic(handle, sp->vs_vnic_id, &state); 5148da14cebeSEric Cheng if (state.vs_status != DLADM_STATUS_OK) { 5149da14cebeSEric Cheng die_dlerr(state.vs_status, 5150da14cebeSEric Cheng "failed to show vnic '%s'", sp->vs_vnic); 5151da14cebeSEric Cheng } 5152da14cebeSEric Cheng } 51537c478bd9Sstevel@tonic-gate 51547c478bd9Sstevel@tonic-gate if (interval == 0) 51557c478bd9Sstevel@tonic-gate break; 51567c478bd9Sstevel@tonic-gate 5157c3affd82SMichael Lim (void) fflush(stdout); 51587c478bd9Sstevel@tonic-gate (void) sleep(interval); 51597c478bd9Sstevel@tonic-gate } 51607c478bd9Sstevel@tonic-gate } 51617c478bd9Sstevel@tonic-gate 51627c478bd9Sstevel@tonic-gate static void 5163da14cebeSEric Cheng get_mac_stats(const char *dev, pktsum_t *stats) 51647c478bd9Sstevel@tonic-gate { 51657c478bd9Sstevel@tonic-gate kstat_ctl_t *kcp; 51667c478bd9Sstevel@tonic-gate kstat_t *ksp; 5167da14cebeSEric Cheng char module[DLPI_LINKNAME_MAX]; 5168da14cebeSEric Cheng uint_t instance; 5169da14cebeSEric Cheng 5170da14cebeSEric Cheng 5171da14cebeSEric Cheng bzero(stats, sizeof (*stats)); 5172da14cebeSEric Cheng 5173da14cebeSEric Cheng if (dlpi_parselink(dev, module, &instance) != DLPI_SUCCESS) 5174da14cebeSEric Cheng return; 51757c478bd9Sstevel@tonic-gate 51767c478bd9Sstevel@tonic-gate if ((kcp = kstat_open()) == NULL) { 517733343a97Smeem warn("kstat open operation failed"); 51787c478bd9Sstevel@tonic-gate return; 51797c478bd9Sstevel@tonic-gate } 51807c478bd9Sstevel@tonic-gate 5181da14cebeSEric Cheng ksp = dladm_kstat_lookup(kcp, module, instance, "mac", NULL); 5182da14cebeSEric Cheng if (ksp != NULL) 5183da14cebeSEric Cheng dladm_get_stats(kcp, ksp, stats); 5184da14cebeSEric Cheng 51857c478bd9Sstevel@tonic-gate (void) kstat_close(kcp); 51867c478bd9Sstevel@tonic-gate 51877c478bd9Sstevel@tonic-gate } 51887c478bd9Sstevel@tonic-gate 51897c478bd9Sstevel@tonic-gate static void 51907c478bd9Sstevel@tonic-gate get_link_stats(const char *link, pktsum_t *stats) 51917c478bd9Sstevel@tonic-gate { 5192da14cebeSEric Cheng kstat_ctl_t *kcp; 5193da14cebeSEric Cheng kstat_t *ksp; 5194da14cebeSEric Cheng 51957c478bd9Sstevel@tonic-gate bzero(stats, sizeof (*stats)); 5196da14cebeSEric Cheng 5197da14cebeSEric Cheng if ((kcp = kstat_open()) == NULL) { 5198da14cebeSEric Cheng warn("kstat_open operation failed"); 5199da14cebeSEric Cheng return; 5200da14cebeSEric Cheng } 5201da14cebeSEric Cheng 5202da14cebeSEric Cheng ksp = dladm_kstat_lookup(kcp, "link", 0, link, NULL); 5203da14cebeSEric Cheng 5204da14cebeSEric Cheng if (ksp != NULL) 5205da14cebeSEric Cheng dladm_get_stats(kcp, ksp, stats); 5206da14cebeSEric Cheng 5207da14cebeSEric Cheng (void) kstat_close(kcp); 52087c478bd9Sstevel@tonic-gate } 52097c478bd9Sstevel@tonic-gate 5210ba2e4443Sseb static int 5211d62bc4baSyz147064 query_kstat(char *module, int instance, const char *name, const char *stat, 5212d62bc4baSyz147064 uint8_t type, void *val) 52137c478bd9Sstevel@tonic-gate { 52147c478bd9Sstevel@tonic-gate kstat_ctl_t *kcp; 52157c478bd9Sstevel@tonic-gate kstat_t *ksp; 52167c478bd9Sstevel@tonic-gate 52177c478bd9Sstevel@tonic-gate if ((kcp = kstat_open()) == NULL) { 521833343a97Smeem warn("kstat open operation failed"); 5219ba2e4443Sseb return (-1); 52207c478bd9Sstevel@tonic-gate } 52217c478bd9Sstevel@tonic-gate 5222d62bc4baSyz147064 if ((ksp = kstat_lookup(kcp, module, instance, (char *)name)) == NULL) { 52237c478bd9Sstevel@tonic-gate /* 52247c478bd9Sstevel@tonic-gate * The kstat query could fail if the underlying MAC 52257c478bd9Sstevel@tonic-gate * driver was already detached. 52267c478bd9Sstevel@tonic-gate */ 52277c478bd9Sstevel@tonic-gate goto bail; 52287c478bd9Sstevel@tonic-gate } 52297c478bd9Sstevel@tonic-gate 52307c478bd9Sstevel@tonic-gate if (kstat_read(kcp, ksp, NULL) == -1) { 523133343a97Smeem warn("kstat read failed"); 52327c478bd9Sstevel@tonic-gate goto bail; 52337c478bd9Sstevel@tonic-gate } 52347c478bd9Sstevel@tonic-gate 5235e7801d59Ssowmini if (dladm_kstat_value(ksp, stat, type, val) < 0) 52367c478bd9Sstevel@tonic-gate goto bail; 5237ba2e4443Sseb 5238ba2e4443Sseb (void) kstat_close(kcp); 5239ba2e4443Sseb return (0); 52407c478bd9Sstevel@tonic-gate 52417c478bd9Sstevel@tonic-gate bail: 52427c478bd9Sstevel@tonic-gate (void) kstat_close(kcp); 5243ba2e4443Sseb return (-1); 5244ba2e4443Sseb } 5245ba2e4443Sseb 5246d62bc4baSyz147064 static int 5247d62bc4baSyz147064 get_one_kstat(const char *name, const char *stat, uint8_t type, 5248d62bc4baSyz147064 void *val, boolean_t islink) 5249d62bc4baSyz147064 { 5250d62bc4baSyz147064 char module[DLPI_LINKNAME_MAX]; 5251d62bc4baSyz147064 uint_t instance; 5252d62bc4baSyz147064 5253d62bc4baSyz147064 if (islink) { 5254d62bc4baSyz147064 return (query_kstat("link", 0, name, stat, type, val)); 5255d62bc4baSyz147064 } else { 5256d62bc4baSyz147064 if (dlpi_parselink(name, module, &instance) != DLPI_SUCCESS) 5257d62bc4baSyz147064 return (-1); 5258d62bc4baSyz147064 5259d62bc4baSyz147064 return (query_kstat(module, instance, "mac", stat, type, val)); 5260d62bc4baSyz147064 } 5261d62bc4baSyz147064 } 5262d62bc4baSyz147064 5263ba2e4443Sseb static uint64_t 5264d62bc4baSyz147064 get_ifspeed(const char *name, boolean_t islink) 5265ba2e4443Sseb { 5266ba2e4443Sseb uint64_t ifspeed = 0; 5267ba2e4443Sseb 5268d62bc4baSyz147064 (void) get_one_kstat(name, "ifspeed", KSTAT_DATA_UINT64, 5269d62bc4baSyz147064 &ifspeed, islink); 5270d62bc4baSyz147064 52717c478bd9Sstevel@tonic-gate return (ifspeed); 52727c478bd9Sstevel@tonic-gate } 52737c478bd9Sstevel@tonic-gate 5274f595a68aSyz147064 static const char * 5275d62bc4baSyz147064 get_linkstate(const char *name, boolean_t islink, char *buf) 52767c478bd9Sstevel@tonic-gate { 5277d62bc4baSyz147064 link_state_t linkstate; 52787c478bd9Sstevel@tonic-gate 5279d62bc4baSyz147064 if (get_one_kstat(name, "link_state", KSTAT_DATA_UINT32, 5280d62bc4baSyz147064 &linkstate, islink) != 0) { 5281da14cebeSEric Cheng (void) strlcpy(buf, "?", DLADM_STRSIZE); 52823a62633bSyz147064 return (buf); 52837c478bd9Sstevel@tonic-gate } 5284d62bc4baSyz147064 return (dladm_linkstate2str(linkstate, buf)); 52857c478bd9Sstevel@tonic-gate } 52867c478bd9Sstevel@tonic-gate 5287f595a68aSyz147064 static const char * 5288d62bc4baSyz147064 get_linkduplex(const char *name, boolean_t islink, char *buf) 52897c478bd9Sstevel@tonic-gate { 5290d62bc4baSyz147064 link_duplex_t linkduplex; 52917c478bd9Sstevel@tonic-gate 5292d62bc4baSyz147064 if (get_one_kstat(name, "link_duplex", KSTAT_DATA_UINT32, 5293d62bc4baSyz147064 &linkduplex, islink) != 0) { 52943a62633bSyz147064 (void) strlcpy(buf, "unknown", DLADM_STRSIZE); 52953a62633bSyz147064 return (buf); 52967c478bd9Sstevel@tonic-gate } 52977c478bd9Sstevel@tonic-gate 5298d62bc4baSyz147064 return (dladm_linkduplex2str(linkduplex, buf)); 52997c478bd9Sstevel@tonic-gate } 53000ba2cbe9Sxc151355 53010ba2cbe9Sxc151355 static int 53028002d411SSowmini Varadhan parse_wifi_fields(char *str, ofmt_handle_t *ofmt, uint_t cmdtype, 53038002d411SSowmini Varadhan boolean_t parsable) 53040ba2cbe9Sxc151355 { 53058002d411SSowmini Varadhan ofmt_field_t *template, *of; 53068002d411SSowmini Varadhan ofmt_cb_t *fn; 53078002d411SSowmini Varadhan ofmt_status_t oferr; 53080ba2cbe9Sxc151355 53090ba2cbe9Sxc151355 if (cmdtype == WIFI_CMD_SCAN) { 53108002d411SSowmini Varadhan template = wifi_common_fields; 53110ba2cbe9Sxc151355 if (str == NULL) 53120ba2cbe9Sxc151355 str = def_scan_wifi_fields; 53130ba2cbe9Sxc151355 if (strcasecmp(str, "all") == 0) 53140ba2cbe9Sxc151355 str = all_scan_wifi_fields; 53158002d411SSowmini Varadhan fn = print_wlan_attr_cb; 53160ba2cbe9Sxc151355 } else if (cmdtype == WIFI_CMD_SHOW) { 53178002d411SSowmini Varadhan bcopy(wifi_common_fields, &wifi_show_fields[2], 53188002d411SSowmini Varadhan sizeof (wifi_common_fields)); 53198002d411SSowmini Varadhan template = wifi_show_fields; 53200ba2cbe9Sxc151355 if (str == NULL) 53210ba2cbe9Sxc151355 str = def_show_wifi_fields; 53220ba2cbe9Sxc151355 if (strcasecmp(str, "all") == 0) 53230ba2cbe9Sxc151355 str = all_show_wifi_fields; 53248002d411SSowmini Varadhan fn = print_link_attr_cb; 53250ba2cbe9Sxc151355 } else { 53260ba2cbe9Sxc151355 return (-1); 53270ba2cbe9Sxc151355 } 53288002d411SSowmini Varadhan 53298002d411SSowmini Varadhan for (of = template; of->of_name != NULL; of++) { 53308002d411SSowmini Varadhan if (of->of_cb == NULL) 53318002d411SSowmini Varadhan of->of_cb = fn; 53328002d411SSowmini Varadhan } 53338002d411SSowmini Varadhan 53348002d411SSowmini Varadhan oferr = ofmt_open(str, template, (parsable ? OFMT_PARSABLE : 0), 53358002d411SSowmini Varadhan 0, ofmt); 53368002d411SSowmini Varadhan dladm_ofmt_check(oferr, parsable, *ofmt); 5337e7801d59Ssowmini return (0); 53380ba2cbe9Sxc151355 } 53390ba2cbe9Sxc151355 53400ba2cbe9Sxc151355 typedef struct print_wifi_state { 5341d62bc4baSyz147064 char *ws_link; 53428002d411SSowmini Varadhan boolean_t ws_parsable; 53430ba2cbe9Sxc151355 boolean_t ws_header; 53448002d411SSowmini Varadhan ofmt_handle_t ws_ofmt; 53450ba2cbe9Sxc151355 } print_wifi_state_t; 53460ba2cbe9Sxc151355 5347e7801d59Ssowmini typedef struct wlan_scan_args_s { 5348e7801d59Ssowmini print_wifi_state_t *ws_state; 5349e7801d59Ssowmini void *ws_attr; 5350e7801d59Ssowmini } wlan_scan_args_t; 53510ba2cbe9Sxc151355 53528002d411SSowmini Varadhan static boolean_t 53538002d411SSowmini Varadhan print_wlan_attr_cb(ofmt_arg_t *ofarg, char *buf, uint_t bufsize) 53540ba2cbe9Sxc151355 { 53558002d411SSowmini Varadhan wlan_scan_args_t *w = ofarg->ofmt_cbarg; 5356e7801d59Ssowmini print_wifi_state_t *statep = w->ws_state; 5357e7801d59Ssowmini dladm_wlan_attr_t *attrp = w->ws_attr; 53588002d411SSowmini Varadhan char tmpbuf[DLADM_STRSIZE]; 53590ba2cbe9Sxc151355 53608002d411SSowmini Varadhan if (ofarg->ofmt_id == 0) { 53618002d411SSowmini Varadhan (void) strlcpy(buf, (char *)statep->ws_link, bufsize); 53628002d411SSowmini Varadhan return (B_TRUE); 53630ba2cbe9Sxc151355 } 53640ba2cbe9Sxc151355 53658002d411SSowmini Varadhan if ((ofarg->ofmt_id & attrp->wa_valid) == 0) 53668002d411SSowmini Varadhan return (B_TRUE); 53670ba2cbe9Sxc151355 53688002d411SSowmini Varadhan switch (ofarg->ofmt_id) { 5369f595a68aSyz147064 case DLADM_WLAN_ATTR_ESSID: 53708002d411SSowmini Varadhan (void) dladm_wlan_essid2str(&attrp->wa_essid, tmpbuf); 53710ba2cbe9Sxc151355 break; 5372f595a68aSyz147064 case DLADM_WLAN_ATTR_BSSID: 53738002d411SSowmini Varadhan (void) dladm_wlan_bssid2str(&attrp->wa_bssid, tmpbuf); 53740ba2cbe9Sxc151355 break; 5375f595a68aSyz147064 case DLADM_WLAN_ATTR_SECMODE: 53768002d411SSowmini Varadhan (void) dladm_wlan_secmode2str(&attrp->wa_secmode, tmpbuf); 53770ba2cbe9Sxc151355 break; 5378f595a68aSyz147064 case DLADM_WLAN_ATTR_STRENGTH: 53798002d411SSowmini Varadhan (void) dladm_wlan_strength2str(&attrp->wa_strength, tmpbuf); 53800ba2cbe9Sxc151355 break; 5381f595a68aSyz147064 case DLADM_WLAN_ATTR_MODE: 53828002d411SSowmini Varadhan (void) dladm_wlan_mode2str(&attrp->wa_mode, tmpbuf); 53830ba2cbe9Sxc151355 break; 5384f595a68aSyz147064 case DLADM_WLAN_ATTR_SPEED: 53858002d411SSowmini Varadhan (void) dladm_wlan_speed2str(&attrp->wa_speed, tmpbuf); 53868002d411SSowmini Varadhan (void) strlcat(tmpbuf, "Mb", sizeof (tmpbuf)); 53870ba2cbe9Sxc151355 break; 5388f595a68aSyz147064 case DLADM_WLAN_ATTR_AUTH: 53898002d411SSowmini Varadhan (void) dladm_wlan_auth2str(&attrp->wa_auth, tmpbuf); 53900ba2cbe9Sxc151355 break; 5391f595a68aSyz147064 case DLADM_WLAN_ATTR_BSSTYPE: 53928002d411SSowmini Varadhan (void) dladm_wlan_bsstype2str(&attrp->wa_bsstype, tmpbuf); 53930ba2cbe9Sxc151355 break; 53940ba2cbe9Sxc151355 } 53958002d411SSowmini Varadhan (void) strlcpy(buf, tmpbuf, bufsize); 53960ba2cbe9Sxc151355 53978002d411SSowmini Varadhan return (B_TRUE); 53980ba2cbe9Sxc151355 } 53990ba2cbe9Sxc151355 54000ba2cbe9Sxc151355 static boolean_t 5401f595a68aSyz147064 print_scan_results(void *arg, dladm_wlan_attr_t *attrp) 54020ba2cbe9Sxc151355 { 54030ba2cbe9Sxc151355 print_wifi_state_t *statep = arg; 5404e7801d59Ssowmini wlan_scan_args_t warg; 54050ba2cbe9Sxc151355 5406e7801d59Ssowmini bzero(&warg, sizeof (warg)); 5407e7801d59Ssowmini warg.ws_state = statep; 5408e7801d59Ssowmini warg.ws_attr = attrp; 54098002d411SSowmini Varadhan ofmt_print(statep->ws_ofmt, &warg); 54100ba2cbe9Sxc151355 return (B_TRUE); 54110ba2cbe9Sxc151355 } 54120ba2cbe9Sxc151355 5413d62bc4baSyz147064 static int 54144ac67f02SAnurag S. Maskey scan_wifi(dladm_handle_t dh, datalink_id_t linkid, void *arg) 54150ba2cbe9Sxc151355 { 54160ba2cbe9Sxc151355 print_wifi_state_t *statep = arg; 5417f595a68aSyz147064 dladm_status_t status; 5418d62bc4baSyz147064 char link[MAXLINKNAMELEN]; 5419d62bc4baSyz147064 54204ac67f02SAnurag S. Maskey if ((status = dladm_datalink_id2info(dh, linkid, NULL, NULL, NULL, link, 5421e7801d59Ssowmini sizeof (link))) != DLADM_STATUS_OK) { 5422d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 5423d62bc4baSyz147064 } 54240ba2cbe9Sxc151355 54250ba2cbe9Sxc151355 statep->ws_link = link; 54264ac67f02SAnurag S. Maskey status = dladm_wlan_scan(dh, linkid, statep, print_scan_results); 5427f595a68aSyz147064 if (status != DLADM_STATUS_OK) 5428d62bc4baSyz147064 die_dlerr(status, "cannot scan link '%s'", statep->ws_link); 542933343a97Smeem 5430d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 54310ba2cbe9Sxc151355 } 54320ba2cbe9Sxc151355 54338002d411SSowmini Varadhan static boolean_t 54348002d411SSowmini Varadhan print_wifi_status_cb(ofmt_arg_t *ofarg, char *buf, uint_t bufsize) 54350ba2cbe9Sxc151355 { 54368002d411SSowmini Varadhan static char tmpbuf[DLADM_STRSIZE]; 54378002d411SSowmini Varadhan wlan_scan_args_t *w = ofarg->ofmt_cbarg; 54388002d411SSowmini Varadhan dladm_wlan_linkattr_t *attrp = w->ws_attr; 54398002d411SSowmini Varadhan 54408002d411SSowmini Varadhan if ((ofarg->ofmt_id & attrp->la_valid) != 0) { 54418002d411SSowmini Varadhan (void) dladm_wlan_linkstatus2str(&attrp->la_status, tmpbuf); 54428002d411SSowmini Varadhan (void) strlcpy(buf, tmpbuf, bufsize); 54438002d411SSowmini Varadhan } 54448002d411SSowmini Varadhan return (B_TRUE); 54458002d411SSowmini Varadhan } 54468002d411SSowmini Varadhan 54478002d411SSowmini Varadhan static boolean_t 54488002d411SSowmini Varadhan print_link_attr_cb(ofmt_arg_t *ofarg, char *buf, uint_t bufsize) 54498002d411SSowmini Varadhan { 54508002d411SSowmini Varadhan wlan_scan_args_t *w = ofarg->ofmt_cbarg, w1; 5451e7801d59Ssowmini print_wifi_state_t *statep = w->ws_state; 5452e7801d59Ssowmini dladm_wlan_linkattr_t *attrp = w->ws_attr; 54530ba2cbe9Sxc151355 5454e7801d59Ssowmini bzero(&w1, sizeof (w1)); 5455e7801d59Ssowmini w1.ws_state = statep; 5456e7801d59Ssowmini w1.ws_attr = &attrp->la_wlan_attr; 54578002d411SSowmini Varadhan ofarg->ofmt_cbarg = &w1; 54588002d411SSowmini Varadhan return (print_wlan_attr_cb(ofarg, buf, bufsize)); 54590ba2cbe9Sxc151355 } 54600ba2cbe9Sxc151355 5461d62bc4baSyz147064 static int 54624ac67f02SAnurag S. Maskey show_wifi(dladm_handle_t dh, datalink_id_t linkid, void *arg) 54630ba2cbe9Sxc151355 { 54640ba2cbe9Sxc151355 print_wifi_state_t *statep = arg; 5465f595a68aSyz147064 dladm_wlan_linkattr_t attr; 5466f595a68aSyz147064 dladm_status_t status; 5467d62bc4baSyz147064 char link[MAXLINKNAMELEN]; 5468e7801d59Ssowmini wlan_scan_args_t warg; 54690ba2cbe9Sxc151355 54704ac67f02SAnurag S. Maskey if ((status = dladm_datalink_id2info(dh, linkid, NULL, NULL, NULL, link, 5471e7801d59Ssowmini sizeof (link))) != DLADM_STATUS_OK) { 5472d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 5473d62bc4baSyz147064 } 5474d62bc4baSyz147064 54755f5c9f54SAnurag S. Maskey /* dladm_wlan_get_linkattr() memsets attr with 0 */ 54764ac67f02SAnurag S. Maskey status = dladm_wlan_get_linkattr(dh, linkid, &attr); 5477f595a68aSyz147064 if (status != DLADM_STATUS_OK) 5478d62bc4baSyz147064 die_dlerr(status, "cannot get link attributes for %s", link); 5479d62bc4baSyz147064 5480d62bc4baSyz147064 statep->ws_link = link; 54810ba2cbe9Sxc151355 5482e7801d59Ssowmini bzero(&warg, sizeof (warg)); 5483e7801d59Ssowmini warg.ws_state = statep; 5484e7801d59Ssowmini warg.ws_attr = &attr; 54858002d411SSowmini Varadhan ofmt_print(statep->ws_ofmt, &warg); 5486d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 54870ba2cbe9Sxc151355 } 54880ba2cbe9Sxc151355 54890ba2cbe9Sxc151355 static void 54908d5c46e6Sam223141 do_display_wifi(int argc, char **argv, int cmd, const char *use) 54910ba2cbe9Sxc151355 { 54920ba2cbe9Sxc151355 int option; 54930ba2cbe9Sxc151355 char *fields_str = NULL; 54944ac67f02SAnurag S. Maskey int (*callback)(dladm_handle_t, datalink_id_t, void *); 54950ba2cbe9Sxc151355 print_wifi_state_t state; 5496d62bc4baSyz147064 datalink_id_t linkid = DATALINK_ALL_LINKID; 5497f595a68aSyz147064 dladm_status_t status; 54980ba2cbe9Sxc151355 54990ba2cbe9Sxc151355 if (cmd == WIFI_CMD_SCAN) 55000ba2cbe9Sxc151355 callback = scan_wifi; 55010ba2cbe9Sxc151355 else if (cmd == WIFI_CMD_SHOW) 55020ba2cbe9Sxc151355 callback = show_wifi; 55030ba2cbe9Sxc151355 else 55040ba2cbe9Sxc151355 return; 55050ba2cbe9Sxc151355 55068002d411SSowmini Varadhan state.ws_parsable = B_FALSE; 55070ba2cbe9Sxc151355 state.ws_header = B_TRUE; 55080ba2cbe9Sxc151355 opterr = 0; 55090ba2cbe9Sxc151355 while ((option = getopt_long(argc, argv, ":o:p", 55100ba2cbe9Sxc151355 wifi_longopts, NULL)) != -1) { 55110ba2cbe9Sxc151355 switch (option) { 55120ba2cbe9Sxc151355 case 'o': 55130ba2cbe9Sxc151355 fields_str = optarg; 55140ba2cbe9Sxc151355 break; 55150ba2cbe9Sxc151355 case 'p': 55168002d411SSowmini Varadhan state.ws_parsable = B_TRUE; 55170ba2cbe9Sxc151355 break; 55180ba2cbe9Sxc151355 default: 55198d5c46e6Sam223141 die_opterr(optopt, option, use); 55200ba2cbe9Sxc151355 } 55210ba2cbe9Sxc151355 } 55220ba2cbe9Sxc151355 55238002d411SSowmini Varadhan if (state.ws_parsable && fields_str == NULL) 55240d365605Sschuster die("-p requires -o"); 55250d365605Sschuster 55268002d411SSowmini Varadhan if (state.ws_parsable && strcasecmp(fields_str, "all") == 0) 55270d365605Sschuster die("\"-o all\" is invalid with -p"); 55280d365605Sschuster 5529d62bc4baSyz147064 if (optind == (argc - 1)) { 55304ac67f02SAnurag S. Maskey if ((status = dladm_name2info(handle, argv[optind], &linkid, 55314ac67f02SAnurag S. Maskey NULL, NULL, NULL)) != DLADM_STATUS_OK) { 5532d62bc4baSyz147064 die_dlerr(status, "link %s is not valid", argv[optind]); 5533d62bc4baSyz147064 } 5534d62bc4baSyz147064 } else if (optind != argc) { 55350ba2cbe9Sxc151355 usage(); 5536d62bc4baSyz147064 } 55370ba2cbe9Sxc151355 55388002d411SSowmini Varadhan if (parse_wifi_fields(fields_str, &state.ws_ofmt, cmd, 55398002d411SSowmini Varadhan state.ws_parsable) < 0) 554033343a97Smeem die("invalid field(s) specified"); 554133343a97Smeem 5542d62bc4baSyz147064 if (linkid == DATALINK_ALL_LINKID) { 55434ac67f02SAnurag S. Maskey (void) dladm_walk_datalink_id(callback, handle, &state, 5544b509e89bSRishi Srivatsavai DATALINK_CLASS_PHYS | DATALINK_CLASS_SIMNET, 5545b509e89bSRishi Srivatsavai DL_WIFI, DLADM_OPT_ACTIVE); 55460ba2cbe9Sxc151355 } else { 55474ac67f02SAnurag S. Maskey (void) (*callback)(handle, linkid, &state); 55480ba2cbe9Sxc151355 } 55498002d411SSowmini Varadhan ofmt_close(state.ws_ofmt); 55500ba2cbe9Sxc151355 } 55510ba2cbe9Sxc151355 55520ba2cbe9Sxc151355 static void 55538d5c46e6Sam223141 do_scan_wifi(int argc, char **argv, const char *use) 55540ba2cbe9Sxc151355 { 55558d5c46e6Sam223141 do_display_wifi(argc, argv, WIFI_CMD_SCAN, use); 55560ba2cbe9Sxc151355 } 55570ba2cbe9Sxc151355 55580ba2cbe9Sxc151355 static void 55598d5c46e6Sam223141 do_show_wifi(int argc, char **argv, const char *use) 55600ba2cbe9Sxc151355 { 55618d5c46e6Sam223141 do_display_wifi(argc, argv, WIFI_CMD_SHOW, use); 55620ba2cbe9Sxc151355 } 55630ba2cbe9Sxc151355 55640ba2cbe9Sxc151355 typedef struct wlan_count_attr { 55650ba2cbe9Sxc151355 uint_t wc_count; 5566d62bc4baSyz147064 datalink_id_t wc_linkid; 55670ba2cbe9Sxc151355 } wlan_count_attr_t; 55680ba2cbe9Sxc151355 55694ac67f02SAnurag S. Maskey /* ARGSUSED */ 5570d62bc4baSyz147064 static int 55714ac67f02SAnurag S. Maskey do_count_wlan(dladm_handle_t dh, datalink_id_t linkid, void *arg) 55720ba2cbe9Sxc151355 { 557333343a97Smeem wlan_count_attr_t *cp = arg; 55740ba2cbe9Sxc151355 55750ba2cbe9Sxc151355 if (cp->wc_count == 0) 5576d62bc4baSyz147064 cp->wc_linkid = linkid; 55770ba2cbe9Sxc151355 cp->wc_count++; 5578d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 55790ba2cbe9Sxc151355 } 55800ba2cbe9Sxc151355 55810ba2cbe9Sxc151355 static int 5582a399b765Szf162725 parse_wlan_keys(char *str, dladm_wlan_key_t **keys, uint_t *key_countp) 55830ba2cbe9Sxc151355 { 55840ba2cbe9Sxc151355 uint_t i; 5585a399b765Szf162725 dladm_wlan_key_t *wk; 55868002d411SSowmini Varadhan int nfields = 1; 55878002d411SSowmini Varadhan char *field, *token, *lasts = NULL, c; 55880ba2cbe9Sxc151355 55898002d411SSowmini Varadhan token = str; 55908002d411SSowmini Varadhan while ((c = *token++) != NULL) { 55918002d411SSowmini Varadhan if (c == ',') 55928002d411SSowmini Varadhan nfields++; 55938002d411SSowmini Varadhan } 55948002d411SSowmini Varadhan token = strdup(str); 55958002d411SSowmini Varadhan if (token == NULL) 55960ba2cbe9Sxc151355 return (-1); 55970ba2cbe9Sxc151355 55988002d411SSowmini Varadhan wk = malloc(nfields * sizeof (dladm_wlan_key_t)); 55990ba2cbe9Sxc151355 if (wk == NULL) 56000ba2cbe9Sxc151355 goto fail; 56010ba2cbe9Sxc151355 56028002d411SSowmini Varadhan token = str; 56038002d411SSowmini Varadhan for (i = 0; i < nfields; i++) { 56040ba2cbe9Sxc151355 char *s; 56050ba2cbe9Sxc151355 dladm_secobj_class_t class; 56060ba2cbe9Sxc151355 dladm_status_t status; 56070ba2cbe9Sxc151355 56088002d411SSowmini Varadhan field = strtok_r(token, ",", &lasts); 56098002d411SSowmini Varadhan token = NULL; 56108002d411SSowmini Varadhan 56118002d411SSowmini Varadhan (void) strlcpy(wk[i].wk_name, field, 5612a399b765Szf162725 DLADM_WLAN_MAX_KEYNAME_LEN); 56130ba2cbe9Sxc151355 56140ba2cbe9Sxc151355 wk[i].wk_idx = 1; 56150ba2cbe9Sxc151355 if ((s = strrchr(wk[i].wk_name, ':')) != NULL) { 56160ba2cbe9Sxc151355 if (s[1] == '\0' || s[2] != '\0' || !isdigit(s[1])) 56170ba2cbe9Sxc151355 goto fail; 56180ba2cbe9Sxc151355 56190ba2cbe9Sxc151355 wk[i].wk_idx = (uint_t)(s[1] - '0'); 56200ba2cbe9Sxc151355 *s = '\0'; 56210ba2cbe9Sxc151355 } 5622a399b765Szf162725 wk[i].wk_len = DLADM_WLAN_MAX_KEY_LEN; 56230ba2cbe9Sxc151355 56244ac67f02SAnurag S. Maskey status = dladm_get_secobj(handle, wk[i].wk_name, &class, 56250ba2cbe9Sxc151355 wk[i].wk_val, &wk[i].wk_len, 0); 56260ba2cbe9Sxc151355 if (status != DLADM_STATUS_OK) { 56270ba2cbe9Sxc151355 if (status == DLADM_STATUS_NOTFOUND) { 56284ac67f02SAnurag S. Maskey status = dladm_get_secobj(handle, wk[i].wk_name, 56290ba2cbe9Sxc151355 &class, wk[i].wk_val, &wk[i].wk_len, 56300ba2cbe9Sxc151355 DLADM_OPT_PERSIST); 56310ba2cbe9Sxc151355 } 56320ba2cbe9Sxc151355 if (status != DLADM_STATUS_OK) 56330ba2cbe9Sxc151355 goto fail; 56340ba2cbe9Sxc151355 } 5635a399b765Szf162725 wk[i].wk_class = class; 56360ba2cbe9Sxc151355 } 56370ba2cbe9Sxc151355 *keys = wk; 56380ba2cbe9Sxc151355 *key_countp = i; 56398002d411SSowmini Varadhan free(token); 56400ba2cbe9Sxc151355 return (0); 56410ba2cbe9Sxc151355 fail: 56420ba2cbe9Sxc151355 free(wk); 56438002d411SSowmini Varadhan free(token); 56440ba2cbe9Sxc151355 return (-1); 56450ba2cbe9Sxc151355 } 56460ba2cbe9Sxc151355 56470ba2cbe9Sxc151355 static void 56488d5c46e6Sam223141 do_connect_wifi(int argc, char **argv, const char *use) 56490ba2cbe9Sxc151355 { 56500ba2cbe9Sxc151355 int option; 5651f595a68aSyz147064 dladm_wlan_attr_t attr, *attrp; 5652f595a68aSyz147064 dladm_status_t status = DLADM_STATUS_OK; 5653f595a68aSyz147064 int timeout = DLADM_WLAN_CONNECT_TIMEOUT_DEFAULT; 5654d62bc4baSyz147064 datalink_id_t linkid = DATALINK_ALL_LINKID; 5655a399b765Szf162725 dladm_wlan_key_t *keys = NULL; 56560ba2cbe9Sxc151355 uint_t key_count = 0; 56570ba2cbe9Sxc151355 uint_t flags = 0; 5658f595a68aSyz147064 dladm_wlan_secmode_t keysecmode = DLADM_WLAN_SECMODE_NONE; 5659a399b765Szf162725 char buf[DLADM_STRSIZE]; 56600ba2cbe9Sxc151355 56610ba2cbe9Sxc151355 opterr = 0; 56620ba2cbe9Sxc151355 (void) memset(&attr, 0, sizeof (attr)); 56630ba2cbe9Sxc151355 while ((option = getopt_long(argc, argv, ":e:i:a:m:b:s:k:T:c", 56640ba2cbe9Sxc151355 wifi_longopts, NULL)) != -1) { 56650ba2cbe9Sxc151355 switch (option) { 56660ba2cbe9Sxc151355 case 'e': 5667f595a68aSyz147064 status = dladm_wlan_str2essid(optarg, &attr.wa_essid); 5668f595a68aSyz147064 if (status != DLADM_STATUS_OK) 566933343a97Smeem die("invalid ESSID '%s'", optarg); 567033343a97Smeem 5671f595a68aSyz147064 attr.wa_valid |= DLADM_WLAN_ATTR_ESSID; 56720ba2cbe9Sxc151355 /* 56730ba2cbe9Sxc151355 * Try to connect without doing a scan. 56740ba2cbe9Sxc151355 */ 5675f595a68aSyz147064 flags |= DLADM_WLAN_CONNECT_NOSCAN; 56760ba2cbe9Sxc151355 break; 56770ba2cbe9Sxc151355 case 'i': 5678f595a68aSyz147064 status = dladm_wlan_str2bssid(optarg, &attr.wa_bssid); 5679f595a68aSyz147064 if (status != DLADM_STATUS_OK) 568033343a97Smeem die("invalid BSSID %s", optarg); 568133343a97Smeem 5682f595a68aSyz147064 attr.wa_valid |= DLADM_WLAN_ATTR_BSSID; 56830ba2cbe9Sxc151355 break; 56840ba2cbe9Sxc151355 case 'a': 5685f595a68aSyz147064 status = dladm_wlan_str2auth(optarg, &attr.wa_auth); 5686f595a68aSyz147064 if (status != DLADM_STATUS_OK) 568733343a97Smeem die("invalid authentication mode '%s'", optarg); 568833343a97Smeem 5689f595a68aSyz147064 attr.wa_valid |= DLADM_WLAN_ATTR_AUTH; 56900ba2cbe9Sxc151355 break; 56910ba2cbe9Sxc151355 case 'm': 5692f595a68aSyz147064 status = dladm_wlan_str2mode(optarg, &attr.wa_mode); 5693f595a68aSyz147064 if (status != DLADM_STATUS_OK) 569433343a97Smeem die("invalid mode '%s'", optarg); 569533343a97Smeem 5696f595a68aSyz147064 attr.wa_valid |= DLADM_WLAN_ATTR_MODE; 56970ba2cbe9Sxc151355 break; 56980ba2cbe9Sxc151355 case 'b': 5699f595a68aSyz147064 if ((status = dladm_wlan_str2bsstype(optarg, 5700f595a68aSyz147064 &attr.wa_bsstype)) != DLADM_STATUS_OK) { 570133343a97Smeem die("invalid bsstype '%s'", optarg); 5702f595a68aSyz147064 } 570333343a97Smeem 5704f595a68aSyz147064 attr.wa_valid |= DLADM_WLAN_ATTR_BSSTYPE; 57050ba2cbe9Sxc151355 break; 57060ba2cbe9Sxc151355 case 's': 5707f595a68aSyz147064 if ((status = dladm_wlan_str2secmode(optarg, 5708f595a68aSyz147064 &attr.wa_secmode)) != DLADM_STATUS_OK) { 570933343a97Smeem die("invalid security mode '%s'", optarg); 5710f595a68aSyz147064 } 571133343a97Smeem 5712f595a68aSyz147064 attr.wa_valid |= DLADM_WLAN_ATTR_SECMODE; 57130ba2cbe9Sxc151355 break; 57140ba2cbe9Sxc151355 case 'k': 5715a399b765Szf162725 if (parse_wlan_keys(optarg, &keys, &key_count) < 0) 571633343a97Smeem die("invalid key(s) '%s'", optarg); 571733343a97Smeem 5718a399b765Szf162725 if (keys[0].wk_class == DLADM_SECOBJ_CLASS_WEP) 5719f595a68aSyz147064 keysecmode = DLADM_WLAN_SECMODE_WEP; 5720a399b765Szf162725 else 5721a399b765Szf162725 keysecmode = DLADM_WLAN_SECMODE_WPA; 57220ba2cbe9Sxc151355 break; 57230ba2cbe9Sxc151355 case 'T': 57240ba2cbe9Sxc151355 if (strcasecmp(optarg, "forever") == 0) { 57250ba2cbe9Sxc151355 timeout = -1; 57260ba2cbe9Sxc151355 break; 57270ba2cbe9Sxc151355 } 572833343a97Smeem if (!str2int(optarg, &timeout) || timeout < 0) 572933343a97Smeem die("invalid timeout value '%s'", optarg); 57300ba2cbe9Sxc151355 break; 57310ba2cbe9Sxc151355 case 'c': 5732f595a68aSyz147064 flags |= DLADM_WLAN_CONNECT_CREATEIBSS; 5733a399b765Szf162725 flags |= DLADM_WLAN_CONNECT_CREATEIBSS; 57340ba2cbe9Sxc151355 break; 57350ba2cbe9Sxc151355 default: 57368d5c46e6Sam223141 die_opterr(optopt, option, use); 57370ba2cbe9Sxc151355 break; 57380ba2cbe9Sxc151355 } 57390ba2cbe9Sxc151355 } 57400ba2cbe9Sxc151355 5741f595a68aSyz147064 if (keysecmode == DLADM_WLAN_SECMODE_NONE) { 5742a399b765Szf162725 if ((attr.wa_valid & DLADM_WLAN_ATTR_SECMODE) != 0) { 5743a399b765Szf162725 die("key required for security mode '%s'", 5744a399b765Szf162725 dladm_wlan_secmode2str(&attr.wa_secmode, buf)); 5745a399b765Szf162725 } 57460ba2cbe9Sxc151355 } else { 5747f595a68aSyz147064 if ((attr.wa_valid & DLADM_WLAN_ATTR_SECMODE) != 0 && 574833343a97Smeem attr.wa_secmode != keysecmode) 574933343a97Smeem die("incompatible -s and -k options"); 5750f595a68aSyz147064 attr.wa_valid |= DLADM_WLAN_ATTR_SECMODE; 5751a399b765Szf162725 attr.wa_secmode = keysecmode; 5752a399b765Szf162725 } 57530ba2cbe9Sxc151355 5754d62bc4baSyz147064 if (optind == (argc - 1)) { 57554ac67f02SAnurag S. Maskey if ((status = dladm_name2info(handle, argv[optind], &linkid, 57564ac67f02SAnurag S. Maskey NULL, NULL, NULL)) != DLADM_STATUS_OK) { 5757d62bc4baSyz147064 die_dlerr(status, "link %s is not valid", argv[optind]); 5758d62bc4baSyz147064 } 5759d62bc4baSyz147064 } else if (optind != argc) { 57600ba2cbe9Sxc151355 usage(); 5761d62bc4baSyz147064 } 57620ba2cbe9Sxc151355 5763d62bc4baSyz147064 if (linkid == DATALINK_ALL_LINKID) { 57640ba2cbe9Sxc151355 wlan_count_attr_t wcattr; 57650ba2cbe9Sxc151355 5766d62bc4baSyz147064 wcattr.wc_linkid = DATALINK_INVALID_LINKID; 57670ba2cbe9Sxc151355 wcattr.wc_count = 0; 57684ac67f02SAnurag S. Maskey (void) dladm_walk_datalink_id(do_count_wlan, handle, &wcattr, 5769b509e89bSRishi Srivatsavai DATALINK_CLASS_PHYS | DATALINK_CLASS_SIMNET, 5770b509e89bSRishi Srivatsavai DL_WIFI, DLADM_OPT_ACTIVE); 57710ba2cbe9Sxc151355 if (wcattr.wc_count == 0) { 577233343a97Smeem die("no wifi links are available"); 57730ba2cbe9Sxc151355 } else if (wcattr.wc_count > 1) { 577433343a97Smeem die("link name is required when more than one wifi " 577533343a97Smeem "link is available"); 57760ba2cbe9Sxc151355 } 5777d62bc4baSyz147064 linkid = wcattr.wc_linkid; 57780ba2cbe9Sxc151355 } 57790ba2cbe9Sxc151355 attrp = (attr.wa_valid == 0) ? NULL : &attr; 578033343a97Smeem again: 57814ac67f02SAnurag S. Maskey if ((status = dladm_wlan_connect(handle, linkid, attrp, timeout, keys, 5782f595a68aSyz147064 key_count, flags)) != DLADM_STATUS_OK) { 5783f595a68aSyz147064 if ((flags & DLADM_WLAN_CONNECT_NOSCAN) != 0) { 57840ba2cbe9Sxc151355 /* 578533343a97Smeem * Try again with scanning and filtering. 57860ba2cbe9Sxc151355 */ 5787f595a68aSyz147064 flags &= ~DLADM_WLAN_CONNECT_NOSCAN; 578833343a97Smeem goto again; 57890ba2cbe9Sxc151355 } 579033343a97Smeem 5791f595a68aSyz147064 if (status == DLADM_STATUS_NOTFOUND) { 57920ba2cbe9Sxc151355 if (attr.wa_valid == 0) { 579333343a97Smeem die("no wifi networks are available"); 57940ba2cbe9Sxc151355 } else { 579533343a97Smeem die("no wifi networks with the specified " 579633343a97Smeem "criteria are available"); 57970ba2cbe9Sxc151355 } 57980ba2cbe9Sxc151355 } 5799d62bc4baSyz147064 die_dlerr(status, "cannot connect"); 58000ba2cbe9Sxc151355 } 58010ba2cbe9Sxc151355 free(keys); 58020ba2cbe9Sxc151355 } 58030ba2cbe9Sxc151355 58040ba2cbe9Sxc151355 /* ARGSUSED */ 5805d62bc4baSyz147064 static int 58064ac67f02SAnurag S. Maskey do_all_disconnect_wifi(dladm_handle_t dh, datalink_id_t linkid, void *arg) 58070ba2cbe9Sxc151355 { 5808f595a68aSyz147064 dladm_status_t status; 58090ba2cbe9Sxc151355 58104ac67f02SAnurag S. Maskey status = dladm_wlan_disconnect(dh, linkid); 5811f595a68aSyz147064 if (status != DLADM_STATUS_OK) 5812d62bc4baSyz147064 warn_dlerr(status, "cannot disconnect link"); 581333343a97Smeem 5814d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 58150ba2cbe9Sxc151355 } 58160ba2cbe9Sxc151355 58170ba2cbe9Sxc151355 static void 58188d5c46e6Sam223141 do_disconnect_wifi(int argc, char **argv, const char *use) 58190ba2cbe9Sxc151355 { 58200ba2cbe9Sxc151355 int option; 5821d62bc4baSyz147064 datalink_id_t linkid = DATALINK_ALL_LINKID; 58220ba2cbe9Sxc151355 boolean_t all_links = B_FALSE; 5823f595a68aSyz147064 dladm_status_t status; 58240ba2cbe9Sxc151355 wlan_count_attr_t wcattr; 58250ba2cbe9Sxc151355 58260ba2cbe9Sxc151355 opterr = 0; 58270ba2cbe9Sxc151355 while ((option = getopt_long(argc, argv, ":a", 58280ba2cbe9Sxc151355 wifi_longopts, NULL)) != -1) { 58290ba2cbe9Sxc151355 switch (option) { 58300ba2cbe9Sxc151355 case 'a': 58310ba2cbe9Sxc151355 all_links = B_TRUE; 58320ba2cbe9Sxc151355 break; 58330ba2cbe9Sxc151355 default: 58348d5c46e6Sam223141 die_opterr(optopt, option, use); 58350ba2cbe9Sxc151355 break; 58360ba2cbe9Sxc151355 } 58370ba2cbe9Sxc151355 } 58380ba2cbe9Sxc151355 5839d62bc4baSyz147064 if (optind == (argc - 1)) { 58404ac67f02SAnurag S. Maskey if ((status = dladm_name2info(handle, argv[optind], &linkid, 58414ac67f02SAnurag S. Maskey NULL, NULL, NULL)) != DLADM_STATUS_OK) { 5842d62bc4baSyz147064 die_dlerr(status, "link %s is not valid", argv[optind]); 5843d62bc4baSyz147064 } 5844d62bc4baSyz147064 } else if (optind != argc) { 58450ba2cbe9Sxc151355 usage(); 5846d62bc4baSyz147064 } 58470ba2cbe9Sxc151355 5848d62bc4baSyz147064 if (linkid == DATALINK_ALL_LINKID) { 58490ba2cbe9Sxc151355 if (!all_links) { 5850d62bc4baSyz147064 wcattr.wc_linkid = linkid; 58510ba2cbe9Sxc151355 wcattr.wc_count = 0; 58524ac67f02SAnurag S. Maskey (void) dladm_walk_datalink_id(do_count_wlan, handle, 5853b509e89bSRishi Srivatsavai &wcattr, 5854b509e89bSRishi Srivatsavai DATALINK_CLASS_PHYS | DATALINK_CLASS_SIMNET, 5855b509e89bSRishi Srivatsavai DL_WIFI, DLADM_OPT_ACTIVE); 58560ba2cbe9Sxc151355 if (wcattr.wc_count == 0) { 585733343a97Smeem die("no wifi links are available"); 58580ba2cbe9Sxc151355 } else if (wcattr.wc_count > 1) { 585933343a97Smeem die("link name is required when more than " 586033343a97Smeem "one wifi link is available"); 58610ba2cbe9Sxc151355 } 5862d62bc4baSyz147064 linkid = wcattr.wc_linkid; 58630ba2cbe9Sxc151355 } else { 5864d62bc4baSyz147064 (void) dladm_walk_datalink_id(do_all_disconnect_wifi, 5865b509e89bSRishi Srivatsavai handle, NULL, 5866b509e89bSRishi Srivatsavai DATALINK_CLASS_PHYS | DATALINK_CLASS_SIMNET, 5867b509e89bSRishi Srivatsavai DL_WIFI, DLADM_OPT_ACTIVE); 58680ba2cbe9Sxc151355 return; 58690ba2cbe9Sxc151355 } 58700ba2cbe9Sxc151355 } 58714ac67f02SAnurag S. Maskey status = dladm_wlan_disconnect(handle, linkid); 5872f595a68aSyz147064 if (status != DLADM_STATUS_OK) 5873d62bc4baSyz147064 die_dlerr(status, "cannot disconnect"); 58740ba2cbe9Sxc151355 } 58750ba2cbe9Sxc151355 58760ba2cbe9Sxc151355 static void 5877d62bc4baSyz147064 print_linkprop(datalink_id_t linkid, show_linkprop_state_t *statep, 58784ac67f02SAnurag S. Maskey const char *propname, dladm_prop_type_t type, const char *format, 58794ac67f02SAnurag S. Maskey char **pptr) 58800ba2cbe9Sxc151355 { 58810ba2cbe9Sxc151355 int i; 58820ba2cbe9Sxc151355 char *ptr, *lim; 58830ba2cbe9Sxc151355 char buf[DLADM_STRSIZE]; 5884da14cebeSEric Cheng char *unknown = "--", *notsup = ""; 58850ba2cbe9Sxc151355 char **propvals = statep->ls_propvals; 5886d62bc4baSyz147064 uint_t valcnt = DLADM_MAX_PROP_VALCNT; 58870ba2cbe9Sxc151355 dladm_status_t status; 58880ba2cbe9Sxc151355 58894ac67f02SAnurag S. Maskey status = dladm_get_linkprop(handle, linkid, type, propname, propvals, 58904ac67f02SAnurag S. Maskey &valcnt); 58910ba2cbe9Sxc151355 if (status != DLADM_STATUS_OK) { 5892f595a68aSyz147064 if (status == DLADM_STATUS_TEMPONLY) { 5893d62bc4baSyz147064 if (type == DLADM_PROP_VAL_MODIFIABLE && 5894d62bc4baSyz147064 statep->ls_persist) { 5895d62bc4baSyz147064 valcnt = 1; 5896d62bc4baSyz147064 propvals = &unknown; 5897d62bc4baSyz147064 } else { 5898f595a68aSyz147064 statep->ls_status = status; 5899e7801d59Ssowmini statep->ls_retstatus = status; 5900f595a68aSyz147064 return; 5901d62bc4baSyz147064 } 5902f595a68aSyz147064 } else if (status == DLADM_STATUS_NOTSUP || 5903f595a68aSyz147064 statep->ls_persist) { 59040ba2cbe9Sxc151355 valcnt = 1; 5905afdda45fSVasumathi Sundaram - Sun Microsystems if (type == DLADM_PROP_VAL_CURRENT || 5906afdda45fSVasumathi Sundaram - Sun Microsystems type == DLADM_PROP_VAL_PERM) 59070ba2cbe9Sxc151355 propvals = &unknown; 59080ba2cbe9Sxc151355 else 59090ba2cbe9Sxc151355 propvals = ¬sup; 5910149b7eb2SSowmini Varadhan } else if (status == DLADM_STATUS_NOTDEFINED) { 5911149b7eb2SSowmini Varadhan propvals = ¬sup; /* STR_UNDEF_VAL */ 59120ba2cbe9Sxc151355 } else { 5913e7801d59Ssowmini if (statep->ls_proplist && 5914e7801d59Ssowmini statep->ls_status == DLADM_STATUS_OK) { 5915f595a68aSyz147064 warn_dlerr(status, 5916f595a68aSyz147064 "cannot get link property '%s' for %s", 5917f595a68aSyz147064 propname, statep->ls_link); 5918d62bc4baSyz147064 } 5919e7801d59Ssowmini statep->ls_status = status; 5920e7801d59Ssowmini statep->ls_retstatus = status; 5921f595a68aSyz147064 return; 59220ba2cbe9Sxc151355 } 59230ba2cbe9Sxc151355 } 59240ba2cbe9Sxc151355 5925e7801d59Ssowmini statep->ls_status = DLADM_STATUS_OK; 5926e7801d59Ssowmini 59270ba2cbe9Sxc151355 ptr = buf; 59280ba2cbe9Sxc151355 lim = buf + DLADM_STRSIZE; 59290ba2cbe9Sxc151355 for (i = 0; i < valcnt; i++) { 59308002d411SSowmini Varadhan if (propvals[i][0] == '\0' && !statep->ls_parsable) 59318002d411SSowmini Varadhan ptr += snprintf(ptr, lim - ptr, "--,"); 59320ba2cbe9Sxc151355 else 59330ba2cbe9Sxc151355 ptr += snprintf(ptr, lim - ptr, "%s,", propvals[i]); 59340ba2cbe9Sxc151355 if (ptr >= lim) 59350ba2cbe9Sxc151355 break; 59360ba2cbe9Sxc151355 } 59370ba2cbe9Sxc151355 if (valcnt > 0) 59380ba2cbe9Sxc151355 buf[strlen(buf) - 1] = '\0'; 59390ba2cbe9Sxc151355 59400ba2cbe9Sxc151355 lim = statep->ls_line + MAX_PROP_LINE; 59418002d411SSowmini Varadhan if (statep->ls_parsable) { 59420ba2cbe9Sxc151355 *pptr += snprintf(*pptr, lim - *pptr, 5943e7801d59Ssowmini "%s", buf); 59440ba2cbe9Sxc151355 } else { 59450ba2cbe9Sxc151355 *pptr += snprintf(*pptr, lim - *pptr, format, buf); 59460ba2cbe9Sxc151355 } 59470ba2cbe9Sxc151355 } 59480ba2cbe9Sxc151355 59498002d411SSowmini Varadhan static boolean_t 59508002d411SSowmini Varadhan print_linkprop_cb(ofmt_arg_t *ofarg, char *buf, uint_t bufsize) 5951e7801d59Ssowmini { 59528002d411SSowmini Varadhan linkprop_args_t *arg = ofarg->ofmt_cbarg; 5953e7801d59Ssowmini char *propname = arg->ls_propname; 5954e7801d59Ssowmini show_linkprop_state_t *statep = arg->ls_state; 5955e7801d59Ssowmini char *ptr = statep->ls_line; 5956e7801d59Ssowmini char *lim = ptr + MAX_PROP_LINE; 5957e7801d59Ssowmini datalink_id_t linkid = arg->ls_linkid; 5958e7801d59Ssowmini 59598002d411SSowmini Varadhan switch (ofarg->ofmt_id) { 5960e7801d59Ssowmini case LINKPROP_LINK: 5961e7801d59Ssowmini (void) snprintf(ptr, lim - ptr, "%s", statep->ls_link); 5962e7801d59Ssowmini break; 5963e7801d59Ssowmini case LINKPROP_PROPERTY: 5964e7801d59Ssowmini (void) snprintf(ptr, lim - ptr, "%s", propname); 5965e7801d59Ssowmini break; 5966e7801d59Ssowmini case LINKPROP_VALUE: 5967e7801d59Ssowmini print_linkprop(linkid, statep, propname, 5968e7801d59Ssowmini statep->ls_persist ? DLADM_PROP_VAL_PERSISTENT : 5969e7801d59Ssowmini DLADM_PROP_VAL_CURRENT, "%s", &ptr); 5970e7801d59Ssowmini /* 5971e7801d59Ssowmini * If we failed to query the link property, for example, query 5972e7801d59Ssowmini * the persistent value of a non-persistable link property, 5973e7801d59Ssowmini * simply skip the output. 5974e7801d59Ssowmini */ 5975e7801d59Ssowmini if (statep->ls_status != DLADM_STATUS_OK) 5976e7801d59Ssowmini goto skip; 5977e7801d59Ssowmini ptr = statep->ls_line; 5978e7801d59Ssowmini break; 5979afdda45fSVasumathi Sundaram - Sun Microsystems case LINKPROP_PERM: 5980afdda45fSVasumathi Sundaram - Sun Microsystems print_linkprop(linkid, statep, propname, 5981afdda45fSVasumathi Sundaram - Sun Microsystems DLADM_PROP_VAL_PERM, "%s", &ptr); 5982afdda45fSVasumathi Sundaram - Sun Microsystems if (statep->ls_status != DLADM_STATUS_OK) 5983afdda45fSVasumathi Sundaram - Sun Microsystems goto skip; 5984afdda45fSVasumathi Sundaram - Sun Microsystems ptr = statep->ls_line; 5985afdda45fSVasumathi Sundaram - Sun Microsystems break; 5986e7801d59Ssowmini case LINKPROP_DEFAULT: 5987e7801d59Ssowmini print_linkprop(linkid, statep, propname, 5988e7801d59Ssowmini DLADM_PROP_VAL_DEFAULT, "%s", &ptr); 5989e7801d59Ssowmini if (statep->ls_status != DLADM_STATUS_OK) 5990e7801d59Ssowmini goto skip; 5991e7801d59Ssowmini ptr = statep->ls_line; 5992e7801d59Ssowmini break; 5993e7801d59Ssowmini case LINKPROP_POSSIBLE: 5994e7801d59Ssowmini print_linkprop(linkid, statep, propname, 5995e7801d59Ssowmini DLADM_PROP_VAL_MODIFIABLE, "%s ", &ptr); 5996e7801d59Ssowmini if (statep->ls_status != DLADM_STATUS_OK) 5997e7801d59Ssowmini goto skip; 5998e7801d59Ssowmini ptr = statep->ls_line; 5999e7801d59Ssowmini break; 6000e7801d59Ssowmini default: 6001e7801d59Ssowmini die("invalid input"); 6002e7801d59Ssowmini break; 6003e7801d59Ssowmini } 60048002d411SSowmini Varadhan (void) strlcpy(buf, ptr, bufsize); 60058002d411SSowmini Varadhan return (B_TRUE); 6006e7801d59Ssowmini skip: 60078002d411SSowmini Varadhan return ((statep->ls_status == DLADM_STATUS_OK) ? 60088002d411SSowmini Varadhan B_TRUE : B_FALSE); 6009e7801d59Ssowmini } 6010e7801d59Ssowmini 6011bcb5c89dSSowmini Varadhan static boolean_t 6012bcb5c89dSSowmini Varadhan linkprop_is_supported(datalink_id_t linkid, const char *propname, 6013bcb5c89dSSowmini Varadhan show_linkprop_state_t *statep) 6014bcb5c89dSSowmini Varadhan { 6015bcb5c89dSSowmini Varadhan dladm_status_t status; 6016bcb5c89dSSowmini Varadhan uint_t valcnt = DLADM_MAX_PROP_VALCNT; 6017bcb5c89dSSowmini Varadhan 60184784fcbdSSowmini Varadhan /* if used with -p flag, always print output */ 60194784fcbdSSowmini Varadhan if (statep->ls_proplist != NULL) 60204784fcbdSSowmini Varadhan return (B_TRUE); 60214784fcbdSSowmini Varadhan 60224ac67f02SAnurag S. Maskey status = dladm_get_linkprop(handle, linkid, DLADM_PROP_VAL_DEFAULT, 6023bcb5c89dSSowmini Varadhan propname, statep->ls_propvals, &valcnt); 6024bcb5c89dSSowmini Varadhan 6025149b7eb2SSowmini Varadhan if (status == DLADM_STATUS_OK) 6026149b7eb2SSowmini Varadhan return (B_TRUE); 6027149b7eb2SSowmini Varadhan 6028149b7eb2SSowmini Varadhan /* 6029149b7eb2SSowmini Varadhan * A system wide default value is not available for the 6030149b7eb2SSowmini Varadhan * property. Check if current value can be retrieved. 6031149b7eb2SSowmini Varadhan */ 60324ac67f02SAnurag S. Maskey status = dladm_get_linkprop(handle, linkid, DLADM_PROP_VAL_CURRENT, 6033149b7eb2SSowmini Varadhan propname, statep->ls_propvals, &valcnt); 6034149b7eb2SSowmini Varadhan 6035149b7eb2SSowmini Varadhan return (status == DLADM_STATUS_OK); 6036bcb5c89dSSowmini Varadhan } 6037bcb5c89dSSowmini Varadhan 60384ac67f02SAnurag S. Maskey /* ARGSUSED */ 6039d62bc4baSyz147064 static int 60404ac67f02SAnurag S. Maskey show_linkprop(dladm_handle_t dh, datalink_id_t linkid, const char *propname, 60414ac67f02SAnurag S. Maskey void *arg) 60420ba2cbe9Sxc151355 { 60430ba2cbe9Sxc151355 show_linkprop_state_t *statep = arg; 6044e7801d59Ssowmini linkprop_args_t ls_arg; 60450ba2cbe9Sxc151355 6046e7801d59Ssowmini bzero(&ls_arg, sizeof (ls_arg)); 6047e7801d59Ssowmini ls_arg.ls_state = statep; 6048e7801d59Ssowmini ls_arg.ls_propname = (char *)propname; 6049e7801d59Ssowmini ls_arg.ls_linkid = linkid; 60500ba2cbe9Sxc151355 605162ee1d25SArtem Kachitchkine /* 605262ee1d25SArtem Kachitchkine * This will need to be fixed when kernel interfaces are added 605362ee1d25SArtem Kachitchkine * to enable walking of all known private properties. For now, 605462ee1d25SArtem Kachitchkine * we are limited to walking persistent private properties only. 605562ee1d25SArtem Kachitchkine */ 605662ee1d25SArtem Kachitchkine if ((propname[0] == '_') && !statep->ls_persist && 605762ee1d25SArtem Kachitchkine (statep->ls_proplist == NULL)) 605862ee1d25SArtem Kachitchkine return (DLADM_WALK_CONTINUE); 60598002d411SSowmini Varadhan if (!statep->ls_parsable && 6060149b7eb2SSowmini Varadhan !linkprop_is_supported(linkid, propname, statep)) 6061bcb5c89dSSowmini Varadhan return (DLADM_WALK_CONTINUE); 6062bcb5c89dSSowmini Varadhan 60638002d411SSowmini Varadhan ofmt_print(statep->ls_ofmt, &ls_arg); 6064e7801d59Ssowmini 6065d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 60660ba2cbe9Sxc151355 } 60670ba2cbe9Sxc151355 60680ba2cbe9Sxc151355 static void 60698d5c46e6Sam223141 do_show_linkprop(int argc, char **argv, const char *use) 60700ba2cbe9Sxc151355 { 6071f4b3ec61Sdh155122 int option; 607263a6526dSMichael Lim char propstr[DLADM_STRSIZE]; 6073da14cebeSEric Cheng dladm_arg_list_t *proplist = NULL; 6074d62bc4baSyz147064 datalink_id_t linkid = DATALINK_ALL_LINKID; 60750ba2cbe9Sxc151355 show_linkprop_state_t state; 6076d62bc4baSyz147064 uint32_t flags = DLADM_OPT_ACTIVE; 6077d62bc4baSyz147064 dladm_status_t status; 6078e7801d59Ssowmini char *fields_str = NULL; 60798002d411SSowmini Varadhan ofmt_handle_t ofmt; 60808002d411SSowmini Varadhan ofmt_status_t oferr; 60818002d411SSowmini Varadhan uint_t ofmtflags = 0; 60820ba2cbe9Sxc151355 608363a6526dSMichael Lim bzero(propstr, DLADM_STRSIZE); 60840ba2cbe9Sxc151355 opterr = 0; 60850ba2cbe9Sxc151355 state.ls_propvals = NULL; 60860ba2cbe9Sxc151355 state.ls_line = NULL; 60878002d411SSowmini Varadhan state.ls_parsable = B_FALSE; 60880ba2cbe9Sxc151355 state.ls_persist = B_FALSE; 60890ba2cbe9Sxc151355 state.ls_header = B_TRUE; 6090e7801d59Ssowmini state.ls_retstatus = DLADM_STATUS_OK; 609163a6526dSMichael Lim 6092e7801d59Ssowmini while ((option = getopt_long(argc, argv, ":p:cPo:", 60930ba2cbe9Sxc151355 prop_longopts, NULL)) != -1) { 60940ba2cbe9Sxc151355 switch (option) { 60950ba2cbe9Sxc151355 case 'p': 609663a6526dSMichael Lim (void) strlcat(propstr, optarg, DLADM_STRSIZE); 609763a6526dSMichael Lim if (strlcat(propstr, ",", DLADM_STRSIZE) >= 609863a6526dSMichael Lim DLADM_STRSIZE) 609963a6526dSMichael Lim die("property list too long '%s'", propstr); 61000ba2cbe9Sxc151355 break; 61010ba2cbe9Sxc151355 case 'c': 61028002d411SSowmini Varadhan state.ls_parsable = B_TRUE; 61030ba2cbe9Sxc151355 break; 61040ba2cbe9Sxc151355 case 'P': 61050ba2cbe9Sxc151355 state.ls_persist = B_TRUE; 6106d62bc4baSyz147064 flags = DLADM_OPT_PERSIST; 61070ba2cbe9Sxc151355 break; 6108e7801d59Ssowmini case 'o': 6109e7801d59Ssowmini fields_str = optarg; 6110e7801d59Ssowmini break; 61110ba2cbe9Sxc151355 default: 61128d5c46e6Sam223141 die_opterr(optopt, option, use); 61130ba2cbe9Sxc151355 break; 61140ba2cbe9Sxc151355 } 61150ba2cbe9Sxc151355 } 61160ba2cbe9Sxc151355 6117d62bc4baSyz147064 if (optind == (argc - 1)) { 61184ac67f02SAnurag S. Maskey if ((status = dladm_name2info(handle, argv[optind], &linkid, 61194ac67f02SAnurag S. Maskey NULL, NULL, NULL)) != DLADM_STATUS_OK) { 6120d62bc4baSyz147064 die_dlerr(status, "link %s is not valid", argv[optind]); 6121d62bc4baSyz147064 } 6122d62bc4baSyz147064 } else if (optind != argc) { 61230ba2cbe9Sxc151355 usage(); 6124d62bc4baSyz147064 } 61250ba2cbe9Sxc151355 612663a6526dSMichael Lim if (dladm_parse_link_props(propstr, &proplist, B_TRUE) 612763a6526dSMichael Lim != DLADM_STATUS_OK) 612863a6526dSMichael Lim die("invalid link properties specified"); 6129f4b3ec61Sdh155122 state.ls_proplist = proplist; 6130f595a68aSyz147064 state.ls_status = DLADM_STATUS_OK; 6131f4b3ec61Sdh155122 61328002d411SSowmini Varadhan if (state.ls_parsable) 61338002d411SSowmini Varadhan ofmtflags |= OFMT_PARSABLE; 61348002d411SSowmini Varadhan oferr = ofmt_open(fields_str, linkprop_fields, ofmtflags, 0, &ofmt); 61358002d411SSowmini Varadhan dladm_ofmt_check(oferr, state.ls_parsable, ofmt); 61368002d411SSowmini Varadhan state.ls_ofmt = ofmt; 6137e7801d59Ssowmini 6138d62bc4baSyz147064 if (linkid == DATALINK_ALL_LINKID) { 61394ac67f02SAnurag S. Maskey (void) dladm_walk_datalink_id(show_linkprop_onelink, handle, 61404ac67f02SAnurag S. Maskey &state, DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE, flags); 6141f4b3ec61Sdh155122 } else { 61424ac67f02SAnurag S. Maskey (void) show_linkprop_onelink(handle, linkid, &state); 6143f4b3ec61Sdh155122 } 61448002d411SSowmini Varadhan ofmt_close(ofmt); 6145da14cebeSEric Cheng dladm_free_props(proplist); 6146f595a68aSyz147064 61474ac67f02SAnurag S. Maskey if (state.ls_retstatus != DLADM_STATUS_OK) { 61484ac67f02SAnurag S. Maskey dladm_close(handle); 6149f595a68aSyz147064 exit(EXIT_FAILURE); 6150f4b3ec61Sdh155122 } 61514ac67f02SAnurag S. Maskey } 6152f4b3ec61Sdh155122 6153d62bc4baSyz147064 static int 61544ac67f02SAnurag S. Maskey show_linkprop_onelink(dladm_handle_t hdl, datalink_id_t linkid, void *arg) 6155f4b3ec61Sdh155122 { 6156948f2876Sss150715 int i; 6157f4b3ec61Sdh155122 char *buf; 6158d62bc4baSyz147064 uint32_t flags; 6159da14cebeSEric Cheng dladm_arg_list_t *proplist = NULL; 6160d62bc4baSyz147064 show_linkprop_state_t *statep = arg; 6161d62bc4baSyz147064 dlpi_handle_t dh = NULL; 6162f4b3ec61Sdh155122 6163d62bc4baSyz147064 statep->ls_status = DLADM_STATUS_OK; 6164d62bc4baSyz147064 61654ac67f02SAnurag S. Maskey if (dladm_datalink_id2info(hdl, linkid, &flags, NULL, NULL, 61664ac67f02SAnurag S. Maskey statep->ls_link, MAXLINKNAMELEN) != DLADM_STATUS_OK) { 6167d62bc4baSyz147064 statep->ls_status = DLADM_STATUS_NOTFOUND; 6168d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 6169d62bc4baSyz147064 } 6170d62bc4baSyz147064 6171d62bc4baSyz147064 if ((statep->ls_persist && !(flags & DLADM_OPT_PERSIST)) || 6172d62bc4baSyz147064 (!statep->ls_persist && !(flags & DLADM_OPT_ACTIVE))) { 6173d62bc4baSyz147064 statep->ls_status = DLADM_STATUS_BADARG; 6174d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 6175d62bc4baSyz147064 } 6176d62bc4baSyz147064 6177f4b3ec61Sdh155122 proplist = statep->ls_proplist; 61780ba2cbe9Sxc151355 61790ba2cbe9Sxc151355 /* 61800ba2cbe9Sxc151355 * When some WiFi links are opened for the first time, their hardware 61810ba2cbe9Sxc151355 * automatically scans for APs and does other slow operations. Thus, 61820ba2cbe9Sxc151355 * if there are no open links, the retrieval of link properties 61830ba2cbe9Sxc151355 * (below) will proceed slowly unless we hold the link open. 6184d62bc4baSyz147064 * 6185d62bc4baSyz147064 * Note that failure of dlpi_open() does not necessarily mean invalid 6186d62bc4baSyz147064 * link properties, because dlpi_open() may fail because of incorrect 6187d62bc4baSyz147064 * autopush configuration. Therefore, we ingore the return value of 6188d62bc4baSyz147064 * dlpi_open(). 61890ba2cbe9Sxc151355 */ 6190d62bc4baSyz147064 if (!statep->ls_persist) 6191d62bc4baSyz147064 (void) dlpi_open(statep->ls_link, &dh, 0); 61920ba2cbe9Sxc151355 6193d62bc4baSyz147064 buf = malloc((sizeof (char *) + DLADM_PROP_VAL_MAX) * 6194d62bc4baSyz147064 DLADM_MAX_PROP_VALCNT + MAX_PROP_LINE); 619533343a97Smeem if (buf == NULL) 619633343a97Smeem die("insufficient memory"); 619733343a97Smeem 6198f4b3ec61Sdh155122 statep->ls_propvals = (char **)(void *)buf; 6199d62bc4baSyz147064 for (i = 0; i < DLADM_MAX_PROP_VALCNT; i++) { 6200d62bc4baSyz147064 statep->ls_propvals[i] = buf + 6201d62bc4baSyz147064 sizeof (char *) * DLADM_MAX_PROP_VALCNT + 62020ba2cbe9Sxc151355 i * DLADM_PROP_VAL_MAX; 62030ba2cbe9Sxc151355 } 6204f4b3ec61Sdh155122 statep->ls_line = buf + 6205d62bc4baSyz147064 (sizeof (char *) + DLADM_PROP_VAL_MAX) * DLADM_MAX_PROP_VALCNT; 62060ba2cbe9Sxc151355 62070ba2cbe9Sxc151355 if (proplist != NULL) { 6208da14cebeSEric Cheng for (i = 0; i < proplist->al_count; i++) { 62094ac67f02SAnurag S. Maskey (void) show_linkprop(hdl, linkid, 6210da14cebeSEric Cheng proplist->al_info[i].ai_name, statep); 62110ba2cbe9Sxc151355 } 6212d62bc4baSyz147064 } else { 62134ac67f02SAnurag S. Maskey (void) dladm_walk_linkprop(hdl, linkid, statep, 62144ac67f02SAnurag S. Maskey show_linkprop); 6215d62bc4baSyz147064 } 6216d62bc4baSyz147064 if (dh != NULL) 6217948f2876Sss150715 dlpi_close(dh); 62180ba2cbe9Sxc151355 free(buf); 6219d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 62200ba2cbe9Sxc151355 } 62210ba2cbe9Sxc151355 6222da14cebeSEric Cheng static int 62234ac67f02SAnurag S. Maskey reset_one_linkprop(dladm_handle_t dh, datalink_id_t linkid, 62244ac67f02SAnurag S. Maskey const char *propname, void *arg) 6225da14cebeSEric Cheng { 6226da14cebeSEric Cheng set_linkprop_state_t *statep = arg; 6227da14cebeSEric Cheng dladm_status_t status; 6228da14cebeSEric Cheng 62294ac67f02SAnurag S. Maskey status = dladm_set_linkprop(dh, linkid, propname, NULL, 0, 6230*4eaa4710SRishi Srivatsavai DLADM_OPT_ACTIVE | (statep->ls_temp ? 0 : DLADM_OPT_PERSIST)); 62310b8f0546SSowmini Varadhan if (status != DLADM_STATUS_OK && 62320b8f0546SSowmini Varadhan status != DLADM_STATUS_PROPRDONLY && 62330b8f0546SSowmini Varadhan status != DLADM_STATUS_NOTSUP) { 6234da14cebeSEric Cheng warn_dlerr(status, "cannot reset link property '%s' on '%s'", 6235da14cebeSEric Cheng propname, statep->ls_name); 6236da14cebeSEric Cheng statep->ls_status = status; 6237*4eaa4710SRishi Srivatsavai } 6238da14cebeSEric Cheng 6239da14cebeSEric Cheng return (DLADM_WALK_CONTINUE); 6240da14cebeSEric Cheng } 6241da14cebeSEric Cheng 62420ba2cbe9Sxc151355 static void 62438d5c46e6Sam223141 set_linkprop(int argc, char **argv, boolean_t reset, const char *use) 62440ba2cbe9Sxc151355 { 62450ba2cbe9Sxc151355 int i, option; 62460ba2cbe9Sxc151355 char errmsg[DLADM_STRSIZE]; 6247d62bc4baSyz147064 char *altroot = NULL; 6248d62bc4baSyz147064 datalink_id_t linkid; 62490ba2cbe9Sxc151355 boolean_t temp = B_FALSE; 62500ba2cbe9Sxc151355 dladm_status_t status = DLADM_STATUS_OK; 625163a6526dSMichael Lim char propstr[DLADM_STRSIZE]; 6252da14cebeSEric Cheng dladm_arg_list_t *proplist = NULL; 62530ba2cbe9Sxc151355 62540ba2cbe9Sxc151355 opterr = 0; 625563a6526dSMichael Lim bzero(propstr, DLADM_STRSIZE); 625663a6526dSMichael Lim 62570ba2cbe9Sxc151355 while ((option = getopt_long(argc, argv, ":p:R:t", 62580ba2cbe9Sxc151355 prop_longopts, NULL)) != -1) { 62590ba2cbe9Sxc151355 switch (option) { 62600ba2cbe9Sxc151355 case 'p': 626163a6526dSMichael Lim (void) strlcat(propstr, optarg, DLADM_STRSIZE); 626263a6526dSMichael Lim if (strlcat(propstr, ",", DLADM_STRSIZE) >= 626363a6526dSMichael Lim DLADM_STRSIZE) 626463a6526dSMichael Lim die("property list too long '%s'", propstr); 62650ba2cbe9Sxc151355 break; 62660ba2cbe9Sxc151355 case 't': 62670ba2cbe9Sxc151355 temp = B_TRUE; 62680ba2cbe9Sxc151355 break; 62690ba2cbe9Sxc151355 case 'R': 6270d62bc4baSyz147064 altroot = optarg; 62710ba2cbe9Sxc151355 break; 62720ba2cbe9Sxc151355 default: 62738d5c46e6Sam223141 die_opterr(optopt, option, use); 62748d5c46e6Sam223141 62750ba2cbe9Sxc151355 } 62760ba2cbe9Sxc151355 } 62770ba2cbe9Sxc151355 6278d62bc4baSyz147064 /* get link name (required last argument) */ 6279d62bc4baSyz147064 if (optind != (argc - 1)) 62800ba2cbe9Sxc151355 usage(); 62810ba2cbe9Sxc151355 628263a6526dSMichael Lim if (dladm_parse_link_props(propstr, &proplist, reset) != 628363a6526dSMichael Lim DLADM_STATUS_OK) 628463a6526dSMichael Lim die("invalid link properties specified"); 628563a6526dSMichael Lim 6286d62bc4baSyz147064 if (proplist == NULL && !reset) 628733343a97Smeem die("link property must be specified"); 628833343a97Smeem 6289d62bc4baSyz147064 if (altroot != NULL) { 6290da14cebeSEric Cheng dladm_free_props(proplist); 6291d62bc4baSyz147064 altroot_cmd(altroot, argc, argv); 6292d62bc4baSyz147064 } 6293d62bc4baSyz147064 62944ac67f02SAnurag S. Maskey status = dladm_name2info(handle, argv[optind], &linkid, NULL, NULL, 62954ac67f02SAnurag S. Maskey NULL); 6296d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 6297d62bc4baSyz147064 die_dlerr(status, "link %s is not valid", argv[optind]); 6298d62bc4baSyz147064 6299d62bc4baSyz147064 if (proplist == NULL) { 6300da14cebeSEric Cheng set_linkprop_state_t state; 630113994ee8Sxz162242 6302da14cebeSEric Cheng state.ls_name = argv[optind]; 6303da14cebeSEric Cheng state.ls_reset = reset; 6304da14cebeSEric Cheng state.ls_temp = temp; 6305da14cebeSEric Cheng state.ls_status = DLADM_STATUS_OK; 6306da14cebeSEric Cheng 63074ac67f02SAnurag S. Maskey (void) dladm_walk_linkprop(handle, linkid, &state, 63084ac67f02SAnurag S. Maskey reset_one_linkprop); 6309da14cebeSEric Cheng 6310da14cebeSEric Cheng status = state.ls_status; 63110ba2cbe9Sxc151355 goto done; 63120ba2cbe9Sxc151355 } 63130ba2cbe9Sxc151355 6314da14cebeSEric Cheng for (i = 0; i < proplist->al_count; i++) { 6315da14cebeSEric Cheng dladm_arg_info_t *aip = &proplist->al_info[i]; 63160ba2cbe9Sxc151355 char **val; 63170ba2cbe9Sxc151355 uint_t count; 63180ba2cbe9Sxc151355 63190ba2cbe9Sxc151355 if (reset) { 63200ba2cbe9Sxc151355 val = NULL; 63210ba2cbe9Sxc151355 count = 0; 63220ba2cbe9Sxc151355 } else { 6323da14cebeSEric Cheng val = aip->ai_val; 6324da14cebeSEric Cheng count = aip->ai_count; 63250ba2cbe9Sxc151355 if (count == 0) { 632633343a97Smeem warn("no value specified for '%s'", 6327da14cebeSEric Cheng aip->ai_name); 63280ba2cbe9Sxc151355 status = DLADM_STATUS_BADARG; 63290ba2cbe9Sxc151355 continue; 63300ba2cbe9Sxc151355 } 63310ba2cbe9Sxc151355 } 6332*4eaa4710SRishi Srivatsavai status = dladm_set_linkprop(handle, linkid, aip->ai_name, val, 6333*4eaa4710SRishi Srivatsavai count, DLADM_OPT_ACTIVE | (temp ? 0 : DLADM_OPT_PERSIST)); 6334*4eaa4710SRishi Srivatsavai switch (status) { 6335*4eaa4710SRishi Srivatsavai case DLADM_STATUS_OK: 6336*4eaa4710SRishi Srivatsavai break; 63370ba2cbe9Sxc151355 case DLADM_STATUS_NOTFOUND: 6338da14cebeSEric Cheng warn("invalid link property '%s'", aip->ai_name); 63390ba2cbe9Sxc151355 break; 63400ba2cbe9Sxc151355 case DLADM_STATUS_BADVAL: { 63410ba2cbe9Sxc151355 int j; 63420ba2cbe9Sxc151355 char *ptr, *lim; 63430ba2cbe9Sxc151355 char **propvals = NULL; 6344d62bc4baSyz147064 uint_t valcnt = DLADM_MAX_PROP_VALCNT; 6345*4eaa4710SRishi Srivatsavai dladm_status_t s; 63460ba2cbe9Sxc151355 63470ba2cbe9Sxc151355 ptr = malloc((sizeof (char *) + 6348d62bc4baSyz147064 DLADM_PROP_VAL_MAX) * DLADM_MAX_PROP_VALCNT + 63490ba2cbe9Sxc151355 MAX_PROP_LINE); 63500ba2cbe9Sxc151355 63510ba2cbe9Sxc151355 propvals = (char **)(void *)ptr; 635233343a97Smeem if (propvals == NULL) 635333343a97Smeem die("insufficient memory"); 635433343a97Smeem 6355d62bc4baSyz147064 for (j = 0; j < DLADM_MAX_PROP_VALCNT; j++) { 63560ba2cbe9Sxc151355 propvals[j] = ptr + sizeof (char *) * 6357d62bc4baSyz147064 DLADM_MAX_PROP_VALCNT + 63580ba2cbe9Sxc151355 j * DLADM_PROP_VAL_MAX; 63590ba2cbe9Sxc151355 } 63604ac67f02SAnurag S. Maskey s = dladm_get_linkprop(handle, linkid, 6361da14cebeSEric Cheng DLADM_PROP_VAL_MODIFIABLE, aip->ai_name, propvals, 6362d62bc4baSyz147064 &valcnt); 6363d62bc4baSyz147064 6364d62bc4baSyz147064 if (s != DLADM_STATUS_OK) { 6365d62bc4baSyz147064 warn_dlerr(status, "cannot set link property " 6366da14cebeSEric Cheng "'%s' on '%s'", aip->ai_name, argv[optind]); 6367d62bc4baSyz147064 free(propvals); 6368d62bc4baSyz147064 break; 6369d62bc4baSyz147064 } 63700ba2cbe9Sxc151355 63710ba2cbe9Sxc151355 ptr = errmsg; 63720ba2cbe9Sxc151355 lim = ptr + DLADM_STRSIZE; 63730ba2cbe9Sxc151355 *ptr = '\0'; 6374d62bc4baSyz147064 for (j = 0; j < valcnt; j++) { 63750ba2cbe9Sxc151355 ptr += snprintf(ptr, lim - ptr, "%s,", 63760ba2cbe9Sxc151355 propvals[j]); 63770ba2cbe9Sxc151355 if (ptr >= lim) 63780ba2cbe9Sxc151355 break; 63790ba2cbe9Sxc151355 } 6380f4b3ec61Sdh155122 if (ptr > errmsg) { 63810ba2cbe9Sxc151355 *(ptr - 1) = '\0'; 638233343a97Smeem warn("link property '%s' must be one of: %s", 6383da14cebeSEric Cheng aip->ai_name, errmsg); 6384f4b3ec61Sdh155122 } else 6385f4b3ec61Sdh155122 warn("invalid link property '%s'", *val); 63860ba2cbe9Sxc151355 free(propvals); 63870ba2cbe9Sxc151355 break; 63880ba2cbe9Sxc151355 } 63890ba2cbe9Sxc151355 default: 63900ba2cbe9Sxc151355 if (reset) { 639133343a97Smeem warn_dlerr(status, "cannot reset link property " 6392da14cebeSEric Cheng "'%s' on '%s'", aip->ai_name, argv[optind]); 63930ba2cbe9Sxc151355 } else { 639433343a97Smeem warn_dlerr(status, "cannot set link property " 6395da14cebeSEric Cheng "'%s' on '%s'", aip->ai_name, argv[optind]); 63960ba2cbe9Sxc151355 } 63970ba2cbe9Sxc151355 break; 63980ba2cbe9Sxc151355 } 63990ba2cbe9Sxc151355 } 64000ba2cbe9Sxc151355 done: 6401da14cebeSEric Cheng dladm_free_props(proplist); 64024ac67f02SAnurag S. Maskey if (status != DLADM_STATUS_OK) { 64034ac67f02SAnurag S. Maskey dladm_close(handle); 64040ba2cbe9Sxc151355 exit(1); 64050ba2cbe9Sxc151355 } 64064ac67f02SAnurag S. Maskey } 64070ba2cbe9Sxc151355 64080ba2cbe9Sxc151355 static void 64098d5c46e6Sam223141 do_set_linkprop(int argc, char **argv, const char *use) 64100ba2cbe9Sxc151355 { 64118d5c46e6Sam223141 set_linkprop(argc, argv, B_FALSE, use); 64120ba2cbe9Sxc151355 } 64130ba2cbe9Sxc151355 64140ba2cbe9Sxc151355 static void 64158d5c46e6Sam223141 do_reset_linkprop(int argc, char **argv, const char *use) 64160ba2cbe9Sxc151355 { 64178d5c46e6Sam223141 set_linkprop(argc, argv, B_TRUE, use); 64180ba2cbe9Sxc151355 } 64190ba2cbe9Sxc151355 64200ba2cbe9Sxc151355 static int 64210ba2cbe9Sxc151355 convert_secobj(char *buf, uint_t len, uint8_t *obj_val, uint_t *obj_lenp, 64220ba2cbe9Sxc151355 dladm_secobj_class_t class) 64230ba2cbe9Sxc151355 { 64240ba2cbe9Sxc151355 int error = 0; 64250ba2cbe9Sxc151355 6426a399b765Szf162725 if (class == DLADM_SECOBJ_CLASS_WPA) { 6427a399b765Szf162725 if (len < 8 || len > 63) 6428a399b765Szf162725 return (EINVAL); 6429a399b765Szf162725 (void) memcpy(obj_val, buf, len); 6430a399b765Szf162725 *obj_lenp = len; 6431a399b765Szf162725 return (error); 6432a399b765Szf162725 } 64330ba2cbe9Sxc151355 6434a399b765Szf162725 if (class == DLADM_SECOBJ_CLASS_WEP) { 64350ba2cbe9Sxc151355 switch (len) { 64360ba2cbe9Sxc151355 case 5: /* ASCII key sizes */ 64370ba2cbe9Sxc151355 case 13: 64380ba2cbe9Sxc151355 (void) memcpy(obj_val, buf, len); 64390ba2cbe9Sxc151355 *obj_lenp = len; 64400ba2cbe9Sxc151355 break; 64410ba2cbe9Sxc151355 case 10: /* Hex key sizes, not preceded by 0x */ 64420ba2cbe9Sxc151355 case 26: 64430ba2cbe9Sxc151355 error = hexascii_to_octet(buf, len, obj_val, obj_lenp); 64440ba2cbe9Sxc151355 break; 64450ba2cbe9Sxc151355 case 12: /* Hex key sizes, preceded by 0x */ 64460ba2cbe9Sxc151355 case 28: 64470ba2cbe9Sxc151355 if (strncmp(buf, "0x", 2) != 0) 64480ba2cbe9Sxc151355 return (EINVAL); 6449a399b765Szf162725 error = hexascii_to_octet(buf + 2, len - 2, 6450a399b765Szf162725 obj_val, obj_lenp); 64510ba2cbe9Sxc151355 break; 64520ba2cbe9Sxc151355 default: 64530ba2cbe9Sxc151355 return (EINVAL); 64540ba2cbe9Sxc151355 } 64550ba2cbe9Sxc151355 return (error); 64560ba2cbe9Sxc151355 } 64570ba2cbe9Sxc151355 6458a399b765Szf162725 return (ENOENT); 6459a399b765Szf162725 } 6460a399b765Szf162725 64610ba2cbe9Sxc151355 static void 64620ba2cbe9Sxc151355 defersig(int sig) 64630ba2cbe9Sxc151355 { 64640ba2cbe9Sxc151355 signalled = sig; 64650ba2cbe9Sxc151355 } 64660ba2cbe9Sxc151355 64670ba2cbe9Sxc151355 static int 64680ba2cbe9Sxc151355 get_secobj_from_tty(uint_t try, const char *objname, char *buf) 64690ba2cbe9Sxc151355 { 64700ba2cbe9Sxc151355 uint_t len = 0; 64710ba2cbe9Sxc151355 int c; 64720ba2cbe9Sxc151355 struct termios stored, current; 64730ba2cbe9Sxc151355 void (*sigfunc)(int); 64740ba2cbe9Sxc151355 64750ba2cbe9Sxc151355 /* 64760ba2cbe9Sxc151355 * Turn off echo -- but before we do so, defer SIGINT handling 64770ba2cbe9Sxc151355 * so that a ^C doesn't leave the terminal corrupted. 64780ba2cbe9Sxc151355 */ 64790ba2cbe9Sxc151355 sigfunc = signal(SIGINT, defersig); 64800ba2cbe9Sxc151355 (void) fflush(stdin); 64810ba2cbe9Sxc151355 (void) tcgetattr(0, &stored); 64820ba2cbe9Sxc151355 current = stored; 64830ba2cbe9Sxc151355 current.c_lflag &= ~(ICANON|ECHO); 64840ba2cbe9Sxc151355 current.c_cc[VTIME] = 0; 64850ba2cbe9Sxc151355 current.c_cc[VMIN] = 1; 64860ba2cbe9Sxc151355 (void) tcsetattr(0, TCSANOW, ¤t); 64870ba2cbe9Sxc151355 again: 64880ba2cbe9Sxc151355 if (try == 1) 64890ba2cbe9Sxc151355 (void) printf(gettext("provide value for '%s': "), objname); 64900ba2cbe9Sxc151355 else 64910ba2cbe9Sxc151355 (void) printf(gettext("confirm value for '%s': "), objname); 64920ba2cbe9Sxc151355 64930ba2cbe9Sxc151355 (void) fflush(stdout); 64940ba2cbe9Sxc151355 while (signalled == 0) { 64950ba2cbe9Sxc151355 c = getchar(); 64960ba2cbe9Sxc151355 if (c == '\n' || c == '\r') { 64970ba2cbe9Sxc151355 if (len != 0) 64980ba2cbe9Sxc151355 break; 64990ba2cbe9Sxc151355 (void) putchar('\n'); 65000ba2cbe9Sxc151355 goto again; 65010ba2cbe9Sxc151355 } 65020ba2cbe9Sxc151355 65030ba2cbe9Sxc151355 buf[len++] = c; 65040ba2cbe9Sxc151355 if (len >= DLADM_SECOBJ_VAL_MAX - 1) 65050ba2cbe9Sxc151355 break; 65060ba2cbe9Sxc151355 (void) putchar('*'); 65070ba2cbe9Sxc151355 } 65080ba2cbe9Sxc151355 65090ba2cbe9Sxc151355 (void) putchar('\n'); 65100ba2cbe9Sxc151355 (void) fflush(stdin); 65110ba2cbe9Sxc151355 65120ba2cbe9Sxc151355 /* 65130ba2cbe9Sxc151355 * Restore terminal setting and handle deferred signals. 65140ba2cbe9Sxc151355 */ 65150ba2cbe9Sxc151355 (void) tcsetattr(0, TCSANOW, &stored); 65160ba2cbe9Sxc151355 65170ba2cbe9Sxc151355 (void) signal(SIGINT, sigfunc); 65180ba2cbe9Sxc151355 if (signalled != 0) 65190ba2cbe9Sxc151355 (void) kill(getpid(), signalled); 65200ba2cbe9Sxc151355 65210ba2cbe9Sxc151355 return (len); 65220ba2cbe9Sxc151355 } 65230ba2cbe9Sxc151355 65240ba2cbe9Sxc151355 static int 65250ba2cbe9Sxc151355 get_secobj_val(char *obj_name, uint8_t *obj_val, uint_t *obj_lenp, 65260ba2cbe9Sxc151355 dladm_secobj_class_t class, FILE *filep) 65270ba2cbe9Sxc151355 { 65280ba2cbe9Sxc151355 int rval; 65290ba2cbe9Sxc151355 uint_t len, len2; 65300ba2cbe9Sxc151355 char buf[DLADM_SECOBJ_VAL_MAX], buf2[DLADM_SECOBJ_VAL_MAX]; 65310ba2cbe9Sxc151355 65320ba2cbe9Sxc151355 if (filep == NULL) { 65330ba2cbe9Sxc151355 len = get_secobj_from_tty(1, obj_name, buf); 65340ba2cbe9Sxc151355 rval = convert_secobj(buf, len, obj_val, obj_lenp, class); 65350ba2cbe9Sxc151355 if (rval == 0) { 65360ba2cbe9Sxc151355 len2 = get_secobj_from_tty(2, obj_name, buf2); 65370ba2cbe9Sxc151355 if (len != len2 || memcmp(buf, buf2, len) != 0) 65380ba2cbe9Sxc151355 rval = ENOTSUP; 65390ba2cbe9Sxc151355 } 65400ba2cbe9Sxc151355 return (rval); 65410ba2cbe9Sxc151355 } else { 65420ba2cbe9Sxc151355 for (;;) { 65430ba2cbe9Sxc151355 if (fgets(buf, sizeof (buf), filep) == NULL) 65440ba2cbe9Sxc151355 break; 65450ba2cbe9Sxc151355 if (isspace(buf[0])) 65460ba2cbe9Sxc151355 continue; 65470ba2cbe9Sxc151355 65480ba2cbe9Sxc151355 len = strlen(buf); 65490ba2cbe9Sxc151355 if (buf[len - 1] == '\n') { 65500ba2cbe9Sxc151355 buf[len - 1] = '\0'; 65510ba2cbe9Sxc151355 len--; 65520ba2cbe9Sxc151355 } 65530ba2cbe9Sxc151355 break; 65540ba2cbe9Sxc151355 } 65550ba2cbe9Sxc151355 (void) fclose(filep); 65560ba2cbe9Sxc151355 } 65570ba2cbe9Sxc151355 return (convert_secobj(buf, len, obj_val, obj_lenp, class)); 65580ba2cbe9Sxc151355 } 65590ba2cbe9Sxc151355 65600ba2cbe9Sxc151355 static boolean_t 65610ba2cbe9Sxc151355 check_auth(const char *auth) 65620ba2cbe9Sxc151355 { 65630ba2cbe9Sxc151355 struct passwd *pw; 65640ba2cbe9Sxc151355 65650ba2cbe9Sxc151355 if ((pw = getpwuid(getuid())) == NULL) 65660ba2cbe9Sxc151355 return (B_FALSE); 65670ba2cbe9Sxc151355 65680ba2cbe9Sxc151355 return (chkauthattr(auth, pw->pw_name) != 0); 65690ba2cbe9Sxc151355 } 65700ba2cbe9Sxc151355 65710ba2cbe9Sxc151355 static void 65720ba2cbe9Sxc151355 audit_secobj(char *auth, char *class, char *obj, 65730ba2cbe9Sxc151355 boolean_t success, boolean_t create) 65740ba2cbe9Sxc151355 { 65750ba2cbe9Sxc151355 adt_session_data_t *ah; 65760ba2cbe9Sxc151355 adt_event_data_t *event; 65770ba2cbe9Sxc151355 au_event_t flag; 65780ba2cbe9Sxc151355 char *errstr; 65790ba2cbe9Sxc151355 65800ba2cbe9Sxc151355 if (create) { 65810ba2cbe9Sxc151355 flag = ADT_dladm_create_secobj; 65820ba2cbe9Sxc151355 errstr = "ADT_dladm_create_secobj"; 65830ba2cbe9Sxc151355 } else { 65840ba2cbe9Sxc151355 flag = ADT_dladm_delete_secobj; 65850ba2cbe9Sxc151355 errstr = "ADT_dladm_delete_secobj"; 65860ba2cbe9Sxc151355 } 65870ba2cbe9Sxc151355 658833343a97Smeem if (adt_start_session(&ah, NULL, ADT_USE_PROC_DATA) != 0) 658933343a97Smeem die("adt_start_session: %s", strerror(errno)); 65900ba2cbe9Sxc151355 659133343a97Smeem if ((event = adt_alloc_event(ah, flag)) == NULL) 659233343a97Smeem die("adt_alloc_event (%s): %s", errstr, strerror(errno)); 65930ba2cbe9Sxc151355 65940ba2cbe9Sxc151355 /* fill in audit info */ 65950ba2cbe9Sxc151355 if (create) { 65960ba2cbe9Sxc151355 event->adt_dladm_create_secobj.auth_used = auth; 65970ba2cbe9Sxc151355 event->adt_dladm_create_secobj.obj_class = class; 65980ba2cbe9Sxc151355 event->adt_dladm_create_secobj.obj_name = obj; 65990ba2cbe9Sxc151355 } else { 66000ba2cbe9Sxc151355 event->adt_dladm_delete_secobj.auth_used = auth; 66010ba2cbe9Sxc151355 event->adt_dladm_delete_secobj.obj_class = class; 66020ba2cbe9Sxc151355 event->adt_dladm_delete_secobj.obj_name = obj; 66030ba2cbe9Sxc151355 } 66040ba2cbe9Sxc151355 66050ba2cbe9Sxc151355 if (success) { 66060ba2cbe9Sxc151355 if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0) { 660733343a97Smeem die("adt_put_event (%s, success): %s", errstr, 660833343a97Smeem strerror(errno)); 66090ba2cbe9Sxc151355 } 66100ba2cbe9Sxc151355 } else { 66110ba2cbe9Sxc151355 if (adt_put_event(event, ADT_FAILURE, 66120ba2cbe9Sxc151355 ADT_FAIL_VALUE_AUTH) != 0) { 661333343a97Smeem die("adt_put_event: (%s, failure): %s", errstr, 661433343a97Smeem strerror(errno)); 66150ba2cbe9Sxc151355 } 66160ba2cbe9Sxc151355 } 66170ba2cbe9Sxc151355 66180ba2cbe9Sxc151355 adt_free_event(event); 66190ba2cbe9Sxc151355 (void) adt_end_session(ah); 66200ba2cbe9Sxc151355 } 66210ba2cbe9Sxc151355 66220ba2cbe9Sxc151355 #define MAX_SECOBJS 32 66230ba2cbe9Sxc151355 #define MAX_SECOBJ_NAMELEN 32 66240ba2cbe9Sxc151355 static void 66258d5c46e6Sam223141 do_create_secobj(int argc, char **argv, const char *use) 66260ba2cbe9Sxc151355 { 66270ba2cbe9Sxc151355 int option, rval; 66280ba2cbe9Sxc151355 FILE *filep = NULL; 66290ba2cbe9Sxc151355 char *obj_name = NULL; 66300ba2cbe9Sxc151355 char *class_name = NULL; 66310ba2cbe9Sxc151355 uint8_t obj_val[DLADM_SECOBJ_VAL_MAX]; 66320ba2cbe9Sxc151355 uint_t obj_len; 66330ba2cbe9Sxc151355 boolean_t success, temp = B_FALSE; 66340ba2cbe9Sxc151355 dladm_status_t status; 66350ba2cbe9Sxc151355 dladm_secobj_class_t class = -1; 66360ba2cbe9Sxc151355 uid_t euid; 66370ba2cbe9Sxc151355 66380ba2cbe9Sxc151355 opterr = 0; 66390ba2cbe9Sxc151355 (void) memset(obj_val, 0, DLADM_SECOBJ_VAL_MAX); 66400ba2cbe9Sxc151355 while ((option = getopt_long(argc, argv, ":f:c:R:t", 66410ba2cbe9Sxc151355 wifi_longopts, NULL)) != -1) { 66420ba2cbe9Sxc151355 switch (option) { 66430ba2cbe9Sxc151355 case 'f': 66440ba2cbe9Sxc151355 euid = geteuid(); 66450ba2cbe9Sxc151355 (void) seteuid(getuid()); 66460ba2cbe9Sxc151355 filep = fopen(optarg, "r"); 66470ba2cbe9Sxc151355 if (filep == NULL) { 664833343a97Smeem die("cannot open %s: %s", optarg, 664933343a97Smeem strerror(errno)); 66500ba2cbe9Sxc151355 } 66510ba2cbe9Sxc151355 (void) seteuid(euid); 66520ba2cbe9Sxc151355 break; 66530ba2cbe9Sxc151355 case 'c': 66540ba2cbe9Sxc151355 class_name = optarg; 66550ba2cbe9Sxc151355 status = dladm_str2secobjclass(optarg, &class); 66560ba2cbe9Sxc151355 if (status != DLADM_STATUS_OK) { 665733343a97Smeem die("invalid secure object class '%s', " 6658a399b765Szf162725 "valid values are: wep, wpa", optarg); 66590ba2cbe9Sxc151355 } 66600ba2cbe9Sxc151355 break; 66610ba2cbe9Sxc151355 case 't': 66620ba2cbe9Sxc151355 temp = B_TRUE; 66630ba2cbe9Sxc151355 break; 66640ba2cbe9Sxc151355 case 'R': 66650ba2cbe9Sxc151355 status = dladm_set_rootdir(optarg); 66660ba2cbe9Sxc151355 if (status != DLADM_STATUS_OK) { 666733343a97Smeem die_dlerr(status, "invalid directory " 666833343a97Smeem "specified"); 66690ba2cbe9Sxc151355 } 66700ba2cbe9Sxc151355 break; 66710ba2cbe9Sxc151355 default: 66728d5c46e6Sam223141 die_opterr(optopt, option, use); 66730ba2cbe9Sxc151355 break; 66740ba2cbe9Sxc151355 } 66750ba2cbe9Sxc151355 } 66760ba2cbe9Sxc151355 66770ba2cbe9Sxc151355 if (optind == (argc - 1)) 66780ba2cbe9Sxc151355 obj_name = argv[optind]; 66790ba2cbe9Sxc151355 else if (optind != argc) 66800ba2cbe9Sxc151355 usage(); 66810ba2cbe9Sxc151355 668233343a97Smeem if (class == -1) 668333343a97Smeem die("secure object class required"); 66840ba2cbe9Sxc151355 668533343a97Smeem if (obj_name == NULL) 668633343a97Smeem die("secure object name required"); 66870ba2cbe9Sxc151355 6688a9489f61SAnurag S. Maskey if (!dladm_valid_secobj_name(obj_name)) 6689a9489f61SAnurag S. Maskey die("invalid secure object name '%s'", obj_name); 6690a9489f61SAnurag S. Maskey 66910ba2cbe9Sxc151355 success = check_auth(LINK_SEC_AUTH); 66920ba2cbe9Sxc151355 audit_secobj(LINK_SEC_AUTH, class_name, obj_name, success, B_TRUE); 669333343a97Smeem if (!success) 669433343a97Smeem die("authorization '%s' is required", LINK_SEC_AUTH); 66950ba2cbe9Sxc151355 669633343a97Smeem rval = get_secobj_val(obj_name, obj_val, &obj_len, class, filep); 669733343a97Smeem if (rval != 0) { 66980ba2cbe9Sxc151355 switch (rval) { 66990ba2cbe9Sxc151355 case ENOENT: 670033343a97Smeem die("invalid secure object class"); 67010ba2cbe9Sxc151355 break; 67020ba2cbe9Sxc151355 case EINVAL: 670333343a97Smeem die("invalid secure object value"); 67040ba2cbe9Sxc151355 break; 67050ba2cbe9Sxc151355 case ENOTSUP: 670633343a97Smeem die("verification failed"); 67070ba2cbe9Sxc151355 break; 67080ba2cbe9Sxc151355 default: 670933343a97Smeem die("invalid secure object: %s", strerror(rval)); 67100ba2cbe9Sxc151355 break; 67110ba2cbe9Sxc151355 } 67120ba2cbe9Sxc151355 } 67130ba2cbe9Sxc151355 67144ac67f02SAnurag S. Maskey status = dladm_set_secobj(handle, obj_name, class, obj_val, obj_len, 6715d62bc4baSyz147064 DLADM_OPT_CREATE | DLADM_OPT_ACTIVE); 67160ba2cbe9Sxc151355 if (status != DLADM_STATUS_OK) { 671733343a97Smeem die_dlerr(status, "could not create secure object '%s'", 671833343a97Smeem obj_name); 67190ba2cbe9Sxc151355 } 67200ba2cbe9Sxc151355 if (temp) 67210ba2cbe9Sxc151355 return; 67220ba2cbe9Sxc151355 67234ac67f02SAnurag S. Maskey status = dladm_set_secobj(handle, obj_name, class, obj_val, obj_len, 67240ba2cbe9Sxc151355 DLADM_OPT_PERSIST); 67250ba2cbe9Sxc151355 if (status != DLADM_STATUS_OK) { 672633343a97Smeem warn_dlerr(status, "could not persistently create secure " 672733343a97Smeem "object '%s'", obj_name); 67280ba2cbe9Sxc151355 } 67290ba2cbe9Sxc151355 } 67300ba2cbe9Sxc151355 67310ba2cbe9Sxc151355 static void 67328d5c46e6Sam223141 do_delete_secobj(int argc, char **argv, const char *use) 67330ba2cbe9Sxc151355 { 67340ba2cbe9Sxc151355 int i, option; 67350ba2cbe9Sxc151355 boolean_t temp = B_FALSE; 67360ba2cbe9Sxc151355 boolean_t success; 67370ba2cbe9Sxc151355 dladm_status_t status, pstatus; 67388002d411SSowmini Varadhan int nfields = 1; 67398002d411SSowmini Varadhan char *field, *token, *lasts = NULL, c; 67400ba2cbe9Sxc151355 67410ba2cbe9Sxc151355 opterr = 0; 67420ba2cbe9Sxc151355 status = pstatus = DLADM_STATUS_OK; 674333343a97Smeem while ((option = getopt_long(argc, argv, ":R:t", 67440ba2cbe9Sxc151355 wifi_longopts, NULL)) != -1) { 67450ba2cbe9Sxc151355 switch (option) { 67460ba2cbe9Sxc151355 case 't': 67470ba2cbe9Sxc151355 temp = B_TRUE; 67480ba2cbe9Sxc151355 break; 67490ba2cbe9Sxc151355 case 'R': 67500ba2cbe9Sxc151355 status = dladm_set_rootdir(optarg); 67510ba2cbe9Sxc151355 if (status != DLADM_STATUS_OK) { 675233343a97Smeem die_dlerr(status, "invalid directory " 675333343a97Smeem "specified"); 67540ba2cbe9Sxc151355 } 67550ba2cbe9Sxc151355 break; 67560ba2cbe9Sxc151355 default: 67578d5c46e6Sam223141 die_opterr(optopt, option, use); 67580ba2cbe9Sxc151355 break; 67590ba2cbe9Sxc151355 } 67600ba2cbe9Sxc151355 } 67610ba2cbe9Sxc151355 67620ba2cbe9Sxc151355 if (optind == (argc - 1)) { 67638002d411SSowmini Varadhan token = argv[optind]; 67648002d411SSowmini Varadhan if (token == NULL) 67658002d411SSowmini Varadhan die("secure object name required"); 67668002d411SSowmini Varadhan while ((c = *token++) != NULL) { 67678002d411SSowmini Varadhan if (c == ',') 67688002d411SSowmini Varadhan nfields++; 67690ba2cbe9Sxc151355 } 67708002d411SSowmini Varadhan token = strdup(argv[optind]); 67718002d411SSowmini Varadhan if (token == NULL) 67728002d411SSowmini Varadhan die("no memory"); 67730ba2cbe9Sxc151355 } else if (optind != argc) 67740ba2cbe9Sxc151355 usage(); 67750ba2cbe9Sxc151355 67760ba2cbe9Sxc151355 success = check_auth(LINK_SEC_AUTH); 6777a399b765Szf162725 audit_secobj(LINK_SEC_AUTH, "unknown", argv[optind], success, B_FALSE); 677833343a97Smeem if (!success) 677933343a97Smeem die("authorization '%s' is required", LINK_SEC_AUTH); 67800ba2cbe9Sxc151355 67818002d411SSowmini Varadhan for (i = 0; i < nfields; i++) { 67828002d411SSowmini Varadhan 67838002d411SSowmini Varadhan field = strtok_r(token, ",", &lasts); 67848002d411SSowmini Varadhan token = NULL; 67858002d411SSowmini Varadhan status = dladm_unset_secobj(handle, field, DLADM_OPT_ACTIVE); 67860ba2cbe9Sxc151355 if (!temp) { 67878002d411SSowmini Varadhan pstatus = dladm_unset_secobj(handle, field, 67880ba2cbe9Sxc151355 DLADM_OPT_PERSIST); 67890ba2cbe9Sxc151355 } else { 67900ba2cbe9Sxc151355 pstatus = DLADM_STATUS_OK; 67910ba2cbe9Sxc151355 } 67920ba2cbe9Sxc151355 67930ba2cbe9Sxc151355 if (status != DLADM_STATUS_OK) { 679433343a97Smeem warn_dlerr(status, "could not delete secure object " 67958002d411SSowmini Varadhan "'%s'", field); 67960ba2cbe9Sxc151355 } 67970ba2cbe9Sxc151355 if (pstatus != DLADM_STATUS_OK) { 679833343a97Smeem warn_dlerr(pstatus, "could not persistently delete " 67998002d411SSowmini Varadhan "secure object '%s'", field); 68000ba2cbe9Sxc151355 } 68010ba2cbe9Sxc151355 } 68028002d411SSowmini Varadhan free(token); 68034ac67f02SAnurag S. Maskey 68044ac67f02SAnurag S. Maskey if (status != DLADM_STATUS_OK || pstatus != DLADM_STATUS_OK) { 68054ac67f02SAnurag S. Maskey dladm_close(handle); 68060ba2cbe9Sxc151355 exit(1); 68070ba2cbe9Sxc151355 } 68084ac67f02SAnurag S. Maskey } 68090ba2cbe9Sxc151355 68100ba2cbe9Sxc151355 typedef struct show_secobj_state { 68110ba2cbe9Sxc151355 boolean_t ss_persist; 68128002d411SSowmini Varadhan boolean_t ss_parsable; 68130ba2cbe9Sxc151355 boolean_t ss_header; 68148002d411SSowmini Varadhan ofmt_handle_t ss_ofmt; 68150ba2cbe9Sxc151355 } show_secobj_state_t; 68160ba2cbe9Sxc151355 68170ba2cbe9Sxc151355 68180ba2cbe9Sxc151355 static boolean_t 68194ac67f02SAnurag S. Maskey show_secobj(dladm_handle_t dh, void *arg, const char *obj_name) 68200ba2cbe9Sxc151355 { 68210ba2cbe9Sxc151355 uint_t obj_len = DLADM_SECOBJ_VAL_MAX; 68220ba2cbe9Sxc151355 uint8_t obj_val[DLADM_SECOBJ_VAL_MAX]; 68230ba2cbe9Sxc151355 char buf[DLADM_STRSIZE]; 68240ba2cbe9Sxc151355 uint_t flags = 0; 68250ba2cbe9Sxc151355 dladm_secobj_class_t class; 68260ba2cbe9Sxc151355 show_secobj_state_t *statep = arg; 68270ba2cbe9Sxc151355 dladm_status_t status; 6828e7801d59Ssowmini secobj_fields_buf_t sbuf; 68290ba2cbe9Sxc151355 68305f5c9f54SAnurag S. Maskey bzero(&sbuf, sizeof (secobj_fields_buf_t)); 68310ba2cbe9Sxc151355 if (statep->ss_persist) 68320ba2cbe9Sxc151355 flags |= DLADM_OPT_PERSIST; 68330ba2cbe9Sxc151355 68344ac67f02SAnurag S. Maskey status = dladm_get_secobj(dh, obj_name, &class, obj_val, &obj_len, 68354ac67f02SAnurag S. Maskey flags); 683633343a97Smeem if (status != DLADM_STATUS_OK) 683733343a97Smeem die_dlerr(status, "cannot get secure object '%s'", obj_name); 68380ba2cbe9Sxc151355 6839e7801d59Ssowmini (void) snprintf(sbuf.ss_obj_name, sizeof (sbuf.ss_obj_name), 6840e7801d59Ssowmini obj_name); 6841e7801d59Ssowmini (void) dladm_secobjclass2str(class, buf); 6842e7801d59Ssowmini (void) snprintf(sbuf.ss_class, sizeof (sbuf.ss_class), "%s", buf); 6843e7801d59Ssowmini if (getuid() == 0) { 68440ba2cbe9Sxc151355 char val[DLADM_SECOBJ_VAL_MAX * 2]; 68450ba2cbe9Sxc151355 uint_t len = sizeof (val); 68460ba2cbe9Sxc151355 6847e7801d59Ssowmini if (octet_to_hexascii(obj_val, obj_len, val, &len) == 0) 6848e7801d59Ssowmini (void) snprintf(sbuf.ss_val, 6849e7801d59Ssowmini sizeof (sbuf.ss_val), "%s", val); 68500ba2cbe9Sxc151355 } 68518002d411SSowmini Varadhan ofmt_print(statep->ss_ofmt, &sbuf); 68520ba2cbe9Sxc151355 return (B_TRUE); 68530ba2cbe9Sxc151355 } 68540ba2cbe9Sxc151355 68550ba2cbe9Sxc151355 static void 68568d5c46e6Sam223141 do_show_secobj(int argc, char **argv, const char *use) 68570ba2cbe9Sxc151355 { 68580ba2cbe9Sxc151355 int option; 68590ba2cbe9Sxc151355 show_secobj_state_t state; 68600ba2cbe9Sxc151355 dladm_status_t status; 68610d365605Sschuster boolean_t o_arg = B_FALSE; 68620ba2cbe9Sxc151355 uint_t i; 68630ba2cbe9Sxc151355 uint_t flags; 6864e7801d59Ssowmini char *fields_str = NULL; 6865e7801d59Ssowmini char *def_fields = "object,class"; 6866e7801d59Ssowmini char *all_fields = "object,class,value"; 68678002d411SSowmini Varadhan char *field, *token, *lasts = NULL, c; 68688002d411SSowmini Varadhan ofmt_handle_t ofmt; 68698002d411SSowmini Varadhan ofmt_status_t oferr; 68708002d411SSowmini Varadhan uint_t ofmtflags = 0; 68710ba2cbe9Sxc151355 68720ba2cbe9Sxc151355 opterr = 0; 6873e7801d59Ssowmini bzero(&state, sizeof (state)); 68748002d411SSowmini Varadhan state.ss_parsable = B_FALSE; 6875e7801d59Ssowmini fields_str = def_fields; 68760ba2cbe9Sxc151355 state.ss_persist = B_FALSE; 68778002d411SSowmini Varadhan state.ss_parsable = B_FALSE; 68780ba2cbe9Sxc151355 state.ss_header = B_TRUE; 6879e7801d59Ssowmini while ((option = getopt_long(argc, argv, ":pPo:", 68800ba2cbe9Sxc151355 wifi_longopts, NULL)) != -1) { 68810ba2cbe9Sxc151355 switch (option) { 68820ba2cbe9Sxc151355 case 'p': 68838002d411SSowmini Varadhan state.ss_parsable = B_TRUE; 68840ba2cbe9Sxc151355 break; 68850ba2cbe9Sxc151355 case 'P': 68860ba2cbe9Sxc151355 state.ss_persist = B_TRUE; 68870ba2cbe9Sxc151355 break; 6888e7801d59Ssowmini case 'o': 68890d365605Sschuster o_arg = B_TRUE; 6890e7801d59Ssowmini if (strcasecmp(optarg, "all") == 0) 6891e7801d59Ssowmini fields_str = all_fields; 6892e7801d59Ssowmini else 6893e7801d59Ssowmini fields_str = optarg; 68940ba2cbe9Sxc151355 break; 68950ba2cbe9Sxc151355 default: 68968d5c46e6Sam223141 die_opterr(optopt, option, use); 68970ba2cbe9Sxc151355 break; 68980ba2cbe9Sxc151355 } 68990ba2cbe9Sxc151355 } 69000ba2cbe9Sxc151355 69018002d411SSowmini Varadhan if (state.ss_parsable && !o_arg) 69020d365605Sschuster die("option -c requires -o"); 69030d365605Sschuster 69048002d411SSowmini Varadhan if (state.ss_parsable && fields_str == all_fields) 69050d365605Sschuster die("\"-o all\" is invalid with -p"); 69060d365605Sschuster 69078002d411SSowmini Varadhan if (state.ss_parsable) 69088002d411SSowmini Varadhan ofmtflags |= OFMT_PARSABLE; 69098002d411SSowmini Varadhan oferr = ofmt_open(fields_str, secobj_fields, ofmtflags, 0, &ofmt); 69108002d411SSowmini Varadhan dladm_ofmt_check(oferr, state.ss_parsable, ofmt); 69118002d411SSowmini Varadhan state.ss_ofmt = ofmt; 6912e7801d59Ssowmini 6913e7801d59Ssowmini flags = state.ss_persist ? DLADM_OPT_PERSIST : 0; 69144ac67f02SAnurag S. Maskey 69150ba2cbe9Sxc151355 if (optind == (argc - 1)) { 69168002d411SSowmini Varadhan uint_t obj_fields = 1; 69178002d411SSowmini Varadhan 69188002d411SSowmini Varadhan token = argv[optind]; 69198002d411SSowmini Varadhan if (token == NULL) 69208002d411SSowmini Varadhan die("secure object name required"); 69218002d411SSowmini Varadhan while ((c = *token++) != NULL) { 69228002d411SSowmini Varadhan if (c == ',') 69238002d411SSowmini Varadhan obj_fields++; 69240ba2cbe9Sxc151355 } 69258002d411SSowmini Varadhan token = strdup(argv[optind]); 69268002d411SSowmini Varadhan if (token == NULL) 69278002d411SSowmini Varadhan die("no memory"); 69288002d411SSowmini Varadhan for (i = 0; i < obj_fields; i++) { 69298002d411SSowmini Varadhan field = strtok_r(token, ",", &lasts); 69308002d411SSowmini Varadhan token = NULL; 69318002d411SSowmini Varadhan if (!show_secobj(handle, &state, field)) 69320ba2cbe9Sxc151355 break; 69330ba2cbe9Sxc151355 } 69348002d411SSowmini Varadhan free(token); 69358002d411SSowmini Varadhan ofmt_close(ofmt); 69360ba2cbe9Sxc151355 return; 69370ba2cbe9Sxc151355 } else if (optind != argc) 69380ba2cbe9Sxc151355 usage(); 69390ba2cbe9Sxc151355 69404ac67f02SAnurag S. Maskey status = dladm_walk_secobj(handle, &state, show_secobj, flags); 69414ac67f02SAnurag S. Maskey 694233343a97Smeem if (status != DLADM_STATUS_OK) 694333343a97Smeem die_dlerr(status, "show-secobj"); 69448002d411SSowmini Varadhan ofmt_close(ofmt); 69450ba2cbe9Sxc151355 } 69460ba2cbe9Sxc151355 69470ba2cbe9Sxc151355 /*ARGSUSED*/ 6948d62bc4baSyz147064 static int 69494ac67f02SAnurag S. Maskey i_dladm_init_linkprop(dladm_handle_t dh, datalink_id_t linkid, void *arg) 6950d62bc4baSyz147064 { 69514ac67f02SAnurag S. Maskey (void) dladm_init_linkprop(dh, linkid, B_TRUE); 6952d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 6953d62bc4baSyz147064 } 6954d62bc4baSyz147064 69558d5c46e6Sam223141 /*ARGSUSED*/ 6956da14cebeSEric Cheng void 69578d5c46e6Sam223141 do_init_linkprop(int argc, char **argv, const char *use) 69580ba2cbe9Sxc151355 { 695930890389Sartem int option; 696030890389Sartem dladm_status_t status; 696130890389Sartem datalink_id_t linkid = DATALINK_ALL_LINKID; 696230890389Sartem datalink_media_t media = DATALINK_ANY_MEDIATYPE; 696330890389Sartem uint_t any_media = B_TRUE; 696430890389Sartem 696530890389Sartem opterr = 0; 696630890389Sartem while ((option = getopt(argc, argv, ":w")) != -1) { 696730890389Sartem switch (option) { 696830890389Sartem case 'w': 696930890389Sartem media = DL_WIFI; 697030890389Sartem any_media = B_FALSE; 697130890389Sartem break; 697230890389Sartem default: 69738d5c46e6Sam223141 /* 69748d5c46e6Sam223141 * Because init-linkprop is not a public command, 69758d5c46e6Sam223141 * print the usage instead. 69768d5c46e6Sam223141 */ 69778d5c46e6Sam223141 usage(); 697830890389Sartem break; 697930890389Sartem } 698030890389Sartem } 698130890389Sartem 698230890389Sartem if (optind == (argc - 1)) { 69834ac67f02SAnurag S. Maskey if ((status = dladm_name2info(handle, argv[optind], &linkid, 69844ac67f02SAnurag S. Maskey NULL, NULL, NULL)) != DLADM_STATUS_OK) 698530890389Sartem die_dlerr(status, "link %s is not valid", argv[optind]); 698630890389Sartem } else if (optind != argc) { 698730890389Sartem usage(); 698830890389Sartem } 698930890389Sartem 699030890389Sartem if (linkid == DATALINK_ALL_LINKID) { 6991d62bc4baSyz147064 /* 699230890389Sartem * linkprops of links of other classes have been initialized as 6993d62bc4baSyz147064 * part of the dladm up-xxx operation. 6994d62bc4baSyz147064 */ 69954ac67f02SAnurag S. Maskey (void) dladm_walk_datalink_id(i_dladm_init_linkprop, handle, 69964ac67f02SAnurag S. Maskey NULL, DATALINK_CLASS_PHYS, media, DLADM_OPT_PERSIST); 699730890389Sartem } else { 69984ac67f02SAnurag S. Maskey (void) dladm_init_linkprop(handle, linkid, any_media); 699930890389Sartem } 70000ba2cbe9Sxc151355 } 70010ba2cbe9Sxc151355 70020ba2cbe9Sxc151355 static void 70038d5c46e6Sam223141 do_show_ether(int argc, char **argv, const char *use) 7004e7801d59Ssowmini { 7005e7801d59Ssowmini int option; 7006e7801d59Ssowmini datalink_id_t linkid; 7007e7801d59Ssowmini print_ether_state_t state; 70088002d411SSowmini Varadhan char *fields_str = NULL; 70098002d411SSowmini Varadhan ofmt_handle_t ofmt; 70108002d411SSowmini Varadhan ofmt_status_t oferr; 70118002d411SSowmini Varadhan uint_t ofmtflags = 0; 7012e7801d59Ssowmini 7013e7801d59Ssowmini bzero(&state, sizeof (state)); 7014e7801d59Ssowmini state.es_link = NULL; 70158002d411SSowmini Varadhan state.es_parsable = B_FALSE; 7016e7801d59Ssowmini 7017e7801d59Ssowmini while ((option = getopt_long(argc, argv, "o:px", 7018e7801d59Ssowmini showeth_lopts, NULL)) != -1) { 7019e7801d59Ssowmini switch (option) { 7020e7801d59Ssowmini case 'x': 7021e7801d59Ssowmini state.es_extended = B_TRUE; 7022e7801d59Ssowmini break; 7023e7801d59Ssowmini case 'p': 70248002d411SSowmini Varadhan state.es_parsable = B_TRUE; 7025e7801d59Ssowmini break; 7026e7801d59Ssowmini case 'o': 7027e7801d59Ssowmini fields_str = optarg; 7028e7801d59Ssowmini break; 7029e7801d59Ssowmini default: 70308d5c46e6Sam223141 die_opterr(optopt, option, use); 7031e7801d59Ssowmini break; 7032e7801d59Ssowmini } 7033e7801d59Ssowmini } 7034e7801d59Ssowmini 7035e7801d59Ssowmini if (optind == (argc - 1)) 7036e7801d59Ssowmini state.es_link = argv[optind]; 7037e7801d59Ssowmini 70388002d411SSowmini Varadhan if (state.es_parsable) 70398002d411SSowmini Varadhan ofmtflags |= OFMT_PARSABLE; 70408002d411SSowmini Varadhan oferr = ofmt_open(fields_str, ether_fields, ofmtflags, 70418002d411SSowmini Varadhan DLADM_DEFAULT_COL, &ofmt); 70428002d411SSowmini Varadhan dladm_ofmt_check(oferr, state.es_parsable, ofmt); 70438002d411SSowmini Varadhan state.es_ofmt = ofmt; 70444ac67f02SAnurag S. Maskey 7045e7801d59Ssowmini if (state.es_link == NULL) { 70464ac67f02SAnurag S. Maskey (void) dladm_walk_datalink_id(show_etherprop, handle, &state, 70473361618bSRishi Srivatsavai DATALINK_CLASS_PHYS, DL_ETHER, DLADM_OPT_ACTIVE); 7048e7801d59Ssowmini } else { 70494ac67f02SAnurag S. Maskey if (!link_is_ether(state.es_link, &linkid)) 7050e7801d59Ssowmini die("invalid link specified"); 70514ac67f02SAnurag S. Maskey (void) show_etherprop(handle, linkid, &state); 7052e7801d59Ssowmini } 70538002d411SSowmini Varadhan ofmt_close(ofmt); 7054e7801d59Ssowmini } 7055e7801d59Ssowmini 7056e7801d59Ssowmini static int 70574ac67f02SAnurag S. Maskey show_etherprop(dladm_handle_t dh, datalink_id_t linkid, void *arg) 7058e7801d59Ssowmini { 7059e7801d59Ssowmini print_ether_state_t *statep = arg; 7060e7801d59Ssowmini ether_fields_buf_t ebuf; 70614784fcbdSSowmini Varadhan dladm_ether_info_t eattr; 70624784fcbdSSowmini Varadhan dladm_status_t status; 7063e7801d59Ssowmini 70645f5c9f54SAnurag S. Maskey bzero(&ebuf, sizeof (ether_fields_buf_t)); 70654ac67f02SAnurag S. Maskey if (dladm_datalink_id2info(dh, linkid, NULL, NULL, NULL, 7066e7801d59Ssowmini ebuf.eth_link, sizeof (ebuf.eth_link)) != DLADM_STATUS_OK) { 7067e7801d59Ssowmini return (DLADM_WALK_CONTINUE); 7068e7801d59Ssowmini } 7069e7801d59Ssowmini 70704ac67f02SAnurag S. Maskey status = dladm_ether_info(dh, linkid, &eattr); 70714784fcbdSSowmini Varadhan if (status != DLADM_STATUS_OK) 70724784fcbdSSowmini Varadhan goto cleanup; 7073e7801d59Ssowmini 70744784fcbdSSowmini Varadhan (void) strlcpy(ebuf.eth_ptype, "current", sizeof (ebuf.eth_ptype)); 7075e7801d59Ssowmini 70764784fcbdSSowmini Varadhan (void) dladm_ether_autoneg2str(ebuf.eth_autoneg, 70774784fcbdSSowmini Varadhan sizeof (ebuf.eth_autoneg), &eattr, CURRENT); 70784784fcbdSSowmini Varadhan (void) dladm_ether_pause2str(ebuf.eth_pause, 70794784fcbdSSowmini Varadhan sizeof (ebuf.eth_pause), &eattr, CURRENT); 70804784fcbdSSowmini Varadhan (void) dladm_ether_spdx2str(ebuf.eth_spdx, 70814784fcbdSSowmini Varadhan sizeof (ebuf.eth_spdx), &eattr, CURRENT); 70824784fcbdSSowmini Varadhan (void) strlcpy(ebuf.eth_state, 70834784fcbdSSowmini Varadhan dladm_linkstate2str(eattr.lei_state, ebuf.eth_state), 70844784fcbdSSowmini Varadhan sizeof (ebuf.eth_state)); 70854784fcbdSSowmini Varadhan (void) strlcpy(ebuf.eth_rem_fault, 70864784fcbdSSowmini Varadhan (eattr.lei_attr[CURRENT].le_fault ? "fault" : "none"), 70874784fcbdSSowmini Varadhan sizeof (ebuf.eth_rem_fault)); 7088e7801d59Ssowmini 70898002d411SSowmini Varadhan ofmt_print(statep->es_ofmt, &ebuf); 7090e7801d59Ssowmini 7091e7801d59Ssowmini if (statep->es_extended) 70924784fcbdSSowmini Varadhan show_ether_xprop(arg, &eattr); 7093e7801d59Ssowmini 70944784fcbdSSowmini Varadhan cleanup: 70954784fcbdSSowmini Varadhan dladm_ether_info_done(&eattr); 7096e7801d59Ssowmini return (DLADM_WALK_CONTINUE); 7097e7801d59Ssowmini } 7098e7801d59Ssowmini 7099e7801d59Ssowmini /* ARGSUSED */ 7100e7801d59Ssowmini static void 71018d5c46e6Sam223141 do_init_secobj(int argc, char **argv, const char *use) 71020ba2cbe9Sxc151355 { 71030ba2cbe9Sxc151355 dladm_status_t status; 71040ba2cbe9Sxc151355 71054ac67f02SAnurag S. Maskey status = dladm_init_secobj(handle); 710633343a97Smeem if (status != DLADM_STATUS_OK) 710733343a97Smeem die_dlerr(status, "secure object initialization failed"); 710833343a97Smeem } 710933343a97Smeem 7110*4eaa4710SRishi Srivatsavai enum bridge_func { 7111*4eaa4710SRishi Srivatsavai brCreate, brAdd, brModify 7112*4eaa4710SRishi Srivatsavai }; 7113*4eaa4710SRishi Srivatsavai 7114*4eaa4710SRishi Srivatsavai static void 7115*4eaa4710SRishi Srivatsavai create_modify_add_bridge(int argc, char **argv, const char *use, 7116*4eaa4710SRishi Srivatsavai enum bridge_func func) 7117*4eaa4710SRishi Srivatsavai { 7118*4eaa4710SRishi Srivatsavai int option; 7119*4eaa4710SRishi Srivatsavai uint_t n, i, nlink; 7120*4eaa4710SRishi Srivatsavai uint32_t flags = DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST; 7121*4eaa4710SRishi Srivatsavai char *altroot = NULL; 7122*4eaa4710SRishi Srivatsavai char *links[MAXPORT]; 7123*4eaa4710SRishi Srivatsavai datalink_id_t linkids[MAXPORT]; 7124*4eaa4710SRishi Srivatsavai dladm_status_t status; 7125*4eaa4710SRishi Srivatsavai const char *bridge; 7126*4eaa4710SRishi Srivatsavai UID_STP_CFG_T cfg, cfg_old; 7127*4eaa4710SRishi Srivatsavai dladm_bridge_prot_t brprot = DLADM_BRIDGE_PROT_UNKNOWN; 7128*4eaa4710SRishi Srivatsavai dladm_bridge_prot_t brprot_old; 7129*4eaa4710SRishi Srivatsavai 7130*4eaa4710SRishi Srivatsavai /* Set up the default configuration values */ 7131*4eaa4710SRishi Srivatsavai cfg.field_mask = 0; 7132*4eaa4710SRishi Srivatsavai cfg.bridge_priority = DEF_BR_PRIO; 7133*4eaa4710SRishi Srivatsavai cfg.max_age = DEF_BR_MAXAGE; 7134*4eaa4710SRishi Srivatsavai cfg.hello_time = DEF_BR_HELLOT; 7135*4eaa4710SRishi Srivatsavai cfg.forward_delay = DEF_BR_FWDELAY; 7136*4eaa4710SRishi Srivatsavai cfg.force_version = DEF_FORCE_VERS; 7137*4eaa4710SRishi Srivatsavai 7138*4eaa4710SRishi Srivatsavai nlink = opterr = 0; 7139*4eaa4710SRishi Srivatsavai while ((option = getopt_long(argc, argv, ":P:R:d:f:h:l:m:p:", 7140*4eaa4710SRishi Srivatsavai bridge_lopts, NULL)) != -1) { 7141*4eaa4710SRishi Srivatsavai switch (option) { 7142*4eaa4710SRishi Srivatsavai case 'P': 7143*4eaa4710SRishi Srivatsavai if (func == brAdd) 7144*4eaa4710SRishi Srivatsavai die_opterr(optopt, option, use); 7145*4eaa4710SRishi Srivatsavai status = dladm_bridge_str2prot(optarg, &brprot); 7146*4eaa4710SRishi Srivatsavai if (status != DLADM_STATUS_OK) 7147*4eaa4710SRishi Srivatsavai die_dlerr(status, "protection %s", optarg); 7148*4eaa4710SRishi Srivatsavai break; 7149*4eaa4710SRishi Srivatsavai case 'R': 7150*4eaa4710SRishi Srivatsavai altroot = optarg; 7151*4eaa4710SRishi Srivatsavai break; 7152*4eaa4710SRishi Srivatsavai case 'd': 7153*4eaa4710SRishi Srivatsavai if (func == brAdd) 7154*4eaa4710SRishi Srivatsavai die_opterr(optopt, option, use); 7155*4eaa4710SRishi Srivatsavai if (cfg.field_mask & BR_CFG_DELAY) 7156*4eaa4710SRishi Srivatsavai die("forwarding delay set more than once"); 7157*4eaa4710SRishi Srivatsavai if (!str2int(optarg, &cfg.forward_delay) || 7158*4eaa4710SRishi Srivatsavai cfg.forward_delay < MIN_BR_FWDELAY || 7159*4eaa4710SRishi Srivatsavai cfg.forward_delay > MAX_BR_FWDELAY) 7160*4eaa4710SRishi Srivatsavai die("incorrect forwarding delay"); 7161*4eaa4710SRishi Srivatsavai cfg.field_mask |= BR_CFG_DELAY; 7162*4eaa4710SRishi Srivatsavai break; 7163*4eaa4710SRishi Srivatsavai case 'f': 7164*4eaa4710SRishi Srivatsavai if (func == brAdd) 7165*4eaa4710SRishi Srivatsavai die_opterr(optopt, option, use); 7166*4eaa4710SRishi Srivatsavai if (cfg.field_mask & BR_CFG_FORCE_VER) 7167*4eaa4710SRishi Srivatsavai die("force protocol set more than once"); 7168*4eaa4710SRishi Srivatsavai if (!str2int(optarg, &cfg.force_version) || 7169*4eaa4710SRishi Srivatsavai cfg.force_version < 0) 7170*4eaa4710SRishi Srivatsavai die("incorrect force protocol"); 7171*4eaa4710SRishi Srivatsavai cfg.field_mask |= BR_CFG_FORCE_VER; 7172*4eaa4710SRishi Srivatsavai break; 7173*4eaa4710SRishi Srivatsavai case 'h': 7174*4eaa4710SRishi Srivatsavai if (func == brAdd) 7175*4eaa4710SRishi Srivatsavai die_opterr(optopt, option, use); 7176*4eaa4710SRishi Srivatsavai if (cfg.field_mask & BR_CFG_HELLO) 7177*4eaa4710SRishi Srivatsavai die("hello time set more than once"); 7178*4eaa4710SRishi Srivatsavai if (!str2int(optarg, &cfg.hello_time) || 7179*4eaa4710SRishi Srivatsavai cfg.hello_time < MIN_BR_HELLOT || 7180*4eaa4710SRishi Srivatsavai cfg.hello_time > MAX_BR_HELLOT) 7181*4eaa4710SRishi Srivatsavai die("incorrect hello time"); 7182*4eaa4710SRishi Srivatsavai cfg.field_mask |= BR_CFG_HELLO; 7183*4eaa4710SRishi Srivatsavai break; 7184*4eaa4710SRishi Srivatsavai case 'l': 7185*4eaa4710SRishi Srivatsavai if (func == brModify) 7186*4eaa4710SRishi Srivatsavai die_opterr(optopt, option, use); 7187*4eaa4710SRishi Srivatsavai if (nlink >= MAXPORT) 7188*4eaa4710SRishi Srivatsavai die("too many links specified"); 7189*4eaa4710SRishi Srivatsavai links[nlink++] = optarg; 7190*4eaa4710SRishi Srivatsavai break; 7191*4eaa4710SRishi Srivatsavai case 'm': 7192*4eaa4710SRishi Srivatsavai if (func == brAdd) 7193*4eaa4710SRishi Srivatsavai die_opterr(optopt, option, use); 7194*4eaa4710SRishi Srivatsavai if (cfg.field_mask & BR_CFG_AGE) 7195*4eaa4710SRishi Srivatsavai die("max age set more than once"); 7196*4eaa4710SRishi Srivatsavai if (!str2int(optarg, &cfg.max_age) || 7197*4eaa4710SRishi Srivatsavai cfg.max_age < MIN_BR_MAXAGE || 7198*4eaa4710SRishi Srivatsavai cfg.max_age > MAX_BR_MAXAGE) 7199*4eaa4710SRishi Srivatsavai die("incorrect max age"); 7200*4eaa4710SRishi Srivatsavai cfg.field_mask |= BR_CFG_AGE; 7201*4eaa4710SRishi Srivatsavai break; 7202*4eaa4710SRishi Srivatsavai case 'p': 7203*4eaa4710SRishi Srivatsavai if (func == brAdd) 7204*4eaa4710SRishi Srivatsavai die_opterr(optopt, option, use); 7205*4eaa4710SRishi Srivatsavai if (cfg.field_mask & BR_CFG_PRIO) 7206*4eaa4710SRishi Srivatsavai die("priority set more than once"); 7207*4eaa4710SRishi Srivatsavai if (!str2int(optarg, &cfg.bridge_priority) || 7208*4eaa4710SRishi Srivatsavai cfg.bridge_priority < MIN_BR_PRIO || 7209*4eaa4710SRishi Srivatsavai cfg.bridge_priority > MAX_BR_PRIO) 7210*4eaa4710SRishi Srivatsavai die("incorrect priority"); 7211*4eaa4710SRishi Srivatsavai cfg.bridge_priority &= 0xF000; 7212*4eaa4710SRishi Srivatsavai cfg.field_mask |= BR_CFG_PRIO; 7213*4eaa4710SRishi Srivatsavai break; 7214*4eaa4710SRishi Srivatsavai default: 7215*4eaa4710SRishi Srivatsavai die_opterr(optopt, option, use); 7216*4eaa4710SRishi Srivatsavai break; 7217*4eaa4710SRishi Srivatsavai } 7218*4eaa4710SRishi Srivatsavai } 7219*4eaa4710SRishi Srivatsavai 7220*4eaa4710SRishi Srivatsavai /* get the bridge name (required last argument) */ 7221*4eaa4710SRishi Srivatsavai if (optind != (argc-1)) 7222*4eaa4710SRishi Srivatsavai usage(); 7223*4eaa4710SRishi Srivatsavai 7224*4eaa4710SRishi Srivatsavai bridge = argv[optind]; 7225*4eaa4710SRishi Srivatsavai if (!dladm_valid_bridgename(bridge)) 7226*4eaa4710SRishi Srivatsavai die("invalid bridge name '%s'", bridge); 7227*4eaa4710SRishi Srivatsavai 7228*4eaa4710SRishi Srivatsavai /* 7229*4eaa4710SRishi Srivatsavai * Get the current properties, if any, and merge in with changes. This 7230*4eaa4710SRishi Srivatsavai * is necessary (even with the field_mask feature) so that the 7231*4eaa4710SRishi Srivatsavai * value-checking macros will produce the right results with proposed 7232*4eaa4710SRishi Srivatsavai * changes to existing configuration. We only need it for those 7233*4eaa4710SRishi Srivatsavai * parameters, though. 7234*4eaa4710SRishi Srivatsavai */ 7235*4eaa4710SRishi Srivatsavai (void) dladm_bridge_get_properties(bridge, &cfg_old, &brprot_old); 7236*4eaa4710SRishi Srivatsavai if (brprot == DLADM_BRIDGE_PROT_UNKNOWN) 7237*4eaa4710SRishi Srivatsavai brprot = brprot_old; 7238*4eaa4710SRishi Srivatsavai if (!(cfg.field_mask & BR_CFG_AGE)) 7239*4eaa4710SRishi Srivatsavai cfg.max_age = cfg_old.max_age; 7240*4eaa4710SRishi Srivatsavai if (!(cfg.field_mask & BR_CFG_HELLO)) 7241*4eaa4710SRishi Srivatsavai cfg.hello_time = cfg_old.hello_time; 7242*4eaa4710SRishi Srivatsavai if (!(cfg.field_mask & BR_CFG_DELAY)) 7243*4eaa4710SRishi Srivatsavai cfg.forward_delay = cfg_old.forward_delay; 7244*4eaa4710SRishi Srivatsavai 7245*4eaa4710SRishi Srivatsavai if (!CHECK_BRIDGE_CONFIG(cfg)) { 7246*4eaa4710SRishi Srivatsavai warn("illegal forward delay / max age / hello time " 7247*4eaa4710SRishi Srivatsavai "combination"); 7248*4eaa4710SRishi Srivatsavai if (NO_MAXAGE(cfg)) { 7249*4eaa4710SRishi Srivatsavai die("no max age possible: need forward delay >= %d or " 7250*4eaa4710SRishi Srivatsavai "hello time <= %d", MIN_FWDELAY_NOM(cfg), 7251*4eaa4710SRishi Srivatsavai MAX_HELLOTIME_NOM(cfg)); 7252*4eaa4710SRishi Srivatsavai } else if (SMALL_MAXAGE(cfg)) { 7253*4eaa4710SRishi Srivatsavai if (CAPPED_MAXAGE(cfg)) 7254*4eaa4710SRishi Srivatsavai die("max age too small: need age >= %d and " 7255*4eaa4710SRishi Srivatsavai "<= %d or hello time <= %d", 7256*4eaa4710SRishi Srivatsavai MIN_MAXAGE(cfg), MAX_MAXAGE(cfg), 7257*4eaa4710SRishi Srivatsavai MAX_HELLOTIME(cfg)); 7258*4eaa4710SRishi Srivatsavai else 7259*4eaa4710SRishi Srivatsavai die("max age too small: need age >= %d or " 7260*4eaa4710SRishi Srivatsavai "hello time <= %d", 7261*4eaa4710SRishi Srivatsavai MIN_MAXAGE(cfg), MAX_HELLOTIME(cfg)); 7262*4eaa4710SRishi Srivatsavai } else if (FLOORED_MAXAGE(cfg)) { 7263*4eaa4710SRishi Srivatsavai die("max age too large: need age >= %d and <= %d or " 7264*4eaa4710SRishi Srivatsavai "forward delay >= %d", 7265*4eaa4710SRishi Srivatsavai MIN_MAXAGE(cfg), MAX_MAXAGE(cfg), 7266*4eaa4710SRishi Srivatsavai MIN_FWDELAY(cfg)); 7267*4eaa4710SRishi Srivatsavai } else { 7268*4eaa4710SRishi Srivatsavai die("max age too large: need age <= %d or forward " 7269*4eaa4710SRishi Srivatsavai "delay >= %d", 7270*4eaa4710SRishi Srivatsavai MAX_MAXAGE(cfg), MIN_FWDELAY(cfg)); 7271*4eaa4710SRishi Srivatsavai } 7272*4eaa4710SRishi Srivatsavai } 7273*4eaa4710SRishi Srivatsavai 7274*4eaa4710SRishi Srivatsavai if (altroot != NULL) 7275*4eaa4710SRishi Srivatsavai altroot_cmd(altroot, argc, argv); 7276*4eaa4710SRishi Srivatsavai 7277*4eaa4710SRishi Srivatsavai for (n = 0; n < nlink; n++) { 7278*4eaa4710SRishi Srivatsavai datalink_class_t class; 7279*4eaa4710SRishi Srivatsavai uint32_t media; 7280*4eaa4710SRishi Srivatsavai char pointless[DLADM_STRSIZE]; 7281*4eaa4710SRishi Srivatsavai 7282*4eaa4710SRishi Srivatsavai if (dladm_name2info(handle, links[n], &linkids[n], NULL, &class, 7283*4eaa4710SRishi Srivatsavai &media) != DLADM_STATUS_OK) 7284*4eaa4710SRishi Srivatsavai die("invalid link name '%s'", links[n]); 7285*4eaa4710SRishi Srivatsavai if (class & ~(DATALINK_CLASS_PHYS | DATALINK_CLASS_AGGR | 7286*4eaa4710SRishi Srivatsavai DATALINK_CLASS_ETHERSTUB | DATALINK_CLASS_SIMNET)) 7287*4eaa4710SRishi Srivatsavai die("%s %s cannot be bridged", 7288*4eaa4710SRishi Srivatsavai dladm_class2str(class, pointless), links[n]); 7289*4eaa4710SRishi Srivatsavai if (media != DL_ETHER && media != DL_100VG && 7290*4eaa4710SRishi Srivatsavai media != DL_ETH_CSMA && media != DL_100BT) 7291*4eaa4710SRishi Srivatsavai die("%s interface %s cannot be bridged", 7292*4eaa4710SRishi Srivatsavai dladm_media2str(media, pointless), links[n]); 7293*4eaa4710SRishi Srivatsavai } 7294*4eaa4710SRishi Srivatsavai 7295*4eaa4710SRishi Srivatsavai if (func == brCreate) 7296*4eaa4710SRishi Srivatsavai flags |= DLADM_OPT_CREATE; 7297*4eaa4710SRishi Srivatsavai 7298*4eaa4710SRishi Srivatsavai if (func != brAdd) { 7299*4eaa4710SRishi Srivatsavai status = dladm_bridge_configure(handle, bridge, &cfg, brprot, 7300*4eaa4710SRishi Srivatsavai flags); 7301*4eaa4710SRishi Srivatsavai if (status != DLADM_STATUS_OK) 7302*4eaa4710SRishi Srivatsavai die_dlerr(status, "create operation failed"); 7303*4eaa4710SRishi Srivatsavai } 7304*4eaa4710SRishi Srivatsavai 7305*4eaa4710SRishi Srivatsavai status = DLADM_STATUS_OK; 7306*4eaa4710SRishi Srivatsavai for (n = 0; n < nlink; n++) { 7307*4eaa4710SRishi Srivatsavai status = dladm_bridge_setlink(handle, linkids[n], bridge); 7308*4eaa4710SRishi Srivatsavai if (status != DLADM_STATUS_OK) 7309*4eaa4710SRishi Srivatsavai break; 7310*4eaa4710SRishi Srivatsavai } 7311*4eaa4710SRishi Srivatsavai 7312*4eaa4710SRishi Srivatsavai if (n >= nlink) { 7313*4eaa4710SRishi Srivatsavai /* 7314*4eaa4710SRishi Srivatsavai * We were successful. If we're creating a new bridge, then 7315*4eaa4710SRishi Srivatsavai * there's just one more step: enabling. If we're modifying or 7316*4eaa4710SRishi Srivatsavai * just adding links, then we're done. 7317*4eaa4710SRishi Srivatsavai */ 7318*4eaa4710SRishi Srivatsavai if (func != brCreate || 7319*4eaa4710SRishi Srivatsavai (status = dladm_bridge_enable(bridge)) == DLADM_STATUS_OK) 7320*4eaa4710SRishi Srivatsavai return; 7321*4eaa4710SRishi Srivatsavai } 7322*4eaa4710SRishi Srivatsavai 7323*4eaa4710SRishi Srivatsavai /* clean up the partial configuration */ 7324*4eaa4710SRishi Srivatsavai for (i = 0; i < n; i++) 7325*4eaa4710SRishi Srivatsavai (void) dladm_bridge_setlink(handle, linkids[i], ""); 7326*4eaa4710SRishi Srivatsavai 7327*4eaa4710SRishi Srivatsavai /* if failure for brCreate, then delete the bridge */ 7328*4eaa4710SRishi Srivatsavai if (func == brCreate) 7329*4eaa4710SRishi Srivatsavai (void) dladm_bridge_delete(handle, bridge, flags); 7330*4eaa4710SRishi Srivatsavai 7331*4eaa4710SRishi Srivatsavai if (n < nlink) 7332*4eaa4710SRishi Srivatsavai die_dlerr(status, "unable to add link %s to bridge %s", 7333*4eaa4710SRishi Srivatsavai links[n], bridge); 7334*4eaa4710SRishi Srivatsavai else 7335*4eaa4710SRishi Srivatsavai die_dlerr(status, "unable to enable bridge %s", bridge); 7336*4eaa4710SRishi Srivatsavai } 7337*4eaa4710SRishi Srivatsavai 7338*4eaa4710SRishi Srivatsavai static void 7339*4eaa4710SRishi Srivatsavai do_create_bridge(int argc, char **argv, const char *use) 7340*4eaa4710SRishi Srivatsavai { 7341*4eaa4710SRishi Srivatsavai create_modify_add_bridge(argc, argv, use, brCreate); 7342*4eaa4710SRishi Srivatsavai } 7343*4eaa4710SRishi Srivatsavai 7344*4eaa4710SRishi Srivatsavai static void 7345*4eaa4710SRishi Srivatsavai do_modify_bridge(int argc, char **argv, const char *use) 7346*4eaa4710SRishi Srivatsavai { 7347*4eaa4710SRishi Srivatsavai create_modify_add_bridge(argc, argv, use, brModify); 7348*4eaa4710SRishi Srivatsavai } 7349*4eaa4710SRishi Srivatsavai 7350*4eaa4710SRishi Srivatsavai static void 7351*4eaa4710SRishi Srivatsavai do_add_bridge(int argc, char **argv, const char *use) 7352*4eaa4710SRishi Srivatsavai { 7353*4eaa4710SRishi Srivatsavai create_modify_add_bridge(argc, argv, use, brAdd); 7354*4eaa4710SRishi Srivatsavai } 7355*4eaa4710SRishi Srivatsavai 7356*4eaa4710SRishi Srivatsavai static void 7357*4eaa4710SRishi Srivatsavai do_delete_bridge(int argc, char **argv, const char *use) 7358*4eaa4710SRishi Srivatsavai { 7359*4eaa4710SRishi Srivatsavai char option; 7360*4eaa4710SRishi Srivatsavai char *altroot = NULL; 7361*4eaa4710SRishi Srivatsavai uint32_t flags = DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST; 7362*4eaa4710SRishi Srivatsavai dladm_status_t status; 7363*4eaa4710SRishi Srivatsavai 7364*4eaa4710SRishi Srivatsavai opterr = 0; 7365*4eaa4710SRishi Srivatsavai while ((option = getopt_long(argc, argv, ":R:", bridge_lopts, NULL)) != 7366*4eaa4710SRishi Srivatsavai -1) { 7367*4eaa4710SRishi Srivatsavai switch (option) { 7368*4eaa4710SRishi Srivatsavai case 'R': 7369*4eaa4710SRishi Srivatsavai altroot = optarg; 7370*4eaa4710SRishi Srivatsavai break; 7371*4eaa4710SRishi Srivatsavai default: 7372*4eaa4710SRishi Srivatsavai die_opterr(optopt, option, use); 7373*4eaa4710SRishi Srivatsavai break; 7374*4eaa4710SRishi Srivatsavai } 7375*4eaa4710SRishi Srivatsavai } 7376*4eaa4710SRishi Srivatsavai 7377*4eaa4710SRishi Srivatsavai /* get the bridge name (required last argument) */ 7378*4eaa4710SRishi Srivatsavai if (optind != (argc-1)) 7379*4eaa4710SRishi Srivatsavai usage(); 7380*4eaa4710SRishi Srivatsavai 7381*4eaa4710SRishi Srivatsavai if (altroot != NULL) 7382*4eaa4710SRishi Srivatsavai altroot_cmd(altroot, argc, argv); 7383*4eaa4710SRishi Srivatsavai 7384*4eaa4710SRishi Srivatsavai status = dladm_bridge_delete(handle, argv[optind], flags); 7385*4eaa4710SRishi Srivatsavai if (status != DLADM_STATUS_OK) 7386*4eaa4710SRishi Srivatsavai die_dlerr(status, "delete operation failed"); 7387*4eaa4710SRishi Srivatsavai } 7388*4eaa4710SRishi Srivatsavai 7389*4eaa4710SRishi Srivatsavai static void 7390*4eaa4710SRishi Srivatsavai do_remove_bridge(int argc, char **argv, const char *use) 7391*4eaa4710SRishi Srivatsavai { 7392*4eaa4710SRishi Srivatsavai char option; 7393*4eaa4710SRishi Srivatsavai uint_t n, nlink; 7394*4eaa4710SRishi Srivatsavai char *links[MAXPORT]; 7395*4eaa4710SRishi Srivatsavai datalink_id_t linkids[MAXPORT]; 7396*4eaa4710SRishi Srivatsavai char *altroot = NULL; 7397*4eaa4710SRishi Srivatsavai dladm_status_t status; 7398*4eaa4710SRishi Srivatsavai boolean_t removed_one; 7399*4eaa4710SRishi Srivatsavai 7400*4eaa4710SRishi Srivatsavai nlink = opterr = 0; 7401*4eaa4710SRishi Srivatsavai while ((option = getopt_long(argc, argv, ":R:l:", bridge_lopts, 7402*4eaa4710SRishi Srivatsavai NULL)) != -1) { 7403*4eaa4710SRishi Srivatsavai switch (option) { 7404*4eaa4710SRishi Srivatsavai case 'R': 7405*4eaa4710SRishi Srivatsavai altroot = optarg; 7406*4eaa4710SRishi Srivatsavai break; 7407*4eaa4710SRishi Srivatsavai case 'l': 7408*4eaa4710SRishi Srivatsavai if (nlink >= MAXPORT) 7409*4eaa4710SRishi Srivatsavai die("too many links specified"); 7410*4eaa4710SRishi Srivatsavai links[nlink++] = optarg; 7411*4eaa4710SRishi Srivatsavai break; 7412*4eaa4710SRishi Srivatsavai default: 7413*4eaa4710SRishi Srivatsavai die_opterr(optopt, option, use); 7414*4eaa4710SRishi Srivatsavai break; 7415*4eaa4710SRishi Srivatsavai } 7416*4eaa4710SRishi Srivatsavai } 7417*4eaa4710SRishi Srivatsavai 7418*4eaa4710SRishi Srivatsavai if (nlink == 0) 7419*4eaa4710SRishi Srivatsavai usage(); 7420*4eaa4710SRishi Srivatsavai 7421*4eaa4710SRishi Srivatsavai /* get the bridge name (required last argument) */ 7422*4eaa4710SRishi Srivatsavai if (optind != (argc-1)) 7423*4eaa4710SRishi Srivatsavai usage(); 7424*4eaa4710SRishi Srivatsavai 7425*4eaa4710SRishi Srivatsavai if (altroot != NULL) 7426*4eaa4710SRishi Srivatsavai altroot_cmd(altroot, argc, argv); 7427*4eaa4710SRishi Srivatsavai 7428*4eaa4710SRishi Srivatsavai for (n = 0; n < nlink; n++) { 7429*4eaa4710SRishi Srivatsavai char bridge[MAXLINKNAMELEN]; 7430*4eaa4710SRishi Srivatsavai 7431*4eaa4710SRishi Srivatsavai if (dladm_name2info(handle, links[n], &linkids[n], NULL, NULL, 7432*4eaa4710SRishi Srivatsavai NULL) != DLADM_STATUS_OK) 7433*4eaa4710SRishi Srivatsavai die("invalid link name '%s'", links[n]); 7434*4eaa4710SRishi Srivatsavai status = dladm_bridge_getlink(handle, linkids[n], bridge, 7435*4eaa4710SRishi Srivatsavai sizeof (bridge)); 7436*4eaa4710SRishi Srivatsavai if (status != DLADM_STATUS_OK && 7437*4eaa4710SRishi Srivatsavai status != DLADM_STATUS_NOTFOUND) { 7438*4eaa4710SRishi Srivatsavai die_dlerr(status, "cannot get bridge status on %s", 7439*4eaa4710SRishi Srivatsavai links[n]); 7440*4eaa4710SRishi Srivatsavai } 7441*4eaa4710SRishi Srivatsavai if (status == DLADM_STATUS_NOTFOUND || 7442*4eaa4710SRishi Srivatsavai strcmp(bridge, argv[optind]) != 0) 7443*4eaa4710SRishi Srivatsavai die("link %s is not on bridge %s", links[n], 7444*4eaa4710SRishi Srivatsavai argv[optind]); 7445*4eaa4710SRishi Srivatsavai } 7446*4eaa4710SRishi Srivatsavai 7447*4eaa4710SRishi Srivatsavai removed_one = B_FALSE; 7448*4eaa4710SRishi Srivatsavai for (n = 0; n < nlink; n++) { 7449*4eaa4710SRishi Srivatsavai status = dladm_bridge_setlink(handle, linkids[n], ""); 7450*4eaa4710SRishi Srivatsavai if (status == DLADM_STATUS_OK) { 7451*4eaa4710SRishi Srivatsavai removed_one = B_TRUE; 7452*4eaa4710SRishi Srivatsavai } else { 7453*4eaa4710SRishi Srivatsavai warn_dlerr(status, 7454*4eaa4710SRishi Srivatsavai "cannot remove link %s from bridge %s", 7455*4eaa4710SRishi Srivatsavai links[n], argv[optind]); 7456*4eaa4710SRishi Srivatsavai } 7457*4eaa4710SRishi Srivatsavai } 7458*4eaa4710SRishi Srivatsavai if (!removed_one) 7459*4eaa4710SRishi Srivatsavai die("unable to remove any links from bridge %s", argv[optind]); 7460*4eaa4710SRishi Srivatsavai } 7461*4eaa4710SRishi Srivatsavai 7462*4eaa4710SRishi Srivatsavai static void 7463*4eaa4710SRishi Srivatsavai fmt_int(char *buf, size_t buflen, int value, int runvalue, 7464*4eaa4710SRishi Srivatsavai boolean_t printstar) 7465*4eaa4710SRishi Srivatsavai { 7466*4eaa4710SRishi Srivatsavai (void) snprintf(buf, buflen, "%d", value); 7467*4eaa4710SRishi Srivatsavai if (value != runvalue && printstar) 7468*4eaa4710SRishi Srivatsavai (void) strlcat(buf, "*", buflen); 7469*4eaa4710SRishi Srivatsavai } 7470*4eaa4710SRishi Srivatsavai 7471*4eaa4710SRishi Srivatsavai static void 7472*4eaa4710SRishi Srivatsavai fmt_bridge_id(char *buf, size_t buflen, UID_BRIDGE_ID_T *bid) 7473*4eaa4710SRishi Srivatsavai { 7474*4eaa4710SRishi Srivatsavai (void) snprintf(buf, buflen, "%u/%x:%x:%x:%x:%x:%x", bid->prio, 7475*4eaa4710SRishi Srivatsavai bid->addr[0], bid->addr[1], bid->addr[2], bid->addr[3], 7476*4eaa4710SRishi Srivatsavai bid->addr[4], bid->addr[5]); 7477*4eaa4710SRishi Srivatsavai } 7478*4eaa4710SRishi Srivatsavai 7479*4eaa4710SRishi Srivatsavai static dladm_status_t 7480*4eaa4710SRishi Srivatsavai print_bridge(show_state_t *state, datalink_id_t linkid, 7481*4eaa4710SRishi Srivatsavai bridge_fields_buf_t *bbuf) 7482*4eaa4710SRishi Srivatsavai { 7483*4eaa4710SRishi Srivatsavai char link[MAXLINKNAMELEN]; 7484*4eaa4710SRishi Srivatsavai datalink_class_t class; 7485*4eaa4710SRishi Srivatsavai uint32_t flags; 7486*4eaa4710SRishi Srivatsavai dladm_status_t status; 7487*4eaa4710SRishi Srivatsavai UID_STP_CFG_T smfcfg, runcfg; 7488*4eaa4710SRishi Srivatsavai UID_STP_STATE_T stpstate; 7489*4eaa4710SRishi Srivatsavai dladm_bridge_prot_t smfprot, runprot; 7490*4eaa4710SRishi Srivatsavai 7491*4eaa4710SRishi Srivatsavai if ((status = dladm_datalink_id2info(handle, linkid, &flags, &class, 7492*4eaa4710SRishi Srivatsavai NULL, link, sizeof (link))) != DLADM_STATUS_OK) 7493*4eaa4710SRishi Srivatsavai return (status); 7494*4eaa4710SRishi Srivatsavai 7495*4eaa4710SRishi Srivatsavai if (!(state->ls_flags & flags)) 7496*4eaa4710SRishi Srivatsavai return (DLADM_STATUS_NOTFOUND); 7497*4eaa4710SRishi Srivatsavai 7498*4eaa4710SRishi Srivatsavai /* Convert observability node name back to bridge name */ 7499*4eaa4710SRishi Srivatsavai if (!dladm_observe_to_bridge(link)) 7500*4eaa4710SRishi Srivatsavai return (DLADM_STATUS_NOTFOUND); 7501*4eaa4710SRishi Srivatsavai (void) strlcpy(bbuf->bridge_name, link, sizeof (bbuf->bridge_name)); 7502*4eaa4710SRishi Srivatsavai 7503*4eaa4710SRishi Srivatsavai /* 7504*4eaa4710SRishi Srivatsavai * If the running value differs from the one in SMF, and parsable 7505*4eaa4710SRishi Srivatsavai * output is not requested, then we show the running value with an 7506*4eaa4710SRishi Srivatsavai * asterisk. 7507*4eaa4710SRishi Srivatsavai */ 7508*4eaa4710SRishi Srivatsavai (void) dladm_bridge_get_properties(bbuf->bridge_name, &smfcfg, 7509*4eaa4710SRishi Srivatsavai &smfprot); 7510*4eaa4710SRishi Srivatsavai (void) dladm_bridge_run_properties(bbuf->bridge_name, &runcfg, 7511*4eaa4710SRishi Srivatsavai &runprot); 7512*4eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridge_protect, sizeof (bbuf->bridge_protect), 7513*4eaa4710SRishi Srivatsavai "%s%s", state->ls_parsable || smfprot == runprot ? "" : "*", 7514*4eaa4710SRishi Srivatsavai dladm_bridge_prot2str(runprot)); 7515*4eaa4710SRishi Srivatsavai fmt_int(bbuf->bridge_priority, sizeof (bbuf->bridge_priority), 7516*4eaa4710SRishi Srivatsavai smfcfg.bridge_priority, runcfg.bridge_priority, 7517*4eaa4710SRishi Srivatsavai !state->ls_parsable && (runcfg.field_mask & BR_CFG_AGE)); 7518*4eaa4710SRishi Srivatsavai fmt_int(bbuf->bridge_bmaxage, sizeof (bbuf->bridge_bmaxage), 7519*4eaa4710SRishi Srivatsavai smfcfg.max_age, runcfg.max_age, 7520*4eaa4710SRishi Srivatsavai !state->ls_parsable && (runcfg.field_mask & BR_CFG_AGE)); 7521*4eaa4710SRishi Srivatsavai fmt_int(bbuf->bridge_bhellotime, 7522*4eaa4710SRishi Srivatsavai sizeof (bbuf->bridge_bhellotime), smfcfg.hello_time, 7523*4eaa4710SRishi Srivatsavai runcfg.hello_time, 7524*4eaa4710SRishi Srivatsavai !state->ls_parsable && (runcfg.field_mask & BR_CFG_HELLO)); 7525*4eaa4710SRishi Srivatsavai fmt_int(bbuf->bridge_bfwddelay, sizeof (bbuf->bridge_bfwddelay), 7526*4eaa4710SRishi Srivatsavai smfcfg.forward_delay, runcfg.forward_delay, 7527*4eaa4710SRishi Srivatsavai !state->ls_parsable && (runcfg.field_mask & BR_CFG_DELAY)); 7528*4eaa4710SRishi Srivatsavai fmt_int(bbuf->bridge_forceproto, sizeof (bbuf->bridge_forceproto), 7529*4eaa4710SRishi Srivatsavai smfcfg.force_version, runcfg.force_version, 7530*4eaa4710SRishi Srivatsavai !state->ls_parsable && (runcfg.field_mask & BR_CFG_FORCE_VER)); 7531*4eaa4710SRishi Srivatsavai fmt_int(bbuf->bridge_holdtime, sizeof (bbuf->bridge_holdtime), 7532*4eaa4710SRishi Srivatsavai smfcfg.hold_time, runcfg.hold_time, 7533*4eaa4710SRishi Srivatsavai !state->ls_parsable && (runcfg.field_mask & BR_CFG_HOLD_TIME)); 7534*4eaa4710SRishi Srivatsavai 7535*4eaa4710SRishi Srivatsavai if (dladm_bridge_state(bbuf->bridge_name, &stpstate) == 7536*4eaa4710SRishi Srivatsavai DLADM_STATUS_OK) { 7537*4eaa4710SRishi Srivatsavai fmt_bridge_id(bbuf->bridge_address, 7538*4eaa4710SRishi Srivatsavai sizeof (bbuf->bridge_address), &stpstate.bridge_id); 7539*4eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridge_tctime, 7540*4eaa4710SRishi Srivatsavai sizeof (bbuf->bridge_tctime), "%lu", 7541*4eaa4710SRishi Srivatsavai stpstate.timeSince_Topo_Change); 7542*4eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridge_tccount, 7543*4eaa4710SRishi Srivatsavai sizeof (bbuf->bridge_tccount), "%lu", 7544*4eaa4710SRishi Srivatsavai stpstate.Topo_Change_Count); 7545*4eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridge_tchange, 7546*4eaa4710SRishi Srivatsavai sizeof (bbuf->bridge_tchange), "%u", stpstate.Topo_Change); 7547*4eaa4710SRishi Srivatsavai fmt_bridge_id(bbuf->bridge_desroot, 7548*4eaa4710SRishi Srivatsavai sizeof (bbuf->bridge_desroot), &stpstate.designated_root); 7549*4eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridge_rootcost, 7550*4eaa4710SRishi Srivatsavai sizeof (bbuf->bridge_rootcost), "%lu", 7551*4eaa4710SRishi Srivatsavai stpstate.root_path_cost); 7552*4eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridge_rootport, 7553*4eaa4710SRishi Srivatsavai sizeof (bbuf->bridge_rootport), "%u", stpstate.root_port); 7554*4eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridge_maxage, 7555*4eaa4710SRishi Srivatsavai sizeof (bbuf->bridge_maxage), "%d", stpstate.max_age); 7556*4eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridge_hellotime, 7557*4eaa4710SRishi Srivatsavai sizeof (bbuf->bridge_hellotime), "%d", stpstate.hello_time); 7558*4eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridge_fwddelay, 7559*4eaa4710SRishi Srivatsavai sizeof (bbuf->bridge_fwddelay), "%d", 7560*4eaa4710SRishi Srivatsavai stpstate.forward_delay); 7561*4eaa4710SRishi Srivatsavai } 7562*4eaa4710SRishi Srivatsavai return (DLADM_STATUS_OK); 7563*4eaa4710SRishi Srivatsavai } 7564*4eaa4710SRishi Srivatsavai 7565*4eaa4710SRishi Srivatsavai static dladm_status_t 7566*4eaa4710SRishi Srivatsavai print_bridge_stats(show_state_t *state, datalink_id_t linkid, 7567*4eaa4710SRishi Srivatsavai bridge_statfields_buf_t *bbuf) 7568*4eaa4710SRishi Srivatsavai { 7569*4eaa4710SRishi Srivatsavai char link[MAXLINKNAMELEN]; 7570*4eaa4710SRishi Srivatsavai datalink_class_t class; 7571*4eaa4710SRishi Srivatsavai uint32_t flags; 7572*4eaa4710SRishi Srivatsavai dladm_status_t status; 7573*4eaa4710SRishi Srivatsavai kstat_ctl_t *kcp; 7574*4eaa4710SRishi Srivatsavai kstat_t *ksp; 7575*4eaa4710SRishi Srivatsavai brsum_t *brsum = (brsum_t *)&state->ls_prevstats; 7576*4eaa4710SRishi Srivatsavai brsum_t newval; 7577*4eaa4710SRishi Srivatsavai 7578*4eaa4710SRishi Srivatsavai #ifndef lint 7579*4eaa4710SRishi Srivatsavai /* This is a compile-time assertion; optimizer normally fixes this */ 7580*4eaa4710SRishi Srivatsavai extern void brsum_t_is_too_large(void); 7581*4eaa4710SRishi Srivatsavai 7582*4eaa4710SRishi Srivatsavai if (sizeof (*brsum) > sizeof (state->ls_prevstats)) 7583*4eaa4710SRishi Srivatsavai brsum_t_is_too_large(); 7584*4eaa4710SRishi Srivatsavai #endif 7585*4eaa4710SRishi Srivatsavai 7586*4eaa4710SRishi Srivatsavai if (state->ls_firstonly) { 7587*4eaa4710SRishi Srivatsavai if (state->ls_donefirst) 7588*4eaa4710SRishi Srivatsavai return (DLADM_WALK_CONTINUE); 7589*4eaa4710SRishi Srivatsavai state->ls_donefirst = B_TRUE; 7590*4eaa4710SRishi Srivatsavai } else { 7591*4eaa4710SRishi Srivatsavai bzero(brsum, sizeof (*brsum)); 7592*4eaa4710SRishi Srivatsavai } 7593*4eaa4710SRishi Srivatsavai bzero(&newval, sizeof (newval)); 7594*4eaa4710SRishi Srivatsavai 7595*4eaa4710SRishi Srivatsavai if ((status = dladm_datalink_id2info(handle, linkid, &flags, &class, 7596*4eaa4710SRishi Srivatsavai NULL, link, sizeof (link))) != DLADM_STATUS_OK) 7597*4eaa4710SRishi Srivatsavai return (status); 7598*4eaa4710SRishi Srivatsavai 7599*4eaa4710SRishi Srivatsavai if (!(state->ls_flags & flags)) 7600*4eaa4710SRishi Srivatsavai return (DLADM_STATUS_NOTFOUND); 7601*4eaa4710SRishi Srivatsavai 7602*4eaa4710SRishi Srivatsavai if ((kcp = kstat_open()) == NULL) { 7603*4eaa4710SRishi Srivatsavai warn("kstat open operation failed"); 7604*4eaa4710SRishi Srivatsavai return (DLADM_STATUS_OK); 7605*4eaa4710SRishi Srivatsavai } 7606*4eaa4710SRishi Srivatsavai if ((ksp = kstat_lookup(kcp, "bridge", 0, link)) != NULL && 7607*4eaa4710SRishi Srivatsavai kstat_read(kcp, ksp, NULL) != -1) { 7608*4eaa4710SRishi Srivatsavai if (dladm_kstat_value(ksp, "drops", KSTAT_DATA_UINT64, 7609*4eaa4710SRishi Srivatsavai &newval.drops) == DLADM_STATUS_OK) { 7610*4eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridges_drops, 7611*4eaa4710SRishi Srivatsavai sizeof (bbuf->bridges_drops), "%llu", 7612*4eaa4710SRishi Srivatsavai newval.drops - brsum->drops); 7613*4eaa4710SRishi Srivatsavai } 7614*4eaa4710SRishi Srivatsavai if (dladm_kstat_value(ksp, "forward_direct", KSTAT_DATA_UINT64, 7615*4eaa4710SRishi Srivatsavai &newval.forward_dir) == DLADM_STATUS_OK) { 7616*4eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridges_forwards, 7617*4eaa4710SRishi Srivatsavai sizeof (bbuf->bridges_forwards), "%llu", 7618*4eaa4710SRishi Srivatsavai newval.forward_dir - brsum->forward_dir); 7619*4eaa4710SRishi Srivatsavai } 7620*4eaa4710SRishi Srivatsavai if (dladm_kstat_value(ksp, "forward_mbcast", KSTAT_DATA_UINT64, 7621*4eaa4710SRishi Srivatsavai &newval.forward_mb) == DLADM_STATUS_OK) { 7622*4eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridges_mbcast, 7623*4eaa4710SRishi Srivatsavai sizeof (bbuf->bridges_mbcast), "%llu", 7624*4eaa4710SRishi Srivatsavai newval.forward_mb - brsum->forward_mb); 7625*4eaa4710SRishi Srivatsavai } 7626*4eaa4710SRishi Srivatsavai if (dladm_kstat_value(ksp, "forward_unknown", KSTAT_DATA_UINT64, 7627*4eaa4710SRishi Srivatsavai &newval.forward_unk) == DLADM_STATUS_OK) { 7628*4eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridges_unknown, 7629*4eaa4710SRishi Srivatsavai sizeof (bbuf->bridges_unknown), "%llu", 7630*4eaa4710SRishi Srivatsavai newval.forward_unk - brsum->forward_unk); 7631*4eaa4710SRishi Srivatsavai } 7632*4eaa4710SRishi Srivatsavai if (dladm_kstat_value(ksp, "recv", KSTAT_DATA_UINT64, 7633*4eaa4710SRishi Srivatsavai &newval.recv) == DLADM_STATUS_OK) { 7634*4eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridges_recv, 7635*4eaa4710SRishi Srivatsavai sizeof (bbuf->bridges_recv), "%llu", 7636*4eaa4710SRishi Srivatsavai newval.recv - brsum->recv); 7637*4eaa4710SRishi Srivatsavai } 7638*4eaa4710SRishi Srivatsavai if (dladm_kstat_value(ksp, "sent", KSTAT_DATA_UINT64, 7639*4eaa4710SRishi Srivatsavai &newval.sent) == DLADM_STATUS_OK) { 7640*4eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridges_sent, 7641*4eaa4710SRishi Srivatsavai sizeof (bbuf->bridges_sent), "%llu", 7642*4eaa4710SRishi Srivatsavai newval.sent - brsum->sent); 7643*4eaa4710SRishi Srivatsavai } 7644*4eaa4710SRishi Srivatsavai } 7645*4eaa4710SRishi Srivatsavai (void) kstat_close(kcp); 7646*4eaa4710SRishi Srivatsavai 7647*4eaa4710SRishi Srivatsavai /* Convert observability node name back to bridge name */ 7648*4eaa4710SRishi Srivatsavai if (!dladm_observe_to_bridge(link)) 7649*4eaa4710SRishi Srivatsavai return (DLADM_STATUS_NOTFOUND); 7650*4eaa4710SRishi Srivatsavai (void) strlcpy(bbuf->bridges_name, link, sizeof (bbuf->bridges_name)); 7651*4eaa4710SRishi Srivatsavai 7652*4eaa4710SRishi Srivatsavai *brsum = newval; 7653*4eaa4710SRishi Srivatsavai 7654*4eaa4710SRishi Srivatsavai return (DLADM_STATUS_OK); 7655*4eaa4710SRishi Srivatsavai } 7656*4eaa4710SRishi Srivatsavai 7657*4eaa4710SRishi Srivatsavai /* 7658*4eaa4710SRishi Srivatsavai * This structure carries around extra state information for the show-bridge 7659*4eaa4710SRishi Srivatsavai * command and allows us to use common support functions. 7660*4eaa4710SRishi Srivatsavai */ 7661*4eaa4710SRishi Srivatsavai typedef struct { 7662*4eaa4710SRishi Srivatsavai show_state_t state; 7663*4eaa4710SRishi Srivatsavai boolean_t show_stats; 7664*4eaa4710SRishi Srivatsavai const char *bridge; 7665*4eaa4710SRishi Srivatsavai } show_brstate_t; 7666*4eaa4710SRishi Srivatsavai 7667*4eaa4710SRishi Srivatsavai /* ARGSUSED */ 7668*4eaa4710SRishi Srivatsavai static int 7669*4eaa4710SRishi Srivatsavai show_bridge(dladm_handle_t handle, datalink_id_t linkid, void *arg) 7670*4eaa4710SRishi Srivatsavai { 7671*4eaa4710SRishi Srivatsavai show_brstate_t *brstate = arg; 7672*4eaa4710SRishi Srivatsavai void *buf; 7673*4eaa4710SRishi Srivatsavai 7674*4eaa4710SRishi Srivatsavai if (brstate->show_stats) { 7675*4eaa4710SRishi Srivatsavai bridge_statfields_buf_t bbuf; 7676*4eaa4710SRishi Srivatsavai 7677*4eaa4710SRishi Srivatsavai bzero(&bbuf, sizeof (bbuf)); 7678*4eaa4710SRishi Srivatsavai brstate->state.ls_status = print_bridge_stats(&brstate->state, 7679*4eaa4710SRishi Srivatsavai linkid, &bbuf); 7680*4eaa4710SRishi Srivatsavai buf = &bbuf; 7681*4eaa4710SRishi Srivatsavai } else { 7682*4eaa4710SRishi Srivatsavai bridge_fields_buf_t bbuf; 7683*4eaa4710SRishi Srivatsavai 7684*4eaa4710SRishi Srivatsavai bzero(&bbuf, sizeof (bbuf)); 7685*4eaa4710SRishi Srivatsavai brstate->state.ls_status = print_bridge(&brstate->state, linkid, 7686*4eaa4710SRishi Srivatsavai &bbuf); 7687*4eaa4710SRishi Srivatsavai buf = &bbuf; 7688*4eaa4710SRishi Srivatsavai } 7689*4eaa4710SRishi Srivatsavai if (brstate->state.ls_status == DLADM_STATUS_OK) 7690*4eaa4710SRishi Srivatsavai ofmt_print(brstate->state.ls_ofmt, buf); 7691*4eaa4710SRishi Srivatsavai return (DLADM_WALK_CONTINUE); 7692*4eaa4710SRishi Srivatsavai } 7693*4eaa4710SRishi Srivatsavai 7694*4eaa4710SRishi Srivatsavai static void 7695*4eaa4710SRishi Srivatsavai fmt_bool(char *buf, size_t buflen, int val) 7696*4eaa4710SRishi Srivatsavai { 7697*4eaa4710SRishi Srivatsavai (void) strlcpy(buf, val ? "yes" : "no", buflen); 7698*4eaa4710SRishi Srivatsavai } 7699*4eaa4710SRishi Srivatsavai 7700*4eaa4710SRishi Srivatsavai static dladm_status_t 7701*4eaa4710SRishi Srivatsavai print_bridge_link(show_state_t *state, datalink_id_t linkid, 7702*4eaa4710SRishi Srivatsavai bridge_link_fields_buf_t *bbuf) 7703*4eaa4710SRishi Srivatsavai { 7704*4eaa4710SRishi Srivatsavai datalink_class_t class; 7705*4eaa4710SRishi Srivatsavai uint32_t flags; 7706*4eaa4710SRishi Srivatsavai dladm_status_t status; 7707*4eaa4710SRishi Srivatsavai UID_STP_PORT_STATE_T stpstate; 7708*4eaa4710SRishi Srivatsavai 7709*4eaa4710SRishi Srivatsavai status = dladm_datalink_id2info(handle, linkid, &flags, &class, NULL, 7710*4eaa4710SRishi Srivatsavai bbuf->bridgel_link, sizeof (bbuf->bridgel_link)); 7711*4eaa4710SRishi Srivatsavai if (status != DLADM_STATUS_OK) 7712*4eaa4710SRishi Srivatsavai return (status); 7713*4eaa4710SRishi Srivatsavai 7714*4eaa4710SRishi Srivatsavai if (!(state->ls_flags & flags)) 7715*4eaa4710SRishi Srivatsavai return (DLADM_STATUS_NOTFOUND); 7716*4eaa4710SRishi Srivatsavai 7717*4eaa4710SRishi Srivatsavai if (dladm_bridge_link_state(handle, linkid, &stpstate) == 7718*4eaa4710SRishi Srivatsavai DLADM_STATUS_OK) { 7719*4eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridgel_index, 7720*4eaa4710SRishi Srivatsavai sizeof (bbuf->bridgel_index), "%u", stpstate.port_no); 7721*4eaa4710SRishi Srivatsavai if (dlsym(RTLD_PROBE, "STP_IN_state2str")) { 7722*4eaa4710SRishi Srivatsavai (void) strlcpy(bbuf->bridgel_state, 7723*4eaa4710SRishi Srivatsavai STP_IN_state2str(stpstate.state), 7724*4eaa4710SRishi Srivatsavai sizeof (bbuf->bridgel_state)); 7725*4eaa4710SRishi Srivatsavai } else { 7726*4eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridgel_state, 7727*4eaa4710SRishi Srivatsavai sizeof (bbuf->bridgel_state), "%u", 7728*4eaa4710SRishi Srivatsavai stpstate.state); 7729*4eaa4710SRishi Srivatsavai } 7730*4eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridgel_uptime, 7731*4eaa4710SRishi Srivatsavai sizeof (bbuf->bridgel_uptime), "%lu", stpstate.uptime); 7732*4eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridgel_opercost, 7733*4eaa4710SRishi Srivatsavai sizeof (bbuf->bridgel_opercost), "%lu", 7734*4eaa4710SRishi Srivatsavai stpstate.oper_port_path_cost); 7735*4eaa4710SRishi Srivatsavai fmt_bool(bbuf->bridgel_operp2p, sizeof (bbuf->bridgel_operp2p), 7736*4eaa4710SRishi Srivatsavai stpstate.oper_point2point); 7737*4eaa4710SRishi Srivatsavai fmt_bool(bbuf->bridgel_operedge, 7738*4eaa4710SRishi Srivatsavai sizeof (bbuf->bridgel_operedge), stpstate.oper_edge); 7739*4eaa4710SRishi Srivatsavai fmt_bridge_id(bbuf->bridgel_desroot, 7740*4eaa4710SRishi Srivatsavai sizeof (bbuf->bridgel_desroot), &stpstate.designated_root); 7741*4eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridgel_descost, 7742*4eaa4710SRishi Srivatsavai sizeof (bbuf->bridgel_descost), "%lu", 7743*4eaa4710SRishi Srivatsavai stpstate.designated_cost); 7744*4eaa4710SRishi Srivatsavai fmt_bridge_id(bbuf->bridgel_desbridge, 7745*4eaa4710SRishi Srivatsavai sizeof (bbuf->bridgel_desbridge), 7746*4eaa4710SRishi Srivatsavai &stpstate.designated_bridge); 7747*4eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridgel_desport, 7748*4eaa4710SRishi Srivatsavai sizeof (bbuf->bridgel_desport), "%u", 7749*4eaa4710SRishi Srivatsavai stpstate.designated_port); 7750*4eaa4710SRishi Srivatsavai fmt_bool(bbuf->bridgel_tcack, sizeof (bbuf->bridgel_tcack), 7751*4eaa4710SRishi Srivatsavai stpstate.top_change_ack); 7752*4eaa4710SRishi Srivatsavai } 7753*4eaa4710SRishi Srivatsavai return (DLADM_STATUS_OK); 7754*4eaa4710SRishi Srivatsavai } 7755*4eaa4710SRishi Srivatsavai 7756*4eaa4710SRishi Srivatsavai static dladm_status_t 7757*4eaa4710SRishi Srivatsavai print_bridge_link_stats(show_state_t *state, datalink_id_t linkid, 7758*4eaa4710SRishi Srivatsavai bridge_link_statfields_buf_t *bbuf) 7759*4eaa4710SRishi Srivatsavai { 7760*4eaa4710SRishi Srivatsavai datalink_class_t class; 7761*4eaa4710SRishi Srivatsavai uint32_t flags; 7762*4eaa4710SRishi Srivatsavai dladm_status_t status; 7763*4eaa4710SRishi Srivatsavai UID_STP_PORT_STATE_T stpstate; 7764*4eaa4710SRishi Srivatsavai kstat_ctl_t *kcp; 7765*4eaa4710SRishi Srivatsavai kstat_t *ksp; 7766*4eaa4710SRishi Srivatsavai char bridge[MAXLINKNAMELEN]; 7767*4eaa4710SRishi Srivatsavai char kstatname[MAXLINKNAMELEN*2 + 1]; 7768*4eaa4710SRishi Srivatsavai brlsum_t *brlsum = (brlsum_t *)&state->ls_prevstats; 7769*4eaa4710SRishi Srivatsavai brlsum_t newval; 7770*4eaa4710SRishi Srivatsavai 7771*4eaa4710SRishi Srivatsavai #ifndef lint 7772*4eaa4710SRishi Srivatsavai /* This is a compile-time assertion; optimizer normally fixes this */ 7773*4eaa4710SRishi Srivatsavai extern void brlsum_t_is_too_large(void); 7774*4eaa4710SRishi Srivatsavai 7775*4eaa4710SRishi Srivatsavai if (sizeof (*brlsum) > sizeof (state->ls_prevstats)) 7776*4eaa4710SRishi Srivatsavai brlsum_t_is_too_large(); 7777*4eaa4710SRishi Srivatsavai #endif 7778*4eaa4710SRishi Srivatsavai 7779*4eaa4710SRishi Srivatsavai if (state->ls_firstonly) { 7780*4eaa4710SRishi Srivatsavai if (state->ls_donefirst) 7781*4eaa4710SRishi Srivatsavai return (DLADM_WALK_CONTINUE); 7782*4eaa4710SRishi Srivatsavai state->ls_donefirst = B_TRUE; 7783*4eaa4710SRishi Srivatsavai } else { 7784*4eaa4710SRishi Srivatsavai bzero(brlsum, sizeof (*brlsum)); 7785*4eaa4710SRishi Srivatsavai } 7786*4eaa4710SRishi Srivatsavai bzero(&newval, sizeof (newval)); 7787*4eaa4710SRishi Srivatsavai 7788*4eaa4710SRishi Srivatsavai status = dladm_datalink_id2info(handle, linkid, &flags, &class, NULL, 7789*4eaa4710SRishi Srivatsavai bbuf->bridgels_link, sizeof (bbuf->bridgels_link)); 7790*4eaa4710SRishi Srivatsavai if (status != DLADM_STATUS_OK) 7791*4eaa4710SRishi Srivatsavai return (status); 7792*4eaa4710SRishi Srivatsavai 7793*4eaa4710SRishi Srivatsavai if (!(state->ls_flags & flags)) 7794*4eaa4710SRishi Srivatsavai return (DLADM_STATUS_NOTFOUND); 7795*4eaa4710SRishi Srivatsavai 7796*4eaa4710SRishi Srivatsavai if (dladm_bridge_link_state(handle, linkid, &stpstate) == 7797*4eaa4710SRishi Srivatsavai DLADM_STATUS_OK) { 7798*4eaa4710SRishi Srivatsavai newval.cfgbpdu = stpstate.rx_cfg_bpdu_cnt; 7799*4eaa4710SRishi Srivatsavai newval.tcnbpdu = stpstate.rx_tcn_bpdu_cnt; 7800*4eaa4710SRishi Srivatsavai newval.rstpbpdu = stpstate.rx_rstp_bpdu_cnt; 7801*4eaa4710SRishi Srivatsavai newval.txbpdu = stpstate.txCount; 7802*4eaa4710SRishi Srivatsavai 7803*4eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridgels_cfgbpdu, 7804*4eaa4710SRishi Srivatsavai sizeof (bbuf->bridgels_cfgbpdu), "%lu", 7805*4eaa4710SRishi Srivatsavai newval.cfgbpdu - brlsum->cfgbpdu); 7806*4eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridgels_tcnbpdu, 7807*4eaa4710SRishi Srivatsavai sizeof (bbuf->bridgels_tcnbpdu), "%lu", 7808*4eaa4710SRishi Srivatsavai newval.tcnbpdu - brlsum->tcnbpdu); 7809*4eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridgels_rstpbpdu, 7810*4eaa4710SRishi Srivatsavai sizeof (bbuf->bridgels_rstpbpdu), "%lu", 7811*4eaa4710SRishi Srivatsavai newval.rstpbpdu - brlsum->rstpbpdu); 7812*4eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridgels_txbpdu, 7813*4eaa4710SRishi Srivatsavai sizeof (bbuf->bridgels_txbpdu), "%lu", 7814*4eaa4710SRishi Srivatsavai newval.txbpdu - brlsum->txbpdu); 7815*4eaa4710SRishi Srivatsavai } 7816*4eaa4710SRishi Srivatsavai 7817*4eaa4710SRishi Srivatsavai if ((status = dladm_bridge_getlink(handle, linkid, bridge, 7818*4eaa4710SRishi Srivatsavai sizeof (bridge))) != DLADM_STATUS_OK) 7819*4eaa4710SRishi Srivatsavai goto bls_out; 7820*4eaa4710SRishi Srivatsavai (void) snprintf(kstatname, sizeof (kstatname), "%s0-%s", bridge, 7821*4eaa4710SRishi Srivatsavai bbuf->bridgels_link); 7822*4eaa4710SRishi Srivatsavai if ((kcp = kstat_open()) == NULL) { 7823*4eaa4710SRishi Srivatsavai warn("kstat open operation failed"); 7824*4eaa4710SRishi Srivatsavai goto bls_out; 7825*4eaa4710SRishi Srivatsavai } 7826*4eaa4710SRishi Srivatsavai if ((ksp = kstat_lookup(kcp, "bridge", 0, kstatname)) != NULL && 7827*4eaa4710SRishi Srivatsavai kstat_read(kcp, ksp, NULL) != -1) { 7828*4eaa4710SRishi Srivatsavai if (dladm_kstat_value(ksp, "drops", KSTAT_DATA_UINT64, 7829*4eaa4710SRishi Srivatsavai &newval.drops) != -1) { 7830*4eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridgels_drops, 7831*4eaa4710SRishi Srivatsavai sizeof (bbuf->bridgels_drops), "%llu", 7832*4eaa4710SRishi Srivatsavai newval.drops - brlsum->drops); 7833*4eaa4710SRishi Srivatsavai } 7834*4eaa4710SRishi Srivatsavai if (dladm_kstat_value(ksp, "recv", KSTAT_DATA_UINT64, 7835*4eaa4710SRishi Srivatsavai &newval.recv) != -1) { 7836*4eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridgels_recv, 7837*4eaa4710SRishi Srivatsavai sizeof (bbuf->bridgels_recv), "%llu", 7838*4eaa4710SRishi Srivatsavai newval.recv - brlsum->recv); 7839*4eaa4710SRishi Srivatsavai } 7840*4eaa4710SRishi Srivatsavai if (dladm_kstat_value(ksp, "xmit", KSTAT_DATA_UINT64, 7841*4eaa4710SRishi Srivatsavai &newval.xmit) != -1) { 7842*4eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridgels_xmit, 7843*4eaa4710SRishi Srivatsavai sizeof (bbuf->bridgels_xmit), "%llu", 7844*4eaa4710SRishi Srivatsavai newval.xmit - brlsum->xmit); 7845*4eaa4710SRishi Srivatsavai } 7846*4eaa4710SRishi Srivatsavai } 7847*4eaa4710SRishi Srivatsavai (void) kstat_close(kcp); 7848*4eaa4710SRishi Srivatsavai bls_out: 7849*4eaa4710SRishi Srivatsavai *brlsum = newval; 7850*4eaa4710SRishi Srivatsavai 7851*4eaa4710SRishi Srivatsavai return (status); 7852*4eaa4710SRishi Srivatsavai } 7853*4eaa4710SRishi Srivatsavai 7854*4eaa4710SRishi Srivatsavai static void 7855*4eaa4710SRishi Srivatsavai show_bridge_link(datalink_id_t linkid, show_brstate_t *brstate) 7856*4eaa4710SRishi Srivatsavai { 7857*4eaa4710SRishi Srivatsavai void *buf; 7858*4eaa4710SRishi Srivatsavai 7859*4eaa4710SRishi Srivatsavai if (brstate->show_stats) { 7860*4eaa4710SRishi Srivatsavai bridge_link_statfields_buf_t bbuf; 7861*4eaa4710SRishi Srivatsavai 7862*4eaa4710SRishi Srivatsavai bzero(&bbuf, sizeof (bbuf)); 7863*4eaa4710SRishi Srivatsavai brstate->state.ls_status = print_bridge_link_stats( 7864*4eaa4710SRishi Srivatsavai &brstate->state, linkid, &bbuf); 7865*4eaa4710SRishi Srivatsavai buf = &bbuf; 7866*4eaa4710SRishi Srivatsavai } else { 7867*4eaa4710SRishi Srivatsavai bridge_link_fields_buf_t bbuf; 7868*4eaa4710SRishi Srivatsavai 7869*4eaa4710SRishi Srivatsavai bzero(&bbuf, sizeof (bbuf)); 7870*4eaa4710SRishi Srivatsavai brstate->state.ls_status = print_bridge_link(&brstate->state, 7871*4eaa4710SRishi Srivatsavai linkid, &bbuf); 7872*4eaa4710SRishi Srivatsavai buf = &bbuf; 7873*4eaa4710SRishi Srivatsavai } 7874*4eaa4710SRishi Srivatsavai if (brstate->state.ls_status == DLADM_STATUS_OK) 7875*4eaa4710SRishi Srivatsavai ofmt_print(brstate->state.ls_ofmt, buf); 7876*4eaa4710SRishi Srivatsavai } 7877*4eaa4710SRishi Srivatsavai 7878*4eaa4710SRishi Srivatsavai /* ARGSUSED */ 7879*4eaa4710SRishi Srivatsavai static int 7880*4eaa4710SRishi Srivatsavai show_bridge_link_walk(dladm_handle_t handle, datalink_id_t linkid, void *arg) 7881*4eaa4710SRishi Srivatsavai { 7882*4eaa4710SRishi Srivatsavai show_brstate_t *brstate = arg; 7883*4eaa4710SRishi Srivatsavai char bridge[MAXLINKNAMELEN]; 7884*4eaa4710SRishi Srivatsavai 7885*4eaa4710SRishi Srivatsavai if (dladm_bridge_getlink(handle, linkid, bridge, sizeof (bridge)) == 7886*4eaa4710SRishi Srivatsavai DLADM_STATUS_OK && strcmp(bridge, brstate->bridge) == 0) { 7887*4eaa4710SRishi Srivatsavai show_bridge_link(linkid, brstate); 7888*4eaa4710SRishi Srivatsavai } 7889*4eaa4710SRishi Srivatsavai return (DLADM_WALK_CONTINUE); 7890*4eaa4710SRishi Srivatsavai } 7891*4eaa4710SRishi Srivatsavai 7892*4eaa4710SRishi Srivatsavai static void 7893*4eaa4710SRishi Srivatsavai show_bridge_fwd(dladm_handle_t handle, bridge_listfwd_t *blf, 7894*4eaa4710SRishi Srivatsavai show_state_t *state) 7895*4eaa4710SRishi Srivatsavai { 7896*4eaa4710SRishi Srivatsavai bridge_fwd_fields_buf_t bbuf; 7897*4eaa4710SRishi Srivatsavai 7898*4eaa4710SRishi Srivatsavai bzero(&bbuf, sizeof (bbuf)); 7899*4eaa4710SRishi Srivatsavai (void) snprintf(bbuf.bridgef_dest, sizeof (bbuf.bridgef_dest), 7900*4eaa4710SRishi Srivatsavai "%s", ether_ntoa((struct ether_addr *)blf->blf_dest)); 7901*4eaa4710SRishi Srivatsavai if (blf->blf_is_local) { 7902*4eaa4710SRishi Srivatsavai (void) strlcpy(bbuf.bridgef_flags, "L", 7903*4eaa4710SRishi Srivatsavai sizeof (bbuf.bridgef_flags)); 7904*4eaa4710SRishi Srivatsavai } else { 7905*4eaa4710SRishi Srivatsavai (void) snprintf(bbuf.bridgef_age, sizeof (bbuf.bridgef_age), 7906*4eaa4710SRishi Srivatsavai "%2d.%03d", blf->blf_ms_age / 1000, blf->blf_ms_age % 1000); 7907*4eaa4710SRishi Srivatsavai if (blf->blf_trill_nick != 0) { 7908*4eaa4710SRishi Srivatsavai (void) snprintf(bbuf.bridgef_output, 7909*4eaa4710SRishi Srivatsavai sizeof (bbuf.bridgef_output), "%u", 7910*4eaa4710SRishi Srivatsavai blf->blf_trill_nick); 7911*4eaa4710SRishi Srivatsavai } 7912*4eaa4710SRishi Srivatsavai } 7913*4eaa4710SRishi Srivatsavai if (blf->blf_linkid != DATALINK_INVALID_LINKID && 7914*4eaa4710SRishi Srivatsavai blf->blf_trill_nick == 0) { 7915*4eaa4710SRishi Srivatsavai state->ls_status = dladm_datalink_id2info(handle, 7916*4eaa4710SRishi Srivatsavai blf->blf_linkid, NULL, NULL, NULL, bbuf.bridgef_output, 7917*4eaa4710SRishi Srivatsavai sizeof (bbuf.bridgef_output)); 7918*4eaa4710SRishi Srivatsavai } 7919*4eaa4710SRishi Srivatsavai if (state->ls_status == DLADM_STATUS_OK) 7920*4eaa4710SRishi Srivatsavai ofmt_print(state->ls_ofmt, &bbuf); 7921*4eaa4710SRishi Srivatsavai } 7922*4eaa4710SRishi Srivatsavai 7923*4eaa4710SRishi Srivatsavai static void 7924*4eaa4710SRishi Srivatsavai show_bridge_trillnick(trill_listnick_t *tln, show_state_t *state) 7925*4eaa4710SRishi Srivatsavai { 7926*4eaa4710SRishi Srivatsavai bridge_trill_fields_buf_t bbuf; 7927*4eaa4710SRishi Srivatsavai 7928*4eaa4710SRishi Srivatsavai bzero(&bbuf, sizeof (bbuf)); 7929*4eaa4710SRishi Srivatsavai (void) snprintf(bbuf.bridget_nick, sizeof (bbuf.bridget_nick), 7930*4eaa4710SRishi Srivatsavai "%u", tln->tln_nick); 7931*4eaa4710SRishi Srivatsavai if (tln->tln_ours) { 7932*4eaa4710SRishi Srivatsavai (void) strlcpy(bbuf.bridget_flags, "L", 7933*4eaa4710SRishi Srivatsavai sizeof (bbuf.bridget_flags)); 7934*4eaa4710SRishi Srivatsavai } else { 7935*4eaa4710SRishi Srivatsavai state->ls_status = dladm_datalink_id2info(handle, 7936*4eaa4710SRishi Srivatsavai tln->tln_linkid, NULL, NULL, NULL, bbuf.bridget_link, 7937*4eaa4710SRishi Srivatsavai sizeof (bbuf.bridget_link)); 7938*4eaa4710SRishi Srivatsavai (void) snprintf(bbuf.bridget_nexthop, 7939*4eaa4710SRishi Srivatsavai sizeof (bbuf.bridget_nexthop), "%s", 7940*4eaa4710SRishi Srivatsavai ether_ntoa((struct ether_addr *)tln->tln_nexthop)); 7941*4eaa4710SRishi Srivatsavai } 7942*4eaa4710SRishi Srivatsavai if (state->ls_status == DLADM_STATUS_OK) 7943*4eaa4710SRishi Srivatsavai ofmt_print(state->ls_ofmt, &bbuf); 7944*4eaa4710SRishi Srivatsavai } 7945*4eaa4710SRishi Srivatsavai 7946*4eaa4710SRishi Srivatsavai static void 7947*4eaa4710SRishi Srivatsavai do_show_bridge(int argc, char **argv, const char *use) 7948*4eaa4710SRishi Srivatsavai { 7949*4eaa4710SRishi Srivatsavai int option; 7950*4eaa4710SRishi Srivatsavai enum { 7951*4eaa4710SRishi Srivatsavai bridgeMode, linkMode, fwdMode, trillMode 7952*4eaa4710SRishi Srivatsavai } op_mode = bridgeMode; 7953*4eaa4710SRishi Srivatsavai uint32_t flags = DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST; 7954*4eaa4710SRishi Srivatsavai boolean_t parsable = B_FALSE; 7955*4eaa4710SRishi Srivatsavai datalink_id_t linkid = DATALINK_ALL_LINKID; 7956*4eaa4710SRishi Srivatsavai int interval = 0; 7957*4eaa4710SRishi Srivatsavai show_brstate_t brstate; 7958*4eaa4710SRishi Srivatsavai dladm_status_t status; 7959*4eaa4710SRishi Srivatsavai char *fields_str = NULL; 7960*4eaa4710SRishi Srivatsavai /* default: bridge-related data */ 7961*4eaa4710SRishi Srivatsavai char *all_fields = "bridge,protect,address,priority,bmaxage," 7962*4eaa4710SRishi Srivatsavai "bhellotime,bfwddelay,forceproto,tctime,tccount,tchange," 7963*4eaa4710SRishi Srivatsavai "desroot,rootcost,rootport,maxage,hellotime,fwddelay,holdtime"; 7964*4eaa4710SRishi Srivatsavai char *default_fields = "bridge,protect,address,priority," 7965*4eaa4710SRishi Srivatsavai "desroot"; 7966*4eaa4710SRishi Srivatsavai char *all_statfields = "bridge,drops,forwards,mbcast," 7967*4eaa4710SRishi Srivatsavai "unknown,recv,sent"; 7968*4eaa4710SRishi Srivatsavai char *default_statfields = "bridge,drops,forwards,mbcast," 7969*4eaa4710SRishi Srivatsavai "unknown"; 7970*4eaa4710SRishi Srivatsavai /* -l: link-related data */ 7971*4eaa4710SRishi Srivatsavai char *all_link_fields = "link,index,state,uptime,opercost," 7972*4eaa4710SRishi Srivatsavai "operp2p,operedge,desroot,descost,desbridge,desport,tcack"; 7973*4eaa4710SRishi Srivatsavai char *default_link_fields = "link,state,uptime,desroot"; 7974*4eaa4710SRishi Srivatsavai char *all_link_statfields = "link,cfgbpdu,tcnbpdu,rstpbpdu," 7975*4eaa4710SRishi Srivatsavai "txbpdu,drops,recv,xmit"; 7976*4eaa4710SRishi Srivatsavai char *default_link_statfields = "link,drops,recv,xmit"; 7977*4eaa4710SRishi Srivatsavai /* -f: bridge forwarding table related data */ 7978*4eaa4710SRishi Srivatsavai char *default_fwd_fields = "dest,age,flags,output"; 7979*4eaa4710SRishi Srivatsavai /* -t: TRILL nickname table related data */ 7980*4eaa4710SRishi Srivatsavai char *default_trill_fields = "nick,flags,link,nexthop"; 7981*4eaa4710SRishi Srivatsavai char *default_str; 7982*4eaa4710SRishi Srivatsavai char *all_str; 7983*4eaa4710SRishi Srivatsavai ofmt_field_t *field_arr; 7984*4eaa4710SRishi Srivatsavai ofmt_handle_t ofmt; 7985*4eaa4710SRishi Srivatsavai ofmt_status_t oferr; 7986*4eaa4710SRishi Srivatsavai uint_t ofmtflags = 0; 7987*4eaa4710SRishi Srivatsavai 7988*4eaa4710SRishi Srivatsavai bzero(&brstate, sizeof (brstate)); 7989*4eaa4710SRishi Srivatsavai 7990*4eaa4710SRishi Srivatsavai opterr = 0; 7991*4eaa4710SRishi Srivatsavai while ((option = getopt_long(argc, argv, ":fi:lo:pst", 7992*4eaa4710SRishi Srivatsavai bridge_show_lopts, NULL)) != -1) { 7993*4eaa4710SRishi Srivatsavai switch (option) { 7994*4eaa4710SRishi Srivatsavai case 'f': 7995*4eaa4710SRishi Srivatsavai if (op_mode != bridgeMode && op_mode != fwdMode) 7996*4eaa4710SRishi Srivatsavai die("-f is incompatible with -l or -t"); 7997*4eaa4710SRishi Srivatsavai op_mode = fwdMode; 7998*4eaa4710SRishi Srivatsavai break; 7999*4eaa4710SRishi Srivatsavai case 'i': 8000*4eaa4710SRishi Srivatsavai if (interval != 0) 8001*4eaa4710SRishi Srivatsavai die_optdup(option); 8002*4eaa4710SRishi Srivatsavai if (!str2int(optarg, &interval) || interval == 0) 8003*4eaa4710SRishi Srivatsavai die("invalid interval value '%s'", optarg); 8004*4eaa4710SRishi Srivatsavai break; 8005*4eaa4710SRishi Srivatsavai case 'l': 8006*4eaa4710SRishi Srivatsavai if (op_mode != bridgeMode && op_mode != linkMode) 8007*4eaa4710SRishi Srivatsavai die("-l is incompatible with -f or -t"); 8008*4eaa4710SRishi Srivatsavai op_mode = linkMode; 8009*4eaa4710SRishi Srivatsavai break; 8010*4eaa4710SRishi Srivatsavai case 'o': 8011*4eaa4710SRishi Srivatsavai fields_str = optarg; 8012*4eaa4710SRishi Srivatsavai break; 8013*4eaa4710SRishi Srivatsavai case 'p': 8014*4eaa4710SRishi Srivatsavai if (parsable) 8015*4eaa4710SRishi Srivatsavai die_optdup(option); 8016*4eaa4710SRishi Srivatsavai parsable = B_TRUE; 8017*4eaa4710SRishi Srivatsavai break; 8018*4eaa4710SRishi Srivatsavai case 's': 8019*4eaa4710SRishi Srivatsavai if (brstate.show_stats) 8020*4eaa4710SRishi Srivatsavai die_optdup(option); 8021*4eaa4710SRishi Srivatsavai brstate.show_stats = B_TRUE; 8022*4eaa4710SRishi Srivatsavai break; 8023*4eaa4710SRishi Srivatsavai case 't': 8024*4eaa4710SRishi Srivatsavai if (op_mode != bridgeMode && op_mode != trillMode) 8025*4eaa4710SRishi Srivatsavai die("-t is incompatible with -f or -l"); 8026*4eaa4710SRishi Srivatsavai op_mode = trillMode; 8027*4eaa4710SRishi Srivatsavai break; 8028*4eaa4710SRishi Srivatsavai default: 8029*4eaa4710SRishi Srivatsavai die_opterr(optopt, option, use); 8030*4eaa4710SRishi Srivatsavai break; 8031*4eaa4710SRishi Srivatsavai } 8032*4eaa4710SRishi Srivatsavai } 8033*4eaa4710SRishi Srivatsavai 8034*4eaa4710SRishi Srivatsavai if (interval != 0 && !brstate.show_stats) 8035*4eaa4710SRishi Srivatsavai die("the -i option can be used only with -s"); 8036*4eaa4710SRishi Srivatsavai 8037*4eaa4710SRishi Srivatsavai if ((op_mode == fwdMode || op_mode == trillMode) && brstate.show_stats) 8038*4eaa4710SRishi Srivatsavai die("the -f/-t and -s options cannot be used together"); 8039*4eaa4710SRishi Srivatsavai 8040*4eaa4710SRishi Srivatsavai /* get the bridge name (optional last argument) */ 8041*4eaa4710SRishi Srivatsavai if (optind == (argc-1)) { 8042*4eaa4710SRishi Srivatsavai char lname[MAXLINKNAMELEN]; 8043*4eaa4710SRishi Srivatsavai uint32_t lnkflg; 8044*4eaa4710SRishi Srivatsavai datalink_class_t class; 8045*4eaa4710SRishi Srivatsavai 8046*4eaa4710SRishi Srivatsavai brstate.bridge = argv[optind]; 8047*4eaa4710SRishi Srivatsavai (void) snprintf(lname, sizeof (lname), "%s0", brstate.bridge); 8048*4eaa4710SRishi Srivatsavai if ((status = dladm_name2info(handle, lname, &linkid, &lnkflg, 8049*4eaa4710SRishi Srivatsavai &class, NULL)) != DLADM_STATUS_OK) { 8050*4eaa4710SRishi Srivatsavai die_dlerr(status, "bridge %s is not valid", 8051*4eaa4710SRishi Srivatsavai brstate.bridge); 8052*4eaa4710SRishi Srivatsavai } 8053*4eaa4710SRishi Srivatsavai 8054*4eaa4710SRishi Srivatsavai if (class != DATALINK_CLASS_BRIDGE) 8055*4eaa4710SRishi Srivatsavai die("%s is not a bridge", brstate.bridge); 8056*4eaa4710SRishi Srivatsavai 8057*4eaa4710SRishi Srivatsavai if (!(lnkflg & flags)) { 8058*4eaa4710SRishi Srivatsavai die_dlerr(DLADM_STATUS_BADARG, 8059*4eaa4710SRishi Srivatsavai "bridge %s is temporarily removed", brstate.bridge); 8060*4eaa4710SRishi Srivatsavai } 8061*4eaa4710SRishi Srivatsavai } else if (optind != argc) { 8062*4eaa4710SRishi Srivatsavai usage(); 8063*4eaa4710SRishi Srivatsavai } else if (op_mode != bridgeMode) { 8064*4eaa4710SRishi Srivatsavai die("bridge name required for -l, -f, or -t"); 8065*4eaa4710SRishi Srivatsavai return; 8066*4eaa4710SRishi Srivatsavai } 8067*4eaa4710SRishi Srivatsavai 8068*4eaa4710SRishi Srivatsavai brstate.state.ls_parsable = parsable; 8069*4eaa4710SRishi Srivatsavai brstate.state.ls_flags = flags; 8070*4eaa4710SRishi Srivatsavai brstate.state.ls_firstonly = (interval != 0); 8071*4eaa4710SRishi Srivatsavai 8072*4eaa4710SRishi Srivatsavai switch (op_mode) { 8073*4eaa4710SRishi Srivatsavai case bridgeMode: 8074*4eaa4710SRishi Srivatsavai if (brstate.show_stats) { 8075*4eaa4710SRishi Srivatsavai default_str = default_statfields; 8076*4eaa4710SRishi Srivatsavai all_str = all_statfields; 8077*4eaa4710SRishi Srivatsavai field_arr = bridge_statfields; 8078*4eaa4710SRishi Srivatsavai } else { 8079*4eaa4710SRishi Srivatsavai default_str = default_fields; 8080*4eaa4710SRishi Srivatsavai all_str = all_fields; 8081*4eaa4710SRishi Srivatsavai field_arr = bridge_fields; 8082*4eaa4710SRishi Srivatsavai } 8083*4eaa4710SRishi Srivatsavai break; 8084*4eaa4710SRishi Srivatsavai 8085*4eaa4710SRishi Srivatsavai case linkMode: 8086*4eaa4710SRishi Srivatsavai if (brstate.show_stats) { 8087*4eaa4710SRishi Srivatsavai default_str = default_link_statfields; 8088*4eaa4710SRishi Srivatsavai all_str = all_link_statfields; 8089*4eaa4710SRishi Srivatsavai field_arr = bridge_link_statfields; 8090*4eaa4710SRishi Srivatsavai } else { 8091*4eaa4710SRishi Srivatsavai default_str = default_link_fields; 8092*4eaa4710SRishi Srivatsavai all_str = all_link_fields; 8093*4eaa4710SRishi Srivatsavai field_arr = bridge_link_fields; 8094*4eaa4710SRishi Srivatsavai } 8095*4eaa4710SRishi Srivatsavai break; 8096*4eaa4710SRishi Srivatsavai 8097*4eaa4710SRishi Srivatsavai case fwdMode: 8098*4eaa4710SRishi Srivatsavai default_str = all_str = default_fwd_fields; 8099*4eaa4710SRishi Srivatsavai field_arr = bridge_fwd_fields; 8100*4eaa4710SRishi Srivatsavai break; 8101*4eaa4710SRishi Srivatsavai 8102*4eaa4710SRishi Srivatsavai case trillMode: 8103*4eaa4710SRishi Srivatsavai default_str = all_str = default_trill_fields; 8104*4eaa4710SRishi Srivatsavai field_arr = bridge_trill_fields; 8105*4eaa4710SRishi Srivatsavai break; 8106*4eaa4710SRishi Srivatsavai } 8107*4eaa4710SRishi Srivatsavai 8108*4eaa4710SRishi Srivatsavai if (fields_str == NULL) 8109*4eaa4710SRishi Srivatsavai fields_str = default_str; 8110*4eaa4710SRishi Srivatsavai else if (strcasecmp(fields_str, "all") == 0) 8111*4eaa4710SRishi Srivatsavai fields_str = all_str; 8112*4eaa4710SRishi Srivatsavai 8113*4eaa4710SRishi Srivatsavai if (parsable) 8114*4eaa4710SRishi Srivatsavai ofmtflags |= OFMT_PARSABLE; 8115*4eaa4710SRishi Srivatsavai oferr = ofmt_open(fields_str, field_arr, ofmtflags, 0, &ofmt); 8116*4eaa4710SRishi Srivatsavai dladm_ofmt_check(oferr, brstate.state.ls_parsable, ofmt); 8117*4eaa4710SRishi Srivatsavai brstate.state.ls_ofmt = ofmt; 8118*4eaa4710SRishi Srivatsavai 8119*4eaa4710SRishi Srivatsavai for (;;) { 8120*4eaa4710SRishi Srivatsavai brstate.state.ls_donefirst = B_FALSE; 8121*4eaa4710SRishi Srivatsavai switch (op_mode) { 8122*4eaa4710SRishi Srivatsavai case bridgeMode: 8123*4eaa4710SRishi Srivatsavai if (linkid == DATALINK_ALL_LINKID) { 8124*4eaa4710SRishi Srivatsavai (void) dladm_walk_datalink_id(show_bridge, 8125*4eaa4710SRishi Srivatsavai handle, &brstate, DATALINK_CLASS_BRIDGE, 8126*4eaa4710SRishi Srivatsavai DATALINK_ANY_MEDIATYPE, flags); 8127*4eaa4710SRishi Srivatsavai } else { 8128*4eaa4710SRishi Srivatsavai (void) show_bridge(handle, linkid, &brstate); 8129*4eaa4710SRishi Srivatsavai if (brstate.state.ls_status != 8130*4eaa4710SRishi Srivatsavai DLADM_STATUS_OK) { 8131*4eaa4710SRishi Srivatsavai die_dlerr(brstate.state.ls_status, 8132*4eaa4710SRishi Srivatsavai "failed to show bridge %s", 8133*4eaa4710SRishi Srivatsavai brstate.bridge); 8134*4eaa4710SRishi Srivatsavai } 8135*4eaa4710SRishi Srivatsavai } 8136*4eaa4710SRishi Srivatsavai break; 8137*4eaa4710SRishi Srivatsavai 8138*4eaa4710SRishi Srivatsavai case linkMode: { 8139*4eaa4710SRishi Srivatsavai datalink_id_t *dlp; 8140*4eaa4710SRishi Srivatsavai uint_t i, nlinks; 8141*4eaa4710SRishi Srivatsavai 8142*4eaa4710SRishi Srivatsavai dlp = dladm_bridge_get_portlist(brstate.bridge, 8143*4eaa4710SRishi Srivatsavai &nlinks); 8144*4eaa4710SRishi Srivatsavai if (dlp != NULL) { 8145*4eaa4710SRishi Srivatsavai for (i = 0; i < nlinks; i++) 8146*4eaa4710SRishi Srivatsavai show_bridge_link(dlp[i], &brstate); 8147*4eaa4710SRishi Srivatsavai dladm_bridge_free_portlist(dlp); 8148*4eaa4710SRishi Srivatsavai } else if (errno == ENOENT) { 8149*4eaa4710SRishi Srivatsavai /* bridge not running; iterate on libdladm */ 8150*4eaa4710SRishi Srivatsavai (void) dladm_walk_datalink_id( 8151*4eaa4710SRishi Srivatsavai show_bridge_link_walk, handle, 8152*4eaa4710SRishi Srivatsavai &brstate, DATALINK_CLASS_PHYS | 8153*4eaa4710SRishi Srivatsavai DATALINK_CLASS_AGGR | 8154*4eaa4710SRishi Srivatsavai DATALINK_CLASS_ETHERSTUB, 8155*4eaa4710SRishi Srivatsavai DATALINK_ANY_MEDIATYPE, flags); 8156*4eaa4710SRishi Srivatsavai } else { 8157*4eaa4710SRishi Srivatsavai die("unable to get port list for bridge %s: %s", 8158*4eaa4710SRishi Srivatsavai brstate.bridge, strerror(errno)); 8159*4eaa4710SRishi Srivatsavai } 8160*4eaa4710SRishi Srivatsavai break; 8161*4eaa4710SRishi Srivatsavai } 8162*4eaa4710SRishi Srivatsavai 8163*4eaa4710SRishi Srivatsavai case fwdMode: { 8164*4eaa4710SRishi Srivatsavai bridge_listfwd_t *blf; 8165*4eaa4710SRishi Srivatsavai uint_t i, nfwd; 8166*4eaa4710SRishi Srivatsavai 8167*4eaa4710SRishi Srivatsavai blf = dladm_bridge_get_fwdtable(handle, brstate.bridge, 8168*4eaa4710SRishi Srivatsavai &nfwd); 8169*4eaa4710SRishi Srivatsavai if (blf == NULL) { 8170*4eaa4710SRishi Srivatsavai die("unable to get forwarding entries for " 8171*4eaa4710SRishi Srivatsavai "bridge %s", brstate.bridge); 8172*4eaa4710SRishi Srivatsavai } else { 8173*4eaa4710SRishi Srivatsavai for (i = 0; i < nfwd; i++) 8174*4eaa4710SRishi Srivatsavai show_bridge_fwd(handle, blf + i, 8175*4eaa4710SRishi Srivatsavai &brstate.state); 8176*4eaa4710SRishi Srivatsavai dladm_bridge_free_fwdtable(blf); 8177*4eaa4710SRishi Srivatsavai } 8178*4eaa4710SRishi Srivatsavai break; 8179*4eaa4710SRishi Srivatsavai } 8180*4eaa4710SRishi Srivatsavai 8181*4eaa4710SRishi Srivatsavai case trillMode: { 8182*4eaa4710SRishi Srivatsavai trill_listnick_t *tln; 8183*4eaa4710SRishi Srivatsavai uint_t i, nnick; 8184*4eaa4710SRishi Srivatsavai 8185*4eaa4710SRishi Srivatsavai tln = dladm_bridge_get_trillnick(brstate.bridge, 8186*4eaa4710SRishi Srivatsavai &nnick); 8187*4eaa4710SRishi Srivatsavai if (tln == NULL) { 8188*4eaa4710SRishi Srivatsavai if (errno == ENOENT) 8189*4eaa4710SRishi Srivatsavai die("bridge %s is not running TRILL", 8190*4eaa4710SRishi Srivatsavai brstate.bridge); 8191*4eaa4710SRishi Srivatsavai else 8192*4eaa4710SRishi Srivatsavai die("unable to get TRILL nickname " 8193*4eaa4710SRishi Srivatsavai "entries for bridge %s", 8194*4eaa4710SRishi Srivatsavai brstate.bridge); 8195*4eaa4710SRishi Srivatsavai } else { 8196*4eaa4710SRishi Srivatsavai for (i = 0; i < nnick; i++) 8197*4eaa4710SRishi Srivatsavai show_bridge_trillnick(tln + i, 8198*4eaa4710SRishi Srivatsavai &brstate.state); 8199*4eaa4710SRishi Srivatsavai dladm_bridge_free_trillnick(tln); 8200*4eaa4710SRishi Srivatsavai } 8201*4eaa4710SRishi Srivatsavai break; 8202*4eaa4710SRishi Srivatsavai } 8203*4eaa4710SRishi Srivatsavai } 8204*4eaa4710SRishi Srivatsavai if (interval == 0) 8205*4eaa4710SRishi Srivatsavai break; 8206*4eaa4710SRishi Srivatsavai (void) sleep(interval); 8207*4eaa4710SRishi Srivatsavai } 8208*4eaa4710SRishi Srivatsavai } 8209*4eaa4710SRishi Srivatsavai 8210d62bc4baSyz147064 /* 8211d62bc4baSyz147064 * "-R" option support. It is used for live upgrading. Append dladm commands 8212d62bc4baSyz147064 * to a upgrade script which will be run when the alternative root boots up: 8213d62bc4baSyz147064 * 8214b9e076dcSyz147064 * - If the /etc/dladm/datalink.conf file exists on the alternative root, 8215b9e076dcSyz147064 * append dladm commands to the <altroot>/var/svc/profile/upgrade_datalink 8216b9e076dcSyz147064 * script. This script will be run as part of the network/physical service. 8217b9e076dcSyz147064 * We cannot defer this to /var/svc/profile/upgrade because then the 8218b9e076dcSyz147064 * configuration will not be able to take effect before network/physical 8219b9e076dcSyz147064 * plumbs various interfaces. 8220d62bc4baSyz147064 * 8221b9e076dcSyz147064 * - If the /etc/dladm/datalink.conf file does not exist on the alternative 8222b9e076dcSyz147064 * root, append dladm commands to the <altroot>/var/svc/profile/upgrade script, 8223b9e076dcSyz147064 * which will be run in the manifest-import service. 8224d62bc4baSyz147064 * 8225d62bc4baSyz147064 * Note that the SMF team is considering to move the manifest-import service 8226d62bc4baSyz147064 * to be run at the very begining of boot. Once that is done, the need for 8227d62bc4baSyz147064 * the /var/svc/profile/upgrade_datalink script will not exist any more. 8228d62bc4baSyz147064 */ 8229d62bc4baSyz147064 static void 8230d62bc4baSyz147064 altroot_cmd(char *altroot, int argc, char *argv[]) 8231d62bc4baSyz147064 { 8232d62bc4baSyz147064 char path[MAXPATHLEN]; 8233d62bc4baSyz147064 struct stat stbuf; 8234d62bc4baSyz147064 FILE *fp; 8235d62bc4baSyz147064 int i; 8236d62bc4baSyz147064 8237d62bc4baSyz147064 /* 8238b9e076dcSyz147064 * Check for the existence of the /etc/dladm/datalink.conf 8239b9e076dcSyz147064 * configuration file, and determine the name of script file. 8240d62bc4baSyz147064 */ 8241b9e076dcSyz147064 (void) snprintf(path, MAXPATHLEN, "/%s/etc/dladm/datalink.conf", 8242b9e076dcSyz147064 altroot); 8243d62bc4baSyz147064 if (stat(path, &stbuf) < 0) { 8244d62bc4baSyz147064 (void) snprintf(path, MAXPATHLEN, "/%s/%s", altroot, 8245d62bc4baSyz147064 SMF_UPGRADE_FILE); 8246d62bc4baSyz147064 } else { 8247d62bc4baSyz147064 (void) snprintf(path, MAXPATHLEN, "/%s/%s", altroot, 8248d62bc4baSyz147064 SMF_UPGRADEDATALINK_FILE); 8249d62bc4baSyz147064 } 8250d62bc4baSyz147064 8251d62bc4baSyz147064 if ((fp = fopen(path, "a+")) == NULL) 8252d62bc4baSyz147064 die("operation not supported on %s", altroot); 8253d62bc4baSyz147064 8254d62bc4baSyz147064 (void) fprintf(fp, "/sbin/dladm "); 8255d62bc4baSyz147064 for (i = 0; i < argc; i++) { 8256d62bc4baSyz147064 /* 8257d62bc4baSyz147064 * Directly write to the file if it is not the "-R <altroot>" 8258d62bc4baSyz147064 * option. In which case, skip it. 8259d62bc4baSyz147064 */ 8260d62bc4baSyz147064 if (strcmp(argv[i], "-R") != 0) 8261d62bc4baSyz147064 (void) fprintf(fp, "%s ", argv[i]); 8262d62bc4baSyz147064 else 8263d62bc4baSyz147064 i ++; 8264d62bc4baSyz147064 } 8265d62bc4baSyz147064 (void) fprintf(fp, "%s\n", SMF_DLADM_UPGRADE_MSG); 8266d62bc4baSyz147064 (void) fclose(fp); 82674ac67f02SAnurag S. Maskey dladm_close(handle); 8268d62bc4baSyz147064 exit(0); 8269d62bc4baSyz147064 } 8270d62bc4baSyz147064 8271d62bc4baSyz147064 /* 8272d62bc4baSyz147064 * Convert the string to an integer. Note that the string must not have any 8273d62bc4baSyz147064 * trailing non-integer characters. 8274d62bc4baSyz147064 */ 827533343a97Smeem static boolean_t 827633343a97Smeem str2int(const char *str, int *valp) 827733343a97Smeem { 827833343a97Smeem int val; 827933343a97Smeem char *endp = NULL; 828033343a97Smeem 828133343a97Smeem errno = 0; 828233343a97Smeem val = strtol(str, &endp, 10); 828333343a97Smeem if (errno != 0 || *endp != '\0') 828433343a97Smeem return (B_FALSE); 828533343a97Smeem 828633343a97Smeem *valp = val; 828733343a97Smeem return (B_TRUE); 828833343a97Smeem } 828933343a97Smeem 829033343a97Smeem /* PRINTFLIKE1 */ 829133343a97Smeem static void 829233343a97Smeem warn(const char *format, ...) 829333343a97Smeem { 829433343a97Smeem va_list alist; 829533343a97Smeem 829633343a97Smeem format = gettext(format); 829733343a97Smeem (void) fprintf(stderr, "%s: warning: ", progname); 829833343a97Smeem 829933343a97Smeem va_start(alist, format); 830033343a97Smeem (void) vfprintf(stderr, format, alist); 830133343a97Smeem va_end(alist); 830233343a97Smeem 830333343a97Smeem (void) putchar('\n'); 830433343a97Smeem } 830533343a97Smeem 830633343a97Smeem /* PRINTFLIKE2 */ 830733343a97Smeem static void 830833343a97Smeem warn_dlerr(dladm_status_t err, const char *format, ...) 830933343a97Smeem { 831033343a97Smeem va_list alist; 831133343a97Smeem char errmsg[DLADM_STRSIZE]; 831233343a97Smeem 831333343a97Smeem format = gettext(format); 831433343a97Smeem (void) fprintf(stderr, gettext("%s: warning: "), progname); 831533343a97Smeem 831633343a97Smeem va_start(alist, format); 831733343a97Smeem (void) vfprintf(stderr, format, alist); 831833343a97Smeem va_end(alist); 831933343a97Smeem (void) fprintf(stderr, ": %s\n", dladm_status2str(err, errmsg)); 832033343a97Smeem } 832133343a97Smeem 83224ac67f02SAnurag S. Maskey /* 83234ac67f02SAnurag S. Maskey * Also closes the dladm handle if it is not NULL. 83244ac67f02SAnurag S. Maskey */ 832533343a97Smeem /* PRINTFLIKE2 */ 832633343a97Smeem static void 832733343a97Smeem die_dlerr(dladm_status_t err, const char *format, ...) 832833343a97Smeem { 832933343a97Smeem va_list alist; 833033343a97Smeem char errmsg[DLADM_STRSIZE]; 833133343a97Smeem 833233343a97Smeem format = gettext(format); 833333343a97Smeem (void) fprintf(stderr, "%s: ", progname); 833433343a97Smeem 833533343a97Smeem va_start(alist, format); 833633343a97Smeem (void) vfprintf(stderr, format, alist); 833733343a97Smeem va_end(alist); 833833343a97Smeem (void) fprintf(stderr, ": %s\n", dladm_status2str(err, errmsg)); 833933343a97Smeem 83404ac67f02SAnurag S. Maskey /* close dladm handle if it was opened */ 83414ac67f02SAnurag S. Maskey if (handle != NULL) 83424ac67f02SAnurag S. Maskey dladm_close(handle); 83434ac67f02SAnurag S. Maskey 834433343a97Smeem exit(EXIT_FAILURE); 834533343a97Smeem } 834633343a97Smeem 834733343a97Smeem /* PRINTFLIKE1 */ 834833343a97Smeem static void 834933343a97Smeem die(const char *format, ...) 835033343a97Smeem { 835133343a97Smeem va_list alist; 835233343a97Smeem 835333343a97Smeem format = gettext(format); 835433343a97Smeem (void) fprintf(stderr, "%s: ", progname); 835533343a97Smeem 835633343a97Smeem va_start(alist, format); 835733343a97Smeem (void) vfprintf(stderr, format, alist); 835833343a97Smeem va_end(alist); 835933343a97Smeem 836033343a97Smeem (void) putchar('\n'); 83614ac67f02SAnurag S. Maskey 83624ac67f02SAnurag S. Maskey /* close dladm handle if it was opened */ 83634ac67f02SAnurag S. Maskey if (handle != NULL) 83644ac67f02SAnurag S. Maskey dladm_close(handle); 83654ac67f02SAnurag S. Maskey 836633343a97Smeem exit(EXIT_FAILURE); 836733343a97Smeem } 836833343a97Smeem 836933343a97Smeem static void 837033343a97Smeem die_optdup(int opt) 837133343a97Smeem { 837233343a97Smeem die("the option -%c cannot be specified more than once", opt); 837333343a97Smeem } 837433343a97Smeem 837533343a97Smeem static void 83768d5c46e6Sam223141 die_opterr(int opt, int opterr, const char *usage) 837733343a97Smeem { 837833343a97Smeem switch (opterr) { 837933343a97Smeem case ':': 83808d5c46e6Sam223141 die("option '-%c' requires a value\nusage: %s", opt, 83818d5c46e6Sam223141 gettext(usage)); 838233343a97Smeem break; 838333343a97Smeem case '?': 838433343a97Smeem default: 83858d5c46e6Sam223141 die("unrecognized option '-%c'\nusage: %s", opt, 83868d5c46e6Sam223141 gettext(usage)); 838733343a97Smeem break; 83880ba2cbe9Sxc151355 } 83890ba2cbe9Sxc151355 } 8390e7801d59Ssowmini 8391e7801d59Ssowmini static void 83924784fcbdSSowmini Varadhan show_ether_xprop(void *arg, dladm_ether_info_t *eattr) 8393e7801d59Ssowmini { 8394e7801d59Ssowmini print_ether_state_t *statep = arg; 8395e7801d59Ssowmini ether_fields_buf_t ebuf; 83964784fcbdSSowmini Varadhan int i; 8397e7801d59Ssowmini 83984784fcbdSSowmini Varadhan for (i = CAPABLE; i <= PEERADV; i++) { 8399e7801d59Ssowmini bzero(&ebuf, sizeof (ebuf)); 84004784fcbdSSowmini Varadhan (void) strlcpy(ebuf.eth_ptype, ptype[i], 84014784fcbdSSowmini Varadhan sizeof (ebuf.eth_ptype)); 84024784fcbdSSowmini Varadhan (void) dladm_ether_autoneg2str(ebuf.eth_autoneg, 84034784fcbdSSowmini Varadhan sizeof (ebuf.eth_autoneg), eattr, i); 84044784fcbdSSowmini Varadhan (void) dladm_ether_spdx2str(ebuf.eth_spdx, 84054784fcbdSSowmini Varadhan sizeof (ebuf.eth_spdx), eattr, i); 84064784fcbdSSowmini Varadhan (void) dladm_ether_pause2str(ebuf.eth_pause, 84074784fcbdSSowmini Varadhan sizeof (ebuf.eth_pause), eattr, i); 84084784fcbdSSowmini Varadhan (void) strlcpy(ebuf.eth_rem_fault, 84094784fcbdSSowmini Varadhan (eattr->lei_attr[i].le_fault ? "fault" : "none"), 84104784fcbdSSowmini Varadhan sizeof (ebuf.eth_rem_fault)); 84118002d411SSowmini Varadhan ofmt_print(statep->es_ofmt, &ebuf); 8412e7801d59Ssowmini } 8413e7801d59Ssowmini 8414e7801d59Ssowmini } 8415e7801d59Ssowmini 8416e7801d59Ssowmini static boolean_t 8417e7801d59Ssowmini link_is_ether(const char *link, datalink_id_t *linkid) 8418e7801d59Ssowmini { 8419e7801d59Ssowmini uint32_t media; 8420e7801d59Ssowmini datalink_class_t class; 8421e7801d59Ssowmini 84224ac67f02SAnurag S. Maskey if (dladm_name2info(handle, link, linkid, NULL, &class, &media) == 8423e7801d59Ssowmini DLADM_STATUS_OK) { 8424e7801d59Ssowmini if (class == DATALINK_CLASS_PHYS && media == DL_ETHER) 8425e7801d59Ssowmini return (B_TRUE); 8426e7801d59Ssowmini } 8427e7801d59Ssowmini return (B_FALSE); 8428e7801d59Ssowmini } 84298002d411SSowmini Varadhan 84308002d411SSowmini Varadhan /* 84318002d411SSowmini Varadhan * default output callback function that, when invoked, 84328002d411SSowmini Varadhan * prints string which is offset by ofmt_arg->ofmt_id within buf. 84338002d411SSowmini Varadhan */ 84348002d411SSowmini Varadhan static boolean_t 84358002d411SSowmini Varadhan print_default_cb(ofmt_arg_t *ofarg, char *buf, uint_t bufsize) 84368002d411SSowmini Varadhan { 84378002d411SSowmini Varadhan char *value; 84388002d411SSowmini Varadhan 84398002d411SSowmini Varadhan value = (char *)ofarg->ofmt_cbarg + ofarg->ofmt_id; 84408002d411SSowmini Varadhan (void) strlcpy(buf, value, bufsize); 84418002d411SSowmini Varadhan return (B_TRUE); 84428002d411SSowmini Varadhan } 84438002d411SSowmini Varadhan 84448002d411SSowmini Varadhan static void 84458002d411SSowmini Varadhan dladm_ofmt_check(ofmt_status_t oferr, boolean_t parsable, 84468002d411SSowmini Varadhan ofmt_handle_t ofmt) 84478002d411SSowmini Varadhan { 84488002d411SSowmini Varadhan char buf[OFMT_BUFSIZE]; 84498002d411SSowmini Varadhan 84508002d411SSowmini Varadhan if (oferr == OFMT_SUCCESS) 84518002d411SSowmini Varadhan return; 84528002d411SSowmini Varadhan (void) ofmt_strerror(ofmt, oferr, buf, sizeof (buf)); 84538002d411SSowmini Varadhan /* 84548002d411SSowmini Varadhan * All errors are considered fatal in parsable mode. 84558002d411SSowmini Varadhan * NOMEM errors are always fatal, regardless of mode. 84568002d411SSowmini Varadhan * For other errors, we print diagnostics in human-readable 84578002d411SSowmini Varadhan * mode and processs what we can. 84588002d411SSowmini Varadhan */ 84598002d411SSowmini Varadhan if (parsable || oferr == OFMT_ENOFIELDS) { 84608002d411SSowmini Varadhan ofmt_close(ofmt); 84618002d411SSowmini Varadhan die(buf); 84628002d411SSowmini Varadhan } else { 84638002d411SSowmini Varadhan warn(buf); 84648002d411SSowmini Varadhan } 84658002d411SSowmini Varadhan } 8466