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 /* 221cfa752fSRamaswamy Tummala * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 237c478bd9Sstevel@tonic-gate */ 247c478bd9Sstevel@tonic-gate 257c478bd9Sstevel@tonic-gate #include <stdio.h> 260ba2cbe9Sxc151355 #include <ctype.h> 274eaa4710SRishi Srivatsavai #include <dlfcn.h> 287c478bd9Sstevel@tonic-gate #include <locale.h> 290ba2cbe9Sxc151355 #include <signal.h> 307c478bd9Sstevel@tonic-gate #include <stdarg.h> 317c478bd9Sstevel@tonic-gate #include <stdlib.h> 327c478bd9Sstevel@tonic-gate #include <fcntl.h> 337c478bd9Sstevel@tonic-gate #include <string.h> 347c478bd9Sstevel@tonic-gate #include <stropts.h> 35d62bc4baSyz147064 #include <sys/stat.h> 367c478bd9Sstevel@tonic-gate #include <errno.h> 377c478bd9Sstevel@tonic-gate #include <kstat.h> 387c478bd9Sstevel@tonic-gate #include <strings.h> 397c478bd9Sstevel@tonic-gate #include <getopt.h> 407c478bd9Sstevel@tonic-gate #include <unistd.h> 41cd93090eSericheng #include <priv.h> 422b24ab6bSSebastien Roy #include <limits.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> 571cfa752fSRamaswamy Tummala #include <libdlib.h> 584784fcbdSSowmini Varadhan #include <libdlether.h> 592b24ab6bSSebastien Roy #include <libdliptun.h> 60b509e89bSRishi Srivatsavai #include <libdlsim.h> 614eaa4710SRishi Srivatsavai #include <libdlbridge.h> 620ba2cbe9Sxc151355 #include <libinetutil.h> 631cb875aeSCathy Zhou #include <libvrrpadm.h> 640ba2cbe9Sxc151355 #include <bsm/adt.h> 650ba2cbe9Sxc151355 #include <bsm/adt_event.h> 66da14cebeSEric Cheng #include <libdlvnic.h> 67da14cebeSEric Cheng #include <sys/types.h> 68da14cebeSEric Cheng #include <sys/socket.h> 691cfa752fSRamaswamy Tummala #include <sys/ib/ib_types.h> 70da14cebeSEric Cheng #include <sys/processor.h> 71da14cebeSEric Cheng #include <netinet/in.h> 72da14cebeSEric Cheng #include <arpa/inet.h> 73da14cebeSEric Cheng #include <net/if_types.h> 74e7801d59Ssowmini #include <stddef.h> 754eaa4710SRishi Srivatsavai #include <stp_in.h> 768002d411SSowmini Varadhan #include <ofmt.h> 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate #define MAXPORT 256 79da14cebeSEric Cheng #define MAXVNIC 256 80d62bc4baSyz147064 #define BUFLEN(lim, ptr) (((lim) > (ptr)) ? ((lim) - (ptr)) : 0) 81d62bc4baSyz147064 #define MAXLINELEN 1024 82d62bc4baSyz147064 #define SMF_UPGRADE_FILE "/var/svc/profile/upgrade" 83d62bc4baSyz147064 #define SMF_UPGRADEDATALINK_FILE "/var/svc/profile/upgrade_datalink" 84d62bc4baSyz147064 #define SMF_DLADM_UPGRADE_MSG " # added by dladm(1M)" 858002d411SSowmini Varadhan #define DLADM_DEFAULT_COL 80 867c478bd9Sstevel@tonic-gate 878002d411SSowmini Varadhan /* 888002d411SSowmini Varadhan * used by the wifi show-* commands to set up ofmt_field_t structures. 898002d411SSowmini Varadhan */ 90e7801d59Ssowmini #define WIFI_CMD_SCAN 0x00000001 91e7801d59Ssowmini #define WIFI_CMD_SHOW 0x00000002 92e7801d59Ssowmini #define WIFI_CMD_ALL (WIFI_CMD_SCAN | WIFI_CMD_SHOW) 93e7801d59Ssowmini 944eaa4710SRishi Srivatsavai /* No larger than pktsum_t */ 954eaa4710SRishi Srivatsavai typedef struct brsum_s { 964eaa4710SRishi Srivatsavai uint64_t drops; 974eaa4710SRishi Srivatsavai uint64_t forward_dir; 984eaa4710SRishi Srivatsavai uint64_t forward_mb; 994eaa4710SRishi Srivatsavai uint64_t forward_unk; 1004eaa4710SRishi Srivatsavai uint64_t recv; 1014eaa4710SRishi Srivatsavai uint64_t sent; 1024eaa4710SRishi Srivatsavai } brsum_t; 1034eaa4710SRishi Srivatsavai 1044eaa4710SRishi Srivatsavai /* No larger than pktsum_t */ 1054eaa4710SRishi Srivatsavai typedef struct brlsum_s { 1064eaa4710SRishi Srivatsavai uint32_t cfgbpdu; 1074eaa4710SRishi Srivatsavai uint32_t tcnbpdu; 1084eaa4710SRishi Srivatsavai uint32_t rstpbpdu; 1094eaa4710SRishi Srivatsavai uint32_t txbpdu; 1104eaa4710SRishi Srivatsavai uint64_t drops; 1114eaa4710SRishi Srivatsavai uint64_t recv; 1124eaa4710SRishi Srivatsavai uint64_t xmit; 1134eaa4710SRishi Srivatsavai } brlsum_t; 1144eaa4710SRishi Srivatsavai 115d62bc4baSyz147064 typedef struct show_state { 1167c478bd9Sstevel@tonic-gate boolean_t ls_firstonly; 1177c478bd9Sstevel@tonic-gate boolean_t ls_donefirst; 1187c478bd9Sstevel@tonic-gate pktsum_t ls_prevstats; 119d62bc4baSyz147064 uint32_t ls_flags; 120d62bc4baSyz147064 dladm_status_t ls_status; 1218002d411SSowmini Varadhan ofmt_handle_t ls_ofmt; 1228002d411SSowmini Varadhan boolean_t ls_parsable; 123da14cebeSEric Cheng boolean_t ls_mac; 124da14cebeSEric Cheng boolean_t ls_hwgrp; 125d62bc4baSyz147064 } show_state_t; 1267c478bd9Sstevel@tonic-gate 1277c478bd9Sstevel@tonic-gate typedef struct show_grp_state { 128e7801d59Ssowmini pktsum_t gs_prevstats[MAXPORT]; 129e7801d59Ssowmini uint32_t gs_flags; 130e7801d59Ssowmini dladm_status_t gs_status; 1318002d411SSowmini Varadhan boolean_t gs_parsable; 1327c478bd9Sstevel@tonic-gate boolean_t gs_lacp; 133d62bc4baSyz147064 boolean_t gs_extended; 1347c478bd9Sstevel@tonic-gate boolean_t gs_stats; 1357c478bd9Sstevel@tonic-gate boolean_t gs_firstonly; 136d62bc4baSyz147064 boolean_t gs_donefirst; 1378002d411SSowmini Varadhan ofmt_handle_t gs_ofmt; 1387c478bd9Sstevel@tonic-gate } show_grp_state_t; 1397c478bd9Sstevel@tonic-gate 140da14cebeSEric Cheng typedef struct show_vnic_state { 141da14cebeSEric Cheng datalink_id_t vs_vnic_id; 142da14cebeSEric Cheng datalink_id_t vs_link_id; 143da14cebeSEric Cheng char vs_vnic[MAXLINKNAMELEN]; 144da14cebeSEric Cheng char vs_link[MAXLINKNAMELEN]; 1458002d411SSowmini Varadhan boolean_t vs_parsable; 146da14cebeSEric Cheng boolean_t vs_found; 147da14cebeSEric Cheng boolean_t vs_firstonly; 148da14cebeSEric Cheng boolean_t vs_donefirst; 149da14cebeSEric Cheng boolean_t vs_stats; 150da14cebeSEric Cheng boolean_t vs_printstats; 151da14cebeSEric Cheng pktsum_t vs_totalstats; 152da14cebeSEric Cheng pktsum_t vs_prevstats[MAXVNIC]; 153da14cebeSEric Cheng boolean_t vs_etherstub; 154da14cebeSEric Cheng dladm_status_t vs_status; 155da14cebeSEric Cheng uint32_t vs_flags; 1568002d411SSowmini Varadhan ofmt_handle_t vs_ofmt; 157da14cebeSEric Cheng } show_vnic_state_t; 158da14cebeSEric Cheng 1591cfa752fSRamaswamy Tummala typedef struct show_part_state { 1601cfa752fSRamaswamy Tummala datalink_id_t ps_over_id; 1611cfa752fSRamaswamy Tummala char ps_part[MAXLINKNAMELEN]; 1621cfa752fSRamaswamy Tummala boolean_t ps_parsable; 1631cfa752fSRamaswamy Tummala boolean_t ps_found; 1641cfa752fSRamaswamy Tummala dladm_status_t ps_status; 1651cfa752fSRamaswamy Tummala uint32_t ps_flags; 1661cfa752fSRamaswamy Tummala ofmt_handle_t ps_ofmt; 1671cfa752fSRamaswamy Tummala } show_part_state_t; 1681cfa752fSRamaswamy Tummala 1691cfa752fSRamaswamy Tummala typedef struct show_ib_state { 1701cfa752fSRamaswamy Tummala datalink_id_t is_link_id; 1711cfa752fSRamaswamy Tummala char is_link[MAXLINKNAMELEN]; 1721cfa752fSRamaswamy Tummala boolean_t is_parsable; 1731cfa752fSRamaswamy Tummala dladm_status_t is_status; 1741cfa752fSRamaswamy Tummala uint32_t is_flags; 1751cfa752fSRamaswamy Tummala ofmt_handle_t is_ofmt; 1761cfa752fSRamaswamy Tummala } show_ib_state_t; 1771cfa752fSRamaswamy Tummala 178da14cebeSEric Cheng typedef struct show_usage_state_s { 179da14cebeSEric Cheng boolean_t us_plot; 1808002d411SSowmini Varadhan boolean_t us_parsable; 181da14cebeSEric Cheng boolean_t us_printheader; 182da14cebeSEric Cheng boolean_t us_first; 183ae6aa22aSVenugopal Iyer boolean_t us_showall; 1848002d411SSowmini Varadhan ofmt_handle_t us_ofmt; 185da14cebeSEric Cheng } show_usage_state_t; 186da14cebeSEric Cheng 1878002d411SSowmini Varadhan /* 1888002d411SSowmini Varadhan * callback functions for printing output and error diagnostics. 1898002d411SSowmini Varadhan */ 1908002d411SSowmini Varadhan static ofmt_cb_t print_default_cb, print_link_stats_cb, print_linkprop_cb; 1918002d411SSowmini Varadhan static ofmt_cb_t print_lacp_cb, print_phys_one_mac_cb; 1928002d411SSowmini Varadhan static ofmt_cb_t print_xaggr_cb, print_aggr_stats_cb; 1938002d411SSowmini Varadhan static ofmt_cb_t print_phys_one_hwgrp_cb, print_wlan_attr_cb; 1948002d411SSowmini Varadhan static ofmt_cb_t print_wifi_status_cb, print_link_attr_cb; 1958002d411SSowmini Varadhan static void dladm_ofmt_check(ofmt_status_t, boolean_t, ofmt_handle_t); 1968002d411SSowmini Varadhan 1978d5c46e6Sam223141 typedef void cmdfunc_t(int, char **, const char *); 1980ba2cbe9Sxc151355 199da14cebeSEric Cheng static cmdfunc_t do_show_link, do_show_wifi, do_show_phys; 2000ba2cbe9Sxc151355 static cmdfunc_t do_create_aggr, do_delete_aggr, do_add_aggr, do_remove_aggr; 201d62bc4baSyz147064 static cmdfunc_t do_modify_aggr, do_show_aggr, do_up_aggr; 2020ba2cbe9Sxc151355 static cmdfunc_t do_scan_wifi, do_connect_wifi, do_disconnect_wifi; 2030ba2cbe9Sxc151355 static cmdfunc_t do_show_linkprop, do_set_linkprop, do_reset_linkprop; 2040ba2cbe9Sxc151355 static cmdfunc_t do_create_secobj, do_delete_secobj, do_show_secobj; 2050ba2cbe9Sxc151355 static cmdfunc_t do_init_linkprop, do_init_secobj; 206d62bc4baSyz147064 static cmdfunc_t do_create_vlan, do_delete_vlan, do_up_vlan, do_show_vlan; 207d62bc4baSyz147064 static cmdfunc_t do_rename_link, do_delete_phys, do_init_phys; 208d62bc4baSyz147064 static cmdfunc_t do_show_linkmap; 209e7801d59Ssowmini static cmdfunc_t do_show_ether; 210da14cebeSEric Cheng static cmdfunc_t do_create_vnic, do_delete_vnic, do_show_vnic; 211da14cebeSEric Cheng static cmdfunc_t do_up_vnic; 2121cfa752fSRamaswamy Tummala static cmdfunc_t do_create_part, do_delete_part, do_show_part, do_show_ib; 2131cfa752fSRamaswamy Tummala static cmdfunc_t do_up_part; 214da14cebeSEric Cheng static cmdfunc_t do_create_etherstub, do_delete_etherstub, do_show_etherstub; 215b509e89bSRishi Srivatsavai static cmdfunc_t do_create_simnet, do_modify_simnet; 216b509e89bSRishi Srivatsavai static cmdfunc_t do_delete_simnet, do_show_simnet, do_up_simnet; 217da14cebeSEric Cheng static cmdfunc_t do_show_usage; 2184eaa4710SRishi Srivatsavai static cmdfunc_t do_create_bridge, do_modify_bridge, do_delete_bridge; 2194eaa4710SRishi Srivatsavai static cmdfunc_t do_add_bridge, do_remove_bridge, do_show_bridge; 2202b24ab6bSSebastien Roy static cmdfunc_t do_create_iptun, do_modify_iptun, do_delete_iptun; 2212b24ab6bSSebastien Roy static cmdfunc_t do_show_iptun, do_up_iptun, do_down_iptun; 222da14cebeSEric Cheng 223da14cebeSEric Cheng static void do_up_vnic_common(int, char **, const char *, boolean_t); 2247c478bd9Sstevel@tonic-gate 2251cfa752fSRamaswamy Tummala static int show_part(dladm_handle_t, datalink_id_t, void *); 2261cfa752fSRamaswamy Tummala 227d62bc4baSyz147064 static void altroot_cmd(char *, int, char **); 2284ac67f02SAnurag S. Maskey static int show_linkprop_onelink(dladm_handle_t, datalink_id_t, void *); 229f4b3ec61Sdh155122 2306be03d0bSVasumathi Sundaram - Sun Microsystems static void link_stats(datalink_id_t, uint_t, char *, show_state_t *); 231d62bc4baSyz147064 static void aggr_stats(datalink_id_t, show_grp_state_t *, uint_t); 232da14cebeSEric Cheng static void vnic_stats(show_vnic_state_t *, uint32_t); 2337c478bd9Sstevel@tonic-gate 234d62bc4baSyz147064 static int get_one_kstat(const char *, const char *, uint8_t, 235d62bc4baSyz147064 void *, boolean_t); 236ba2e4443Sseb static void get_mac_stats(const char *, pktsum_t *); 2377c478bd9Sstevel@tonic-gate static void get_link_stats(const char *, pktsum_t *); 238d62bc4baSyz147064 static uint64_t get_ifspeed(const char *, boolean_t); 239d62bc4baSyz147064 static const char *get_linkstate(const char *, boolean_t, char *); 240d62bc4baSyz147064 static const char *get_linkduplex(const char *, boolean_t, char *); 2417c478bd9Sstevel@tonic-gate 2422b24ab6bSSebastien Roy static iptun_type_t iptun_gettypebyname(char *); 2432b24ab6bSSebastien Roy static const char *iptun_gettypebyvalue(iptun_type_t); 2442b24ab6bSSebastien Roy static dladm_status_t print_iptun(dladm_handle_t, datalink_id_t, 2452b24ab6bSSebastien Roy show_state_t *); 2462b24ab6bSSebastien Roy static int print_iptun_walker(dladm_handle_t, datalink_id_t, void *); 2472b24ab6bSSebastien Roy 2484ac67f02SAnurag S. Maskey static int show_etherprop(dladm_handle_t, datalink_id_t, void *); 2494784fcbdSSowmini Varadhan static void show_ether_xprop(void *, dladm_ether_info_t *); 250e7801d59Ssowmini static boolean_t link_is_ether(const char *, datalink_id_t *); 251e7801d59Ssowmini 25233343a97Smeem static boolean_t str2int(const char *, int *); 25333343a97Smeem static void die(const char *, ...); 25433343a97Smeem static void die_optdup(int); 2558d5c46e6Sam223141 static void die_opterr(int, int, const char *); 25633343a97Smeem static void die_dlerr(dladm_status_t, const char *, ...); 25733343a97Smeem static void warn(const char *, ...); 25833343a97Smeem static void warn_dlerr(dladm_status_t, const char *, ...); 25933343a97Smeem 2607c478bd9Sstevel@tonic-gate typedef struct cmd { 2617c478bd9Sstevel@tonic-gate char *c_name; 2620ba2cbe9Sxc151355 cmdfunc_t *c_fn; 2638d5c46e6Sam223141 const char *c_usage; 2647c478bd9Sstevel@tonic-gate } cmd_t; 2657c478bd9Sstevel@tonic-gate 2667c478bd9Sstevel@tonic-gate static cmd_t cmds[] = { 2678d5c46e6Sam223141 { "rename-link", do_rename_link, 2680790b6dcSAnurag S. Maskey " rename-link <oldlink> <newlink>" }, 2690790b6dcSAnurag S. Maskey { "show-link", do_show_link, 2700790b6dcSAnurag S. Maskey " show-link [-pP] [-o <field>,..] [-s [-i <interval>]] " 2710790b6dcSAnurag S. Maskey "[<link>]\n" }, 2728d5c46e6Sam223141 { "create-aggr", do_create_aggr, 2730790b6dcSAnurag S. Maskey " create-aggr [-t] [-P <policy>] [-L <mode>] [-T <time>] " 2740790b6dcSAnurag S. Maskey "[-u <address>]\n" 2750790b6dcSAnurag S. Maskey "\t\t -l <link> [-l <link>...] <link>" }, 2768d5c46e6Sam223141 { "delete-aggr", do_delete_aggr, 2770790b6dcSAnurag S. Maskey " delete-aggr [-t] <link>" }, 2788d5c46e6Sam223141 { "add-aggr", do_add_aggr, 2790790b6dcSAnurag S. Maskey " add-aggr [-t] -l <link> [-l <link>...] <link>" }, 2808d5c46e6Sam223141 { "remove-aggr", do_remove_aggr, 2810790b6dcSAnurag S. Maskey " remove-aggr [-t] -l <link> [-l <link>...] <link>" }, 2828d5c46e6Sam223141 { "modify-aggr", do_modify_aggr, 2830790b6dcSAnurag S. Maskey " modify-aggr [-t] [-P <policy>] [-L <mode>] [-T <time>] " 2840790b6dcSAnurag S. Maskey "[-u <address>]\n" 2850790b6dcSAnurag S. Maskey "\t\t <link>" }, 2868d5c46e6Sam223141 { "show-aggr", do_show_aggr, 2870790b6dcSAnurag S. Maskey " show-aggr [-pPLx] [-o <field>,..] [-s [-i <interval>]] " 2888d5c46e6Sam223141 "[<link>]\n" }, 2898d5c46e6Sam223141 { "up-aggr", do_up_aggr, NULL }, 2908d5c46e6Sam223141 { "scan-wifi", do_scan_wifi, 2910790b6dcSAnurag S. Maskey " scan-wifi [-p] [-o <field>,...] [<link>]" }, 2928d5c46e6Sam223141 { "connect-wifi", do_connect_wifi, 2930790b6dcSAnurag S. Maskey " connect-wifi [-e <essid>] [-i <bssid>] [-k <key>,...] " 2948d5c46e6Sam223141 "[-s wep|wpa]\n" 2950790b6dcSAnurag S. Maskey "\t\t [-a open|shared] [-b bss|ibss] [-c] [-m a|b|g] " 2960790b6dcSAnurag S. Maskey "[-T <time>]\n" 2970790b6dcSAnurag S. Maskey "\t\t [<link>]" }, 2988d5c46e6Sam223141 { "disconnect-wifi", do_disconnect_wifi, 2990790b6dcSAnurag S. Maskey " disconnect-wifi [-a] [<link>]" }, 3008d5c46e6Sam223141 { "show-wifi", do_show_wifi, 3010790b6dcSAnurag S. Maskey " show-wifi [-p] [-o <field>,...] [<link>]\n" }, 3028d5c46e6Sam223141 { "set-linkprop", do_set_linkprop, 3030790b6dcSAnurag S. Maskey " set-linkprop [-t] -p <prop>=<value>[,...] <name>" }, 3048d5c46e6Sam223141 { "reset-linkprop", do_reset_linkprop, 3050790b6dcSAnurag S. Maskey " reset-linkprop [-t] [-p <prop>,...] <name>" }, 3060790b6dcSAnurag S. Maskey { "show-linkprop", do_show_linkprop, 3070790b6dcSAnurag S. Maskey " show-linkprop [-cP] [-o <field>,...] [-p <prop>,...] " 3080790b6dcSAnurag S. Maskey "<name>\n" }, 3098d5c46e6Sam223141 { "show-ether", do_show_ether, 3100790b6dcSAnurag S. Maskey " show-ether [-px][-o <field>,...] <link>\n" }, 3118d5c46e6Sam223141 { "create-secobj", do_create_secobj, 3120790b6dcSAnurag S. Maskey " create-secobj [-t] [-f <file>] -c <class> <secobj>" }, 3138d5c46e6Sam223141 { "delete-secobj", do_delete_secobj, 3140790b6dcSAnurag S. Maskey " delete-secobj [-t] <secobj>[,...]" }, 3158d5c46e6Sam223141 { "show-secobj", do_show_secobj, 3160790b6dcSAnurag S. Maskey " show-secobj [-pP] [-o <field>,...] [<secobj>,...]\n" }, 3178d5c46e6Sam223141 { "init-linkprop", do_init_linkprop, NULL }, 3188d5c46e6Sam223141 { "init-secobj", do_init_secobj, NULL }, 3198d5c46e6Sam223141 { "create-vlan", do_create_vlan, 3200790b6dcSAnurag S. Maskey " create-vlan [-ft] -l <link> -v <vid> [link]" }, 3218d5c46e6Sam223141 { "delete-vlan", do_delete_vlan, 3220790b6dcSAnurag S. Maskey " delete-vlan [-t] <link>" }, 3238d5c46e6Sam223141 { "show-vlan", do_show_vlan, 3240790b6dcSAnurag S. Maskey " show-vlan [-pP] [-o <field>,..] [<link>]\n" }, 3258d5c46e6Sam223141 { "up-vlan", do_up_vlan, NULL }, 3262b24ab6bSSebastien Roy { "create-iptun", do_create_iptun, 3272b24ab6bSSebastien Roy " create-iptun [-t] -T <type> " 3282b24ab6bSSebastien Roy "[-a {local|remote}=<addr>,...] <link>]" }, 3292b24ab6bSSebastien Roy { "delete-iptun", do_delete_iptun, 3302b24ab6bSSebastien Roy " delete-iptun [-t] <link>" }, 3312b24ab6bSSebastien Roy { "modify-iptun", do_modify_iptun, 3322b24ab6bSSebastien Roy " modify-iptun [-t] -a {local|remote}=<addr>,... <link>" }, 3332b24ab6bSSebastien Roy { "show-iptun", do_show_iptun, 3342b24ab6bSSebastien Roy " show-iptun [-pP] [-o <field>,..] [<link>]\n" }, 3352b24ab6bSSebastien Roy { "up-iptun", do_up_iptun, NULL }, 3362b24ab6bSSebastien Roy { "down-iptun", do_down_iptun, NULL }, 3378d5c46e6Sam223141 { "delete-phys", do_delete_phys, 3380790b6dcSAnurag S. Maskey " delete-phys <link>" }, 3398d5c46e6Sam223141 { "show-phys", do_show_phys, 3400790b6dcSAnurag S. Maskey " show-phys [-pP] [-o <field>,..] [-H] [<link>]\n"}, 3418d5c46e6Sam223141 { "init-phys", do_init_phys, NULL }, 342da14cebeSEric Cheng { "show-linkmap", do_show_linkmap, NULL }, 343da14cebeSEric Cheng { "create-vnic", do_create_vnic, 3440790b6dcSAnurag S. Maskey " create-vnic [-t] -l <link> [-m <value> | auto |\n" 3451cb875aeSCathy Zhou "\t\t {factory [-n <slot-id>]} | {random [-r <prefix>]} |\n" 3461cb875aeSCathy Zhou "\t\t {vrrp -V <vrid> -A {inet | inet6}} [-v <vid> [-f]]\n" 3470dc2366fSVenugopal Iyer "\t\t [-p <prop>=<value>[,...]] <vnic-link>" }, 348da14cebeSEric Cheng { "delete-vnic", do_delete_vnic, 3490790b6dcSAnurag S. Maskey " delete-vnic [-t] <vnic-link>" }, 350da14cebeSEric Cheng { "show-vnic", do_show_vnic, 3510790b6dcSAnurag S. Maskey " show-vnic [-pP] [-l <link>] [-s [-i <interval>]] " 3520790b6dcSAnurag S. Maskey "[<link>]\n" }, 353da14cebeSEric Cheng { "up-vnic", do_up_vnic, NULL }, 3541cfa752fSRamaswamy Tummala { "create-part", do_create_part, 3551cfa752fSRamaswamy Tummala " create-part [-t] [-f] -l <link> [-P <pkey>]\n" 3561cfa752fSRamaswamy Tummala "\t\t [-R <root-dir>] <part-link>" }, 3571cfa752fSRamaswamy Tummala { "delete-part", do_delete_part, 3581cfa752fSRamaswamy Tummala " delete-part [-t] [-R <root-dir>] <part-link>"}, 3591cfa752fSRamaswamy Tummala { "show-part", do_show_part, 3601cfa752fSRamaswamy Tummala " show-part [-pP] [-o <field>,...][-l <linkover>]\n" 3611cfa752fSRamaswamy Tummala "\t\t [<part-link>]" }, 3621cfa752fSRamaswamy Tummala { "show-ib", do_show_ib, 3631cfa752fSRamaswamy Tummala " show-ib [-p] [-o <field>,...] [<link>]\n" }, 3641cfa752fSRamaswamy Tummala { "up-part", do_up_part, NULL }, 365da14cebeSEric Cheng { "create-etherstub", do_create_etherstub, 3660790b6dcSAnurag S. Maskey " create-etherstub [-t] <link>" }, 367da14cebeSEric Cheng { "delete-etherstub", do_delete_etherstub, 3680790b6dcSAnurag S. Maskey " delete-etherstub [-t] <link>" }, 369da14cebeSEric Cheng { "show-etherstub", do_show_etherstub, 3700790b6dcSAnurag S. Maskey " show-etherstub [-t] [<link>]\n" }, 3710f83d385SRishi Srivatsavai { "create-simnet", do_create_simnet, NULL }, 3720f83d385SRishi Srivatsavai { "modify-simnet", do_modify_simnet, NULL }, 3730f83d385SRishi Srivatsavai { "delete-simnet", do_delete_simnet, NULL }, 3740f83d385SRishi Srivatsavai { "show-simnet", do_show_simnet, NULL }, 375b509e89bSRishi Srivatsavai { "up-simnet", do_up_simnet, NULL }, 3764eaa4710SRishi Srivatsavai { "create-bridge", do_create_bridge, 3774eaa4710SRishi Srivatsavai " create-bridge [-R <root-dir>] [-P <protect>] " 3784eaa4710SRishi Srivatsavai "[-p <priority>]\n" 3794eaa4710SRishi Srivatsavai "\t\t [-m <max-age>] [-h <hello-time>] [-d <forward-delay>]\n" 3804eaa4710SRishi Srivatsavai "\t\t [-f <force-protocol>] [-l <link>]... <bridge>" }, 3814eaa4710SRishi Srivatsavai { "modify-bridge", do_modify_bridge, 3824eaa4710SRishi Srivatsavai " modify-bridge [-R <root-dir>] [-P <protect>] " 3834eaa4710SRishi Srivatsavai "[-p <priority>]\n" 3844eaa4710SRishi Srivatsavai "\t\t [-m <max-age>] [-h <hello-time>] [-d <forward-delay>]\n" 3854eaa4710SRishi Srivatsavai "\t\t [-f <force-protocol>] <bridge>" }, 3864eaa4710SRishi Srivatsavai { "delete-bridge", do_delete_bridge, 3874eaa4710SRishi Srivatsavai " delete-bridge [-R <root-dir>] <bridge>" }, 3884eaa4710SRishi Srivatsavai { "add-bridge", do_add_bridge, 3894eaa4710SRishi Srivatsavai " add-bridge [-R <root-dir>] -l <link> [-l <link>]... " 3904eaa4710SRishi Srivatsavai "<bridge>" }, 3914eaa4710SRishi Srivatsavai { "remove-bridge", do_remove_bridge, 3924eaa4710SRishi Srivatsavai " remove-bridge [-R <root-dir>] -l <link> [-l <link>]... " 3934eaa4710SRishi Srivatsavai "<bridge>" }, 3944eaa4710SRishi Srivatsavai { "show-bridge", do_show_bridge, 3954eaa4710SRishi Srivatsavai " show-bridge [-p] [-o <field>,...] [-s [-i <interval>]] " 3964eaa4710SRishi Srivatsavai "[<bridge>]\n" 3974eaa4710SRishi Srivatsavai " show-bridge -l [-p] [-o <field>,...] [-s [-i <interval>]]" 3984eaa4710SRishi Srivatsavai " <bridge>\n" 3994eaa4710SRishi Srivatsavai " show-bridge -f [-p] [-o <field>,...] [-s [-i <interval>]]" 4004eaa4710SRishi Srivatsavai " <bridge>\n" 4014eaa4710SRishi Srivatsavai " show-bridge -t [-p] [-o <field>,...] [-s [-i <interval>]]" 4024eaa4710SRishi Srivatsavai " <bridge>\n" }, 403da14cebeSEric Cheng { "show-usage", do_show_usage, 404ae6aa22aSVenugopal Iyer " show-usage [-a] [-d | -F <format>] " 4050790b6dcSAnurag S. Maskey "[-s <DD/MM/YYYY,HH:MM:SS>]\n" 4060790b6dcSAnurag S. Maskey "\t\t [-e <DD/MM/YYYY,HH:MM:SS>] -f <logfile> [<link>]" } 4077c478bd9Sstevel@tonic-gate }; 4087c478bd9Sstevel@tonic-gate 409d62bc4baSyz147064 static const struct option lopts[] = { 4107c478bd9Sstevel@tonic-gate {"vlan-id", required_argument, 0, 'v'}, 411e7801d59Ssowmini {"output", required_argument, 0, 'o'}, 4127c478bd9Sstevel@tonic-gate {"dev", required_argument, 0, 'd'}, 4137c478bd9Sstevel@tonic-gate {"policy", required_argument, 0, 'P'}, 414d62bc4baSyz147064 {"lacp-mode", required_argument, 0, 'L'}, 4157c478bd9Sstevel@tonic-gate {"lacp-timer", required_argument, 0, 'T'}, 4167c478bd9Sstevel@tonic-gate {"unicast", required_argument, 0, 'u'}, 417d62bc4baSyz147064 {"temporary", no_argument, 0, 't'}, 418d62bc4baSyz147064 {"root-dir", required_argument, 0, 'R'}, 419d62bc4baSyz147064 {"link", required_argument, 0, 'l'}, 420d62bc4baSyz147064 {"forcible", no_argument, 0, 'f'}, 421da14cebeSEric Cheng {"bw-limit", required_argument, 0, 'b'}, 422da14cebeSEric Cheng {"mac-address", required_argument, 0, 'm'}, 423da14cebeSEric Cheng {"slot", required_argument, 0, 'n'}, 424d62bc4baSyz147064 { 0, 0, 0, 0 } 425d62bc4baSyz147064 }; 426d62bc4baSyz147064 427d62bc4baSyz147064 static const struct option show_lopts[] = { 4287c478bd9Sstevel@tonic-gate {"statistics", no_argument, 0, 's'}, 429da14cebeSEric Cheng {"continuous", no_argument, 0, 'S'}, 4307c478bd9Sstevel@tonic-gate {"interval", required_argument, 0, 'i'}, 4318002d411SSowmini Varadhan {"parsable", no_argument, 0, 'p'}, 4327c478bd9Sstevel@tonic-gate {"parseable", no_argument, 0, 'p'}, 433d62bc4baSyz147064 {"extended", no_argument, 0, 'x'}, 434e7801d59Ssowmini {"output", required_argument, 0, 'o'}, 435d62bc4baSyz147064 {"persistent", no_argument, 0, 'P'}, 436d62bc4baSyz147064 {"lacp", no_argument, 0, 'L'}, 4377c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 } 4387c478bd9Sstevel@tonic-gate }; 4397c478bd9Sstevel@tonic-gate 4402b24ab6bSSebastien Roy static const struct option iptun_lopts[] = { 4412b24ab6bSSebastien Roy {"output", required_argument, 0, 'o'}, 4422b24ab6bSSebastien Roy {"tunnel-type", required_argument, 0, 'T'}, 4432b24ab6bSSebastien Roy {"address", required_argument, 0, 'a'}, 4442b24ab6bSSebastien Roy {"root-dir", required_argument, 0, 'R'}, 4452b24ab6bSSebastien Roy {"parsable", no_argument, 0, 'p'}, 4462b24ab6bSSebastien Roy {"parseable", no_argument, 0, 'p'}, 4472b24ab6bSSebastien Roy {"persistent", no_argument, 0, 'P'}, 4482b24ab6bSSebastien Roy { 0, 0, 0, 0 } 4492b24ab6bSSebastien Roy }; 4502b24ab6bSSebastien Roy 4512b24ab6bSSebastien Roy static char * const iptun_addropts[] = { 4522b24ab6bSSebastien Roy #define IPTUN_LOCAL 0 4532b24ab6bSSebastien Roy "local", 4542b24ab6bSSebastien Roy #define IPTUN_REMOTE 1 4552b24ab6bSSebastien Roy "remote", 4562b24ab6bSSebastien Roy NULL}; 4572b24ab6bSSebastien Roy 4582b24ab6bSSebastien Roy static const struct { 4592b24ab6bSSebastien Roy const char *type_name; 4602b24ab6bSSebastien Roy iptun_type_t type_value; 4612b24ab6bSSebastien Roy } iptun_types[] = { 4622b24ab6bSSebastien Roy {"ipv4", IPTUN_TYPE_IPV4}, 4632b24ab6bSSebastien Roy {"ipv6", IPTUN_TYPE_IPV6}, 4642b24ab6bSSebastien Roy {"6to4", IPTUN_TYPE_6TO4}, 4652b24ab6bSSebastien Roy {NULL, 0} 4662b24ab6bSSebastien Roy }; 4672b24ab6bSSebastien Roy 4680ba2cbe9Sxc151355 static const struct option prop_longopts[] = { 4690ba2cbe9Sxc151355 {"temporary", no_argument, 0, 't' }, 470e7801d59Ssowmini {"output", required_argument, 0, 'o' }, 4710ba2cbe9Sxc151355 {"root-dir", required_argument, 0, 'R' }, 4720ba2cbe9Sxc151355 {"prop", required_argument, 0, 'p' }, 4738002d411SSowmini Varadhan {"parsable", no_argument, 0, 'c' }, 4740ba2cbe9Sxc151355 {"parseable", no_argument, 0, 'c' }, 4750ba2cbe9Sxc151355 {"persistent", no_argument, 0, 'P' }, 4760ba2cbe9Sxc151355 { 0, 0, 0, 0 } 4770ba2cbe9Sxc151355 }; 4780ba2cbe9Sxc151355 4790ba2cbe9Sxc151355 static const struct option wifi_longopts[] = { 4808002d411SSowmini Varadhan {"parsable", no_argument, 0, 'p' }, 4810ba2cbe9Sxc151355 {"parseable", no_argument, 0, 'p' }, 4820ba2cbe9Sxc151355 {"output", required_argument, 0, 'o' }, 4830ba2cbe9Sxc151355 {"essid", required_argument, 0, 'e' }, 4840ba2cbe9Sxc151355 {"bsstype", required_argument, 0, 'b' }, 4850ba2cbe9Sxc151355 {"mode", required_argument, 0, 'm' }, 4860ba2cbe9Sxc151355 {"key", required_argument, 0, 'k' }, 4870ba2cbe9Sxc151355 {"sec", required_argument, 0, 's' }, 4880ba2cbe9Sxc151355 {"auth", required_argument, 0, 'a' }, 4890ba2cbe9Sxc151355 {"create-ibss", required_argument, 0, 'c' }, 4900ba2cbe9Sxc151355 {"timeout", required_argument, 0, 'T' }, 4910ba2cbe9Sxc151355 {"all-links", no_argument, 0, 'a' }, 4920ba2cbe9Sxc151355 {"temporary", no_argument, 0, 't' }, 4930ba2cbe9Sxc151355 {"root-dir", required_argument, 0, 'R' }, 4940ba2cbe9Sxc151355 {"persistent", no_argument, 0, 'P' }, 4950ba2cbe9Sxc151355 {"file", required_argument, 0, 'f' }, 4960ba2cbe9Sxc151355 { 0, 0, 0, 0 } 4970ba2cbe9Sxc151355 }; 4982b24ab6bSSebastien Roy 499e7801d59Ssowmini static const struct option showeth_lopts[] = { 5008002d411SSowmini Varadhan {"parsable", no_argument, 0, 'p' }, 501e7801d59Ssowmini {"parseable", no_argument, 0, 'p' }, 502e7801d59Ssowmini {"extended", no_argument, 0, 'x' }, 503e7801d59Ssowmini {"output", required_argument, 0, 'o' }, 504e7801d59Ssowmini { 0, 0, 0, 0 } 505e7801d59Ssowmini }; 506e7801d59Ssowmini 507da14cebeSEric Cheng static const struct option vnic_lopts[] = { 508da14cebeSEric Cheng {"temporary", no_argument, 0, 't' }, 509da14cebeSEric Cheng {"root-dir", required_argument, 0, 'R' }, 510da14cebeSEric Cheng {"dev", required_argument, 0, 'd' }, 511da14cebeSEric Cheng {"mac-address", required_argument, 0, 'm' }, 512da14cebeSEric Cheng {"cpus", required_argument, 0, 'c' }, 513da14cebeSEric Cheng {"bw-limit", required_argument, 0, 'b' }, 514da14cebeSEric Cheng {"slot", required_argument, 0, 'n' }, 515da14cebeSEric Cheng {"mac-prefix", required_argument, 0, 'r' }, 5161cb875aeSCathy Zhou {"vrid", required_argument, 0, 'V' }, 5171cb875aeSCathy Zhou {"address-family", required_argument, 0, 'A' }, 518da14cebeSEric Cheng { 0, 0, 0, 0 } 519da14cebeSEric Cheng }; 520da14cebeSEric Cheng 5211cfa752fSRamaswamy Tummala static const struct option part_lopts[] = { 5221cfa752fSRamaswamy Tummala {"temporary", no_argument, 0, 't' }, 5231cfa752fSRamaswamy Tummala {"pkey", required_argument, 0, 'P' }, 5241cfa752fSRamaswamy Tummala {"link", required_argument, 0, 'l' }, 5251cfa752fSRamaswamy Tummala {"force", no_argument, 0, 'f' }, 5261cfa752fSRamaswamy Tummala {"root-dir", required_argument, 0, 'R' }, 5271cfa752fSRamaswamy Tummala {"prop", required_argument, 0, 'p' }, 5281cfa752fSRamaswamy Tummala { 0, 0, 0, 0 } 5291cfa752fSRamaswamy Tummala }; 5301cfa752fSRamaswamy Tummala 5311cfa752fSRamaswamy Tummala static const struct option show_part_lopts[] = { 5321cfa752fSRamaswamy Tummala {"parsable", no_argument, 0, 'p' }, 5331cfa752fSRamaswamy Tummala {"parseable", no_argument, 0, 'p' }, 5341cfa752fSRamaswamy Tummala {"link", required_argument, 0, 'l' }, 5351cfa752fSRamaswamy Tummala {"persistent", no_argument, 0, 'P' }, 5361cfa752fSRamaswamy Tummala {"output", required_argument, 0, 'o' }, 5371cfa752fSRamaswamy Tummala { 0, 0, 0, 0 } 5381cfa752fSRamaswamy Tummala }; 5391cfa752fSRamaswamy Tummala 540da14cebeSEric Cheng static const struct option etherstub_lopts[] = { 541da14cebeSEric Cheng {"temporary", no_argument, 0, 't' }, 542da14cebeSEric Cheng {"root-dir", required_argument, 0, 'R' }, 543da14cebeSEric Cheng { 0, 0, 0, 0 } 544da14cebeSEric Cheng }; 545da14cebeSEric Cheng 546ae6aa22aSVenugopal Iyer static const struct option usage_opts[] = { 547ae6aa22aSVenugopal Iyer {"file", required_argument, 0, 'f' }, 548ae6aa22aSVenugopal Iyer {"format", required_argument, 0, 'F' }, 549ae6aa22aSVenugopal Iyer {"start", required_argument, 0, 's' }, 550ae6aa22aSVenugopal Iyer {"stop", required_argument, 0, 'e' }, 551ae6aa22aSVenugopal Iyer { 0, 0, 0, 0 } 552ae6aa22aSVenugopal Iyer }; 553ae6aa22aSVenugopal Iyer 554b509e89bSRishi Srivatsavai static const struct option simnet_lopts[] = { 555b509e89bSRishi Srivatsavai {"temporary", no_argument, 0, 't' }, 556b509e89bSRishi Srivatsavai {"root-dir", required_argument, 0, 'R' }, 557b509e89bSRishi Srivatsavai {"media", required_argument, 0, 'm' }, 558b509e89bSRishi Srivatsavai {"peer", required_argument, 0, 'p' }, 559b509e89bSRishi Srivatsavai { 0, 0, 0, 0 } 560b509e89bSRishi Srivatsavai }; 561b509e89bSRishi Srivatsavai 5624eaa4710SRishi Srivatsavai static const struct option bridge_lopts[] = { 5634eaa4710SRishi Srivatsavai { "protect", required_argument, 0, 'P' }, 5644eaa4710SRishi Srivatsavai { "root-dir", required_argument, 0, 'R' }, 5654eaa4710SRishi Srivatsavai { "forward-delay", required_argument, 0, 'd' }, 5664eaa4710SRishi Srivatsavai { "force-protocol", required_argument, 0, 'f' }, 5674eaa4710SRishi Srivatsavai { "hello-time", required_argument, 0, 'h' }, 5684eaa4710SRishi Srivatsavai { "link", required_argument, 0, 'l' }, 5694eaa4710SRishi Srivatsavai { "max-age", required_argument, 0, 'm' }, 5704eaa4710SRishi Srivatsavai { "priority", required_argument, 0, 'p' }, 5714eaa4710SRishi Srivatsavai { NULL, NULL, 0, 0 } 5724eaa4710SRishi Srivatsavai }; 5734eaa4710SRishi Srivatsavai 5744eaa4710SRishi Srivatsavai static const struct option bridge_show_lopts[] = { 5754eaa4710SRishi Srivatsavai { "forwarding", no_argument, 0, 'f' }, 5764eaa4710SRishi Srivatsavai { "interval", required_argument, 0, 'i' }, 5774eaa4710SRishi Srivatsavai { "link", no_argument, 0, 'l' }, 5784eaa4710SRishi Srivatsavai { "output", required_argument, 0, 'o' }, 5794eaa4710SRishi Srivatsavai { "parsable", no_argument, 0, 'p' }, 5804eaa4710SRishi Srivatsavai { "parseable", no_argument, 0, 'p' }, 5814eaa4710SRishi Srivatsavai { "statistics", no_argument, 0, 's' }, 5824eaa4710SRishi Srivatsavai { "trill", no_argument, 0, 't' }, 5834eaa4710SRishi Srivatsavai { 0, 0, 0, 0 } 5844eaa4710SRishi Srivatsavai }; 5854eaa4710SRishi Srivatsavai 586e7801d59Ssowmini /* 587e7801d59Ssowmini * structures for 'dladm show-ether' 588e7801d59Ssowmini */ 5894784fcbdSSowmini Varadhan static const char *ptype[] = {LEI_ATTR_NAMES}; 5904784fcbdSSowmini Varadhan 591e7801d59Ssowmini typedef struct ether_fields_buf_s 592e7801d59Ssowmini { 593e7801d59Ssowmini char eth_link[15]; 594e7801d59Ssowmini char eth_ptype[8]; 595e7801d59Ssowmini char eth_state[8]; 596e7801d59Ssowmini char eth_autoneg[5]; 597e7801d59Ssowmini char eth_spdx[31]; 598e7801d59Ssowmini char eth_pause[6]; 599e7801d59Ssowmini char eth_rem_fault[16]; 600e7801d59Ssowmini } ether_fields_buf_t; 601e7801d59Ssowmini 6022b24ab6bSSebastien Roy static const ofmt_field_t ether_fields[] = { 6038002d411SSowmini Varadhan /* name, field width, offset callback */ 6048002d411SSowmini Varadhan { "LINK", 16, 6058002d411SSowmini Varadhan offsetof(ether_fields_buf_t, eth_link), print_default_cb}, 6068002d411SSowmini Varadhan { "PTYPE", 9, 6078002d411SSowmini Varadhan offsetof(ether_fields_buf_t, eth_ptype), print_default_cb}, 6088002d411SSowmini Varadhan { "STATE", 9, 6098002d411SSowmini Varadhan offsetof(ether_fields_buf_t, eth_state), 6108002d411SSowmini Varadhan print_default_cb}, 6118002d411SSowmini Varadhan { "AUTO", 6, 6128002d411SSowmini Varadhan offsetof(ether_fields_buf_t, eth_autoneg), print_default_cb}, 6138002d411SSowmini Varadhan { "SPEED-DUPLEX", 32, 6148002d411SSowmini Varadhan offsetof(ether_fields_buf_t, eth_spdx), print_default_cb}, 6158002d411SSowmini Varadhan { "PAUSE", 7, 6168002d411SSowmini Varadhan offsetof(ether_fields_buf_t, eth_pause), print_default_cb}, 6178002d411SSowmini Varadhan { "REM_FAULT", 17, 6188002d411SSowmini Varadhan offsetof(ether_fields_buf_t, eth_rem_fault), print_default_cb}, 6198002d411SSowmini Varadhan {NULL, 0, 6208002d411SSowmini Varadhan 0, NULL}} 621e7801d59Ssowmini ; 622e7801d59Ssowmini 623e7801d59Ssowmini typedef struct print_ether_state { 624e7801d59Ssowmini const char *es_link; 6258002d411SSowmini Varadhan boolean_t es_parsable; 626e7801d59Ssowmini boolean_t es_header; 627e7801d59Ssowmini boolean_t es_extended; 6288002d411SSowmini Varadhan ofmt_handle_t es_ofmt; 629e7801d59Ssowmini } print_ether_state_t; 630e7801d59Ssowmini 631e7801d59Ssowmini /* 632da14cebeSEric Cheng * structures for 'dladm show-link -s' (print statistics) 633e7801d59Ssowmini */ 634e7801d59Ssowmini typedef enum { 635ae6aa22aSVenugopal Iyer LINK_S_LINK, 636ae6aa22aSVenugopal Iyer LINK_S_IPKTS, 637ae6aa22aSVenugopal Iyer LINK_S_RBYTES, 638ae6aa22aSVenugopal Iyer LINK_S_IERRORS, 639ae6aa22aSVenugopal Iyer LINK_S_OPKTS, 640ae6aa22aSVenugopal Iyer LINK_S_OBYTES, 641ae6aa22aSVenugopal Iyer LINK_S_OERRORS 642ae6aa22aSVenugopal Iyer } link_s_field_index_t; 643e7801d59Ssowmini 6442b24ab6bSSebastien Roy static const ofmt_field_t link_s_fields[] = { 6458002d411SSowmini Varadhan /* name, field width, index, callback */ 6468002d411SSowmini Varadhan { "LINK", 15, LINK_S_LINK, print_link_stats_cb}, 6478002d411SSowmini Varadhan { "IPACKETS", 10, LINK_S_IPKTS, print_link_stats_cb}, 6488002d411SSowmini Varadhan { "RBYTES", 8, LINK_S_RBYTES, print_link_stats_cb}, 6498002d411SSowmini Varadhan { "IERRORS", 10, LINK_S_IERRORS, print_link_stats_cb}, 6508002d411SSowmini Varadhan { "OPACKETS", 12, LINK_S_OPKTS, print_link_stats_cb}, 6518002d411SSowmini Varadhan { "OBYTES", 12, LINK_S_OBYTES, print_link_stats_cb}, 6528002d411SSowmini Varadhan { "OERRORS", 8, LINK_S_OERRORS, print_link_stats_cb}} 653e7801d59Ssowmini ; 654ae6aa22aSVenugopal Iyer 655ae6aa22aSVenugopal Iyer typedef struct link_args_s { 656ae6aa22aSVenugopal Iyer char *link_s_link; 657ae6aa22aSVenugopal Iyer pktsum_t *link_s_psum; 658ae6aa22aSVenugopal Iyer } link_args_t; 659e7801d59Ssowmini 660e7801d59Ssowmini /* 661e7801d59Ssowmini * buffer used by print functions for show-{link,phys,vlan} commands. 662e7801d59Ssowmini */ 663e7801d59Ssowmini typedef struct link_fields_buf_s { 664e7801d59Ssowmini char link_name[MAXLINKNAMELEN]; 665e7801d59Ssowmini char link_class[DLADM_STRSIZE]; 666c08e5e1aSdr146992 char link_mtu[11]; 667e7801d59Ssowmini char link_state[DLADM_STRSIZE]; 6684eaa4710SRishi Srivatsavai char link_bridge[MAXLINKNAMELEN]; 669e7801d59Ssowmini char link_over[MAXLINKNAMELEN]; 6704045d941Ssowmini char link_phys_state[DLADM_STRSIZE]; 671e7801d59Ssowmini char link_phys_media[DLADM_STRSIZE]; 672e7801d59Ssowmini char link_phys_speed[DLADM_STRSIZE]; 673e7801d59Ssowmini char link_phys_duplex[DLPI_LINKNAME_MAX]; 674e7801d59Ssowmini char link_phys_device[DLPI_LINKNAME_MAX]; 675e7801d59Ssowmini char link_flags[6]; 676e7801d59Ssowmini char link_vlan_vid[6]; 677e7801d59Ssowmini } link_fields_buf_t; 678e7801d59Ssowmini 679e7801d59Ssowmini /* 680e7801d59Ssowmini * structures for 'dladm show-link' 681e7801d59Ssowmini */ 6822b24ab6bSSebastien Roy static const ofmt_field_t link_fields[] = { 6838002d411SSowmini Varadhan /* name, field width, index, callback */ 6848002d411SSowmini Varadhan { "LINK", 12, 6858002d411SSowmini Varadhan offsetof(link_fields_buf_t, link_name), print_default_cb}, 6864fd5d067Smeem { "CLASS", 10, 6878002d411SSowmini Varadhan offsetof(link_fields_buf_t, link_class), print_default_cb}, 6888002d411SSowmini Varadhan { "MTU", 7, 6898002d411SSowmini Varadhan offsetof(link_fields_buf_t, link_mtu), print_default_cb}, 6908002d411SSowmini Varadhan { "STATE", 9, 6918002d411SSowmini Varadhan offsetof(link_fields_buf_t, link_state), print_default_cb}, 6924eaa4710SRishi Srivatsavai { "BRIDGE", 11, 6934eaa4710SRishi Srivatsavai offsetof(link_fields_buf_t, link_bridge), print_default_cb}, 6948002d411SSowmini Varadhan { "OVER", DLPI_LINKNAME_MAX, 6958002d411SSowmini Varadhan offsetof(link_fields_buf_t, link_over), print_default_cb}, 6968002d411SSowmini Varadhan { NULL, 0, 0, NULL}} 697e7801d59Ssowmini ; 698e7801d59Ssowmini 699e7801d59Ssowmini /* 700e7801d59Ssowmini * structures for 'dladm show-aggr' 701e7801d59Ssowmini */ 702e7801d59Ssowmini typedef struct laggr_fields_buf_s { 703e7801d59Ssowmini char laggr_name[DLPI_LINKNAME_MAX]; 704e7801d59Ssowmini char laggr_policy[9]; 705e7801d59Ssowmini char laggr_addrpolicy[ETHERADDRL * 3 + 3]; 706e7801d59Ssowmini char laggr_lacpactivity[14]; 707e7801d59Ssowmini char laggr_lacptimer[DLADM_STRSIZE]; 708e7801d59Ssowmini char laggr_flags[7]; 709e7801d59Ssowmini } laggr_fields_buf_t; 710e7801d59Ssowmini 711e7801d59Ssowmini typedef struct laggr_args_s { 712e7801d59Ssowmini int laggr_lport; /* -1 indicates the aggr itself */ 713e7801d59Ssowmini const char *laggr_link; 714e7801d59Ssowmini dladm_aggr_grp_attr_t *laggr_ginfop; 715e7801d59Ssowmini dladm_status_t *laggr_status; 716e7801d59Ssowmini pktsum_t *laggr_pktsumtot; /* -s only */ 7172d40c3b2SPrakash Jalan pktsum_t *laggr_diffstats; /* -s only */ 7188002d411SSowmini Varadhan boolean_t laggr_parsable; 719e7801d59Ssowmini } laggr_args_t; 720e7801d59Ssowmini 7212b24ab6bSSebastien Roy static const ofmt_field_t laggr_fields[] = { 7228002d411SSowmini Varadhan /* name, field width, offset, callback */ 7238002d411SSowmini Varadhan { "LINK", 16, 7248002d411SSowmini Varadhan offsetof(laggr_fields_buf_t, laggr_name), print_default_cb}, 7258002d411SSowmini Varadhan { "POLICY", 9, 7268002d411SSowmini Varadhan offsetof(laggr_fields_buf_t, laggr_policy), print_default_cb}, 7278002d411SSowmini Varadhan { "ADDRPOLICY", ETHERADDRL * 3 + 3, 7288002d411SSowmini Varadhan offsetof(laggr_fields_buf_t, laggr_addrpolicy), print_default_cb}, 7298002d411SSowmini Varadhan { "LACPACTIVITY", 14, 7308002d411SSowmini Varadhan offsetof(laggr_fields_buf_t, laggr_lacpactivity), print_default_cb}, 7318002d411SSowmini Varadhan { "LACPTIMER", 12, 7328002d411SSowmini Varadhan offsetof(laggr_fields_buf_t, laggr_lacptimer), print_default_cb}, 7338002d411SSowmini Varadhan { "FLAGS", 8, 7348002d411SSowmini Varadhan offsetof(laggr_fields_buf_t, laggr_flags), print_default_cb}, 7358002d411SSowmini Varadhan { NULL, 0, 0, NULL}} 736e7801d59Ssowmini ; 737e7801d59Ssowmini 738e7801d59Ssowmini /* 739e7801d59Ssowmini * structures for 'dladm show-aggr -x'. 740e7801d59Ssowmini */ 741e7801d59Ssowmini typedef enum { 742e7801d59Ssowmini AGGR_X_LINK, 743e7801d59Ssowmini AGGR_X_PORT, 744e7801d59Ssowmini AGGR_X_SPEED, 745e7801d59Ssowmini AGGR_X_DUPLEX, 746e7801d59Ssowmini AGGR_X_STATE, 747e7801d59Ssowmini AGGR_X_ADDRESS, 748e7801d59Ssowmini AGGR_X_PORTSTATE 749e7801d59Ssowmini } aggr_x_field_index_t; 750e7801d59Ssowmini 7512b24ab6bSSebastien Roy static const ofmt_field_t aggr_x_fields[] = { 7528002d411SSowmini Varadhan /* name, field width, index callback */ 7538002d411SSowmini Varadhan { "LINK", 12, AGGR_X_LINK, print_xaggr_cb}, 7548002d411SSowmini Varadhan { "PORT", 15, AGGR_X_PORT, print_xaggr_cb}, 7558002d411SSowmini Varadhan { "SPEED", 5, AGGR_X_SPEED, print_xaggr_cb}, 7568002d411SSowmini Varadhan { "DUPLEX", 10, AGGR_X_DUPLEX, print_xaggr_cb}, 7578002d411SSowmini Varadhan { "STATE", 10, AGGR_X_STATE, print_xaggr_cb}, 7588002d411SSowmini Varadhan { "ADDRESS", 19, AGGR_X_ADDRESS, print_xaggr_cb}, 7598002d411SSowmini Varadhan { "PORTSTATE", 16, AGGR_X_PORTSTATE, print_xaggr_cb}, 7608002d411SSowmini Varadhan { NULL, 0, 0, NULL}} 761e7801d59Ssowmini ; 762e7801d59Ssowmini 763e7801d59Ssowmini /* 764e7801d59Ssowmini * structures for 'dladm show-aggr -s'. 765e7801d59Ssowmini */ 766e7801d59Ssowmini typedef enum { 767e7801d59Ssowmini AGGR_S_LINK, 768e7801d59Ssowmini AGGR_S_PORT, 769e7801d59Ssowmini AGGR_S_IPKTS, 770e7801d59Ssowmini AGGR_S_RBYTES, 771e7801d59Ssowmini AGGR_S_OPKTS, 772e7801d59Ssowmini AGGR_S_OBYTES, 773e7801d59Ssowmini AGGR_S_IPKTDIST, 774e7801d59Ssowmini AGGR_S_OPKTDIST 775e7801d59Ssowmini } aggr_s_field_index_t; 776e7801d59Ssowmini 7772b24ab6bSSebastien Roy static const ofmt_field_t aggr_s_fields[] = { 7788002d411SSowmini Varadhan { "LINK", 12, AGGR_S_LINK, print_aggr_stats_cb}, 7798002d411SSowmini Varadhan { "PORT", 10, AGGR_S_PORT, print_aggr_stats_cb}, 7808002d411SSowmini Varadhan { "IPACKETS", 8, AGGR_S_IPKTS, print_aggr_stats_cb}, 7818002d411SSowmini Varadhan { "RBYTES", 8, AGGR_S_RBYTES, print_aggr_stats_cb}, 7828002d411SSowmini Varadhan { "OPACKETS", 8, AGGR_S_OPKTS, print_aggr_stats_cb}, 7838002d411SSowmini Varadhan { "OBYTES", 8, AGGR_S_OBYTES, print_aggr_stats_cb}, 7848002d411SSowmini Varadhan { "IPKTDIST", 9, AGGR_S_IPKTDIST, print_aggr_stats_cb}, 7858002d411SSowmini Varadhan { "OPKTDIST", 15, AGGR_S_OPKTDIST, print_aggr_stats_cb}, 7868002d411SSowmini Varadhan { NULL, 0, 0, NULL}} 787e7801d59Ssowmini ; 788e7801d59Ssowmini 789e7801d59Ssowmini /* 790da14cebeSEric Cheng * structures for 'dladm show-aggr -L'. 791e7801d59Ssowmini */ 792e7801d59Ssowmini typedef enum { 793e7801d59Ssowmini AGGR_L_LINK, 794e7801d59Ssowmini AGGR_L_PORT, 795e7801d59Ssowmini AGGR_L_AGGREGATABLE, 796e7801d59Ssowmini AGGR_L_SYNC, 797e7801d59Ssowmini AGGR_L_COLL, 798e7801d59Ssowmini AGGR_L_DIST, 799e7801d59Ssowmini AGGR_L_DEFAULTED, 800e7801d59Ssowmini AGGR_L_EXPIRED 801e7801d59Ssowmini } aggr_l_field_index_t; 802e7801d59Ssowmini 8032b24ab6bSSebastien Roy static const ofmt_field_t aggr_l_fields[] = { 8048002d411SSowmini Varadhan /* name, field width, index */ 8058002d411SSowmini Varadhan { "LINK", 12, AGGR_L_LINK, print_lacp_cb}, 8068002d411SSowmini Varadhan { "PORT", 13, AGGR_L_PORT, print_lacp_cb}, 8078002d411SSowmini Varadhan { "AGGREGATABLE", 13, AGGR_L_AGGREGATABLE, print_lacp_cb}, 8088002d411SSowmini Varadhan { "SYNC", 5, AGGR_L_SYNC, print_lacp_cb}, 8098002d411SSowmini Varadhan { "COLL", 5, AGGR_L_COLL, print_lacp_cb}, 8108002d411SSowmini Varadhan { "DIST", 5, AGGR_L_DIST, print_lacp_cb}, 8118002d411SSowmini Varadhan { "DEFAULTED", 10, AGGR_L_DEFAULTED, print_lacp_cb}, 8128002d411SSowmini Varadhan { "EXPIRED", 15, AGGR_L_EXPIRED, print_lacp_cb}, 8138002d411SSowmini Varadhan { NULL, 0, 0, NULL}} 814e7801d59Ssowmini ; 815e7801d59Ssowmini 816e7801d59Ssowmini /* 817e7801d59Ssowmini * structures for 'dladm show-phys' 818e7801d59Ssowmini */ 819e7801d59Ssowmini 8202b24ab6bSSebastien Roy static const ofmt_field_t phys_fields[] = { 8218002d411SSowmini Varadhan /* name, field width, offset */ 8228002d411SSowmini Varadhan { "LINK", 13, 8238002d411SSowmini Varadhan offsetof(link_fields_buf_t, link_name), print_default_cb}, 8248002d411SSowmini Varadhan { "MEDIA", 21, 8258002d411SSowmini Varadhan offsetof(link_fields_buf_t, link_phys_media), print_default_cb}, 8268002d411SSowmini Varadhan { "STATE", 11, 8278002d411SSowmini Varadhan offsetof(link_fields_buf_t, link_phys_state), print_default_cb}, 8288002d411SSowmini Varadhan { "SPEED", 7, 8298002d411SSowmini Varadhan offsetof(link_fields_buf_t, link_phys_speed), print_default_cb}, 8308002d411SSowmini Varadhan { "DUPLEX", 10, 8318002d411SSowmini Varadhan offsetof(link_fields_buf_t, link_phys_duplex), print_default_cb}, 8328002d411SSowmini Varadhan { "DEVICE", 13, 8338002d411SSowmini Varadhan offsetof(link_fields_buf_t, link_phys_device), print_default_cb}, 8348002d411SSowmini Varadhan { "FLAGS", 7, 8358002d411SSowmini Varadhan offsetof(link_fields_buf_t, link_flags), print_default_cb}, 8368002d411SSowmini Varadhan { NULL, 0, NULL, 0}} 837e7801d59Ssowmini ; 838e7801d59Ssowmini 839e7801d59Ssowmini /* 840da14cebeSEric Cheng * structures for 'dladm show-phys -m' 841da14cebeSEric Cheng */ 842da14cebeSEric Cheng 843da14cebeSEric Cheng typedef enum { 844da14cebeSEric Cheng PHYS_M_LINK, 845da14cebeSEric Cheng PHYS_M_SLOT, 846da14cebeSEric Cheng PHYS_M_ADDRESS, 847da14cebeSEric Cheng PHYS_M_INUSE, 848da14cebeSEric Cheng PHYS_M_CLIENT 849da14cebeSEric Cheng } phys_m_field_index_t; 850da14cebeSEric Cheng 8512b24ab6bSSebastien Roy static const ofmt_field_t phys_m_fields[] = { 8528002d411SSowmini Varadhan /* name, field width, offset */ 8538002d411SSowmini Varadhan { "LINK", 13, PHYS_M_LINK, print_phys_one_mac_cb}, 8548002d411SSowmini Varadhan { "SLOT", 9, PHYS_M_SLOT, print_phys_one_mac_cb}, 8558002d411SSowmini Varadhan { "ADDRESS", 19, PHYS_M_ADDRESS, print_phys_one_mac_cb}, 8568002d411SSowmini Varadhan { "INUSE", 5, PHYS_M_INUSE, print_phys_one_mac_cb}, 8578002d411SSowmini Varadhan { "CLIENT", 13, PHYS_M_CLIENT, print_phys_one_mac_cb}, 8588002d411SSowmini Varadhan { NULL, 0, 0, NULL}} 859da14cebeSEric Cheng ; 860da14cebeSEric Cheng 861da14cebeSEric Cheng /* 862da14cebeSEric Cheng * structures for 'dladm show-phys -H' 863da14cebeSEric Cheng */ 864da14cebeSEric Cheng 865da14cebeSEric Cheng typedef enum { 866da14cebeSEric Cheng PHYS_H_LINK, 8670dc2366fSVenugopal Iyer PHYS_H_RINGTYPE, 868da14cebeSEric Cheng PHYS_H_RINGS, 869da14cebeSEric Cheng PHYS_H_CLIENTS 870da14cebeSEric Cheng } phys_h_field_index_t; 871da14cebeSEric Cheng 8720dc2366fSVenugopal Iyer #define RINGSTRLEN 21 8730dc2366fSVenugopal Iyer 8742b24ab6bSSebastien Roy static const ofmt_field_t phys_h_fields[] = { 8758002d411SSowmini Varadhan { "LINK", 13, PHYS_H_LINK, print_phys_one_hwgrp_cb}, 8760dc2366fSVenugopal Iyer { "RINGTYPE", 9, PHYS_H_RINGTYPE, print_phys_one_hwgrp_cb}, 8770dc2366fSVenugopal Iyer { "RINGS", RINGSTRLEN, PHYS_H_RINGS, print_phys_one_hwgrp_cb}, 8780dc2366fSVenugopal Iyer { "CLIENTS", 24, PHYS_H_CLIENTS, print_phys_one_hwgrp_cb}, 8798002d411SSowmini Varadhan { NULL, 0, 0, NULL}} 880da14cebeSEric Cheng ; 881da14cebeSEric Cheng 882da14cebeSEric Cheng /* 883e7801d59Ssowmini * structures for 'dladm show-vlan' 884e7801d59Ssowmini */ 8852b24ab6bSSebastien Roy static const ofmt_field_t vlan_fields[] = { 8868002d411SSowmini Varadhan { "LINK", 16, 8878002d411SSowmini Varadhan offsetof(link_fields_buf_t, link_name), print_default_cb}, 8888002d411SSowmini Varadhan { "VID", 9, 8898002d411SSowmini Varadhan offsetof(link_fields_buf_t, link_vlan_vid), print_default_cb}, 8908002d411SSowmini Varadhan { "OVER", 13, 8918002d411SSowmini Varadhan offsetof(link_fields_buf_t, link_over), print_default_cb}, 8928002d411SSowmini Varadhan { "FLAGS", 7, 8938002d411SSowmini Varadhan offsetof(link_fields_buf_t, link_flags), print_default_cb}, 8948002d411SSowmini Varadhan { NULL, 0, 0, NULL}} 895e7801d59Ssowmini ; 896da14cebeSEric Cheng 897e7801d59Ssowmini /* 8988002d411SSowmini Varadhan * structures common to 'dladm scan-wifi' and 'dladm show-wifi' 8998002d411SSowmini Varadhan * callback will be determined in parse_wifi_fields. 900e7801d59Ssowmini */ 9018002d411SSowmini Varadhan static ofmt_field_t wifi_common_fields[] = { 9028002d411SSowmini Varadhan { "LINK", 11, 0, NULL}, 9038002d411SSowmini Varadhan { "ESSID", 20, DLADM_WLAN_ATTR_ESSID, NULL}, 9048002d411SSowmini Varadhan { "BSSID", 18, DLADM_WLAN_ATTR_BSSID, NULL}, 9058002d411SSowmini Varadhan { "IBSSID", 18, DLADM_WLAN_ATTR_BSSID, NULL}, 9068002d411SSowmini Varadhan { "MODE", 7, DLADM_WLAN_ATTR_MODE, NULL}, 9078002d411SSowmini Varadhan { "SPEED", 7, DLADM_WLAN_ATTR_SPEED, NULL}, 9088002d411SSowmini Varadhan { "BSSTYPE", 9, DLADM_WLAN_ATTR_BSSTYPE, NULL}, 9098002d411SSowmini Varadhan { "SEC", 7, DLADM_WLAN_ATTR_SECMODE, NULL}, 9108002d411SSowmini Varadhan { "STRENGTH", 11, DLADM_WLAN_ATTR_STRENGTH, NULL}, 9118002d411SSowmini Varadhan { NULL, 0, 0, NULL}}; 9128002d411SSowmini Varadhan 9138002d411SSowmini Varadhan /* 9148002d411SSowmini Varadhan * the 'show-wifi' command supports all the fields in wifi_common_fields 9158002d411SSowmini Varadhan * plus the AUTH and STATUS fields. 9168002d411SSowmini Varadhan */ 9178002d411SSowmini Varadhan static ofmt_field_t wifi_show_fields[A_CNT(wifi_common_fields) + 2] = { 9188002d411SSowmini Varadhan { "AUTH", 9, DLADM_WLAN_ATTR_AUTH, NULL}, 9198002d411SSowmini Varadhan { "STATUS", 18, DLADM_WLAN_LINKATTR_STATUS, print_wifi_status_cb}, 9208002d411SSowmini Varadhan /* copy wifi_common_fields here */ 9218002d411SSowmini Varadhan }; 922e7801d59Ssowmini 923e7801d59Ssowmini static char *all_scan_wifi_fields = 924e7801d59Ssowmini "link,essid,bssid,sec,strength,mode,speed,bsstype"; 925e7801d59Ssowmini static char *all_show_wifi_fields = 926e7801d59Ssowmini "link,status,essid,sec,strength,mode,speed,auth,bssid,bsstype"; 927e7801d59Ssowmini static char *def_scan_wifi_fields = 928e7801d59Ssowmini "link,essid,bssid,sec,strength,mode,speed"; 929e7801d59Ssowmini static char *def_show_wifi_fields = 930e7801d59Ssowmini "link,status,essid,sec,strength,mode,speed"; 931e7801d59Ssowmini 932e7801d59Ssowmini /* 933e7801d59Ssowmini * structures for 'dladm show-linkprop' 934e7801d59Ssowmini */ 935e7801d59Ssowmini typedef enum { 936e7801d59Ssowmini LINKPROP_LINK, 937e7801d59Ssowmini LINKPROP_PROPERTY, 938afdda45fSVasumathi Sundaram - Sun Microsystems LINKPROP_PERM, 939e7801d59Ssowmini LINKPROP_VALUE, 940e7801d59Ssowmini LINKPROP_DEFAULT, 941e7801d59Ssowmini LINKPROP_POSSIBLE 942e7801d59Ssowmini } linkprop_field_index_t; 943e7801d59Ssowmini 9442b24ab6bSSebastien Roy static const ofmt_field_t linkprop_fields[] = { 9458002d411SSowmini Varadhan /* name, field width, index */ 9468002d411SSowmini Varadhan { "LINK", 13, LINKPROP_LINK, print_linkprop_cb}, 9478002d411SSowmini Varadhan { "PROPERTY", 16, LINKPROP_PROPERTY, print_linkprop_cb}, 9488002d411SSowmini Varadhan { "PERM", 5, LINKPROP_PERM, print_linkprop_cb}, 9498002d411SSowmini Varadhan { "VALUE", 15, LINKPROP_VALUE, print_linkprop_cb}, 9508002d411SSowmini Varadhan { "DEFAULT", 15, LINKPROP_DEFAULT, print_linkprop_cb}, 95125ec3e3dSEric Cheng { "POSSIBLE", 20, LINKPROP_POSSIBLE, print_linkprop_cb}, 9528002d411SSowmini Varadhan { NULL, 0, 0, NULL}} 953e7801d59Ssowmini ; 954e7801d59Ssowmini 955e7801d59Ssowmini #define MAX_PROP_LINE 512 956e7801d59Ssowmini 957e7801d59Ssowmini typedef struct show_linkprop_state { 958e7801d59Ssowmini char ls_link[MAXLINKNAMELEN]; 959e7801d59Ssowmini char *ls_line; 960e7801d59Ssowmini char **ls_propvals; 961da14cebeSEric Cheng dladm_arg_list_t *ls_proplist; 9628002d411SSowmini Varadhan boolean_t ls_parsable; 963e7801d59Ssowmini boolean_t ls_persist; 964e7801d59Ssowmini boolean_t ls_header; 965e7801d59Ssowmini dladm_status_t ls_status; 966e7801d59Ssowmini dladm_status_t ls_retstatus; 9678002d411SSowmini Varadhan ofmt_handle_t ls_ofmt; 968e7801d59Ssowmini } show_linkprop_state_t; 969e7801d59Ssowmini 970da14cebeSEric Cheng typedef struct set_linkprop_state { 971da14cebeSEric Cheng const char *ls_name; 972da14cebeSEric Cheng boolean_t ls_reset; 973da14cebeSEric Cheng boolean_t ls_temp; 974da14cebeSEric Cheng dladm_status_t ls_status; 975da14cebeSEric Cheng } set_linkprop_state_t; 976da14cebeSEric Cheng 977e7801d59Ssowmini typedef struct linkprop_args_s { 978e7801d59Ssowmini show_linkprop_state_t *ls_state; 979e7801d59Ssowmini char *ls_propname; 980e7801d59Ssowmini datalink_id_t ls_linkid; 981e7801d59Ssowmini } linkprop_args_t; 982e7801d59Ssowmini 983e7801d59Ssowmini /* 984e7801d59Ssowmini * structures for 'dladm show-secobj' 985e7801d59Ssowmini */ 986e7801d59Ssowmini typedef struct secobj_fields_buf_s { 987e7801d59Ssowmini char ss_obj_name[DLADM_SECOBJ_VAL_MAX]; 988e7801d59Ssowmini char ss_class[20]; 989e7801d59Ssowmini char ss_val[30]; 990e7801d59Ssowmini } secobj_fields_buf_t; 9918002d411SSowmini Varadhan 9922b24ab6bSSebastien Roy static const ofmt_field_t secobj_fields[] = { 9938002d411SSowmini Varadhan { "OBJECT", 21, 9948002d411SSowmini Varadhan offsetof(secobj_fields_buf_t, ss_obj_name), print_default_cb}, 9958002d411SSowmini Varadhan { "CLASS", 21, 9968002d411SSowmini Varadhan offsetof(secobj_fields_buf_t, ss_class), print_default_cb}, 9978002d411SSowmini Varadhan { "VALUE", 31, 9988002d411SSowmini Varadhan offsetof(secobj_fields_buf_t, ss_val), print_default_cb}, 9998002d411SSowmini Varadhan { NULL, 0, 0, NULL}} 1000e7801d59Ssowmini ; 10010ba2cbe9Sxc151355 1002da14cebeSEric Cheng /* 1003da14cebeSEric Cheng * structures for 'dladm show-vnic' 1004da14cebeSEric Cheng */ 1005da14cebeSEric Cheng typedef struct vnic_fields_buf_s 1006da14cebeSEric Cheng { 1007da14cebeSEric Cheng char vnic_link[DLPI_LINKNAME_MAX]; 1008da14cebeSEric Cheng char vnic_over[DLPI_LINKNAME_MAX]; 1009da14cebeSEric Cheng char vnic_speed[6]; 1010b509e89bSRishi Srivatsavai char vnic_macaddr[18]; 1011da14cebeSEric Cheng char vnic_macaddrtype[19]; 1012da14cebeSEric Cheng char vnic_vid[6]; 1013da14cebeSEric Cheng } vnic_fields_buf_t; 1014da14cebeSEric Cheng 10152b24ab6bSSebastien Roy static const ofmt_field_t vnic_fields[] = { 10168002d411SSowmini Varadhan { "LINK", 13, 10178002d411SSowmini Varadhan offsetof(vnic_fields_buf_t, vnic_link), print_default_cb}, 10188002d411SSowmini Varadhan { "OVER", 13, 10198002d411SSowmini Varadhan offsetof(vnic_fields_buf_t, vnic_over), print_default_cb}, 10208002d411SSowmini Varadhan { "SPEED", 7, 10218002d411SSowmini Varadhan offsetof(vnic_fields_buf_t, vnic_speed), print_default_cb}, 1022b509e89bSRishi Srivatsavai { "MACADDRESS", 18, 10238002d411SSowmini Varadhan offsetof(vnic_fields_buf_t, vnic_macaddr), print_default_cb}, 10248002d411SSowmini Varadhan { "MACADDRTYPE", 20, 10258002d411SSowmini Varadhan offsetof(vnic_fields_buf_t, vnic_macaddrtype), print_default_cb}, 10268002d411SSowmini Varadhan { "VID", 7, 10278002d411SSowmini Varadhan offsetof(vnic_fields_buf_t, vnic_vid), print_default_cb}, 10288002d411SSowmini Varadhan { NULL, 0, 0, NULL}} 1029da14cebeSEric Cheng ; 1030da14cebeSEric Cheng 1031da14cebeSEric Cheng /* 10321cfa752fSRamaswamy Tummala * structures for 'dladm show-ib' 10331cfa752fSRamaswamy Tummala */ 10341cfa752fSRamaswamy Tummala typedef struct ib_fields_buf_s 10351cfa752fSRamaswamy Tummala { 10361cfa752fSRamaswamy Tummala char ib_link[DLPI_LINKNAME_MAX]; 10371cfa752fSRamaswamy Tummala char ib_hcaguid[17]; 10381cfa752fSRamaswamy Tummala char ib_portguid[17]; 10391cfa752fSRamaswamy Tummala char ib_portnum[4]; 10401cfa752fSRamaswamy Tummala char ib_state[6]; 10411cfa752fSRamaswamy Tummala char ib_pkeys[MAXPKEYSTRSZ]; 10421cfa752fSRamaswamy Tummala } ib_fields_buf_t; 10431cfa752fSRamaswamy Tummala 10441cfa752fSRamaswamy Tummala static const ofmt_field_t ib_fields[] = { 10451cfa752fSRamaswamy Tummala { "LINK", 13, 10461cfa752fSRamaswamy Tummala offsetof(ib_fields_buf_t, ib_link), print_default_cb}, 10471cfa752fSRamaswamy Tummala { "HCAGUID", IBGUIDSTRLEN, 10481cfa752fSRamaswamy Tummala offsetof(ib_fields_buf_t, ib_hcaguid), print_default_cb}, 10491cfa752fSRamaswamy Tummala { "PORTGUID", IBGUIDSTRLEN, 10501cfa752fSRamaswamy Tummala offsetof(ib_fields_buf_t, ib_portguid), print_default_cb}, 10511cfa752fSRamaswamy Tummala { "PORT", IBPORTSTRLEN, 10521cfa752fSRamaswamy Tummala offsetof(ib_fields_buf_t, ib_portnum), print_default_cb}, 10531cfa752fSRamaswamy Tummala { "STATE", 7, 10541cfa752fSRamaswamy Tummala offsetof(ib_fields_buf_t, ib_state), print_default_cb}, 10551cfa752fSRamaswamy Tummala { "PKEYS", 18, 10561cfa752fSRamaswamy Tummala offsetof(ib_fields_buf_t, ib_pkeys), print_default_cb}, 10571cfa752fSRamaswamy Tummala { NULL, 0, 0, NULL}}; 10581cfa752fSRamaswamy Tummala 10591cfa752fSRamaswamy Tummala /* 10601cfa752fSRamaswamy Tummala * structures for 'dladm show-part' 10611cfa752fSRamaswamy Tummala */ 10621cfa752fSRamaswamy Tummala typedef struct part_fields_buf_s 10631cfa752fSRamaswamy Tummala { 10641cfa752fSRamaswamy Tummala char part_link[DLPI_LINKNAME_MAX]; 10651cfa752fSRamaswamy Tummala char part_pkey[5]; 10661cfa752fSRamaswamy Tummala char part_over[DLPI_LINKNAME_MAX]; 10671cfa752fSRamaswamy Tummala char part_state[8]; 10681cfa752fSRamaswamy Tummala char part_flags[5]; 10691cfa752fSRamaswamy Tummala } part_fields_buf_t; 10701cfa752fSRamaswamy Tummala 10711cfa752fSRamaswamy Tummala static const ofmt_field_t part_fields[] = { 10721cfa752fSRamaswamy Tummala { "LINK", 13, 10731cfa752fSRamaswamy Tummala offsetof(part_fields_buf_t, part_link), print_default_cb}, 10741cfa752fSRamaswamy Tummala { "PKEY", MAXPKEYLEN, 10751cfa752fSRamaswamy Tummala offsetof(part_fields_buf_t, part_pkey), print_default_cb}, 10761cfa752fSRamaswamy Tummala { "OVER", 13, 10771cfa752fSRamaswamy Tummala offsetof(part_fields_buf_t, part_over), print_default_cb}, 10781cfa752fSRamaswamy Tummala { "STATE", 9, 10791cfa752fSRamaswamy Tummala offsetof(part_fields_buf_t, part_state), print_default_cb}, 10801cfa752fSRamaswamy Tummala { "FLAGS", 5, 10811cfa752fSRamaswamy Tummala offsetof(part_fields_buf_t, part_flags), print_default_cb}, 10821cfa752fSRamaswamy Tummala { NULL, 0, 0, NULL}}; 10831cfa752fSRamaswamy Tummala 10841cfa752fSRamaswamy Tummala /* 1085b509e89bSRishi Srivatsavai * structures for 'dladm show-simnet' 1086b509e89bSRishi Srivatsavai */ 1087b509e89bSRishi Srivatsavai typedef struct simnet_fields_buf_s 1088b509e89bSRishi Srivatsavai { 1089b509e89bSRishi Srivatsavai char simnet_name[DLPI_LINKNAME_MAX]; 1090b509e89bSRishi Srivatsavai char simnet_media[DLADM_STRSIZE]; 1091b509e89bSRishi Srivatsavai char simnet_macaddr[18]; 1092b509e89bSRishi Srivatsavai char simnet_otherlink[DLPI_LINKNAME_MAX]; 1093b509e89bSRishi Srivatsavai } simnet_fields_buf_t; 1094b509e89bSRishi Srivatsavai 10952b24ab6bSSebastien Roy static const ofmt_field_t simnet_fields[] = { 1096b509e89bSRishi Srivatsavai { "LINK", 12, 1097b509e89bSRishi Srivatsavai offsetof(simnet_fields_buf_t, simnet_name), print_default_cb}, 1098b509e89bSRishi Srivatsavai { "MEDIA", 20, 1099b509e89bSRishi Srivatsavai offsetof(simnet_fields_buf_t, simnet_media), print_default_cb}, 1100b509e89bSRishi Srivatsavai { "MACADDRESS", 18, 1101b509e89bSRishi Srivatsavai offsetof(simnet_fields_buf_t, simnet_macaddr), print_default_cb}, 1102b509e89bSRishi Srivatsavai { "OTHERLINK", 12, 1103b509e89bSRishi Srivatsavai offsetof(simnet_fields_buf_t, simnet_otherlink), print_default_cb}, 1104b509e89bSRishi Srivatsavai { NULL, 0, 0, NULL}} 1105b509e89bSRishi Srivatsavai ; 1106b509e89bSRishi Srivatsavai 1107b509e89bSRishi Srivatsavai /* 1108da14cebeSEric Cheng * structures for 'dladm show-usage' 1109da14cebeSEric Cheng */ 1110da14cebeSEric Cheng 1111da14cebeSEric Cheng typedef struct usage_fields_buf_s { 1112da14cebeSEric Cheng char usage_link[12]; 1113da14cebeSEric Cheng char usage_duration[10]; 1114da14cebeSEric Cheng char usage_ipackets[9]; 1115da14cebeSEric Cheng char usage_rbytes[10]; 1116da14cebeSEric Cheng char usage_opackets[9]; 1117da14cebeSEric Cheng char usage_obytes[10]; 1118da14cebeSEric Cheng char usage_bandwidth[14]; 1119da14cebeSEric Cheng } usage_fields_buf_t; 1120da14cebeSEric Cheng 11212b24ab6bSSebastien Roy static const ofmt_field_t usage_fields[] = { 11228002d411SSowmini Varadhan { "LINK", 13, 11238002d411SSowmini Varadhan offsetof(usage_fields_buf_t, usage_link), print_default_cb}, 11248002d411SSowmini Varadhan { "DURATION", 11, 11258002d411SSowmini Varadhan offsetof(usage_fields_buf_t, usage_duration), print_default_cb}, 11268002d411SSowmini Varadhan { "IPACKETS", 10, 11278002d411SSowmini Varadhan offsetof(usage_fields_buf_t, usage_ipackets), print_default_cb}, 11288002d411SSowmini Varadhan { "RBYTES", 11, 11298002d411SSowmini Varadhan offsetof(usage_fields_buf_t, usage_rbytes), print_default_cb}, 11308002d411SSowmini Varadhan { "OPACKETS", 10, 11318002d411SSowmini Varadhan offsetof(usage_fields_buf_t, usage_opackets), print_default_cb}, 11328002d411SSowmini Varadhan { "OBYTES", 11, 11338002d411SSowmini Varadhan offsetof(usage_fields_buf_t, usage_obytes), print_default_cb}, 11348002d411SSowmini Varadhan { "BANDWIDTH", 15, 11358002d411SSowmini Varadhan offsetof(usage_fields_buf_t, usage_bandwidth), print_default_cb}, 11368002d411SSowmini Varadhan { NULL, 0, 0, NULL}} 1137da14cebeSEric Cheng ; 1138da14cebeSEric Cheng 1139da14cebeSEric Cheng 1140da14cebeSEric Cheng /* 1141da14cebeSEric Cheng * structures for 'dladm show-usage link' 1142da14cebeSEric Cheng */ 1143da14cebeSEric Cheng 1144da14cebeSEric Cheng typedef struct usage_l_fields_buf_s { 1145da14cebeSEric Cheng char usage_l_link[12]; 1146da14cebeSEric Cheng char usage_l_stime[13]; 1147da14cebeSEric Cheng char usage_l_etime[13]; 1148da14cebeSEric Cheng char usage_l_rbytes[8]; 1149da14cebeSEric Cheng char usage_l_obytes[8]; 1150da14cebeSEric Cheng char usage_l_bandwidth[14]; 1151da14cebeSEric Cheng } usage_l_fields_buf_t; 1152da14cebeSEric Cheng 11532b24ab6bSSebastien Roy static const ofmt_field_t usage_l_fields[] = { 11548002d411SSowmini Varadhan /* name, field width, offset */ 11558002d411SSowmini Varadhan { "LINK", 13, 11568002d411SSowmini Varadhan offsetof(usage_l_fields_buf_t, usage_l_link), print_default_cb}, 11578002d411SSowmini Varadhan { "START", 14, 11588002d411SSowmini Varadhan offsetof(usage_l_fields_buf_t, usage_l_stime), print_default_cb}, 11598002d411SSowmini Varadhan { "END", 14, 11608002d411SSowmini Varadhan offsetof(usage_l_fields_buf_t, usage_l_etime), print_default_cb}, 11618002d411SSowmini Varadhan { "RBYTES", 9, 11628002d411SSowmini Varadhan offsetof(usage_l_fields_buf_t, usage_l_rbytes), print_default_cb}, 11638002d411SSowmini Varadhan { "OBYTES", 9, 11648002d411SSowmini Varadhan offsetof(usage_l_fields_buf_t, usage_l_obytes), print_default_cb}, 11658002d411SSowmini Varadhan { "BANDWIDTH", 15, 11668002d411SSowmini Varadhan offsetof(usage_l_fields_buf_t, usage_l_bandwidth), print_default_cb}, 11678002d411SSowmini Varadhan { NULL, 0, 0, NULL}} 1168da14cebeSEric Cheng ; 1169da14cebeSEric Cheng 11702b24ab6bSSebastien Roy /* IPTUN_*FLAG_INDEX values are indices into iptun_flags below. */ 11712b24ab6bSSebastien Roy enum { IPTUN_SFLAG_INDEX, IPTUN_IFLAG_INDEX, IPTUN_NUM_FLAGS }; 11722b24ab6bSSebastien Roy 11732b24ab6bSSebastien Roy /* 11742b24ab6bSSebastien Roy * structures for 'dladm show-iptun' 11752b24ab6bSSebastien Roy */ 11762b24ab6bSSebastien Roy typedef struct iptun_fields_buf_s { 11772b24ab6bSSebastien Roy char iptun_name[MAXLINKNAMELEN]; 11782b24ab6bSSebastien Roy char iptun_type[5]; 11792b24ab6bSSebastien Roy char iptun_laddr[NI_MAXHOST]; 11802b24ab6bSSebastien Roy char iptun_raddr[NI_MAXHOST]; 11812b24ab6bSSebastien Roy char iptun_flags[IPTUN_NUM_FLAGS + 1]; 11822b24ab6bSSebastien Roy } iptun_fields_buf_t; 11832b24ab6bSSebastien Roy 11842b24ab6bSSebastien Roy static const ofmt_field_t iptun_fields[] = { 11852b24ab6bSSebastien Roy { "LINK", 16, 11862b24ab6bSSebastien Roy offsetof(iptun_fields_buf_t, iptun_name), print_default_cb }, 11872b24ab6bSSebastien Roy { "TYPE", 6, 11882b24ab6bSSebastien Roy offsetof(iptun_fields_buf_t, iptun_type), print_default_cb }, 11892b24ab6bSSebastien Roy { "FLAGS", 7, 11902b24ab6bSSebastien Roy offsetof(iptun_fields_buf_t, iptun_flags), print_default_cb }, 11912b24ab6bSSebastien Roy { "LOCAL", 20, 11922b24ab6bSSebastien Roy offsetof(iptun_fields_buf_t, iptun_laddr), print_default_cb }, 11932b24ab6bSSebastien Roy { "REMOTE", 20, 11942b24ab6bSSebastien Roy offsetof(iptun_fields_buf_t, iptun_raddr), print_default_cb }, 11952b24ab6bSSebastien Roy { NULL, 0, 0, NULL} 11962b24ab6bSSebastien Roy }; 11972b24ab6bSSebastien Roy 11984eaa4710SRishi Srivatsavai /* 11994eaa4710SRishi Srivatsavai * structures for 'dladm show-bridge'. These are based on sections 14.8.1.1.3 12004eaa4710SRishi Srivatsavai * and 14.8.1.2.2 of IEEE 802.1D-2004. 12014eaa4710SRishi Srivatsavai */ 12024eaa4710SRishi Srivatsavai typedef struct bridge_fields_buf_s { 12034eaa4710SRishi Srivatsavai char bridge_name[MAXLINKNAMELEN]; /* 14.4.1.2.3(b) */ 12044eaa4710SRishi Srivatsavai char bridge_protect[7]; /* stp or trill */ 12054eaa4710SRishi Srivatsavai char bridge_address[24]; /* 17.18.3, 7.12.5, 14.4.1.2.3(a) */ 12064eaa4710SRishi Srivatsavai char bridge_priority[7]; /* 17.18.3 9.2.5 - only upper 4 bits */ 12074eaa4710SRishi Srivatsavai char bridge_bmaxage[7]; /* 17.18.4 configured */ 12084eaa4710SRishi Srivatsavai char bridge_bhellotime[7]; /* 17.18.4 configured */ 12094eaa4710SRishi Srivatsavai char bridge_bfwddelay[7]; /* 17.18.4 configured */ 12104eaa4710SRishi Srivatsavai char bridge_forceproto[3]; /* 17.13.4 configured */ 12114eaa4710SRishi Srivatsavai char bridge_tctime[12]; /* 14.8.1.1.3(b) */ 12124eaa4710SRishi Srivatsavai char bridge_tccount[12]; /* 17.17.8 */ 12134eaa4710SRishi Srivatsavai char bridge_tchange[12]; /* 17.17.8 */ 12144eaa4710SRishi Srivatsavai char bridge_desroot[24]; /* 17.18.6 priority "/" MAC */ 12154eaa4710SRishi Srivatsavai char bridge_rootcost[12]; /* 17.18.6 */ 12164eaa4710SRishi Srivatsavai char bridge_rootport[12]; /* 17.18.6 */ 12174eaa4710SRishi Srivatsavai char bridge_maxage[7]; /* 17.18.7 for root */ 12184eaa4710SRishi Srivatsavai char bridge_hellotime[7]; /* 17.13.6 for root */ 12194eaa4710SRishi Srivatsavai char bridge_fwddelay[7]; /* 17.13.5 for root */ 12204eaa4710SRishi Srivatsavai char bridge_holdtime[12]; /* 17.13.12 for root */ 12214eaa4710SRishi Srivatsavai } bridge_fields_buf_t; 12224eaa4710SRishi Srivatsavai 12234eaa4710SRishi Srivatsavai static ofmt_field_t bridge_fields[] = { 12244eaa4710SRishi Srivatsavai /* name, field width, offset, callback */ 12254eaa4710SRishi Srivatsavai { "BRIDGE", 12, 12264eaa4710SRishi Srivatsavai offsetof(bridge_fields_buf_t, bridge_name), print_default_cb }, 12274eaa4710SRishi Srivatsavai { "PROTECT", 8, 12284eaa4710SRishi Srivatsavai offsetof(bridge_fields_buf_t, bridge_protect), print_default_cb }, 12294eaa4710SRishi Srivatsavai { "ADDRESS", 19, 12304eaa4710SRishi Srivatsavai offsetof(bridge_fields_buf_t, bridge_address), print_default_cb }, 12314eaa4710SRishi Srivatsavai { "PRIORITY", 9, 12324eaa4710SRishi Srivatsavai offsetof(bridge_fields_buf_t, bridge_priority), print_default_cb }, 12334eaa4710SRishi Srivatsavai { "BMAXAGE", 8, 12344eaa4710SRishi Srivatsavai offsetof(bridge_fields_buf_t, bridge_bmaxage), print_default_cb }, 12354eaa4710SRishi Srivatsavai { "BHELLOTIME", 11, 12364eaa4710SRishi Srivatsavai offsetof(bridge_fields_buf_t, bridge_bhellotime), print_default_cb }, 12374eaa4710SRishi Srivatsavai { "BFWDDELAY", 10, 12384eaa4710SRishi Srivatsavai offsetof(bridge_fields_buf_t, bridge_bfwddelay), print_default_cb }, 12394eaa4710SRishi Srivatsavai { "FORCEPROTO", 11, 12404eaa4710SRishi Srivatsavai offsetof(bridge_fields_buf_t, bridge_forceproto), print_default_cb }, 12414eaa4710SRishi Srivatsavai { "TCTIME", 10, 12424eaa4710SRishi Srivatsavai offsetof(bridge_fields_buf_t, bridge_tctime), print_default_cb }, 12434eaa4710SRishi Srivatsavai { "TCCOUNT", 10, 12444eaa4710SRishi Srivatsavai offsetof(bridge_fields_buf_t, bridge_tccount), print_default_cb }, 12454eaa4710SRishi Srivatsavai { "TCHANGE", 10, 12464eaa4710SRishi Srivatsavai offsetof(bridge_fields_buf_t, bridge_tchange), print_default_cb }, 12474eaa4710SRishi Srivatsavai { "DESROOT", 23, 12484eaa4710SRishi Srivatsavai offsetof(bridge_fields_buf_t, bridge_desroot), print_default_cb }, 12494eaa4710SRishi Srivatsavai { "ROOTCOST", 11, 12504eaa4710SRishi Srivatsavai offsetof(bridge_fields_buf_t, bridge_rootcost), print_default_cb }, 12514eaa4710SRishi Srivatsavai { "ROOTPORT", 11, 12524eaa4710SRishi Srivatsavai offsetof(bridge_fields_buf_t, bridge_rootport), print_default_cb }, 12534eaa4710SRishi Srivatsavai { "MAXAGE", 8, 12544eaa4710SRishi Srivatsavai offsetof(bridge_fields_buf_t, bridge_maxage), print_default_cb }, 12554eaa4710SRishi Srivatsavai { "HELLOTIME", 10, 12564eaa4710SRishi Srivatsavai offsetof(bridge_fields_buf_t, bridge_hellotime), print_default_cb }, 12574eaa4710SRishi Srivatsavai { "FWDDELAY", 9, 12584eaa4710SRishi Srivatsavai offsetof(bridge_fields_buf_t, bridge_fwddelay), print_default_cb }, 12594eaa4710SRishi Srivatsavai { "HOLDTIME", 9, 12604eaa4710SRishi Srivatsavai offsetof(bridge_fields_buf_t, bridge_holdtime), print_default_cb }, 12614eaa4710SRishi Srivatsavai { NULL, 0, 0, NULL}}; 12624eaa4710SRishi Srivatsavai 12634eaa4710SRishi Srivatsavai /* 12644eaa4710SRishi Srivatsavai * structures for 'dladm show-bridge -l'. These are based on 14.4.1.2.3 and 12654eaa4710SRishi Srivatsavai * 14.8.2.1.3 of IEEE 802.1D-2004. 12664eaa4710SRishi Srivatsavai */ 12674eaa4710SRishi Srivatsavai typedef struct bridge_link_fields_buf_s { 12684eaa4710SRishi Srivatsavai char bridgel_link[MAXLINKNAMELEN]; 12694eaa4710SRishi Srivatsavai char bridgel_index[7]; /* 14.4.1.2.3(d1) */ 12704eaa4710SRishi Srivatsavai char bridgel_state[11]; /* 14.8.2.1.3(b) */ 12714eaa4710SRishi Srivatsavai char bridgel_uptime[7]; /* 14.8.2.1.3(a) */ 12724eaa4710SRishi Srivatsavai char bridgel_opercost[7] /* 14.8.2.1.3(d) */; 12734eaa4710SRishi Srivatsavai char bridgel_operp2p[4]; /* 14.8.2.1.3(p) */ 12744eaa4710SRishi Srivatsavai char bridgel_operedge[4]; /* 14.8.2.1.3(k) */ 12754eaa4710SRishi Srivatsavai char bridgel_desroot[23]; /* 14.8.2.1.3(e) */ 12764eaa4710SRishi Srivatsavai char bridgel_descost[12]; /* 14.8.2.1.3(f) */ 12774eaa4710SRishi Srivatsavai char bridgel_desbridge[23]; /* 14.8.2.1.3(g) */ 12784eaa4710SRishi Srivatsavai char bridgel_desport[7]; /* 14.8.2.1.3(h) */ 12794eaa4710SRishi Srivatsavai char bridgel_tcack[4]; /* 14.8.2.1.3(i) */ 12804eaa4710SRishi Srivatsavai } bridge_link_fields_buf_t; 12814eaa4710SRishi Srivatsavai 12824eaa4710SRishi Srivatsavai static ofmt_field_t bridge_link_fields[] = { 12834eaa4710SRishi Srivatsavai /* name, field width, offset, callback */ 12844eaa4710SRishi Srivatsavai { "LINK", 12, 12854eaa4710SRishi Srivatsavai offsetof(bridge_link_fields_buf_t, bridgel_link), print_default_cb }, 12864eaa4710SRishi Srivatsavai { "INDEX", 8, 12874eaa4710SRishi Srivatsavai offsetof(bridge_link_fields_buf_t, bridgel_index), print_default_cb }, 12884eaa4710SRishi Srivatsavai { "STATE", 12, 12894eaa4710SRishi Srivatsavai offsetof(bridge_link_fields_buf_t, bridgel_state), print_default_cb }, 12904eaa4710SRishi Srivatsavai { "UPTIME", 8, 12914eaa4710SRishi Srivatsavai offsetof(bridge_link_fields_buf_t, bridgel_uptime), print_default_cb }, 12924eaa4710SRishi Srivatsavai { "OPERCOST", 9, 12934eaa4710SRishi Srivatsavai offsetof(bridge_link_fields_buf_t, bridgel_opercost), print_default_cb }, 12944eaa4710SRishi Srivatsavai { "OPERP2P", 8, 12954eaa4710SRishi Srivatsavai offsetof(bridge_link_fields_buf_t, bridgel_operp2p), print_default_cb }, 12964eaa4710SRishi Srivatsavai { "OPEREDGE", 9, 12974eaa4710SRishi Srivatsavai offsetof(bridge_link_fields_buf_t, bridgel_operedge), print_default_cb }, 12984eaa4710SRishi Srivatsavai { "DESROOT", 22, 12994eaa4710SRishi Srivatsavai offsetof(bridge_link_fields_buf_t, bridgel_desroot), print_default_cb }, 13004eaa4710SRishi Srivatsavai { "DESCOST", 11, 13014eaa4710SRishi Srivatsavai offsetof(bridge_link_fields_buf_t, bridgel_descost), print_default_cb }, 13024eaa4710SRishi Srivatsavai { "DESBRIDGE", 22, 13034eaa4710SRishi Srivatsavai offsetof(bridge_link_fields_buf_t, bridgel_desbridge), print_default_cb }, 13044eaa4710SRishi Srivatsavai { "DESPORT", 8, 13054eaa4710SRishi Srivatsavai offsetof(bridge_link_fields_buf_t, bridgel_desport), print_default_cb }, 13064eaa4710SRishi Srivatsavai { "TCACK", 6, 13074eaa4710SRishi Srivatsavai offsetof(bridge_link_fields_buf_t, bridgel_tcack), print_default_cb }, 13084eaa4710SRishi Srivatsavai { NULL, 0, 0, NULL}}; 13094eaa4710SRishi Srivatsavai 13104eaa4710SRishi Srivatsavai /* 13114eaa4710SRishi Srivatsavai * structures for 'dladm show-bridge -s'. These are not based on IEEE 13124eaa4710SRishi Srivatsavai * 802.1D-2004. 13134eaa4710SRishi Srivatsavai */ 13144eaa4710SRishi Srivatsavai #define ULONG_DIG (((sizeof (ulong_t) * NBBY) * 3 / 10) + 1) 13154eaa4710SRishi Srivatsavai #define UINT64_DIG (((sizeof (uint64_t) * NBBY) * 3 / 10) + 1) 13164eaa4710SRishi Srivatsavai typedef struct bridge_statfields_buf_s { 13174eaa4710SRishi Srivatsavai char bridges_name[MAXLINKNAMELEN]; 13184eaa4710SRishi Srivatsavai char bridges_drops[UINT64_DIG]; 13194eaa4710SRishi Srivatsavai char bridges_forwards[UINT64_DIG]; 13204eaa4710SRishi Srivatsavai char bridges_mbcast[UINT64_DIG]; 13214eaa4710SRishi Srivatsavai char bridges_unknown[UINT64_DIG]; 13224eaa4710SRishi Srivatsavai char bridges_recv[UINT64_DIG]; 13234eaa4710SRishi Srivatsavai char bridges_sent[UINT64_DIG]; 13244eaa4710SRishi Srivatsavai } bridge_statfields_buf_t; 13254eaa4710SRishi Srivatsavai 13264eaa4710SRishi Srivatsavai static ofmt_field_t bridge_statfields[] = { 13274eaa4710SRishi Srivatsavai /* name, field width, offset, callback */ 13284eaa4710SRishi Srivatsavai { "BRIDGE", 12, 13294eaa4710SRishi Srivatsavai offsetof(bridge_statfields_buf_t, bridges_name), print_default_cb }, 13304eaa4710SRishi Srivatsavai { "DROPS", 12, 13314eaa4710SRishi Srivatsavai offsetof(bridge_statfields_buf_t, bridges_drops), print_default_cb }, 13324eaa4710SRishi Srivatsavai { "FORWARDS", 12, 13334eaa4710SRishi Srivatsavai offsetof(bridge_statfields_buf_t, bridges_forwards), print_default_cb }, 13344eaa4710SRishi Srivatsavai { "MBCAST", 12, 13354eaa4710SRishi Srivatsavai offsetof(bridge_statfields_buf_t, bridges_mbcast), print_default_cb }, 13364eaa4710SRishi Srivatsavai { "UNKNOWN", 12, 13374eaa4710SRishi Srivatsavai offsetof(bridge_statfields_buf_t, bridges_unknown), print_default_cb }, 13384eaa4710SRishi Srivatsavai { "RECV", 12, 13394eaa4710SRishi Srivatsavai offsetof(bridge_statfields_buf_t, bridges_recv), print_default_cb }, 13404eaa4710SRishi Srivatsavai { "SENT", 12, 13414eaa4710SRishi Srivatsavai offsetof(bridge_statfields_buf_t, bridges_sent), print_default_cb }, 13424eaa4710SRishi Srivatsavai { NULL, 0, 0, NULL}}; 13434eaa4710SRishi Srivatsavai 13444eaa4710SRishi Srivatsavai /* 13454eaa4710SRishi Srivatsavai * structures for 'dladm show-bridge -s -l'. These are based in part on 13464eaa4710SRishi Srivatsavai * section 14.6.1.1.3 of IEEE 802.1D-2004. 13474eaa4710SRishi Srivatsavai */ 13484eaa4710SRishi Srivatsavai typedef struct bridge_link_statfields_buf_s { 13494eaa4710SRishi Srivatsavai char bridgels_link[MAXLINKNAMELEN]; 13504eaa4710SRishi Srivatsavai char bridgels_cfgbpdu[ULONG_DIG]; 13514eaa4710SRishi Srivatsavai char bridgels_tcnbpdu[ULONG_DIG]; 13524eaa4710SRishi Srivatsavai char bridgels_rstpbpdu[ULONG_DIG]; 13534eaa4710SRishi Srivatsavai char bridgels_txbpdu[ULONG_DIG]; 13544eaa4710SRishi Srivatsavai char bridgels_drops[UINT64_DIG]; /* 14.6.1.1.3(d) */ 13554eaa4710SRishi Srivatsavai char bridgels_recv[UINT64_DIG]; /* 14.6.1.1.3(a) */ 13564eaa4710SRishi Srivatsavai char bridgels_xmit[UINT64_DIG]; /* 14.6.1.1.3(c) */ 13574eaa4710SRishi Srivatsavai } bridge_link_statfields_buf_t; 13584eaa4710SRishi Srivatsavai 13594eaa4710SRishi Srivatsavai static ofmt_field_t bridge_link_statfields[] = { 13604eaa4710SRishi Srivatsavai /* name, field width, offset, callback */ 13614eaa4710SRishi Srivatsavai { "LINK", 12, 13624eaa4710SRishi Srivatsavai offsetof(bridge_link_statfields_buf_t, bridgels_link), print_default_cb }, 13634eaa4710SRishi Srivatsavai { "CFGBPDU", 9, 13644eaa4710SRishi Srivatsavai offsetof(bridge_link_statfields_buf_t, bridgels_cfgbpdu), 13654eaa4710SRishi Srivatsavai print_default_cb }, 13664eaa4710SRishi Srivatsavai { "TCNBPDU", 9, 13674eaa4710SRishi Srivatsavai offsetof(bridge_link_statfields_buf_t, bridgels_tcnbpdu), 13684eaa4710SRishi Srivatsavai print_default_cb }, 13694eaa4710SRishi Srivatsavai { "RSTPBPDU", 9, 13704eaa4710SRishi Srivatsavai offsetof(bridge_link_statfields_buf_t, bridgels_rstpbpdu), 13714eaa4710SRishi Srivatsavai print_default_cb }, 13724eaa4710SRishi Srivatsavai { "TXBPDU", 9, 13734eaa4710SRishi Srivatsavai offsetof(bridge_link_statfields_buf_t, bridgels_txbpdu), print_default_cb }, 13744eaa4710SRishi Srivatsavai { "DROPS", 9, 13754eaa4710SRishi Srivatsavai offsetof(bridge_link_statfields_buf_t, bridgels_drops), print_default_cb }, 13764eaa4710SRishi Srivatsavai { "RECV", 9, 13774eaa4710SRishi Srivatsavai offsetof(bridge_link_statfields_buf_t, bridgels_recv), print_default_cb }, 13784eaa4710SRishi Srivatsavai { "XMIT", 9, 13794eaa4710SRishi Srivatsavai offsetof(bridge_link_statfields_buf_t, bridgels_xmit), print_default_cb }, 13804eaa4710SRishi Srivatsavai { NULL, 0, 0, NULL}}; 13814eaa4710SRishi Srivatsavai 13824eaa4710SRishi Srivatsavai /* 13834eaa4710SRishi Srivatsavai * structures for 'dladm show-bridge -f'. These are based in part on 13844eaa4710SRishi Srivatsavai * section 14.7.6.3.3 of IEEE 802.1D-2004. 13854eaa4710SRishi Srivatsavai */ 13864eaa4710SRishi Srivatsavai typedef struct bridge_fwd_fields_buf_s { 13874eaa4710SRishi Srivatsavai char bridgef_dest[18]; /* 14.7.6.3.3(a) */ 13884eaa4710SRishi Srivatsavai char bridgef_age[8]; 13894eaa4710SRishi Srivatsavai char bridgef_flags[6]; 13904eaa4710SRishi Srivatsavai char bridgef_output[MAXLINKNAMELEN]; /* 14.7.6.3.3(c) */ 13914eaa4710SRishi Srivatsavai } bridge_fwd_fields_buf_t; 13924eaa4710SRishi Srivatsavai 13934eaa4710SRishi Srivatsavai static ofmt_field_t bridge_fwd_fields[] = { 13944eaa4710SRishi Srivatsavai /* name, field width, offset, callback */ 13954eaa4710SRishi Srivatsavai { "DEST", 17, 13964eaa4710SRishi Srivatsavai offsetof(bridge_fwd_fields_buf_t, bridgef_dest), print_default_cb }, 13974eaa4710SRishi Srivatsavai { "AGE", 7, 13984eaa4710SRishi Srivatsavai offsetof(bridge_fwd_fields_buf_t, bridgef_age), print_default_cb }, 13994eaa4710SRishi Srivatsavai { "FLAGS", 6, 14004eaa4710SRishi Srivatsavai offsetof(bridge_fwd_fields_buf_t, bridgef_flags), print_default_cb }, 14014eaa4710SRishi Srivatsavai { "OUTPUT", 12, 14024eaa4710SRishi Srivatsavai offsetof(bridge_fwd_fields_buf_t, bridgef_output), print_default_cb }, 14034eaa4710SRishi Srivatsavai { NULL, 0, 0, NULL}}; 14044eaa4710SRishi Srivatsavai 14054eaa4710SRishi Srivatsavai /* 14064eaa4710SRishi Srivatsavai * structures for 'dladm show-bridge -t'. 14074eaa4710SRishi Srivatsavai */ 14084eaa4710SRishi Srivatsavai typedef struct bridge_trill_fields_buf_s { 14094eaa4710SRishi Srivatsavai char bridget_nick[6]; 14104eaa4710SRishi Srivatsavai char bridget_flags[6]; 14114eaa4710SRishi Srivatsavai char bridget_link[MAXLINKNAMELEN]; 14124eaa4710SRishi Srivatsavai char bridget_nexthop[18]; 14134eaa4710SRishi Srivatsavai } bridge_trill_fields_buf_t; 14144eaa4710SRishi Srivatsavai 14154eaa4710SRishi Srivatsavai static ofmt_field_t bridge_trill_fields[] = { 14164eaa4710SRishi Srivatsavai /* name, field width, offset, callback */ 14174eaa4710SRishi Srivatsavai { "NICK", 5, 14184eaa4710SRishi Srivatsavai offsetof(bridge_trill_fields_buf_t, bridget_nick), print_default_cb }, 14194eaa4710SRishi Srivatsavai { "FLAGS", 6, 14204eaa4710SRishi Srivatsavai offsetof(bridge_trill_fields_buf_t, bridget_flags), print_default_cb }, 14214eaa4710SRishi Srivatsavai { "LINK", 12, 14224eaa4710SRishi Srivatsavai offsetof(bridge_trill_fields_buf_t, bridget_link), print_default_cb }, 14234eaa4710SRishi Srivatsavai { "NEXTHOP", 17, 14244eaa4710SRishi Srivatsavai offsetof(bridge_trill_fields_buf_t, bridget_nexthop), print_default_cb }, 14254eaa4710SRishi Srivatsavai { NULL, 0, 0, NULL}}; 14264eaa4710SRishi Srivatsavai 14277c478bd9Sstevel@tonic-gate static char *progname; 14280ba2cbe9Sxc151355 static sig_atomic_t signalled; 14297c478bd9Sstevel@tonic-gate 14304ac67f02SAnurag S. Maskey /* 14314ac67f02SAnurag S. Maskey * Handle to libdladm. Opened in main() before the sub-command 14324ac67f02SAnurag S. Maskey * specific function is called. 14334ac67f02SAnurag S. Maskey */ 14344ac67f02SAnurag S. Maskey static dladm_handle_t handle = NULL; 14354ac67f02SAnurag S. Maskey 1436da14cebeSEric Cheng #define DLADM_ETHERSTUB_NAME "etherstub" 1437da14cebeSEric Cheng #define DLADM_IS_ETHERSTUB(id) (id == DATALINK_INVALID_LINKID) 1438da14cebeSEric Cheng 14397c478bd9Sstevel@tonic-gate static void 14407c478bd9Sstevel@tonic-gate usage(void) 14417c478bd9Sstevel@tonic-gate { 14428d5c46e6Sam223141 int i; 14438d5c46e6Sam223141 cmd_t *cmdp; 14448d5c46e6Sam223141 (void) fprintf(stderr, gettext("usage: dladm <subcommand> <args> ..." 14458d5c46e6Sam223141 "\n")); 14468d5c46e6Sam223141 for (i = 0; i < sizeof (cmds) / sizeof (cmds[0]); i++) { 14478d5c46e6Sam223141 cmdp = &cmds[i]; 14488d5c46e6Sam223141 if (cmdp->c_usage != NULL) 14498d5c46e6Sam223141 (void) fprintf(stderr, "%s\n", gettext(cmdp->c_usage)); 14508d5c46e6Sam223141 } 14514ac67f02SAnurag S. Maskey 14524ac67f02SAnurag S. Maskey /* close dladm handle if it was opened */ 14534ac67f02SAnurag S. Maskey if (handle != NULL) 14544ac67f02SAnurag S. Maskey dladm_close(handle); 14554ac67f02SAnurag S. Maskey 14562b24ab6bSSebastien Roy exit(EXIT_FAILURE); 14577c478bd9Sstevel@tonic-gate } 14587c478bd9Sstevel@tonic-gate 14597c478bd9Sstevel@tonic-gate int 14607c478bd9Sstevel@tonic-gate main(int argc, char *argv[]) 14617c478bd9Sstevel@tonic-gate { 14627c478bd9Sstevel@tonic-gate int i; 14637c478bd9Sstevel@tonic-gate cmd_t *cmdp; 14644ac67f02SAnurag S. Maskey dladm_status_t status; 14657c478bd9Sstevel@tonic-gate 14667c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 14677c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) 14687c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" 14697c478bd9Sstevel@tonic-gate #endif 14707c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 14717c478bd9Sstevel@tonic-gate 14727c478bd9Sstevel@tonic-gate progname = argv[0]; 14737c478bd9Sstevel@tonic-gate 14747c478bd9Sstevel@tonic-gate if (argc < 2) 14757c478bd9Sstevel@tonic-gate usage(); 14767c478bd9Sstevel@tonic-gate 14777c478bd9Sstevel@tonic-gate for (i = 0; i < sizeof (cmds) / sizeof (cmds[0]); i++) { 14787c478bd9Sstevel@tonic-gate cmdp = &cmds[i]; 14797c478bd9Sstevel@tonic-gate if (strcmp(argv[1], cmdp->c_name) == 0) { 14804ac67f02SAnurag S. Maskey /* Open the libdladm handle */ 14814ac67f02SAnurag S. Maskey if ((status = dladm_open(&handle)) != DLADM_STATUS_OK) { 14824ac67f02SAnurag S. Maskey die_dlerr(status, 14834ac67f02SAnurag S. Maskey "could not open /dev/dld"); 14844ac67f02SAnurag S. Maskey } 14854ac67f02SAnurag S. Maskey 14868d5c46e6Sam223141 cmdp->c_fn(argc - 1, &argv[1], cmdp->c_usage); 14874ac67f02SAnurag S. Maskey 14884ac67f02SAnurag S. Maskey dladm_close(handle); 14892b24ab6bSSebastien Roy return (EXIT_SUCCESS); 14907c478bd9Sstevel@tonic-gate } 14917c478bd9Sstevel@tonic-gate } 14927c478bd9Sstevel@tonic-gate 14937c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("%s: unknown subcommand '%s'\n"), 14947c478bd9Sstevel@tonic-gate progname, argv[1]); 14957c478bd9Sstevel@tonic-gate usage(); 14962b24ab6bSSebastien Roy return (EXIT_FAILURE); 14977c478bd9Sstevel@tonic-gate } 14987c478bd9Sstevel@tonic-gate 1499da14cebeSEric Cheng /*ARGSUSED*/ 1500da14cebeSEric Cheng static int 1501da14cebeSEric Cheng show_usage_date(dladm_usage_t *usage, void *arg) 1502da14cebeSEric Cheng { 1503ae6aa22aSVenugopal Iyer show_usage_state_t *state = (show_usage_state_t *)arg; 1504da14cebeSEric Cheng time_t stime; 1505da14cebeSEric Cheng char timebuf[20]; 1506ae6aa22aSVenugopal Iyer dladm_status_t status; 1507ae6aa22aSVenugopal Iyer uint32_t flags; 1508ae6aa22aSVenugopal Iyer 1509ae6aa22aSVenugopal Iyer /* 1510ae6aa22aSVenugopal Iyer * Only show usage information for existing links unless '-a' 1511ae6aa22aSVenugopal Iyer * is specified. 1512ae6aa22aSVenugopal Iyer */ 1513ae6aa22aSVenugopal Iyer if (!state->us_showall) { 1514ae6aa22aSVenugopal Iyer if ((status = dladm_name2info(handle, usage->du_name, 1515ae6aa22aSVenugopal Iyer NULL, &flags, NULL, NULL)) != DLADM_STATUS_OK) { 1516ae6aa22aSVenugopal Iyer return (status); 1517ae6aa22aSVenugopal Iyer } 1518ae6aa22aSVenugopal Iyer if ((flags & DLADM_OPT_ACTIVE) == 0) 1519ae6aa22aSVenugopal Iyer return (DLADM_STATUS_LINKINVAL); 1520ae6aa22aSVenugopal Iyer } 1521da14cebeSEric Cheng 1522da14cebeSEric Cheng stime = usage->du_stime; 1523da14cebeSEric Cheng (void) strftime(timebuf, sizeof (timebuf), "%m/%d/%Y", 1524da14cebeSEric Cheng localtime(&stime)); 1525da14cebeSEric Cheng (void) printf("%s\n", timebuf); 1526da14cebeSEric Cheng 1527da14cebeSEric Cheng return (DLADM_STATUS_OK); 1528da14cebeSEric Cheng } 1529da14cebeSEric Cheng 1530da14cebeSEric Cheng static int 1531da14cebeSEric Cheng show_usage_time(dladm_usage_t *usage, void *arg) 1532da14cebeSEric Cheng { 1533da14cebeSEric Cheng show_usage_state_t *state = (show_usage_state_t *)arg; 1534da14cebeSEric Cheng char buf[DLADM_STRSIZE]; 1535da14cebeSEric Cheng usage_l_fields_buf_t ubuf; 1536da14cebeSEric Cheng time_t time; 1537da14cebeSEric Cheng double bw; 1538ae6aa22aSVenugopal Iyer dladm_status_t status; 1539ae6aa22aSVenugopal Iyer uint32_t flags; 1540ae6aa22aSVenugopal Iyer 1541ae6aa22aSVenugopal Iyer /* 1542ae6aa22aSVenugopal Iyer * Only show usage information for existing links unless '-a' 1543ae6aa22aSVenugopal Iyer * is specified. 1544ae6aa22aSVenugopal Iyer */ 1545ae6aa22aSVenugopal Iyer if (!state->us_showall) { 1546ae6aa22aSVenugopal Iyer if ((status = dladm_name2info(handle, usage->du_name, 1547ae6aa22aSVenugopal Iyer NULL, &flags, NULL, NULL)) != DLADM_STATUS_OK) { 1548ae6aa22aSVenugopal Iyer return (status); 1549ae6aa22aSVenugopal Iyer } 1550ae6aa22aSVenugopal Iyer if ((flags & DLADM_OPT_ACTIVE) == 0) 1551ae6aa22aSVenugopal Iyer return (DLADM_STATUS_LINKINVAL); 1552ae6aa22aSVenugopal Iyer } 1553da14cebeSEric Cheng 1554da14cebeSEric Cheng if (state->us_plot) { 1555da14cebeSEric Cheng if (!state->us_printheader) { 1556da14cebeSEric Cheng if (state->us_first) { 1557da14cebeSEric Cheng (void) printf("# Time"); 1558da14cebeSEric Cheng state->us_first = B_FALSE; 1559da14cebeSEric Cheng } 1560da14cebeSEric Cheng (void) printf(" %s", usage->du_name); 1561da14cebeSEric Cheng if (usage->du_last) { 1562da14cebeSEric Cheng (void) printf("\n"); 1563da14cebeSEric Cheng state->us_first = B_TRUE; 1564da14cebeSEric Cheng state->us_printheader = B_TRUE; 1565da14cebeSEric Cheng } 1566da14cebeSEric Cheng } else { 1567da14cebeSEric Cheng if (state->us_first) { 1568da14cebeSEric Cheng time = usage->du_etime; 1569da14cebeSEric Cheng (void) strftime(buf, sizeof (buf), "%T", 1570da14cebeSEric Cheng localtime(&time)); 1571da14cebeSEric Cheng state->us_first = B_FALSE; 1572da14cebeSEric Cheng (void) printf("%s", buf); 1573da14cebeSEric Cheng } 1574da14cebeSEric Cheng bw = (double)usage->du_bandwidth/1000; 1575da14cebeSEric Cheng (void) printf(" %.2f", bw); 1576da14cebeSEric Cheng if (usage->du_last) { 1577da14cebeSEric Cheng (void) printf("\n"); 1578da14cebeSEric Cheng state->us_first = B_TRUE; 1579da14cebeSEric Cheng } 1580da14cebeSEric Cheng } 1581da14cebeSEric Cheng return (DLADM_STATUS_OK); 1582da14cebeSEric Cheng } 1583da14cebeSEric Cheng 1584da14cebeSEric Cheng bzero(&ubuf, sizeof (ubuf)); 1585da14cebeSEric Cheng 1586da14cebeSEric Cheng (void) snprintf(ubuf.usage_l_link, sizeof (ubuf.usage_l_link), "%s", 1587da14cebeSEric Cheng usage->du_name); 1588da14cebeSEric Cheng time = usage->du_stime; 1589da14cebeSEric Cheng (void) strftime(buf, sizeof (buf), "%T", localtime(&time)); 1590da14cebeSEric Cheng (void) snprintf(ubuf.usage_l_stime, sizeof (ubuf.usage_l_stime), "%s", 1591da14cebeSEric Cheng buf); 1592da14cebeSEric Cheng time = usage->du_etime; 1593da14cebeSEric Cheng (void) strftime(buf, sizeof (buf), "%T", localtime(&time)); 1594da14cebeSEric Cheng (void) snprintf(ubuf.usage_l_etime, sizeof (ubuf.usage_l_etime), "%s", 1595da14cebeSEric Cheng buf); 1596da14cebeSEric Cheng (void) snprintf(ubuf.usage_l_rbytes, sizeof (ubuf.usage_l_rbytes), 1597da14cebeSEric Cheng "%llu", usage->du_rbytes); 1598da14cebeSEric Cheng (void) snprintf(ubuf.usage_l_obytes, sizeof (ubuf.usage_l_obytes), 1599da14cebeSEric Cheng "%llu", usage->du_obytes); 1600da14cebeSEric Cheng (void) snprintf(ubuf.usage_l_bandwidth, sizeof (ubuf.usage_l_bandwidth), 1601da14cebeSEric Cheng "%s Mbps", dladm_bw2str(usage->du_bandwidth, buf)); 1602da14cebeSEric Cheng 16038002d411SSowmini Varadhan ofmt_print(state->us_ofmt, &ubuf); 1604da14cebeSEric Cheng return (DLADM_STATUS_OK); 1605da14cebeSEric Cheng } 1606da14cebeSEric Cheng 1607da14cebeSEric Cheng static int 1608da14cebeSEric Cheng show_usage_res(dladm_usage_t *usage, void *arg) 1609da14cebeSEric Cheng { 1610da14cebeSEric Cheng show_usage_state_t *state = (show_usage_state_t *)arg; 1611da14cebeSEric Cheng char buf[DLADM_STRSIZE]; 1612da14cebeSEric Cheng usage_fields_buf_t ubuf; 1613ae6aa22aSVenugopal Iyer dladm_status_t status; 1614ae6aa22aSVenugopal Iyer uint32_t flags; 1615ae6aa22aSVenugopal Iyer 1616ae6aa22aSVenugopal Iyer /* 1617ae6aa22aSVenugopal Iyer * Only show usage information for existing links unless '-a' 1618ae6aa22aSVenugopal Iyer * is specified. 1619ae6aa22aSVenugopal Iyer */ 1620ae6aa22aSVenugopal Iyer if (!state->us_showall) { 1621ae6aa22aSVenugopal Iyer if ((status = dladm_name2info(handle, usage->du_name, 1622ae6aa22aSVenugopal Iyer NULL, &flags, NULL, NULL)) != DLADM_STATUS_OK) { 1623ae6aa22aSVenugopal Iyer return (status); 1624ae6aa22aSVenugopal Iyer } 1625ae6aa22aSVenugopal Iyer if ((flags & DLADM_OPT_ACTIVE) == 0) 1626ae6aa22aSVenugopal Iyer return (DLADM_STATUS_LINKINVAL); 1627ae6aa22aSVenugopal Iyer } 1628da14cebeSEric Cheng 1629da14cebeSEric Cheng bzero(&ubuf, sizeof (ubuf)); 1630da14cebeSEric Cheng 1631da14cebeSEric Cheng (void) snprintf(ubuf.usage_link, sizeof (ubuf.usage_link), "%s", 1632da14cebeSEric Cheng usage->du_name); 1633da14cebeSEric Cheng (void) snprintf(ubuf.usage_duration, sizeof (ubuf.usage_duration), 1634da14cebeSEric Cheng "%llu", usage->du_duration); 1635da14cebeSEric Cheng (void) snprintf(ubuf.usage_ipackets, sizeof (ubuf.usage_ipackets), 1636da14cebeSEric Cheng "%llu", usage->du_ipackets); 1637da14cebeSEric Cheng (void) snprintf(ubuf.usage_rbytes, sizeof (ubuf.usage_rbytes), 1638da14cebeSEric Cheng "%llu", usage->du_rbytes); 1639da14cebeSEric Cheng (void) snprintf(ubuf.usage_opackets, sizeof (ubuf.usage_opackets), 1640da14cebeSEric Cheng "%llu", usage->du_opackets); 1641da14cebeSEric Cheng (void) snprintf(ubuf.usage_obytes, sizeof (ubuf.usage_obytes), 1642da14cebeSEric Cheng "%llu", usage->du_obytes); 1643da14cebeSEric Cheng (void) snprintf(ubuf.usage_bandwidth, sizeof (ubuf.usage_bandwidth), 1644da14cebeSEric Cheng "%s Mbps", dladm_bw2str(usage->du_bandwidth, buf)); 1645da14cebeSEric Cheng 16468002d411SSowmini Varadhan ofmt_print(state->us_ofmt, &ubuf); 1647da14cebeSEric Cheng 1648da14cebeSEric Cheng return (DLADM_STATUS_OK); 1649da14cebeSEric Cheng } 1650da14cebeSEric Cheng 1651da14cebeSEric Cheng static boolean_t 1652da14cebeSEric Cheng valid_formatspec(char *formatspec_str) 1653da14cebeSEric Cheng { 1654da14cebeSEric Cheng if (strcmp(formatspec_str, "gnuplot") == 0) 1655da14cebeSEric Cheng return (B_TRUE); 1656da14cebeSEric Cheng return (B_FALSE); 1657da14cebeSEric Cheng 1658da14cebeSEric Cheng } 1659da14cebeSEric Cheng 1660da14cebeSEric Cheng /*ARGSUSED*/ 1661da14cebeSEric Cheng static void 1662da14cebeSEric Cheng do_show_usage(int argc, char *argv[], const char *use) 1663da14cebeSEric Cheng { 1664da14cebeSEric Cheng char *file = NULL; 1665da14cebeSEric Cheng int opt; 1666da14cebeSEric Cheng dladm_status_t status; 1667da14cebeSEric Cheng boolean_t d_arg = B_FALSE; 1668da14cebeSEric Cheng char *stime = NULL; 1669da14cebeSEric Cheng char *etime = NULL; 1670da14cebeSEric Cheng char *resource = NULL; 1671da14cebeSEric Cheng show_usage_state_t state; 1672da14cebeSEric Cheng boolean_t o_arg = B_FALSE; 1673da14cebeSEric Cheng boolean_t F_arg = B_FALSE; 1674da14cebeSEric Cheng char *fields_str = NULL; 1675da14cebeSEric Cheng char *formatspec_str = NULL; 1676da14cebeSEric Cheng char *all_l_fields = 1677da14cebeSEric Cheng "link,start,end,rbytes,obytes,bandwidth"; 16788002d411SSowmini Varadhan ofmt_handle_t ofmt; 16798002d411SSowmini Varadhan ofmt_status_t oferr; 16808002d411SSowmini Varadhan uint_t ofmtflags = 0; 1681da14cebeSEric Cheng 1682da14cebeSEric Cheng bzero(&state, sizeof (show_usage_state_t)); 16838002d411SSowmini Varadhan state.us_parsable = B_FALSE; 1684da14cebeSEric Cheng state.us_printheader = B_FALSE; 1685da14cebeSEric Cheng state.us_plot = B_FALSE; 1686da14cebeSEric Cheng state.us_first = B_TRUE; 1687da14cebeSEric Cheng 1688ae6aa22aSVenugopal Iyer while ((opt = getopt_long(argc, argv, "das:e:o:f:F:", 1689ae6aa22aSVenugopal Iyer usage_opts, NULL)) != -1) { 1690da14cebeSEric Cheng switch (opt) { 1691da14cebeSEric Cheng case 'd': 1692da14cebeSEric Cheng d_arg = B_TRUE; 1693da14cebeSEric Cheng break; 1694ae6aa22aSVenugopal Iyer case 'a': 1695ae6aa22aSVenugopal Iyer state.us_showall = B_TRUE; 1696da14cebeSEric Cheng break; 1697da14cebeSEric Cheng case 'f': 1698da14cebeSEric Cheng file = optarg; 1699da14cebeSEric Cheng break; 1700da14cebeSEric Cheng case 's': 1701da14cebeSEric Cheng stime = optarg; 1702da14cebeSEric Cheng break; 1703da14cebeSEric Cheng case 'e': 1704da14cebeSEric Cheng etime = optarg; 1705da14cebeSEric Cheng break; 1706da14cebeSEric Cheng case 'o': 1707da14cebeSEric Cheng o_arg = B_TRUE; 1708da14cebeSEric Cheng fields_str = optarg; 1709da14cebeSEric Cheng break; 1710da14cebeSEric Cheng case 'F': 1711ae6aa22aSVenugopal Iyer state.us_plot = F_arg = B_TRUE; 1712da14cebeSEric Cheng formatspec_str = optarg; 1713da14cebeSEric Cheng break; 1714da14cebeSEric Cheng default: 1715da14cebeSEric Cheng die_opterr(optopt, opt, use); 1716da14cebeSEric Cheng break; 1717da14cebeSEric Cheng } 1718da14cebeSEric Cheng } 1719da14cebeSEric Cheng 1720da14cebeSEric Cheng if (file == NULL) 1721da14cebeSEric Cheng die("show-usage requires a file"); 1722da14cebeSEric Cheng 1723da14cebeSEric Cheng if (optind == (argc-1)) { 1724ae6aa22aSVenugopal Iyer uint32_t flags; 1725ae6aa22aSVenugopal Iyer 1726da14cebeSEric Cheng resource = argv[optind]; 1727ae6aa22aSVenugopal Iyer if (!state.us_showall && 1728ae6aa22aSVenugopal Iyer (((status = dladm_name2info(handle, resource, NULL, &flags, 1729ae6aa22aSVenugopal Iyer NULL, NULL)) != DLADM_STATUS_OK) || 1730ae6aa22aSVenugopal Iyer ((flags & DLADM_OPT_ACTIVE) == 0))) { 1731ae6aa22aSVenugopal Iyer die("invalid link: '%s'", resource); 1732ae6aa22aSVenugopal Iyer } 1733da14cebeSEric Cheng } 1734da14cebeSEric Cheng 1735ae6aa22aSVenugopal Iyer if (F_arg && d_arg) 1736ae6aa22aSVenugopal Iyer die("incompatible -d and -F options"); 1737da14cebeSEric Cheng 1738da14cebeSEric Cheng if (F_arg && valid_formatspec(formatspec_str) == B_FALSE) 1739da14cebeSEric Cheng die("Format specifier %s not supported", formatspec_str); 1740da14cebeSEric Cheng 17418002d411SSowmini Varadhan if (state.us_parsable) 17428002d411SSowmini Varadhan ofmtflags |= OFMT_PARSABLE; 17438002d411SSowmini Varadhan 17448002d411SSowmini Varadhan if (resource == NULL && stime == NULL && etime == NULL) { 17458002d411SSowmini Varadhan oferr = ofmt_open(fields_str, usage_fields, ofmtflags, 0, 17468002d411SSowmini Varadhan &ofmt); 17478002d411SSowmini Varadhan } else { 17488002d411SSowmini Varadhan if (!o_arg || (o_arg && strcasecmp(fields_str, "all") == 0)) 17498002d411SSowmini Varadhan fields_str = all_l_fields; 17508002d411SSowmini Varadhan oferr = ofmt_open(fields_str, usage_l_fields, ofmtflags, 0, 17518002d411SSowmini Varadhan &ofmt); 17528002d411SSowmini Varadhan 17538002d411SSowmini Varadhan } 17548002d411SSowmini Varadhan dladm_ofmt_check(oferr, state.us_parsable, ofmt); 17558002d411SSowmini Varadhan state.us_ofmt = ofmt; 17568002d411SSowmini Varadhan 1757da14cebeSEric Cheng if (d_arg) { 1758da14cebeSEric Cheng /* Print log dates */ 1759da14cebeSEric Cheng status = dladm_usage_dates(show_usage_date, 1760da14cebeSEric Cheng DLADM_LOGTYPE_LINK, file, resource, &state); 1761da14cebeSEric Cheng } else if (resource == NULL && stime == NULL && etime == NULL && 1762ae6aa22aSVenugopal Iyer !F_arg) { 1763da14cebeSEric Cheng /* Print summary */ 1764da14cebeSEric Cheng status = dladm_usage_summary(show_usage_res, 1765da14cebeSEric Cheng DLADM_LOGTYPE_LINK, file, &state); 1766da14cebeSEric Cheng } else if (resource != NULL) { 1767da14cebeSEric Cheng /* Print log entries for named resource */ 1768da14cebeSEric Cheng status = dladm_walk_usage_res(show_usage_time, 1769da14cebeSEric Cheng DLADM_LOGTYPE_LINK, file, resource, stime, etime, &state); 1770da14cebeSEric Cheng } else { 1771da14cebeSEric Cheng /* Print time and information for each link */ 1772da14cebeSEric Cheng status = dladm_walk_usage_time(show_usage_time, 1773da14cebeSEric Cheng DLADM_LOGTYPE_LINK, file, stime, etime, &state); 1774da14cebeSEric Cheng } 1775da14cebeSEric Cheng 1776da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 1777da14cebeSEric Cheng die_dlerr(status, "show-usage"); 17788002d411SSowmini Varadhan ofmt_close(ofmt); 1779da14cebeSEric Cheng } 1780da14cebeSEric Cheng 17817c478bd9Sstevel@tonic-gate static void 17828d5c46e6Sam223141 do_create_aggr(int argc, char *argv[], const char *use) 17837c478bd9Sstevel@tonic-gate { 1784b509e89bSRishi Srivatsavai int option; 1785d62bc4baSyz147064 int key = 0; 17867c478bd9Sstevel@tonic-gate uint32_t policy = AGGR_POLICY_L4; 17877c478bd9Sstevel@tonic-gate aggr_lacp_mode_t lacp_mode = AGGR_LACP_OFF; 17887c478bd9Sstevel@tonic-gate aggr_lacp_timer_t lacp_timer = AGGR_LACP_TIMER_SHORT; 1789f595a68aSyz147064 dladm_aggr_port_attr_db_t port[MAXPORT]; 1790d62bc4baSyz147064 uint_t n, ndev, nlink; 17917c478bd9Sstevel@tonic-gate uint8_t mac_addr[ETHERADDRL]; 17927c478bd9Sstevel@tonic-gate boolean_t mac_addr_fixed = B_FALSE; 17937c478bd9Sstevel@tonic-gate boolean_t P_arg = B_FALSE; 17947c478bd9Sstevel@tonic-gate boolean_t l_arg = B_FALSE; 17957c478bd9Sstevel@tonic-gate boolean_t u_arg = B_FALSE; 17967c478bd9Sstevel@tonic-gate boolean_t T_arg = B_FALSE; 1797d62bc4baSyz147064 uint32_t flags = DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST; 17987c478bd9Sstevel@tonic-gate char *altroot = NULL; 1799d62bc4baSyz147064 char name[MAXLINKNAMELEN]; 1800d62bc4baSyz147064 char *devs[MAXPORT]; 1801d62bc4baSyz147064 char *links[MAXPORT]; 1802f595a68aSyz147064 dladm_status_t status; 1803da14cebeSEric Cheng dladm_status_t pstatus; 180463a6526dSMichael Lim char propstr[DLADM_STRSIZE]; 1805da14cebeSEric Cheng dladm_arg_list_t *proplist = NULL; 1806da14cebeSEric Cheng int i; 1807da14cebeSEric Cheng datalink_id_t linkid; 18087c478bd9Sstevel@tonic-gate 1809d62bc4baSyz147064 ndev = nlink = opterr = 0; 181063a6526dSMichael Lim bzero(propstr, DLADM_STRSIZE); 181163a6526dSMichael Lim 1812da14cebeSEric Cheng while ((option = getopt_long(argc, argv, ":d:l:L:P:R:tfu:T:p:", 1813d62bc4baSyz147064 lopts, NULL)) != -1) { 18147c478bd9Sstevel@tonic-gate switch (option) { 18157c478bd9Sstevel@tonic-gate case 'd': 1816d62bc4baSyz147064 if (ndev + nlink >= MAXPORT) 1817d62bc4baSyz147064 die("too many ports specified"); 18187c478bd9Sstevel@tonic-gate 1819d62bc4baSyz147064 devs[ndev++] = optarg; 18207c478bd9Sstevel@tonic-gate break; 18217c478bd9Sstevel@tonic-gate case 'P': 182233343a97Smeem if (P_arg) 182333343a97Smeem die_optdup(option); 18247c478bd9Sstevel@tonic-gate 18257c478bd9Sstevel@tonic-gate P_arg = B_TRUE; 1826f595a68aSyz147064 if (!dladm_aggr_str2policy(optarg, &policy)) 182733343a97Smeem die("invalid policy '%s'", optarg); 18287c478bd9Sstevel@tonic-gate break; 18297c478bd9Sstevel@tonic-gate case 'u': 183033343a97Smeem if (u_arg) 183133343a97Smeem die_optdup(option); 18327c478bd9Sstevel@tonic-gate 18337c478bd9Sstevel@tonic-gate u_arg = B_TRUE; 1834f595a68aSyz147064 if (!dladm_aggr_str2macaddr(optarg, &mac_addr_fixed, 183533343a97Smeem mac_addr)) 183633343a97Smeem die("invalid MAC address '%s'", optarg); 18377c478bd9Sstevel@tonic-gate break; 18387c478bd9Sstevel@tonic-gate case 'l': 1839d62bc4baSyz147064 if (isdigit(optarg[strlen(optarg) - 1])) { 1840d62bc4baSyz147064 1841d62bc4baSyz147064 /* 1842d62bc4baSyz147064 * Ended with digit, possibly a link name. 1843d62bc4baSyz147064 */ 1844d62bc4baSyz147064 if (ndev + nlink >= MAXPORT) 1845d62bc4baSyz147064 die("too many ports specified"); 1846d62bc4baSyz147064 1847d62bc4baSyz147064 links[nlink++] = optarg; 1848d62bc4baSyz147064 break; 1849d62bc4baSyz147064 } 1850d62bc4baSyz147064 /* FALLTHROUGH */ 1851d62bc4baSyz147064 case 'L': 185233343a97Smeem if (l_arg) 185333343a97Smeem die_optdup(option); 18547c478bd9Sstevel@tonic-gate 18557c478bd9Sstevel@tonic-gate l_arg = B_TRUE; 1856f595a68aSyz147064 if (!dladm_aggr_str2lacpmode(optarg, &lacp_mode)) 185733343a97Smeem die("invalid LACP mode '%s'", optarg); 18587c478bd9Sstevel@tonic-gate break; 18597c478bd9Sstevel@tonic-gate case 'T': 186033343a97Smeem if (T_arg) 186133343a97Smeem die_optdup(option); 18627c478bd9Sstevel@tonic-gate 18637c478bd9Sstevel@tonic-gate T_arg = B_TRUE; 1864f595a68aSyz147064 if (!dladm_aggr_str2lacptimer(optarg, &lacp_timer)) 186533343a97Smeem die("invalid LACP timer value '%s'", optarg); 18667c478bd9Sstevel@tonic-gate break; 18677c478bd9Sstevel@tonic-gate case 't': 1868d62bc4baSyz147064 flags &= ~DLADM_OPT_PERSIST; 1869d62bc4baSyz147064 break; 1870d62bc4baSyz147064 case 'f': 1871d62bc4baSyz147064 flags |= DLADM_OPT_FORCE; 18727c478bd9Sstevel@tonic-gate break; 18737c478bd9Sstevel@tonic-gate case 'R': 18747c478bd9Sstevel@tonic-gate altroot = optarg; 18757c478bd9Sstevel@tonic-gate break; 1876da14cebeSEric Cheng case 'p': 187763a6526dSMichael Lim (void) strlcat(propstr, optarg, DLADM_STRSIZE); 187863a6526dSMichael Lim if (strlcat(propstr, ",", DLADM_STRSIZE) >= 187963a6526dSMichael Lim DLADM_STRSIZE) 188063a6526dSMichael Lim die("property list too long '%s'", propstr); 1881da14cebeSEric Cheng break; 188263a6526dSMichael Lim 18837c478bd9Sstevel@tonic-gate default: 18848d5c46e6Sam223141 die_opterr(optopt, option, use); 188533343a97Smeem break; 18867c478bd9Sstevel@tonic-gate } 18877c478bd9Sstevel@tonic-gate } 18887c478bd9Sstevel@tonic-gate 1889d62bc4baSyz147064 if (ndev + nlink == 0) 18907c478bd9Sstevel@tonic-gate usage(); 18917c478bd9Sstevel@tonic-gate 1892d62bc4baSyz147064 /* get key value or the aggregation name (required last argument) */ 18937c478bd9Sstevel@tonic-gate if (optind != (argc-1)) 18947c478bd9Sstevel@tonic-gate usage(); 18957c478bd9Sstevel@tonic-gate 1896d62bc4baSyz147064 if (!str2int(argv[optind], &key)) { 1897d62bc4baSyz147064 if (strlcpy(name, argv[optind], MAXLINKNAMELEN) >= 1898d62bc4baSyz147064 MAXLINKNAMELEN) { 1899d62bc4baSyz147064 die("link name too long '%s'", argv[optind]); 1900d62bc4baSyz147064 } 19017c478bd9Sstevel@tonic-gate 1902d62bc4baSyz147064 if (!dladm_valid_linkname(name)) 1903d62bc4baSyz147064 die("invalid link name '%s'", argv[optind]); 1904d62bc4baSyz147064 } else { 1905d62bc4baSyz147064 (void) snprintf(name, MAXLINKNAMELEN, "aggr%d", key); 1906d62bc4baSyz147064 } 1907d62bc4baSyz147064 1908d62bc4baSyz147064 if (altroot != NULL) 1909d62bc4baSyz147064 altroot_cmd(altroot, argc, argv); 1910d62bc4baSyz147064 1911d62bc4baSyz147064 for (n = 0; n < ndev; n++) { 19124ac67f02SAnurag S. Maskey if ((status = dladm_dev2linkid(handle, devs[n], 19134ac67f02SAnurag S. Maskey &port[n].lp_linkid)) != DLADM_STATUS_OK) { 19144ac67f02SAnurag S. Maskey die_dlerr(status, "invalid dev name '%s'", devs[n]); 1915d62bc4baSyz147064 } 1916d62bc4baSyz147064 } 1917d62bc4baSyz147064 1918d62bc4baSyz147064 for (n = 0; n < nlink; n++) { 19194ac67f02SAnurag S. Maskey if ((status = dladm_name2info(handle, links[n], 19204ac67f02SAnurag S. Maskey &port[ndev + n].lp_linkid, NULL, NULL, NULL)) != 19214ac67f02SAnurag S. Maskey DLADM_STATUS_OK) { 19224ac67f02SAnurag S. Maskey die_dlerr(status, "invalid link name '%s'", links[n]); 1923d62bc4baSyz147064 } 1924d62bc4baSyz147064 } 1925d62bc4baSyz147064 19264ac67f02SAnurag S. Maskey status = dladm_aggr_create(handle, name, key, ndev + nlink, port, 19274ac67f02SAnurag S. Maskey policy, mac_addr_fixed, (const uchar_t *)mac_addr, lacp_mode, 1928d62bc4baSyz147064 lacp_timer, flags); 1929da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 1930da14cebeSEric Cheng goto done; 1931da14cebeSEric Cheng 193263a6526dSMichael Lim if (dladm_parse_link_props(propstr, &proplist, B_FALSE) 193363a6526dSMichael Lim != DLADM_STATUS_OK) 193463a6526dSMichael Lim die("invalid aggregation property"); 193563a6526dSMichael Lim 1936da14cebeSEric Cheng if (proplist == NULL) 1937da14cebeSEric Cheng return; 1938da14cebeSEric Cheng 19394ac67f02SAnurag S. Maskey status = dladm_name2info(handle, name, &linkid, NULL, NULL, NULL); 1940da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 1941da14cebeSEric Cheng goto done; 1942da14cebeSEric Cheng 1943da14cebeSEric Cheng for (i = 0; i < proplist->al_count; i++) { 1944da14cebeSEric Cheng dladm_arg_info_t *aip = &proplist->al_info[i]; 1945da14cebeSEric Cheng 19464ac67f02SAnurag S. Maskey pstatus = dladm_set_linkprop(handle, linkid, aip->ai_name, 1947da14cebeSEric Cheng aip->ai_val, aip->ai_count, flags); 1948da14cebeSEric Cheng 1949da14cebeSEric Cheng if (pstatus != DLADM_STATUS_OK) { 1950da14cebeSEric Cheng die_dlerr(pstatus, 1951da14cebeSEric Cheng "aggr creation succeeded but " 1952da14cebeSEric Cheng "could not set property '%s'", aip->ai_name); 1953da14cebeSEric Cheng } 1954da14cebeSEric Cheng } 1955d62bc4baSyz147064 done: 1956da14cebeSEric Cheng dladm_free_props(proplist); 1957d62bc4baSyz147064 if (status != DLADM_STATUS_OK) { 1958d62bc4baSyz147064 if (status == DLADM_STATUS_NONOTIF) { 19594eaa4710SRishi Srivatsavai die("not all links have link up/down detection; must " 19604eaa4710SRishi Srivatsavai "use -f (see dladm(1M))"); 1961d62bc4baSyz147064 } else { 1962f595a68aSyz147064 die_dlerr(status, "create operation failed"); 19637c478bd9Sstevel@tonic-gate } 1964d62bc4baSyz147064 } 1965d62bc4baSyz147064 } 1966d62bc4baSyz147064 1967d62bc4baSyz147064 /* 1968d62bc4baSyz147064 * arg is either the key or the aggr name. Validate it and convert it to 1969d62bc4baSyz147064 * the linkid if altroot is NULL. 1970d62bc4baSyz147064 */ 1971d62bc4baSyz147064 static dladm_status_t 1972d62bc4baSyz147064 i_dladm_aggr_get_linkid(const char *altroot, const char *arg, 1973d62bc4baSyz147064 datalink_id_t *linkidp, uint32_t flags) 1974d62bc4baSyz147064 { 1975d62bc4baSyz147064 int key = 0; 1976d62bc4baSyz147064 char *aggr = NULL; 1977d62bc4baSyz147064 dladm_status_t status; 1978d62bc4baSyz147064 1979d62bc4baSyz147064 if (!str2int(arg, &key)) 1980d62bc4baSyz147064 aggr = (char *)arg; 1981d62bc4baSyz147064 1982d62bc4baSyz147064 if (aggr == NULL && key == 0) 1983d62bc4baSyz147064 return (DLADM_STATUS_LINKINVAL); 1984d62bc4baSyz147064 1985d62bc4baSyz147064 if (altroot != NULL) 1986d62bc4baSyz147064 return (DLADM_STATUS_OK); 1987d62bc4baSyz147064 1988d62bc4baSyz147064 if (aggr != NULL) { 19894ac67f02SAnurag S. Maskey status = dladm_name2info(handle, aggr, linkidp, NULL, NULL, 19904ac67f02SAnurag S. Maskey NULL); 1991d62bc4baSyz147064 } else { 19924ac67f02SAnurag S. Maskey status = dladm_key2linkid(handle, key, linkidp, flags); 1993d62bc4baSyz147064 } 1994d62bc4baSyz147064 1995d62bc4baSyz147064 return (status); 1996d62bc4baSyz147064 } 19977c478bd9Sstevel@tonic-gate 19987c478bd9Sstevel@tonic-gate static void 19998d5c46e6Sam223141 do_delete_aggr(int argc, char *argv[], const char *use) 20007c478bd9Sstevel@tonic-gate { 2001b509e89bSRishi Srivatsavai int option; 20027c478bd9Sstevel@tonic-gate char *altroot = NULL; 2003d62bc4baSyz147064 uint32_t flags = DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST; 2004f595a68aSyz147064 dladm_status_t status; 2005d62bc4baSyz147064 datalink_id_t linkid; 20067c478bd9Sstevel@tonic-gate 20077c478bd9Sstevel@tonic-gate opterr = 0; 2008d62bc4baSyz147064 while ((option = getopt_long(argc, argv, ":R:t", lopts, NULL)) != -1) { 20097c478bd9Sstevel@tonic-gate switch (option) { 20107c478bd9Sstevel@tonic-gate case 't': 2011d62bc4baSyz147064 flags &= ~DLADM_OPT_PERSIST; 20127c478bd9Sstevel@tonic-gate break; 20137c478bd9Sstevel@tonic-gate case 'R': 20147c478bd9Sstevel@tonic-gate altroot = optarg; 20157c478bd9Sstevel@tonic-gate break; 20167c478bd9Sstevel@tonic-gate default: 20178d5c46e6Sam223141 die_opterr(optopt, option, use); 20187c478bd9Sstevel@tonic-gate break; 20197c478bd9Sstevel@tonic-gate } 20207c478bd9Sstevel@tonic-gate } 20217c478bd9Sstevel@tonic-gate 2022d62bc4baSyz147064 /* get key value or the aggregation name (required last argument) */ 20237c478bd9Sstevel@tonic-gate if (optind != (argc-1)) 20247c478bd9Sstevel@tonic-gate usage(); 20257c478bd9Sstevel@tonic-gate 2026d62bc4baSyz147064 status = i_dladm_aggr_get_linkid(altroot, argv[optind], &linkid, flags); 2027d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 2028d62bc4baSyz147064 goto done; 20297c478bd9Sstevel@tonic-gate 2030d62bc4baSyz147064 if (altroot != NULL) 2031d62bc4baSyz147064 altroot_cmd(altroot, argc, argv); 2032d62bc4baSyz147064 20334ac67f02SAnurag S. Maskey status = dladm_aggr_delete(handle, linkid, flags); 2034d62bc4baSyz147064 done: 2035f595a68aSyz147064 if (status != DLADM_STATUS_OK) 2036f595a68aSyz147064 die_dlerr(status, "delete operation failed"); 20377c478bd9Sstevel@tonic-gate } 20387c478bd9Sstevel@tonic-gate 20397c478bd9Sstevel@tonic-gate static void 20408d5c46e6Sam223141 do_add_aggr(int argc, char *argv[], const char *use) 20417c478bd9Sstevel@tonic-gate { 2042b509e89bSRishi Srivatsavai int option; 2043d62bc4baSyz147064 uint_t n, ndev, nlink; 20447c478bd9Sstevel@tonic-gate char *altroot = NULL; 2045d62bc4baSyz147064 uint32_t flags = DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST; 2046d62bc4baSyz147064 datalink_id_t linkid; 2047f595a68aSyz147064 dladm_status_t status; 2048d62bc4baSyz147064 dladm_aggr_port_attr_db_t port[MAXPORT]; 2049d62bc4baSyz147064 char *devs[MAXPORT]; 2050d62bc4baSyz147064 char *links[MAXPORT]; 20517c478bd9Sstevel@tonic-gate 2052d62bc4baSyz147064 ndev = nlink = opterr = 0; 2053d62bc4baSyz147064 while ((option = getopt_long(argc, argv, ":d:l:R:tf", lopts, 20547c478bd9Sstevel@tonic-gate NULL)) != -1) { 20557c478bd9Sstevel@tonic-gate switch (option) { 20567c478bd9Sstevel@tonic-gate case 'd': 2057d62bc4baSyz147064 if (ndev + nlink >= MAXPORT) 2058d62bc4baSyz147064 die("too many ports specified"); 20597c478bd9Sstevel@tonic-gate 2060d62bc4baSyz147064 devs[ndev++] = optarg; 2061d62bc4baSyz147064 break; 2062d62bc4baSyz147064 case 'l': 2063d62bc4baSyz147064 if (ndev + nlink >= MAXPORT) 2064d62bc4baSyz147064 die("too many ports specified"); 206533343a97Smeem 2066d62bc4baSyz147064 links[nlink++] = optarg; 20677c478bd9Sstevel@tonic-gate break; 20687c478bd9Sstevel@tonic-gate case 't': 2069d62bc4baSyz147064 flags &= ~DLADM_OPT_PERSIST; 2070d62bc4baSyz147064 break; 2071d62bc4baSyz147064 case 'f': 2072d62bc4baSyz147064 flags |= DLADM_OPT_FORCE; 20737c478bd9Sstevel@tonic-gate break; 20747c478bd9Sstevel@tonic-gate case 'R': 20757c478bd9Sstevel@tonic-gate altroot = optarg; 20767c478bd9Sstevel@tonic-gate break; 20777c478bd9Sstevel@tonic-gate default: 20788d5c46e6Sam223141 die_opterr(optopt, option, use); 207933343a97Smeem break; 20807c478bd9Sstevel@tonic-gate } 20817c478bd9Sstevel@tonic-gate } 20827c478bd9Sstevel@tonic-gate 2083d62bc4baSyz147064 if (ndev + nlink == 0) 20847c478bd9Sstevel@tonic-gate usage(); 20857c478bd9Sstevel@tonic-gate 2086d62bc4baSyz147064 /* get key value or the aggregation name (required last argument) */ 20877c478bd9Sstevel@tonic-gate if (optind != (argc-1)) 20887c478bd9Sstevel@tonic-gate usage(); 20897c478bd9Sstevel@tonic-gate 2090d62bc4baSyz147064 if ((status = i_dladm_aggr_get_linkid(altroot, argv[optind], &linkid, 2091d62bc4baSyz147064 flags & (DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST))) != 2092d62bc4baSyz147064 DLADM_STATUS_OK) { 2093d62bc4baSyz147064 goto done; 2094d62bc4baSyz147064 } 20957c478bd9Sstevel@tonic-gate 2096d62bc4baSyz147064 if (altroot != NULL) 2097d62bc4baSyz147064 altroot_cmd(altroot, argc, argv); 2098d62bc4baSyz147064 2099d62bc4baSyz147064 for (n = 0; n < ndev; n++) { 21004ac67f02SAnurag S. Maskey if ((status = dladm_dev2linkid(handle, devs[n], 21014ac67f02SAnurag S. Maskey &(port[n].lp_linkid))) != DLADM_STATUS_OK) { 21024ac67f02SAnurag S. Maskey die_dlerr(status, "invalid <dev> '%s'", devs[n]); 2103d62bc4baSyz147064 } 2104d62bc4baSyz147064 } 2105d62bc4baSyz147064 2106d62bc4baSyz147064 for (n = 0; n < nlink; n++) { 21074ac67f02SAnurag S. Maskey if ((status = dladm_name2info(handle, links[n], 21084ac67f02SAnurag S. Maskey &port[n + ndev].lp_linkid, NULL, NULL, NULL)) != 21094ac67f02SAnurag S. Maskey DLADM_STATUS_OK) { 21104ac67f02SAnurag S. Maskey die_dlerr(status, "invalid <link> '%s'", links[n]); 2111d62bc4baSyz147064 } 2112d62bc4baSyz147064 } 2113d62bc4baSyz147064 21144ac67f02SAnurag S. Maskey status = dladm_aggr_add(handle, linkid, ndev + nlink, port, flags); 2115d62bc4baSyz147064 done: 2116f595a68aSyz147064 if (status != DLADM_STATUS_OK) { 2117219a2a31Shl157128 /* 2118f595a68aSyz147064 * checking DLADM_STATUS_NOTSUP is a temporary workaround 2119219a2a31Shl157128 * and should be removed once 6399681 is fixed. 2120219a2a31Shl157128 */ 2121f595a68aSyz147064 if (status == DLADM_STATUS_NOTSUP) { 21222b24ab6bSSebastien Roy die("add operation failed: link capabilities don't " 21232b24ab6bSSebastien Roy "match"); 2124d62bc4baSyz147064 } else if (status == DLADM_STATUS_NONOTIF) { 21254eaa4710SRishi Srivatsavai die("not all links have link up/down detection; must " 21264eaa4710SRishi Srivatsavai "use -f (see dladm(1M))"); 2127d62bc4baSyz147064 } else { 2128f595a68aSyz147064 die_dlerr(status, "add operation failed"); 21297c478bd9Sstevel@tonic-gate } 21307c478bd9Sstevel@tonic-gate } 2131d62bc4baSyz147064 } 21327c478bd9Sstevel@tonic-gate 21337c478bd9Sstevel@tonic-gate static void 21348d5c46e6Sam223141 do_remove_aggr(int argc, char *argv[], const char *use) 21357c478bd9Sstevel@tonic-gate { 2136b509e89bSRishi Srivatsavai int option; 2137f595a68aSyz147064 dladm_aggr_port_attr_db_t port[MAXPORT]; 2138d62bc4baSyz147064 uint_t n, ndev, nlink; 2139d62bc4baSyz147064 char *devs[MAXPORT]; 2140d62bc4baSyz147064 char *links[MAXPORT]; 21417c478bd9Sstevel@tonic-gate char *altroot = NULL; 2142d62bc4baSyz147064 uint32_t flags; 2143d62bc4baSyz147064 datalink_id_t linkid; 2144f595a68aSyz147064 dladm_status_t status; 21457c478bd9Sstevel@tonic-gate 2146d62bc4baSyz147064 flags = DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST; 2147d62bc4baSyz147064 ndev = nlink = opterr = 0; 2148d62bc4baSyz147064 while ((option = getopt_long(argc, argv, ":d:l:R:t", 2149d62bc4baSyz147064 lopts, NULL)) != -1) { 21507c478bd9Sstevel@tonic-gate switch (option) { 21517c478bd9Sstevel@tonic-gate case 'd': 2152d62bc4baSyz147064 if (ndev + nlink >= MAXPORT) 2153d62bc4baSyz147064 die("too many ports specified"); 21547c478bd9Sstevel@tonic-gate 2155d62bc4baSyz147064 devs[ndev++] = optarg; 2156d62bc4baSyz147064 break; 2157d62bc4baSyz147064 case 'l': 2158d62bc4baSyz147064 if (ndev + nlink >= MAXPORT) 2159d62bc4baSyz147064 die("too many ports specified"); 216033343a97Smeem 2161d62bc4baSyz147064 links[nlink++] = optarg; 21627c478bd9Sstevel@tonic-gate break; 21637c478bd9Sstevel@tonic-gate case 't': 2164d62bc4baSyz147064 flags &= ~DLADM_OPT_PERSIST; 21657c478bd9Sstevel@tonic-gate break; 21667c478bd9Sstevel@tonic-gate case 'R': 21677c478bd9Sstevel@tonic-gate altroot = optarg; 21687c478bd9Sstevel@tonic-gate break; 21697c478bd9Sstevel@tonic-gate default: 21708d5c46e6Sam223141 die_opterr(optopt, option, use); 217133343a97Smeem break; 21727c478bd9Sstevel@tonic-gate } 21737c478bd9Sstevel@tonic-gate } 21747c478bd9Sstevel@tonic-gate 2175d62bc4baSyz147064 if (ndev + nlink == 0) 21767c478bd9Sstevel@tonic-gate usage(); 21777c478bd9Sstevel@tonic-gate 2178d62bc4baSyz147064 /* get key value or the aggregation name (required last argument) */ 21797c478bd9Sstevel@tonic-gate if (optind != (argc-1)) 21807c478bd9Sstevel@tonic-gate usage(); 21817c478bd9Sstevel@tonic-gate 2182d62bc4baSyz147064 status = i_dladm_aggr_get_linkid(altroot, argv[optind], &linkid, flags); 2183d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 2184d62bc4baSyz147064 goto done; 21857c478bd9Sstevel@tonic-gate 2186d62bc4baSyz147064 if (altroot != NULL) 2187d62bc4baSyz147064 altroot_cmd(altroot, argc, argv); 2188d62bc4baSyz147064 2189d62bc4baSyz147064 for (n = 0; n < ndev; n++) { 21904ac67f02SAnurag S. Maskey if ((status = dladm_dev2linkid(handle, devs[n], 21914ac67f02SAnurag S. Maskey &(port[n].lp_linkid))) != DLADM_STATUS_OK) { 21924ac67f02SAnurag S. Maskey die_dlerr(status, "invalid <dev> '%s'", devs[n]); 2193d62bc4baSyz147064 } 2194d62bc4baSyz147064 } 2195d62bc4baSyz147064 2196d62bc4baSyz147064 for (n = 0; n < nlink; n++) { 21974ac67f02SAnurag S. Maskey if ((status = dladm_name2info(handle, links[n], 21984ac67f02SAnurag S. Maskey &port[n + ndev].lp_linkid, NULL, NULL, NULL)) != 21994ac67f02SAnurag S. Maskey DLADM_STATUS_OK) { 22004ac67f02SAnurag S. Maskey die_dlerr(status, "invalid <link> '%s'", links[n]); 2201d62bc4baSyz147064 } 2202d62bc4baSyz147064 } 2203d62bc4baSyz147064 22044ac67f02SAnurag S. Maskey status = dladm_aggr_remove(handle, linkid, ndev + nlink, port, flags); 2205d62bc4baSyz147064 done: 2206f595a68aSyz147064 if (status != DLADM_STATUS_OK) 2207f595a68aSyz147064 die_dlerr(status, "remove operation failed"); 22087c478bd9Sstevel@tonic-gate } 22097c478bd9Sstevel@tonic-gate 22107c478bd9Sstevel@tonic-gate static void 22118d5c46e6Sam223141 do_modify_aggr(int argc, char *argv[], const char *use) 22127c478bd9Sstevel@tonic-gate { 2213b509e89bSRishi Srivatsavai int option; 22147c478bd9Sstevel@tonic-gate uint32_t policy = AGGR_POLICY_L4; 22157c478bd9Sstevel@tonic-gate aggr_lacp_mode_t lacp_mode = AGGR_LACP_OFF; 22167c478bd9Sstevel@tonic-gate aggr_lacp_timer_t lacp_timer = AGGR_LACP_TIMER_SHORT; 22177c478bd9Sstevel@tonic-gate uint8_t mac_addr[ETHERADDRL]; 22187c478bd9Sstevel@tonic-gate boolean_t mac_addr_fixed = B_FALSE; 22197c478bd9Sstevel@tonic-gate uint8_t modify_mask = 0; 22207c478bd9Sstevel@tonic-gate char *altroot = NULL; 2221d62bc4baSyz147064 uint32_t flags = DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST; 2222d62bc4baSyz147064 datalink_id_t linkid; 2223f595a68aSyz147064 dladm_status_t status; 22247c478bd9Sstevel@tonic-gate 22257c478bd9Sstevel@tonic-gate opterr = 0; 2226d62bc4baSyz147064 while ((option = getopt_long(argc, argv, ":L:l:P:R:tu:T:", lopts, 22277c478bd9Sstevel@tonic-gate NULL)) != -1) { 22287c478bd9Sstevel@tonic-gate switch (option) { 22297c478bd9Sstevel@tonic-gate case 'P': 2230f595a68aSyz147064 if (modify_mask & DLADM_AGGR_MODIFY_POLICY) 223133343a97Smeem die_optdup(option); 22327c478bd9Sstevel@tonic-gate 2233f595a68aSyz147064 modify_mask |= DLADM_AGGR_MODIFY_POLICY; 22347c478bd9Sstevel@tonic-gate 2235f595a68aSyz147064 if (!dladm_aggr_str2policy(optarg, &policy)) 223633343a97Smeem die("invalid policy '%s'", optarg); 22377c478bd9Sstevel@tonic-gate break; 22387c478bd9Sstevel@tonic-gate case 'u': 2239f595a68aSyz147064 if (modify_mask & DLADM_AGGR_MODIFY_MAC) 224033343a97Smeem die_optdup(option); 22417c478bd9Sstevel@tonic-gate 2242f595a68aSyz147064 modify_mask |= DLADM_AGGR_MODIFY_MAC; 22437c478bd9Sstevel@tonic-gate 2244f595a68aSyz147064 if (!dladm_aggr_str2macaddr(optarg, &mac_addr_fixed, 224533343a97Smeem mac_addr)) 224633343a97Smeem die("invalid MAC address '%s'", optarg); 22477c478bd9Sstevel@tonic-gate break; 22487c478bd9Sstevel@tonic-gate case 'l': 2249d62bc4baSyz147064 case 'L': 2250f595a68aSyz147064 if (modify_mask & DLADM_AGGR_MODIFY_LACP_MODE) 225133343a97Smeem die_optdup(option); 22527c478bd9Sstevel@tonic-gate 2253f595a68aSyz147064 modify_mask |= DLADM_AGGR_MODIFY_LACP_MODE; 22547c478bd9Sstevel@tonic-gate 2255f595a68aSyz147064 if (!dladm_aggr_str2lacpmode(optarg, &lacp_mode)) 225633343a97Smeem die("invalid LACP mode '%s'", optarg); 22577c478bd9Sstevel@tonic-gate break; 22587c478bd9Sstevel@tonic-gate case 'T': 2259f595a68aSyz147064 if (modify_mask & DLADM_AGGR_MODIFY_LACP_TIMER) 226033343a97Smeem die_optdup(option); 22617c478bd9Sstevel@tonic-gate 2262f595a68aSyz147064 modify_mask |= DLADM_AGGR_MODIFY_LACP_TIMER; 22637c478bd9Sstevel@tonic-gate 2264f595a68aSyz147064 if (!dladm_aggr_str2lacptimer(optarg, &lacp_timer)) 226533343a97Smeem die("invalid LACP timer value '%s'", optarg); 22667c478bd9Sstevel@tonic-gate break; 22677c478bd9Sstevel@tonic-gate case 't': 2268d62bc4baSyz147064 flags &= ~DLADM_OPT_PERSIST; 22697c478bd9Sstevel@tonic-gate break; 22707c478bd9Sstevel@tonic-gate case 'R': 22717c478bd9Sstevel@tonic-gate altroot = optarg; 22727c478bd9Sstevel@tonic-gate break; 22737c478bd9Sstevel@tonic-gate default: 22748d5c46e6Sam223141 die_opterr(optopt, option, use); 227533343a97Smeem break; 22767c478bd9Sstevel@tonic-gate } 22777c478bd9Sstevel@tonic-gate } 22787c478bd9Sstevel@tonic-gate 227933343a97Smeem if (modify_mask == 0) 228033343a97Smeem die("at least one of the -PulT options must be specified"); 22817c478bd9Sstevel@tonic-gate 2282d62bc4baSyz147064 /* get key value or the aggregation name (required last argument) */ 22837c478bd9Sstevel@tonic-gate if (optind != (argc-1)) 22847c478bd9Sstevel@tonic-gate usage(); 22857c478bd9Sstevel@tonic-gate 2286d62bc4baSyz147064 status = i_dladm_aggr_get_linkid(altroot, argv[optind], &linkid, flags); 2287d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 2288d62bc4baSyz147064 goto done; 22897c478bd9Sstevel@tonic-gate 2290d62bc4baSyz147064 if (altroot != NULL) 2291d62bc4baSyz147064 altroot_cmd(altroot, argc, argv); 2292d62bc4baSyz147064 22934ac67f02SAnurag S. Maskey status = dladm_aggr_modify(handle, linkid, modify_mask, policy, 22944ac67f02SAnurag S. Maskey mac_addr_fixed, (const uchar_t *)mac_addr, lacp_mode, lacp_timer, 22954ac67f02SAnurag S. Maskey flags); 2296d62bc4baSyz147064 2297d62bc4baSyz147064 done: 2298f595a68aSyz147064 if (status != DLADM_STATUS_OK) 2299f595a68aSyz147064 die_dlerr(status, "modify operation failed"); 23007c478bd9Sstevel@tonic-gate } 23017c478bd9Sstevel@tonic-gate 23028d5c46e6Sam223141 /*ARGSUSED*/ 23037c478bd9Sstevel@tonic-gate static void 23048d5c46e6Sam223141 do_up_aggr(int argc, char *argv[], const char *use) 23057c478bd9Sstevel@tonic-gate { 2306d62bc4baSyz147064 datalink_id_t linkid = DATALINK_ALL_LINKID; 2307f595a68aSyz147064 dladm_status_t status; 23087c478bd9Sstevel@tonic-gate 2309d62bc4baSyz147064 /* 2310d62bc4baSyz147064 * get the key or the name of the aggregation (optional last argument) 2311d62bc4baSyz147064 */ 23127c478bd9Sstevel@tonic-gate if (argc == 2) { 2313d62bc4baSyz147064 if ((status = i_dladm_aggr_get_linkid(NULL, argv[1], &linkid, 23144ac67f02SAnurag S. Maskey DLADM_OPT_PERSIST)) != DLADM_STATUS_OK) 2315d62bc4baSyz147064 goto done; 23167c478bd9Sstevel@tonic-gate } else if (argc > 2) { 23177c478bd9Sstevel@tonic-gate usage(); 23187c478bd9Sstevel@tonic-gate } 23197c478bd9Sstevel@tonic-gate 23204ac67f02SAnurag S. Maskey status = dladm_aggr_up(handle, linkid); 2321d62bc4baSyz147064 done: 2322d62bc4baSyz147064 if (status != DLADM_STATUS_OK) { 2323d62bc4baSyz147064 if (argc == 2) { 2324d62bc4baSyz147064 die_dlerr(status, 2325d62bc4baSyz147064 "could not bring up aggregation '%s'", argv[1]); 23267c478bd9Sstevel@tonic-gate } else { 2327f595a68aSyz147064 die_dlerr(status, "could not bring aggregations up"); 23287c478bd9Sstevel@tonic-gate } 23297c478bd9Sstevel@tonic-gate } 23307c478bd9Sstevel@tonic-gate } 23317c478bd9Sstevel@tonic-gate 23327c478bd9Sstevel@tonic-gate static void 23338d5c46e6Sam223141 do_create_vlan(int argc, char *argv[], const char *use) 23347c478bd9Sstevel@tonic-gate { 2335d62bc4baSyz147064 char *link = NULL; 2336d62bc4baSyz147064 char drv[DLPI_LINKNAME_MAX]; 2337d62bc4baSyz147064 uint_t ppa; 2338d62bc4baSyz147064 datalink_id_t linkid; 2339da14cebeSEric Cheng datalink_id_t dev_linkid; 2340d62bc4baSyz147064 int vid = 0; 2341b509e89bSRishi Srivatsavai int option; 2342d62bc4baSyz147064 uint32_t flags = (DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST); 2343d62bc4baSyz147064 char *altroot = NULL; 2344d62bc4baSyz147064 char vlan[MAXLINKNAMELEN]; 234563a6526dSMichael Lim char propstr[DLADM_STRSIZE]; 2346da14cebeSEric Cheng dladm_arg_list_t *proplist = NULL; 2347f595a68aSyz147064 dladm_status_t status; 23487c478bd9Sstevel@tonic-gate 2349d62bc4baSyz147064 opterr = 0; 235063a6526dSMichael Lim bzero(propstr, DLADM_STRSIZE); 235163a6526dSMichael Lim 2352da14cebeSEric Cheng while ((option = getopt_long(argc, argv, ":tfR:l:v:p:", 2353d62bc4baSyz147064 lopts, NULL)) != -1) { 2354d62bc4baSyz147064 switch (option) { 2355d62bc4baSyz147064 case 'v': 2356d62bc4baSyz147064 if (vid != 0) 2357d62bc4baSyz147064 die_optdup(option); 2358d62bc4baSyz147064 2359d62bc4baSyz147064 if (!str2int(optarg, &vid) || vid < 1 || vid > 4094) 2360d62bc4baSyz147064 die("invalid VLAN identifier '%s'", optarg); 2361d62bc4baSyz147064 2362d62bc4baSyz147064 break; 2363d62bc4baSyz147064 case 'l': 2364d62bc4baSyz147064 if (link != NULL) 2365d62bc4baSyz147064 die_optdup(option); 2366d62bc4baSyz147064 2367d62bc4baSyz147064 link = optarg; 2368d62bc4baSyz147064 break; 2369d62bc4baSyz147064 case 't': 2370d62bc4baSyz147064 flags &= ~DLADM_OPT_PERSIST; 2371d62bc4baSyz147064 break; 2372d62bc4baSyz147064 case 'R': 2373d62bc4baSyz147064 altroot = optarg; 2374d62bc4baSyz147064 break; 2375da14cebeSEric Cheng case 'p': 237663a6526dSMichael Lim (void) strlcat(propstr, optarg, DLADM_STRSIZE); 237763a6526dSMichael Lim if (strlcat(propstr, ",", DLADM_STRSIZE) >= 237863a6526dSMichael Lim DLADM_STRSIZE) 237963a6526dSMichael Lim die("property list too long '%s'", propstr); 2380da14cebeSEric Cheng break; 2381da14cebeSEric Cheng case 'f': 2382da14cebeSEric Cheng flags |= DLADM_OPT_FORCE; 2383da14cebeSEric Cheng break; 2384d62bc4baSyz147064 default: 23858d5c46e6Sam223141 die_opterr(optopt, option, use); 2386d62bc4baSyz147064 break; 2387d62bc4baSyz147064 } 2388d62bc4baSyz147064 } 2389d62bc4baSyz147064 2390d62bc4baSyz147064 /* get vlan name if there is any */ 2391d62bc4baSyz147064 if ((vid == 0) || (link == NULL) || (argc - optind > 1)) 23927c478bd9Sstevel@tonic-gate usage(); 2393d62bc4baSyz147064 2394d62bc4baSyz147064 if (optind == (argc - 1)) { 2395d62bc4baSyz147064 if (strlcpy(vlan, argv[optind], MAXLINKNAMELEN) >= 2396d62bc4baSyz147064 MAXLINKNAMELEN) { 2397d62bc4baSyz147064 die("vlan name too long '%s'", argv[optind]); 2398d62bc4baSyz147064 } 2399d62bc4baSyz147064 } else { 2400d62bc4baSyz147064 if ((dlpi_parselink(link, drv, &ppa) != DLPI_SUCCESS) || 2401d62bc4baSyz147064 (ppa >= 1000) || 2402d62bc4baSyz147064 (dlpi_makelink(vlan, drv, vid * 1000 + ppa) != 2403d62bc4baSyz147064 DLPI_SUCCESS)) { 2404d62bc4baSyz147064 die("invalid link name '%s'", link); 2405d62bc4baSyz147064 } 24067c478bd9Sstevel@tonic-gate } 24077c478bd9Sstevel@tonic-gate 2408d62bc4baSyz147064 if (altroot != NULL) 2409d62bc4baSyz147064 altroot_cmd(altroot, argc, argv); 2410d62bc4baSyz147064 24114ac67f02SAnurag S. Maskey if (dladm_name2info(handle, link, &dev_linkid, NULL, NULL, NULL) != 2412d62bc4baSyz147064 DLADM_STATUS_OK) { 2413d62bc4baSyz147064 die("invalid link name '%s'", link); 2414d62bc4baSyz147064 } 2415d62bc4baSyz147064 241663a6526dSMichael Lim if (dladm_parse_link_props(propstr, &proplist, B_FALSE) 241763a6526dSMichael Lim != DLADM_STATUS_OK) 241863a6526dSMichael Lim die("invalid vlan property"); 241963a6526dSMichael Lim 24204eaa4710SRishi Srivatsavai status = dladm_vlan_create(handle, vlan, dev_linkid, vid, proplist, 24214eaa4710SRishi Srivatsavai flags, &linkid); 24224eaa4710SRishi Srivatsavai switch (status) { 24234eaa4710SRishi Srivatsavai case DLADM_STATUS_OK: 24244eaa4710SRishi Srivatsavai break; 24254eaa4710SRishi Srivatsavai 24264eaa4710SRishi Srivatsavai case DLADM_STATUS_NOTSUP: 24274eaa4710SRishi Srivatsavai die("VLAN over '%s' may require lowered MTU; must use -f (see " 24284eaa4710SRishi Srivatsavai "dladm(1M))", link); 24294eaa4710SRishi Srivatsavai break; 24304eaa4710SRishi Srivatsavai 24314eaa4710SRishi Srivatsavai case DLADM_STATUS_LINKBUSY: 24326f40bf67SRishi Srivatsavai die("VLAN over '%s' may not use default_tag ID " 24336f40bf67SRishi Srivatsavai "(see dladm(1M))", link); 24344eaa4710SRishi Srivatsavai break; 24354eaa4710SRishi Srivatsavai 24364eaa4710SRishi Srivatsavai default: 24374eaa4710SRishi Srivatsavai die_dlerr(status, "create operation failed"); 2438d62bc4baSyz147064 } 2439d62bc4baSyz147064 } 2440d62bc4baSyz147064 2441d62bc4baSyz147064 static void 24428d5c46e6Sam223141 do_delete_vlan(int argc, char *argv[], const char *use) 2443d62bc4baSyz147064 { 2444b509e89bSRishi Srivatsavai int option; 2445d62bc4baSyz147064 uint32_t flags = (DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST); 2446d62bc4baSyz147064 char *altroot = NULL; 2447d62bc4baSyz147064 datalink_id_t linkid; 2448d62bc4baSyz147064 dladm_status_t status; 2449d62bc4baSyz147064 2450d62bc4baSyz147064 opterr = 0; 2451d62bc4baSyz147064 while ((option = getopt_long(argc, argv, ":R:t", lopts, NULL)) != -1) { 2452d62bc4baSyz147064 switch (option) { 2453d62bc4baSyz147064 case 't': 2454d62bc4baSyz147064 flags &= ~DLADM_OPT_PERSIST; 2455d62bc4baSyz147064 break; 2456d62bc4baSyz147064 case 'R': 2457d62bc4baSyz147064 altroot = optarg; 2458d62bc4baSyz147064 break; 2459d62bc4baSyz147064 default: 24608d5c46e6Sam223141 die_opterr(optopt, option, use); 2461d62bc4baSyz147064 break; 2462d62bc4baSyz147064 } 2463d62bc4baSyz147064 } 2464d62bc4baSyz147064 2465d62bc4baSyz147064 /* get VLAN link name (required last argument) */ 2466d62bc4baSyz147064 if (optind != (argc - 1)) 2467d62bc4baSyz147064 usage(); 2468d62bc4baSyz147064 2469d62bc4baSyz147064 if (altroot != NULL) 2470d62bc4baSyz147064 altroot_cmd(altroot, argc, argv); 2471d62bc4baSyz147064 24724ac67f02SAnurag S. Maskey status = dladm_name2info(handle, argv[optind], &linkid, NULL, NULL, 24734ac67f02SAnurag S. Maskey NULL); 2474d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 2475d62bc4baSyz147064 goto done; 2476d62bc4baSyz147064 24774ac67f02SAnurag S. Maskey status = dladm_vlan_delete(handle, linkid, flags); 2478d62bc4baSyz147064 done: 2479d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 2480d62bc4baSyz147064 die_dlerr(status, "delete operation failed"); 2481d62bc4baSyz147064 } 2482d62bc4baSyz147064 24838d5c46e6Sam223141 /*ARGSUSED*/ 2484d62bc4baSyz147064 static void 24858d5c46e6Sam223141 do_up_vlan(int argc, char *argv[], const char *use) 2486d62bc4baSyz147064 { 2487da14cebeSEric Cheng do_up_vnic_common(argc, argv, use, B_TRUE); 24887c478bd9Sstevel@tonic-gate } 24897c478bd9Sstevel@tonic-gate 2490210db224Sericheng static void 24918d5c46e6Sam223141 do_rename_link(int argc, char *argv[], const char *use) 2492210db224Sericheng { 2493b509e89bSRishi Srivatsavai int option; 2494d62bc4baSyz147064 char *link1, *link2; 2495d62bc4baSyz147064 char *altroot = NULL; 2496d62bc4baSyz147064 dladm_status_t status; 2497210db224Sericheng 2498d62bc4baSyz147064 opterr = 0; 2499d62bc4baSyz147064 while ((option = getopt_long(argc, argv, ":R:", lopts, NULL)) != -1) { 2500d62bc4baSyz147064 switch (option) { 2501d62bc4baSyz147064 case 'R': 2502d62bc4baSyz147064 altroot = optarg; 2503d62bc4baSyz147064 break; 2504d62bc4baSyz147064 default: 25058d5c46e6Sam223141 die_opterr(optopt, option, use); 2506d62bc4baSyz147064 break; 2507210db224Sericheng } 2508210db224Sericheng } 2509210db224Sericheng 2510d62bc4baSyz147064 /* get link1 and link2 name (required the last 2 arguments) */ 2511d62bc4baSyz147064 if (optind != (argc - 2)) 2512d62bc4baSyz147064 usage(); 2513d62bc4baSyz147064 2514d62bc4baSyz147064 if (altroot != NULL) 2515d62bc4baSyz147064 altroot_cmd(altroot, argc, argv); 2516d62bc4baSyz147064 2517d62bc4baSyz147064 link1 = argv[optind++]; 2518d62bc4baSyz147064 link2 = argv[optind]; 25194ac67f02SAnurag S. Maskey if ((status = dladm_rename_link(handle, link1, link2)) != 25204ac67f02SAnurag S. Maskey DLADM_STATUS_OK) 2521d62bc4baSyz147064 die_dlerr(status, "rename operation failed"); 2522d62bc4baSyz147064 } 2523d62bc4baSyz147064 25248d5c46e6Sam223141 /*ARGSUSED*/ 2525d62bc4baSyz147064 static void 25268d5c46e6Sam223141 do_delete_phys(int argc, char *argv[], const char *use) 2527d62bc4baSyz147064 { 2528d62bc4baSyz147064 datalink_id_t linkid = DATALINK_ALL_LINKID; 2529d62bc4baSyz147064 dladm_status_t status; 2530d62bc4baSyz147064 2531d62bc4baSyz147064 /* get link name (required the last argument) */ 2532d62bc4baSyz147064 if (argc > 2) 2533d62bc4baSyz147064 usage(); 2534d62bc4baSyz147064 2535d62bc4baSyz147064 if (argc == 2) { 25364ac67f02SAnurag S. Maskey if ((status = dladm_name2info(handle, argv[1], &linkid, NULL, 25374ac67f02SAnurag S. Maskey NULL, NULL)) != DLADM_STATUS_OK) 2538d62bc4baSyz147064 die_dlerr(status, "cannot delete '%s'", argv[1]); 2539d62bc4baSyz147064 } 2540d62bc4baSyz147064 25414ac67f02SAnurag S. Maskey if ((status = dladm_phys_delete(handle, linkid)) != DLADM_STATUS_OK) { 2542d62bc4baSyz147064 if (argc == 2) 2543d62bc4baSyz147064 die_dlerr(status, "cannot delete '%s'", argv[1]); 2544d62bc4baSyz147064 else 2545d62bc4baSyz147064 die_dlerr(status, "delete operation failed"); 2546d62bc4baSyz147064 } 2547d62bc4baSyz147064 } 2548d62bc4baSyz147064 2549d62bc4baSyz147064 /*ARGSUSED*/ 2550210db224Sericheng static int 25514ac67f02SAnurag S. Maskey i_dladm_walk_linkmap(dladm_handle_t dh, datalink_id_t linkid, void *arg) 2552210db224Sericheng { 2553d62bc4baSyz147064 char name[MAXLINKNAMELEN]; 2554d62bc4baSyz147064 char mediabuf[DLADM_STRSIZE]; 2555d62bc4baSyz147064 char classbuf[DLADM_STRSIZE]; 2556d62bc4baSyz147064 datalink_class_t class; 2557d62bc4baSyz147064 uint32_t media; 2558d62bc4baSyz147064 uint32_t flags; 2559210db224Sericheng 25604ac67f02SAnurag S. Maskey if (dladm_datalink_id2info(dh, linkid, &flags, &class, &media, name, 2561d62bc4baSyz147064 MAXLINKNAMELEN) == DLADM_STATUS_OK) { 2562d62bc4baSyz147064 (void) dladm_class2str(class, classbuf); 2563d62bc4baSyz147064 (void) dladm_media2str(media, mediabuf); 2564d62bc4baSyz147064 (void) printf("%-12s%8d %-12s%-20s %6d\n", name, 2565d62bc4baSyz147064 linkid, classbuf, mediabuf, flags); 2566210db224Sericheng } 2567d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 2568210db224Sericheng } 25697c478bd9Sstevel@tonic-gate 25707c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 25717c478bd9Sstevel@tonic-gate static void 25728d5c46e6Sam223141 do_show_linkmap(int argc, char *argv[], const char *use) 25737c478bd9Sstevel@tonic-gate { 2574d62bc4baSyz147064 if (argc != 1) 2575d62bc4baSyz147064 die("invalid arguments"); 25767c478bd9Sstevel@tonic-gate 2577d62bc4baSyz147064 (void) printf("%-12s%8s %-12s%-20s %6s\n", "NAME", "LINKID", 2578d62bc4baSyz147064 "CLASS", "MEDIA", "FLAGS"); 25794ac67f02SAnurag S. Maskey 25804ac67f02SAnurag S. Maskey (void) dladm_walk_datalink_id(i_dladm_walk_linkmap, handle, NULL, 2581d62bc4baSyz147064 DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE, 2582d62bc4baSyz147064 DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST); 25837c478bd9Sstevel@tonic-gate } 2584d62bc4baSyz147064 2585d62bc4baSyz147064 /* 2586d62bc4baSyz147064 * Delete inactive physical links. 2587d62bc4baSyz147064 */ 2588d62bc4baSyz147064 /*ARGSUSED*/ 2589d62bc4baSyz147064 static int 25904ac67f02SAnurag S. Maskey purge_phys(dladm_handle_t dh, datalink_id_t linkid, void *arg) 2591d62bc4baSyz147064 { 2592d62bc4baSyz147064 datalink_class_t class; 2593d62bc4baSyz147064 uint32_t flags; 2594d62bc4baSyz147064 25954ac67f02SAnurag S. Maskey if (dladm_datalink_id2info(dh, linkid, &flags, &class, NULL, NULL, 0) 25964ac67f02SAnurag S. Maskey != DLADM_STATUS_OK) { 2597d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 2598d62bc4baSyz147064 } 2599d62bc4baSyz147064 2600d62bc4baSyz147064 if (class == DATALINK_CLASS_PHYS && !(flags & DLADM_OPT_ACTIVE)) 26014ac67f02SAnurag S. Maskey (void) dladm_phys_delete(dh, linkid); 2602d62bc4baSyz147064 2603d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 2604d62bc4baSyz147064 } 2605d62bc4baSyz147064 2606d62bc4baSyz147064 /*ARGSUSED*/ 2607d62bc4baSyz147064 static void 26088d5c46e6Sam223141 do_init_phys(int argc, char *argv[], const char *use) 2609d62bc4baSyz147064 { 2610d62bc4baSyz147064 di_node_t devtree; 2611d62bc4baSyz147064 2612d62bc4baSyz147064 if (argc > 1) 2613d62bc4baSyz147064 usage(); 2614d62bc4baSyz147064 2615d62bc4baSyz147064 /* 2616d62bc4baSyz147064 * Force all the devices to attach, therefore all the network physical 2617d62bc4baSyz147064 * devices can be known to the dlmgmtd daemon. 2618d62bc4baSyz147064 */ 2619d62bc4baSyz147064 if ((devtree = di_init("/", DINFOFORCE | DINFOSUBTREE)) != DI_NODE_NIL) 2620d62bc4baSyz147064 di_fini(devtree); 2621d62bc4baSyz147064 26224ac67f02SAnurag S. Maskey (void) dladm_walk_datalink_id(purge_phys, handle, NULL, 2623d62bc4baSyz147064 DATALINK_CLASS_PHYS, DATALINK_ANY_MEDIATYPE, DLADM_OPT_PERSIST); 26247c478bd9Sstevel@tonic-gate } 26257c478bd9Sstevel@tonic-gate 2626d62bc4baSyz147064 /* 2627d62bc4baSyz147064 * Print the active topology information. 2628d62bc4baSyz147064 */ 26292b24ab6bSSebastien Roy void 2630d62bc4baSyz147064 print_link_topology(show_state_t *state, datalink_id_t linkid, 2631e7801d59Ssowmini datalink_class_t class, link_fields_buf_t *lbuf) 2632d62bc4baSyz147064 { 2633d62bc4baSyz147064 uint32_t flags = state->ls_flags; 26344eaa4710SRishi Srivatsavai dladm_status_t status; 26356b9e797cSsowmini char tmpbuf[MAXLINKNAMELEN]; 2636d62bc4baSyz147064 2637b509e89bSRishi Srivatsavai lbuf->link_over[0] = '\0'; 26384eaa4710SRishi Srivatsavai lbuf->link_bridge[0] = '\0'; 2639b509e89bSRishi Srivatsavai 2640b509e89bSRishi Srivatsavai switch (class) { 26414eaa4710SRishi Srivatsavai case DATALINK_CLASS_AGGR: 26424eaa4710SRishi Srivatsavai case DATALINK_CLASS_PHYS: 26434eaa4710SRishi Srivatsavai case DATALINK_CLASS_ETHERSTUB: 26444eaa4710SRishi Srivatsavai status = dladm_bridge_getlink(handle, linkid, lbuf->link_bridge, 26454eaa4710SRishi Srivatsavai sizeof (lbuf->link_bridge)); 26462b24ab6bSSebastien Roy if (status != DLADM_STATUS_OK && 26472b24ab6bSSebastien Roy status != DLADM_STATUS_NOTFOUND) 26482b24ab6bSSebastien Roy (void) strcpy(lbuf->link_bridge, "?"); 26494eaa4710SRishi Srivatsavai break; 26504eaa4710SRishi Srivatsavai } 26514eaa4710SRishi Srivatsavai 26524eaa4710SRishi Srivatsavai switch (class) { 2653b509e89bSRishi Srivatsavai case DATALINK_CLASS_VLAN: { 2654d62bc4baSyz147064 dladm_vlan_attr_t vinfo; 2655d62bc4baSyz147064 26562b24ab6bSSebastien Roy if (dladm_vlan_info(handle, linkid, &vinfo, flags) != 26572b24ab6bSSebastien Roy DLADM_STATUS_OK) { 26582b24ab6bSSebastien Roy (void) strcpy(lbuf->link_over, "?"); 2659b509e89bSRishi Srivatsavai break; 2660b509e89bSRishi Srivatsavai } 26612b24ab6bSSebastien Roy if (dladm_datalink_id2info(handle, vinfo.dv_linkid, NULL, NULL, 26622b24ab6bSSebastien Roy NULL, lbuf->link_over, sizeof (lbuf->link_over)) != 26632b24ab6bSSebastien Roy DLADM_STATUS_OK) 26642b24ab6bSSebastien Roy (void) strcpy(lbuf->link_over, "?"); 26652b24ab6bSSebastien Roy break; 26662b24ab6bSSebastien Roy } 2667b509e89bSRishi Srivatsavai case DATALINK_CLASS_AGGR: { 2668d62bc4baSyz147064 dladm_aggr_grp_attr_t ginfo; 2669d62bc4baSyz147064 int i; 2670d62bc4baSyz147064 26712b24ab6bSSebastien Roy if (dladm_aggr_info(handle, linkid, &ginfo, flags) != 26722b24ab6bSSebastien Roy DLADM_STATUS_OK || ginfo.lg_nports == 0) { 26732b24ab6bSSebastien Roy (void) strcpy(lbuf->link_over, "?"); 2674b509e89bSRishi Srivatsavai break; 2675d62bc4baSyz147064 } 2676d62bc4baSyz147064 for (i = 0; i < ginfo.lg_nports; i++) { 26772b24ab6bSSebastien Roy if (dladm_datalink_id2info(handle, 2678e7801d59Ssowmini ginfo.lg_ports[i].lp_linkid, NULL, NULL, NULL, 26792b24ab6bSSebastien Roy tmpbuf, sizeof (tmpbuf)) != DLADM_STATUS_OK) { 26802b24ab6bSSebastien Roy (void) strcpy(lbuf->link_over, "?"); 2681b509e89bSRishi Srivatsavai break; 26822b24ab6bSSebastien Roy } 26836b9e797cSsowmini (void) strlcat(lbuf->link_over, tmpbuf, 26846b9e797cSsowmini sizeof (lbuf->link_over)); 26856b9e797cSsowmini if (i != (ginfo.lg_nports - 1)) { 26866b9e797cSsowmini (void) strlcat(lbuf->link_over, " ", 26876b9e797cSsowmini sizeof (lbuf->link_over)); 26886b9e797cSsowmini } 2689d62bc4baSyz147064 } 2690d62bc4baSyz147064 free(ginfo.lg_ports); 2691b509e89bSRishi Srivatsavai break; 2692b509e89bSRishi Srivatsavai } 2693b509e89bSRishi Srivatsavai case DATALINK_CLASS_VNIC: { 2694da14cebeSEric Cheng dladm_vnic_attr_t vinfo; 2695d62bc4baSyz147064 26962b24ab6bSSebastien Roy if (dladm_vnic_info(handle, linkid, &vinfo, flags) != 26972b24ab6bSSebastien Roy DLADM_STATUS_OK) { 26982b24ab6bSSebastien Roy (void) strcpy(lbuf->link_over, "?"); 2699b509e89bSRishi Srivatsavai break; 2700b509e89bSRishi Srivatsavai } 27012b24ab6bSSebastien Roy if (dladm_datalink_id2info(handle, vinfo.va_link_id, NULL, NULL, 27022b24ab6bSSebastien Roy NULL, lbuf->link_over, sizeof (lbuf->link_over)) != 27032b24ab6bSSebastien Roy DLADM_STATUS_OK) 27042b24ab6bSSebastien Roy (void) strcpy(lbuf->link_over, "?"); 27052b24ab6bSSebastien Roy break; 27062b24ab6bSSebastien Roy } 27071cfa752fSRamaswamy Tummala 27081cfa752fSRamaswamy Tummala case DATALINK_CLASS_PART: { 27091cfa752fSRamaswamy Tummala dladm_part_attr_t pinfo; 27101cfa752fSRamaswamy Tummala 27111cfa752fSRamaswamy Tummala if (dladm_part_info(handle, linkid, &pinfo, flags) != 27121cfa752fSRamaswamy Tummala DLADM_STATUS_OK) { 27131cfa752fSRamaswamy Tummala (void) strcpy(lbuf->link_over, "?"); 27141cfa752fSRamaswamy Tummala break; 27151cfa752fSRamaswamy Tummala } 27161cfa752fSRamaswamy Tummala if (dladm_datalink_id2info(handle, pinfo.dia_physlinkid, NULL, 27171cfa752fSRamaswamy Tummala NULL, NULL, lbuf->link_over, sizeof (lbuf->link_over)) != 27181cfa752fSRamaswamy Tummala DLADM_STATUS_OK) 27191cfa752fSRamaswamy Tummala (void) strcpy(lbuf->link_over, "?"); 27201cfa752fSRamaswamy Tummala break; 27211cfa752fSRamaswamy Tummala } 27221cfa752fSRamaswamy Tummala 27234eaa4710SRishi Srivatsavai case DATALINK_CLASS_BRIDGE: { 27244eaa4710SRishi Srivatsavai datalink_id_t *dlp; 27254eaa4710SRishi Srivatsavai uint_t i, nports; 27264eaa4710SRishi Srivatsavai 27272b24ab6bSSebastien Roy if (dladm_datalink_id2info(handle, linkid, NULL, NULL, 27282b24ab6bSSebastien Roy NULL, tmpbuf, sizeof (tmpbuf)) != DLADM_STATUS_OK) { 27292b24ab6bSSebastien Roy (void) strcpy(lbuf->link_over, "?"); 27304eaa4710SRishi Srivatsavai break; 27312b24ab6bSSebastien Roy } 27324eaa4710SRishi Srivatsavai if (tmpbuf[0] != '\0') 27334eaa4710SRishi Srivatsavai tmpbuf[strlen(tmpbuf) - 1] = '\0'; 27344eaa4710SRishi Srivatsavai dlp = dladm_bridge_get_portlist(tmpbuf, &nports); 27354eaa4710SRishi Srivatsavai if (dlp == NULL) { 27362b24ab6bSSebastien Roy (void) strcpy(lbuf->link_over, "?"); 27374eaa4710SRishi Srivatsavai break; 27384eaa4710SRishi Srivatsavai } 27394eaa4710SRishi Srivatsavai for (i = 0; i < nports; i++) { 27402b24ab6bSSebastien Roy if (dladm_datalink_id2info(handle, dlp[i], NULL, 27412b24ab6bSSebastien Roy NULL, NULL, tmpbuf, sizeof (tmpbuf)) != 27422b24ab6bSSebastien Roy DLADM_STATUS_OK) { 27432b24ab6bSSebastien Roy (void) strcpy(lbuf->link_over, "?"); 27444eaa4710SRishi Srivatsavai break; 27452b24ab6bSSebastien Roy } 27464eaa4710SRishi Srivatsavai (void) strlcat(lbuf->link_over, tmpbuf, 27474eaa4710SRishi Srivatsavai sizeof (lbuf->link_over)); 27484eaa4710SRishi Srivatsavai if (i != nports - 1) { 27494eaa4710SRishi Srivatsavai (void) strlcat(lbuf->link_over, " ", 27504eaa4710SRishi Srivatsavai sizeof (lbuf->link_over)); 27514eaa4710SRishi Srivatsavai } 27524eaa4710SRishi Srivatsavai } 27534eaa4710SRishi Srivatsavai dladm_bridge_free_portlist(dlp); 27544eaa4710SRishi Srivatsavai break; 27554eaa4710SRishi Srivatsavai } 27564eaa4710SRishi Srivatsavai 2757b509e89bSRishi Srivatsavai case DATALINK_CLASS_SIMNET: { 2758b509e89bSRishi Srivatsavai dladm_simnet_attr_t slinfo; 2759b509e89bSRishi Srivatsavai 27602b24ab6bSSebastien Roy if (dladm_simnet_info(handle, linkid, &slinfo, flags) != 27612b24ab6bSSebastien Roy DLADM_STATUS_OK) { 27622b24ab6bSSebastien Roy (void) strcpy(lbuf->link_over, "?"); 27632b24ab6bSSebastien Roy break; 27642b24ab6bSSebastien Roy } 27652b24ab6bSSebastien Roy if (slinfo.sna_peer_link_id != DATALINK_INVALID_LINKID) { 27662b24ab6bSSebastien Roy if (dladm_datalink_id2info(handle, 2767b509e89bSRishi Srivatsavai slinfo.sna_peer_link_id, NULL, NULL, NULL, 27682b24ab6bSSebastien Roy lbuf->link_over, sizeof (lbuf->link_over)) != 27692b24ab6bSSebastien Roy DLADM_STATUS_OK) 27702b24ab6bSSebastien Roy (void) strcpy(lbuf->link_over, "?"); 27712b24ab6bSSebastien Roy } 2772b509e89bSRishi Srivatsavai break; 2773d62bc4baSyz147064 } 2774d62bc4baSyz147064 } 2775d62bc4baSyz147064 } 2776d62bc4baSyz147064 2777d62bc4baSyz147064 static dladm_status_t 2778e7801d59Ssowmini print_link(show_state_t *state, datalink_id_t linkid, link_fields_buf_t *lbuf) 2779d62bc4baSyz147064 { 2780d62bc4baSyz147064 char link[MAXLINKNAMELEN]; 2781d62bc4baSyz147064 datalink_class_t class; 2782d62bc4baSyz147064 uint_t mtu; 2783d62bc4baSyz147064 uint32_t flags; 2784d62bc4baSyz147064 dladm_status_t status; 2785d62bc4baSyz147064 27864ac67f02SAnurag S. Maskey if ((status = dladm_datalink_id2info(handle, linkid, &flags, &class, 27874ac67f02SAnurag S. Maskey NULL, link, sizeof (link))) != DLADM_STATUS_OK) { 2788d62bc4baSyz147064 goto done; 2789d62bc4baSyz147064 } 2790d62bc4baSyz147064 2791d62bc4baSyz147064 if (!(state->ls_flags & flags)) { 2792d62bc4baSyz147064 status = DLADM_STATUS_NOTFOUND; 2793d62bc4baSyz147064 goto done; 2794d62bc4baSyz147064 } 2795d62bc4baSyz147064 2796d62bc4baSyz147064 if (state->ls_flags == DLADM_OPT_ACTIVE) { 2797d62bc4baSyz147064 dladm_attr_t dlattr; 2798d62bc4baSyz147064 2799d62bc4baSyz147064 if (class == DATALINK_CLASS_PHYS) { 2800d62bc4baSyz147064 dladm_phys_attr_t dpa; 2801d62bc4baSyz147064 dlpi_handle_t dh; 2802d62bc4baSyz147064 dlpi_info_t dlinfo; 2803d62bc4baSyz147064 28044ac67f02SAnurag S. Maskey if ((status = dladm_phys_info(handle, linkid, &dpa, 2805d62bc4baSyz147064 DLADM_OPT_ACTIVE)) != DLADM_STATUS_OK) { 2806d62bc4baSyz147064 goto done; 2807d62bc4baSyz147064 } 2808d62bc4baSyz147064 2809d62bc4baSyz147064 if (!dpa.dp_novanity) 2810d62bc4baSyz147064 goto link_mtu; 2811d62bc4baSyz147064 2812d62bc4baSyz147064 /* 2813d62bc4baSyz147064 * This is a physical link that does not have 2814d62bc4baSyz147064 * vanity naming support. 2815d62bc4baSyz147064 */ 2816d62bc4baSyz147064 if (dlpi_open(dpa.dp_dev, &dh, DLPI_DEVONLY) != 2817d62bc4baSyz147064 DLPI_SUCCESS) { 2818d62bc4baSyz147064 status = DLADM_STATUS_NOTFOUND; 2819d62bc4baSyz147064 goto done; 2820d62bc4baSyz147064 } 2821d62bc4baSyz147064 2822d62bc4baSyz147064 if (dlpi_info(dh, &dlinfo, 0) != DLPI_SUCCESS) { 2823d62bc4baSyz147064 dlpi_close(dh); 2824d62bc4baSyz147064 status = DLADM_STATUS_BADARG; 2825d62bc4baSyz147064 goto done; 2826d62bc4baSyz147064 } 2827d62bc4baSyz147064 2828d62bc4baSyz147064 dlpi_close(dh); 2829d62bc4baSyz147064 mtu = dlinfo.di_max_sdu; 2830d62bc4baSyz147064 } else { 2831d62bc4baSyz147064 link_mtu: 28324ac67f02SAnurag S. Maskey status = dladm_info(handle, linkid, &dlattr); 2833d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 2834d62bc4baSyz147064 goto done; 2835d62bc4baSyz147064 mtu = dlattr.da_max_sdu; 2836d62bc4baSyz147064 } 2837d62bc4baSyz147064 } 2838d62bc4baSyz147064 2839e7801d59Ssowmini (void) snprintf(lbuf->link_name, sizeof (lbuf->link_name), 2840e7801d59Ssowmini "%s", link); 2841e7801d59Ssowmini (void) dladm_class2str(class, lbuf->link_class); 2842d62bc4baSyz147064 if (state->ls_flags == DLADM_OPT_ACTIVE) { 2843e7801d59Ssowmini (void) snprintf(lbuf->link_mtu, sizeof (lbuf->link_mtu), 2844c08e5e1aSdr146992 "%u", mtu); 2845e7801d59Ssowmini (void) get_linkstate(link, B_TRUE, lbuf->link_state); 2846d62bc4baSyz147064 } 2847d62bc4baSyz147064 28482b24ab6bSSebastien Roy print_link_topology(state, linkid, class, lbuf); 2849d62bc4baSyz147064 done: 2850d62bc4baSyz147064 return (status); 2851d62bc4baSyz147064 } 2852d62bc4baSyz147064 28534ac67f02SAnurag S. Maskey /* ARGSUSED */ 2854d62bc4baSyz147064 static int 28554ac67f02SAnurag S. Maskey show_link(dladm_handle_t dh, datalink_id_t linkid, void *arg) 2856d62bc4baSyz147064 { 2857e7801d59Ssowmini show_state_t *state = (show_state_t *)arg; 2858d62bc4baSyz147064 dladm_status_t status; 2859e7801d59Ssowmini link_fields_buf_t lbuf; 2860d62bc4baSyz147064 2861e7801d59Ssowmini /* 2862e7801d59Ssowmini * first get all the link attributes into lbuf; 2863e7801d59Ssowmini */ 28645f5c9f54SAnurag S. Maskey bzero(&lbuf, sizeof (link_fields_buf_t)); 28652b24ab6bSSebastien Roy if ((status = print_link(state, linkid, &lbuf)) == DLADM_STATUS_OK) 28668002d411SSowmini Varadhan ofmt_print(state->ls_ofmt, &lbuf); 2867d62bc4baSyz147064 state->ls_status = status; 2868d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 2869d62bc4baSyz147064 } 2870d62bc4baSyz147064 28718002d411SSowmini Varadhan static boolean_t 28728002d411SSowmini Varadhan print_link_stats_cb(ofmt_arg_t *ofarg, char *buf, uint_t bufsize) 2873ae6aa22aSVenugopal Iyer { 28748002d411SSowmini Varadhan link_args_t *largs = ofarg->ofmt_cbarg; 2875ae6aa22aSVenugopal Iyer pktsum_t *diff_stats = largs->link_s_psum; 2876ae6aa22aSVenugopal Iyer 28778002d411SSowmini Varadhan switch (ofarg->ofmt_id) { 2878ae6aa22aSVenugopal Iyer case LINK_S_LINK: 28798002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%s", largs->link_s_link); 2880ae6aa22aSVenugopal Iyer break; 2881ae6aa22aSVenugopal Iyer case LINK_S_IPKTS: 28828002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%llu", diff_stats->ipackets); 2883ae6aa22aSVenugopal Iyer break; 2884ae6aa22aSVenugopal Iyer case LINK_S_RBYTES: 28858002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%llu", diff_stats->rbytes); 2886ae6aa22aSVenugopal Iyer break; 2887ae6aa22aSVenugopal Iyer case LINK_S_IERRORS: 28888002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%u", diff_stats->ierrors); 2889ae6aa22aSVenugopal Iyer break; 2890ae6aa22aSVenugopal Iyer case LINK_S_OPKTS: 28918002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%llu", diff_stats->opackets); 2892ae6aa22aSVenugopal Iyer break; 2893ae6aa22aSVenugopal Iyer case LINK_S_OBYTES: 28948002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%llu", diff_stats->obytes); 2895ae6aa22aSVenugopal Iyer break; 2896ae6aa22aSVenugopal Iyer case LINK_S_OERRORS: 28978002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%u", diff_stats->oerrors); 2898ae6aa22aSVenugopal Iyer break; 2899ae6aa22aSVenugopal Iyer default: 2900ae6aa22aSVenugopal Iyer die("invalid input"); 2901ae6aa22aSVenugopal Iyer break; 2902ae6aa22aSVenugopal Iyer } 29038002d411SSowmini Varadhan return (B_TRUE); 2904ae6aa22aSVenugopal Iyer } 2905ae6aa22aSVenugopal Iyer 2906d62bc4baSyz147064 static int 29074ac67f02SAnurag S. Maskey show_link_stats(dladm_handle_t dh, datalink_id_t linkid, void *arg) 2908d62bc4baSyz147064 { 2909e7801d59Ssowmini char link[DLPI_LINKNAME_MAX]; 2910d62bc4baSyz147064 datalink_class_t class; 29112b24ab6bSSebastien Roy show_state_t *state = arg; 29127c478bd9Sstevel@tonic-gate pktsum_t stats, diff_stats; 2913d62bc4baSyz147064 dladm_phys_attr_t dpa; 2914ae6aa22aSVenugopal Iyer link_args_t largs; 29157c478bd9Sstevel@tonic-gate 29167c478bd9Sstevel@tonic-gate if (state->ls_firstonly) { 29177c478bd9Sstevel@tonic-gate if (state->ls_donefirst) 2918d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 29197c478bd9Sstevel@tonic-gate state->ls_donefirst = B_TRUE; 29207c478bd9Sstevel@tonic-gate } else { 29217c478bd9Sstevel@tonic-gate bzero(&state->ls_prevstats, sizeof (state->ls_prevstats)); 29227c478bd9Sstevel@tonic-gate } 29237c478bd9Sstevel@tonic-gate 29244ac67f02SAnurag S. Maskey if (dladm_datalink_id2info(dh, linkid, NULL, &class, NULL, link, 2925e7801d59Ssowmini DLPI_LINKNAME_MAX) != DLADM_STATUS_OK) { 2926d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 2927d62bc4baSyz147064 } 2928d62bc4baSyz147064 2929d62bc4baSyz147064 if (class == DATALINK_CLASS_PHYS) { 29304ac67f02SAnurag S. Maskey if (dladm_phys_info(dh, linkid, &dpa, DLADM_OPT_ACTIVE) != 2931d62bc4baSyz147064 DLADM_STATUS_OK) { 2932d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 2933d62bc4baSyz147064 } 2934d62bc4baSyz147064 if (dpa.dp_novanity) 2935d62bc4baSyz147064 get_mac_stats(dpa.dp_dev, &stats); 2936d62bc4baSyz147064 else 2937d62bc4baSyz147064 get_link_stats(link, &stats); 2938d62bc4baSyz147064 } else { 2939d62bc4baSyz147064 get_link_stats(link, &stats); 2940d62bc4baSyz147064 } 2941da14cebeSEric Cheng dladm_stats_diff(&diff_stats, &stats, &state->ls_prevstats); 29427c478bd9Sstevel@tonic-gate 2943ae6aa22aSVenugopal Iyer largs.link_s_link = link; 2944ae6aa22aSVenugopal Iyer largs.link_s_psum = &diff_stats; 29458002d411SSowmini Varadhan ofmt_print(state->ls_ofmt, &largs); 29467c478bd9Sstevel@tonic-gate 29477c478bd9Sstevel@tonic-gate state->ls_prevstats = stats; 2948d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 29497c478bd9Sstevel@tonic-gate } 29507c478bd9Sstevel@tonic-gate 2951d62bc4baSyz147064 2952d62bc4baSyz147064 static dladm_status_t 2953d62bc4baSyz147064 print_aggr_info(show_grp_state_t *state, const char *link, 2954e7801d59Ssowmini dladm_aggr_grp_attr_t *ginfop) 2955d62bc4baSyz147064 { 2956d62bc4baSyz147064 char addr_str[ETHERADDRL * 3]; 2957e7801d59Ssowmini laggr_fields_buf_t lbuf; 2958d62bc4baSyz147064 2959e7801d59Ssowmini (void) snprintf(lbuf.laggr_name, sizeof (lbuf.laggr_name), 2960e7801d59Ssowmini "%s", link); 2961e7801d59Ssowmini 2962e7801d59Ssowmini (void) dladm_aggr_policy2str(ginfop->lg_policy, 2963e7801d59Ssowmini lbuf.laggr_policy); 2964d62bc4baSyz147064 2965d62bc4baSyz147064 if (ginfop->lg_mac_fixed) { 2966d62bc4baSyz147064 (void) dladm_aggr_macaddr2str(ginfop->lg_mac, addr_str); 2967e7801d59Ssowmini (void) snprintf(lbuf.laggr_addrpolicy, 2968e7801d59Ssowmini sizeof (lbuf.laggr_addrpolicy), "fixed (%s)", addr_str); 2969d62bc4baSyz147064 } else { 2970e7801d59Ssowmini (void) snprintf(lbuf.laggr_addrpolicy, 2971e7801d59Ssowmini sizeof (lbuf.laggr_addrpolicy), "auto"); 2972d62bc4baSyz147064 } 2973d62bc4baSyz147064 2974e7801d59Ssowmini (void) dladm_aggr_lacpmode2str(ginfop->lg_lacp_mode, 2975e7801d59Ssowmini lbuf.laggr_lacpactivity); 2976e7801d59Ssowmini (void) dladm_aggr_lacptimer2str(ginfop->lg_lacp_timer, 2977e7801d59Ssowmini lbuf.laggr_lacptimer); 2978e7801d59Ssowmini (void) snprintf(lbuf.laggr_flags, sizeof (lbuf.laggr_flags), "%c----", 2979d62bc4baSyz147064 ginfop->lg_force ? 'f' : '-'); 2980e7801d59Ssowmini 29818002d411SSowmini Varadhan ofmt_print(state->gs_ofmt, &lbuf); 2982e7801d59Ssowmini 2983d62bc4baSyz147064 return (DLADM_STATUS_OK); 2984d62bc4baSyz147064 } 2985d62bc4baSyz147064 29868002d411SSowmini Varadhan static boolean_t 29878002d411SSowmini Varadhan print_xaggr_cb(ofmt_arg_t *ofarg, char *buf, uint_t bufsize) 2988d62bc4baSyz147064 { 29898002d411SSowmini Varadhan const laggr_args_t *l = ofarg->ofmt_cbarg; 2990e7801d59Ssowmini boolean_t is_port = (l->laggr_lport >= 0); 29912b24ab6bSSebastien Roy char tmpbuf[DLADM_STRSIZE]; 29922b24ab6bSSebastien Roy const char *objname; 2993e7801d59Ssowmini dladm_aggr_port_attr_t *portp; 2994d62bc4baSyz147064 dladm_phys_attr_t dpa; 2995d62bc4baSyz147064 2996e7801d59Ssowmini if (is_port) { 29972b24ab6bSSebastien Roy portp = &(l->laggr_ginfop->lg_ports[l->laggr_lport]); 29982b24ab6bSSebastien Roy if (dladm_phys_info(handle, portp->lp_linkid, &dpa, 29992b24ab6bSSebastien Roy DLADM_OPT_ACTIVE) != DLADM_STATUS_OK) 30002b24ab6bSSebastien Roy objname = "?"; 30012b24ab6bSSebastien Roy else 30022b24ab6bSSebastien Roy objname = dpa.dp_dev; 30032b24ab6bSSebastien Roy } else { 30042b24ab6bSSebastien Roy objname = l->laggr_link; 3005d62bc4baSyz147064 } 3006d62bc4baSyz147064 30078002d411SSowmini Varadhan switch (ofarg->ofmt_id) { 3008e7801d59Ssowmini case AGGR_X_LINK: 30098002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%s", 30108002d411SSowmini Varadhan (is_port && !l->laggr_parsable ? " " : l->laggr_link)); 3011e7801d59Ssowmini break; 3012e7801d59Ssowmini case AGGR_X_PORT: 3013e7801d59Ssowmini if (is_port) { 30142b24ab6bSSebastien Roy if (dladm_datalink_id2info(handle, portp->lp_linkid, 30152b24ab6bSSebastien Roy NULL, NULL, NULL, buf, bufsize) != DLADM_STATUS_OK) 30162b24ab6bSSebastien Roy (void) sprintf(buf, "?"); 3017e7801d59Ssowmini } 3018e7801d59Ssowmini break; 3019e7801d59Ssowmini 30202b24ab6bSSebastien Roy case AGGR_X_SPEED: 30212b24ab6bSSebastien Roy (void) snprintf(buf, bufsize, "%uMb", 30222b24ab6bSSebastien Roy (uint_t)((get_ifspeed(objname, !is_port)) / 1000000ull)); 30232b24ab6bSSebastien Roy break; 30242b24ab6bSSebastien Roy 3025e7801d59Ssowmini case AGGR_X_DUPLEX: 30262b24ab6bSSebastien Roy (void) get_linkduplex(objname, !is_port, tmpbuf); 30278002d411SSowmini Varadhan (void) strlcpy(buf, tmpbuf, bufsize); 3028e7801d59Ssowmini break; 3029d62bc4baSyz147064 3030e7801d59Ssowmini case AGGR_X_STATE: 30312b24ab6bSSebastien Roy (void) get_linkstate(objname, !is_port, tmpbuf); 30328002d411SSowmini Varadhan (void) strlcpy(buf, tmpbuf, bufsize); 3033e7801d59Ssowmini break; 3034e7801d59Ssowmini case AGGR_X_ADDRESS: 3035e7801d59Ssowmini (void) dladm_aggr_macaddr2str( 3036e7801d59Ssowmini (is_port ? portp->lp_mac : l->laggr_ginfop->lg_mac), 30378002d411SSowmini Varadhan tmpbuf); 30388002d411SSowmini Varadhan (void) strlcpy(buf, tmpbuf, bufsize); 3039e7801d59Ssowmini break; 3040e7801d59Ssowmini case AGGR_X_PORTSTATE: 30418002d411SSowmini Varadhan if (is_port) { 30428002d411SSowmini Varadhan (void) dladm_aggr_portstate2str(portp->lp_state, 30438002d411SSowmini Varadhan tmpbuf); 30448002d411SSowmini Varadhan (void) strlcpy(buf, tmpbuf, bufsize); 30458002d411SSowmini Varadhan } 3046e7801d59Ssowmini break; 3047e7801d59Ssowmini } 3048e7801d59Ssowmini err: 30492b24ab6bSSebastien Roy *(l->laggr_status) = DLADM_STATUS_OK; 30508002d411SSowmini Varadhan return (B_TRUE); 3051e7801d59Ssowmini } 3052e7801d59Ssowmini 3053e7801d59Ssowmini static dladm_status_t 3054e7801d59Ssowmini print_aggr_extended(show_grp_state_t *state, const char *link, 3055e7801d59Ssowmini dladm_aggr_grp_attr_t *ginfop) 3056e7801d59Ssowmini { 3057e7801d59Ssowmini int i; 3058e7801d59Ssowmini dladm_status_t status; 3059e7801d59Ssowmini laggr_args_t largs; 3060e7801d59Ssowmini 3061e7801d59Ssowmini largs.laggr_lport = -1; 3062e7801d59Ssowmini largs.laggr_link = link; 3063e7801d59Ssowmini largs.laggr_ginfop = ginfop; 3064e7801d59Ssowmini largs.laggr_status = &status; 30658002d411SSowmini Varadhan largs.laggr_parsable = state->gs_parsable; 3066e7801d59Ssowmini 30678002d411SSowmini Varadhan ofmt_print(state->gs_ofmt, &largs); 3068e7801d59Ssowmini 3069e7801d59Ssowmini if (status != DLADM_STATUS_OK) 3070e7801d59Ssowmini goto done; 3071e7801d59Ssowmini 3072e7801d59Ssowmini for (i = 0; i < ginfop->lg_nports; i++) { 3073e7801d59Ssowmini largs.laggr_lport = i; 30748002d411SSowmini Varadhan ofmt_print(state->gs_ofmt, &largs); 3075e7801d59Ssowmini if (status != DLADM_STATUS_OK) 3076e7801d59Ssowmini goto done; 3077d62bc4baSyz147064 } 3078d62bc4baSyz147064 3079d62bc4baSyz147064 status = DLADM_STATUS_OK; 3080d62bc4baSyz147064 done: 3081d62bc4baSyz147064 return (status); 3082d62bc4baSyz147064 } 3083d62bc4baSyz147064 30848002d411SSowmini Varadhan static boolean_t 30858002d411SSowmini Varadhan print_lacp_cb(ofmt_arg_t *ofarg, char *buf, uint_t bufsize) 3086e7801d59Ssowmini { 30878002d411SSowmini Varadhan const laggr_args_t *l = ofarg->ofmt_cbarg; 3088e7801d59Ssowmini int portnum; 3089e7801d59Ssowmini boolean_t is_port = (l->laggr_lport >= 0); 3090e7801d59Ssowmini dladm_aggr_port_attr_t *portp; 3091e7801d59Ssowmini aggr_lacp_state_t *lstate; 3092e7801d59Ssowmini 30932b24ab6bSSebastien Roy if (!is_port) 30948002d411SSowmini Varadhan return (B_FALSE); /* cannot happen! */ 3095e7801d59Ssowmini 3096e7801d59Ssowmini portnum = l->laggr_lport; 3097e7801d59Ssowmini portp = &(l->laggr_ginfop->lg_ports[portnum]); 3098e7801d59Ssowmini lstate = &(portp->lp_lacp_state); 3099e7801d59Ssowmini 31008002d411SSowmini Varadhan switch (ofarg->ofmt_id) { 3101e7801d59Ssowmini case AGGR_L_LINK: 31028002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%s", 3103e7801d59Ssowmini (portnum > 0 ? "" : l->laggr_link)); 3104e7801d59Ssowmini break; 3105e7801d59Ssowmini 3106e7801d59Ssowmini case AGGR_L_PORT: 31072b24ab6bSSebastien Roy if (dladm_datalink_id2info(handle, portp->lp_linkid, NULL, NULL, 31082b24ab6bSSebastien Roy NULL, buf, bufsize) != DLADM_STATUS_OK) 31092b24ab6bSSebastien Roy (void) sprintf(buf, "?"); 3110e7801d59Ssowmini break; 3111e7801d59Ssowmini 3112e7801d59Ssowmini case AGGR_L_AGGREGATABLE: 31138002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%s", 3114e7801d59Ssowmini (lstate->bit.aggregation ? "yes" : "no")); 3115e7801d59Ssowmini break; 3116e7801d59Ssowmini 3117e7801d59Ssowmini case AGGR_L_SYNC: 31188002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%s", 3119e7801d59Ssowmini (lstate->bit.sync ? "yes" : "no")); 3120e7801d59Ssowmini break; 3121e7801d59Ssowmini 3122e7801d59Ssowmini case AGGR_L_COLL: 31238002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%s", 3124e7801d59Ssowmini (lstate->bit.collecting ? "yes" : "no")); 3125e7801d59Ssowmini break; 3126e7801d59Ssowmini 3127e7801d59Ssowmini case AGGR_L_DIST: 31288002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%s", 3129e7801d59Ssowmini (lstate->bit.distributing ? "yes" : "no")); 3130e7801d59Ssowmini break; 3131e7801d59Ssowmini 3132e7801d59Ssowmini case AGGR_L_DEFAULTED: 31338002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%s", 3134e7801d59Ssowmini (lstate->bit.defaulted ? "yes" : "no")); 3135e7801d59Ssowmini break; 3136e7801d59Ssowmini 3137e7801d59Ssowmini case AGGR_L_EXPIRED: 31388002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%s", 3139e7801d59Ssowmini (lstate->bit.expired ? "yes" : "no")); 3140e7801d59Ssowmini break; 3141e7801d59Ssowmini } 3142e7801d59Ssowmini 31432b24ab6bSSebastien Roy *(l->laggr_status) = DLADM_STATUS_OK; 31448002d411SSowmini Varadhan return (B_TRUE); 3145e7801d59Ssowmini } 3146e7801d59Ssowmini 3147d62bc4baSyz147064 static dladm_status_t 3148d62bc4baSyz147064 print_aggr_lacp(show_grp_state_t *state, const char *link, 3149e7801d59Ssowmini dladm_aggr_grp_attr_t *ginfop) 3150d62bc4baSyz147064 { 3151d62bc4baSyz147064 int i; 3152d62bc4baSyz147064 dladm_status_t status; 3153e7801d59Ssowmini laggr_args_t largs; 3154d62bc4baSyz147064 3155e7801d59Ssowmini largs.laggr_link = link; 3156e7801d59Ssowmini largs.laggr_ginfop = ginfop; 3157e7801d59Ssowmini largs.laggr_status = &status; 3158d62bc4baSyz147064 3159e7801d59Ssowmini for (i = 0; i < ginfop->lg_nports; i++) { 3160e7801d59Ssowmini largs.laggr_lport = i; 31618002d411SSowmini Varadhan ofmt_print(state->gs_ofmt, &largs); 3162d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 3163d62bc4baSyz147064 goto done; 3164d62bc4baSyz147064 } 3165d62bc4baSyz147064 3166d62bc4baSyz147064 status = DLADM_STATUS_OK; 3167d62bc4baSyz147064 done: 3168d62bc4baSyz147064 return (status); 3169d62bc4baSyz147064 } 3170d62bc4baSyz147064 31718002d411SSowmini Varadhan static boolean_t 31728002d411SSowmini Varadhan print_aggr_stats_cb(ofmt_arg_t *ofarg, char *buf, uint_t bufsize) 3173e7801d59Ssowmini { 31748002d411SSowmini Varadhan const laggr_args_t *l = ofarg->ofmt_cbarg; 3175e7801d59Ssowmini int portnum; 3176e7801d59Ssowmini boolean_t is_port = (l->laggr_lport >= 0); 3177e7801d59Ssowmini dladm_aggr_port_attr_t *portp; 3178e7801d59Ssowmini dladm_status_t *stat, status; 31792d40c3b2SPrakash Jalan pktsum_t *diff_stats; 3180e7801d59Ssowmini 3181e7801d59Ssowmini stat = l->laggr_status; 3182e7801d59Ssowmini *stat = DLADM_STATUS_OK; 3183e7801d59Ssowmini 3184e7801d59Ssowmini if (is_port) { 3185e7801d59Ssowmini portnum = l->laggr_lport; 3186e7801d59Ssowmini portp = &(l->laggr_ginfop->lg_ports[portnum]); 3187e7801d59Ssowmini 31884ac67f02SAnurag S. Maskey if ((status = dladm_datalink_id2info(handle, 31898002d411SSowmini Varadhan portp->lp_linkid, NULL, NULL, NULL, buf, bufsize)) != 31904ac67f02SAnurag S. Maskey DLADM_STATUS_OK) { 3191e7801d59Ssowmini goto err; 3192e7801d59Ssowmini } 31932d40c3b2SPrakash Jalan diff_stats = l->laggr_diffstats; 3194e7801d59Ssowmini } 3195e7801d59Ssowmini 31968002d411SSowmini Varadhan switch (ofarg->ofmt_id) { 3197e7801d59Ssowmini case AGGR_S_LINK: 31988002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%s", 3199e7801d59Ssowmini (is_port ? "" : l->laggr_link)); 3200e7801d59Ssowmini break; 3201e7801d59Ssowmini case AGGR_S_PORT: 32028002d411SSowmini Varadhan /* 32038002d411SSowmini Varadhan * if (is_port), buf has port name. Otherwise we print 32048002d411SSowmini Varadhan * STR_UNDEF_VAL 32058002d411SSowmini Varadhan */ 3206e7801d59Ssowmini break; 3207e7801d59Ssowmini 3208e7801d59Ssowmini case AGGR_S_IPKTS: 3209e7801d59Ssowmini if (is_port) { 32108002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%llu", 32112d40c3b2SPrakash Jalan diff_stats->ipackets); 3212e7801d59Ssowmini } else { 32138002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%llu", 3214e7801d59Ssowmini l->laggr_pktsumtot->ipackets); 3215e7801d59Ssowmini } 3216e7801d59Ssowmini break; 3217e7801d59Ssowmini 3218e7801d59Ssowmini case AGGR_S_RBYTES: 3219e7801d59Ssowmini if (is_port) { 32208002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%llu", 32212d40c3b2SPrakash Jalan diff_stats->rbytes); 3222e7801d59Ssowmini } else { 32238002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%llu", 3224e7801d59Ssowmini l->laggr_pktsumtot->rbytes); 3225e7801d59Ssowmini } 3226e7801d59Ssowmini break; 3227e7801d59Ssowmini 3228e7801d59Ssowmini case AGGR_S_OPKTS: 3229e7801d59Ssowmini if (is_port) { 32308002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%llu", 32312d40c3b2SPrakash Jalan diff_stats->opackets); 3232e7801d59Ssowmini } else { 32338002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%llu", 3234e7801d59Ssowmini l->laggr_pktsumtot->opackets); 3235e7801d59Ssowmini } 3236e7801d59Ssowmini break; 3237e7801d59Ssowmini case AGGR_S_OBYTES: 3238e7801d59Ssowmini if (is_port) { 32398002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%llu", 32402d40c3b2SPrakash Jalan diff_stats->obytes); 3241e7801d59Ssowmini } else { 32428002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%llu", 3243e7801d59Ssowmini l->laggr_pktsumtot->obytes); 3244e7801d59Ssowmini } 3245e7801d59Ssowmini break; 3246e7801d59Ssowmini 3247e7801d59Ssowmini case AGGR_S_IPKTDIST: 3248e7801d59Ssowmini if (is_port) { 32498002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%-6.1f", 32502d40c3b2SPrakash Jalan (double)diff_stats->ipackets/ 3251e7801d59Ssowmini (double)l->laggr_pktsumtot->ipackets * 100); 3252e7801d59Ssowmini } 3253e7801d59Ssowmini break; 3254e7801d59Ssowmini case AGGR_S_OPKTDIST: 3255e7801d59Ssowmini if (is_port) { 32568002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%-6.1f", 32572d40c3b2SPrakash Jalan (double)diff_stats->opackets/ 3258e7801d59Ssowmini (double)l->laggr_pktsumtot->opackets * 100); 3259e7801d59Ssowmini } 3260e7801d59Ssowmini break; 3261e7801d59Ssowmini } 32628002d411SSowmini Varadhan return (B_TRUE); 3263e7801d59Ssowmini 3264e7801d59Ssowmini err: 3265e7801d59Ssowmini *stat = status; 32668002d411SSowmini Varadhan return (B_TRUE); 3267e7801d59Ssowmini } 3268e7801d59Ssowmini 3269d62bc4baSyz147064 static dladm_status_t 3270d62bc4baSyz147064 print_aggr_stats(show_grp_state_t *state, const char *link, 3271e7801d59Ssowmini dladm_aggr_grp_attr_t *ginfop) 3272d62bc4baSyz147064 { 3273d62bc4baSyz147064 dladm_phys_attr_t dpa; 3274d62bc4baSyz147064 dladm_aggr_port_attr_t *portp; 32752d40c3b2SPrakash Jalan pktsum_t pktsumtot, *port_stat; 3276d62bc4baSyz147064 dladm_status_t status; 3277d62bc4baSyz147064 int i; 3278e7801d59Ssowmini laggr_args_t largs; 32797c478bd9Sstevel@tonic-gate 32807c478bd9Sstevel@tonic-gate /* sum the ports statistics */ 32817c478bd9Sstevel@tonic-gate bzero(&pktsumtot, sizeof (pktsumtot)); 3282d62bc4baSyz147064 32832d40c3b2SPrakash Jalan /* Allocate memory to keep stats of each port */ 32842d40c3b2SPrakash Jalan port_stat = malloc(ginfop->lg_nports * sizeof (pktsum_t)); 32852d40c3b2SPrakash Jalan if (port_stat == NULL) { 32862d40c3b2SPrakash Jalan /* Bail out; no memory */ 32872d40c3b2SPrakash Jalan return (DLADM_STATUS_NOMEM); 32882d40c3b2SPrakash Jalan } 32892d40c3b2SPrakash Jalan 32902d40c3b2SPrakash Jalan 3291d62bc4baSyz147064 for (i = 0; i < ginfop->lg_nports; i++) { 3292d62bc4baSyz147064 3293d62bc4baSyz147064 portp = &(ginfop->lg_ports[i]); 32944ac67f02SAnurag S. Maskey if ((status = dladm_phys_info(handle, portp->lp_linkid, &dpa, 3295d62bc4baSyz147064 DLADM_OPT_ACTIVE)) != DLADM_STATUS_OK) { 3296d62bc4baSyz147064 goto done; 32977c478bd9Sstevel@tonic-gate } 32987c478bd9Sstevel@tonic-gate 32992d40c3b2SPrakash Jalan get_mac_stats(dpa.dp_dev, &port_stat[i]); 33002d40c3b2SPrakash Jalan 33012d40c3b2SPrakash Jalan /* 33022d40c3b2SPrakash Jalan * Let's re-use gs_prevstats[] to store the difference of the 33032d40c3b2SPrakash Jalan * counters since last use. We will store the new stats from 33042d40c3b2SPrakash Jalan * port_stat[] once we have the stats displayed. 33052d40c3b2SPrakash Jalan */ 33062d40c3b2SPrakash Jalan 33072d40c3b2SPrakash Jalan dladm_stats_diff(&state->gs_prevstats[i], &port_stat[i], 33082d40c3b2SPrakash Jalan &state->gs_prevstats[i]); 33092d40c3b2SPrakash Jalan dladm_stats_total(&pktsumtot, &pktsumtot, 3310da14cebeSEric Cheng &state->gs_prevstats[i]); 33117c478bd9Sstevel@tonic-gate } 33127c478bd9Sstevel@tonic-gate 3313e7801d59Ssowmini largs.laggr_lport = -1; 3314e7801d59Ssowmini largs.laggr_link = link; 3315e7801d59Ssowmini largs.laggr_ginfop = ginfop; 3316e7801d59Ssowmini largs.laggr_status = &status; 3317e7801d59Ssowmini largs.laggr_pktsumtot = &pktsumtot; 3318e7801d59Ssowmini 33198002d411SSowmini Varadhan ofmt_print(state->gs_ofmt, &largs); 3320e7801d59Ssowmini 3321e7801d59Ssowmini if (status != DLADM_STATUS_OK) 3322e7801d59Ssowmini goto done; 3323d62bc4baSyz147064 3324d62bc4baSyz147064 for (i = 0; i < ginfop->lg_nports; i++) { 3325e7801d59Ssowmini largs.laggr_lport = i; 33262d40c3b2SPrakash Jalan largs.laggr_diffstats = &state->gs_prevstats[i]; 33278002d411SSowmini Varadhan ofmt_print(state->gs_ofmt, &largs); 3328e7801d59Ssowmini if (status != DLADM_STATUS_OK) 3329d62bc4baSyz147064 goto done; 3330d62bc4baSyz147064 } 3331d62bc4baSyz147064 3332d62bc4baSyz147064 status = DLADM_STATUS_OK; 33332d40c3b2SPrakash Jalan for (i = 0; i < ginfop->lg_nports; i++) 33342d40c3b2SPrakash Jalan state->gs_prevstats[i] = port_stat[i]; 33352d40c3b2SPrakash Jalan 3336d62bc4baSyz147064 done: 33372d40c3b2SPrakash Jalan free(port_stat); 3338d62bc4baSyz147064 return (status); 3339d62bc4baSyz147064 } 3340d62bc4baSyz147064 3341d62bc4baSyz147064 static dladm_status_t 3342e7801d59Ssowmini print_aggr(show_grp_state_t *state, datalink_id_t linkid) 3343d62bc4baSyz147064 { 3344d62bc4baSyz147064 char link[MAXLINKNAMELEN]; 3345d62bc4baSyz147064 dladm_aggr_grp_attr_t ginfo; 3346d62bc4baSyz147064 uint32_t flags; 3347d62bc4baSyz147064 dladm_status_t status; 3348d62bc4baSyz147064 33495f5c9f54SAnurag S. Maskey bzero(&ginfo, sizeof (dladm_aggr_grp_attr_t)); 33504ac67f02SAnurag S. Maskey if ((status = dladm_datalink_id2info(handle, linkid, &flags, NULL, 33514ac67f02SAnurag S. Maskey NULL, link, MAXLINKNAMELEN)) != DLADM_STATUS_OK) { 3352d62bc4baSyz147064 return (status); 3353d62bc4baSyz147064 } 3354d62bc4baSyz147064 3355d62bc4baSyz147064 if (!(state->gs_flags & flags)) 3356d62bc4baSyz147064 return (DLADM_STATUS_NOTFOUND); 3357d62bc4baSyz147064 33584ac67f02SAnurag S. Maskey status = dladm_aggr_info(handle, linkid, &ginfo, state->gs_flags); 3359d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 3360d62bc4baSyz147064 return (status); 3361d62bc4baSyz147064 3362d62bc4baSyz147064 if (state->gs_lacp) 3363e7801d59Ssowmini status = print_aggr_lacp(state, link, &ginfo); 3364d62bc4baSyz147064 else if (state->gs_extended) 3365e7801d59Ssowmini status = print_aggr_extended(state, link, &ginfo); 3366d62bc4baSyz147064 else if (state->gs_stats) 3367e7801d59Ssowmini status = print_aggr_stats(state, link, &ginfo); 33684ac67f02SAnurag S. Maskey else 3369e7801d59Ssowmini status = print_aggr_info(state, link, &ginfo); 3370d62bc4baSyz147064 3371d62bc4baSyz147064 done: 3372d62bc4baSyz147064 free(ginfo.lg_ports); 3373d62bc4baSyz147064 return (status); 3374d62bc4baSyz147064 } 3375d62bc4baSyz147064 33764ac67f02SAnurag S. Maskey /* ARGSUSED */ 3377d62bc4baSyz147064 static int 33784ac67f02SAnurag S. Maskey show_aggr(dladm_handle_t dh, datalink_id_t linkid, void *arg) 3379d62bc4baSyz147064 { 3380d62bc4baSyz147064 show_grp_state_t *state = arg; 3381d62bc4baSyz147064 33828002d411SSowmini Varadhan state->gs_status = print_aggr(state, linkid); 3383d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 33847c478bd9Sstevel@tonic-gate } 33857c478bd9Sstevel@tonic-gate 33867c478bd9Sstevel@tonic-gate static void 33878d5c46e6Sam223141 do_show_link(int argc, char *argv[], const char *use) 33887c478bd9Sstevel@tonic-gate { 33897c478bd9Sstevel@tonic-gate int option; 33907c478bd9Sstevel@tonic-gate boolean_t s_arg = B_FALSE; 3391da14cebeSEric Cheng boolean_t S_arg = B_FALSE; 33927c478bd9Sstevel@tonic-gate boolean_t i_arg = B_FALSE; 3393d62bc4baSyz147064 uint32_t flags = DLADM_OPT_ACTIVE; 3394d62bc4baSyz147064 boolean_t p_arg = B_FALSE; 3395d62bc4baSyz147064 datalink_id_t linkid = DATALINK_ALL_LINKID; 3396da14cebeSEric Cheng char linkname[MAXLINKNAMELEN]; 339763a6526dSMichael Lim uint32_t interval = 0; 3398d62bc4baSyz147064 show_state_t state; 3399d62bc4baSyz147064 dladm_status_t status; 3400e7801d59Ssowmini boolean_t o_arg = B_FALSE; 3401e7801d59Ssowmini char *fields_str = NULL; 34024eaa4710SRishi Srivatsavai char *all_active_fields = "link,class,mtu,state,bridge,over"; 34034eaa4710SRishi Srivatsavai char *all_inactive_fields = "link,class,bridge,over"; 34046be03d0bSVasumathi Sundaram - Sun Microsystems char *allstat_fields = 34056be03d0bSVasumathi Sundaram - Sun Microsystems "link,ipackets,rbytes,ierrors,opackets,obytes,oerrors"; 34068002d411SSowmini Varadhan ofmt_handle_t ofmt; 34078002d411SSowmini Varadhan ofmt_status_t oferr; 34088002d411SSowmini Varadhan uint_t ofmtflags = 0; 3409e7801d59Ssowmini 3410e7801d59Ssowmini bzero(&state, sizeof (state)); 34117c478bd9Sstevel@tonic-gate 34127c478bd9Sstevel@tonic-gate opterr = 0; 3413da14cebeSEric Cheng while ((option = getopt_long(argc, argv, ":pPsSi:o:", 3414d62bc4baSyz147064 show_lopts, NULL)) != -1) { 34157c478bd9Sstevel@tonic-gate switch (option) { 34167c478bd9Sstevel@tonic-gate case 'p': 3417d62bc4baSyz147064 if (p_arg) 3418d62bc4baSyz147064 die_optdup(option); 3419d62bc4baSyz147064 3420d62bc4baSyz147064 p_arg = B_TRUE; 34217c478bd9Sstevel@tonic-gate break; 34227c478bd9Sstevel@tonic-gate case 's': 342333343a97Smeem if (s_arg) 342433343a97Smeem die_optdup(option); 34257c478bd9Sstevel@tonic-gate 34267c478bd9Sstevel@tonic-gate s_arg = B_TRUE; 34277c478bd9Sstevel@tonic-gate break; 3428d62bc4baSyz147064 case 'P': 3429d62bc4baSyz147064 if (flags != DLADM_OPT_ACTIVE) 3430d62bc4baSyz147064 die_optdup(option); 3431d62bc4baSyz147064 3432d62bc4baSyz147064 flags = DLADM_OPT_PERSIST; 3433d62bc4baSyz147064 break; 3434da14cebeSEric Cheng case 'S': 3435da14cebeSEric Cheng if (S_arg) 3436da14cebeSEric Cheng die_optdup(option); 3437da14cebeSEric Cheng 3438da14cebeSEric Cheng S_arg = B_TRUE; 3439da14cebeSEric Cheng break; 3440e7801d59Ssowmini case 'o': 3441e7801d59Ssowmini o_arg = B_TRUE; 3442e7801d59Ssowmini fields_str = optarg; 3443e7801d59Ssowmini break; 34447c478bd9Sstevel@tonic-gate case 'i': 344533343a97Smeem if (i_arg) 344633343a97Smeem die_optdup(option); 34477c478bd9Sstevel@tonic-gate 34487c478bd9Sstevel@tonic-gate i_arg = B_TRUE; 344963a6526dSMichael Lim if (!dladm_str2interval(optarg, &interval)) 345033343a97Smeem die("invalid interval value '%s'", optarg); 34517c478bd9Sstevel@tonic-gate break; 34527c478bd9Sstevel@tonic-gate default: 34538d5c46e6Sam223141 die_opterr(optopt, option, use); 345433343a97Smeem break; 34557c478bd9Sstevel@tonic-gate } 34567c478bd9Sstevel@tonic-gate } 34577c478bd9Sstevel@tonic-gate 3458da14cebeSEric Cheng if (i_arg && !(s_arg || S_arg)) 3459da14cebeSEric Cheng die("the option -i can be used only with -s or -S"); 3460da14cebeSEric Cheng 3461da14cebeSEric Cheng if (s_arg && S_arg) 3462da14cebeSEric Cheng die("the -s option cannot be used with -S"); 34637c478bd9Sstevel@tonic-gate 34646be03d0bSVasumathi Sundaram - Sun Microsystems if (s_arg && flags != DLADM_OPT_ACTIVE) 34656be03d0bSVasumathi Sundaram - Sun Microsystems die("the option -P cannot be used with -s"); 3466d62bc4baSyz147064 3467da14cebeSEric Cheng if (S_arg && (p_arg || flags != DLADM_OPT_ACTIVE)) 3468da14cebeSEric Cheng die("the option -%c cannot be used with -S", p_arg ? 'p' : 'P'); 3469da14cebeSEric Cheng 34707c478bd9Sstevel@tonic-gate /* get link name (optional last argument) */ 3471d62bc4baSyz147064 if (optind == (argc-1)) { 3472d62bc4baSyz147064 uint32_t f; 3473d62bc4baSyz147064 34742b24ab6bSSebastien Roy if (strlcpy(linkname, argv[optind], MAXLINKNAMELEN) >= 34752b24ab6bSSebastien Roy MAXLINKNAMELEN) 34762b24ab6bSSebastien Roy die("link name too long"); 34774ac67f02SAnurag S. Maskey if ((status = dladm_name2info(handle, linkname, &linkid, &f, 3478d62bc4baSyz147064 NULL, NULL)) != DLADM_STATUS_OK) { 3479da14cebeSEric Cheng die_dlerr(status, "link %s is not valid", linkname); 3480d62bc4baSyz147064 } 3481d62bc4baSyz147064 3482d62bc4baSyz147064 if (!(f & flags)) { 3483d62bc4baSyz147064 die_dlerr(DLADM_STATUS_BADARG, "link %s is %s", 3484d62bc4baSyz147064 argv[optind], flags == DLADM_OPT_PERSIST ? 3485d62bc4baSyz147064 "a temporary link" : "temporarily removed"); 3486d62bc4baSyz147064 } 3487d62bc4baSyz147064 } else if (optind != argc) { 34887c478bd9Sstevel@tonic-gate usage(); 3489d62bc4baSyz147064 } 34907c478bd9Sstevel@tonic-gate 34910d365605Sschuster if (p_arg && !o_arg) 34920d365605Sschuster die("-p requires -o"); 34930d365605Sschuster 3494da14cebeSEric Cheng if (S_arg) { 34954ac67f02SAnurag S. Maskey dladm_continuous(handle, linkid, NULL, interval, LINK_REPORT); 3496da14cebeSEric Cheng return; 3497da14cebeSEric Cheng } 3498da14cebeSEric Cheng 34990d365605Sschuster if (p_arg && strcasecmp(fields_str, "all") == 0) 35000d365605Sschuster die("\"-o all\" is invalid with -p"); 35010d365605Sschuster 3502e7801d59Ssowmini if (!o_arg || (o_arg && strcasecmp(fields_str, "all") == 0)) { 35036be03d0bSVasumathi Sundaram - Sun Microsystems if (s_arg) 35046be03d0bSVasumathi Sundaram - Sun Microsystems fields_str = allstat_fields; 35056be03d0bSVasumathi Sundaram - Sun Microsystems else if (flags & DLADM_OPT_ACTIVE) 3506e7801d59Ssowmini fields_str = all_active_fields; 3507e7801d59Ssowmini else 3508e7801d59Ssowmini fields_str = all_inactive_fields; 3509e7801d59Ssowmini } 3510e7801d59Ssowmini 35118002d411SSowmini Varadhan state.ls_parsable = p_arg; 35126be03d0bSVasumathi Sundaram - Sun Microsystems state.ls_flags = flags; 35136be03d0bSVasumathi Sundaram - Sun Microsystems state.ls_donefirst = B_FALSE; 35146be03d0bSVasumathi Sundaram - Sun Microsystems 35156be03d0bSVasumathi Sundaram - Sun Microsystems if (s_arg) { 35166be03d0bSVasumathi Sundaram - Sun Microsystems link_stats(linkid, interval, fields_str, &state); 35176be03d0bSVasumathi Sundaram - Sun Microsystems return; 35186be03d0bSVasumathi Sundaram - Sun Microsystems } 35198002d411SSowmini Varadhan if (state.ls_parsable) 35208002d411SSowmini Varadhan ofmtflags |= OFMT_PARSABLE; 35218002d411SSowmini Varadhan oferr = ofmt_open(fields_str, link_fields, ofmtflags, 0, &ofmt); 35228002d411SSowmini Varadhan dladm_ofmt_check(oferr, state.ls_parsable, ofmt); 35238002d411SSowmini Varadhan state.ls_ofmt = ofmt; 3524e7801d59Ssowmini 3525d62bc4baSyz147064 if (linkid == DATALINK_ALL_LINKID) { 35264ac67f02SAnurag S. Maskey (void) dladm_walk_datalink_id(show_link, handle, &state, 3527d62bc4baSyz147064 DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE, flags); 3528210db224Sericheng } else { 35294ac67f02SAnurag S. Maskey (void) show_link(handle, linkid, &state); 3530d62bc4baSyz147064 if (state.ls_status != DLADM_STATUS_OK) { 3531d62bc4baSyz147064 die_dlerr(state.ls_status, "failed to show link %s", 3532d62bc4baSyz147064 argv[optind]); 3533d62bc4baSyz147064 } 35347c478bd9Sstevel@tonic-gate } 35358002d411SSowmini Varadhan ofmt_close(ofmt); 3536210db224Sericheng } 35377c478bd9Sstevel@tonic-gate 35387c478bd9Sstevel@tonic-gate static void 35398d5c46e6Sam223141 do_show_aggr(int argc, char *argv[], const char *use) 35407c478bd9Sstevel@tonic-gate { 35417c478bd9Sstevel@tonic-gate boolean_t L_arg = B_FALSE; 35427c478bd9Sstevel@tonic-gate boolean_t s_arg = B_FALSE; 35437c478bd9Sstevel@tonic-gate boolean_t i_arg = B_FALSE; 3544d62bc4baSyz147064 boolean_t p_arg = B_FALSE; 3545d62bc4baSyz147064 boolean_t x_arg = B_FALSE; 35467c478bd9Sstevel@tonic-gate show_grp_state_t state; 3547d62bc4baSyz147064 uint32_t flags = DLADM_OPT_ACTIVE; 3548d62bc4baSyz147064 datalink_id_t linkid = DATALINK_ALL_LINKID; 3549d62bc4baSyz147064 int option; 355063a6526dSMichael Lim uint32_t interval = 0; 3551d62bc4baSyz147064 int key; 3552d62bc4baSyz147064 dladm_status_t status; 3553e7801d59Ssowmini boolean_t o_arg = B_FALSE; 3554e7801d59Ssowmini char *fields_str = NULL; 3555e7801d59Ssowmini char *all_fields = 3556e7801d59Ssowmini "link,policy,addrpolicy,lacpactivity,lacptimer,flags"; 3557e7801d59Ssowmini char *all_lacp_fields = 3558e7801d59Ssowmini "link,port,aggregatable,sync,coll,dist,defaulted,expired"; 3559e7801d59Ssowmini char *all_stats_fields = 3560e7801d59Ssowmini "link,port,ipackets,rbytes,opackets,obytes,ipktdist,opktdist"; 3561e7801d59Ssowmini char *all_extended_fields = 3562e7801d59Ssowmini "link,port,speed,duplex,state,address,portstate"; 35632b24ab6bSSebastien Roy const ofmt_field_t *pf; 35648002d411SSowmini Varadhan ofmt_handle_t ofmt; 35658002d411SSowmini Varadhan ofmt_status_t oferr; 35668002d411SSowmini Varadhan uint_t ofmtflags = 0; 3567e7801d59Ssowmini 35687c478bd9Sstevel@tonic-gate opterr = 0; 3569e7801d59Ssowmini while ((option = getopt_long(argc, argv, ":LpPxsi:o:", 3570d62bc4baSyz147064 show_lopts, NULL)) != -1) { 35717c478bd9Sstevel@tonic-gate switch (option) { 35727c478bd9Sstevel@tonic-gate case 'L': 357333343a97Smeem if (L_arg) 357433343a97Smeem die_optdup(option); 35757c478bd9Sstevel@tonic-gate 35767c478bd9Sstevel@tonic-gate L_arg = B_TRUE; 35777c478bd9Sstevel@tonic-gate break; 35787c478bd9Sstevel@tonic-gate case 'p': 3579d62bc4baSyz147064 if (p_arg) 3580d62bc4baSyz147064 die_optdup(option); 3581d62bc4baSyz147064 3582d62bc4baSyz147064 p_arg = B_TRUE; 3583d62bc4baSyz147064 break; 3584d62bc4baSyz147064 case 'x': 3585d62bc4baSyz147064 if (x_arg) 3586d62bc4baSyz147064 die_optdup(option); 3587d62bc4baSyz147064 3588d62bc4baSyz147064 x_arg = B_TRUE; 3589d62bc4baSyz147064 break; 3590d62bc4baSyz147064 case 'P': 3591d62bc4baSyz147064 if (flags != DLADM_OPT_ACTIVE) 3592d62bc4baSyz147064 die_optdup(option); 3593d62bc4baSyz147064 3594d62bc4baSyz147064 flags = DLADM_OPT_PERSIST; 35957c478bd9Sstevel@tonic-gate break; 35967c478bd9Sstevel@tonic-gate case 's': 359733343a97Smeem if (s_arg) 359833343a97Smeem die_optdup(option); 35997c478bd9Sstevel@tonic-gate 36007c478bd9Sstevel@tonic-gate s_arg = B_TRUE; 36017c478bd9Sstevel@tonic-gate break; 3602e7801d59Ssowmini case 'o': 3603e7801d59Ssowmini o_arg = B_TRUE; 3604e7801d59Ssowmini fields_str = optarg; 3605e7801d59Ssowmini break; 36067c478bd9Sstevel@tonic-gate case 'i': 360733343a97Smeem if (i_arg) 360833343a97Smeem die_optdup(option); 36097c478bd9Sstevel@tonic-gate 36107c478bd9Sstevel@tonic-gate i_arg = B_TRUE; 361163a6526dSMichael Lim if (!dladm_str2interval(optarg, &interval)) 361233343a97Smeem die("invalid interval value '%s'", optarg); 36137c478bd9Sstevel@tonic-gate break; 36147c478bd9Sstevel@tonic-gate default: 36158d5c46e6Sam223141 die_opterr(optopt, option, use); 361633343a97Smeem break; 36177c478bd9Sstevel@tonic-gate } 36187c478bd9Sstevel@tonic-gate } 36197c478bd9Sstevel@tonic-gate 36200d365605Sschuster if (p_arg && !o_arg) 36210d365605Sschuster die("-p requires -o"); 36220d365605Sschuster 36230d365605Sschuster if (p_arg && strcasecmp(fields_str, "all") == 0) 36240d365605Sschuster die("\"-o all\" is invalid with -p"); 36250d365605Sschuster 362633343a97Smeem if (i_arg && !s_arg) 362733343a97Smeem die("the option -i can be used only with -s"); 36287c478bd9Sstevel@tonic-gate 3629d62bc4baSyz147064 if (s_arg && (L_arg || p_arg || x_arg || flags != DLADM_OPT_ACTIVE)) { 3630d62bc4baSyz147064 die("the option -%c cannot be used with -s", 3631d62bc4baSyz147064 L_arg ? 'L' : (p_arg ? 'p' : (x_arg ? 'x' : 'P'))); 3632d62bc4baSyz147064 } 3633d62bc4baSyz147064 3634d62bc4baSyz147064 if (L_arg && flags != DLADM_OPT_ACTIVE) 3635d62bc4baSyz147064 die("the option -P cannot be used with -L"); 3636d62bc4baSyz147064 3637d62bc4baSyz147064 if (x_arg && (L_arg || flags != DLADM_OPT_ACTIVE)) 3638d62bc4baSyz147064 die("the option -%c cannot be used with -x", L_arg ? 'L' : 'P'); 3639d62bc4baSyz147064 3640d62bc4baSyz147064 /* get aggregation key or aggrname (optional last argument) */ 36417c478bd9Sstevel@tonic-gate if (optind == (argc-1)) { 3642d62bc4baSyz147064 if (!str2int(argv[optind], &key)) { 36434ac67f02SAnurag S. Maskey status = dladm_name2info(handle, argv[optind], 36444ac67f02SAnurag S. Maskey &linkid, NULL, NULL, NULL); 3645d62bc4baSyz147064 } else { 36464ac67f02SAnurag S. Maskey status = dladm_key2linkid(handle, (uint16_t)key, 3647d62bc4baSyz147064 &linkid, DLADM_OPT_ACTIVE); 3648d62bc4baSyz147064 } 3649d62bc4baSyz147064 3650d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 3651d62bc4baSyz147064 die("non-existent aggregation '%s'", argv[optind]); 3652d62bc4baSyz147064 36537c478bd9Sstevel@tonic-gate } else if (optind != argc) { 36547c478bd9Sstevel@tonic-gate usage(); 36557c478bd9Sstevel@tonic-gate } 36567c478bd9Sstevel@tonic-gate 3657d62bc4baSyz147064 bzero(&state, sizeof (state)); 3658d62bc4baSyz147064 state.gs_lacp = L_arg; 3659d62bc4baSyz147064 state.gs_stats = s_arg; 3660d62bc4baSyz147064 state.gs_flags = flags; 36618002d411SSowmini Varadhan state.gs_parsable = p_arg; 3662d62bc4baSyz147064 state.gs_extended = x_arg; 3663d62bc4baSyz147064 3664e7801d59Ssowmini if (!o_arg || (o_arg && strcasecmp(fields_str, "all") == 0)) { 3665e7801d59Ssowmini if (state.gs_lacp) 3666e7801d59Ssowmini fields_str = all_lacp_fields; 3667e7801d59Ssowmini else if (state.gs_stats) 3668e7801d59Ssowmini fields_str = all_stats_fields; 3669e7801d59Ssowmini else if (state.gs_extended) 3670e7801d59Ssowmini fields_str = all_extended_fields; 3671e7801d59Ssowmini else 3672e7801d59Ssowmini fields_str = all_fields; 3673e7801d59Ssowmini } 3674e7801d59Ssowmini 3675e7801d59Ssowmini if (state.gs_lacp) { 3676e7801d59Ssowmini pf = aggr_l_fields; 3677e7801d59Ssowmini } else if (state.gs_stats) { 3678e7801d59Ssowmini pf = aggr_s_fields; 3679e7801d59Ssowmini } else if (state.gs_extended) { 3680e7801d59Ssowmini pf = aggr_x_fields; 3681e7801d59Ssowmini } else { 3682e7801d59Ssowmini pf = laggr_fields; 3683e7801d59Ssowmini } 3684e7801d59Ssowmini 36858002d411SSowmini Varadhan if (state.gs_parsable) 36868002d411SSowmini Varadhan ofmtflags |= OFMT_PARSABLE; 36878002d411SSowmini Varadhan oferr = ofmt_open(fields_str, pf, ofmtflags, 0, &ofmt); 36888002d411SSowmini Varadhan dladm_ofmt_check(oferr, state.gs_parsable, ofmt); 36898002d411SSowmini Varadhan state.gs_ofmt = ofmt; 3690e7801d59Ssowmini 36917c478bd9Sstevel@tonic-gate if (s_arg) { 3692d62bc4baSyz147064 aggr_stats(linkid, &state, interval); 36938002d411SSowmini Varadhan ofmt_close(ofmt); 36947c478bd9Sstevel@tonic-gate return; 36957c478bd9Sstevel@tonic-gate } 36967c478bd9Sstevel@tonic-gate 3697d62bc4baSyz147064 if (linkid == DATALINK_ALL_LINKID) { 36984ac67f02SAnurag S. Maskey (void) dladm_walk_datalink_id(show_aggr, handle, &state, 3699d62bc4baSyz147064 DATALINK_CLASS_AGGR, DATALINK_ANY_MEDIATYPE, flags); 3700d62bc4baSyz147064 } else { 37014ac67f02SAnurag S. Maskey (void) show_aggr(handle, linkid, &state); 3702d62bc4baSyz147064 if (state.gs_status != DLADM_STATUS_OK) { 3703d62bc4baSyz147064 die_dlerr(state.gs_status, "failed to show aggr %s", 3704d62bc4baSyz147064 argv[optind]); 3705d62bc4baSyz147064 } 3706d62bc4baSyz147064 } 37078002d411SSowmini Varadhan ofmt_close(ofmt); 37087c478bd9Sstevel@tonic-gate } 37097c478bd9Sstevel@tonic-gate 3710da14cebeSEric Cheng static dladm_status_t 3711da14cebeSEric Cheng print_phys_default(show_state_t *state, datalink_id_t linkid, 3712da14cebeSEric Cheng const char *link, uint32_t flags, uint32_t media) 37137c478bd9Sstevel@tonic-gate { 3714da14cebeSEric Cheng dladm_phys_attr_t dpa; 3715da14cebeSEric Cheng dladm_status_t status; 3716da14cebeSEric Cheng link_fields_buf_t pattr; 3717e7801d59Ssowmini 37184ac67f02SAnurag S. Maskey status = dladm_phys_info(handle, linkid, &dpa, state->ls_flags); 3719da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 3720da14cebeSEric Cheng goto done; 37217c478bd9Sstevel@tonic-gate 3722da14cebeSEric Cheng (void) snprintf(pattr.link_phys_device, 3723da14cebeSEric Cheng sizeof (pattr.link_phys_device), "%s", dpa.dp_dev); 3724da14cebeSEric Cheng (void) dladm_media2str(media, pattr.link_phys_media); 3725da14cebeSEric Cheng if (state->ls_flags == DLADM_OPT_ACTIVE) { 3726da14cebeSEric Cheng boolean_t islink; 3727d62bc4baSyz147064 3728da14cebeSEric Cheng if (!dpa.dp_novanity) { 3729da14cebeSEric Cheng (void) strlcpy(pattr.link_name, link, 3730da14cebeSEric Cheng sizeof (pattr.link_name)); 3731da14cebeSEric Cheng islink = B_TRUE; 3732d62bc4baSyz147064 } else { 3733da14cebeSEric Cheng /* 3734da14cebeSEric Cheng * This is a physical link that does not have 3735da14cebeSEric Cheng * vanity naming support. 3736da14cebeSEric Cheng */ 3737da14cebeSEric Cheng (void) strlcpy(pattr.link_name, dpa.dp_dev, 3738da14cebeSEric Cheng sizeof (pattr.link_name)); 3739da14cebeSEric Cheng islink = B_FALSE; 37407c478bd9Sstevel@tonic-gate } 37417c478bd9Sstevel@tonic-gate 3742da14cebeSEric Cheng (void) get_linkstate(pattr.link_name, islink, 3743da14cebeSEric Cheng pattr.link_phys_state); 3744da14cebeSEric Cheng (void) snprintf(pattr.link_phys_speed, 3745da14cebeSEric Cheng sizeof (pattr.link_phys_speed), "%u", 3746da14cebeSEric Cheng (uint_t)((get_ifspeed(pattr.link_name, 3747da14cebeSEric Cheng islink)) / 1000000ull)); 3748da14cebeSEric Cheng (void) get_linkduplex(pattr.link_name, islink, 3749da14cebeSEric Cheng pattr.link_phys_duplex); 3750da14cebeSEric Cheng } else { 3751da14cebeSEric Cheng (void) snprintf(pattr.link_name, sizeof (pattr.link_name), 3752da14cebeSEric Cheng "%s", link); 3753da14cebeSEric Cheng (void) snprintf(pattr.link_flags, sizeof (pattr.link_flags), 3754da14cebeSEric Cheng "%c----", flags & DLADM_OPT_ACTIVE ? '-' : 'r'); 3755da14cebeSEric Cheng } 3756da14cebeSEric Cheng 37578002d411SSowmini Varadhan ofmt_print(state->ls_ofmt, &pattr); 3758da14cebeSEric Cheng 3759da14cebeSEric Cheng done: 3760da14cebeSEric Cheng return (status); 3761da14cebeSEric Cheng } 3762da14cebeSEric Cheng 3763da14cebeSEric Cheng typedef struct { 3764da14cebeSEric Cheng show_state_t *ms_state; 3765da14cebeSEric Cheng char *ms_link; 3766da14cebeSEric Cheng dladm_macaddr_attr_t *ms_mac_attr; 3767da14cebeSEric Cheng } print_phys_mac_state_t; 3768da14cebeSEric Cheng 37698002d411SSowmini Varadhan /* 37708002d411SSowmini Varadhan * callback for ofmt_print() 37718002d411SSowmini Varadhan */ 37728002d411SSowmini Varadhan static boolean_t 37738002d411SSowmini Varadhan print_phys_one_mac_cb(ofmt_arg_t *ofarg, char *buf, uint_t bufsize) 3774da14cebeSEric Cheng { 37758002d411SSowmini Varadhan print_phys_mac_state_t *mac_state = ofarg->ofmt_cbarg; 3776da14cebeSEric Cheng dladm_macaddr_attr_t *attr = mac_state->ms_mac_attr; 3777da14cebeSEric Cheng boolean_t is_primary = (attr->ma_slot == 0); 37788002d411SSowmini Varadhan boolean_t is_parsable = mac_state->ms_state->ls_parsable; 3779da14cebeSEric Cheng 37808002d411SSowmini Varadhan switch (ofarg->ofmt_id) { 3781da14cebeSEric Cheng case PHYS_M_LINK: 37828002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%s", 37838002d411SSowmini Varadhan (is_primary || is_parsable) ? mac_state->ms_link : " "); 3784da14cebeSEric Cheng break; 3785da14cebeSEric Cheng case PHYS_M_SLOT: 3786da14cebeSEric Cheng if (is_primary) 37878002d411SSowmini Varadhan (void) snprintf(buf, bufsize, gettext("primary")); 3788da14cebeSEric Cheng else 37898002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%d", attr->ma_slot); 3790da14cebeSEric Cheng break; 3791da14cebeSEric Cheng case PHYS_M_ADDRESS: 3792da14cebeSEric Cheng (void) dladm_aggr_macaddr2str(attr->ma_addr, buf); 3793da14cebeSEric Cheng break; 3794da14cebeSEric Cheng case PHYS_M_INUSE: 37958002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%s", 3796da14cebeSEric Cheng attr->ma_flags & DLADM_MACADDR_USED ? gettext("yes") : 3797da14cebeSEric Cheng gettext("no")); 3798da14cebeSEric Cheng break; 3799da14cebeSEric Cheng case PHYS_M_CLIENT: 3800da14cebeSEric Cheng /* 3801da14cebeSEric Cheng * CR 6678526: resolve link id to actual link name if 3802da14cebeSEric Cheng * it is valid. 3803da14cebeSEric Cheng */ 38048002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%s", attr->ma_client_name); 3805da14cebeSEric Cheng break; 3806da14cebeSEric Cheng } 3807da14cebeSEric Cheng 38088002d411SSowmini Varadhan return (B_TRUE); 3809da14cebeSEric Cheng } 3810da14cebeSEric Cheng 3811da14cebeSEric Cheng typedef struct { 3812da14cebeSEric Cheng show_state_t *hs_state; 3813da14cebeSEric Cheng char *hs_link; 3814da14cebeSEric Cheng dladm_hwgrp_attr_t *hs_grp_attr; 3815da14cebeSEric Cheng } print_phys_hwgrp_state_t; 3816da14cebeSEric Cheng 38178002d411SSowmini Varadhan static boolean_t 38188002d411SSowmini Varadhan print_phys_one_hwgrp_cb(ofmt_arg_t *ofarg, char *buf, uint_t bufsize) 3819da14cebeSEric Cheng { 38200dc2366fSVenugopal Iyer int i; 38210dc2366fSVenugopal Iyer boolean_t first = B_TRUE; 38220dc2366fSVenugopal Iyer int start = -1; 38230dc2366fSVenugopal Iyer int end = -1; 38240dc2366fSVenugopal Iyer char ringstr[RINGSTRLEN]; 38250dc2366fSVenugopal Iyer char ringsubstr[RINGSTRLEN]; 38260dc2366fSVenugopal Iyer 38278002d411SSowmini Varadhan print_phys_hwgrp_state_t *hg_state = ofarg->ofmt_cbarg; 3828da14cebeSEric Cheng dladm_hwgrp_attr_t *attr = hg_state->hs_grp_attr; 3829da14cebeSEric Cheng 38308002d411SSowmini Varadhan switch (ofarg->ofmt_id) { 3831da14cebeSEric Cheng case PHYS_H_LINK: 38328002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%s", attr->hg_link_name); 3833da14cebeSEric Cheng break; 38340dc2366fSVenugopal Iyer case PHYS_H_RINGTYPE: 38358002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%s", 3836da14cebeSEric Cheng attr->hg_grp_type == DLADM_HWGRP_TYPE_RX ? "RX" : "TX"); 3837da14cebeSEric Cheng break; 3838da14cebeSEric Cheng case PHYS_H_RINGS: 38390dc2366fSVenugopal Iyer ringstr[0] = '\0'; 38400dc2366fSVenugopal Iyer for (i = 0; i < attr->hg_n_rings; i++) { 38410dc2366fSVenugopal Iyer uint_t index = attr->hg_rings[i]; 38420dc2366fSVenugopal Iyer 38430dc2366fSVenugopal Iyer if (start == -1) { 38440dc2366fSVenugopal Iyer start = index; 38450dc2366fSVenugopal Iyer end = index; 38460dc2366fSVenugopal Iyer } else if (index == end + 1) { 38470dc2366fSVenugopal Iyer end = index; 38480dc2366fSVenugopal Iyer } else { 38490dc2366fSVenugopal Iyer if (start == end) { 38500dc2366fSVenugopal Iyer if (first) { 38510dc2366fSVenugopal Iyer (void) snprintf( 38520dc2366fSVenugopal Iyer ringsubstr, 38530dc2366fSVenugopal Iyer RINGSTRLEN, "%d", 38540dc2366fSVenugopal Iyer start); 38550dc2366fSVenugopal Iyer first = B_FALSE; 38560dc2366fSVenugopal Iyer } else { 38570dc2366fSVenugopal Iyer (void) snprintf( 38580dc2366fSVenugopal Iyer ringsubstr, 38590dc2366fSVenugopal Iyer RINGSTRLEN, ",%d", 38600dc2366fSVenugopal Iyer start); 38610dc2366fSVenugopal Iyer } 38620dc2366fSVenugopal Iyer } else { 38630dc2366fSVenugopal Iyer if (first) { 38640dc2366fSVenugopal Iyer (void) snprintf( 38650dc2366fSVenugopal Iyer ringsubstr, 38660dc2366fSVenugopal Iyer RINGSTRLEN, 38670dc2366fSVenugopal Iyer "%d-%d", 38680dc2366fSVenugopal Iyer start, end); 38690dc2366fSVenugopal Iyer first = B_FALSE; 38700dc2366fSVenugopal Iyer } else { 38710dc2366fSVenugopal Iyer (void) snprintf( 38720dc2366fSVenugopal Iyer ringsubstr, 38730dc2366fSVenugopal Iyer RINGSTRLEN, 38740dc2366fSVenugopal Iyer ",%d-%d", 38750dc2366fSVenugopal Iyer start, end); 38760dc2366fSVenugopal Iyer } 38770dc2366fSVenugopal Iyer } 38780dc2366fSVenugopal Iyer (void) strlcat(ringstr, ringsubstr, 38790dc2366fSVenugopal Iyer RINGSTRLEN); 38800dc2366fSVenugopal Iyer start = index; 38810dc2366fSVenugopal Iyer end = index; 38820dc2366fSVenugopal Iyer } 38830dc2366fSVenugopal Iyer } 38840dc2366fSVenugopal Iyer /* The last one */ 38850dc2366fSVenugopal Iyer if (start != -1) { 38860dc2366fSVenugopal Iyer if (first) { 38870dc2366fSVenugopal Iyer if (start == end) { 38880dc2366fSVenugopal Iyer (void) snprintf(buf, bufsize, "%d", 38890dc2366fSVenugopal Iyer start); 38900dc2366fSVenugopal Iyer } else { 38910dc2366fSVenugopal Iyer (void) snprintf(buf, bufsize, "%d-%d", 38920dc2366fSVenugopal Iyer start, end); 38930dc2366fSVenugopal Iyer } 38940dc2366fSVenugopal Iyer } else { 38950dc2366fSVenugopal Iyer if (start == end) { 38960dc2366fSVenugopal Iyer (void) snprintf(ringsubstr, RINGSTRLEN, 38970dc2366fSVenugopal Iyer ",%d", start); 38980dc2366fSVenugopal Iyer } else { 38990dc2366fSVenugopal Iyer (void) snprintf(ringsubstr, RINGSTRLEN, 39000dc2366fSVenugopal Iyer ",%d-%d", start, end); 39010dc2366fSVenugopal Iyer } 39020dc2366fSVenugopal Iyer (void) strlcat(ringstr, ringsubstr, RINGSTRLEN); 39030dc2366fSVenugopal Iyer (void) snprintf(buf, bufsize, "%s", ringstr); 39040dc2366fSVenugopal Iyer } 39050dc2366fSVenugopal Iyer } 3906da14cebeSEric Cheng break; 3907da14cebeSEric Cheng case PHYS_H_CLIENTS: 3908da14cebeSEric Cheng if (attr->hg_client_names[0] == '\0') { 39098002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "--"); 3910da14cebeSEric Cheng } else { 39118002d411SSowmini Varadhan (void) snprintf(buf, bufsize, "%s ", 3912da14cebeSEric Cheng attr->hg_client_names); 3913da14cebeSEric Cheng } 3914da14cebeSEric Cheng break; 3915da14cebeSEric Cheng } 3916da14cebeSEric Cheng 39178002d411SSowmini Varadhan return (B_TRUE); 3918da14cebeSEric Cheng } 3919da14cebeSEric Cheng 39208002d411SSowmini Varadhan /* 39218002d411SSowmini Varadhan * callback for dladm_walk_macaddr, invoked for each MAC address slot 39228002d411SSowmini Varadhan */ 3923da14cebeSEric Cheng static boolean_t 3924da14cebeSEric Cheng print_phys_mac_callback(void *arg, dladm_macaddr_attr_t *attr) 3925da14cebeSEric Cheng { 3926da14cebeSEric Cheng print_phys_mac_state_t *mac_state = arg; 3927da14cebeSEric Cheng show_state_t *state = mac_state->ms_state; 3928da14cebeSEric Cheng 3929da14cebeSEric Cheng mac_state->ms_mac_attr = attr; 39308002d411SSowmini Varadhan ofmt_print(state->ls_ofmt, mac_state); 3931da14cebeSEric Cheng 3932da14cebeSEric Cheng return (B_TRUE); 3933da14cebeSEric Cheng } 3934da14cebeSEric Cheng 39358002d411SSowmini Varadhan /* 39368002d411SSowmini Varadhan * invoked by show-phys -m for each physical data-link 39378002d411SSowmini Varadhan */ 3938da14cebeSEric Cheng static dladm_status_t 3939da14cebeSEric Cheng print_phys_mac(show_state_t *state, datalink_id_t linkid, char *link) 3940da14cebeSEric Cheng { 3941da14cebeSEric Cheng print_phys_mac_state_t mac_state; 3942da14cebeSEric Cheng 3943da14cebeSEric Cheng mac_state.ms_state = state; 3944da14cebeSEric Cheng mac_state.ms_link = link; 3945da14cebeSEric Cheng 39464ac67f02SAnurag S. Maskey return (dladm_walk_macaddr(handle, linkid, &mac_state, 3947da14cebeSEric Cheng print_phys_mac_callback)); 3948da14cebeSEric Cheng } 3949da14cebeSEric Cheng 39508002d411SSowmini Varadhan /* 39518002d411SSowmini Varadhan * callback for dladm_walk_hwgrp, invoked for each MAC hwgrp 39528002d411SSowmini Varadhan */ 3953da14cebeSEric Cheng static boolean_t 3954da14cebeSEric Cheng print_phys_hwgrp_callback(void *arg, dladm_hwgrp_attr_t *attr) 3955da14cebeSEric Cheng { 3956da14cebeSEric Cheng print_phys_hwgrp_state_t *hwgrp_state = arg; 3957da14cebeSEric Cheng show_state_t *state = hwgrp_state->hs_state; 3958da14cebeSEric Cheng 3959da14cebeSEric Cheng hwgrp_state->hs_grp_attr = attr; 39608002d411SSowmini Varadhan ofmt_print(state->ls_ofmt, hwgrp_state); 3961da14cebeSEric Cheng 3962da14cebeSEric Cheng return (B_TRUE); 3963da14cebeSEric Cheng } 3964da14cebeSEric Cheng 3965da14cebeSEric Cheng /* invoked by show-phys -H for each physical data-link */ 3966da14cebeSEric Cheng static dladm_status_t 3967da14cebeSEric Cheng print_phys_hwgrp(show_state_t *state, datalink_id_t linkid, char *link) 3968da14cebeSEric Cheng { 3969da14cebeSEric Cheng print_phys_hwgrp_state_t hwgrp_state; 3970da14cebeSEric Cheng 3971da14cebeSEric Cheng hwgrp_state.hs_state = state; 3972da14cebeSEric Cheng hwgrp_state.hs_link = link; 39734ac67f02SAnurag S. Maskey return (dladm_walk_hwgrp(handle, linkid, &hwgrp_state, 3974da14cebeSEric Cheng print_phys_hwgrp_callback)); 3975da14cebeSEric Cheng } 3976d62bc4baSyz147064 39772b24ab6bSSebastien Roy /* 39782b24ab6bSSebastien Roy * Parse the "local=<laddr>,remote=<raddr>" sub-options for the -a option of 39792b24ab6bSSebastien Roy * *-iptun subcommands. 39802b24ab6bSSebastien Roy */ 39812b24ab6bSSebastien Roy static void 39822b24ab6bSSebastien Roy iptun_process_addrarg(char *addrarg, iptun_params_t *params) 39832b24ab6bSSebastien Roy { 39842b24ab6bSSebastien Roy char *addrval; 39852b24ab6bSSebastien Roy 39862b24ab6bSSebastien Roy while (*addrarg != '\0') { 39872b24ab6bSSebastien Roy switch (getsubopt(&addrarg, iptun_addropts, &addrval)) { 39882b24ab6bSSebastien Roy case IPTUN_LOCAL: 39892b24ab6bSSebastien Roy params->iptun_param_flags |= IPTUN_PARAM_LADDR; 39902b24ab6bSSebastien Roy if (strlcpy(params->iptun_param_laddr, addrval, 39912b24ab6bSSebastien Roy sizeof (params->iptun_param_laddr)) >= 39922b24ab6bSSebastien Roy sizeof (params->iptun_param_laddr)) 39932b24ab6bSSebastien Roy die("tunnel source address is too long"); 39942b24ab6bSSebastien Roy break; 39952b24ab6bSSebastien Roy case IPTUN_REMOTE: 39962b24ab6bSSebastien Roy params->iptun_param_flags |= IPTUN_PARAM_RADDR; 39972b24ab6bSSebastien Roy if (strlcpy(params->iptun_param_raddr, addrval, 39982b24ab6bSSebastien Roy sizeof (params->iptun_param_raddr)) >= 39992b24ab6bSSebastien Roy sizeof (params->iptun_param_raddr)) 40002b24ab6bSSebastien Roy die("tunnel destination address is too long"); 40012b24ab6bSSebastien Roy break; 40022b24ab6bSSebastien Roy default: 40032b24ab6bSSebastien Roy die("invalid address type: %s", addrval); 40042b24ab6bSSebastien Roy break; 40052b24ab6bSSebastien Roy } 40062b24ab6bSSebastien Roy } 40072b24ab6bSSebastien Roy } 40082b24ab6bSSebastien Roy 40092b24ab6bSSebastien Roy /* 40102b24ab6bSSebastien Roy * Convenience routine to process iptun-create/modify/delete subcommand 40112b24ab6bSSebastien Roy * arguments. 40122b24ab6bSSebastien Roy */ 40132b24ab6bSSebastien Roy static void 40142b24ab6bSSebastien Roy iptun_process_args(int argc, char *argv[], const char *opts, 40152b24ab6bSSebastien Roy iptun_params_t *params, uint32_t *flags, char *name, const char *use) 40162b24ab6bSSebastien Roy { 40172b24ab6bSSebastien Roy int option; 40182b24ab6bSSebastien Roy char *altroot = NULL; 40192b24ab6bSSebastien Roy 40202b24ab6bSSebastien Roy if (params != NULL) 40212b24ab6bSSebastien Roy bzero(params, sizeof (*params)); 40222b24ab6bSSebastien Roy *flags = DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST; 40232b24ab6bSSebastien Roy 40242b24ab6bSSebastien Roy opterr = 0; 40252b24ab6bSSebastien Roy while ((option = getopt_long(argc, argv, opts, iptun_lopts, NULL)) != 40262b24ab6bSSebastien Roy -1) { 40272b24ab6bSSebastien Roy switch (option) { 40282b24ab6bSSebastien Roy case 'a': 40292b24ab6bSSebastien Roy iptun_process_addrarg(optarg, params); 40302b24ab6bSSebastien Roy break; 40312b24ab6bSSebastien Roy case 'R': 40322b24ab6bSSebastien Roy altroot = optarg; 40332b24ab6bSSebastien Roy break; 40342b24ab6bSSebastien Roy case 't': 40352b24ab6bSSebastien Roy *flags &= ~DLADM_OPT_PERSIST; 40362b24ab6bSSebastien Roy break; 40372b24ab6bSSebastien Roy case 'T': 40382b24ab6bSSebastien Roy params->iptun_param_type = iptun_gettypebyname(optarg); 40392b24ab6bSSebastien Roy if (params->iptun_param_type == IPTUN_TYPE_UNKNOWN) 40402b24ab6bSSebastien Roy die("unknown tunnel type: %s", optarg); 40412b24ab6bSSebastien Roy params->iptun_param_flags |= IPTUN_PARAM_TYPE; 40422b24ab6bSSebastien Roy break; 40432b24ab6bSSebastien Roy default: 40442b24ab6bSSebastien Roy die_opterr(optopt, option, use); 40452b24ab6bSSebastien Roy break; 40462b24ab6bSSebastien Roy } 40472b24ab6bSSebastien Roy } 40482b24ab6bSSebastien Roy 40492b24ab6bSSebastien Roy /* Get the required tunnel name argument. */ 40502b24ab6bSSebastien Roy if (argc - optind != 1) 40512b24ab6bSSebastien Roy usage(); 40522b24ab6bSSebastien Roy 40532b24ab6bSSebastien Roy if (strlcpy(name, argv[optind], MAXLINKNAMELEN) >= MAXLINKNAMELEN) 40542b24ab6bSSebastien Roy die("tunnel name is too long"); 40552b24ab6bSSebastien Roy 40562b24ab6bSSebastien Roy if (altroot != NULL) 40572b24ab6bSSebastien Roy altroot_cmd(altroot, argc, argv); 40582b24ab6bSSebastien Roy } 40592b24ab6bSSebastien Roy 40602b24ab6bSSebastien Roy static void 40612b24ab6bSSebastien Roy do_create_iptun(int argc, char *argv[], const char *use) 40622b24ab6bSSebastien Roy { 40632b24ab6bSSebastien Roy iptun_params_t params; 40642b24ab6bSSebastien Roy dladm_status_t status; 40652b24ab6bSSebastien Roy uint32_t flags; 40662b24ab6bSSebastien Roy char name[MAXLINKNAMELEN]; 40672b24ab6bSSebastien Roy 40682b24ab6bSSebastien Roy iptun_process_args(argc, argv, ":a:R:tT:", ¶ms, &flags, name, 40692b24ab6bSSebastien Roy use); 40702b24ab6bSSebastien Roy 40712b24ab6bSSebastien Roy status = dladm_iptun_create(handle, name, ¶ms, flags); 40722b24ab6bSSebastien Roy if (status != DLADM_STATUS_OK) 40732b24ab6bSSebastien Roy die_dlerr(status, "could not create tunnel"); 40742b24ab6bSSebastien Roy } 40752b24ab6bSSebastien Roy 40762b24ab6bSSebastien Roy static void 40772b24ab6bSSebastien Roy do_delete_iptun(int argc, char *argv[], const char *use) 40782b24ab6bSSebastien Roy { 40792b24ab6bSSebastien Roy uint32_t flags; 40802b24ab6bSSebastien Roy datalink_id_t linkid; 40812b24ab6bSSebastien Roy dladm_status_t status; 40822b24ab6bSSebastien Roy char name[MAXLINKNAMELEN]; 40832b24ab6bSSebastien Roy 40842b24ab6bSSebastien Roy iptun_process_args(argc, argv, ":R:t", NULL, &flags, name, use); 40852b24ab6bSSebastien Roy 40862b24ab6bSSebastien Roy status = dladm_name2info(handle, name, &linkid, NULL, NULL, NULL); 40872b24ab6bSSebastien Roy if (status != DLADM_STATUS_OK) 40882b24ab6bSSebastien Roy die_dlerr(status, "could not delete tunnel"); 40892b24ab6bSSebastien Roy status = dladm_iptun_delete(handle, linkid, flags); 40902b24ab6bSSebastien Roy if (status != DLADM_STATUS_OK) 40912b24ab6bSSebastien Roy die_dlerr(status, "could not delete tunnel"); 40922b24ab6bSSebastien Roy } 40932b24ab6bSSebastien Roy 40942b24ab6bSSebastien Roy static void 40952b24ab6bSSebastien Roy do_modify_iptun(int argc, char *argv[], const char *use) 40962b24ab6bSSebastien Roy { 40972b24ab6bSSebastien Roy iptun_params_t params; 40982b24ab6bSSebastien Roy uint32_t flags; 40992b24ab6bSSebastien Roy dladm_status_t status; 41002b24ab6bSSebastien Roy char name[MAXLINKNAMELEN]; 41012b24ab6bSSebastien Roy 41022b24ab6bSSebastien Roy iptun_process_args(argc, argv, ":a:R:t", ¶ms, &flags, name, use); 41032b24ab6bSSebastien Roy 41042b24ab6bSSebastien Roy if ((status = dladm_name2info(handle, name, ¶ms.iptun_param_linkid, 41052b24ab6bSSebastien Roy NULL, NULL, NULL)) != DLADM_STATUS_OK) 41062b24ab6bSSebastien Roy die_dlerr(status, "could not modify tunnel"); 41072b24ab6bSSebastien Roy status = dladm_iptun_modify(handle, ¶ms, flags); 41082b24ab6bSSebastien Roy if (status != DLADM_STATUS_OK) 41092b24ab6bSSebastien Roy die_dlerr(status, "could not modify tunnel"); 41102b24ab6bSSebastien Roy } 41112b24ab6bSSebastien Roy 41122b24ab6bSSebastien Roy static void 41132b24ab6bSSebastien Roy do_show_iptun(int argc, char *argv[], const char *use) 41142b24ab6bSSebastien Roy { 41152b24ab6bSSebastien Roy char option; 41162b24ab6bSSebastien Roy datalink_id_t linkid; 41172b24ab6bSSebastien Roy uint32_t flags = DLADM_OPT_ACTIVE; 41182b24ab6bSSebastien Roy char *name = NULL; 41192b24ab6bSSebastien Roy dladm_status_t status; 41202b24ab6bSSebastien Roy const char *fields_str = NULL; 41212b24ab6bSSebastien Roy show_state_t state; 41222b24ab6bSSebastien Roy ofmt_handle_t ofmt; 41232b24ab6bSSebastien Roy ofmt_status_t oferr; 41242b24ab6bSSebastien Roy uint_t ofmtflags = 0; 41252b24ab6bSSebastien Roy 41262b24ab6bSSebastien Roy bzero(&state, sizeof (state)); 41272b24ab6bSSebastien Roy opterr = 0; 41282b24ab6bSSebastien Roy while ((option = getopt_long(argc, argv, ":pPo:", 41292b24ab6bSSebastien Roy iptun_lopts, NULL)) != -1) { 41302b24ab6bSSebastien Roy switch (option) { 41312b24ab6bSSebastien Roy case 'o': 41322b24ab6bSSebastien Roy fields_str = optarg; 41332b24ab6bSSebastien Roy break; 41342b24ab6bSSebastien Roy case 'p': 41352b24ab6bSSebastien Roy state.ls_parsable = B_TRUE; 41362b24ab6bSSebastien Roy ofmtflags = OFMT_PARSABLE; 41372b24ab6bSSebastien Roy break; 41382b24ab6bSSebastien Roy case 'P': 41392b24ab6bSSebastien Roy flags = DLADM_OPT_PERSIST; 41402b24ab6bSSebastien Roy break; 41412b24ab6bSSebastien Roy default: 41422b24ab6bSSebastien Roy die_opterr(optopt, option, use); 41432b24ab6bSSebastien Roy break; 41442b24ab6bSSebastien Roy } 41452b24ab6bSSebastien Roy } 41462b24ab6bSSebastien Roy 41472b24ab6bSSebastien Roy /* 41482b24ab6bSSebastien Roy * Get the optional tunnel name argument. If there is one, it must 41492b24ab6bSSebastien Roy * be the last thing remaining on the command-line. 41502b24ab6bSSebastien Roy */ 41512b24ab6bSSebastien Roy if (argc - optind > 1) 41522b24ab6bSSebastien Roy die(gettext(use)); 41532b24ab6bSSebastien Roy if (argc - optind == 1) 41542b24ab6bSSebastien Roy name = argv[optind]; 41552b24ab6bSSebastien Roy 41562b24ab6bSSebastien Roy oferr = ofmt_open(fields_str, iptun_fields, ofmtflags, 41572b24ab6bSSebastien Roy DLADM_DEFAULT_COL, &ofmt); 41582b24ab6bSSebastien Roy dladm_ofmt_check(oferr, state.ls_parsable, ofmt); 41592b24ab6bSSebastien Roy 41602b24ab6bSSebastien Roy state.ls_ofmt = ofmt; 41612b24ab6bSSebastien Roy state.ls_flags = flags; 41622b24ab6bSSebastien Roy 41632b24ab6bSSebastien Roy if (name == NULL) { 41642b24ab6bSSebastien Roy (void) dladm_walk_datalink_id(print_iptun_walker, handle, 41652b24ab6bSSebastien Roy &state, DATALINK_CLASS_IPTUN, DATALINK_ANY_MEDIATYPE, 41662b24ab6bSSebastien Roy flags); 41672b24ab6bSSebastien Roy status = state.ls_status; 41682b24ab6bSSebastien Roy } else { 41692b24ab6bSSebastien Roy if ((status = dladm_name2info(handle, name, &linkid, NULL, NULL, 41702b24ab6bSSebastien Roy NULL)) == DLADM_STATUS_OK) 41712b24ab6bSSebastien Roy status = print_iptun(handle, linkid, &state); 41722b24ab6bSSebastien Roy } 41732b24ab6bSSebastien Roy 41742b24ab6bSSebastien Roy if (status != DLADM_STATUS_OK) 41752b24ab6bSSebastien Roy die_dlerr(status, "unable to obtain tunnel status"); 41762b24ab6bSSebastien Roy } 41772b24ab6bSSebastien Roy 41782b24ab6bSSebastien Roy /* ARGSUSED */ 41792b24ab6bSSebastien Roy static void 41802b24ab6bSSebastien Roy do_up_iptun(int argc, char *argv[], const char *use) 41812b24ab6bSSebastien Roy { 41822b24ab6bSSebastien Roy datalink_id_t linkid = DATALINK_ALL_LINKID; 41832b24ab6bSSebastien Roy dladm_status_t status = DLADM_STATUS_OK; 41842b24ab6bSSebastien Roy 41852b24ab6bSSebastien Roy /* 41862b24ab6bSSebastien Roy * Get the optional tunnel name argument. If there is one, it must 41872b24ab6bSSebastien Roy * be the last thing remaining on the command-line. 41882b24ab6bSSebastien Roy */ 41892b24ab6bSSebastien Roy if (argc - optind > 1) 41902b24ab6bSSebastien Roy usage(); 41912b24ab6bSSebastien Roy if (argc - optind == 1) { 41922b24ab6bSSebastien Roy status = dladm_name2info(handle, argv[optind], &linkid, NULL, 41932b24ab6bSSebastien Roy NULL, NULL); 41942b24ab6bSSebastien Roy } 41952b24ab6bSSebastien Roy if (status == DLADM_STATUS_OK) 41962b24ab6bSSebastien Roy status = dladm_iptun_up(handle, linkid); 41972b24ab6bSSebastien Roy if (status != DLADM_STATUS_OK) 41982b24ab6bSSebastien Roy die_dlerr(status, "unable to configure IP tunnel links"); 41992b24ab6bSSebastien Roy } 42002b24ab6bSSebastien Roy 42012b24ab6bSSebastien Roy /* ARGSUSED */ 42022b24ab6bSSebastien Roy static void 42032b24ab6bSSebastien Roy do_down_iptun(int argc, char *argv[], const char *use) 42042b24ab6bSSebastien Roy { 42052b24ab6bSSebastien Roy datalink_id_t linkid = DATALINK_ALL_LINKID; 42062b24ab6bSSebastien Roy dladm_status_t status = DLADM_STATUS_OK; 42072b24ab6bSSebastien Roy 42082b24ab6bSSebastien Roy /* 42092b24ab6bSSebastien Roy * Get the optional tunnel name argument. If there is one, it must 42102b24ab6bSSebastien Roy * be the last thing remaining on the command-line. 42112b24ab6bSSebastien Roy */ 42122b24ab6bSSebastien Roy if (argc - optind > 1) 42132b24ab6bSSebastien Roy usage(); 42142b24ab6bSSebastien Roy if (argc - optind == 1) { 42152b24ab6bSSebastien Roy status = dladm_name2info(handle, argv[optind], &linkid, NULL, 42162b24ab6bSSebastien Roy NULL, NULL); 42172b24ab6bSSebastien Roy } 42182b24ab6bSSebastien Roy if (status == DLADM_STATUS_OK) 42192b24ab6bSSebastien Roy status = dladm_iptun_down(handle, linkid); 42202b24ab6bSSebastien Roy if (status != DLADM_STATUS_OK) 42212b24ab6bSSebastien Roy die_dlerr(status, "unable to bring down IP tunnel links"); 42222b24ab6bSSebastien Roy } 42232b24ab6bSSebastien Roy 42242b24ab6bSSebastien Roy static iptun_type_t 42252b24ab6bSSebastien Roy iptun_gettypebyname(char *typestr) 42262b24ab6bSSebastien Roy { 42272b24ab6bSSebastien Roy int i; 42282b24ab6bSSebastien Roy 42292b24ab6bSSebastien Roy for (i = 0; iptun_types[i].type_name != NULL; i++) { 42302b24ab6bSSebastien Roy if (strncmp(iptun_types[i].type_name, typestr, 42312b24ab6bSSebastien Roy strlen(iptun_types[i].type_name)) == 0) { 42322b24ab6bSSebastien Roy return (iptun_types[i].type_value); 42332b24ab6bSSebastien Roy } 42342b24ab6bSSebastien Roy } 42352b24ab6bSSebastien Roy return (IPTUN_TYPE_UNKNOWN); 42362b24ab6bSSebastien Roy } 42372b24ab6bSSebastien Roy 42382b24ab6bSSebastien Roy static const char * 42392b24ab6bSSebastien Roy iptun_gettypebyvalue(iptun_type_t type) 42402b24ab6bSSebastien Roy { 42412b24ab6bSSebastien Roy int i; 42422b24ab6bSSebastien Roy 42432b24ab6bSSebastien Roy for (i = 0; iptun_types[i].type_name != NULL; i++) { 42442b24ab6bSSebastien Roy if (iptun_types[i].type_value == type) 42452b24ab6bSSebastien Roy return (iptun_types[i].type_name); 42462b24ab6bSSebastien Roy } 42472b24ab6bSSebastien Roy return (NULL); 42482b24ab6bSSebastien Roy } 42492b24ab6bSSebastien Roy 42502b24ab6bSSebastien Roy static dladm_status_t 42512b24ab6bSSebastien Roy print_iptun(dladm_handle_t dh, datalink_id_t linkid, show_state_t *state) 42522b24ab6bSSebastien Roy { 42532b24ab6bSSebastien Roy dladm_status_t status; 42542b24ab6bSSebastien Roy iptun_params_t params; 42552b24ab6bSSebastien Roy iptun_fields_buf_t lbuf; 42562b24ab6bSSebastien Roy const char *laddr; 42572b24ab6bSSebastien Roy const char *raddr; 42582b24ab6bSSebastien Roy 42592b24ab6bSSebastien Roy params.iptun_param_linkid = linkid; 42602b24ab6bSSebastien Roy status = dladm_iptun_getparams(dh, ¶ms, state->ls_flags); 42612b24ab6bSSebastien Roy if (status != DLADM_STATUS_OK) 42622b24ab6bSSebastien Roy return (status); 42632b24ab6bSSebastien Roy 42642b24ab6bSSebastien Roy /* LINK */ 42652b24ab6bSSebastien Roy status = dladm_datalink_id2info(dh, linkid, NULL, NULL, NULL, 42662b24ab6bSSebastien Roy lbuf.iptun_name, sizeof (lbuf.iptun_name)); 42672b24ab6bSSebastien Roy if (status != DLADM_STATUS_OK) 42682b24ab6bSSebastien Roy return (status); 42692b24ab6bSSebastien Roy 42702b24ab6bSSebastien Roy /* TYPE */ 42712b24ab6bSSebastien Roy (void) strlcpy(lbuf.iptun_type, 42722b24ab6bSSebastien Roy iptun_gettypebyvalue(params.iptun_param_type), 42732b24ab6bSSebastien Roy sizeof (lbuf.iptun_type)); 42742b24ab6bSSebastien Roy 42752b24ab6bSSebastien Roy /* FLAGS */ 42762b24ab6bSSebastien Roy (void) memset(lbuf.iptun_flags, '-', IPTUN_NUM_FLAGS); 42772b24ab6bSSebastien Roy lbuf.iptun_flags[IPTUN_NUM_FLAGS] = '\0'; 42782b24ab6bSSebastien Roy if (params.iptun_param_flags & IPTUN_PARAM_IPSECPOL) 42792b24ab6bSSebastien Roy lbuf.iptun_flags[IPTUN_SFLAG_INDEX] = 's'; 42802b24ab6bSSebastien Roy if (params.iptun_param_flags & IPTUN_PARAM_IMPLICIT) 42812b24ab6bSSebastien Roy lbuf.iptun_flags[IPTUN_IFLAG_INDEX] = 'i'; 42822b24ab6bSSebastien Roy 42832b24ab6bSSebastien Roy /* LOCAL */ 42842b24ab6bSSebastien Roy if (params.iptun_param_flags & IPTUN_PARAM_LADDR) 42852b24ab6bSSebastien Roy laddr = params.iptun_param_laddr; 42862b24ab6bSSebastien Roy else 42872b24ab6bSSebastien Roy laddr = (state->ls_parsable) ? "" : "--"; 42882b24ab6bSSebastien Roy (void) strlcpy(lbuf.iptun_laddr, laddr, sizeof (lbuf.iptun_laddr)); 42892b24ab6bSSebastien Roy 42902b24ab6bSSebastien Roy /* REMOTE */ 42912b24ab6bSSebastien Roy if (params.iptun_param_flags & IPTUN_PARAM_RADDR) 42922b24ab6bSSebastien Roy raddr = params.iptun_param_raddr; 42932b24ab6bSSebastien Roy else 42942b24ab6bSSebastien Roy raddr = (state->ls_parsable) ? "" : "--"; 42952b24ab6bSSebastien Roy (void) strlcpy(lbuf.iptun_raddr, raddr, sizeof (lbuf.iptun_raddr)); 42962b24ab6bSSebastien Roy 42972b24ab6bSSebastien Roy ofmt_print(state->ls_ofmt, &lbuf); 42982b24ab6bSSebastien Roy 42992b24ab6bSSebastien Roy return (DLADM_STATUS_OK); 43002b24ab6bSSebastien Roy } 43012b24ab6bSSebastien Roy 43022b24ab6bSSebastien Roy static int 43032b24ab6bSSebastien Roy print_iptun_walker(dladm_handle_t dh, datalink_id_t linkid, void *arg) 43042b24ab6bSSebastien Roy { 43052b24ab6bSSebastien Roy ((show_state_t *)arg)->ls_status = print_iptun(dh, linkid, arg); 43062b24ab6bSSebastien Roy return (DLADM_WALK_CONTINUE); 43072b24ab6bSSebastien Roy } 43082b24ab6bSSebastien Roy 4309d62bc4baSyz147064 static dladm_status_t 4310da14cebeSEric Cheng print_phys(show_state_t *state, datalink_id_t linkid) 4311d62bc4baSyz147064 { 4312d62bc4baSyz147064 char link[MAXLINKNAMELEN]; 4313d62bc4baSyz147064 uint32_t flags; 4314da14cebeSEric Cheng dladm_status_t status; 4315d62bc4baSyz147064 datalink_class_t class; 4316d62bc4baSyz147064 uint32_t media; 4317d62bc4baSyz147064 43184ac67f02SAnurag S. Maskey if ((status = dladm_datalink_id2info(handle, linkid, &flags, &class, 43194ac67f02SAnurag S. Maskey &media, link, MAXLINKNAMELEN)) != DLADM_STATUS_OK) { 4320d62bc4baSyz147064 goto done; 4321d62bc4baSyz147064 } 4322d62bc4baSyz147064 4323d62bc4baSyz147064 if (class != DATALINK_CLASS_PHYS) { 4324d62bc4baSyz147064 status = DLADM_STATUS_BADARG; 4325d62bc4baSyz147064 goto done; 4326d62bc4baSyz147064 } 4327d62bc4baSyz147064 4328d62bc4baSyz147064 if (!(state->ls_flags & flags)) { 4329d62bc4baSyz147064 status = DLADM_STATUS_NOTFOUND; 4330d62bc4baSyz147064 goto done; 4331d62bc4baSyz147064 } 4332d62bc4baSyz147064 4333da14cebeSEric Cheng if (state->ls_mac) 4334da14cebeSEric Cheng status = print_phys_mac(state, linkid, link); 4335da14cebeSEric Cheng else if (state->ls_hwgrp) 4336da14cebeSEric Cheng status = print_phys_hwgrp(state, linkid, link); 4337da14cebeSEric Cheng else 4338da14cebeSEric Cheng status = print_phys_default(state, linkid, link, flags, media); 4339d62bc4baSyz147064 4340d62bc4baSyz147064 done: 4341d62bc4baSyz147064 return (status); 4342d62bc4baSyz147064 } 4343d62bc4baSyz147064 43444ac67f02SAnurag S. Maskey /* ARGSUSED */ 4345d62bc4baSyz147064 static int 43464ac67f02SAnurag S. Maskey show_phys(dladm_handle_t dh, datalink_id_t linkid, void *arg) 4347d62bc4baSyz147064 { 4348d62bc4baSyz147064 show_state_t *state = arg; 4349d62bc4baSyz147064 4350da14cebeSEric Cheng state->ls_status = print_phys(state, linkid); 4351d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 4352d62bc4baSyz147064 } 4353d62bc4baSyz147064 4354d62bc4baSyz147064 /* 4355d62bc4baSyz147064 * Print the active topology information. 4356d62bc4baSyz147064 */ 4357d62bc4baSyz147064 static dladm_status_t 4358e7801d59Ssowmini print_vlan(show_state_t *state, datalink_id_t linkid, link_fields_buf_t *l) 4359d62bc4baSyz147064 { 4360d62bc4baSyz147064 dladm_vlan_attr_t vinfo; 4361d62bc4baSyz147064 uint32_t flags; 4362d62bc4baSyz147064 dladm_status_t status; 4363d62bc4baSyz147064 43644ac67f02SAnurag S. Maskey if ((status = dladm_datalink_id2info(handle, linkid, &flags, NULL, NULL, 4365e7801d59Ssowmini l->link_name, sizeof (l->link_name))) != DLADM_STATUS_OK) { 4366d62bc4baSyz147064 goto done; 4367d62bc4baSyz147064 } 4368d62bc4baSyz147064 4369d62bc4baSyz147064 if (!(state->ls_flags & flags)) { 4370d62bc4baSyz147064 status = DLADM_STATUS_NOTFOUND; 4371d62bc4baSyz147064 goto done; 4372d62bc4baSyz147064 } 4373d62bc4baSyz147064 43744ac67f02SAnurag S. Maskey if ((status = dladm_vlan_info(handle, linkid, &vinfo, 43754ac67f02SAnurag S. Maskey state->ls_flags)) != DLADM_STATUS_OK || 43764ac67f02SAnurag S. Maskey (status = dladm_datalink_id2info(handle, vinfo.dv_linkid, NULL, 43774ac67f02SAnurag S. Maskey NULL, NULL, l->link_over, sizeof (l->link_over))) != 43784ac67f02SAnurag S. Maskey DLADM_STATUS_OK) { 4379d62bc4baSyz147064 goto done; 4380d62bc4baSyz147064 } 4381d62bc4baSyz147064 4382e7801d59Ssowmini (void) snprintf(l->link_vlan_vid, sizeof (l->link_vlan_vid), "%d", 4383e7801d59Ssowmini vinfo.dv_vid); 4384da14cebeSEric Cheng (void) snprintf(l->link_flags, sizeof (l->link_flags), "%c----", 4385da14cebeSEric Cheng vinfo.dv_force ? 'f' : '-'); 4386d62bc4baSyz147064 4387d62bc4baSyz147064 done: 4388d62bc4baSyz147064 return (status); 4389d62bc4baSyz147064 } 4390d62bc4baSyz147064 43914ac67f02SAnurag S. Maskey /* ARGSUSED */ 4392d62bc4baSyz147064 static int 43934ac67f02SAnurag S. Maskey show_vlan(dladm_handle_t dh, datalink_id_t linkid, void *arg) 4394d62bc4baSyz147064 { 4395d62bc4baSyz147064 show_state_t *state = arg; 4396d62bc4baSyz147064 dladm_status_t status; 4397e7801d59Ssowmini link_fields_buf_t lbuf; 4398d62bc4baSyz147064 43995f5c9f54SAnurag S. Maskey bzero(&lbuf, sizeof (link_fields_buf_t)); 4400e7801d59Ssowmini status = print_vlan(state, linkid, &lbuf); 4401d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 4402d62bc4baSyz147064 goto done; 4403e7801d59Ssowmini 44048002d411SSowmini Varadhan ofmt_print(state->ls_ofmt, &lbuf); 4405d62bc4baSyz147064 4406d62bc4baSyz147064 done: 4407d62bc4baSyz147064 state->ls_status = status; 4408d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 4409d62bc4baSyz147064 } 4410d62bc4baSyz147064 4411d62bc4baSyz147064 static void 44128d5c46e6Sam223141 do_show_phys(int argc, char *argv[], const char *use) 4413d62bc4baSyz147064 { 4414d62bc4baSyz147064 int option; 4415d62bc4baSyz147064 uint32_t flags = DLADM_OPT_ACTIVE; 4416d62bc4baSyz147064 boolean_t p_arg = B_FALSE; 4417e7801d59Ssowmini boolean_t o_arg = B_FALSE; 4418da14cebeSEric Cheng boolean_t m_arg = B_FALSE; 4419da14cebeSEric Cheng boolean_t H_arg = B_FALSE; 4420d62bc4baSyz147064 datalink_id_t linkid = DATALINK_ALL_LINKID; 4421d62bc4baSyz147064 show_state_t state; 4422d62bc4baSyz147064 dladm_status_t status; 4423e7801d59Ssowmini char *fields_str = NULL; 4424e7801d59Ssowmini char *all_active_fields = 4425e7801d59Ssowmini "link,media,state,speed,duplex,device"; 44265f5c9f54SAnurag S. Maskey char *all_inactive_fields = "link,device,media,flags"; 4427da14cebeSEric Cheng char *all_mac_fields = "link,slot,address,inuse,client"; 44280dc2366fSVenugopal Iyer char *all_hwgrp_fields = "link,ringtype,rings,clients"; 44292b24ab6bSSebastien Roy const ofmt_field_t *pf; 44308002d411SSowmini Varadhan ofmt_handle_t ofmt; 44318002d411SSowmini Varadhan ofmt_status_t oferr; 44328002d411SSowmini Varadhan uint_t ofmtflags = 0; 4433d62bc4baSyz147064 4434e7801d59Ssowmini bzero(&state, sizeof (state)); 4435d62bc4baSyz147064 opterr = 0; 4436da14cebeSEric Cheng while ((option = getopt_long(argc, argv, ":pPo:mH", 4437d62bc4baSyz147064 show_lopts, NULL)) != -1) { 4438d62bc4baSyz147064 switch (option) { 4439d62bc4baSyz147064 case 'p': 4440d62bc4baSyz147064 if (p_arg) 4441d62bc4baSyz147064 die_optdup(option); 4442d62bc4baSyz147064 4443d62bc4baSyz147064 p_arg = B_TRUE; 4444d62bc4baSyz147064 break; 4445d62bc4baSyz147064 case 'P': 4446d62bc4baSyz147064 if (flags != DLADM_OPT_ACTIVE) 4447d62bc4baSyz147064 die_optdup(option); 4448d62bc4baSyz147064 4449d62bc4baSyz147064 flags = DLADM_OPT_PERSIST; 4450d62bc4baSyz147064 break; 4451e7801d59Ssowmini case 'o': 4452e7801d59Ssowmini o_arg = B_TRUE; 4453e7801d59Ssowmini fields_str = optarg; 4454e7801d59Ssowmini break; 4455da14cebeSEric Cheng case 'm': 4456da14cebeSEric Cheng m_arg = B_TRUE; 4457da14cebeSEric Cheng break; 4458da14cebeSEric Cheng case 'H': 4459da14cebeSEric Cheng H_arg = B_TRUE; 4460da14cebeSEric Cheng break; 4461d62bc4baSyz147064 default: 44628d5c46e6Sam223141 die_opterr(optopt, option, use); 4463d62bc4baSyz147064 break; 4464d62bc4baSyz147064 } 4465d62bc4baSyz147064 } 4466d62bc4baSyz147064 44670d365605Sschuster if (p_arg && !o_arg) 44680d365605Sschuster die("-p requires -o"); 44690d365605Sschuster 4470da14cebeSEric Cheng if (m_arg && H_arg) 4471da14cebeSEric Cheng die("-m cannot combine with -H"); 4472da14cebeSEric Cheng 44730d365605Sschuster if (p_arg && strcasecmp(fields_str, "all") == 0) 44740d365605Sschuster die("\"-o all\" is invalid with -p"); 44750d365605Sschuster 4476d62bc4baSyz147064 /* get link name (optional last argument) */ 4477d62bc4baSyz147064 if (optind == (argc-1)) { 44784ac67f02SAnurag S. Maskey if ((status = dladm_name2info(handle, argv[optind], &linkid, 44794ac67f02SAnurag S. Maskey NULL, NULL, NULL)) != DLADM_STATUS_OK) { 4480d62bc4baSyz147064 die_dlerr(status, "link %s is not valid", argv[optind]); 4481d62bc4baSyz147064 } 4482d62bc4baSyz147064 } else if (optind != argc) { 4483d62bc4baSyz147064 usage(); 4484d62bc4baSyz147064 } 4485d62bc4baSyz147064 44868002d411SSowmini Varadhan state.ls_parsable = p_arg; 4487d62bc4baSyz147064 state.ls_flags = flags; 4488d62bc4baSyz147064 state.ls_donefirst = B_FALSE; 4489da14cebeSEric Cheng state.ls_mac = m_arg; 4490da14cebeSEric Cheng state.ls_hwgrp = H_arg; 4491d62bc4baSyz147064 4492da14cebeSEric Cheng if (m_arg && !(flags & DLADM_OPT_ACTIVE)) { 4493da14cebeSEric Cheng /* 4494da14cebeSEric Cheng * We can only display the factory MAC addresses of 4495da14cebeSEric Cheng * active data-links. 4496da14cebeSEric Cheng */ 4497da14cebeSEric Cheng die("-m not compatible with -P"); 4498e7801d59Ssowmini } 4499e7801d59Ssowmini 4500da14cebeSEric Cheng if (!o_arg || (o_arg && strcasecmp(fields_str, "all") == 0)) { 4501da14cebeSEric Cheng if (state.ls_mac) 4502da14cebeSEric Cheng fields_str = all_mac_fields; 4503da14cebeSEric Cheng else if (state.ls_hwgrp) 4504da14cebeSEric Cheng fields_str = all_hwgrp_fields; 4505da14cebeSEric Cheng else if (state.ls_flags & DLADM_OPT_ACTIVE) { 4506da14cebeSEric Cheng fields_str = all_active_fields; 4507da14cebeSEric Cheng } else { 4508da14cebeSEric Cheng fields_str = all_inactive_fields; 4509da14cebeSEric Cheng } 4510da14cebeSEric Cheng } 4511da14cebeSEric Cheng 4512da14cebeSEric Cheng if (state.ls_mac) { 4513da14cebeSEric Cheng pf = phys_m_fields; 4514da14cebeSEric Cheng } else if (state.ls_hwgrp) { 4515da14cebeSEric Cheng pf = phys_h_fields; 4516da14cebeSEric Cheng } else { 4517da14cebeSEric Cheng pf = phys_fields; 4518da14cebeSEric Cheng } 4519da14cebeSEric Cheng 45208002d411SSowmini Varadhan if (state.ls_parsable) 45218002d411SSowmini Varadhan ofmtflags |= OFMT_PARSABLE; 45228002d411SSowmini Varadhan oferr = ofmt_open(fields_str, pf, ofmtflags, 0, &ofmt); 45238002d411SSowmini Varadhan dladm_ofmt_check(oferr, state.ls_parsable, ofmt); 45248002d411SSowmini Varadhan state.ls_ofmt = ofmt; 4525e7801d59Ssowmini 4526d62bc4baSyz147064 if (linkid == DATALINK_ALL_LINKID) { 45274ac67f02SAnurag S. Maskey (void) dladm_walk_datalink_id(show_phys, handle, &state, 4528d62bc4baSyz147064 DATALINK_CLASS_PHYS, DATALINK_ANY_MEDIATYPE, flags); 4529d62bc4baSyz147064 } else { 45304ac67f02SAnurag S. Maskey (void) show_phys(handle, linkid, &state); 4531d62bc4baSyz147064 if (state.ls_status != DLADM_STATUS_OK) { 4532d62bc4baSyz147064 die_dlerr(state.ls_status, 4533d62bc4baSyz147064 "failed to show physical link %s", argv[optind]); 4534d62bc4baSyz147064 } 4535d62bc4baSyz147064 } 45368002d411SSowmini Varadhan ofmt_close(ofmt); 4537d62bc4baSyz147064 } 4538d62bc4baSyz147064 4539d62bc4baSyz147064 static void 45408d5c46e6Sam223141 do_show_vlan(int argc, char *argv[], const char *use) 4541d62bc4baSyz147064 { 4542d62bc4baSyz147064 int option; 4543d62bc4baSyz147064 uint32_t flags = DLADM_OPT_ACTIVE; 4544d62bc4baSyz147064 boolean_t p_arg = B_FALSE; 4545d62bc4baSyz147064 datalink_id_t linkid = DATALINK_ALL_LINKID; 4546d62bc4baSyz147064 show_state_t state; 4547d62bc4baSyz147064 dladm_status_t status; 4548e7801d59Ssowmini boolean_t o_arg = B_FALSE; 4549e7801d59Ssowmini char *fields_str = NULL; 45508002d411SSowmini Varadhan ofmt_handle_t ofmt; 45518002d411SSowmini Varadhan ofmt_status_t oferr; 45528002d411SSowmini Varadhan uint_t ofmtflags = 0; 4553e7801d59Ssowmini 4554e7801d59Ssowmini bzero(&state, sizeof (state)); 4555d62bc4baSyz147064 4556d62bc4baSyz147064 opterr = 0; 4557e7801d59Ssowmini while ((option = getopt_long(argc, argv, ":pPo:", 4558d62bc4baSyz147064 show_lopts, NULL)) != -1) { 4559d62bc4baSyz147064 switch (option) { 4560d62bc4baSyz147064 case 'p': 4561d62bc4baSyz147064 if (p_arg) 4562d62bc4baSyz147064 die_optdup(option); 4563d62bc4baSyz147064 4564d62bc4baSyz147064 p_arg = B_TRUE; 4565d62bc4baSyz147064 break; 4566d62bc4baSyz147064 case 'P': 4567d62bc4baSyz147064 if (flags != DLADM_OPT_ACTIVE) 4568d62bc4baSyz147064 die_optdup(option); 4569d62bc4baSyz147064 4570d62bc4baSyz147064 flags = DLADM_OPT_PERSIST; 4571d62bc4baSyz147064 break; 4572e7801d59Ssowmini case 'o': 4573e7801d59Ssowmini o_arg = B_TRUE; 4574e7801d59Ssowmini fields_str = optarg; 4575e7801d59Ssowmini break; 4576d62bc4baSyz147064 default: 45778d5c46e6Sam223141 die_opterr(optopt, option, use); 4578d62bc4baSyz147064 break; 4579d62bc4baSyz147064 } 4580d62bc4baSyz147064 } 4581d62bc4baSyz147064 4582d62bc4baSyz147064 /* get link name (optional last argument) */ 4583d62bc4baSyz147064 if (optind == (argc-1)) { 45844ac67f02SAnurag S. Maskey if ((status = dladm_name2info(handle, argv[optind], &linkid, 45854ac67f02SAnurag S. Maskey NULL, NULL, NULL)) != DLADM_STATUS_OK) { 4586d62bc4baSyz147064 die_dlerr(status, "link %s is not valid", argv[optind]); 4587d62bc4baSyz147064 } 4588d62bc4baSyz147064 } else if (optind != argc) { 4589d62bc4baSyz147064 usage(); 4590d62bc4baSyz147064 } 4591d62bc4baSyz147064 45928002d411SSowmini Varadhan state.ls_parsable = p_arg; 4593d62bc4baSyz147064 state.ls_flags = flags; 4594d62bc4baSyz147064 state.ls_donefirst = B_FALSE; 4595d62bc4baSyz147064 4596e7801d59Ssowmini if (!o_arg || (o_arg && strcasecmp(fields_str, "all") == 0)) 45978002d411SSowmini Varadhan fields_str = NULL; 4598e7801d59Ssowmini 45998002d411SSowmini Varadhan if (state.ls_parsable) 46008002d411SSowmini Varadhan ofmtflags |= OFMT_PARSABLE; 46018002d411SSowmini Varadhan oferr = ofmt_open(fields_str, vlan_fields, ofmtflags, 0, &ofmt); 46028002d411SSowmini Varadhan dladm_ofmt_check(oferr, state.ls_parsable, ofmt); 46038002d411SSowmini Varadhan state.ls_ofmt = ofmt; 4604e7801d59Ssowmini 4605d62bc4baSyz147064 if (linkid == DATALINK_ALL_LINKID) { 46064ac67f02SAnurag S. Maskey (void) dladm_walk_datalink_id(show_vlan, handle, &state, 4607d62bc4baSyz147064 DATALINK_CLASS_VLAN, DATALINK_ANY_MEDIATYPE, flags); 4608d62bc4baSyz147064 } else { 46094ac67f02SAnurag S. Maskey (void) show_vlan(handle, linkid, &state); 4610d62bc4baSyz147064 if (state.ls_status != DLADM_STATUS_OK) { 4611d62bc4baSyz147064 die_dlerr(state.ls_status, "failed to show vlan %s", 4612d62bc4baSyz147064 argv[optind]); 4613d62bc4baSyz147064 } 4614d62bc4baSyz147064 } 46158002d411SSowmini Varadhan ofmt_close(ofmt); 4616d62bc4baSyz147064 } 4617d62bc4baSyz147064 4618d62bc4baSyz147064 static void 4619da14cebeSEric Cheng do_create_vnic(int argc, char *argv[], const char *use) 4620da14cebeSEric Cheng { 4621da14cebeSEric Cheng datalink_id_t linkid, dev_linkid; 4622da14cebeSEric Cheng char devname[MAXLINKNAMELEN]; 4623da14cebeSEric Cheng char name[MAXLINKNAMELEN]; 4624da14cebeSEric Cheng boolean_t l_arg = B_FALSE; 4625da14cebeSEric Cheng uint32_t flags = DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST; 4626da14cebeSEric Cheng char *altroot = NULL; 4627b509e89bSRishi Srivatsavai int option; 4628da14cebeSEric Cheng char *endp = NULL; 4629da14cebeSEric Cheng dladm_status_t status; 46301cb875aeSCathy Zhou vnic_mac_addr_type_t mac_addr_type = VNIC_MAC_ADDR_TYPE_UNKNOWN; 46311cb875aeSCathy Zhou uchar_t *mac_addr = NULL; 46321cb875aeSCathy Zhou int mac_slot = -1; 46331cb875aeSCathy Zhou uint_t maclen = 0, mac_prefix_len = 0; 463463a6526dSMichael Lim char propstr[DLADM_STRSIZE]; 4635da14cebeSEric Cheng dladm_arg_list_t *proplist = NULL; 4636285e94f9SMichael Lim int vid = 0; 46371cb875aeSCathy Zhou int af = AF_UNSPEC; 46381cb875aeSCathy Zhou vrid_t vrid = VRRP_VRID_NONE; 4639da14cebeSEric Cheng 4640da14cebeSEric Cheng opterr = 0; 464163a6526dSMichael Lim bzero(propstr, DLADM_STRSIZE); 464263a6526dSMichael Lim 46431cb875aeSCathy Zhou while ((option = getopt_long(argc, argv, ":tfR:l:m:n:p:r:v:V:A:H", 4644da14cebeSEric Cheng vnic_lopts, NULL)) != -1) { 4645da14cebeSEric Cheng switch (option) { 4646da14cebeSEric Cheng case 't': 4647da14cebeSEric Cheng flags &= ~DLADM_OPT_PERSIST; 4648da14cebeSEric Cheng break; 4649da14cebeSEric Cheng case 'R': 4650da14cebeSEric Cheng altroot = optarg; 4651da14cebeSEric Cheng break; 4652da14cebeSEric Cheng case 'l': 4653da14cebeSEric Cheng if (strlcpy(devname, optarg, MAXLINKNAMELEN) >= 4654da14cebeSEric Cheng MAXLINKNAMELEN) 4655da14cebeSEric Cheng die("link name too long"); 4656da14cebeSEric Cheng l_arg = B_TRUE; 4657da14cebeSEric Cheng break; 4658da14cebeSEric Cheng case 'm': 46591cb875aeSCathy Zhou if (mac_addr_type != VNIC_MAC_ADDR_TYPE_UNKNOWN) 46601cb875aeSCathy Zhou die("cannot specify -m option twice"); 46611cb875aeSCathy Zhou 4662da14cebeSEric Cheng if (strcmp(optarg, "fixed") == 0) { 4663da14cebeSEric Cheng /* 4664da14cebeSEric Cheng * A fixed MAC address must be specified 4665da14cebeSEric Cheng * by its value, not by the keyword 'fixed'. 4666da14cebeSEric Cheng */ 4667da14cebeSEric Cheng die("'fixed' is not a valid MAC address"); 4668da14cebeSEric Cheng } 4669da14cebeSEric Cheng if (dladm_vnic_str2macaddrtype(optarg, 4670da14cebeSEric Cheng &mac_addr_type) != DLADM_STATUS_OK) { 4671da14cebeSEric Cheng mac_addr_type = VNIC_MAC_ADDR_TYPE_FIXED; 4672da14cebeSEric Cheng /* MAC address specified by value */ 46731cb875aeSCathy Zhou mac_addr = _link_aton(optarg, (int *)&maclen); 4674da14cebeSEric Cheng if (mac_addr == NULL) { 46751cb875aeSCathy Zhou if (maclen == (uint_t)-1) 4676da14cebeSEric Cheng die("invalid MAC address"); 4677da14cebeSEric Cheng else 4678da14cebeSEric Cheng die("out of memory"); 4679da14cebeSEric Cheng } 4680da14cebeSEric Cheng } 4681da14cebeSEric Cheng break; 4682da14cebeSEric Cheng case 'n': 4683da14cebeSEric Cheng errno = 0; 4684da14cebeSEric Cheng mac_slot = (int)strtol(optarg, &endp, 10); 4685da14cebeSEric Cheng if (errno != 0 || *endp != '\0') 4686da14cebeSEric Cheng die("invalid slot number"); 4687da14cebeSEric Cheng break; 4688da14cebeSEric Cheng case 'p': 468963a6526dSMichael Lim (void) strlcat(propstr, optarg, DLADM_STRSIZE); 469063a6526dSMichael Lim if (strlcat(propstr, ",", DLADM_STRSIZE) >= 469163a6526dSMichael Lim DLADM_STRSIZE) 469263a6526dSMichael Lim die("property list too long '%s'", propstr); 4693da14cebeSEric Cheng break; 4694da14cebeSEric Cheng case 'r': 46951cb875aeSCathy Zhou mac_addr = _link_aton(optarg, (int *)&mac_prefix_len); 4696da14cebeSEric Cheng if (mac_addr == NULL) { 46971cb875aeSCathy Zhou if (mac_prefix_len == (uint_t)-1) 4698da14cebeSEric Cheng die("invalid MAC address"); 4699da14cebeSEric Cheng else 4700da14cebeSEric Cheng die("out of memory"); 4701da14cebeSEric Cheng } 4702da14cebeSEric Cheng break; 47031cb875aeSCathy Zhou case 'V': 47041cb875aeSCathy Zhou if (!str2int(optarg, (int *)&vrid) || 47051cb875aeSCathy Zhou vrid < VRRP_VRID_MIN || vrid > VRRP_VRID_MAX) { 47061cb875aeSCathy Zhou die("invalid VRRP identifier '%s'", optarg); 47071cb875aeSCathy Zhou } 47081cb875aeSCathy Zhou 47091cb875aeSCathy Zhou break; 47101cb875aeSCathy Zhou case 'A': 47111cb875aeSCathy Zhou if (strcmp(optarg, "inet") == 0) 47121cb875aeSCathy Zhou af = AF_INET; 47131cb875aeSCathy Zhou else if (strcmp(optarg, "inet6") == 0) 47141cb875aeSCathy Zhou af = AF_INET6; 47151cb875aeSCathy Zhou else 47161cb875aeSCathy Zhou die("invalid address family '%s'", optarg); 47171cb875aeSCathy Zhou break; 4718da14cebeSEric Cheng case 'v': 4719285e94f9SMichael Lim if (vid != 0) 4720285e94f9SMichael Lim die_optdup(option); 4721285e94f9SMichael Lim 4722285e94f9SMichael Lim if (!str2int(optarg, &vid) || vid < 1 || vid > 4094) 4723285e94f9SMichael Lim die("invalid VLAN identifier '%s'", optarg); 4724285e94f9SMichael Lim 4725da14cebeSEric Cheng break; 4726da14cebeSEric Cheng case 'f': 4727da14cebeSEric Cheng flags |= DLADM_OPT_FORCE; 4728da14cebeSEric Cheng break; 4729da14cebeSEric Cheng default: 4730da14cebeSEric Cheng die_opterr(optopt, option, use); 4731da14cebeSEric Cheng } 4732da14cebeSEric Cheng } 4733da14cebeSEric Cheng 47341cb875aeSCathy Zhou if (mac_addr_type == VNIC_MAC_ADDR_TYPE_UNKNOWN) 47351cb875aeSCathy Zhou mac_addr_type = VNIC_MAC_ADDR_TYPE_AUTO; 47361cb875aeSCathy Zhou 4737da14cebeSEric Cheng /* 4738da14cebeSEric Cheng * 'f' - force, flag can be specified only with 'v' - vlan. 4739da14cebeSEric Cheng */ 4740da14cebeSEric Cheng if ((flags & DLADM_OPT_FORCE) != 0 && vid == 0) 4741da14cebeSEric Cheng die("-f option can only be used with -v"); 4742da14cebeSEric Cheng 4743da14cebeSEric Cheng if (mac_prefix_len != 0 && mac_addr_type != VNIC_MAC_ADDR_TYPE_RANDOM && 4744da14cebeSEric Cheng mac_addr_type != VNIC_MAC_ADDR_TYPE_FIXED) 4745da14cebeSEric Cheng usage(); 4746da14cebeSEric Cheng 47471cb875aeSCathy Zhou if (mac_addr_type == VNIC_MAC_ADDR_TYPE_VRID) { 47481cb875aeSCathy Zhou if (vrid == VRRP_VRID_NONE || af == AF_UNSPEC || 47491cb875aeSCathy Zhou mac_addr != NULL || maclen != 0 || mac_slot != -1 || 47501cb875aeSCathy Zhou mac_prefix_len != 0) { 47511cb875aeSCathy Zhou usage(); 47521cb875aeSCathy Zhou } 47531cb875aeSCathy Zhou } else if ((af != AF_UNSPEC || vrid != VRRP_VRID_NONE)) { 47541cb875aeSCathy Zhou usage(); 47551cb875aeSCathy Zhou } 47561cb875aeSCathy Zhou 4757da14cebeSEric Cheng /* check required options */ 4758da14cebeSEric Cheng if (!l_arg) 4759da14cebeSEric Cheng usage(); 4760da14cebeSEric Cheng 4761da14cebeSEric Cheng if (mac_slot != -1 && mac_addr_type != VNIC_MAC_ADDR_TYPE_FACTORY) 4762da14cebeSEric Cheng usage(); 4763da14cebeSEric Cheng 4764da14cebeSEric Cheng /* the VNIC id is the required operand */ 4765da14cebeSEric Cheng if (optind != (argc - 1)) 4766da14cebeSEric Cheng usage(); 4767da14cebeSEric Cheng 4768da14cebeSEric Cheng if (strlcpy(name, argv[optind], MAXLINKNAMELEN) >= MAXLINKNAMELEN) 4769da14cebeSEric Cheng die("link name too long '%s'", argv[optind]); 4770da14cebeSEric Cheng 4771da14cebeSEric Cheng if (!dladm_valid_linkname(name)) 4772da14cebeSEric Cheng die("invalid link name '%s'", argv[optind]); 4773da14cebeSEric Cheng 4774da14cebeSEric Cheng if (altroot != NULL) 4775da14cebeSEric Cheng altroot_cmd(altroot, argc, argv); 4776da14cebeSEric Cheng 47774ac67f02SAnurag S. Maskey if (dladm_name2info(handle, devname, &dev_linkid, NULL, NULL, NULL) != 4778da14cebeSEric Cheng DLADM_STATUS_OK) 4779da14cebeSEric Cheng die("invalid link name '%s'", devname); 4780da14cebeSEric Cheng 478163a6526dSMichael Lim if (dladm_parse_link_props(propstr, &proplist, B_FALSE) 478263a6526dSMichael Lim != DLADM_STATUS_OK) 478363a6526dSMichael Lim die("invalid vnic property"); 478463a6526dSMichael Lim 47854ac67f02SAnurag S. Maskey status = dladm_vnic_create(handle, name, dev_linkid, mac_addr_type, 47861cb875aeSCathy Zhou mac_addr, maclen, &mac_slot, mac_prefix_len, vid, vrid, af, 47871cb875aeSCathy Zhou &linkid, proplist, flags); 47886f40bf67SRishi Srivatsavai switch (status) { 47896f40bf67SRishi Srivatsavai case DLADM_STATUS_OK: 47906f40bf67SRishi Srivatsavai break; 47916f40bf67SRishi Srivatsavai 47926f40bf67SRishi Srivatsavai case DLADM_STATUS_LINKBUSY: 47936f40bf67SRishi Srivatsavai die("VLAN over '%s' may not use default_tag ID " 47946f40bf67SRishi Srivatsavai "(see dladm(1M))", devname); 47956f40bf67SRishi Srivatsavai break; 47966f40bf67SRishi Srivatsavai 47976f40bf67SRishi Srivatsavai default: 4798da14cebeSEric Cheng die_dlerr(status, "vnic creation over %s failed", devname); 47996f40bf67SRishi Srivatsavai } 4800da14cebeSEric Cheng 4801da14cebeSEric Cheng dladm_free_props(proplist); 48021cb875aeSCathy Zhou free(mac_addr); 4803da14cebeSEric Cheng } 4804da14cebeSEric Cheng 4805da14cebeSEric Cheng static void 4806da14cebeSEric Cheng do_etherstub_check(const char *name, datalink_id_t linkid, boolean_t etherstub, 4807da14cebeSEric Cheng uint32_t flags) 4808da14cebeSEric Cheng { 4809da14cebeSEric Cheng boolean_t is_etherstub; 4810da14cebeSEric Cheng dladm_vnic_attr_t attr; 4811da14cebeSEric Cheng 48124ac67f02SAnurag S. Maskey if (dladm_vnic_info(handle, linkid, &attr, flags) != DLADM_STATUS_OK) { 4813da14cebeSEric Cheng /* 4814da14cebeSEric Cheng * Let the delete continue anyway. 4815da14cebeSEric Cheng */ 4816da14cebeSEric Cheng return; 4817da14cebeSEric Cheng } 4818da14cebeSEric Cheng is_etherstub = (attr.va_link_id == DATALINK_INVALID_LINKID); 4819da14cebeSEric Cheng if (is_etherstub != etherstub) { 4820da14cebeSEric Cheng die("'%s' is not %s", name, 4821da14cebeSEric Cheng (is_etherstub ? "a vnic" : "an etherstub")); 4822da14cebeSEric Cheng } 4823da14cebeSEric Cheng } 4824da14cebeSEric Cheng 4825da14cebeSEric Cheng static void 4826da14cebeSEric Cheng do_delete_vnic_common(int argc, char *argv[], const char *use, 4827da14cebeSEric Cheng boolean_t etherstub) 4828da14cebeSEric Cheng { 4829b509e89bSRishi Srivatsavai int option; 4830da14cebeSEric Cheng uint32_t flags = DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST; 4831da14cebeSEric Cheng datalink_id_t linkid; 4832da14cebeSEric Cheng char *altroot = NULL; 4833da14cebeSEric Cheng dladm_status_t status; 4834da14cebeSEric Cheng 4835da14cebeSEric Cheng opterr = 0; 4836da14cebeSEric Cheng while ((option = getopt_long(argc, argv, ":R:t", lopts, 4837da14cebeSEric Cheng NULL)) != -1) { 4838da14cebeSEric Cheng switch (option) { 4839da14cebeSEric Cheng case 't': 4840da14cebeSEric Cheng flags &= ~DLADM_OPT_PERSIST; 4841da14cebeSEric Cheng break; 4842da14cebeSEric Cheng case 'R': 4843da14cebeSEric Cheng altroot = optarg; 4844da14cebeSEric Cheng break; 4845da14cebeSEric Cheng default: 4846da14cebeSEric Cheng die_opterr(optopt, option, use); 4847da14cebeSEric Cheng } 4848da14cebeSEric Cheng } 4849da14cebeSEric Cheng 4850da14cebeSEric Cheng /* get vnic name (required last argument) */ 4851da14cebeSEric Cheng if (optind != (argc - 1)) 4852da14cebeSEric Cheng usage(); 4853da14cebeSEric Cheng 4854da14cebeSEric Cheng if (altroot != NULL) 4855da14cebeSEric Cheng altroot_cmd(altroot, argc, argv); 4856da14cebeSEric Cheng 48574ac67f02SAnurag S. Maskey status = dladm_name2info(handle, argv[optind], &linkid, NULL, NULL, 48584ac67f02SAnurag S. Maskey NULL); 4859da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 4860da14cebeSEric Cheng die("invalid link name '%s'", argv[optind]); 4861da14cebeSEric Cheng 4862da14cebeSEric Cheng if ((flags & DLADM_OPT_ACTIVE) != 0) { 4863da14cebeSEric Cheng do_etherstub_check(argv[optind], linkid, etherstub, 4864da14cebeSEric Cheng DLADM_OPT_ACTIVE); 4865da14cebeSEric Cheng } 4866da14cebeSEric Cheng if ((flags & DLADM_OPT_PERSIST) != 0) { 4867da14cebeSEric Cheng do_etherstub_check(argv[optind], linkid, etherstub, 4868da14cebeSEric Cheng DLADM_OPT_PERSIST); 4869da14cebeSEric Cheng } 4870da14cebeSEric Cheng 48714ac67f02SAnurag S. Maskey status = dladm_vnic_delete(handle, linkid, flags); 4872da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 4873da14cebeSEric Cheng die_dlerr(status, "vnic deletion failed"); 4874da14cebeSEric Cheng } 4875da14cebeSEric Cheng 4876da14cebeSEric Cheng static void 4877da14cebeSEric Cheng do_delete_vnic(int argc, char *argv[], const char *use) 4878da14cebeSEric Cheng { 4879da14cebeSEric Cheng do_delete_vnic_common(argc, argv, use, B_FALSE); 4880da14cebeSEric Cheng } 4881da14cebeSEric Cheng 4882da14cebeSEric Cheng /* ARGSUSED */ 4883da14cebeSEric Cheng static void 4884da14cebeSEric Cheng do_up_vnic_common(int argc, char *argv[], const char *use, boolean_t vlan) 4885da14cebeSEric Cheng { 4886da14cebeSEric Cheng datalink_id_t linkid = DATALINK_ALL_LINKID; 4887da14cebeSEric Cheng dladm_status_t status; 4888da14cebeSEric Cheng char *type; 4889da14cebeSEric Cheng 4890da14cebeSEric Cheng type = vlan ? "vlan" : "vnic"; 4891da14cebeSEric Cheng 4892da14cebeSEric Cheng /* 4893da14cebeSEric Cheng * get the id or the name of the vnic/vlan (optional last argument) 4894da14cebeSEric Cheng */ 4895da14cebeSEric Cheng if (argc == 2) { 48964ac67f02SAnurag S. Maskey status = dladm_name2info(handle, argv[1], &linkid, NULL, NULL, 48974ac67f02SAnurag S. Maskey NULL); 4898da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 4899da14cebeSEric Cheng goto done; 4900da14cebeSEric Cheng 4901da14cebeSEric Cheng } else if (argc > 2) { 4902da14cebeSEric Cheng usage(); 4903da14cebeSEric Cheng } 4904da14cebeSEric Cheng 4905da14cebeSEric Cheng if (vlan) 49064ac67f02SAnurag S. Maskey status = dladm_vlan_up(handle, linkid); 4907da14cebeSEric Cheng else 49084ac67f02SAnurag S. Maskey status = dladm_vnic_up(handle, linkid, 0); 4909da14cebeSEric Cheng 4910da14cebeSEric Cheng done: 4911da14cebeSEric Cheng if (status != DLADM_STATUS_OK) { 4912da14cebeSEric Cheng if (argc == 2) { 4913da14cebeSEric Cheng die_dlerr(status, 4914da14cebeSEric Cheng "could not bring up %s '%s'", type, argv[1]); 4915da14cebeSEric Cheng } else { 4916da14cebeSEric Cheng die_dlerr(status, "could not bring %ss up", type); 4917da14cebeSEric Cheng } 4918da14cebeSEric Cheng } 4919da14cebeSEric Cheng } 4920da14cebeSEric Cheng 4921da14cebeSEric Cheng static void 4922da14cebeSEric Cheng do_up_vnic(int argc, char *argv[], const char *use) 4923da14cebeSEric Cheng { 4924da14cebeSEric Cheng do_up_vnic_common(argc, argv, use, B_FALSE); 4925da14cebeSEric Cheng } 4926da14cebeSEric Cheng 4927da14cebeSEric Cheng static void 4928da14cebeSEric Cheng dump_vnics_head(const char *dev) 4929da14cebeSEric Cheng { 4930da14cebeSEric Cheng if (strlen(dev)) 4931da14cebeSEric Cheng (void) printf("%s", dev); 4932da14cebeSEric Cheng 4933da14cebeSEric Cheng (void) printf("\tipackets rbytes opackets obytes "); 4934da14cebeSEric Cheng 4935da14cebeSEric Cheng if (strlen(dev)) 4936da14cebeSEric Cheng (void) printf("%%ipkts %%opkts\n"); 4937da14cebeSEric Cheng else 4938da14cebeSEric Cheng (void) printf("\n"); 4939da14cebeSEric Cheng } 4940da14cebeSEric Cheng 4941da14cebeSEric Cheng static void 4942da14cebeSEric Cheng dump_vnic_stat(const char *name, datalink_id_t vnic_id, 4943da14cebeSEric Cheng show_vnic_state_t *state, pktsum_t *vnic_stats, pktsum_t *tot_stats) 4944da14cebeSEric Cheng { 4945da14cebeSEric Cheng pktsum_t diff_stats; 4946da14cebeSEric Cheng pktsum_t *old_stats = &state->vs_prevstats[vnic_id]; 4947da14cebeSEric Cheng 4948da14cebeSEric Cheng dladm_stats_diff(&diff_stats, vnic_stats, old_stats); 4949da14cebeSEric Cheng 4950da14cebeSEric Cheng (void) printf("%s", name); 4951da14cebeSEric Cheng 4952da14cebeSEric Cheng (void) printf("\t%-10llu", diff_stats.ipackets); 4953da14cebeSEric Cheng (void) printf("%-12llu", diff_stats.rbytes); 4954da14cebeSEric Cheng (void) printf("%-10llu", diff_stats.opackets); 4955da14cebeSEric Cheng (void) printf("%-12llu", diff_stats.obytes); 4956da14cebeSEric Cheng 4957da14cebeSEric Cheng if (tot_stats) { 4958da14cebeSEric Cheng if (tot_stats->ipackets == 0) { 4959da14cebeSEric Cheng (void) printf("\t-"); 4960da14cebeSEric Cheng } else { 4961da14cebeSEric Cheng (void) printf("\t%-6.1f", (double)diff_stats.ipackets/ 4962da14cebeSEric Cheng (double)tot_stats->ipackets * 100); 4963da14cebeSEric Cheng } 4964da14cebeSEric Cheng if (tot_stats->opackets == 0) { 4965da14cebeSEric Cheng (void) printf("\t-"); 4966da14cebeSEric Cheng } else { 4967da14cebeSEric Cheng (void) printf("\t%-6.1f", (double)diff_stats.opackets/ 4968da14cebeSEric Cheng (double)tot_stats->opackets * 100); 4969da14cebeSEric Cheng } 4970da14cebeSEric Cheng } 4971da14cebeSEric Cheng (void) printf("\n"); 4972da14cebeSEric Cheng 4973da14cebeSEric Cheng *old_stats = *vnic_stats; 4974da14cebeSEric Cheng } 4975da14cebeSEric Cheng 4976da14cebeSEric Cheng /* 4977da14cebeSEric Cheng * Called from the walker dladm_vnic_walk_sys() for each vnic to display 4978da14cebeSEric Cheng * vnic information or statistics. 4979da14cebeSEric Cheng */ 4980da14cebeSEric Cheng static dladm_status_t 4981da14cebeSEric Cheng print_vnic(show_vnic_state_t *state, datalink_id_t linkid) 4982da14cebeSEric Cheng { 4983da14cebeSEric Cheng dladm_vnic_attr_t attr, *vnic = &attr; 4984da14cebeSEric Cheng dladm_status_t status; 4985da14cebeSEric Cheng boolean_t is_etherstub; 4986da14cebeSEric Cheng char devname[MAXLINKNAMELEN]; 4987da14cebeSEric Cheng char vnic_name[MAXLINKNAMELEN]; 4988da14cebeSEric Cheng char mstr[MAXMACADDRLEN * 3]; 4989da14cebeSEric Cheng vnic_fields_buf_t vbuf; 4990da14cebeSEric Cheng 49914ac67f02SAnurag S. Maskey if ((status = dladm_vnic_info(handle, linkid, vnic, state->vs_flags)) != 4992da14cebeSEric Cheng DLADM_STATUS_OK) 4993da14cebeSEric Cheng return (status); 4994da14cebeSEric Cheng 4995da14cebeSEric Cheng is_etherstub = (vnic->va_link_id == DATALINK_INVALID_LINKID); 4996da14cebeSEric Cheng if (state->vs_etherstub != is_etherstub) { 4997da14cebeSEric Cheng /* 4998da14cebeSEric Cheng * Want all etherstub but it's not one, or want 4999da14cebeSEric Cheng * non-etherstub and it's one. 5000da14cebeSEric Cheng */ 5001da14cebeSEric Cheng return (DLADM_STATUS_OK); 5002da14cebeSEric Cheng } 5003da14cebeSEric Cheng 5004da14cebeSEric Cheng if (state->vs_link_id != DATALINK_ALL_LINKID) { 5005da14cebeSEric Cheng if (state->vs_link_id != vnic->va_link_id) 5006da14cebeSEric Cheng return (DLADM_STATUS_OK); 5007da14cebeSEric Cheng } 5008da14cebeSEric Cheng 50094ac67f02SAnurag S. Maskey if (dladm_datalink_id2info(handle, linkid, NULL, NULL, 5010da14cebeSEric Cheng NULL, vnic_name, sizeof (vnic_name)) != DLADM_STATUS_OK) 5011da14cebeSEric Cheng return (DLADM_STATUS_BADARG); 5012da14cebeSEric Cheng 5013da14cebeSEric Cheng bzero(devname, sizeof (devname)); 5014da14cebeSEric Cheng if (!is_etherstub && 50154ac67f02SAnurag S. Maskey dladm_datalink_id2info(handle, vnic->va_link_id, NULL, NULL, 5016da14cebeSEric Cheng NULL, devname, sizeof (devname)) != DLADM_STATUS_OK) 50172b24ab6bSSebastien Roy (void) sprintf(devname, "?"); 5018da14cebeSEric Cheng 5019da14cebeSEric Cheng state->vs_found = B_TRUE; 5020da14cebeSEric Cheng if (state->vs_stats) { 5021da14cebeSEric Cheng /* print vnic statistics */ 5022da14cebeSEric Cheng pktsum_t vnic_stats; 5023da14cebeSEric Cheng 5024da14cebeSEric Cheng if (state->vs_firstonly) { 5025da14cebeSEric Cheng if (state->vs_donefirst) 5026da14cebeSEric Cheng return (0); 5027da14cebeSEric Cheng state->vs_donefirst = B_TRUE; 5028da14cebeSEric Cheng } 5029da14cebeSEric Cheng 5030da14cebeSEric Cheng if (!state->vs_printstats) { 5031da14cebeSEric Cheng /* 5032da14cebeSEric Cheng * get vnic statistics and add to the sum for the 5033da14cebeSEric Cheng * named device. 5034da14cebeSEric Cheng */ 5035da14cebeSEric Cheng get_link_stats(vnic_name, &vnic_stats); 5036da14cebeSEric Cheng dladm_stats_total(&state->vs_totalstats, &vnic_stats, 5037da14cebeSEric Cheng &state->vs_prevstats[vnic->va_vnic_id]); 5038da14cebeSEric Cheng } else { 5039da14cebeSEric Cheng /* get and print vnic statistics */ 5040da14cebeSEric Cheng get_link_stats(vnic_name, &vnic_stats); 5041da14cebeSEric Cheng dump_vnic_stat(vnic_name, linkid, state, &vnic_stats, 5042da14cebeSEric Cheng &state->vs_totalstats); 5043da14cebeSEric Cheng } 5044da14cebeSEric Cheng return (DLADM_STATUS_OK); 5045da14cebeSEric Cheng } else { 5046da14cebeSEric Cheng (void) snprintf(vbuf.vnic_link, sizeof (vbuf.vnic_link), 5047da14cebeSEric Cheng "%s", vnic_name); 5048da14cebeSEric Cheng 5049da14cebeSEric Cheng if (!is_etherstub) { 5050da14cebeSEric Cheng 5051da14cebeSEric Cheng (void) snprintf(vbuf.vnic_over, sizeof (vbuf.vnic_over), 5052da14cebeSEric Cheng "%s", devname); 5053da14cebeSEric Cheng (void) snprintf(vbuf.vnic_speed, 5054da14cebeSEric Cheng sizeof (vbuf.vnic_speed), "%u", 5055da14cebeSEric Cheng (uint_t)((get_ifspeed(vnic_name, B_TRUE)) 5056da14cebeSEric Cheng / 1000000ull)); 5057da14cebeSEric Cheng 5058da14cebeSEric Cheng switch (vnic->va_mac_addr_type) { 5059da14cebeSEric Cheng case VNIC_MAC_ADDR_TYPE_FIXED: 5060da14cebeSEric Cheng case VNIC_MAC_ADDR_TYPE_PRIMARY: 5061da14cebeSEric Cheng (void) snprintf(vbuf.vnic_macaddrtype, 5062da14cebeSEric Cheng sizeof (vbuf.vnic_macaddrtype), 5063da14cebeSEric Cheng gettext("fixed")); 5064da14cebeSEric Cheng break; 5065da14cebeSEric Cheng case VNIC_MAC_ADDR_TYPE_RANDOM: 5066da14cebeSEric Cheng (void) snprintf(vbuf.vnic_macaddrtype, 5067da14cebeSEric Cheng sizeof (vbuf.vnic_macaddrtype), 5068da14cebeSEric Cheng gettext("random")); 5069da14cebeSEric Cheng break; 5070da14cebeSEric Cheng case VNIC_MAC_ADDR_TYPE_FACTORY: 5071da14cebeSEric Cheng (void) snprintf(vbuf.vnic_macaddrtype, 5072da14cebeSEric Cheng sizeof (vbuf.vnic_macaddrtype), 5073da14cebeSEric Cheng gettext("factory, slot %d"), 5074da14cebeSEric Cheng vnic->va_mac_slot); 5075da14cebeSEric Cheng break; 50761cb875aeSCathy Zhou case VNIC_MAC_ADDR_TYPE_VRID: 50771cb875aeSCathy Zhou (void) snprintf(vbuf.vnic_macaddrtype, 50781cb875aeSCathy Zhou sizeof (vbuf.vnic_macaddrtype), 50791cb875aeSCathy Zhou gettext("vrrp, %d/%s"), 50801cb875aeSCathy Zhou vnic->va_vrid, vnic->va_af == AF_INET ? 50811cb875aeSCathy Zhou "inet" : "inet6"); 50821cb875aeSCathy Zhou break; 5083da14cebeSEric Cheng } 5084da14cebeSEric Cheng 5085da14cebeSEric Cheng if (strlen(vbuf.vnic_macaddrtype) > 0) { 5086da14cebeSEric Cheng (void) snprintf(vbuf.vnic_macaddr, 5087da14cebeSEric Cheng sizeof (vbuf.vnic_macaddr), "%s", 5088da14cebeSEric Cheng dladm_aggr_macaddr2str(vnic->va_mac_addr, 5089da14cebeSEric Cheng mstr)); 5090da14cebeSEric Cheng } 5091da14cebeSEric Cheng 5092da14cebeSEric Cheng (void) snprintf(vbuf.vnic_vid, sizeof (vbuf.vnic_vid), 5093da14cebeSEric Cheng "%d", vnic->va_vid); 5094da14cebeSEric Cheng } 5095da14cebeSEric Cheng 50968002d411SSowmini Varadhan ofmt_print(state->vs_ofmt, &vbuf); 5097da14cebeSEric Cheng 5098da14cebeSEric Cheng return (DLADM_STATUS_OK); 5099da14cebeSEric Cheng } 5100da14cebeSEric Cheng } 5101da14cebeSEric Cheng 51024ac67f02SAnurag S. Maskey /* ARGSUSED */ 5103da14cebeSEric Cheng static int 51044ac67f02SAnurag S. Maskey show_vnic(dladm_handle_t dh, datalink_id_t linkid, void *arg) 5105da14cebeSEric Cheng { 5106da14cebeSEric Cheng show_vnic_state_t *state = arg; 5107da14cebeSEric Cheng 5108da14cebeSEric Cheng state->vs_status = print_vnic(state, linkid); 5109da14cebeSEric Cheng return (DLADM_WALK_CONTINUE); 5110da14cebeSEric Cheng } 5111da14cebeSEric Cheng 5112da14cebeSEric Cheng static void 5113da14cebeSEric Cheng do_show_vnic_common(int argc, char *argv[], const char *use, 5114da14cebeSEric Cheng boolean_t etherstub) 5115da14cebeSEric Cheng { 5116da14cebeSEric Cheng int option; 5117da14cebeSEric Cheng boolean_t s_arg = B_FALSE; 5118da14cebeSEric Cheng boolean_t i_arg = B_FALSE; 5119da14cebeSEric Cheng boolean_t l_arg = B_FALSE; 5120da14cebeSEric Cheng uint32_t interval = 0, flags = DLADM_OPT_ACTIVE; 5121da14cebeSEric Cheng datalink_id_t linkid = DATALINK_ALL_LINKID; 5122da14cebeSEric Cheng datalink_id_t dev_linkid = DATALINK_ALL_LINKID; 5123da14cebeSEric Cheng show_vnic_state_t state; 5124da14cebeSEric Cheng dladm_status_t status; 5125da14cebeSEric Cheng boolean_t o_arg = B_FALSE; 5126da14cebeSEric Cheng char *fields_str = NULL; 51272b24ab6bSSebastien Roy const ofmt_field_t *pf; 51288002d411SSowmini Varadhan char *all_e_fields = "link"; 51298002d411SSowmini Varadhan ofmt_handle_t ofmt; 51308002d411SSowmini Varadhan ofmt_status_t oferr; 51318002d411SSowmini Varadhan uint_t ofmtflags = 0; 5132da14cebeSEric Cheng 5133da14cebeSEric Cheng bzero(&state, sizeof (state)); 5134da14cebeSEric Cheng opterr = 0; 5135da14cebeSEric Cheng while ((option = getopt_long(argc, argv, ":pPl:si:o:", lopts, 5136da14cebeSEric Cheng NULL)) != -1) { 5137da14cebeSEric Cheng switch (option) { 5138da14cebeSEric Cheng case 'p': 51398002d411SSowmini Varadhan state.vs_parsable = B_TRUE; 5140da14cebeSEric Cheng break; 5141da14cebeSEric Cheng case 'P': 5142da14cebeSEric Cheng flags = DLADM_OPT_PERSIST; 5143da14cebeSEric Cheng break; 5144da14cebeSEric Cheng case 'l': 5145da14cebeSEric Cheng if (etherstub) 5146da14cebeSEric Cheng die("option not supported for this command"); 5147da14cebeSEric Cheng 5148da14cebeSEric Cheng if (strlcpy(state.vs_link, optarg, MAXLINKNAMELEN) >= 5149da14cebeSEric Cheng MAXLINKNAMELEN) 5150da14cebeSEric Cheng die("link name too long"); 5151da14cebeSEric Cheng 5152da14cebeSEric Cheng l_arg = B_TRUE; 5153da14cebeSEric Cheng break; 5154da14cebeSEric Cheng case 's': 5155da14cebeSEric Cheng if (s_arg) { 5156da14cebeSEric Cheng die("the option -s cannot be specified " 5157da14cebeSEric Cheng "more than once"); 5158da14cebeSEric Cheng } 5159da14cebeSEric Cheng s_arg = B_TRUE; 5160da14cebeSEric Cheng break; 5161da14cebeSEric Cheng case 'i': 5162da14cebeSEric Cheng if (i_arg) { 5163da14cebeSEric Cheng die("the option -i cannot be specified " 5164da14cebeSEric Cheng "more than once"); 5165da14cebeSEric Cheng } 5166da14cebeSEric Cheng i_arg = B_TRUE; 516763a6526dSMichael Lim if (!dladm_str2interval(optarg, &interval)) 5168da14cebeSEric Cheng die("invalid interval value '%s'", optarg); 5169da14cebeSEric Cheng break; 5170da14cebeSEric Cheng case 'o': 5171da14cebeSEric Cheng o_arg = B_TRUE; 5172da14cebeSEric Cheng fields_str = optarg; 5173da14cebeSEric Cheng break; 5174da14cebeSEric Cheng default: 5175da14cebeSEric Cheng die_opterr(optopt, option, use); 5176da14cebeSEric Cheng } 5177da14cebeSEric Cheng } 5178da14cebeSEric Cheng 5179da14cebeSEric Cheng if (i_arg && !s_arg) 5180da14cebeSEric Cheng die("the option -i can be used only with -s"); 5181da14cebeSEric Cheng 5182da14cebeSEric Cheng /* get vnic ID (optional last argument) */ 5183da14cebeSEric Cheng if (optind == (argc - 1)) { 51844ac67f02SAnurag S. Maskey status = dladm_name2info(handle, argv[optind], &linkid, NULL, 5185da14cebeSEric Cheng NULL, NULL); 5186da14cebeSEric Cheng if (status != DLADM_STATUS_OK) { 5187da14cebeSEric Cheng die_dlerr(status, "invalid vnic name '%s'", 5188da14cebeSEric Cheng argv[optind]); 5189da14cebeSEric Cheng } 5190da14cebeSEric Cheng (void) strlcpy(state.vs_vnic, argv[optind], MAXLINKNAMELEN); 5191da14cebeSEric Cheng } else if (optind != argc) { 5192da14cebeSEric Cheng usage(); 5193da14cebeSEric Cheng } 5194da14cebeSEric Cheng 5195da14cebeSEric Cheng if (l_arg) { 51964ac67f02SAnurag S. Maskey status = dladm_name2info(handle, state.vs_link, &dev_linkid, 51974ac67f02SAnurag S. Maskey NULL, NULL, NULL); 5198da14cebeSEric Cheng if (status != DLADM_STATUS_OK) { 5199da14cebeSEric Cheng die_dlerr(status, "invalid link name '%s'", 5200da14cebeSEric Cheng state.vs_link); 5201da14cebeSEric Cheng } 5202da14cebeSEric Cheng } 5203da14cebeSEric Cheng 5204da14cebeSEric Cheng state.vs_vnic_id = linkid; 5205da14cebeSEric Cheng state.vs_link_id = dev_linkid; 5206da14cebeSEric Cheng state.vs_etherstub = etherstub; 5207da14cebeSEric Cheng state.vs_found = B_FALSE; 5208da14cebeSEric Cheng state.vs_flags = flags; 5209da14cebeSEric Cheng 5210da14cebeSEric Cheng if (!o_arg || (o_arg && strcasecmp(fields_str, "all") == 0)) { 5211da14cebeSEric Cheng if (etherstub) 5212da14cebeSEric Cheng fields_str = all_e_fields; 5213da14cebeSEric Cheng } 5214da14cebeSEric Cheng pf = vnic_fields; 5215da14cebeSEric Cheng 52168002d411SSowmini Varadhan if (state.vs_parsable) 52178002d411SSowmini Varadhan ofmtflags |= OFMT_PARSABLE; 52188002d411SSowmini Varadhan oferr = ofmt_open(fields_str, pf, ofmtflags, 0, &ofmt); 52198002d411SSowmini Varadhan dladm_ofmt_check(oferr, state.vs_parsable, ofmt); 52208002d411SSowmini Varadhan state.vs_ofmt = ofmt; 5221da14cebeSEric Cheng 5222da14cebeSEric Cheng if (s_arg) { 5223da14cebeSEric Cheng /* Display vnic statistics */ 5224da14cebeSEric Cheng vnic_stats(&state, interval); 52258002d411SSowmini Varadhan ofmt_close(ofmt); 5226da14cebeSEric Cheng return; 5227da14cebeSEric Cheng } 5228da14cebeSEric Cheng 5229da14cebeSEric Cheng /* Display vnic information */ 5230da14cebeSEric Cheng state.vs_donefirst = B_FALSE; 5231da14cebeSEric Cheng 5232da14cebeSEric Cheng if (linkid == DATALINK_ALL_LINKID) { 52334ac67f02SAnurag S. Maskey (void) dladm_walk_datalink_id(show_vnic, handle, &state, 5234da14cebeSEric Cheng DATALINK_CLASS_VNIC | DATALINK_CLASS_ETHERSTUB, 5235c3affd82SMichael Lim DATALINK_ANY_MEDIATYPE, flags); 5236da14cebeSEric Cheng } else { 52374ac67f02SAnurag S. Maskey (void) show_vnic(handle, linkid, &state); 5238da14cebeSEric Cheng if (state.vs_status != DLADM_STATUS_OK) { 52398002d411SSowmini Varadhan ofmt_close(ofmt); 5240da14cebeSEric Cheng die_dlerr(state.vs_status, "failed to show vnic '%s'", 5241da14cebeSEric Cheng state.vs_vnic); 5242da14cebeSEric Cheng } 5243da14cebeSEric Cheng } 52448002d411SSowmini Varadhan ofmt_close(ofmt); 5245da14cebeSEric Cheng } 5246da14cebeSEric Cheng 5247da14cebeSEric Cheng static void 5248da14cebeSEric Cheng do_show_vnic(int argc, char *argv[], const char *use) 5249da14cebeSEric Cheng { 5250da14cebeSEric Cheng do_show_vnic_common(argc, argv, use, B_FALSE); 5251da14cebeSEric Cheng } 5252da14cebeSEric Cheng 5253da14cebeSEric Cheng static void 5254da14cebeSEric Cheng do_create_etherstub(int argc, char *argv[], const char *use) 5255da14cebeSEric Cheng { 5256da14cebeSEric Cheng uint32_t flags; 5257da14cebeSEric Cheng char *altroot = NULL; 5258b509e89bSRishi Srivatsavai int option; 5259da14cebeSEric Cheng dladm_status_t status; 5260da14cebeSEric Cheng char name[MAXLINKNAMELEN]; 5261da14cebeSEric Cheng uchar_t mac_addr[ETHERADDRL]; 5262da14cebeSEric Cheng 5263da14cebeSEric Cheng name[0] = '\0'; 5264da14cebeSEric Cheng bzero(mac_addr, sizeof (mac_addr)); 5265da14cebeSEric Cheng flags = DLADM_OPT_ANCHOR | DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST; 5266da14cebeSEric Cheng 5267da14cebeSEric Cheng opterr = 0; 5268da14cebeSEric Cheng while ((option = getopt_long(argc, argv, "tR:", 5269da14cebeSEric Cheng etherstub_lopts, NULL)) != -1) { 5270da14cebeSEric Cheng switch (option) { 5271da14cebeSEric Cheng case 't': 5272da14cebeSEric Cheng flags &= ~DLADM_OPT_PERSIST; 5273da14cebeSEric Cheng break; 5274da14cebeSEric Cheng case 'R': 5275da14cebeSEric Cheng altroot = optarg; 5276da14cebeSEric Cheng break; 5277da14cebeSEric Cheng default: 5278da14cebeSEric Cheng die_opterr(optopt, option, use); 5279da14cebeSEric Cheng } 5280da14cebeSEric Cheng } 5281da14cebeSEric Cheng 5282da14cebeSEric Cheng /* the etherstub id is the required operand */ 5283da14cebeSEric Cheng if (optind != (argc - 1)) 5284da14cebeSEric Cheng usage(); 5285da14cebeSEric Cheng 5286da14cebeSEric Cheng if (strlcpy(name, argv[optind], MAXLINKNAMELEN) >= MAXLINKNAMELEN) 5287da14cebeSEric Cheng die("link name too long '%s'", argv[optind]); 5288da14cebeSEric Cheng 5289da14cebeSEric Cheng if (!dladm_valid_linkname(name)) 5290da14cebeSEric Cheng die("invalid link name '%s'", argv[optind]); 5291da14cebeSEric Cheng 5292da14cebeSEric Cheng if (altroot != NULL) 5293da14cebeSEric Cheng altroot_cmd(altroot, argc, argv); 5294da14cebeSEric Cheng 52954ac67f02SAnurag S. Maskey status = dladm_vnic_create(handle, name, DATALINK_INVALID_LINKID, 52961cb875aeSCathy Zhou VNIC_MAC_ADDR_TYPE_AUTO, mac_addr, ETHERADDRL, NULL, 0, 0, 52971cb875aeSCathy Zhou VRRP_VRID_NONE, AF_UNSPEC, NULL, NULL, flags); 5298da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 5299da14cebeSEric Cheng die_dlerr(status, "etherstub creation failed"); 5300da14cebeSEric Cheng } 5301da14cebeSEric Cheng 5302da14cebeSEric Cheng static void 5303da14cebeSEric Cheng do_delete_etherstub(int argc, char *argv[], const char *use) 5304da14cebeSEric Cheng { 5305da14cebeSEric Cheng do_delete_vnic_common(argc, argv, use, B_TRUE); 5306da14cebeSEric Cheng } 5307da14cebeSEric Cheng 5308da14cebeSEric Cheng /* ARGSUSED */ 5309da14cebeSEric Cheng static void 5310da14cebeSEric Cheng do_show_etherstub(int argc, char *argv[], const char *use) 5311da14cebeSEric Cheng { 5312da14cebeSEric Cheng do_show_vnic_common(argc, argv, use, B_TRUE); 5313da14cebeSEric Cheng } 5314da14cebeSEric Cheng 5315b509e89bSRishi Srivatsavai /* ARGSUSED */ 5316b509e89bSRishi Srivatsavai static void 5317b509e89bSRishi Srivatsavai do_up_simnet(int argc, char *argv[], const char *use) 5318b509e89bSRishi Srivatsavai { 5319b509e89bSRishi Srivatsavai (void) dladm_simnet_up(handle, DATALINK_ALL_LINKID, 0); 5320b509e89bSRishi Srivatsavai } 5321b509e89bSRishi Srivatsavai 5322b509e89bSRishi Srivatsavai static void 5323b509e89bSRishi Srivatsavai do_create_simnet(int argc, char *argv[], const char *use) 5324b509e89bSRishi Srivatsavai { 5325b509e89bSRishi Srivatsavai uint32_t flags; 5326b509e89bSRishi Srivatsavai char *altroot = NULL; 5327b509e89bSRishi Srivatsavai char *media = NULL; 5328b509e89bSRishi Srivatsavai uint32_t mtype = DL_ETHER; 5329b509e89bSRishi Srivatsavai int option; 5330b509e89bSRishi Srivatsavai dladm_status_t status; 5331b509e89bSRishi Srivatsavai char name[MAXLINKNAMELEN]; 5332b509e89bSRishi Srivatsavai 5333b509e89bSRishi Srivatsavai name[0] = '\0'; 5334b509e89bSRishi Srivatsavai flags = DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST; 5335b509e89bSRishi Srivatsavai 5336b509e89bSRishi Srivatsavai opterr = 0; 5337b509e89bSRishi Srivatsavai while ((option = getopt_long(argc, argv, ":tR:m:", 5338b509e89bSRishi Srivatsavai simnet_lopts, NULL)) != -1) { 5339b509e89bSRishi Srivatsavai switch (option) { 5340b509e89bSRishi Srivatsavai case 't': 5341b509e89bSRishi Srivatsavai flags &= ~DLADM_OPT_PERSIST; 5342b509e89bSRishi Srivatsavai break; 5343b509e89bSRishi Srivatsavai case 'R': 5344b509e89bSRishi Srivatsavai altroot = optarg; 5345b509e89bSRishi Srivatsavai break; 5346b509e89bSRishi Srivatsavai case 'm': 5347b509e89bSRishi Srivatsavai media = optarg; 5348b509e89bSRishi Srivatsavai break; 5349b509e89bSRishi Srivatsavai default: 5350b509e89bSRishi Srivatsavai die_opterr(optopt, option, use); 5351b509e89bSRishi Srivatsavai } 5352b509e89bSRishi Srivatsavai } 5353b509e89bSRishi Srivatsavai 5354b509e89bSRishi Srivatsavai /* the simnet id is the required operand */ 5355b509e89bSRishi Srivatsavai if (optind != (argc - 1)) 5356b509e89bSRishi Srivatsavai usage(); 5357b509e89bSRishi Srivatsavai 5358b509e89bSRishi Srivatsavai if (strlcpy(name, argv[optind], MAXLINKNAMELEN) >= MAXLINKNAMELEN) 5359b509e89bSRishi Srivatsavai die("link name too long '%s'", argv[optind]); 5360b509e89bSRishi Srivatsavai 5361b509e89bSRishi Srivatsavai if (!dladm_valid_linkname(name)) 5362b509e89bSRishi Srivatsavai die("invalid link name '%s'", name); 5363b509e89bSRishi Srivatsavai 5364b509e89bSRishi Srivatsavai if (media != NULL) { 5365b509e89bSRishi Srivatsavai mtype = dladm_str2media(media); 5366b509e89bSRishi Srivatsavai if (mtype != DL_ETHER && mtype != DL_WIFI) 5367b509e89bSRishi Srivatsavai die("media type '%s' is not supported", media); 5368b509e89bSRishi Srivatsavai } 5369b509e89bSRishi Srivatsavai 5370b509e89bSRishi Srivatsavai if (altroot != NULL) 5371b509e89bSRishi Srivatsavai altroot_cmd(altroot, argc, argv); 5372b509e89bSRishi Srivatsavai 5373b509e89bSRishi Srivatsavai status = dladm_simnet_create(handle, name, mtype, flags); 5374b509e89bSRishi Srivatsavai if (status != DLADM_STATUS_OK) 5375b509e89bSRishi Srivatsavai die_dlerr(status, "simnet creation failed"); 5376b509e89bSRishi Srivatsavai } 5377b509e89bSRishi Srivatsavai 5378b509e89bSRishi Srivatsavai static void 5379b509e89bSRishi Srivatsavai do_delete_simnet(int argc, char *argv[], const char *use) 5380b509e89bSRishi Srivatsavai { 5381b509e89bSRishi Srivatsavai int option; 5382b509e89bSRishi Srivatsavai uint32_t flags = DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST; 5383b509e89bSRishi Srivatsavai datalink_id_t linkid; 5384b509e89bSRishi Srivatsavai char *altroot = NULL; 5385b509e89bSRishi Srivatsavai dladm_status_t status; 5386b509e89bSRishi Srivatsavai dladm_simnet_attr_t slinfo; 5387b509e89bSRishi Srivatsavai 5388b509e89bSRishi Srivatsavai opterr = 0; 5389b509e89bSRishi Srivatsavai while ((option = getopt_long(argc, argv, ":tR:", simnet_lopts, 5390b509e89bSRishi Srivatsavai NULL)) != -1) { 5391b509e89bSRishi Srivatsavai switch (option) { 5392b509e89bSRishi Srivatsavai case 't': 5393b509e89bSRishi Srivatsavai flags &= ~DLADM_OPT_PERSIST; 5394b509e89bSRishi Srivatsavai break; 5395b509e89bSRishi Srivatsavai case 'R': 5396b509e89bSRishi Srivatsavai altroot = optarg; 5397b509e89bSRishi Srivatsavai break; 5398b509e89bSRishi Srivatsavai default: 5399b509e89bSRishi Srivatsavai die_opterr(optopt, option, use); 5400b509e89bSRishi Srivatsavai } 5401b509e89bSRishi Srivatsavai } 5402b509e89bSRishi Srivatsavai 5403b509e89bSRishi Srivatsavai /* get simnet name (required last argument) */ 5404b509e89bSRishi Srivatsavai if (optind != (argc - 1)) 5405b509e89bSRishi Srivatsavai usage(); 5406b509e89bSRishi Srivatsavai 5407b509e89bSRishi Srivatsavai if (!dladm_valid_linkname(argv[optind])) 5408b509e89bSRishi Srivatsavai die("invalid link name '%s'", argv[optind]); 5409b509e89bSRishi Srivatsavai 5410b509e89bSRishi Srivatsavai if (altroot != NULL) 5411b509e89bSRishi Srivatsavai altroot_cmd(altroot, argc, argv); 5412b509e89bSRishi Srivatsavai 5413b509e89bSRishi Srivatsavai status = dladm_name2info(handle, argv[optind], &linkid, NULL, NULL, 5414b509e89bSRishi Srivatsavai NULL); 5415b509e89bSRishi Srivatsavai if (status != DLADM_STATUS_OK) 5416b509e89bSRishi Srivatsavai die("simnet '%s' not found", argv[optind]); 5417b509e89bSRishi Srivatsavai 5418b509e89bSRishi Srivatsavai if ((status = dladm_simnet_info(handle, linkid, &slinfo, 5419b509e89bSRishi Srivatsavai flags)) != DLADM_STATUS_OK) 5420b509e89bSRishi Srivatsavai die_dlerr(status, "failed to retrieve simnet information"); 5421b509e89bSRishi Srivatsavai 5422b509e89bSRishi Srivatsavai status = dladm_simnet_delete(handle, linkid, flags); 5423b509e89bSRishi Srivatsavai if (status != DLADM_STATUS_OK) 5424b509e89bSRishi Srivatsavai die_dlerr(status, "simnet deletion failed"); 5425b509e89bSRishi Srivatsavai } 5426b509e89bSRishi Srivatsavai 5427b509e89bSRishi Srivatsavai static void 5428b509e89bSRishi Srivatsavai do_modify_simnet(int argc, char *argv[], const char *use) 5429b509e89bSRishi Srivatsavai { 5430b509e89bSRishi Srivatsavai int option; 5431b509e89bSRishi Srivatsavai uint32_t flags = DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST; 5432b509e89bSRishi Srivatsavai datalink_id_t linkid; 5433b509e89bSRishi Srivatsavai datalink_id_t peer_linkid; 5434b509e89bSRishi Srivatsavai char *altroot = NULL; 5435b509e89bSRishi Srivatsavai dladm_status_t status; 5436b509e89bSRishi Srivatsavai boolean_t p_arg = B_FALSE; 5437b509e89bSRishi Srivatsavai 5438b509e89bSRishi Srivatsavai opterr = 0; 5439b509e89bSRishi Srivatsavai while ((option = getopt_long(argc, argv, ":tR:p:", simnet_lopts, 5440b509e89bSRishi Srivatsavai NULL)) != -1) { 5441b509e89bSRishi Srivatsavai switch (option) { 5442b509e89bSRishi Srivatsavai case 't': 5443b509e89bSRishi Srivatsavai flags &= ~DLADM_OPT_PERSIST; 5444b509e89bSRishi Srivatsavai break; 5445b509e89bSRishi Srivatsavai case 'R': 5446b509e89bSRishi Srivatsavai altroot = optarg; 5447b509e89bSRishi Srivatsavai break; 5448b509e89bSRishi Srivatsavai case 'p': 5449b509e89bSRishi Srivatsavai if (p_arg) 5450b509e89bSRishi Srivatsavai die_optdup(option); 5451b509e89bSRishi Srivatsavai p_arg = B_TRUE; 5452b509e89bSRishi Srivatsavai if (strcasecmp(optarg, "none") == 0) 5453b509e89bSRishi Srivatsavai peer_linkid = DATALINK_INVALID_LINKID; 5454b509e89bSRishi Srivatsavai else if (dladm_name2info(handle, optarg, &peer_linkid, 5455b509e89bSRishi Srivatsavai NULL, NULL, NULL) != DLADM_STATUS_OK) 5456b509e89bSRishi Srivatsavai die("invalid peer link name '%s'", optarg); 5457b509e89bSRishi Srivatsavai break; 5458b509e89bSRishi Srivatsavai default: 5459b509e89bSRishi Srivatsavai die_opterr(optopt, option, use); 5460b509e89bSRishi Srivatsavai } 5461b509e89bSRishi Srivatsavai } 5462b509e89bSRishi Srivatsavai 5463b509e89bSRishi Srivatsavai /* get simnet name (required last argument) */ 5464b509e89bSRishi Srivatsavai if (optind != (argc - 1)) 5465b509e89bSRishi Srivatsavai usage(); 5466b509e89bSRishi Srivatsavai 5467b509e89bSRishi Srivatsavai /* Nothing to do if no peer link argument */ 5468b509e89bSRishi Srivatsavai if (!p_arg) 5469b509e89bSRishi Srivatsavai return; 5470b509e89bSRishi Srivatsavai 5471b509e89bSRishi Srivatsavai if (altroot != NULL) 5472b509e89bSRishi Srivatsavai altroot_cmd(altroot, argc, argv); 5473b509e89bSRishi Srivatsavai 5474b509e89bSRishi Srivatsavai status = dladm_name2info(handle, argv[optind], &linkid, NULL, NULL, 5475b509e89bSRishi Srivatsavai NULL); 5476b509e89bSRishi Srivatsavai if (status != DLADM_STATUS_OK) 5477b509e89bSRishi Srivatsavai die("invalid link name '%s'", argv[optind]); 5478b509e89bSRishi Srivatsavai 5479b509e89bSRishi Srivatsavai status = dladm_simnet_modify(handle, linkid, peer_linkid, flags); 5480b509e89bSRishi Srivatsavai if (status != DLADM_STATUS_OK) 5481b509e89bSRishi Srivatsavai die_dlerr(status, "simnet modification failed"); 5482b509e89bSRishi Srivatsavai } 5483b509e89bSRishi Srivatsavai 5484b509e89bSRishi Srivatsavai static dladm_status_t 5485b509e89bSRishi Srivatsavai print_simnet(show_state_t *state, datalink_id_t linkid) 5486b509e89bSRishi Srivatsavai { 5487b509e89bSRishi Srivatsavai dladm_simnet_attr_t slinfo; 5488b509e89bSRishi Srivatsavai uint32_t flags; 5489b509e89bSRishi Srivatsavai dladm_status_t status; 5490b509e89bSRishi Srivatsavai simnet_fields_buf_t slbuf; 5491b509e89bSRishi Srivatsavai char mstr[ETHERADDRL * 3]; 5492b509e89bSRishi Srivatsavai 5493b509e89bSRishi Srivatsavai bzero(&slbuf, sizeof (slbuf)); 5494b509e89bSRishi Srivatsavai if ((status = dladm_datalink_id2info(handle, linkid, &flags, NULL, NULL, 5495b509e89bSRishi Srivatsavai slbuf.simnet_name, sizeof (slbuf.simnet_name))) 5496b509e89bSRishi Srivatsavai != DLADM_STATUS_OK) 5497b509e89bSRishi Srivatsavai return (status); 5498b509e89bSRishi Srivatsavai 5499b509e89bSRishi Srivatsavai if (!(state->ls_flags & flags)) 5500b509e89bSRishi Srivatsavai return (DLADM_STATUS_NOTFOUND); 5501b509e89bSRishi Srivatsavai 5502b509e89bSRishi Srivatsavai if ((status = dladm_simnet_info(handle, linkid, &slinfo, 5503b509e89bSRishi Srivatsavai state->ls_flags)) != DLADM_STATUS_OK) 5504b509e89bSRishi Srivatsavai return (status); 5505b509e89bSRishi Srivatsavai 5506b509e89bSRishi Srivatsavai if (slinfo.sna_peer_link_id != DATALINK_INVALID_LINKID && 5507b509e89bSRishi Srivatsavai (status = dladm_datalink_id2info(handle, slinfo.sna_peer_link_id, 5508b509e89bSRishi Srivatsavai NULL, NULL, NULL, slbuf.simnet_otherlink, 5509b509e89bSRishi Srivatsavai sizeof (slbuf.simnet_otherlink))) != 5510b509e89bSRishi Srivatsavai DLADM_STATUS_OK) 5511b509e89bSRishi Srivatsavai return (status); 5512b509e89bSRishi Srivatsavai 5513b509e89bSRishi Srivatsavai if (slinfo.sna_mac_len > sizeof (slbuf.simnet_macaddr)) 5514b509e89bSRishi Srivatsavai return (DLADM_STATUS_BADVAL); 5515b509e89bSRishi Srivatsavai 5516b509e89bSRishi Srivatsavai (void) strlcpy(slbuf.simnet_macaddr, 5517b509e89bSRishi Srivatsavai dladm_aggr_macaddr2str(slinfo.sna_mac_addr, mstr), 5518b509e89bSRishi Srivatsavai sizeof (slbuf.simnet_macaddr)); 5519b509e89bSRishi Srivatsavai (void) dladm_media2str(slinfo.sna_type, slbuf.simnet_media); 5520b509e89bSRishi Srivatsavai 5521b509e89bSRishi Srivatsavai ofmt_print(state->ls_ofmt, &slbuf); 5522b509e89bSRishi Srivatsavai return (status); 5523b509e89bSRishi Srivatsavai } 5524b509e89bSRishi Srivatsavai 5525b509e89bSRishi Srivatsavai /* ARGSUSED */ 5526b509e89bSRishi Srivatsavai static int 5527b509e89bSRishi Srivatsavai show_simnet(dladm_handle_t dh, datalink_id_t linkid, void *arg) 5528b509e89bSRishi Srivatsavai { 5529b509e89bSRishi Srivatsavai show_state_t *state = arg; 5530b509e89bSRishi Srivatsavai 5531b509e89bSRishi Srivatsavai state->ls_status = print_simnet(state, linkid); 5532b509e89bSRishi Srivatsavai return (DLADM_WALK_CONTINUE); 5533b509e89bSRishi Srivatsavai } 5534b509e89bSRishi Srivatsavai 5535b509e89bSRishi Srivatsavai static void 5536b509e89bSRishi Srivatsavai do_show_simnet(int argc, char *argv[], const char *use) 5537b509e89bSRishi Srivatsavai { 5538b509e89bSRishi Srivatsavai int option; 5539b509e89bSRishi Srivatsavai uint32_t flags = DLADM_OPT_ACTIVE; 5540b509e89bSRishi Srivatsavai boolean_t p_arg = B_FALSE; 5541b509e89bSRishi Srivatsavai datalink_id_t linkid = DATALINK_ALL_LINKID; 5542b509e89bSRishi Srivatsavai show_state_t state; 5543b509e89bSRishi Srivatsavai dladm_status_t status; 5544b509e89bSRishi Srivatsavai boolean_t o_arg = B_FALSE; 5545b509e89bSRishi Srivatsavai ofmt_handle_t ofmt; 5546b509e89bSRishi Srivatsavai ofmt_status_t oferr; 5547b509e89bSRishi Srivatsavai char *all_fields = "link,media,macaddress,otherlink"; 5548b509e89bSRishi Srivatsavai char *fields_str = all_fields; 5549b509e89bSRishi Srivatsavai uint_t ofmtflags = 0; 5550b509e89bSRishi Srivatsavai 5551b509e89bSRishi Srivatsavai bzero(&state, sizeof (state)); 5552b509e89bSRishi Srivatsavai 5553b509e89bSRishi Srivatsavai opterr = 0; 5554b509e89bSRishi Srivatsavai while ((option = getopt_long(argc, argv, ":pPo:", 5555b509e89bSRishi Srivatsavai show_lopts, NULL)) != -1) { 5556b509e89bSRishi Srivatsavai switch (option) { 5557b509e89bSRishi Srivatsavai case 'p': 5558b509e89bSRishi Srivatsavai if (p_arg) 5559b509e89bSRishi Srivatsavai die_optdup(option); 5560b509e89bSRishi Srivatsavai 5561b509e89bSRishi Srivatsavai p_arg = B_TRUE; 5562b509e89bSRishi Srivatsavai state.ls_parsable = p_arg; 5563b509e89bSRishi Srivatsavai break; 5564b509e89bSRishi Srivatsavai case 'P': 5565b509e89bSRishi Srivatsavai if (flags != DLADM_OPT_ACTIVE) 5566b509e89bSRishi Srivatsavai die_optdup(option); 5567b509e89bSRishi Srivatsavai 5568b509e89bSRishi Srivatsavai flags = DLADM_OPT_PERSIST; 5569b509e89bSRishi Srivatsavai break; 5570b509e89bSRishi Srivatsavai case 'o': 5571b509e89bSRishi Srivatsavai o_arg = B_TRUE; 5572b509e89bSRishi Srivatsavai fields_str = optarg; 5573b509e89bSRishi Srivatsavai break; 5574b509e89bSRishi Srivatsavai default: 5575b509e89bSRishi Srivatsavai die_opterr(optopt, option, use); 5576b509e89bSRishi Srivatsavai break; 5577b509e89bSRishi Srivatsavai } 5578b509e89bSRishi Srivatsavai } 5579b509e89bSRishi Srivatsavai 5580b509e89bSRishi Srivatsavai if (p_arg && !o_arg) 5581b509e89bSRishi Srivatsavai die("-p requires -o"); 5582b509e89bSRishi Srivatsavai 5583b509e89bSRishi Srivatsavai if (strcasecmp(fields_str, "all") == 0) { 5584b509e89bSRishi Srivatsavai if (p_arg) 5585b509e89bSRishi Srivatsavai die("\"-o all\" is invalid with -p"); 5586b509e89bSRishi Srivatsavai fields_str = all_fields; 5587b509e89bSRishi Srivatsavai } 5588b509e89bSRishi Srivatsavai 5589b509e89bSRishi Srivatsavai /* get link name (optional last argument) */ 5590b509e89bSRishi Srivatsavai if (optind == (argc-1)) { 5591b509e89bSRishi Srivatsavai if ((status = dladm_name2info(handle, argv[optind], &linkid, 5592b509e89bSRishi Srivatsavai NULL, NULL, NULL)) != DLADM_STATUS_OK) { 5593b509e89bSRishi Srivatsavai die_dlerr(status, "link %s is not valid", argv[optind]); 5594b509e89bSRishi Srivatsavai } 5595b509e89bSRishi Srivatsavai } else if (optind != argc) { 5596b509e89bSRishi Srivatsavai usage(); 5597b509e89bSRishi Srivatsavai } 5598b509e89bSRishi Srivatsavai 5599b509e89bSRishi Srivatsavai state.ls_flags = flags; 5600b509e89bSRishi Srivatsavai state.ls_donefirst = B_FALSE; 5601b509e89bSRishi Srivatsavai if (state.ls_parsable) 5602b509e89bSRishi Srivatsavai ofmtflags |= OFMT_PARSABLE; 5603b509e89bSRishi Srivatsavai oferr = ofmt_open(fields_str, simnet_fields, ofmtflags, 0, &ofmt); 5604b509e89bSRishi Srivatsavai dladm_ofmt_check(oferr, state.ls_parsable, ofmt); 5605b509e89bSRishi Srivatsavai state.ls_ofmt = ofmt; 5606b509e89bSRishi Srivatsavai 5607b509e89bSRishi Srivatsavai if (linkid == DATALINK_ALL_LINKID) { 5608b509e89bSRishi Srivatsavai (void) dladm_walk_datalink_id(show_simnet, handle, &state, 5609b509e89bSRishi Srivatsavai DATALINK_CLASS_SIMNET, DATALINK_ANY_MEDIATYPE, flags); 5610b509e89bSRishi Srivatsavai } else { 5611b509e89bSRishi Srivatsavai (void) show_simnet(handle, linkid, &state); 5612b509e89bSRishi Srivatsavai if (state.ls_status != DLADM_STATUS_OK) { 5613b509e89bSRishi Srivatsavai ofmt_close(ofmt); 5614b509e89bSRishi Srivatsavai die_dlerr(state.ls_status, "failed to show simnet %s", 5615b509e89bSRishi Srivatsavai argv[optind]); 5616b509e89bSRishi Srivatsavai } 5617b509e89bSRishi Srivatsavai } 5618b509e89bSRishi Srivatsavai ofmt_close(ofmt); 5619b509e89bSRishi Srivatsavai } 5620b509e89bSRishi Srivatsavai 5621da14cebeSEric Cheng static void 56226be03d0bSVasumathi Sundaram - Sun Microsystems link_stats(datalink_id_t linkid, uint_t interval, char *fields_str, 56236be03d0bSVasumathi Sundaram - Sun Microsystems show_state_t *state) 5624d62bc4baSyz147064 { 56258002d411SSowmini Varadhan ofmt_handle_t ofmt; 56268002d411SSowmini Varadhan ofmt_status_t oferr; 56278002d411SSowmini Varadhan uint_t ofmtflags = 0; 562833343a97Smeem 56298002d411SSowmini Varadhan if (state->ls_parsable) 56308002d411SSowmini Varadhan ofmtflags |= OFMT_PARSABLE; 56318002d411SSowmini Varadhan oferr = ofmt_open(fields_str, link_s_fields, ofmtflags, 0, &ofmt); 56328002d411SSowmini Varadhan dladm_ofmt_check(oferr, state->ls_parsable, ofmt); 56338002d411SSowmini Varadhan state->ls_ofmt = ofmt; 56347c478bd9Sstevel@tonic-gate 56357c478bd9Sstevel@tonic-gate /* 56367c478bd9Sstevel@tonic-gate * If an interval is specified, continuously show the stats 56377c478bd9Sstevel@tonic-gate * only for the first MAC port. 56387c478bd9Sstevel@tonic-gate */ 56396be03d0bSVasumathi Sundaram - Sun Microsystems state->ls_firstonly = (interval != 0); 56407c478bd9Sstevel@tonic-gate 56417c478bd9Sstevel@tonic-gate for (;;) { 56426be03d0bSVasumathi Sundaram - Sun Microsystems state->ls_donefirst = B_FALSE; 5643d62bc4baSyz147064 if (linkid == DATALINK_ALL_LINKID) { 56444ac67f02SAnurag S. Maskey (void) dladm_walk_datalink_id(show_link_stats, handle, 56454ac67f02SAnurag S. Maskey state, DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE, 5646d62bc4baSyz147064 DLADM_OPT_ACTIVE); 5647d62bc4baSyz147064 } else { 56484ac67f02SAnurag S. Maskey (void) show_link_stats(handle, linkid, state); 5649d62bc4baSyz147064 } 56507c478bd9Sstevel@tonic-gate 56517c478bd9Sstevel@tonic-gate if (interval == 0) 56527c478bd9Sstevel@tonic-gate break; 56537c478bd9Sstevel@tonic-gate 5654c3affd82SMichael Lim (void) fflush(stdout); 56557c478bd9Sstevel@tonic-gate (void) sleep(interval); 56567c478bd9Sstevel@tonic-gate } 56578002d411SSowmini Varadhan ofmt_close(ofmt); 56587c478bd9Sstevel@tonic-gate } 56597c478bd9Sstevel@tonic-gate 56607c478bd9Sstevel@tonic-gate static void 5661d62bc4baSyz147064 aggr_stats(datalink_id_t linkid, show_grp_state_t *state, uint_t interval) 56627c478bd9Sstevel@tonic-gate { 56637c478bd9Sstevel@tonic-gate /* 56647c478bd9Sstevel@tonic-gate * If an interval is specified, continuously show the stats 56657c478bd9Sstevel@tonic-gate * only for the first group. 56667c478bd9Sstevel@tonic-gate */ 5667d62bc4baSyz147064 state->gs_firstonly = (interval != 0); 56687c478bd9Sstevel@tonic-gate 56697c478bd9Sstevel@tonic-gate for (;;) { 5670d62bc4baSyz147064 state->gs_donefirst = B_FALSE; 5671d62bc4baSyz147064 if (linkid == DATALINK_ALL_LINKID) 56724ac67f02SAnurag S. Maskey (void) dladm_walk_datalink_id(show_aggr, handle, state, 5673d62bc4baSyz147064 DATALINK_CLASS_AGGR, DATALINK_ANY_MEDIATYPE, 5674d62bc4baSyz147064 DLADM_OPT_ACTIVE); 5675d62bc4baSyz147064 else 56764ac67f02SAnurag S. Maskey (void) show_aggr(handle, linkid, state); 56777c478bd9Sstevel@tonic-gate 56787c478bd9Sstevel@tonic-gate if (interval == 0) 56797c478bd9Sstevel@tonic-gate break; 56807c478bd9Sstevel@tonic-gate 5681c3affd82SMichael Lim (void) fflush(stdout); 56827c478bd9Sstevel@tonic-gate (void) sleep(interval); 56837c478bd9Sstevel@tonic-gate } 56847c478bd9Sstevel@tonic-gate } 56857c478bd9Sstevel@tonic-gate 5686da14cebeSEric Cheng /* ARGSUSED */ 56877c478bd9Sstevel@tonic-gate static void 5688da14cebeSEric Cheng vnic_stats(show_vnic_state_t *sp, uint32_t interval) 56897c478bd9Sstevel@tonic-gate { 5690da14cebeSEric Cheng show_vnic_state_t state; 5691da14cebeSEric Cheng boolean_t specific_link, specific_dev; 56927c478bd9Sstevel@tonic-gate 5693da14cebeSEric Cheng /* Display vnic statistics */ 5694da14cebeSEric Cheng dump_vnics_head(sp->vs_link); 5695e7801d59Ssowmini 5696da14cebeSEric Cheng bzero(&state, sizeof (state)); 5697da14cebeSEric Cheng state.vs_stats = B_TRUE; 5698da14cebeSEric Cheng state.vs_vnic_id = sp->vs_vnic_id; 5699da14cebeSEric Cheng state.vs_link_id = sp->vs_link_id; 57007c478bd9Sstevel@tonic-gate 57017c478bd9Sstevel@tonic-gate /* 5702da14cebeSEric Cheng * If an interval is specified, and a vnic ID is not specified, 5703da14cebeSEric Cheng * continuously show the stats only for the first vnic. 57047c478bd9Sstevel@tonic-gate */ 5705da14cebeSEric Cheng specific_link = (sp->vs_vnic_id != DATALINK_ALL_LINKID); 5706da14cebeSEric Cheng specific_dev = (sp->vs_link_id != DATALINK_ALL_LINKID); 57077c478bd9Sstevel@tonic-gate 57087c478bd9Sstevel@tonic-gate for (;;) { 5709da14cebeSEric Cheng /* Get stats for each vnic */ 5710da14cebeSEric Cheng state.vs_found = B_FALSE; 5711da14cebeSEric Cheng state.vs_donefirst = B_FALSE; 5712da14cebeSEric Cheng state.vs_printstats = B_FALSE; 5713da14cebeSEric Cheng state.vs_flags = DLADM_OPT_ACTIVE; 57147c478bd9Sstevel@tonic-gate 5715da14cebeSEric Cheng if (!specific_link) { 57164ac67f02SAnurag S. Maskey (void) dladm_walk_datalink_id(show_vnic, handle, &state, 5717da14cebeSEric Cheng DATALINK_CLASS_VNIC, DATALINK_ANY_MEDIATYPE, 5718da14cebeSEric Cheng DLADM_OPT_ACTIVE); 5719da14cebeSEric Cheng } else { 57204ac67f02SAnurag S. Maskey (void) show_vnic(handle, sp->vs_vnic_id, &state); 5721da14cebeSEric Cheng if (state.vs_status != DLADM_STATUS_OK) { 5722da14cebeSEric Cheng die_dlerr(state.vs_status, 5723da14cebeSEric Cheng "failed to show vnic '%s'", sp->vs_vnic); 5724da14cebeSEric Cheng } 5725da14cebeSEric Cheng } 57267c478bd9Sstevel@tonic-gate 5727da14cebeSEric Cheng if (specific_link && !state.vs_found) 5728da14cebeSEric Cheng die("non-existent vnic '%s'", sp->vs_vnic); 5729da14cebeSEric Cheng if (specific_dev && !state.vs_found) 5730da14cebeSEric Cheng die("device %s has no vnics", sp->vs_link); 5731da14cebeSEric Cheng 5732da14cebeSEric Cheng /* Show totals */ 5733da14cebeSEric Cheng if ((specific_link | specific_dev) && !interval) { 5734da14cebeSEric Cheng (void) printf("Total"); 5735da14cebeSEric Cheng (void) printf("\t%-10llu", 5736da14cebeSEric Cheng state.vs_totalstats.ipackets); 5737da14cebeSEric Cheng (void) printf("%-12llu", 5738da14cebeSEric Cheng state.vs_totalstats.rbytes); 5739da14cebeSEric Cheng (void) printf("%-10llu", 5740da14cebeSEric Cheng state.vs_totalstats.opackets); 5741da14cebeSEric Cheng (void) printf("%-12llu\n", 5742da14cebeSEric Cheng state.vs_totalstats.obytes); 5743da14cebeSEric Cheng } 5744da14cebeSEric Cheng 5745da14cebeSEric Cheng /* Show stats for each vnic */ 5746da14cebeSEric Cheng state.vs_donefirst = B_FALSE; 5747da14cebeSEric Cheng state.vs_printstats = B_TRUE; 5748da14cebeSEric Cheng 5749da14cebeSEric Cheng if (!specific_link) { 57504ac67f02SAnurag S. Maskey (void) dladm_walk_datalink_id(show_vnic, handle, &state, 5751da14cebeSEric Cheng DATALINK_CLASS_VNIC, DATALINK_ANY_MEDIATYPE, 5752da14cebeSEric Cheng DLADM_OPT_ACTIVE); 5753da14cebeSEric Cheng } else { 57544ac67f02SAnurag S. Maskey (void) show_vnic(handle, sp->vs_vnic_id, &state); 5755da14cebeSEric Cheng if (state.vs_status != DLADM_STATUS_OK) { 5756da14cebeSEric Cheng die_dlerr(state.vs_status, 5757da14cebeSEric Cheng "failed to show vnic '%s'", sp->vs_vnic); 5758da14cebeSEric Cheng } 5759da14cebeSEric Cheng } 57607c478bd9Sstevel@tonic-gate 57617c478bd9Sstevel@tonic-gate if (interval == 0) 57627c478bd9Sstevel@tonic-gate break; 57637c478bd9Sstevel@tonic-gate 5764c3affd82SMichael Lim (void) fflush(stdout); 57657c478bd9Sstevel@tonic-gate (void) sleep(interval); 57667c478bd9Sstevel@tonic-gate } 57677c478bd9Sstevel@tonic-gate } 57687c478bd9Sstevel@tonic-gate 57697c478bd9Sstevel@tonic-gate static void 5770da14cebeSEric Cheng get_mac_stats(const char *dev, pktsum_t *stats) 57717c478bd9Sstevel@tonic-gate { 57727c478bd9Sstevel@tonic-gate kstat_ctl_t *kcp; 57737c478bd9Sstevel@tonic-gate kstat_t *ksp; 5774da14cebeSEric Cheng char module[DLPI_LINKNAME_MAX]; 5775da14cebeSEric Cheng uint_t instance; 5776da14cebeSEric Cheng 5777da14cebeSEric Cheng 5778da14cebeSEric Cheng bzero(stats, sizeof (*stats)); 5779da14cebeSEric Cheng 5780da14cebeSEric Cheng if (dlpi_parselink(dev, module, &instance) != DLPI_SUCCESS) 5781da14cebeSEric Cheng return; 57827c478bd9Sstevel@tonic-gate 57837c478bd9Sstevel@tonic-gate if ((kcp = kstat_open()) == NULL) { 578433343a97Smeem warn("kstat open operation failed"); 57857c478bd9Sstevel@tonic-gate return; 57867c478bd9Sstevel@tonic-gate } 57877c478bd9Sstevel@tonic-gate 5788da14cebeSEric Cheng ksp = dladm_kstat_lookup(kcp, module, instance, "mac", NULL); 5789da14cebeSEric Cheng if (ksp != NULL) 5790da14cebeSEric Cheng dladm_get_stats(kcp, ksp, stats); 5791da14cebeSEric Cheng 57927c478bd9Sstevel@tonic-gate (void) kstat_close(kcp); 57937c478bd9Sstevel@tonic-gate 57947c478bd9Sstevel@tonic-gate } 57957c478bd9Sstevel@tonic-gate 57967c478bd9Sstevel@tonic-gate static void 57977c478bd9Sstevel@tonic-gate get_link_stats(const char *link, pktsum_t *stats) 57987c478bd9Sstevel@tonic-gate { 5799da14cebeSEric Cheng kstat_ctl_t *kcp; 5800da14cebeSEric Cheng kstat_t *ksp; 5801da14cebeSEric Cheng 58027c478bd9Sstevel@tonic-gate bzero(stats, sizeof (*stats)); 5803da14cebeSEric Cheng 5804da14cebeSEric Cheng if ((kcp = kstat_open()) == NULL) { 5805da14cebeSEric Cheng warn("kstat_open operation failed"); 5806da14cebeSEric Cheng return; 5807da14cebeSEric Cheng } 5808da14cebeSEric Cheng 5809da14cebeSEric Cheng ksp = dladm_kstat_lookup(kcp, "link", 0, link, NULL); 5810da14cebeSEric Cheng 5811da14cebeSEric Cheng if (ksp != NULL) 5812da14cebeSEric Cheng dladm_get_stats(kcp, ksp, stats); 5813da14cebeSEric Cheng 5814da14cebeSEric Cheng (void) kstat_close(kcp); 58157c478bd9Sstevel@tonic-gate } 58167c478bd9Sstevel@tonic-gate 5817ba2e4443Sseb static int 5818d62bc4baSyz147064 query_kstat(char *module, int instance, const char *name, const char *stat, 5819d62bc4baSyz147064 uint8_t type, void *val) 58207c478bd9Sstevel@tonic-gate { 58217c478bd9Sstevel@tonic-gate kstat_ctl_t *kcp; 58227c478bd9Sstevel@tonic-gate kstat_t *ksp; 58237c478bd9Sstevel@tonic-gate 58247c478bd9Sstevel@tonic-gate if ((kcp = kstat_open()) == NULL) { 582533343a97Smeem warn("kstat open operation failed"); 5826ba2e4443Sseb return (-1); 58277c478bd9Sstevel@tonic-gate } 58287c478bd9Sstevel@tonic-gate 5829d62bc4baSyz147064 if ((ksp = kstat_lookup(kcp, module, instance, (char *)name)) == NULL) { 58307c478bd9Sstevel@tonic-gate /* 58317c478bd9Sstevel@tonic-gate * The kstat query could fail if the underlying MAC 58327c478bd9Sstevel@tonic-gate * driver was already detached. 58337c478bd9Sstevel@tonic-gate */ 58347c478bd9Sstevel@tonic-gate goto bail; 58357c478bd9Sstevel@tonic-gate } 58367c478bd9Sstevel@tonic-gate 58377c478bd9Sstevel@tonic-gate if (kstat_read(kcp, ksp, NULL) == -1) { 583833343a97Smeem warn("kstat read failed"); 58397c478bd9Sstevel@tonic-gate goto bail; 58407c478bd9Sstevel@tonic-gate } 58417c478bd9Sstevel@tonic-gate 5842e7801d59Ssowmini if (dladm_kstat_value(ksp, stat, type, val) < 0) 58437c478bd9Sstevel@tonic-gate goto bail; 5844ba2e4443Sseb 5845ba2e4443Sseb (void) kstat_close(kcp); 5846ba2e4443Sseb return (0); 58477c478bd9Sstevel@tonic-gate 58487c478bd9Sstevel@tonic-gate bail: 58497c478bd9Sstevel@tonic-gate (void) kstat_close(kcp); 5850ba2e4443Sseb return (-1); 5851ba2e4443Sseb } 5852ba2e4443Sseb 5853d62bc4baSyz147064 static int 5854d62bc4baSyz147064 get_one_kstat(const char *name, const char *stat, uint8_t type, 5855d62bc4baSyz147064 void *val, boolean_t islink) 5856d62bc4baSyz147064 { 5857d62bc4baSyz147064 char module[DLPI_LINKNAME_MAX]; 5858d62bc4baSyz147064 uint_t instance; 5859d62bc4baSyz147064 5860d62bc4baSyz147064 if (islink) { 5861d62bc4baSyz147064 return (query_kstat("link", 0, name, stat, type, val)); 5862d62bc4baSyz147064 } else { 5863d62bc4baSyz147064 if (dlpi_parselink(name, module, &instance) != DLPI_SUCCESS) 5864d62bc4baSyz147064 return (-1); 5865d62bc4baSyz147064 5866d62bc4baSyz147064 return (query_kstat(module, instance, "mac", stat, type, val)); 5867d62bc4baSyz147064 } 5868d62bc4baSyz147064 } 5869d62bc4baSyz147064 5870ba2e4443Sseb static uint64_t 5871d62bc4baSyz147064 get_ifspeed(const char *name, boolean_t islink) 5872ba2e4443Sseb { 5873ba2e4443Sseb uint64_t ifspeed = 0; 5874ba2e4443Sseb 5875d62bc4baSyz147064 (void) get_one_kstat(name, "ifspeed", KSTAT_DATA_UINT64, 5876d62bc4baSyz147064 &ifspeed, islink); 5877d62bc4baSyz147064 58787c478bd9Sstevel@tonic-gate return (ifspeed); 58797c478bd9Sstevel@tonic-gate } 58807c478bd9Sstevel@tonic-gate 5881f595a68aSyz147064 static const char * 5882d62bc4baSyz147064 get_linkstate(const char *name, boolean_t islink, char *buf) 58837c478bd9Sstevel@tonic-gate { 5884d62bc4baSyz147064 link_state_t linkstate; 58857c478bd9Sstevel@tonic-gate 5886d62bc4baSyz147064 if (get_one_kstat(name, "link_state", KSTAT_DATA_UINT32, 5887d62bc4baSyz147064 &linkstate, islink) != 0) { 5888da14cebeSEric Cheng (void) strlcpy(buf, "?", DLADM_STRSIZE); 58893a62633bSyz147064 return (buf); 58907c478bd9Sstevel@tonic-gate } 5891d62bc4baSyz147064 return (dladm_linkstate2str(linkstate, buf)); 58927c478bd9Sstevel@tonic-gate } 58937c478bd9Sstevel@tonic-gate 5894f595a68aSyz147064 static const char * 5895d62bc4baSyz147064 get_linkduplex(const char *name, boolean_t islink, char *buf) 58967c478bd9Sstevel@tonic-gate { 5897d62bc4baSyz147064 link_duplex_t linkduplex; 58987c478bd9Sstevel@tonic-gate 5899d62bc4baSyz147064 if (get_one_kstat(name, "link_duplex", KSTAT_DATA_UINT32, 5900d62bc4baSyz147064 &linkduplex, islink) != 0) { 59013a62633bSyz147064 (void) strlcpy(buf, "unknown", DLADM_STRSIZE); 59023a62633bSyz147064 return (buf); 59037c478bd9Sstevel@tonic-gate } 59047c478bd9Sstevel@tonic-gate 5905d62bc4baSyz147064 return (dladm_linkduplex2str(linkduplex, buf)); 59067c478bd9Sstevel@tonic-gate } 59070ba2cbe9Sxc151355 59080ba2cbe9Sxc151355 static int 59098002d411SSowmini Varadhan parse_wifi_fields(char *str, ofmt_handle_t *ofmt, uint_t cmdtype, 59108002d411SSowmini Varadhan boolean_t parsable) 59110ba2cbe9Sxc151355 { 59128002d411SSowmini Varadhan ofmt_field_t *template, *of; 59138002d411SSowmini Varadhan ofmt_cb_t *fn; 59148002d411SSowmini Varadhan ofmt_status_t oferr; 59150ba2cbe9Sxc151355 59160ba2cbe9Sxc151355 if (cmdtype == WIFI_CMD_SCAN) { 59178002d411SSowmini Varadhan template = wifi_common_fields; 59180ba2cbe9Sxc151355 if (str == NULL) 59190ba2cbe9Sxc151355 str = def_scan_wifi_fields; 59200ba2cbe9Sxc151355 if (strcasecmp(str, "all") == 0) 59210ba2cbe9Sxc151355 str = all_scan_wifi_fields; 59228002d411SSowmini Varadhan fn = print_wlan_attr_cb; 59230ba2cbe9Sxc151355 } else if (cmdtype == WIFI_CMD_SHOW) { 59248002d411SSowmini Varadhan bcopy(wifi_common_fields, &wifi_show_fields[2], 59258002d411SSowmini Varadhan sizeof (wifi_common_fields)); 59268002d411SSowmini Varadhan template = wifi_show_fields; 59270ba2cbe9Sxc151355 if (str == NULL) 59280ba2cbe9Sxc151355 str = def_show_wifi_fields; 59290ba2cbe9Sxc151355 if (strcasecmp(str, "all") == 0) 59300ba2cbe9Sxc151355 str = all_show_wifi_fields; 59318002d411SSowmini Varadhan fn = print_link_attr_cb; 59320ba2cbe9Sxc151355 } else { 59330ba2cbe9Sxc151355 return (-1); 59340ba2cbe9Sxc151355 } 59358002d411SSowmini Varadhan 59368002d411SSowmini Varadhan for (of = template; of->of_name != NULL; of++) { 59378002d411SSowmini Varadhan if (of->of_cb == NULL) 59388002d411SSowmini Varadhan of->of_cb = fn; 59398002d411SSowmini Varadhan } 59408002d411SSowmini Varadhan 59418002d411SSowmini Varadhan oferr = ofmt_open(str, template, (parsable ? OFMT_PARSABLE : 0), 59428002d411SSowmini Varadhan 0, ofmt); 59438002d411SSowmini Varadhan dladm_ofmt_check(oferr, parsable, *ofmt); 5944e7801d59Ssowmini return (0); 59450ba2cbe9Sxc151355 } 59460ba2cbe9Sxc151355 59470ba2cbe9Sxc151355 typedef struct print_wifi_state { 5948d62bc4baSyz147064 char *ws_link; 59498002d411SSowmini Varadhan boolean_t ws_parsable; 59500ba2cbe9Sxc151355 boolean_t ws_header; 59518002d411SSowmini Varadhan ofmt_handle_t ws_ofmt; 59520ba2cbe9Sxc151355 } print_wifi_state_t; 59530ba2cbe9Sxc151355 5954e7801d59Ssowmini typedef struct wlan_scan_args_s { 5955e7801d59Ssowmini print_wifi_state_t *ws_state; 5956e7801d59Ssowmini void *ws_attr; 5957e7801d59Ssowmini } wlan_scan_args_t; 59580ba2cbe9Sxc151355 59598002d411SSowmini Varadhan static boolean_t 59608002d411SSowmini Varadhan print_wlan_attr_cb(ofmt_arg_t *ofarg, char *buf, uint_t bufsize) 59610ba2cbe9Sxc151355 { 59628002d411SSowmini Varadhan wlan_scan_args_t *w = ofarg->ofmt_cbarg; 5963e7801d59Ssowmini print_wifi_state_t *statep = w->ws_state; 5964e7801d59Ssowmini dladm_wlan_attr_t *attrp = w->ws_attr; 59658002d411SSowmini Varadhan char tmpbuf[DLADM_STRSIZE]; 59660ba2cbe9Sxc151355 59678002d411SSowmini Varadhan if (ofarg->ofmt_id == 0) { 59688002d411SSowmini Varadhan (void) strlcpy(buf, (char *)statep->ws_link, bufsize); 59698002d411SSowmini Varadhan return (B_TRUE); 59700ba2cbe9Sxc151355 } 59710ba2cbe9Sxc151355 59728002d411SSowmini Varadhan if ((ofarg->ofmt_id & attrp->wa_valid) == 0) 59738002d411SSowmini Varadhan return (B_TRUE); 59740ba2cbe9Sxc151355 59758002d411SSowmini Varadhan switch (ofarg->ofmt_id) { 5976f595a68aSyz147064 case DLADM_WLAN_ATTR_ESSID: 59778002d411SSowmini Varadhan (void) dladm_wlan_essid2str(&attrp->wa_essid, tmpbuf); 59780ba2cbe9Sxc151355 break; 5979f595a68aSyz147064 case DLADM_WLAN_ATTR_BSSID: 59808002d411SSowmini Varadhan (void) dladm_wlan_bssid2str(&attrp->wa_bssid, tmpbuf); 59810ba2cbe9Sxc151355 break; 5982f595a68aSyz147064 case DLADM_WLAN_ATTR_SECMODE: 59838002d411SSowmini Varadhan (void) dladm_wlan_secmode2str(&attrp->wa_secmode, tmpbuf); 59840ba2cbe9Sxc151355 break; 5985f595a68aSyz147064 case DLADM_WLAN_ATTR_STRENGTH: 59868002d411SSowmini Varadhan (void) dladm_wlan_strength2str(&attrp->wa_strength, tmpbuf); 59870ba2cbe9Sxc151355 break; 5988f595a68aSyz147064 case DLADM_WLAN_ATTR_MODE: 59898002d411SSowmini Varadhan (void) dladm_wlan_mode2str(&attrp->wa_mode, tmpbuf); 59900ba2cbe9Sxc151355 break; 5991f595a68aSyz147064 case DLADM_WLAN_ATTR_SPEED: 59928002d411SSowmini Varadhan (void) dladm_wlan_speed2str(&attrp->wa_speed, tmpbuf); 59938002d411SSowmini Varadhan (void) strlcat(tmpbuf, "Mb", sizeof (tmpbuf)); 59940ba2cbe9Sxc151355 break; 5995f595a68aSyz147064 case DLADM_WLAN_ATTR_AUTH: 59968002d411SSowmini Varadhan (void) dladm_wlan_auth2str(&attrp->wa_auth, tmpbuf); 59970ba2cbe9Sxc151355 break; 5998f595a68aSyz147064 case DLADM_WLAN_ATTR_BSSTYPE: 59998002d411SSowmini Varadhan (void) dladm_wlan_bsstype2str(&attrp->wa_bsstype, tmpbuf); 60000ba2cbe9Sxc151355 break; 60010ba2cbe9Sxc151355 } 60028002d411SSowmini Varadhan (void) strlcpy(buf, tmpbuf, bufsize); 60030ba2cbe9Sxc151355 60048002d411SSowmini Varadhan return (B_TRUE); 60050ba2cbe9Sxc151355 } 60060ba2cbe9Sxc151355 60070ba2cbe9Sxc151355 static boolean_t 6008f595a68aSyz147064 print_scan_results(void *arg, dladm_wlan_attr_t *attrp) 60090ba2cbe9Sxc151355 { 60100ba2cbe9Sxc151355 print_wifi_state_t *statep = arg; 6011e7801d59Ssowmini wlan_scan_args_t warg; 60120ba2cbe9Sxc151355 6013e7801d59Ssowmini bzero(&warg, sizeof (warg)); 6014e7801d59Ssowmini warg.ws_state = statep; 6015e7801d59Ssowmini warg.ws_attr = attrp; 60168002d411SSowmini Varadhan ofmt_print(statep->ws_ofmt, &warg); 60170ba2cbe9Sxc151355 return (B_TRUE); 60180ba2cbe9Sxc151355 } 60190ba2cbe9Sxc151355 6020d62bc4baSyz147064 static int 60214ac67f02SAnurag S. Maskey scan_wifi(dladm_handle_t dh, datalink_id_t linkid, void *arg) 60220ba2cbe9Sxc151355 { 60230ba2cbe9Sxc151355 print_wifi_state_t *statep = arg; 6024f595a68aSyz147064 dladm_status_t status; 6025d62bc4baSyz147064 char link[MAXLINKNAMELEN]; 6026d62bc4baSyz147064 60274ac67f02SAnurag S. Maskey if ((status = dladm_datalink_id2info(dh, linkid, NULL, NULL, NULL, link, 6028e7801d59Ssowmini sizeof (link))) != DLADM_STATUS_OK) { 6029d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 6030d62bc4baSyz147064 } 60310ba2cbe9Sxc151355 60320ba2cbe9Sxc151355 statep->ws_link = link; 60334ac67f02SAnurag S. Maskey status = dladm_wlan_scan(dh, linkid, statep, print_scan_results); 6034f595a68aSyz147064 if (status != DLADM_STATUS_OK) 6035d62bc4baSyz147064 die_dlerr(status, "cannot scan link '%s'", statep->ws_link); 603633343a97Smeem 6037d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 60380ba2cbe9Sxc151355 } 60390ba2cbe9Sxc151355 60408002d411SSowmini Varadhan static boolean_t 60418002d411SSowmini Varadhan print_wifi_status_cb(ofmt_arg_t *ofarg, char *buf, uint_t bufsize) 60420ba2cbe9Sxc151355 { 60438002d411SSowmini Varadhan static char tmpbuf[DLADM_STRSIZE]; 60448002d411SSowmini Varadhan wlan_scan_args_t *w = ofarg->ofmt_cbarg; 60458002d411SSowmini Varadhan dladm_wlan_linkattr_t *attrp = w->ws_attr; 60468002d411SSowmini Varadhan 60478002d411SSowmini Varadhan if ((ofarg->ofmt_id & attrp->la_valid) != 0) { 60488002d411SSowmini Varadhan (void) dladm_wlan_linkstatus2str(&attrp->la_status, tmpbuf); 60498002d411SSowmini Varadhan (void) strlcpy(buf, tmpbuf, bufsize); 60508002d411SSowmini Varadhan } 60518002d411SSowmini Varadhan return (B_TRUE); 60528002d411SSowmini Varadhan } 60538002d411SSowmini Varadhan 60548002d411SSowmini Varadhan static boolean_t 60558002d411SSowmini Varadhan print_link_attr_cb(ofmt_arg_t *ofarg, char *buf, uint_t bufsize) 60568002d411SSowmini Varadhan { 60578002d411SSowmini Varadhan wlan_scan_args_t *w = ofarg->ofmt_cbarg, w1; 6058e7801d59Ssowmini print_wifi_state_t *statep = w->ws_state; 6059e7801d59Ssowmini dladm_wlan_linkattr_t *attrp = w->ws_attr; 60600ba2cbe9Sxc151355 6061e7801d59Ssowmini bzero(&w1, sizeof (w1)); 6062e7801d59Ssowmini w1.ws_state = statep; 6063e7801d59Ssowmini w1.ws_attr = &attrp->la_wlan_attr; 60648002d411SSowmini Varadhan ofarg->ofmt_cbarg = &w1; 60658002d411SSowmini Varadhan return (print_wlan_attr_cb(ofarg, buf, bufsize)); 60660ba2cbe9Sxc151355 } 60670ba2cbe9Sxc151355 6068d62bc4baSyz147064 static int 60694ac67f02SAnurag S. Maskey show_wifi(dladm_handle_t dh, datalink_id_t linkid, void *arg) 60700ba2cbe9Sxc151355 { 60710ba2cbe9Sxc151355 print_wifi_state_t *statep = arg; 6072f595a68aSyz147064 dladm_wlan_linkattr_t attr; 6073f595a68aSyz147064 dladm_status_t status; 6074d62bc4baSyz147064 char link[MAXLINKNAMELEN]; 6075e7801d59Ssowmini wlan_scan_args_t warg; 60760ba2cbe9Sxc151355 60774ac67f02SAnurag S. Maskey if ((status = dladm_datalink_id2info(dh, linkid, NULL, NULL, NULL, link, 6078e7801d59Ssowmini sizeof (link))) != DLADM_STATUS_OK) { 6079d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 6080d62bc4baSyz147064 } 6081d62bc4baSyz147064 60825f5c9f54SAnurag S. Maskey /* dladm_wlan_get_linkattr() memsets attr with 0 */ 60834ac67f02SAnurag S. Maskey status = dladm_wlan_get_linkattr(dh, linkid, &attr); 6084f595a68aSyz147064 if (status != DLADM_STATUS_OK) 6085d62bc4baSyz147064 die_dlerr(status, "cannot get link attributes for %s", link); 6086d62bc4baSyz147064 6087d62bc4baSyz147064 statep->ws_link = link; 60880ba2cbe9Sxc151355 6089e7801d59Ssowmini bzero(&warg, sizeof (warg)); 6090e7801d59Ssowmini warg.ws_state = statep; 6091e7801d59Ssowmini warg.ws_attr = &attr; 60928002d411SSowmini Varadhan ofmt_print(statep->ws_ofmt, &warg); 6093d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 60940ba2cbe9Sxc151355 } 60950ba2cbe9Sxc151355 60960ba2cbe9Sxc151355 static void 60978d5c46e6Sam223141 do_display_wifi(int argc, char **argv, int cmd, const char *use) 60980ba2cbe9Sxc151355 { 60990ba2cbe9Sxc151355 int option; 61000ba2cbe9Sxc151355 char *fields_str = NULL; 61014ac67f02SAnurag S. Maskey int (*callback)(dladm_handle_t, datalink_id_t, void *); 61020ba2cbe9Sxc151355 print_wifi_state_t state; 6103d62bc4baSyz147064 datalink_id_t linkid = DATALINK_ALL_LINKID; 6104f595a68aSyz147064 dladm_status_t status; 61050ba2cbe9Sxc151355 61060ba2cbe9Sxc151355 if (cmd == WIFI_CMD_SCAN) 61070ba2cbe9Sxc151355 callback = scan_wifi; 61080ba2cbe9Sxc151355 else if (cmd == WIFI_CMD_SHOW) 61090ba2cbe9Sxc151355 callback = show_wifi; 61100ba2cbe9Sxc151355 else 61110ba2cbe9Sxc151355 return; 61120ba2cbe9Sxc151355 61138002d411SSowmini Varadhan state.ws_parsable = B_FALSE; 61140ba2cbe9Sxc151355 state.ws_header = B_TRUE; 61150ba2cbe9Sxc151355 opterr = 0; 61160ba2cbe9Sxc151355 while ((option = getopt_long(argc, argv, ":o:p", 61170ba2cbe9Sxc151355 wifi_longopts, NULL)) != -1) { 61180ba2cbe9Sxc151355 switch (option) { 61190ba2cbe9Sxc151355 case 'o': 61200ba2cbe9Sxc151355 fields_str = optarg; 61210ba2cbe9Sxc151355 break; 61220ba2cbe9Sxc151355 case 'p': 61238002d411SSowmini Varadhan state.ws_parsable = B_TRUE; 61240ba2cbe9Sxc151355 break; 61250ba2cbe9Sxc151355 default: 61268d5c46e6Sam223141 die_opterr(optopt, option, use); 61270ba2cbe9Sxc151355 } 61280ba2cbe9Sxc151355 } 61290ba2cbe9Sxc151355 61308002d411SSowmini Varadhan if (state.ws_parsable && fields_str == NULL) 61310d365605Sschuster die("-p requires -o"); 61320d365605Sschuster 61338002d411SSowmini Varadhan if (state.ws_parsable && strcasecmp(fields_str, "all") == 0) 61340d365605Sschuster die("\"-o all\" is invalid with -p"); 61350d365605Sschuster 6136d62bc4baSyz147064 if (optind == (argc - 1)) { 61374ac67f02SAnurag S. Maskey if ((status = dladm_name2info(handle, argv[optind], &linkid, 61384ac67f02SAnurag S. Maskey NULL, NULL, NULL)) != DLADM_STATUS_OK) { 6139d62bc4baSyz147064 die_dlerr(status, "link %s is not valid", argv[optind]); 6140d62bc4baSyz147064 } 6141d62bc4baSyz147064 } else if (optind != argc) { 61420ba2cbe9Sxc151355 usage(); 6143d62bc4baSyz147064 } 61440ba2cbe9Sxc151355 61458002d411SSowmini Varadhan if (parse_wifi_fields(fields_str, &state.ws_ofmt, cmd, 61468002d411SSowmini Varadhan state.ws_parsable) < 0) 614733343a97Smeem die("invalid field(s) specified"); 614833343a97Smeem 6149d62bc4baSyz147064 if (linkid == DATALINK_ALL_LINKID) { 61504ac67f02SAnurag S. Maskey (void) dladm_walk_datalink_id(callback, handle, &state, 6151b509e89bSRishi Srivatsavai DATALINK_CLASS_PHYS | DATALINK_CLASS_SIMNET, 6152b509e89bSRishi Srivatsavai DL_WIFI, DLADM_OPT_ACTIVE); 61530ba2cbe9Sxc151355 } else { 61544ac67f02SAnurag S. Maskey (void) (*callback)(handle, linkid, &state); 61550ba2cbe9Sxc151355 } 61568002d411SSowmini Varadhan ofmt_close(state.ws_ofmt); 61570ba2cbe9Sxc151355 } 61580ba2cbe9Sxc151355 61590ba2cbe9Sxc151355 static void 61608d5c46e6Sam223141 do_scan_wifi(int argc, char **argv, const char *use) 61610ba2cbe9Sxc151355 { 61628d5c46e6Sam223141 do_display_wifi(argc, argv, WIFI_CMD_SCAN, use); 61630ba2cbe9Sxc151355 } 61640ba2cbe9Sxc151355 61650ba2cbe9Sxc151355 static void 61668d5c46e6Sam223141 do_show_wifi(int argc, char **argv, const char *use) 61670ba2cbe9Sxc151355 { 61688d5c46e6Sam223141 do_display_wifi(argc, argv, WIFI_CMD_SHOW, use); 61690ba2cbe9Sxc151355 } 61700ba2cbe9Sxc151355 61710ba2cbe9Sxc151355 typedef struct wlan_count_attr { 61720ba2cbe9Sxc151355 uint_t wc_count; 6173d62bc4baSyz147064 datalink_id_t wc_linkid; 61740ba2cbe9Sxc151355 } wlan_count_attr_t; 61750ba2cbe9Sxc151355 61764ac67f02SAnurag S. Maskey /* ARGSUSED */ 6177d62bc4baSyz147064 static int 61784ac67f02SAnurag S. Maskey do_count_wlan(dladm_handle_t dh, datalink_id_t linkid, void *arg) 61790ba2cbe9Sxc151355 { 618033343a97Smeem wlan_count_attr_t *cp = arg; 61810ba2cbe9Sxc151355 61820ba2cbe9Sxc151355 if (cp->wc_count == 0) 6183d62bc4baSyz147064 cp->wc_linkid = linkid; 61840ba2cbe9Sxc151355 cp->wc_count++; 6185d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 61860ba2cbe9Sxc151355 } 61870ba2cbe9Sxc151355 61880ba2cbe9Sxc151355 static int 6189a399b765Szf162725 parse_wlan_keys(char *str, dladm_wlan_key_t **keys, uint_t *key_countp) 61900ba2cbe9Sxc151355 { 61910ba2cbe9Sxc151355 uint_t i; 6192a399b765Szf162725 dladm_wlan_key_t *wk; 61938002d411SSowmini Varadhan int nfields = 1; 61948002d411SSowmini Varadhan char *field, *token, *lasts = NULL, c; 61950ba2cbe9Sxc151355 61968002d411SSowmini Varadhan token = str; 61978002d411SSowmini Varadhan while ((c = *token++) != NULL) { 61988002d411SSowmini Varadhan if (c == ',') 61998002d411SSowmini Varadhan nfields++; 62008002d411SSowmini Varadhan } 62018002d411SSowmini Varadhan token = strdup(str); 62028002d411SSowmini Varadhan if (token == NULL) 62030ba2cbe9Sxc151355 return (-1); 62040ba2cbe9Sxc151355 62058002d411SSowmini Varadhan wk = malloc(nfields * sizeof (dladm_wlan_key_t)); 62060ba2cbe9Sxc151355 if (wk == NULL) 62070ba2cbe9Sxc151355 goto fail; 62080ba2cbe9Sxc151355 62098002d411SSowmini Varadhan token = str; 62108002d411SSowmini Varadhan for (i = 0; i < nfields; i++) { 62110ba2cbe9Sxc151355 char *s; 62120ba2cbe9Sxc151355 dladm_secobj_class_t class; 62130ba2cbe9Sxc151355 dladm_status_t status; 62140ba2cbe9Sxc151355 62158002d411SSowmini Varadhan field = strtok_r(token, ",", &lasts); 62168002d411SSowmini Varadhan token = NULL; 62178002d411SSowmini Varadhan 62188002d411SSowmini Varadhan (void) strlcpy(wk[i].wk_name, field, 6219a399b765Szf162725 DLADM_WLAN_MAX_KEYNAME_LEN); 62200ba2cbe9Sxc151355 62210ba2cbe9Sxc151355 wk[i].wk_idx = 1; 62220ba2cbe9Sxc151355 if ((s = strrchr(wk[i].wk_name, ':')) != NULL) { 62230ba2cbe9Sxc151355 if (s[1] == '\0' || s[2] != '\0' || !isdigit(s[1])) 62240ba2cbe9Sxc151355 goto fail; 62250ba2cbe9Sxc151355 62260ba2cbe9Sxc151355 wk[i].wk_idx = (uint_t)(s[1] - '0'); 62270ba2cbe9Sxc151355 *s = '\0'; 62280ba2cbe9Sxc151355 } 6229a399b765Szf162725 wk[i].wk_len = DLADM_WLAN_MAX_KEY_LEN; 62300ba2cbe9Sxc151355 62314ac67f02SAnurag S. Maskey status = dladm_get_secobj(handle, wk[i].wk_name, &class, 62320ba2cbe9Sxc151355 wk[i].wk_val, &wk[i].wk_len, 0); 62330ba2cbe9Sxc151355 if (status != DLADM_STATUS_OK) { 62340ba2cbe9Sxc151355 if (status == DLADM_STATUS_NOTFOUND) { 62354ac67f02SAnurag S. Maskey status = dladm_get_secobj(handle, wk[i].wk_name, 62360ba2cbe9Sxc151355 &class, wk[i].wk_val, &wk[i].wk_len, 62370ba2cbe9Sxc151355 DLADM_OPT_PERSIST); 62380ba2cbe9Sxc151355 } 62390ba2cbe9Sxc151355 if (status != DLADM_STATUS_OK) 62400ba2cbe9Sxc151355 goto fail; 62410ba2cbe9Sxc151355 } 6242a399b765Szf162725 wk[i].wk_class = class; 62430ba2cbe9Sxc151355 } 62440ba2cbe9Sxc151355 *keys = wk; 62450ba2cbe9Sxc151355 *key_countp = i; 62468002d411SSowmini Varadhan free(token); 62470ba2cbe9Sxc151355 return (0); 62480ba2cbe9Sxc151355 fail: 62490ba2cbe9Sxc151355 free(wk); 62508002d411SSowmini Varadhan free(token); 62510ba2cbe9Sxc151355 return (-1); 62520ba2cbe9Sxc151355 } 62530ba2cbe9Sxc151355 62540ba2cbe9Sxc151355 static void 62558d5c46e6Sam223141 do_connect_wifi(int argc, char **argv, const char *use) 62560ba2cbe9Sxc151355 { 62570ba2cbe9Sxc151355 int option; 6258f595a68aSyz147064 dladm_wlan_attr_t attr, *attrp; 6259f595a68aSyz147064 dladm_status_t status = DLADM_STATUS_OK; 6260f595a68aSyz147064 int timeout = DLADM_WLAN_CONNECT_TIMEOUT_DEFAULT; 6261d62bc4baSyz147064 datalink_id_t linkid = DATALINK_ALL_LINKID; 6262a399b765Szf162725 dladm_wlan_key_t *keys = NULL; 62630ba2cbe9Sxc151355 uint_t key_count = 0; 62640ba2cbe9Sxc151355 uint_t flags = 0; 6265f595a68aSyz147064 dladm_wlan_secmode_t keysecmode = DLADM_WLAN_SECMODE_NONE; 6266a399b765Szf162725 char buf[DLADM_STRSIZE]; 62670ba2cbe9Sxc151355 62680ba2cbe9Sxc151355 opterr = 0; 62690ba2cbe9Sxc151355 (void) memset(&attr, 0, sizeof (attr)); 62700ba2cbe9Sxc151355 while ((option = getopt_long(argc, argv, ":e:i:a:m:b:s:k:T:c", 62710ba2cbe9Sxc151355 wifi_longopts, NULL)) != -1) { 62720ba2cbe9Sxc151355 switch (option) { 62730ba2cbe9Sxc151355 case 'e': 6274f595a68aSyz147064 status = dladm_wlan_str2essid(optarg, &attr.wa_essid); 6275f595a68aSyz147064 if (status != DLADM_STATUS_OK) 627633343a97Smeem die("invalid ESSID '%s'", optarg); 627733343a97Smeem 6278f595a68aSyz147064 attr.wa_valid |= DLADM_WLAN_ATTR_ESSID; 62790ba2cbe9Sxc151355 /* 62800ba2cbe9Sxc151355 * Try to connect without doing a scan. 62810ba2cbe9Sxc151355 */ 6282f595a68aSyz147064 flags |= DLADM_WLAN_CONNECT_NOSCAN; 62830ba2cbe9Sxc151355 break; 62840ba2cbe9Sxc151355 case 'i': 6285f595a68aSyz147064 status = dladm_wlan_str2bssid(optarg, &attr.wa_bssid); 6286f595a68aSyz147064 if (status != DLADM_STATUS_OK) 628733343a97Smeem die("invalid BSSID %s", optarg); 628833343a97Smeem 6289f595a68aSyz147064 attr.wa_valid |= DLADM_WLAN_ATTR_BSSID; 62900ba2cbe9Sxc151355 break; 62910ba2cbe9Sxc151355 case 'a': 6292f595a68aSyz147064 status = dladm_wlan_str2auth(optarg, &attr.wa_auth); 6293f595a68aSyz147064 if (status != DLADM_STATUS_OK) 629433343a97Smeem die("invalid authentication mode '%s'", optarg); 629533343a97Smeem 6296f595a68aSyz147064 attr.wa_valid |= DLADM_WLAN_ATTR_AUTH; 62970ba2cbe9Sxc151355 break; 62980ba2cbe9Sxc151355 case 'm': 6299f595a68aSyz147064 status = dladm_wlan_str2mode(optarg, &attr.wa_mode); 6300f595a68aSyz147064 if (status != DLADM_STATUS_OK) 630133343a97Smeem die("invalid mode '%s'", optarg); 630233343a97Smeem 6303f595a68aSyz147064 attr.wa_valid |= DLADM_WLAN_ATTR_MODE; 63040ba2cbe9Sxc151355 break; 63050ba2cbe9Sxc151355 case 'b': 6306f595a68aSyz147064 if ((status = dladm_wlan_str2bsstype(optarg, 6307f595a68aSyz147064 &attr.wa_bsstype)) != DLADM_STATUS_OK) { 630833343a97Smeem die("invalid bsstype '%s'", optarg); 6309f595a68aSyz147064 } 631033343a97Smeem 6311f595a68aSyz147064 attr.wa_valid |= DLADM_WLAN_ATTR_BSSTYPE; 63120ba2cbe9Sxc151355 break; 63130ba2cbe9Sxc151355 case 's': 6314f595a68aSyz147064 if ((status = dladm_wlan_str2secmode(optarg, 6315f595a68aSyz147064 &attr.wa_secmode)) != DLADM_STATUS_OK) { 631633343a97Smeem die("invalid security mode '%s'", optarg); 6317f595a68aSyz147064 } 631833343a97Smeem 6319f595a68aSyz147064 attr.wa_valid |= DLADM_WLAN_ATTR_SECMODE; 63200ba2cbe9Sxc151355 break; 63210ba2cbe9Sxc151355 case 'k': 6322a399b765Szf162725 if (parse_wlan_keys(optarg, &keys, &key_count) < 0) 632333343a97Smeem die("invalid key(s) '%s'", optarg); 632433343a97Smeem 6325a399b765Szf162725 if (keys[0].wk_class == DLADM_SECOBJ_CLASS_WEP) 6326f595a68aSyz147064 keysecmode = DLADM_WLAN_SECMODE_WEP; 6327a399b765Szf162725 else 6328a399b765Szf162725 keysecmode = DLADM_WLAN_SECMODE_WPA; 63290ba2cbe9Sxc151355 break; 63300ba2cbe9Sxc151355 case 'T': 63310ba2cbe9Sxc151355 if (strcasecmp(optarg, "forever") == 0) { 63320ba2cbe9Sxc151355 timeout = -1; 63330ba2cbe9Sxc151355 break; 63340ba2cbe9Sxc151355 } 633533343a97Smeem if (!str2int(optarg, &timeout) || timeout < 0) 633633343a97Smeem die("invalid timeout value '%s'", optarg); 63370ba2cbe9Sxc151355 break; 63380ba2cbe9Sxc151355 case 'c': 6339f595a68aSyz147064 flags |= DLADM_WLAN_CONNECT_CREATEIBSS; 6340a399b765Szf162725 flags |= DLADM_WLAN_CONNECT_CREATEIBSS; 63410ba2cbe9Sxc151355 break; 63420ba2cbe9Sxc151355 default: 63438d5c46e6Sam223141 die_opterr(optopt, option, use); 63440ba2cbe9Sxc151355 break; 63450ba2cbe9Sxc151355 } 63460ba2cbe9Sxc151355 } 63470ba2cbe9Sxc151355 6348f595a68aSyz147064 if (keysecmode == DLADM_WLAN_SECMODE_NONE) { 6349a399b765Szf162725 if ((attr.wa_valid & DLADM_WLAN_ATTR_SECMODE) != 0) { 6350a399b765Szf162725 die("key required for security mode '%s'", 6351a399b765Szf162725 dladm_wlan_secmode2str(&attr.wa_secmode, buf)); 6352a399b765Szf162725 } 63530ba2cbe9Sxc151355 } else { 6354f595a68aSyz147064 if ((attr.wa_valid & DLADM_WLAN_ATTR_SECMODE) != 0 && 635533343a97Smeem attr.wa_secmode != keysecmode) 635633343a97Smeem die("incompatible -s and -k options"); 6357f595a68aSyz147064 attr.wa_valid |= DLADM_WLAN_ATTR_SECMODE; 6358a399b765Szf162725 attr.wa_secmode = keysecmode; 6359a399b765Szf162725 } 63600ba2cbe9Sxc151355 6361d62bc4baSyz147064 if (optind == (argc - 1)) { 63624ac67f02SAnurag S. Maskey if ((status = dladm_name2info(handle, argv[optind], &linkid, 63634ac67f02SAnurag S. Maskey NULL, NULL, NULL)) != DLADM_STATUS_OK) { 6364d62bc4baSyz147064 die_dlerr(status, "link %s is not valid", argv[optind]); 6365d62bc4baSyz147064 } 6366d62bc4baSyz147064 } else if (optind != argc) { 63670ba2cbe9Sxc151355 usage(); 6368d62bc4baSyz147064 } 63690ba2cbe9Sxc151355 6370d62bc4baSyz147064 if (linkid == DATALINK_ALL_LINKID) { 63710ba2cbe9Sxc151355 wlan_count_attr_t wcattr; 63720ba2cbe9Sxc151355 6373d62bc4baSyz147064 wcattr.wc_linkid = DATALINK_INVALID_LINKID; 63740ba2cbe9Sxc151355 wcattr.wc_count = 0; 63754ac67f02SAnurag S. Maskey (void) dladm_walk_datalink_id(do_count_wlan, handle, &wcattr, 6376b509e89bSRishi Srivatsavai DATALINK_CLASS_PHYS | DATALINK_CLASS_SIMNET, 6377b509e89bSRishi Srivatsavai DL_WIFI, DLADM_OPT_ACTIVE); 63780ba2cbe9Sxc151355 if (wcattr.wc_count == 0) { 637933343a97Smeem die("no wifi links are available"); 63800ba2cbe9Sxc151355 } else if (wcattr.wc_count > 1) { 638133343a97Smeem die("link name is required when more than one wifi " 638233343a97Smeem "link is available"); 63830ba2cbe9Sxc151355 } 6384d62bc4baSyz147064 linkid = wcattr.wc_linkid; 63850ba2cbe9Sxc151355 } 63860ba2cbe9Sxc151355 attrp = (attr.wa_valid == 0) ? NULL : &attr; 638733343a97Smeem again: 63884ac67f02SAnurag S. Maskey if ((status = dladm_wlan_connect(handle, linkid, attrp, timeout, keys, 6389f595a68aSyz147064 key_count, flags)) != DLADM_STATUS_OK) { 6390f595a68aSyz147064 if ((flags & DLADM_WLAN_CONNECT_NOSCAN) != 0) { 63910ba2cbe9Sxc151355 /* 639233343a97Smeem * Try again with scanning and filtering. 63930ba2cbe9Sxc151355 */ 6394f595a68aSyz147064 flags &= ~DLADM_WLAN_CONNECT_NOSCAN; 639533343a97Smeem goto again; 63960ba2cbe9Sxc151355 } 639733343a97Smeem 6398f595a68aSyz147064 if (status == DLADM_STATUS_NOTFOUND) { 63990ba2cbe9Sxc151355 if (attr.wa_valid == 0) { 640033343a97Smeem die("no wifi networks are available"); 64010ba2cbe9Sxc151355 } else { 640233343a97Smeem die("no wifi networks with the specified " 640333343a97Smeem "criteria are available"); 64040ba2cbe9Sxc151355 } 64050ba2cbe9Sxc151355 } 6406d62bc4baSyz147064 die_dlerr(status, "cannot connect"); 64070ba2cbe9Sxc151355 } 64080ba2cbe9Sxc151355 free(keys); 64090ba2cbe9Sxc151355 } 64100ba2cbe9Sxc151355 64110ba2cbe9Sxc151355 /* ARGSUSED */ 6412d62bc4baSyz147064 static int 64134ac67f02SAnurag S. Maskey do_all_disconnect_wifi(dladm_handle_t dh, datalink_id_t linkid, void *arg) 64140ba2cbe9Sxc151355 { 6415f595a68aSyz147064 dladm_status_t status; 64160ba2cbe9Sxc151355 64174ac67f02SAnurag S. Maskey status = dladm_wlan_disconnect(dh, linkid); 6418f595a68aSyz147064 if (status != DLADM_STATUS_OK) 6419d62bc4baSyz147064 warn_dlerr(status, "cannot disconnect link"); 642033343a97Smeem 6421d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 64220ba2cbe9Sxc151355 } 64230ba2cbe9Sxc151355 64240ba2cbe9Sxc151355 static void 64258d5c46e6Sam223141 do_disconnect_wifi(int argc, char **argv, const char *use) 64260ba2cbe9Sxc151355 { 64270ba2cbe9Sxc151355 int option; 6428d62bc4baSyz147064 datalink_id_t linkid = DATALINK_ALL_LINKID; 64290ba2cbe9Sxc151355 boolean_t all_links = B_FALSE; 6430f595a68aSyz147064 dladm_status_t status; 64310ba2cbe9Sxc151355 wlan_count_attr_t wcattr; 64320ba2cbe9Sxc151355 64330ba2cbe9Sxc151355 opterr = 0; 64340ba2cbe9Sxc151355 while ((option = getopt_long(argc, argv, ":a", 64350ba2cbe9Sxc151355 wifi_longopts, NULL)) != -1) { 64360ba2cbe9Sxc151355 switch (option) { 64370ba2cbe9Sxc151355 case 'a': 64380ba2cbe9Sxc151355 all_links = B_TRUE; 64390ba2cbe9Sxc151355 break; 64400ba2cbe9Sxc151355 default: 64418d5c46e6Sam223141 die_opterr(optopt, option, use); 64420ba2cbe9Sxc151355 break; 64430ba2cbe9Sxc151355 } 64440ba2cbe9Sxc151355 } 64450ba2cbe9Sxc151355 6446d62bc4baSyz147064 if (optind == (argc - 1)) { 64474ac67f02SAnurag S. Maskey if ((status = dladm_name2info(handle, argv[optind], &linkid, 64484ac67f02SAnurag S. Maskey NULL, NULL, NULL)) != DLADM_STATUS_OK) { 6449d62bc4baSyz147064 die_dlerr(status, "link %s is not valid", argv[optind]); 6450d62bc4baSyz147064 } 6451d62bc4baSyz147064 } else if (optind != argc) { 64520ba2cbe9Sxc151355 usage(); 6453d62bc4baSyz147064 } 64540ba2cbe9Sxc151355 6455d62bc4baSyz147064 if (linkid == DATALINK_ALL_LINKID) { 64560ba2cbe9Sxc151355 if (!all_links) { 6457d62bc4baSyz147064 wcattr.wc_linkid = linkid; 64580ba2cbe9Sxc151355 wcattr.wc_count = 0; 64594ac67f02SAnurag S. Maskey (void) dladm_walk_datalink_id(do_count_wlan, handle, 6460b509e89bSRishi Srivatsavai &wcattr, 6461b509e89bSRishi Srivatsavai DATALINK_CLASS_PHYS | DATALINK_CLASS_SIMNET, 6462b509e89bSRishi Srivatsavai DL_WIFI, DLADM_OPT_ACTIVE); 64630ba2cbe9Sxc151355 if (wcattr.wc_count == 0) { 646433343a97Smeem die("no wifi links are available"); 64650ba2cbe9Sxc151355 } else if (wcattr.wc_count > 1) { 646633343a97Smeem die("link name is required when more than " 646733343a97Smeem "one wifi link is available"); 64680ba2cbe9Sxc151355 } 6469d62bc4baSyz147064 linkid = wcattr.wc_linkid; 64700ba2cbe9Sxc151355 } else { 6471d62bc4baSyz147064 (void) dladm_walk_datalink_id(do_all_disconnect_wifi, 6472b509e89bSRishi Srivatsavai handle, NULL, 6473b509e89bSRishi Srivatsavai DATALINK_CLASS_PHYS | DATALINK_CLASS_SIMNET, 6474b509e89bSRishi Srivatsavai DL_WIFI, DLADM_OPT_ACTIVE); 64750ba2cbe9Sxc151355 return; 64760ba2cbe9Sxc151355 } 64770ba2cbe9Sxc151355 } 64784ac67f02SAnurag S. Maskey status = dladm_wlan_disconnect(handle, linkid); 6479f595a68aSyz147064 if (status != DLADM_STATUS_OK) 6480d62bc4baSyz147064 die_dlerr(status, "cannot disconnect"); 64810ba2cbe9Sxc151355 } 64820ba2cbe9Sxc151355 64830ba2cbe9Sxc151355 static void 6484d62bc4baSyz147064 print_linkprop(datalink_id_t linkid, show_linkprop_state_t *statep, 64854ac67f02SAnurag S. Maskey const char *propname, dladm_prop_type_t type, const char *format, 64864ac67f02SAnurag S. Maskey char **pptr) 64870ba2cbe9Sxc151355 { 64880ba2cbe9Sxc151355 int i; 64890ba2cbe9Sxc151355 char *ptr, *lim; 64900ba2cbe9Sxc151355 char buf[DLADM_STRSIZE]; 6491da14cebeSEric Cheng char *unknown = "--", *notsup = ""; 64920ba2cbe9Sxc151355 char **propvals = statep->ls_propvals; 6493d62bc4baSyz147064 uint_t valcnt = DLADM_MAX_PROP_VALCNT; 64940ba2cbe9Sxc151355 dladm_status_t status; 64950ba2cbe9Sxc151355 64964ac67f02SAnurag S. Maskey status = dladm_get_linkprop(handle, linkid, type, propname, propvals, 64974ac67f02SAnurag S. Maskey &valcnt); 64980ba2cbe9Sxc151355 if (status != DLADM_STATUS_OK) { 6499f595a68aSyz147064 if (status == DLADM_STATUS_TEMPONLY) { 6500d62bc4baSyz147064 if (type == DLADM_PROP_VAL_MODIFIABLE && 6501d62bc4baSyz147064 statep->ls_persist) { 6502d62bc4baSyz147064 valcnt = 1; 6503d62bc4baSyz147064 propvals = &unknown; 6504d62bc4baSyz147064 } else { 6505f595a68aSyz147064 statep->ls_status = status; 6506e7801d59Ssowmini statep->ls_retstatus = status; 6507f595a68aSyz147064 return; 6508d62bc4baSyz147064 } 6509f595a68aSyz147064 } else if (status == DLADM_STATUS_NOTSUP || 6510f595a68aSyz147064 statep->ls_persist) { 65110ba2cbe9Sxc151355 valcnt = 1; 6512afdda45fSVasumathi Sundaram - Sun Microsystems if (type == DLADM_PROP_VAL_CURRENT || 6513afdda45fSVasumathi Sundaram - Sun Microsystems type == DLADM_PROP_VAL_PERM) 65140ba2cbe9Sxc151355 propvals = &unknown; 65150ba2cbe9Sxc151355 else 65160ba2cbe9Sxc151355 propvals = ¬sup; 6517149b7eb2SSowmini Varadhan } else if (status == DLADM_STATUS_NOTDEFINED) { 6518149b7eb2SSowmini Varadhan propvals = ¬sup; /* STR_UNDEF_VAL */ 65190ba2cbe9Sxc151355 } else { 6520e7801d59Ssowmini if (statep->ls_proplist && 6521e7801d59Ssowmini statep->ls_status == DLADM_STATUS_OK) { 6522f595a68aSyz147064 warn_dlerr(status, 6523f595a68aSyz147064 "cannot get link property '%s' for %s", 6524f595a68aSyz147064 propname, statep->ls_link); 6525d62bc4baSyz147064 } 6526e7801d59Ssowmini statep->ls_status = status; 6527e7801d59Ssowmini statep->ls_retstatus = status; 6528f595a68aSyz147064 return; 65290ba2cbe9Sxc151355 } 65300ba2cbe9Sxc151355 } 65310ba2cbe9Sxc151355 6532e7801d59Ssowmini statep->ls_status = DLADM_STATUS_OK; 6533e7801d59Ssowmini 653425ec3e3dSEric Cheng buf[0] = '\0'; 65350ba2cbe9Sxc151355 ptr = buf; 65360ba2cbe9Sxc151355 lim = buf + DLADM_STRSIZE; 65370ba2cbe9Sxc151355 for (i = 0; i < valcnt; i++) { 65388002d411SSowmini Varadhan if (propvals[i][0] == '\0' && !statep->ls_parsable) 65398002d411SSowmini Varadhan ptr += snprintf(ptr, lim - ptr, "--,"); 65400ba2cbe9Sxc151355 else 65410ba2cbe9Sxc151355 ptr += snprintf(ptr, lim - ptr, "%s,", propvals[i]); 65420ba2cbe9Sxc151355 if (ptr >= lim) 65430ba2cbe9Sxc151355 break; 65440ba2cbe9Sxc151355 } 65450ba2cbe9Sxc151355 if (valcnt > 0) 65460ba2cbe9Sxc151355 buf[strlen(buf) - 1] = '\0'; 65470ba2cbe9Sxc151355 65480ba2cbe9Sxc151355 lim = statep->ls_line + MAX_PROP_LINE; 65498002d411SSowmini Varadhan if (statep->ls_parsable) { 65500ba2cbe9Sxc151355 *pptr += snprintf(*pptr, lim - *pptr, 6551e7801d59Ssowmini "%s", buf); 65520ba2cbe9Sxc151355 } else { 65530ba2cbe9Sxc151355 *pptr += snprintf(*pptr, lim - *pptr, format, buf); 65540ba2cbe9Sxc151355 } 65550ba2cbe9Sxc151355 } 65560ba2cbe9Sxc151355 65578002d411SSowmini Varadhan static boolean_t 65588002d411SSowmini Varadhan print_linkprop_cb(ofmt_arg_t *ofarg, char *buf, uint_t bufsize) 6559e7801d59Ssowmini { 65608002d411SSowmini Varadhan linkprop_args_t *arg = ofarg->ofmt_cbarg; 6561e7801d59Ssowmini char *propname = arg->ls_propname; 6562e7801d59Ssowmini show_linkprop_state_t *statep = arg->ls_state; 6563e7801d59Ssowmini char *ptr = statep->ls_line; 6564e7801d59Ssowmini char *lim = ptr + MAX_PROP_LINE; 6565e7801d59Ssowmini datalink_id_t linkid = arg->ls_linkid; 6566e7801d59Ssowmini 65678002d411SSowmini Varadhan switch (ofarg->ofmt_id) { 6568e7801d59Ssowmini case LINKPROP_LINK: 6569e7801d59Ssowmini (void) snprintf(ptr, lim - ptr, "%s", statep->ls_link); 6570e7801d59Ssowmini break; 6571e7801d59Ssowmini case LINKPROP_PROPERTY: 6572e7801d59Ssowmini (void) snprintf(ptr, lim - ptr, "%s", propname); 6573e7801d59Ssowmini break; 6574e7801d59Ssowmini case LINKPROP_VALUE: 6575e7801d59Ssowmini print_linkprop(linkid, statep, propname, 6576e7801d59Ssowmini statep->ls_persist ? DLADM_PROP_VAL_PERSISTENT : 6577e7801d59Ssowmini DLADM_PROP_VAL_CURRENT, "%s", &ptr); 6578e7801d59Ssowmini /* 6579e7801d59Ssowmini * If we failed to query the link property, for example, query 6580e7801d59Ssowmini * the persistent value of a non-persistable link property, 6581e7801d59Ssowmini * simply skip the output. 6582e7801d59Ssowmini */ 6583*f689bed1SRishi Srivatsavai if (statep->ls_status != DLADM_STATUS_OK) { 6584*f689bed1SRishi Srivatsavai /* 6585*f689bed1SRishi Srivatsavai * Ignore the temponly error when we skip printing 6586*f689bed1SRishi Srivatsavai * link properties to avoid returning failure on exit. 6587*f689bed1SRishi Srivatsavai */ 6588*f689bed1SRishi Srivatsavai if (statep->ls_retstatus == DLADM_STATUS_TEMPONLY) 6589*f689bed1SRishi Srivatsavai statep->ls_retstatus = DLADM_STATUS_OK; 6590e7801d59Ssowmini goto skip; 6591*f689bed1SRishi Srivatsavai } 6592e7801d59Ssowmini ptr = statep->ls_line; 6593e7801d59Ssowmini break; 6594afdda45fSVasumathi Sundaram - Sun Microsystems case LINKPROP_PERM: 6595afdda45fSVasumathi Sundaram - Sun Microsystems print_linkprop(linkid, statep, propname, 6596afdda45fSVasumathi Sundaram - Sun Microsystems DLADM_PROP_VAL_PERM, "%s", &ptr); 6597afdda45fSVasumathi Sundaram - Sun Microsystems if (statep->ls_status != DLADM_STATUS_OK) 6598afdda45fSVasumathi Sundaram - Sun Microsystems goto skip; 6599afdda45fSVasumathi Sundaram - Sun Microsystems ptr = statep->ls_line; 6600afdda45fSVasumathi Sundaram - Sun Microsystems break; 6601e7801d59Ssowmini case LINKPROP_DEFAULT: 6602e7801d59Ssowmini print_linkprop(linkid, statep, propname, 6603e7801d59Ssowmini DLADM_PROP_VAL_DEFAULT, "%s", &ptr); 6604e7801d59Ssowmini if (statep->ls_status != DLADM_STATUS_OK) 6605e7801d59Ssowmini goto skip; 6606e7801d59Ssowmini ptr = statep->ls_line; 6607e7801d59Ssowmini break; 6608e7801d59Ssowmini case LINKPROP_POSSIBLE: 6609e7801d59Ssowmini print_linkprop(linkid, statep, propname, 6610e7801d59Ssowmini DLADM_PROP_VAL_MODIFIABLE, "%s ", &ptr); 6611e7801d59Ssowmini if (statep->ls_status != DLADM_STATUS_OK) 6612e7801d59Ssowmini goto skip; 6613e7801d59Ssowmini ptr = statep->ls_line; 6614e7801d59Ssowmini break; 6615e7801d59Ssowmini default: 6616e7801d59Ssowmini die("invalid input"); 6617e7801d59Ssowmini break; 6618e7801d59Ssowmini } 66198002d411SSowmini Varadhan (void) strlcpy(buf, ptr, bufsize); 66208002d411SSowmini Varadhan return (B_TRUE); 6621e7801d59Ssowmini skip: 66228002d411SSowmini Varadhan return ((statep->ls_status == DLADM_STATUS_OK) ? 66238002d411SSowmini Varadhan B_TRUE : B_FALSE); 6624e7801d59Ssowmini } 6625e7801d59Ssowmini 6626bcb5c89dSSowmini Varadhan static boolean_t 6627bcb5c89dSSowmini Varadhan linkprop_is_supported(datalink_id_t linkid, const char *propname, 6628bcb5c89dSSowmini Varadhan show_linkprop_state_t *statep) 6629bcb5c89dSSowmini Varadhan { 6630bcb5c89dSSowmini Varadhan dladm_status_t status; 6631bcb5c89dSSowmini Varadhan uint_t valcnt = DLADM_MAX_PROP_VALCNT; 6632bcb5c89dSSowmini Varadhan 66334784fcbdSSowmini Varadhan /* if used with -p flag, always print output */ 66344784fcbdSSowmini Varadhan if (statep->ls_proplist != NULL) 66354784fcbdSSowmini Varadhan return (B_TRUE); 66364784fcbdSSowmini Varadhan 66374ac67f02SAnurag S. Maskey status = dladm_get_linkprop(handle, linkid, DLADM_PROP_VAL_DEFAULT, 6638bcb5c89dSSowmini Varadhan propname, statep->ls_propvals, &valcnt); 6639bcb5c89dSSowmini Varadhan 6640149b7eb2SSowmini Varadhan if (status == DLADM_STATUS_OK) 6641149b7eb2SSowmini Varadhan return (B_TRUE); 6642149b7eb2SSowmini Varadhan 6643149b7eb2SSowmini Varadhan /* 6644149b7eb2SSowmini Varadhan * A system wide default value is not available for the 6645149b7eb2SSowmini Varadhan * property. Check if current value can be retrieved. 6646149b7eb2SSowmini Varadhan */ 66474ac67f02SAnurag S. Maskey status = dladm_get_linkprop(handle, linkid, DLADM_PROP_VAL_CURRENT, 6648149b7eb2SSowmini Varadhan propname, statep->ls_propvals, &valcnt); 6649149b7eb2SSowmini Varadhan 6650149b7eb2SSowmini Varadhan return (status == DLADM_STATUS_OK); 6651bcb5c89dSSowmini Varadhan } 6652bcb5c89dSSowmini Varadhan 66534ac67f02SAnurag S. Maskey /* ARGSUSED */ 6654d62bc4baSyz147064 static int 66554ac67f02SAnurag S. Maskey show_linkprop(dladm_handle_t dh, datalink_id_t linkid, const char *propname, 66564ac67f02SAnurag S. Maskey void *arg) 66570ba2cbe9Sxc151355 { 66580ba2cbe9Sxc151355 show_linkprop_state_t *statep = arg; 6659e7801d59Ssowmini linkprop_args_t ls_arg; 66600ba2cbe9Sxc151355 6661e7801d59Ssowmini bzero(&ls_arg, sizeof (ls_arg)); 6662e7801d59Ssowmini ls_arg.ls_state = statep; 6663e7801d59Ssowmini ls_arg.ls_propname = (char *)propname; 6664e7801d59Ssowmini ls_arg.ls_linkid = linkid; 66650ba2cbe9Sxc151355 666662ee1d25SArtem Kachitchkine /* 666762ee1d25SArtem Kachitchkine * This will need to be fixed when kernel interfaces are added 666862ee1d25SArtem Kachitchkine * to enable walking of all known private properties. For now, 666962ee1d25SArtem Kachitchkine * we are limited to walking persistent private properties only. 667062ee1d25SArtem Kachitchkine */ 667162ee1d25SArtem Kachitchkine if ((propname[0] == '_') && !statep->ls_persist && 667262ee1d25SArtem Kachitchkine (statep->ls_proplist == NULL)) 667362ee1d25SArtem Kachitchkine return (DLADM_WALK_CONTINUE); 66748002d411SSowmini Varadhan if (!statep->ls_parsable && 6675149b7eb2SSowmini Varadhan !linkprop_is_supported(linkid, propname, statep)) 6676bcb5c89dSSowmini Varadhan return (DLADM_WALK_CONTINUE); 6677bcb5c89dSSowmini Varadhan 66788002d411SSowmini Varadhan ofmt_print(statep->ls_ofmt, &ls_arg); 6679e7801d59Ssowmini 6680d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 66810ba2cbe9Sxc151355 } 66820ba2cbe9Sxc151355 66830ba2cbe9Sxc151355 static void 66848d5c46e6Sam223141 do_show_linkprop(int argc, char **argv, const char *use) 66850ba2cbe9Sxc151355 { 6686f4b3ec61Sdh155122 int option; 668763a6526dSMichael Lim char propstr[DLADM_STRSIZE]; 6688da14cebeSEric Cheng dladm_arg_list_t *proplist = NULL; 6689d62bc4baSyz147064 datalink_id_t linkid = DATALINK_ALL_LINKID; 66900ba2cbe9Sxc151355 show_linkprop_state_t state; 6691d62bc4baSyz147064 uint32_t flags = DLADM_OPT_ACTIVE; 6692d62bc4baSyz147064 dladm_status_t status; 6693e7801d59Ssowmini char *fields_str = NULL; 66948002d411SSowmini Varadhan ofmt_handle_t ofmt; 66958002d411SSowmini Varadhan ofmt_status_t oferr; 66968002d411SSowmini Varadhan uint_t ofmtflags = 0; 66970ba2cbe9Sxc151355 669863a6526dSMichael Lim bzero(propstr, DLADM_STRSIZE); 66990ba2cbe9Sxc151355 opterr = 0; 67000ba2cbe9Sxc151355 state.ls_propvals = NULL; 67010ba2cbe9Sxc151355 state.ls_line = NULL; 67028002d411SSowmini Varadhan state.ls_parsable = B_FALSE; 67030ba2cbe9Sxc151355 state.ls_persist = B_FALSE; 67040ba2cbe9Sxc151355 state.ls_header = B_TRUE; 6705e7801d59Ssowmini state.ls_retstatus = DLADM_STATUS_OK; 670663a6526dSMichael Lim 6707e7801d59Ssowmini while ((option = getopt_long(argc, argv, ":p:cPo:", 67080ba2cbe9Sxc151355 prop_longopts, NULL)) != -1) { 67090ba2cbe9Sxc151355 switch (option) { 67100ba2cbe9Sxc151355 case 'p': 671163a6526dSMichael Lim (void) strlcat(propstr, optarg, DLADM_STRSIZE); 671263a6526dSMichael Lim if (strlcat(propstr, ",", DLADM_STRSIZE) >= 671363a6526dSMichael Lim DLADM_STRSIZE) 671463a6526dSMichael Lim die("property list too long '%s'", propstr); 67150ba2cbe9Sxc151355 break; 67160ba2cbe9Sxc151355 case 'c': 67178002d411SSowmini Varadhan state.ls_parsable = B_TRUE; 67180ba2cbe9Sxc151355 break; 67190ba2cbe9Sxc151355 case 'P': 67200ba2cbe9Sxc151355 state.ls_persist = B_TRUE; 6721d62bc4baSyz147064 flags = DLADM_OPT_PERSIST; 67220ba2cbe9Sxc151355 break; 6723e7801d59Ssowmini case 'o': 6724e7801d59Ssowmini fields_str = optarg; 6725e7801d59Ssowmini break; 67260ba2cbe9Sxc151355 default: 67278d5c46e6Sam223141 die_opterr(optopt, option, use); 67280ba2cbe9Sxc151355 break; 67290ba2cbe9Sxc151355 } 67300ba2cbe9Sxc151355 } 67310ba2cbe9Sxc151355 6732d62bc4baSyz147064 if (optind == (argc - 1)) { 67334ac67f02SAnurag S. Maskey if ((status = dladm_name2info(handle, argv[optind], &linkid, 67344ac67f02SAnurag S. Maskey NULL, NULL, NULL)) != DLADM_STATUS_OK) { 6735d62bc4baSyz147064 die_dlerr(status, "link %s is not valid", argv[optind]); 6736d62bc4baSyz147064 } 6737d62bc4baSyz147064 } else if (optind != argc) { 67380ba2cbe9Sxc151355 usage(); 6739d62bc4baSyz147064 } 67400ba2cbe9Sxc151355 674163a6526dSMichael Lim if (dladm_parse_link_props(propstr, &proplist, B_TRUE) 674263a6526dSMichael Lim != DLADM_STATUS_OK) 674363a6526dSMichael Lim die("invalid link properties specified"); 6744f4b3ec61Sdh155122 state.ls_proplist = proplist; 6745f595a68aSyz147064 state.ls_status = DLADM_STATUS_OK; 6746f4b3ec61Sdh155122 67478002d411SSowmini Varadhan if (state.ls_parsable) 67488002d411SSowmini Varadhan ofmtflags |= OFMT_PARSABLE; 674925ec3e3dSEric Cheng else 675025ec3e3dSEric Cheng ofmtflags |= OFMT_WRAP; 675125ec3e3dSEric Cheng 67528002d411SSowmini Varadhan oferr = ofmt_open(fields_str, linkprop_fields, ofmtflags, 0, &ofmt); 67538002d411SSowmini Varadhan dladm_ofmt_check(oferr, state.ls_parsable, ofmt); 67548002d411SSowmini Varadhan state.ls_ofmt = ofmt; 6755e7801d59Ssowmini 6756d62bc4baSyz147064 if (linkid == DATALINK_ALL_LINKID) { 67574ac67f02SAnurag S. Maskey (void) dladm_walk_datalink_id(show_linkprop_onelink, handle, 67584ac67f02SAnurag S. Maskey &state, DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE, flags); 6759f4b3ec61Sdh155122 } else { 67604ac67f02SAnurag S. Maskey (void) show_linkprop_onelink(handle, linkid, &state); 6761f4b3ec61Sdh155122 } 67628002d411SSowmini Varadhan ofmt_close(ofmt); 6763da14cebeSEric Cheng dladm_free_props(proplist); 6764f595a68aSyz147064 67654ac67f02SAnurag S. Maskey if (state.ls_retstatus != DLADM_STATUS_OK) { 67664ac67f02SAnurag S. Maskey dladm_close(handle); 6767f595a68aSyz147064 exit(EXIT_FAILURE); 6768f4b3ec61Sdh155122 } 67694ac67f02SAnurag S. Maskey } 6770f4b3ec61Sdh155122 6771d62bc4baSyz147064 static int 67724ac67f02SAnurag S. Maskey show_linkprop_onelink(dladm_handle_t hdl, datalink_id_t linkid, void *arg) 6773f4b3ec61Sdh155122 { 6774948f2876Sss150715 int i; 6775f4b3ec61Sdh155122 char *buf; 6776d62bc4baSyz147064 uint32_t flags; 6777da14cebeSEric Cheng dladm_arg_list_t *proplist = NULL; 6778d62bc4baSyz147064 show_linkprop_state_t *statep = arg; 6779d62bc4baSyz147064 dlpi_handle_t dh = NULL; 6780f4b3ec61Sdh155122 6781d62bc4baSyz147064 statep->ls_status = DLADM_STATUS_OK; 6782d62bc4baSyz147064 67834ac67f02SAnurag S. Maskey if (dladm_datalink_id2info(hdl, linkid, &flags, NULL, NULL, 67844ac67f02SAnurag S. Maskey statep->ls_link, MAXLINKNAMELEN) != DLADM_STATUS_OK) { 6785d62bc4baSyz147064 statep->ls_status = DLADM_STATUS_NOTFOUND; 6786d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 6787d62bc4baSyz147064 } 6788d62bc4baSyz147064 6789d62bc4baSyz147064 if ((statep->ls_persist && !(flags & DLADM_OPT_PERSIST)) || 6790d62bc4baSyz147064 (!statep->ls_persist && !(flags & DLADM_OPT_ACTIVE))) { 6791d62bc4baSyz147064 statep->ls_status = DLADM_STATUS_BADARG; 6792d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 6793d62bc4baSyz147064 } 6794d62bc4baSyz147064 6795f4b3ec61Sdh155122 proplist = statep->ls_proplist; 67960ba2cbe9Sxc151355 67970ba2cbe9Sxc151355 /* 67980ba2cbe9Sxc151355 * When some WiFi links are opened for the first time, their hardware 67990ba2cbe9Sxc151355 * automatically scans for APs and does other slow operations. Thus, 68000ba2cbe9Sxc151355 * if there are no open links, the retrieval of link properties 68010ba2cbe9Sxc151355 * (below) will proceed slowly unless we hold the link open. 6802d62bc4baSyz147064 * 6803d62bc4baSyz147064 * Note that failure of dlpi_open() does not necessarily mean invalid 6804d62bc4baSyz147064 * link properties, because dlpi_open() may fail because of incorrect 6805d62bc4baSyz147064 * autopush configuration. Therefore, we ingore the return value of 6806d62bc4baSyz147064 * dlpi_open(). 68070ba2cbe9Sxc151355 */ 6808d62bc4baSyz147064 if (!statep->ls_persist) 6809d62bc4baSyz147064 (void) dlpi_open(statep->ls_link, &dh, 0); 68100ba2cbe9Sxc151355 6811d62bc4baSyz147064 buf = malloc((sizeof (char *) + DLADM_PROP_VAL_MAX) * 6812d62bc4baSyz147064 DLADM_MAX_PROP_VALCNT + MAX_PROP_LINE); 681333343a97Smeem if (buf == NULL) 681433343a97Smeem die("insufficient memory"); 681533343a97Smeem 6816f4b3ec61Sdh155122 statep->ls_propvals = (char **)(void *)buf; 6817d62bc4baSyz147064 for (i = 0; i < DLADM_MAX_PROP_VALCNT; i++) { 6818d62bc4baSyz147064 statep->ls_propvals[i] = buf + 6819d62bc4baSyz147064 sizeof (char *) * DLADM_MAX_PROP_VALCNT + 68200ba2cbe9Sxc151355 i * DLADM_PROP_VAL_MAX; 68210ba2cbe9Sxc151355 } 6822f4b3ec61Sdh155122 statep->ls_line = buf + 6823d62bc4baSyz147064 (sizeof (char *) + DLADM_PROP_VAL_MAX) * DLADM_MAX_PROP_VALCNT; 68240ba2cbe9Sxc151355 68250ba2cbe9Sxc151355 if (proplist != NULL) { 6826da14cebeSEric Cheng for (i = 0; i < proplist->al_count; i++) { 68274ac67f02SAnurag S. Maskey (void) show_linkprop(hdl, linkid, 6828da14cebeSEric Cheng proplist->al_info[i].ai_name, statep); 68290ba2cbe9Sxc151355 } 6830d62bc4baSyz147064 } else { 68314ac67f02SAnurag S. Maskey (void) dladm_walk_linkprop(hdl, linkid, statep, 68324ac67f02SAnurag S. Maskey show_linkprop); 6833d62bc4baSyz147064 } 6834d62bc4baSyz147064 if (dh != NULL) 6835948f2876Sss150715 dlpi_close(dh); 68360ba2cbe9Sxc151355 free(buf); 6837d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 68380ba2cbe9Sxc151355 } 68390ba2cbe9Sxc151355 6840da14cebeSEric Cheng static int 68414ac67f02SAnurag S. Maskey reset_one_linkprop(dladm_handle_t dh, datalink_id_t linkid, 68424ac67f02SAnurag S. Maskey const char *propname, void *arg) 6843da14cebeSEric Cheng { 6844da14cebeSEric Cheng set_linkprop_state_t *statep = arg; 6845da14cebeSEric Cheng dladm_status_t status; 6846da14cebeSEric Cheng 68474ac67f02SAnurag S. Maskey status = dladm_set_linkprop(dh, linkid, propname, NULL, 0, 68484eaa4710SRishi Srivatsavai DLADM_OPT_ACTIVE | (statep->ls_temp ? 0 : DLADM_OPT_PERSIST)); 68490b8f0546SSowmini Varadhan if (status != DLADM_STATUS_OK && 68500b8f0546SSowmini Varadhan status != DLADM_STATUS_PROPRDONLY && 68510b8f0546SSowmini Varadhan status != DLADM_STATUS_NOTSUP) { 6852da14cebeSEric Cheng warn_dlerr(status, "cannot reset link property '%s' on '%s'", 6853da14cebeSEric Cheng propname, statep->ls_name); 6854da14cebeSEric Cheng statep->ls_status = status; 68554eaa4710SRishi Srivatsavai } 6856da14cebeSEric Cheng 6857da14cebeSEric Cheng return (DLADM_WALK_CONTINUE); 6858da14cebeSEric Cheng } 6859da14cebeSEric Cheng 68600ba2cbe9Sxc151355 static void 68618d5c46e6Sam223141 set_linkprop(int argc, char **argv, boolean_t reset, const char *use) 68620ba2cbe9Sxc151355 { 68630ba2cbe9Sxc151355 int i, option; 68640ba2cbe9Sxc151355 char errmsg[DLADM_STRSIZE]; 6865d62bc4baSyz147064 char *altroot = NULL; 6866d62bc4baSyz147064 datalink_id_t linkid; 68670ba2cbe9Sxc151355 boolean_t temp = B_FALSE; 68680ba2cbe9Sxc151355 dladm_status_t status = DLADM_STATUS_OK; 686963a6526dSMichael Lim char propstr[DLADM_STRSIZE]; 6870da14cebeSEric Cheng dladm_arg_list_t *proplist = NULL; 68710ba2cbe9Sxc151355 68720ba2cbe9Sxc151355 opterr = 0; 687363a6526dSMichael Lim bzero(propstr, DLADM_STRSIZE); 687463a6526dSMichael Lim 68750ba2cbe9Sxc151355 while ((option = getopt_long(argc, argv, ":p:R:t", 68760ba2cbe9Sxc151355 prop_longopts, NULL)) != -1) { 68770ba2cbe9Sxc151355 switch (option) { 68780ba2cbe9Sxc151355 case 'p': 687963a6526dSMichael Lim (void) strlcat(propstr, optarg, DLADM_STRSIZE); 688063a6526dSMichael Lim if (strlcat(propstr, ",", DLADM_STRSIZE) >= 688163a6526dSMichael Lim DLADM_STRSIZE) 688263a6526dSMichael Lim die("property list too long '%s'", propstr); 68830ba2cbe9Sxc151355 break; 68840ba2cbe9Sxc151355 case 't': 68850ba2cbe9Sxc151355 temp = B_TRUE; 68860ba2cbe9Sxc151355 break; 68870ba2cbe9Sxc151355 case 'R': 6888d62bc4baSyz147064 altroot = optarg; 68890ba2cbe9Sxc151355 break; 68900ba2cbe9Sxc151355 default: 68918d5c46e6Sam223141 die_opterr(optopt, option, use); 68928d5c46e6Sam223141 68930ba2cbe9Sxc151355 } 68940ba2cbe9Sxc151355 } 68950ba2cbe9Sxc151355 6896d62bc4baSyz147064 /* get link name (required last argument) */ 6897d62bc4baSyz147064 if (optind != (argc - 1)) 68980ba2cbe9Sxc151355 usage(); 68990ba2cbe9Sxc151355 690063a6526dSMichael Lim if (dladm_parse_link_props(propstr, &proplist, reset) != 690163a6526dSMichael Lim DLADM_STATUS_OK) 690263a6526dSMichael Lim die("invalid link properties specified"); 690363a6526dSMichael Lim 6904d62bc4baSyz147064 if (proplist == NULL && !reset) 690533343a97Smeem die("link property must be specified"); 690633343a97Smeem 6907d62bc4baSyz147064 if (altroot != NULL) { 6908da14cebeSEric Cheng dladm_free_props(proplist); 6909d62bc4baSyz147064 altroot_cmd(altroot, argc, argv); 6910d62bc4baSyz147064 } 6911d62bc4baSyz147064 69124ac67f02SAnurag S. Maskey status = dladm_name2info(handle, argv[optind], &linkid, NULL, NULL, 69134ac67f02SAnurag S. Maskey NULL); 6914d62bc4baSyz147064 if (status != DLADM_STATUS_OK) 6915d62bc4baSyz147064 die_dlerr(status, "link %s is not valid", argv[optind]); 6916d62bc4baSyz147064 6917d62bc4baSyz147064 if (proplist == NULL) { 6918da14cebeSEric Cheng set_linkprop_state_t state; 691913994ee8Sxz162242 6920da14cebeSEric Cheng state.ls_name = argv[optind]; 6921da14cebeSEric Cheng state.ls_reset = reset; 6922da14cebeSEric Cheng state.ls_temp = temp; 6923da14cebeSEric Cheng state.ls_status = DLADM_STATUS_OK; 6924da14cebeSEric Cheng 69254ac67f02SAnurag S. Maskey (void) dladm_walk_linkprop(handle, linkid, &state, 69264ac67f02SAnurag S. Maskey reset_one_linkprop); 6927da14cebeSEric Cheng 6928da14cebeSEric Cheng status = state.ls_status; 69290ba2cbe9Sxc151355 goto done; 69300ba2cbe9Sxc151355 } 69310ba2cbe9Sxc151355 6932da14cebeSEric Cheng for (i = 0; i < proplist->al_count; i++) { 6933da14cebeSEric Cheng dladm_arg_info_t *aip = &proplist->al_info[i]; 69340ba2cbe9Sxc151355 char **val; 69350ba2cbe9Sxc151355 uint_t count; 69360ba2cbe9Sxc151355 69370ba2cbe9Sxc151355 if (reset) { 69380ba2cbe9Sxc151355 val = NULL; 69390ba2cbe9Sxc151355 count = 0; 69400ba2cbe9Sxc151355 } else { 6941da14cebeSEric Cheng val = aip->ai_val; 6942da14cebeSEric Cheng count = aip->ai_count; 69430ba2cbe9Sxc151355 if (count == 0) { 694433343a97Smeem warn("no value specified for '%s'", 6945da14cebeSEric Cheng aip->ai_name); 69460ba2cbe9Sxc151355 status = DLADM_STATUS_BADARG; 69470ba2cbe9Sxc151355 continue; 69480ba2cbe9Sxc151355 } 69490ba2cbe9Sxc151355 } 69504eaa4710SRishi Srivatsavai status = dladm_set_linkprop(handle, linkid, aip->ai_name, val, 69514eaa4710SRishi Srivatsavai count, DLADM_OPT_ACTIVE | (temp ? 0 : DLADM_OPT_PERSIST)); 69524eaa4710SRishi Srivatsavai switch (status) { 69534eaa4710SRishi Srivatsavai case DLADM_STATUS_OK: 69544eaa4710SRishi Srivatsavai break; 69550ba2cbe9Sxc151355 case DLADM_STATUS_NOTFOUND: 6956da14cebeSEric Cheng warn("invalid link property '%s'", aip->ai_name); 69570ba2cbe9Sxc151355 break; 69580ba2cbe9Sxc151355 case DLADM_STATUS_BADVAL: { 69590ba2cbe9Sxc151355 int j; 69600ba2cbe9Sxc151355 char *ptr, *lim; 69610ba2cbe9Sxc151355 char **propvals = NULL; 6962d62bc4baSyz147064 uint_t valcnt = DLADM_MAX_PROP_VALCNT; 69634eaa4710SRishi Srivatsavai dladm_status_t s; 69640ba2cbe9Sxc151355 69650ba2cbe9Sxc151355 ptr = malloc((sizeof (char *) + 6966d62bc4baSyz147064 DLADM_PROP_VAL_MAX) * DLADM_MAX_PROP_VALCNT + 69670ba2cbe9Sxc151355 MAX_PROP_LINE); 69680ba2cbe9Sxc151355 69690ba2cbe9Sxc151355 propvals = (char **)(void *)ptr; 697033343a97Smeem if (propvals == NULL) 697133343a97Smeem die("insufficient memory"); 697233343a97Smeem 6973d62bc4baSyz147064 for (j = 0; j < DLADM_MAX_PROP_VALCNT; j++) { 69740ba2cbe9Sxc151355 propvals[j] = ptr + sizeof (char *) * 6975d62bc4baSyz147064 DLADM_MAX_PROP_VALCNT + 69760ba2cbe9Sxc151355 j * DLADM_PROP_VAL_MAX; 69770ba2cbe9Sxc151355 } 69784ac67f02SAnurag S. Maskey s = dladm_get_linkprop(handle, linkid, 6979da14cebeSEric Cheng DLADM_PROP_VAL_MODIFIABLE, aip->ai_name, propvals, 6980d62bc4baSyz147064 &valcnt); 6981d62bc4baSyz147064 6982d62bc4baSyz147064 if (s != DLADM_STATUS_OK) { 6983d62bc4baSyz147064 warn_dlerr(status, "cannot set link property " 6984da14cebeSEric Cheng "'%s' on '%s'", aip->ai_name, argv[optind]); 6985d62bc4baSyz147064 free(propvals); 6986d62bc4baSyz147064 break; 6987d62bc4baSyz147064 } 69880ba2cbe9Sxc151355 69890ba2cbe9Sxc151355 ptr = errmsg; 69900ba2cbe9Sxc151355 lim = ptr + DLADM_STRSIZE; 69910ba2cbe9Sxc151355 *ptr = '\0'; 6992d62bc4baSyz147064 for (j = 0; j < valcnt; j++) { 69930ba2cbe9Sxc151355 ptr += snprintf(ptr, lim - ptr, "%s,", 69940ba2cbe9Sxc151355 propvals[j]); 69950ba2cbe9Sxc151355 if (ptr >= lim) 69960ba2cbe9Sxc151355 break; 69970ba2cbe9Sxc151355 } 6998f4b3ec61Sdh155122 if (ptr > errmsg) { 69990ba2cbe9Sxc151355 *(ptr - 1) = '\0'; 700033343a97Smeem warn("link property '%s' must be one of: %s", 7001da14cebeSEric Cheng aip->ai_name, errmsg); 7002f4b3ec61Sdh155122 } else 7003f4b3ec61Sdh155122 warn("invalid link property '%s'", *val); 70040ba2cbe9Sxc151355 free(propvals); 70050ba2cbe9Sxc151355 break; 70060ba2cbe9Sxc151355 } 70070ba2cbe9Sxc151355 default: 70080ba2cbe9Sxc151355 if (reset) { 700933343a97Smeem warn_dlerr(status, "cannot reset link property " 7010da14cebeSEric Cheng "'%s' on '%s'", aip->ai_name, argv[optind]); 70110ba2cbe9Sxc151355 } else { 701233343a97Smeem warn_dlerr(status, "cannot set link property " 7013da14cebeSEric Cheng "'%s' on '%s'", aip->ai_name, argv[optind]); 70140ba2cbe9Sxc151355 } 70150ba2cbe9Sxc151355 break; 70160ba2cbe9Sxc151355 } 70170ba2cbe9Sxc151355 } 70180ba2cbe9Sxc151355 done: 7019da14cebeSEric Cheng dladm_free_props(proplist); 70204ac67f02SAnurag S. Maskey if (status != DLADM_STATUS_OK) { 70214ac67f02SAnurag S. Maskey dladm_close(handle); 70222b24ab6bSSebastien Roy exit(EXIT_FAILURE); 70230ba2cbe9Sxc151355 } 70244ac67f02SAnurag S. Maskey } 70250ba2cbe9Sxc151355 70260ba2cbe9Sxc151355 static void 70278d5c46e6Sam223141 do_set_linkprop(int argc, char **argv, const char *use) 70280ba2cbe9Sxc151355 { 70298d5c46e6Sam223141 set_linkprop(argc, argv, B_FALSE, use); 70300ba2cbe9Sxc151355 } 70310ba2cbe9Sxc151355 70320ba2cbe9Sxc151355 static void 70338d5c46e6Sam223141 do_reset_linkprop(int argc, char **argv, const char *use) 70340ba2cbe9Sxc151355 { 70358d5c46e6Sam223141 set_linkprop(argc, argv, B_TRUE, use); 70360ba2cbe9Sxc151355 } 70370ba2cbe9Sxc151355 70380ba2cbe9Sxc151355 static int 70390ba2cbe9Sxc151355 convert_secobj(char *buf, uint_t len, uint8_t *obj_val, uint_t *obj_lenp, 70400ba2cbe9Sxc151355 dladm_secobj_class_t class) 70410ba2cbe9Sxc151355 { 70420ba2cbe9Sxc151355 int error = 0; 70430ba2cbe9Sxc151355 7044a399b765Szf162725 if (class == DLADM_SECOBJ_CLASS_WPA) { 7045a399b765Szf162725 if (len < 8 || len > 63) 7046a399b765Szf162725 return (EINVAL); 7047a399b765Szf162725 (void) memcpy(obj_val, buf, len); 7048a399b765Szf162725 *obj_lenp = len; 7049a399b765Szf162725 return (error); 7050a399b765Szf162725 } 70510ba2cbe9Sxc151355 7052a399b765Szf162725 if (class == DLADM_SECOBJ_CLASS_WEP) { 70530ba2cbe9Sxc151355 switch (len) { 70540ba2cbe9Sxc151355 case 5: /* ASCII key sizes */ 70550ba2cbe9Sxc151355 case 13: 70560ba2cbe9Sxc151355 (void) memcpy(obj_val, buf, len); 70570ba2cbe9Sxc151355 *obj_lenp = len; 70580ba2cbe9Sxc151355 break; 70590ba2cbe9Sxc151355 case 10: /* Hex key sizes, not preceded by 0x */ 70600ba2cbe9Sxc151355 case 26: 70610ba2cbe9Sxc151355 error = hexascii_to_octet(buf, len, obj_val, obj_lenp); 70620ba2cbe9Sxc151355 break; 70630ba2cbe9Sxc151355 case 12: /* Hex key sizes, preceded by 0x */ 70640ba2cbe9Sxc151355 case 28: 70650ba2cbe9Sxc151355 if (strncmp(buf, "0x", 2) != 0) 70660ba2cbe9Sxc151355 return (EINVAL); 7067a399b765Szf162725 error = hexascii_to_octet(buf + 2, len - 2, 7068a399b765Szf162725 obj_val, obj_lenp); 70690ba2cbe9Sxc151355 break; 70700ba2cbe9Sxc151355 default: 70710ba2cbe9Sxc151355 return (EINVAL); 70720ba2cbe9Sxc151355 } 70730ba2cbe9Sxc151355 return (error); 70740ba2cbe9Sxc151355 } 70750ba2cbe9Sxc151355 7076a399b765Szf162725 return (ENOENT); 7077a399b765Szf162725 } 7078a399b765Szf162725 70790ba2cbe9Sxc151355 static void 70800ba2cbe9Sxc151355 defersig(int sig) 70810ba2cbe9Sxc151355 { 70820ba2cbe9Sxc151355 signalled = sig; 70830ba2cbe9Sxc151355 } 70840ba2cbe9Sxc151355 70850ba2cbe9Sxc151355 static int 70860ba2cbe9Sxc151355 get_secobj_from_tty(uint_t try, const char *objname, char *buf) 70870ba2cbe9Sxc151355 { 70880ba2cbe9Sxc151355 uint_t len = 0; 70890ba2cbe9Sxc151355 int c; 70900ba2cbe9Sxc151355 struct termios stored, current; 70910ba2cbe9Sxc151355 void (*sigfunc)(int); 70920ba2cbe9Sxc151355 70930ba2cbe9Sxc151355 /* 70940ba2cbe9Sxc151355 * Turn off echo -- but before we do so, defer SIGINT handling 70950ba2cbe9Sxc151355 * so that a ^C doesn't leave the terminal corrupted. 70960ba2cbe9Sxc151355 */ 70970ba2cbe9Sxc151355 sigfunc = signal(SIGINT, defersig); 70980ba2cbe9Sxc151355 (void) fflush(stdin); 70990ba2cbe9Sxc151355 (void) tcgetattr(0, &stored); 71000ba2cbe9Sxc151355 current = stored; 71010ba2cbe9Sxc151355 current.c_lflag &= ~(ICANON|ECHO); 71020ba2cbe9Sxc151355 current.c_cc[VTIME] = 0; 71030ba2cbe9Sxc151355 current.c_cc[VMIN] = 1; 71040ba2cbe9Sxc151355 (void) tcsetattr(0, TCSANOW, ¤t); 71050ba2cbe9Sxc151355 again: 71060ba2cbe9Sxc151355 if (try == 1) 71070ba2cbe9Sxc151355 (void) printf(gettext("provide value for '%s': "), objname); 71080ba2cbe9Sxc151355 else 71090ba2cbe9Sxc151355 (void) printf(gettext("confirm value for '%s': "), objname); 71100ba2cbe9Sxc151355 71110ba2cbe9Sxc151355 (void) fflush(stdout); 71120ba2cbe9Sxc151355 while (signalled == 0) { 71130ba2cbe9Sxc151355 c = getchar(); 71140ba2cbe9Sxc151355 if (c == '\n' || c == '\r') { 71150ba2cbe9Sxc151355 if (len != 0) 71160ba2cbe9Sxc151355 break; 71170ba2cbe9Sxc151355 (void) putchar('\n'); 71180ba2cbe9Sxc151355 goto again; 71190ba2cbe9Sxc151355 } 71200ba2cbe9Sxc151355 71210ba2cbe9Sxc151355 buf[len++] = c; 71220ba2cbe9Sxc151355 if (len >= DLADM_SECOBJ_VAL_MAX - 1) 71230ba2cbe9Sxc151355 break; 71240ba2cbe9Sxc151355 (void) putchar('*'); 71250ba2cbe9Sxc151355 } 71260ba2cbe9Sxc151355 71270ba2cbe9Sxc151355 (void) putchar('\n'); 71280ba2cbe9Sxc151355 (void) fflush(stdin); 71290ba2cbe9Sxc151355 71300ba2cbe9Sxc151355 /* 71310ba2cbe9Sxc151355 * Restore terminal setting and handle deferred signals. 71320ba2cbe9Sxc151355 */ 71330ba2cbe9Sxc151355 (void) tcsetattr(0, TCSANOW, &stored); 71340ba2cbe9Sxc151355 71350ba2cbe9Sxc151355 (void) signal(SIGINT, sigfunc); 71360ba2cbe9Sxc151355 if (signalled != 0) 71370ba2cbe9Sxc151355 (void) kill(getpid(), signalled); 71380ba2cbe9Sxc151355 71390ba2cbe9Sxc151355 return (len); 71400ba2cbe9Sxc151355 } 71410ba2cbe9Sxc151355 71420ba2cbe9Sxc151355 static int 71430ba2cbe9Sxc151355 get_secobj_val(char *obj_name, uint8_t *obj_val, uint_t *obj_lenp, 71440ba2cbe9Sxc151355 dladm_secobj_class_t class, FILE *filep) 71450ba2cbe9Sxc151355 { 71460ba2cbe9Sxc151355 int rval; 71470ba2cbe9Sxc151355 uint_t len, len2; 71480ba2cbe9Sxc151355 char buf[DLADM_SECOBJ_VAL_MAX], buf2[DLADM_SECOBJ_VAL_MAX]; 71490ba2cbe9Sxc151355 71500ba2cbe9Sxc151355 if (filep == NULL) { 71510ba2cbe9Sxc151355 len = get_secobj_from_tty(1, obj_name, buf); 71520ba2cbe9Sxc151355 rval = convert_secobj(buf, len, obj_val, obj_lenp, class); 71530ba2cbe9Sxc151355 if (rval == 0) { 71540ba2cbe9Sxc151355 len2 = get_secobj_from_tty(2, obj_name, buf2); 71550ba2cbe9Sxc151355 if (len != len2 || memcmp(buf, buf2, len) != 0) 71560ba2cbe9Sxc151355 rval = ENOTSUP; 71570ba2cbe9Sxc151355 } 71580ba2cbe9Sxc151355 return (rval); 71590ba2cbe9Sxc151355 } else { 71600ba2cbe9Sxc151355 for (;;) { 71610ba2cbe9Sxc151355 if (fgets(buf, sizeof (buf), filep) == NULL) 71620ba2cbe9Sxc151355 break; 71630ba2cbe9Sxc151355 if (isspace(buf[0])) 71640ba2cbe9Sxc151355 continue; 71650ba2cbe9Sxc151355 71660ba2cbe9Sxc151355 len = strlen(buf); 71670ba2cbe9Sxc151355 if (buf[len - 1] == '\n') { 71680ba2cbe9Sxc151355 buf[len - 1] = '\0'; 71690ba2cbe9Sxc151355 len--; 71700ba2cbe9Sxc151355 } 71710ba2cbe9Sxc151355 break; 71720ba2cbe9Sxc151355 } 71730ba2cbe9Sxc151355 (void) fclose(filep); 71740ba2cbe9Sxc151355 } 71750ba2cbe9Sxc151355 return (convert_secobj(buf, len, obj_val, obj_lenp, class)); 71760ba2cbe9Sxc151355 } 71770ba2cbe9Sxc151355 71780ba2cbe9Sxc151355 static boolean_t 71790ba2cbe9Sxc151355 check_auth(const char *auth) 71800ba2cbe9Sxc151355 { 71810ba2cbe9Sxc151355 struct passwd *pw; 71820ba2cbe9Sxc151355 71830ba2cbe9Sxc151355 if ((pw = getpwuid(getuid())) == NULL) 71840ba2cbe9Sxc151355 return (B_FALSE); 71850ba2cbe9Sxc151355 71860ba2cbe9Sxc151355 return (chkauthattr(auth, pw->pw_name) != 0); 71870ba2cbe9Sxc151355 } 71880ba2cbe9Sxc151355 71890ba2cbe9Sxc151355 static void 71900ba2cbe9Sxc151355 audit_secobj(char *auth, char *class, char *obj, 71910ba2cbe9Sxc151355 boolean_t success, boolean_t create) 71920ba2cbe9Sxc151355 { 71930ba2cbe9Sxc151355 adt_session_data_t *ah; 71940ba2cbe9Sxc151355 adt_event_data_t *event; 71950ba2cbe9Sxc151355 au_event_t flag; 71960ba2cbe9Sxc151355 char *errstr; 71970ba2cbe9Sxc151355 71980ba2cbe9Sxc151355 if (create) { 71990ba2cbe9Sxc151355 flag = ADT_dladm_create_secobj; 72000ba2cbe9Sxc151355 errstr = "ADT_dladm_create_secobj"; 72010ba2cbe9Sxc151355 } else { 72020ba2cbe9Sxc151355 flag = ADT_dladm_delete_secobj; 72030ba2cbe9Sxc151355 errstr = "ADT_dladm_delete_secobj"; 72040ba2cbe9Sxc151355 } 72050ba2cbe9Sxc151355 720633343a97Smeem if (adt_start_session(&ah, NULL, ADT_USE_PROC_DATA) != 0) 720733343a97Smeem die("adt_start_session: %s", strerror(errno)); 72080ba2cbe9Sxc151355 720933343a97Smeem if ((event = adt_alloc_event(ah, flag)) == NULL) 721033343a97Smeem die("adt_alloc_event (%s): %s", errstr, strerror(errno)); 72110ba2cbe9Sxc151355 72120ba2cbe9Sxc151355 /* fill in audit info */ 72130ba2cbe9Sxc151355 if (create) { 72140ba2cbe9Sxc151355 event->adt_dladm_create_secobj.auth_used = auth; 72150ba2cbe9Sxc151355 event->adt_dladm_create_secobj.obj_class = class; 72160ba2cbe9Sxc151355 event->adt_dladm_create_secobj.obj_name = obj; 72170ba2cbe9Sxc151355 } else { 72180ba2cbe9Sxc151355 event->adt_dladm_delete_secobj.auth_used = auth; 72190ba2cbe9Sxc151355 event->adt_dladm_delete_secobj.obj_class = class; 72200ba2cbe9Sxc151355 event->adt_dladm_delete_secobj.obj_name = obj; 72210ba2cbe9Sxc151355 } 72220ba2cbe9Sxc151355 72230ba2cbe9Sxc151355 if (success) { 72240ba2cbe9Sxc151355 if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0) { 722533343a97Smeem die("adt_put_event (%s, success): %s", errstr, 722633343a97Smeem strerror(errno)); 72270ba2cbe9Sxc151355 } 72280ba2cbe9Sxc151355 } else { 72290ba2cbe9Sxc151355 if (adt_put_event(event, ADT_FAILURE, 72300ba2cbe9Sxc151355 ADT_FAIL_VALUE_AUTH) != 0) { 723133343a97Smeem die("adt_put_event: (%s, failure): %s", errstr, 723233343a97Smeem strerror(errno)); 72330ba2cbe9Sxc151355 } 72340ba2cbe9Sxc151355 } 72350ba2cbe9Sxc151355 72360ba2cbe9Sxc151355 adt_free_event(event); 72370ba2cbe9Sxc151355 (void) adt_end_session(ah); 72380ba2cbe9Sxc151355 } 72390ba2cbe9Sxc151355 72400ba2cbe9Sxc151355 static void 72418d5c46e6Sam223141 do_create_secobj(int argc, char **argv, const char *use) 72420ba2cbe9Sxc151355 { 72430ba2cbe9Sxc151355 int option, rval; 72440ba2cbe9Sxc151355 FILE *filep = NULL; 72450ba2cbe9Sxc151355 char *obj_name = NULL; 72460ba2cbe9Sxc151355 char *class_name = NULL; 72470ba2cbe9Sxc151355 uint8_t obj_val[DLADM_SECOBJ_VAL_MAX]; 72480ba2cbe9Sxc151355 uint_t obj_len; 72490ba2cbe9Sxc151355 boolean_t success, temp = B_FALSE; 72500ba2cbe9Sxc151355 dladm_status_t status; 72510ba2cbe9Sxc151355 dladm_secobj_class_t class = -1; 72520ba2cbe9Sxc151355 uid_t euid; 72530ba2cbe9Sxc151355 72540ba2cbe9Sxc151355 opterr = 0; 72550ba2cbe9Sxc151355 (void) memset(obj_val, 0, DLADM_SECOBJ_VAL_MAX); 72560ba2cbe9Sxc151355 while ((option = getopt_long(argc, argv, ":f:c:R:t", 72570ba2cbe9Sxc151355 wifi_longopts, NULL)) != -1) { 72580ba2cbe9Sxc151355 switch (option) { 72590ba2cbe9Sxc151355 case 'f': 72600ba2cbe9Sxc151355 euid = geteuid(); 72610ba2cbe9Sxc151355 (void) seteuid(getuid()); 72620ba2cbe9Sxc151355 filep = fopen(optarg, "r"); 72630ba2cbe9Sxc151355 if (filep == NULL) { 726433343a97Smeem die("cannot open %s: %s", optarg, 726533343a97Smeem strerror(errno)); 72660ba2cbe9Sxc151355 } 72670ba2cbe9Sxc151355 (void) seteuid(euid); 72680ba2cbe9Sxc151355 break; 72690ba2cbe9Sxc151355 case 'c': 72700ba2cbe9Sxc151355 class_name = optarg; 72710ba2cbe9Sxc151355 status = dladm_str2secobjclass(optarg, &class); 72720ba2cbe9Sxc151355 if (status != DLADM_STATUS_OK) { 727333343a97Smeem die("invalid secure object class '%s', " 7274a399b765Szf162725 "valid values are: wep, wpa", optarg); 72750ba2cbe9Sxc151355 } 72760ba2cbe9Sxc151355 break; 72770ba2cbe9Sxc151355 case 't': 72780ba2cbe9Sxc151355 temp = B_TRUE; 72790ba2cbe9Sxc151355 break; 72800ba2cbe9Sxc151355 case 'R': 72810ba2cbe9Sxc151355 status = dladm_set_rootdir(optarg); 72820ba2cbe9Sxc151355 if (status != DLADM_STATUS_OK) { 728333343a97Smeem die_dlerr(status, "invalid directory " 728433343a97Smeem "specified"); 72850ba2cbe9Sxc151355 } 72860ba2cbe9Sxc151355 break; 72870ba2cbe9Sxc151355 default: 72888d5c46e6Sam223141 die_opterr(optopt, option, use); 72890ba2cbe9Sxc151355 break; 72900ba2cbe9Sxc151355 } 72910ba2cbe9Sxc151355 } 72920ba2cbe9Sxc151355 72930ba2cbe9Sxc151355 if (optind == (argc - 1)) 72940ba2cbe9Sxc151355 obj_name = argv[optind]; 72950ba2cbe9Sxc151355 else if (optind != argc) 72960ba2cbe9Sxc151355 usage(); 72970ba2cbe9Sxc151355 729833343a97Smeem if (class == -1) 729933343a97Smeem die("secure object class required"); 73000ba2cbe9Sxc151355 730133343a97Smeem if (obj_name == NULL) 730233343a97Smeem die("secure object name required"); 73030ba2cbe9Sxc151355 7304a9489f61SAnurag S. Maskey if (!dladm_valid_secobj_name(obj_name)) 7305a9489f61SAnurag S. Maskey die("invalid secure object name '%s'", obj_name); 7306a9489f61SAnurag S. Maskey 73070ba2cbe9Sxc151355 success = check_auth(LINK_SEC_AUTH); 73080ba2cbe9Sxc151355 audit_secobj(LINK_SEC_AUTH, class_name, obj_name, success, B_TRUE); 730933343a97Smeem if (!success) 731033343a97Smeem die("authorization '%s' is required", LINK_SEC_AUTH); 73110ba2cbe9Sxc151355 731233343a97Smeem rval = get_secobj_val(obj_name, obj_val, &obj_len, class, filep); 731333343a97Smeem if (rval != 0) { 73140ba2cbe9Sxc151355 switch (rval) { 73150ba2cbe9Sxc151355 case ENOENT: 731633343a97Smeem die("invalid secure object class"); 73170ba2cbe9Sxc151355 break; 73180ba2cbe9Sxc151355 case EINVAL: 731933343a97Smeem die("invalid secure object value"); 73200ba2cbe9Sxc151355 break; 73210ba2cbe9Sxc151355 case ENOTSUP: 732233343a97Smeem die("verification failed"); 73230ba2cbe9Sxc151355 break; 73240ba2cbe9Sxc151355 default: 732533343a97Smeem die("invalid secure object: %s", strerror(rval)); 73260ba2cbe9Sxc151355 break; 73270ba2cbe9Sxc151355 } 73280ba2cbe9Sxc151355 } 73290ba2cbe9Sxc151355 73304ac67f02SAnurag S. Maskey status = dladm_set_secobj(handle, obj_name, class, obj_val, obj_len, 7331d62bc4baSyz147064 DLADM_OPT_CREATE | DLADM_OPT_ACTIVE); 73320ba2cbe9Sxc151355 if (status != DLADM_STATUS_OK) { 733333343a97Smeem die_dlerr(status, "could not create secure object '%s'", 733433343a97Smeem obj_name); 73350ba2cbe9Sxc151355 } 73360ba2cbe9Sxc151355 if (temp) 73370ba2cbe9Sxc151355 return; 73380ba2cbe9Sxc151355 73394ac67f02SAnurag S. Maskey status = dladm_set_secobj(handle, obj_name, class, obj_val, obj_len, 73400ba2cbe9Sxc151355 DLADM_OPT_PERSIST); 73410ba2cbe9Sxc151355 if (status != DLADM_STATUS_OK) { 734233343a97Smeem warn_dlerr(status, "could not persistently create secure " 734333343a97Smeem "object '%s'", obj_name); 73440ba2cbe9Sxc151355 } 73450ba2cbe9Sxc151355 } 73460ba2cbe9Sxc151355 73470ba2cbe9Sxc151355 static void 73488d5c46e6Sam223141 do_delete_secobj(int argc, char **argv, const char *use) 73490ba2cbe9Sxc151355 { 73500ba2cbe9Sxc151355 int i, option; 73510ba2cbe9Sxc151355 boolean_t temp = B_FALSE; 73520ba2cbe9Sxc151355 boolean_t success; 73530ba2cbe9Sxc151355 dladm_status_t status, pstatus; 73548002d411SSowmini Varadhan int nfields = 1; 73558002d411SSowmini Varadhan char *field, *token, *lasts = NULL, c; 73560ba2cbe9Sxc151355 73570ba2cbe9Sxc151355 opterr = 0; 73580ba2cbe9Sxc151355 status = pstatus = DLADM_STATUS_OK; 735933343a97Smeem while ((option = getopt_long(argc, argv, ":R:t", 73600ba2cbe9Sxc151355 wifi_longopts, NULL)) != -1) { 73610ba2cbe9Sxc151355 switch (option) { 73620ba2cbe9Sxc151355 case 't': 73630ba2cbe9Sxc151355 temp = B_TRUE; 73640ba2cbe9Sxc151355 break; 73650ba2cbe9Sxc151355 case 'R': 73660ba2cbe9Sxc151355 status = dladm_set_rootdir(optarg); 73670ba2cbe9Sxc151355 if (status != DLADM_STATUS_OK) { 736833343a97Smeem die_dlerr(status, "invalid directory " 736933343a97Smeem "specified"); 73700ba2cbe9Sxc151355 } 73710ba2cbe9Sxc151355 break; 73720ba2cbe9Sxc151355 default: 73738d5c46e6Sam223141 die_opterr(optopt, option, use); 73740ba2cbe9Sxc151355 break; 73750ba2cbe9Sxc151355 } 73760ba2cbe9Sxc151355 } 73770ba2cbe9Sxc151355 7378*f689bed1SRishi Srivatsavai if (optind != (argc - 1)) 73798002d411SSowmini Varadhan die("secure object name required"); 7380*f689bed1SRishi Srivatsavai 7381*f689bed1SRishi Srivatsavai token = argv[optind]; 73828002d411SSowmini Varadhan while ((c = *token++) != NULL) { 73838002d411SSowmini Varadhan if (c == ',') 73848002d411SSowmini Varadhan nfields++; 73850ba2cbe9Sxc151355 } 73868002d411SSowmini Varadhan token = strdup(argv[optind]); 73878002d411SSowmini Varadhan if (token == NULL) 73888002d411SSowmini Varadhan die("no memory"); 73890ba2cbe9Sxc151355 73900ba2cbe9Sxc151355 success = check_auth(LINK_SEC_AUTH); 7391a399b765Szf162725 audit_secobj(LINK_SEC_AUTH, "unknown", argv[optind], success, B_FALSE); 739233343a97Smeem if (!success) 739333343a97Smeem die("authorization '%s' is required", LINK_SEC_AUTH); 73940ba2cbe9Sxc151355 73958002d411SSowmini Varadhan for (i = 0; i < nfields; i++) { 73968002d411SSowmini Varadhan 73978002d411SSowmini Varadhan field = strtok_r(token, ",", &lasts); 73988002d411SSowmini Varadhan token = NULL; 73998002d411SSowmini Varadhan status = dladm_unset_secobj(handle, field, DLADM_OPT_ACTIVE); 74000ba2cbe9Sxc151355 if (!temp) { 74018002d411SSowmini Varadhan pstatus = dladm_unset_secobj(handle, field, 74020ba2cbe9Sxc151355 DLADM_OPT_PERSIST); 74030ba2cbe9Sxc151355 } else { 74040ba2cbe9Sxc151355 pstatus = DLADM_STATUS_OK; 74050ba2cbe9Sxc151355 } 74060ba2cbe9Sxc151355 74070ba2cbe9Sxc151355 if (status != DLADM_STATUS_OK) { 740833343a97Smeem warn_dlerr(status, "could not delete secure object " 74098002d411SSowmini Varadhan "'%s'", field); 74100ba2cbe9Sxc151355 } 74110ba2cbe9Sxc151355 if (pstatus != DLADM_STATUS_OK) { 741233343a97Smeem warn_dlerr(pstatus, "could not persistently delete " 74138002d411SSowmini Varadhan "secure object '%s'", field); 74140ba2cbe9Sxc151355 } 74150ba2cbe9Sxc151355 } 74168002d411SSowmini Varadhan free(token); 74174ac67f02SAnurag S. Maskey 74184ac67f02SAnurag S. Maskey if (status != DLADM_STATUS_OK || pstatus != DLADM_STATUS_OK) { 74194ac67f02SAnurag S. Maskey dladm_close(handle); 74202b24ab6bSSebastien Roy exit(EXIT_FAILURE); 74210ba2cbe9Sxc151355 } 74224ac67f02SAnurag S. Maskey } 74230ba2cbe9Sxc151355 74240ba2cbe9Sxc151355 typedef struct show_secobj_state { 74250ba2cbe9Sxc151355 boolean_t ss_persist; 74268002d411SSowmini Varadhan boolean_t ss_parsable; 74270ba2cbe9Sxc151355 boolean_t ss_header; 74288002d411SSowmini Varadhan ofmt_handle_t ss_ofmt; 74290ba2cbe9Sxc151355 } show_secobj_state_t; 74300ba2cbe9Sxc151355 74310ba2cbe9Sxc151355 74320ba2cbe9Sxc151355 static boolean_t 74334ac67f02SAnurag S. Maskey show_secobj(dladm_handle_t dh, void *arg, const char *obj_name) 74340ba2cbe9Sxc151355 { 74350ba2cbe9Sxc151355 uint_t obj_len = DLADM_SECOBJ_VAL_MAX; 74360ba2cbe9Sxc151355 uint8_t obj_val[DLADM_SECOBJ_VAL_MAX]; 74370ba2cbe9Sxc151355 char buf[DLADM_STRSIZE]; 74380ba2cbe9Sxc151355 uint_t flags = 0; 74390ba2cbe9Sxc151355 dladm_secobj_class_t class; 74400ba2cbe9Sxc151355 show_secobj_state_t *statep = arg; 74410ba2cbe9Sxc151355 dladm_status_t status; 7442e7801d59Ssowmini secobj_fields_buf_t sbuf; 74430ba2cbe9Sxc151355 74445f5c9f54SAnurag S. Maskey bzero(&sbuf, sizeof (secobj_fields_buf_t)); 74450ba2cbe9Sxc151355 if (statep->ss_persist) 74460ba2cbe9Sxc151355 flags |= DLADM_OPT_PERSIST; 74470ba2cbe9Sxc151355 74484ac67f02SAnurag S. Maskey status = dladm_get_secobj(dh, obj_name, &class, obj_val, &obj_len, 74494ac67f02SAnurag S. Maskey flags); 745033343a97Smeem if (status != DLADM_STATUS_OK) 745133343a97Smeem die_dlerr(status, "cannot get secure object '%s'", obj_name); 74520ba2cbe9Sxc151355 7453e7801d59Ssowmini (void) snprintf(sbuf.ss_obj_name, sizeof (sbuf.ss_obj_name), 7454e7801d59Ssowmini obj_name); 7455e7801d59Ssowmini (void) dladm_secobjclass2str(class, buf); 7456e7801d59Ssowmini (void) snprintf(sbuf.ss_class, sizeof (sbuf.ss_class), "%s", buf); 7457e7801d59Ssowmini if (getuid() == 0) { 74580ba2cbe9Sxc151355 char val[DLADM_SECOBJ_VAL_MAX * 2]; 74590ba2cbe9Sxc151355 uint_t len = sizeof (val); 74600ba2cbe9Sxc151355 7461e7801d59Ssowmini if (octet_to_hexascii(obj_val, obj_len, val, &len) == 0) 7462e7801d59Ssowmini (void) snprintf(sbuf.ss_val, 7463e7801d59Ssowmini sizeof (sbuf.ss_val), "%s", val); 74640ba2cbe9Sxc151355 } 74658002d411SSowmini Varadhan ofmt_print(statep->ss_ofmt, &sbuf); 74660ba2cbe9Sxc151355 return (B_TRUE); 74670ba2cbe9Sxc151355 } 74680ba2cbe9Sxc151355 74690ba2cbe9Sxc151355 static void 74708d5c46e6Sam223141 do_show_secobj(int argc, char **argv, const char *use) 74710ba2cbe9Sxc151355 { 74720ba2cbe9Sxc151355 int option; 74730ba2cbe9Sxc151355 show_secobj_state_t state; 74740ba2cbe9Sxc151355 dladm_status_t status; 74750d365605Sschuster boolean_t o_arg = B_FALSE; 74760ba2cbe9Sxc151355 uint_t i; 74770ba2cbe9Sxc151355 uint_t flags; 7478e7801d59Ssowmini char *fields_str = NULL; 7479e7801d59Ssowmini char *def_fields = "object,class"; 7480e7801d59Ssowmini char *all_fields = "object,class,value"; 74818002d411SSowmini Varadhan char *field, *token, *lasts = NULL, c; 74828002d411SSowmini Varadhan ofmt_handle_t ofmt; 74838002d411SSowmini Varadhan ofmt_status_t oferr; 74848002d411SSowmini Varadhan uint_t ofmtflags = 0; 74850ba2cbe9Sxc151355 74860ba2cbe9Sxc151355 opterr = 0; 7487e7801d59Ssowmini bzero(&state, sizeof (state)); 74888002d411SSowmini Varadhan state.ss_parsable = B_FALSE; 7489e7801d59Ssowmini fields_str = def_fields; 74900ba2cbe9Sxc151355 state.ss_persist = B_FALSE; 74918002d411SSowmini Varadhan state.ss_parsable = B_FALSE; 74920ba2cbe9Sxc151355 state.ss_header = B_TRUE; 7493e7801d59Ssowmini while ((option = getopt_long(argc, argv, ":pPo:", 74940ba2cbe9Sxc151355 wifi_longopts, NULL)) != -1) { 74950ba2cbe9Sxc151355 switch (option) { 74960ba2cbe9Sxc151355 case 'p': 74978002d411SSowmini Varadhan state.ss_parsable = B_TRUE; 74980ba2cbe9Sxc151355 break; 74990ba2cbe9Sxc151355 case 'P': 75000ba2cbe9Sxc151355 state.ss_persist = B_TRUE; 75010ba2cbe9Sxc151355 break; 7502e7801d59Ssowmini case 'o': 75030d365605Sschuster o_arg = B_TRUE; 7504e7801d59Ssowmini if (strcasecmp(optarg, "all") == 0) 7505e7801d59Ssowmini fields_str = all_fields; 7506e7801d59Ssowmini else 7507e7801d59Ssowmini fields_str = optarg; 75080ba2cbe9Sxc151355 break; 75090ba2cbe9Sxc151355 default: 75108d5c46e6Sam223141 die_opterr(optopt, option, use); 75110ba2cbe9Sxc151355 break; 75120ba2cbe9Sxc151355 } 75130ba2cbe9Sxc151355 } 75140ba2cbe9Sxc151355 75158002d411SSowmini Varadhan if (state.ss_parsable && !o_arg) 75160d365605Sschuster die("option -c requires -o"); 75170d365605Sschuster 75188002d411SSowmini Varadhan if (state.ss_parsable && fields_str == all_fields) 75190d365605Sschuster die("\"-o all\" is invalid with -p"); 75200d365605Sschuster 75218002d411SSowmini Varadhan if (state.ss_parsable) 75228002d411SSowmini Varadhan ofmtflags |= OFMT_PARSABLE; 75238002d411SSowmini Varadhan oferr = ofmt_open(fields_str, secobj_fields, ofmtflags, 0, &ofmt); 75248002d411SSowmini Varadhan dladm_ofmt_check(oferr, state.ss_parsable, ofmt); 75258002d411SSowmini Varadhan state.ss_ofmt = ofmt; 7526e7801d59Ssowmini 7527e7801d59Ssowmini flags = state.ss_persist ? DLADM_OPT_PERSIST : 0; 75284ac67f02SAnurag S. Maskey 75290ba2cbe9Sxc151355 if (optind == (argc - 1)) { 75308002d411SSowmini Varadhan uint_t obj_fields = 1; 75318002d411SSowmini Varadhan 75328002d411SSowmini Varadhan token = argv[optind]; 75338002d411SSowmini Varadhan if (token == NULL) 75348002d411SSowmini Varadhan die("secure object name required"); 75358002d411SSowmini Varadhan while ((c = *token++) != NULL) { 75368002d411SSowmini Varadhan if (c == ',') 75378002d411SSowmini Varadhan obj_fields++; 75380ba2cbe9Sxc151355 } 75398002d411SSowmini Varadhan token = strdup(argv[optind]); 75408002d411SSowmini Varadhan if (token == NULL) 75418002d411SSowmini Varadhan die("no memory"); 75428002d411SSowmini Varadhan for (i = 0; i < obj_fields; i++) { 75438002d411SSowmini Varadhan field = strtok_r(token, ",", &lasts); 75448002d411SSowmini Varadhan token = NULL; 75458002d411SSowmini Varadhan if (!show_secobj(handle, &state, field)) 75460ba2cbe9Sxc151355 break; 75470ba2cbe9Sxc151355 } 75488002d411SSowmini Varadhan free(token); 75498002d411SSowmini Varadhan ofmt_close(ofmt); 75500ba2cbe9Sxc151355 return; 75510ba2cbe9Sxc151355 } else if (optind != argc) 75520ba2cbe9Sxc151355 usage(); 75530ba2cbe9Sxc151355 75544ac67f02SAnurag S. Maskey status = dladm_walk_secobj(handle, &state, show_secobj, flags); 75554ac67f02SAnurag S. Maskey 755633343a97Smeem if (status != DLADM_STATUS_OK) 755733343a97Smeem die_dlerr(status, "show-secobj"); 75588002d411SSowmini Varadhan ofmt_close(ofmt); 75590ba2cbe9Sxc151355 } 75600ba2cbe9Sxc151355 75610ba2cbe9Sxc151355 /*ARGSUSED*/ 7562d62bc4baSyz147064 static int 75634ac67f02SAnurag S. Maskey i_dladm_init_linkprop(dladm_handle_t dh, datalink_id_t linkid, void *arg) 7564d62bc4baSyz147064 { 75654ac67f02SAnurag S. Maskey (void) dladm_init_linkprop(dh, linkid, B_TRUE); 7566d62bc4baSyz147064 return (DLADM_WALK_CONTINUE); 7567d62bc4baSyz147064 } 7568d62bc4baSyz147064 75698d5c46e6Sam223141 /*ARGSUSED*/ 7570da14cebeSEric Cheng void 75718d5c46e6Sam223141 do_init_linkprop(int argc, char **argv, const char *use) 75720ba2cbe9Sxc151355 { 757330890389Sartem int option; 757430890389Sartem dladm_status_t status; 757530890389Sartem datalink_id_t linkid = DATALINK_ALL_LINKID; 757630890389Sartem datalink_media_t media = DATALINK_ANY_MEDIATYPE; 757730890389Sartem uint_t any_media = B_TRUE; 757830890389Sartem 757930890389Sartem opterr = 0; 758030890389Sartem while ((option = getopt(argc, argv, ":w")) != -1) { 758130890389Sartem switch (option) { 758230890389Sartem case 'w': 758330890389Sartem media = DL_WIFI; 758430890389Sartem any_media = B_FALSE; 758530890389Sartem break; 758630890389Sartem default: 75878d5c46e6Sam223141 /* 75888d5c46e6Sam223141 * Because init-linkprop is not a public command, 75898d5c46e6Sam223141 * print the usage instead. 75908d5c46e6Sam223141 */ 75918d5c46e6Sam223141 usage(); 759230890389Sartem break; 759330890389Sartem } 759430890389Sartem } 759530890389Sartem 759630890389Sartem if (optind == (argc - 1)) { 75974ac67f02SAnurag S. Maskey if ((status = dladm_name2info(handle, argv[optind], &linkid, 75984ac67f02SAnurag S. Maskey NULL, NULL, NULL)) != DLADM_STATUS_OK) 759930890389Sartem die_dlerr(status, "link %s is not valid", argv[optind]); 760030890389Sartem } else if (optind != argc) { 760130890389Sartem usage(); 760230890389Sartem } 760330890389Sartem 760430890389Sartem if (linkid == DATALINK_ALL_LINKID) { 7605d62bc4baSyz147064 /* 760630890389Sartem * linkprops of links of other classes have been initialized as 7607d62bc4baSyz147064 * part of the dladm up-xxx operation. 7608d62bc4baSyz147064 */ 76094ac67f02SAnurag S. Maskey (void) dladm_walk_datalink_id(i_dladm_init_linkprop, handle, 76104ac67f02SAnurag S. Maskey NULL, DATALINK_CLASS_PHYS, media, DLADM_OPT_PERSIST); 761130890389Sartem } else { 76124ac67f02SAnurag S. Maskey (void) dladm_init_linkprop(handle, linkid, any_media); 761330890389Sartem } 76140ba2cbe9Sxc151355 } 76150ba2cbe9Sxc151355 76160ba2cbe9Sxc151355 static void 76178d5c46e6Sam223141 do_show_ether(int argc, char **argv, const char *use) 7618e7801d59Ssowmini { 7619e7801d59Ssowmini int option; 7620e7801d59Ssowmini datalink_id_t linkid; 7621e7801d59Ssowmini print_ether_state_t state; 76228002d411SSowmini Varadhan char *fields_str = NULL; 76238002d411SSowmini Varadhan ofmt_handle_t ofmt; 76248002d411SSowmini Varadhan ofmt_status_t oferr; 76258002d411SSowmini Varadhan uint_t ofmtflags = 0; 7626e7801d59Ssowmini 7627e7801d59Ssowmini bzero(&state, sizeof (state)); 7628e7801d59Ssowmini state.es_link = NULL; 76298002d411SSowmini Varadhan state.es_parsable = B_FALSE; 7630e7801d59Ssowmini 7631e7801d59Ssowmini while ((option = getopt_long(argc, argv, "o:px", 7632e7801d59Ssowmini showeth_lopts, NULL)) != -1) { 7633e7801d59Ssowmini switch (option) { 7634e7801d59Ssowmini case 'x': 7635e7801d59Ssowmini state.es_extended = B_TRUE; 7636e7801d59Ssowmini break; 7637e7801d59Ssowmini case 'p': 76388002d411SSowmini Varadhan state.es_parsable = B_TRUE; 7639e7801d59Ssowmini break; 7640e7801d59Ssowmini case 'o': 7641e7801d59Ssowmini fields_str = optarg; 7642e7801d59Ssowmini break; 7643e7801d59Ssowmini default: 76448d5c46e6Sam223141 die_opterr(optopt, option, use); 7645e7801d59Ssowmini break; 7646e7801d59Ssowmini } 7647e7801d59Ssowmini } 7648e7801d59Ssowmini 7649e7801d59Ssowmini if (optind == (argc - 1)) 7650e7801d59Ssowmini state.es_link = argv[optind]; 7651e7801d59Ssowmini 76528002d411SSowmini Varadhan if (state.es_parsable) 76538002d411SSowmini Varadhan ofmtflags |= OFMT_PARSABLE; 76548002d411SSowmini Varadhan oferr = ofmt_open(fields_str, ether_fields, ofmtflags, 76558002d411SSowmini Varadhan DLADM_DEFAULT_COL, &ofmt); 76568002d411SSowmini Varadhan dladm_ofmt_check(oferr, state.es_parsable, ofmt); 76578002d411SSowmini Varadhan state.es_ofmt = ofmt; 76584ac67f02SAnurag S. Maskey 7659e7801d59Ssowmini if (state.es_link == NULL) { 76604ac67f02SAnurag S. Maskey (void) dladm_walk_datalink_id(show_etherprop, handle, &state, 76613361618bSRishi Srivatsavai DATALINK_CLASS_PHYS, DL_ETHER, DLADM_OPT_ACTIVE); 7662e7801d59Ssowmini } else { 76634ac67f02SAnurag S. Maskey if (!link_is_ether(state.es_link, &linkid)) 7664e7801d59Ssowmini die("invalid link specified"); 76654ac67f02SAnurag S. Maskey (void) show_etherprop(handle, linkid, &state); 7666e7801d59Ssowmini } 76678002d411SSowmini Varadhan ofmt_close(ofmt); 7668e7801d59Ssowmini } 7669e7801d59Ssowmini 7670e7801d59Ssowmini static int 76714ac67f02SAnurag S. Maskey show_etherprop(dladm_handle_t dh, datalink_id_t linkid, void *arg) 7672e7801d59Ssowmini { 7673e7801d59Ssowmini print_ether_state_t *statep = arg; 7674e7801d59Ssowmini ether_fields_buf_t ebuf; 76754784fcbdSSowmini Varadhan dladm_ether_info_t eattr; 76764784fcbdSSowmini Varadhan dladm_status_t status; 7677e7801d59Ssowmini 76785f5c9f54SAnurag S. Maskey bzero(&ebuf, sizeof (ether_fields_buf_t)); 76794ac67f02SAnurag S. Maskey if (dladm_datalink_id2info(dh, linkid, NULL, NULL, NULL, 7680e7801d59Ssowmini ebuf.eth_link, sizeof (ebuf.eth_link)) != DLADM_STATUS_OK) { 7681e7801d59Ssowmini return (DLADM_WALK_CONTINUE); 7682e7801d59Ssowmini } 7683e7801d59Ssowmini 76844ac67f02SAnurag S. Maskey status = dladm_ether_info(dh, linkid, &eattr); 76854784fcbdSSowmini Varadhan if (status != DLADM_STATUS_OK) 76864784fcbdSSowmini Varadhan goto cleanup; 7687e7801d59Ssowmini 76884784fcbdSSowmini Varadhan (void) strlcpy(ebuf.eth_ptype, "current", sizeof (ebuf.eth_ptype)); 7689e7801d59Ssowmini 76904784fcbdSSowmini Varadhan (void) dladm_ether_autoneg2str(ebuf.eth_autoneg, 76914784fcbdSSowmini Varadhan sizeof (ebuf.eth_autoneg), &eattr, CURRENT); 76924784fcbdSSowmini Varadhan (void) dladm_ether_pause2str(ebuf.eth_pause, 76934784fcbdSSowmini Varadhan sizeof (ebuf.eth_pause), &eattr, CURRENT); 76944784fcbdSSowmini Varadhan (void) dladm_ether_spdx2str(ebuf.eth_spdx, 76954784fcbdSSowmini Varadhan sizeof (ebuf.eth_spdx), &eattr, CURRENT); 76964784fcbdSSowmini Varadhan (void) strlcpy(ebuf.eth_state, 76974784fcbdSSowmini Varadhan dladm_linkstate2str(eattr.lei_state, ebuf.eth_state), 76984784fcbdSSowmini Varadhan sizeof (ebuf.eth_state)); 76994784fcbdSSowmini Varadhan (void) strlcpy(ebuf.eth_rem_fault, 77004784fcbdSSowmini Varadhan (eattr.lei_attr[CURRENT].le_fault ? "fault" : "none"), 77014784fcbdSSowmini Varadhan sizeof (ebuf.eth_rem_fault)); 7702e7801d59Ssowmini 77038002d411SSowmini Varadhan ofmt_print(statep->es_ofmt, &ebuf); 7704e7801d59Ssowmini 7705e7801d59Ssowmini if (statep->es_extended) 77064784fcbdSSowmini Varadhan show_ether_xprop(arg, &eattr); 7707e7801d59Ssowmini 77084784fcbdSSowmini Varadhan cleanup: 77094784fcbdSSowmini Varadhan dladm_ether_info_done(&eattr); 7710e7801d59Ssowmini return (DLADM_WALK_CONTINUE); 7711e7801d59Ssowmini } 7712e7801d59Ssowmini 7713e7801d59Ssowmini /* ARGSUSED */ 7714e7801d59Ssowmini static void 77158d5c46e6Sam223141 do_init_secobj(int argc, char **argv, const char *use) 77160ba2cbe9Sxc151355 { 77170ba2cbe9Sxc151355 dladm_status_t status; 77180ba2cbe9Sxc151355 77194ac67f02SAnurag S. Maskey status = dladm_init_secobj(handle); 772033343a97Smeem if (status != DLADM_STATUS_OK) 772133343a97Smeem die_dlerr(status, "secure object initialization failed"); 772233343a97Smeem } 772333343a97Smeem 77244eaa4710SRishi Srivatsavai enum bridge_func { 77254eaa4710SRishi Srivatsavai brCreate, brAdd, brModify 77264eaa4710SRishi Srivatsavai }; 77274eaa4710SRishi Srivatsavai 77284eaa4710SRishi Srivatsavai static void 77294eaa4710SRishi Srivatsavai create_modify_add_bridge(int argc, char **argv, const char *use, 77304eaa4710SRishi Srivatsavai enum bridge_func func) 77314eaa4710SRishi Srivatsavai { 77324eaa4710SRishi Srivatsavai int option; 77334eaa4710SRishi Srivatsavai uint_t n, i, nlink; 77344eaa4710SRishi Srivatsavai uint32_t flags = DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST; 77354eaa4710SRishi Srivatsavai char *altroot = NULL; 77364eaa4710SRishi Srivatsavai char *links[MAXPORT]; 77374eaa4710SRishi Srivatsavai datalink_id_t linkids[MAXPORT]; 77384eaa4710SRishi Srivatsavai dladm_status_t status; 77394eaa4710SRishi Srivatsavai const char *bridge; 77404eaa4710SRishi Srivatsavai UID_STP_CFG_T cfg, cfg_old; 77414eaa4710SRishi Srivatsavai dladm_bridge_prot_t brprot = DLADM_BRIDGE_PROT_UNKNOWN; 77424eaa4710SRishi Srivatsavai dladm_bridge_prot_t brprot_old; 77434eaa4710SRishi Srivatsavai 77444eaa4710SRishi Srivatsavai /* Set up the default configuration values */ 77454eaa4710SRishi Srivatsavai cfg.field_mask = 0; 77464eaa4710SRishi Srivatsavai cfg.bridge_priority = DEF_BR_PRIO; 77474eaa4710SRishi Srivatsavai cfg.max_age = DEF_BR_MAXAGE; 77484eaa4710SRishi Srivatsavai cfg.hello_time = DEF_BR_HELLOT; 77494eaa4710SRishi Srivatsavai cfg.forward_delay = DEF_BR_FWDELAY; 77504eaa4710SRishi Srivatsavai cfg.force_version = DEF_FORCE_VERS; 77514eaa4710SRishi Srivatsavai 77524eaa4710SRishi Srivatsavai nlink = opterr = 0; 77534eaa4710SRishi Srivatsavai while ((option = getopt_long(argc, argv, ":P:R:d:f:h:l:m:p:", 77544eaa4710SRishi Srivatsavai bridge_lopts, NULL)) != -1) { 77554eaa4710SRishi Srivatsavai switch (option) { 77564eaa4710SRishi Srivatsavai case 'P': 77574eaa4710SRishi Srivatsavai if (func == brAdd) 77584eaa4710SRishi Srivatsavai die_opterr(optopt, option, use); 77594eaa4710SRishi Srivatsavai status = dladm_bridge_str2prot(optarg, &brprot); 77604eaa4710SRishi Srivatsavai if (status != DLADM_STATUS_OK) 77614eaa4710SRishi Srivatsavai die_dlerr(status, "protection %s", optarg); 77624eaa4710SRishi Srivatsavai break; 77634eaa4710SRishi Srivatsavai case 'R': 77644eaa4710SRishi Srivatsavai altroot = optarg; 77654eaa4710SRishi Srivatsavai break; 77664eaa4710SRishi Srivatsavai case 'd': 77674eaa4710SRishi Srivatsavai if (func == brAdd) 77684eaa4710SRishi Srivatsavai die_opterr(optopt, option, use); 77694eaa4710SRishi Srivatsavai if (cfg.field_mask & BR_CFG_DELAY) 77704eaa4710SRishi Srivatsavai die("forwarding delay set more than once"); 77714eaa4710SRishi Srivatsavai if (!str2int(optarg, &cfg.forward_delay) || 77724eaa4710SRishi Srivatsavai cfg.forward_delay < MIN_BR_FWDELAY || 77734eaa4710SRishi Srivatsavai cfg.forward_delay > MAX_BR_FWDELAY) 77744eaa4710SRishi Srivatsavai die("incorrect forwarding delay"); 77754eaa4710SRishi Srivatsavai cfg.field_mask |= BR_CFG_DELAY; 77764eaa4710SRishi Srivatsavai break; 77774eaa4710SRishi Srivatsavai case 'f': 77784eaa4710SRishi Srivatsavai if (func == brAdd) 77794eaa4710SRishi Srivatsavai die_opterr(optopt, option, use); 77804eaa4710SRishi Srivatsavai if (cfg.field_mask & BR_CFG_FORCE_VER) 77814eaa4710SRishi Srivatsavai die("force protocol set more than once"); 77824eaa4710SRishi Srivatsavai if (!str2int(optarg, &cfg.force_version) || 77834eaa4710SRishi Srivatsavai cfg.force_version < 0) 77844eaa4710SRishi Srivatsavai die("incorrect force protocol"); 77854eaa4710SRishi Srivatsavai cfg.field_mask |= BR_CFG_FORCE_VER; 77864eaa4710SRishi Srivatsavai break; 77874eaa4710SRishi Srivatsavai case 'h': 77884eaa4710SRishi Srivatsavai if (func == brAdd) 77894eaa4710SRishi Srivatsavai die_opterr(optopt, option, use); 77904eaa4710SRishi Srivatsavai if (cfg.field_mask & BR_CFG_HELLO) 77914eaa4710SRishi Srivatsavai die("hello time set more than once"); 77924eaa4710SRishi Srivatsavai if (!str2int(optarg, &cfg.hello_time) || 77934eaa4710SRishi Srivatsavai cfg.hello_time < MIN_BR_HELLOT || 77944eaa4710SRishi Srivatsavai cfg.hello_time > MAX_BR_HELLOT) 77954eaa4710SRishi Srivatsavai die("incorrect hello time"); 77964eaa4710SRishi Srivatsavai cfg.field_mask |= BR_CFG_HELLO; 77974eaa4710SRishi Srivatsavai break; 77984eaa4710SRishi Srivatsavai case 'l': 77994eaa4710SRishi Srivatsavai if (func == brModify) 78004eaa4710SRishi Srivatsavai die_opterr(optopt, option, use); 78014eaa4710SRishi Srivatsavai if (nlink >= MAXPORT) 78024eaa4710SRishi Srivatsavai die("too many links specified"); 78034eaa4710SRishi Srivatsavai links[nlink++] = optarg; 78044eaa4710SRishi Srivatsavai break; 78054eaa4710SRishi Srivatsavai case 'm': 78064eaa4710SRishi Srivatsavai if (func == brAdd) 78074eaa4710SRishi Srivatsavai die_opterr(optopt, option, use); 78084eaa4710SRishi Srivatsavai if (cfg.field_mask & BR_CFG_AGE) 78094eaa4710SRishi Srivatsavai die("max age set more than once"); 78104eaa4710SRishi Srivatsavai if (!str2int(optarg, &cfg.max_age) || 78114eaa4710SRishi Srivatsavai cfg.max_age < MIN_BR_MAXAGE || 78124eaa4710SRishi Srivatsavai cfg.max_age > MAX_BR_MAXAGE) 78134eaa4710SRishi Srivatsavai die("incorrect max age"); 78144eaa4710SRishi Srivatsavai cfg.field_mask |= BR_CFG_AGE; 78154eaa4710SRishi Srivatsavai break; 78164eaa4710SRishi Srivatsavai case 'p': 78174eaa4710SRishi Srivatsavai if (func == brAdd) 78184eaa4710SRishi Srivatsavai die_opterr(optopt, option, use); 78194eaa4710SRishi Srivatsavai if (cfg.field_mask & BR_CFG_PRIO) 78204eaa4710SRishi Srivatsavai die("priority set more than once"); 78214eaa4710SRishi Srivatsavai if (!str2int(optarg, &cfg.bridge_priority) || 78224eaa4710SRishi Srivatsavai cfg.bridge_priority < MIN_BR_PRIO || 78234eaa4710SRishi Srivatsavai cfg.bridge_priority > MAX_BR_PRIO) 78244eaa4710SRishi Srivatsavai die("incorrect priority"); 78254eaa4710SRishi Srivatsavai cfg.bridge_priority &= 0xF000; 78264eaa4710SRishi Srivatsavai cfg.field_mask |= BR_CFG_PRIO; 78274eaa4710SRishi Srivatsavai break; 78284eaa4710SRishi Srivatsavai default: 78294eaa4710SRishi Srivatsavai die_opterr(optopt, option, use); 78304eaa4710SRishi Srivatsavai break; 78314eaa4710SRishi Srivatsavai } 78324eaa4710SRishi Srivatsavai } 78334eaa4710SRishi Srivatsavai 78344eaa4710SRishi Srivatsavai /* get the bridge name (required last argument) */ 78354eaa4710SRishi Srivatsavai if (optind != (argc-1)) 78364eaa4710SRishi Srivatsavai usage(); 78374eaa4710SRishi Srivatsavai 78384eaa4710SRishi Srivatsavai bridge = argv[optind]; 78394eaa4710SRishi Srivatsavai if (!dladm_valid_bridgename(bridge)) 78404eaa4710SRishi Srivatsavai die("invalid bridge name '%s'", bridge); 78414eaa4710SRishi Srivatsavai 78424eaa4710SRishi Srivatsavai /* 78434eaa4710SRishi Srivatsavai * Get the current properties, if any, and merge in with changes. This 78444eaa4710SRishi Srivatsavai * is necessary (even with the field_mask feature) so that the 78454eaa4710SRishi Srivatsavai * value-checking macros will produce the right results with proposed 78464eaa4710SRishi Srivatsavai * changes to existing configuration. We only need it for those 78474eaa4710SRishi Srivatsavai * parameters, though. 78484eaa4710SRishi Srivatsavai */ 78494eaa4710SRishi Srivatsavai (void) dladm_bridge_get_properties(bridge, &cfg_old, &brprot_old); 78504eaa4710SRishi Srivatsavai if (brprot == DLADM_BRIDGE_PROT_UNKNOWN) 78514eaa4710SRishi Srivatsavai brprot = brprot_old; 78524eaa4710SRishi Srivatsavai if (!(cfg.field_mask & BR_CFG_AGE)) 78534eaa4710SRishi Srivatsavai cfg.max_age = cfg_old.max_age; 78544eaa4710SRishi Srivatsavai if (!(cfg.field_mask & BR_CFG_HELLO)) 78554eaa4710SRishi Srivatsavai cfg.hello_time = cfg_old.hello_time; 78564eaa4710SRishi Srivatsavai if (!(cfg.field_mask & BR_CFG_DELAY)) 78574eaa4710SRishi Srivatsavai cfg.forward_delay = cfg_old.forward_delay; 78584eaa4710SRishi Srivatsavai 78594eaa4710SRishi Srivatsavai if (!CHECK_BRIDGE_CONFIG(cfg)) { 78604eaa4710SRishi Srivatsavai warn("illegal forward delay / max age / hello time " 78614eaa4710SRishi Srivatsavai "combination"); 78624eaa4710SRishi Srivatsavai if (NO_MAXAGE(cfg)) { 78634eaa4710SRishi Srivatsavai die("no max age possible: need forward delay >= %d or " 78644eaa4710SRishi Srivatsavai "hello time <= %d", MIN_FWDELAY_NOM(cfg), 78654eaa4710SRishi Srivatsavai MAX_HELLOTIME_NOM(cfg)); 78664eaa4710SRishi Srivatsavai } else if (SMALL_MAXAGE(cfg)) { 78674eaa4710SRishi Srivatsavai if (CAPPED_MAXAGE(cfg)) 78684eaa4710SRishi Srivatsavai die("max age too small: need age >= %d and " 78694eaa4710SRishi Srivatsavai "<= %d or hello time <= %d", 78704eaa4710SRishi Srivatsavai MIN_MAXAGE(cfg), MAX_MAXAGE(cfg), 78714eaa4710SRishi Srivatsavai MAX_HELLOTIME(cfg)); 78724eaa4710SRishi Srivatsavai else 78734eaa4710SRishi Srivatsavai die("max age too small: need age >= %d or " 78744eaa4710SRishi Srivatsavai "hello time <= %d", 78754eaa4710SRishi Srivatsavai MIN_MAXAGE(cfg), MAX_HELLOTIME(cfg)); 78764eaa4710SRishi Srivatsavai } else if (FLOORED_MAXAGE(cfg)) { 78774eaa4710SRishi Srivatsavai die("max age too large: need age >= %d and <= %d or " 78784eaa4710SRishi Srivatsavai "forward delay >= %d", 78794eaa4710SRishi Srivatsavai MIN_MAXAGE(cfg), MAX_MAXAGE(cfg), 78804eaa4710SRishi Srivatsavai MIN_FWDELAY(cfg)); 78814eaa4710SRishi Srivatsavai } else { 78824eaa4710SRishi Srivatsavai die("max age too large: need age <= %d or forward " 78834eaa4710SRishi Srivatsavai "delay >= %d", 78844eaa4710SRishi Srivatsavai MAX_MAXAGE(cfg), MIN_FWDELAY(cfg)); 78854eaa4710SRishi Srivatsavai } 78864eaa4710SRishi Srivatsavai } 78874eaa4710SRishi Srivatsavai 78884eaa4710SRishi Srivatsavai if (altroot != NULL) 78894eaa4710SRishi Srivatsavai altroot_cmd(altroot, argc, argv); 78904eaa4710SRishi Srivatsavai 78914eaa4710SRishi Srivatsavai for (n = 0; n < nlink; n++) { 78924eaa4710SRishi Srivatsavai datalink_class_t class; 78934eaa4710SRishi Srivatsavai uint32_t media; 78944eaa4710SRishi Srivatsavai char pointless[DLADM_STRSIZE]; 78954eaa4710SRishi Srivatsavai 78964eaa4710SRishi Srivatsavai if (dladm_name2info(handle, links[n], &linkids[n], NULL, &class, 78974eaa4710SRishi Srivatsavai &media) != DLADM_STATUS_OK) 78984eaa4710SRishi Srivatsavai die("invalid link name '%s'", links[n]); 78994eaa4710SRishi Srivatsavai if (class & ~(DATALINK_CLASS_PHYS | DATALINK_CLASS_AGGR | 79004eaa4710SRishi Srivatsavai DATALINK_CLASS_ETHERSTUB | DATALINK_CLASS_SIMNET)) 79014eaa4710SRishi Srivatsavai die("%s %s cannot be bridged", 79024eaa4710SRishi Srivatsavai dladm_class2str(class, pointless), links[n]); 79034eaa4710SRishi Srivatsavai if (media != DL_ETHER && media != DL_100VG && 79044eaa4710SRishi Srivatsavai media != DL_ETH_CSMA && media != DL_100BT) 79054eaa4710SRishi Srivatsavai die("%s interface %s cannot be bridged", 79064eaa4710SRishi Srivatsavai dladm_media2str(media, pointless), links[n]); 79074eaa4710SRishi Srivatsavai } 79084eaa4710SRishi Srivatsavai 79094eaa4710SRishi Srivatsavai if (func == brCreate) 79104eaa4710SRishi Srivatsavai flags |= DLADM_OPT_CREATE; 79114eaa4710SRishi Srivatsavai 79124eaa4710SRishi Srivatsavai if (func != brAdd) { 79134eaa4710SRishi Srivatsavai status = dladm_bridge_configure(handle, bridge, &cfg, brprot, 79144eaa4710SRishi Srivatsavai flags); 79154eaa4710SRishi Srivatsavai if (status != DLADM_STATUS_OK) 79164eaa4710SRishi Srivatsavai die_dlerr(status, "create operation failed"); 79174eaa4710SRishi Srivatsavai } 79184eaa4710SRishi Srivatsavai 79194eaa4710SRishi Srivatsavai status = DLADM_STATUS_OK; 79204eaa4710SRishi Srivatsavai for (n = 0; n < nlink; n++) { 79214eaa4710SRishi Srivatsavai status = dladm_bridge_setlink(handle, linkids[n], bridge); 79224eaa4710SRishi Srivatsavai if (status != DLADM_STATUS_OK) 79234eaa4710SRishi Srivatsavai break; 79244eaa4710SRishi Srivatsavai } 79254eaa4710SRishi Srivatsavai 79264eaa4710SRishi Srivatsavai if (n >= nlink) { 79274eaa4710SRishi Srivatsavai /* 79284eaa4710SRishi Srivatsavai * We were successful. If we're creating a new bridge, then 79294eaa4710SRishi Srivatsavai * there's just one more step: enabling. If we're modifying or 79304eaa4710SRishi Srivatsavai * just adding links, then we're done. 79314eaa4710SRishi Srivatsavai */ 79324eaa4710SRishi Srivatsavai if (func != brCreate || 79334eaa4710SRishi Srivatsavai (status = dladm_bridge_enable(bridge)) == DLADM_STATUS_OK) 79344eaa4710SRishi Srivatsavai return; 79354eaa4710SRishi Srivatsavai } 79364eaa4710SRishi Srivatsavai 79374eaa4710SRishi Srivatsavai /* clean up the partial configuration */ 79384eaa4710SRishi Srivatsavai for (i = 0; i < n; i++) 79394eaa4710SRishi Srivatsavai (void) dladm_bridge_setlink(handle, linkids[i], ""); 79404eaa4710SRishi Srivatsavai 79414eaa4710SRishi Srivatsavai /* if failure for brCreate, then delete the bridge */ 79424eaa4710SRishi Srivatsavai if (func == brCreate) 79434eaa4710SRishi Srivatsavai (void) dladm_bridge_delete(handle, bridge, flags); 79444eaa4710SRishi Srivatsavai 79454eaa4710SRishi Srivatsavai if (n < nlink) 79464eaa4710SRishi Srivatsavai die_dlerr(status, "unable to add link %s to bridge %s", 79474eaa4710SRishi Srivatsavai links[n], bridge); 79484eaa4710SRishi Srivatsavai else 79494eaa4710SRishi Srivatsavai die_dlerr(status, "unable to enable bridge %s", bridge); 79504eaa4710SRishi Srivatsavai } 79514eaa4710SRishi Srivatsavai 79524eaa4710SRishi Srivatsavai static void 79534eaa4710SRishi Srivatsavai do_create_bridge(int argc, char **argv, const char *use) 79544eaa4710SRishi Srivatsavai { 79554eaa4710SRishi Srivatsavai create_modify_add_bridge(argc, argv, use, brCreate); 79564eaa4710SRishi Srivatsavai } 79574eaa4710SRishi Srivatsavai 79584eaa4710SRishi Srivatsavai static void 79594eaa4710SRishi Srivatsavai do_modify_bridge(int argc, char **argv, const char *use) 79604eaa4710SRishi Srivatsavai { 79614eaa4710SRishi Srivatsavai create_modify_add_bridge(argc, argv, use, brModify); 79624eaa4710SRishi Srivatsavai } 79634eaa4710SRishi Srivatsavai 79644eaa4710SRishi Srivatsavai static void 79654eaa4710SRishi Srivatsavai do_add_bridge(int argc, char **argv, const char *use) 79664eaa4710SRishi Srivatsavai { 79674eaa4710SRishi Srivatsavai create_modify_add_bridge(argc, argv, use, brAdd); 79684eaa4710SRishi Srivatsavai } 79694eaa4710SRishi Srivatsavai 79704eaa4710SRishi Srivatsavai static void 79714eaa4710SRishi Srivatsavai do_delete_bridge(int argc, char **argv, const char *use) 79724eaa4710SRishi Srivatsavai { 79734eaa4710SRishi Srivatsavai char option; 79744eaa4710SRishi Srivatsavai char *altroot = NULL; 79754eaa4710SRishi Srivatsavai uint32_t flags = DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST; 79764eaa4710SRishi Srivatsavai dladm_status_t status; 79774eaa4710SRishi Srivatsavai 79784eaa4710SRishi Srivatsavai opterr = 0; 79794eaa4710SRishi Srivatsavai while ((option = getopt_long(argc, argv, ":R:", bridge_lopts, NULL)) != 79804eaa4710SRishi Srivatsavai -1) { 79814eaa4710SRishi Srivatsavai switch (option) { 79824eaa4710SRishi Srivatsavai case 'R': 79834eaa4710SRishi Srivatsavai altroot = optarg; 79844eaa4710SRishi Srivatsavai break; 79854eaa4710SRishi Srivatsavai default: 79864eaa4710SRishi Srivatsavai die_opterr(optopt, option, use); 79874eaa4710SRishi Srivatsavai break; 79884eaa4710SRishi Srivatsavai } 79894eaa4710SRishi Srivatsavai } 79904eaa4710SRishi Srivatsavai 79914eaa4710SRishi Srivatsavai /* get the bridge name (required last argument) */ 79924eaa4710SRishi Srivatsavai if (optind != (argc-1)) 79934eaa4710SRishi Srivatsavai usage(); 79944eaa4710SRishi Srivatsavai 79954eaa4710SRishi Srivatsavai if (altroot != NULL) 79964eaa4710SRishi Srivatsavai altroot_cmd(altroot, argc, argv); 79974eaa4710SRishi Srivatsavai 79984eaa4710SRishi Srivatsavai status = dladm_bridge_delete(handle, argv[optind], flags); 79994eaa4710SRishi Srivatsavai if (status != DLADM_STATUS_OK) 80004eaa4710SRishi Srivatsavai die_dlerr(status, "delete operation failed"); 80014eaa4710SRishi Srivatsavai } 80024eaa4710SRishi Srivatsavai 80034eaa4710SRishi Srivatsavai static void 80044eaa4710SRishi Srivatsavai do_remove_bridge(int argc, char **argv, const char *use) 80054eaa4710SRishi Srivatsavai { 80064eaa4710SRishi Srivatsavai char option; 80074eaa4710SRishi Srivatsavai uint_t n, nlink; 80084eaa4710SRishi Srivatsavai char *links[MAXPORT]; 80094eaa4710SRishi Srivatsavai datalink_id_t linkids[MAXPORT]; 80104eaa4710SRishi Srivatsavai char *altroot = NULL; 80114eaa4710SRishi Srivatsavai dladm_status_t status; 80124eaa4710SRishi Srivatsavai boolean_t removed_one; 80134eaa4710SRishi Srivatsavai 80144eaa4710SRishi Srivatsavai nlink = opterr = 0; 80154eaa4710SRishi Srivatsavai while ((option = getopt_long(argc, argv, ":R:l:", bridge_lopts, 80164eaa4710SRishi Srivatsavai NULL)) != -1) { 80174eaa4710SRishi Srivatsavai switch (option) { 80184eaa4710SRishi Srivatsavai case 'R': 80194eaa4710SRishi Srivatsavai altroot = optarg; 80204eaa4710SRishi Srivatsavai break; 80214eaa4710SRishi Srivatsavai case 'l': 80224eaa4710SRishi Srivatsavai if (nlink >= MAXPORT) 80234eaa4710SRishi Srivatsavai die("too many links specified"); 80244eaa4710SRishi Srivatsavai links[nlink++] = optarg; 80254eaa4710SRishi Srivatsavai break; 80264eaa4710SRishi Srivatsavai default: 80274eaa4710SRishi Srivatsavai die_opterr(optopt, option, use); 80284eaa4710SRishi Srivatsavai break; 80294eaa4710SRishi Srivatsavai } 80304eaa4710SRishi Srivatsavai } 80314eaa4710SRishi Srivatsavai 80324eaa4710SRishi Srivatsavai if (nlink == 0) 80334eaa4710SRishi Srivatsavai usage(); 80344eaa4710SRishi Srivatsavai 80354eaa4710SRishi Srivatsavai /* get the bridge name (required last argument) */ 80364eaa4710SRishi Srivatsavai if (optind != (argc-1)) 80374eaa4710SRishi Srivatsavai usage(); 80384eaa4710SRishi Srivatsavai 80394eaa4710SRishi Srivatsavai if (altroot != NULL) 80404eaa4710SRishi Srivatsavai altroot_cmd(altroot, argc, argv); 80414eaa4710SRishi Srivatsavai 80424eaa4710SRishi Srivatsavai for (n = 0; n < nlink; n++) { 80434eaa4710SRishi Srivatsavai char bridge[MAXLINKNAMELEN]; 80444eaa4710SRishi Srivatsavai 80454eaa4710SRishi Srivatsavai if (dladm_name2info(handle, links[n], &linkids[n], NULL, NULL, 80464eaa4710SRishi Srivatsavai NULL) != DLADM_STATUS_OK) 80474eaa4710SRishi Srivatsavai die("invalid link name '%s'", links[n]); 80484eaa4710SRishi Srivatsavai status = dladm_bridge_getlink(handle, linkids[n], bridge, 80494eaa4710SRishi Srivatsavai sizeof (bridge)); 80504eaa4710SRishi Srivatsavai if (status != DLADM_STATUS_OK && 80514eaa4710SRishi Srivatsavai status != DLADM_STATUS_NOTFOUND) { 80524eaa4710SRishi Srivatsavai die_dlerr(status, "cannot get bridge status on %s", 80534eaa4710SRishi Srivatsavai links[n]); 80544eaa4710SRishi Srivatsavai } 80554eaa4710SRishi Srivatsavai if (status == DLADM_STATUS_NOTFOUND || 80564eaa4710SRishi Srivatsavai strcmp(bridge, argv[optind]) != 0) 80574eaa4710SRishi Srivatsavai die("link %s is not on bridge %s", links[n], 80584eaa4710SRishi Srivatsavai argv[optind]); 80594eaa4710SRishi Srivatsavai } 80604eaa4710SRishi Srivatsavai 80614eaa4710SRishi Srivatsavai removed_one = B_FALSE; 80624eaa4710SRishi Srivatsavai for (n = 0; n < nlink; n++) { 80634eaa4710SRishi Srivatsavai status = dladm_bridge_setlink(handle, linkids[n], ""); 80644eaa4710SRishi Srivatsavai if (status == DLADM_STATUS_OK) { 80654eaa4710SRishi Srivatsavai removed_one = B_TRUE; 80664eaa4710SRishi Srivatsavai } else { 80674eaa4710SRishi Srivatsavai warn_dlerr(status, 80684eaa4710SRishi Srivatsavai "cannot remove link %s from bridge %s", 80694eaa4710SRishi Srivatsavai links[n], argv[optind]); 80704eaa4710SRishi Srivatsavai } 80714eaa4710SRishi Srivatsavai } 80724eaa4710SRishi Srivatsavai if (!removed_one) 80734eaa4710SRishi Srivatsavai die("unable to remove any links from bridge %s", argv[optind]); 80744eaa4710SRishi Srivatsavai } 80754eaa4710SRishi Srivatsavai 80764eaa4710SRishi Srivatsavai static void 80774eaa4710SRishi Srivatsavai fmt_int(char *buf, size_t buflen, int value, int runvalue, 80784eaa4710SRishi Srivatsavai boolean_t printstar) 80794eaa4710SRishi Srivatsavai { 80804eaa4710SRishi Srivatsavai (void) snprintf(buf, buflen, "%d", value); 80814eaa4710SRishi Srivatsavai if (value != runvalue && printstar) 80824eaa4710SRishi Srivatsavai (void) strlcat(buf, "*", buflen); 80834eaa4710SRishi Srivatsavai } 80844eaa4710SRishi Srivatsavai 80854eaa4710SRishi Srivatsavai static void 80864eaa4710SRishi Srivatsavai fmt_bridge_id(char *buf, size_t buflen, UID_BRIDGE_ID_T *bid) 80874eaa4710SRishi Srivatsavai { 80884eaa4710SRishi Srivatsavai (void) snprintf(buf, buflen, "%u/%x:%x:%x:%x:%x:%x", bid->prio, 80894eaa4710SRishi Srivatsavai bid->addr[0], bid->addr[1], bid->addr[2], bid->addr[3], 80904eaa4710SRishi Srivatsavai bid->addr[4], bid->addr[5]); 80914eaa4710SRishi Srivatsavai } 80924eaa4710SRishi Srivatsavai 80934eaa4710SRishi Srivatsavai static dladm_status_t 80944eaa4710SRishi Srivatsavai print_bridge(show_state_t *state, datalink_id_t linkid, 80954eaa4710SRishi Srivatsavai bridge_fields_buf_t *bbuf) 80964eaa4710SRishi Srivatsavai { 80974eaa4710SRishi Srivatsavai char link[MAXLINKNAMELEN]; 80984eaa4710SRishi Srivatsavai datalink_class_t class; 80994eaa4710SRishi Srivatsavai uint32_t flags; 81004eaa4710SRishi Srivatsavai dladm_status_t status; 81014eaa4710SRishi Srivatsavai UID_STP_CFG_T smfcfg, runcfg; 81024eaa4710SRishi Srivatsavai UID_STP_STATE_T stpstate; 81034eaa4710SRishi Srivatsavai dladm_bridge_prot_t smfprot, runprot; 81044eaa4710SRishi Srivatsavai 81054eaa4710SRishi Srivatsavai if ((status = dladm_datalink_id2info(handle, linkid, &flags, &class, 81064eaa4710SRishi Srivatsavai NULL, link, sizeof (link))) != DLADM_STATUS_OK) 81074eaa4710SRishi Srivatsavai return (status); 81084eaa4710SRishi Srivatsavai 81094eaa4710SRishi Srivatsavai if (!(state->ls_flags & flags)) 81104eaa4710SRishi Srivatsavai return (DLADM_STATUS_NOTFOUND); 81114eaa4710SRishi Srivatsavai 81124eaa4710SRishi Srivatsavai /* Convert observability node name back to bridge name */ 81134eaa4710SRishi Srivatsavai if (!dladm_observe_to_bridge(link)) 81144eaa4710SRishi Srivatsavai return (DLADM_STATUS_NOTFOUND); 81154eaa4710SRishi Srivatsavai (void) strlcpy(bbuf->bridge_name, link, sizeof (bbuf->bridge_name)); 81164eaa4710SRishi Srivatsavai 81174eaa4710SRishi Srivatsavai /* 81184eaa4710SRishi Srivatsavai * If the running value differs from the one in SMF, and parsable 81194eaa4710SRishi Srivatsavai * output is not requested, then we show the running value with an 81204eaa4710SRishi Srivatsavai * asterisk. 81214eaa4710SRishi Srivatsavai */ 81224eaa4710SRishi Srivatsavai (void) dladm_bridge_get_properties(bbuf->bridge_name, &smfcfg, 81234eaa4710SRishi Srivatsavai &smfprot); 81244eaa4710SRishi Srivatsavai (void) dladm_bridge_run_properties(bbuf->bridge_name, &runcfg, 81254eaa4710SRishi Srivatsavai &runprot); 81264eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridge_protect, sizeof (bbuf->bridge_protect), 81274eaa4710SRishi Srivatsavai "%s%s", state->ls_parsable || smfprot == runprot ? "" : "*", 81284eaa4710SRishi Srivatsavai dladm_bridge_prot2str(runprot)); 81294eaa4710SRishi Srivatsavai fmt_int(bbuf->bridge_priority, sizeof (bbuf->bridge_priority), 81304eaa4710SRishi Srivatsavai smfcfg.bridge_priority, runcfg.bridge_priority, 81314eaa4710SRishi Srivatsavai !state->ls_parsable && (runcfg.field_mask & BR_CFG_AGE)); 81324eaa4710SRishi Srivatsavai fmt_int(bbuf->bridge_bmaxage, sizeof (bbuf->bridge_bmaxage), 81334eaa4710SRishi Srivatsavai smfcfg.max_age, runcfg.max_age, 81344eaa4710SRishi Srivatsavai !state->ls_parsable && (runcfg.field_mask & BR_CFG_AGE)); 81354eaa4710SRishi Srivatsavai fmt_int(bbuf->bridge_bhellotime, 81364eaa4710SRishi Srivatsavai sizeof (bbuf->bridge_bhellotime), smfcfg.hello_time, 81374eaa4710SRishi Srivatsavai runcfg.hello_time, 81384eaa4710SRishi Srivatsavai !state->ls_parsable && (runcfg.field_mask & BR_CFG_HELLO)); 81394eaa4710SRishi Srivatsavai fmt_int(bbuf->bridge_bfwddelay, sizeof (bbuf->bridge_bfwddelay), 81404eaa4710SRishi Srivatsavai smfcfg.forward_delay, runcfg.forward_delay, 81414eaa4710SRishi Srivatsavai !state->ls_parsable && (runcfg.field_mask & BR_CFG_DELAY)); 81424eaa4710SRishi Srivatsavai fmt_int(bbuf->bridge_forceproto, sizeof (bbuf->bridge_forceproto), 81434eaa4710SRishi Srivatsavai smfcfg.force_version, runcfg.force_version, 81444eaa4710SRishi Srivatsavai !state->ls_parsable && (runcfg.field_mask & BR_CFG_FORCE_VER)); 81454eaa4710SRishi Srivatsavai fmt_int(bbuf->bridge_holdtime, sizeof (bbuf->bridge_holdtime), 81464eaa4710SRishi Srivatsavai smfcfg.hold_time, runcfg.hold_time, 81474eaa4710SRishi Srivatsavai !state->ls_parsable && (runcfg.field_mask & BR_CFG_HOLD_TIME)); 81484eaa4710SRishi Srivatsavai 81494eaa4710SRishi Srivatsavai if (dladm_bridge_state(bbuf->bridge_name, &stpstate) == 81504eaa4710SRishi Srivatsavai DLADM_STATUS_OK) { 81514eaa4710SRishi Srivatsavai fmt_bridge_id(bbuf->bridge_address, 81524eaa4710SRishi Srivatsavai sizeof (bbuf->bridge_address), &stpstate.bridge_id); 81534eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridge_tctime, 81544eaa4710SRishi Srivatsavai sizeof (bbuf->bridge_tctime), "%lu", 81554eaa4710SRishi Srivatsavai stpstate.timeSince_Topo_Change); 81564eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridge_tccount, 81574eaa4710SRishi Srivatsavai sizeof (bbuf->bridge_tccount), "%lu", 81584eaa4710SRishi Srivatsavai stpstate.Topo_Change_Count); 81594eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridge_tchange, 81604eaa4710SRishi Srivatsavai sizeof (bbuf->bridge_tchange), "%u", stpstate.Topo_Change); 81614eaa4710SRishi Srivatsavai fmt_bridge_id(bbuf->bridge_desroot, 81624eaa4710SRishi Srivatsavai sizeof (bbuf->bridge_desroot), &stpstate.designated_root); 81634eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridge_rootcost, 81644eaa4710SRishi Srivatsavai sizeof (bbuf->bridge_rootcost), "%lu", 81654eaa4710SRishi Srivatsavai stpstate.root_path_cost); 81664eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridge_rootport, 81674eaa4710SRishi Srivatsavai sizeof (bbuf->bridge_rootport), "%u", stpstate.root_port); 81684eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridge_maxage, 81694eaa4710SRishi Srivatsavai sizeof (bbuf->bridge_maxage), "%d", stpstate.max_age); 81704eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridge_hellotime, 81714eaa4710SRishi Srivatsavai sizeof (bbuf->bridge_hellotime), "%d", stpstate.hello_time); 81724eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridge_fwddelay, 81734eaa4710SRishi Srivatsavai sizeof (bbuf->bridge_fwddelay), "%d", 81744eaa4710SRishi Srivatsavai stpstate.forward_delay); 81754eaa4710SRishi Srivatsavai } 81764eaa4710SRishi Srivatsavai return (DLADM_STATUS_OK); 81774eaa4710SRishi Srivatsavai } 81784eaa4710SRishi Srivatsavai 81794eaa4710SRishi Srivatsavai static dladm_status_t 81804eaa4710SRishi Srivatsavai print_bridge_stats(show_state_t *state, datalink_id_t linkid, 81814eaa4710SRishi Srivatsavai bridge_statfields_buf_t *bbuf) 81824eaa4710SRishi Srivatsavai { 81834eaa4710SRishi Srivatsavai char link[MAXLINKNAMELEN]; 81844eaa4710SRishi Srivatsavai datalink_class_t class; 81854eaa4710SRishi Srivatsavai uint32_t flags; 81864eaa4710SRishi Srivatsavai dladm_status_t status; 81874eaa4710SRishi Srivatsavai kstat_ctl_t *kcp; 81884eaa4710SRishi Srivatsavai kstat_t *ksp; 81894eaa4710SRishi Srivatsavai brsum_t *brsum = (brsum_t *)&state->ls_prevstats; 81904eaa4710SRishi Srivatsavai brsum_t newval; 81914eaa4710SRishi Srivatsavai 81924eaa4710SRishi Srivatsavai #ifndef lint 81934eaa4710SRishi Srivatsavai /* This is a compile-time assertion; optimizer normally fixes this */ 81944eaa4710SRishi Srivatsavai extern void brsum_t_is_too_large(void); 81954eaa4710SRishi Srivatsavai 81964eaa4710SRishi Srivatsavai if (sizeof (*brsum) > sizeof (state->ls_prevstats)) 81974eaa4710SRishi Srivatsavai brsum_t_is_too_large(); 81984eaa4710SRishi Srivatsavai #endif 81994eaa4710SRishi Srivatsavai 82004eaa4710SRishi Srivatsavai if (state->ls_firstonly) { 82014eaa4710SRishi Srivatsavai if (state->ls_donefirst) 82024eaa4710SRishi Srivatsavai return (DLADM_WALK_CONTINUE); 82034eaa4710SRishi Srivatsavai state->ls_donefirst = B_TRUE; 82044eaa4710SRishi Srivatsavai } else { 82054eaa4710SRishi Srivatsavai bzero(brsum, sizeof (*brsum)); 82064eaa4710SRishi Srivatsavai } 82074eaa4710SRishi Srivatsavai bzero(&newval, sizeof (newval)); 82084eaa4710SRishi Srivatsavai 82094eaa4710SRishi Srivatsavai if ((status = dladm_datalink_id2info(handle, linkid, &flags, &class, 82104eaa4710SRishi Srivatsavai NULL, link, sizeof (link))) != DLADM_STATUS_OK) 82114eaa4710SRishi Srivatsavai return (status); 82124eaa4710SRishi Srivatsavai 82134eaa4710SRishi Srivatsavai if (!(state->ls_flags & flags)) 82144eaa4710SRishi Srivatsavai return (DLADM_STATUS_NOTFOUND); 82154eaa4710SRishi Srivatsavai 82164eaa4710SRishi Srivatsavai if ((kcp = kstat_open()) == NULL) { 82174eaa4710SRishi Srivatsavai warn("kstat open operation failed"); 82184eaa4710SRishi Srivatsavai return (DLADM_STATUS_OK); 82194eaa4710SRishi Srivatsavai } 82204eaa4710SRishi Srivatsavai if ((ksp = kstat_lookup(kcp, "bridge", 0, link)) != NULL && 82214eaa4710SRishi Srivatsavai kstat_read(kcp, ksp, NULL) != -1) { 82224eaa4710SRishi Srivatsavai if (dladm_kstat_value(ksp, "drops", KSTAT_DATA_UINT64, 82234eaa4710SRishi Srivatsavai &newval.drops) == DLADM_STATUS_OK) { 82244eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridges_drops, 82254eaa4710SRishi Srivatsavai sizeof (bbuf->bridges_drops), "%llu", 82264eaa4710SRishi Srivatsavai newval.drops - brsum->drops); 82274eaa4710SRishi Srivatsavai } 82284eaa4710SRishi Srivatsavai if (dladm_kstat_value(ksp, "forward_direct", KSTAT_DATA_UINT64, 82294eaa4710SRishi Srivatsavai &newval.forward_dir) == DLADM_STATUS_OK) { 82304eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridges_forwards, 82314eaa4710SRishi Srivatsavai sizeof (bbuf->bridges_forwards), "%llu", 82324eaa4710SRishi Srivatsavai newval.forward_dir - brsum->forward_dir); 82334eaa4710SRishi Srivatsavai } 82344eaa4710SRishi Srivatsavai if (dladm_kstat_value(ksp, "forward_mbcast", KSTAT_DATA_UINT64, 82354eaa4710SRishi Srivatsavai &newval.forward_mb) == DLADM_STATUS_OK) { 82364eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridges_mbcast, 82374eaa4710SRishi Srivatsavai sizeof (bbuf->bridges_mbcast), "%llu", 82384eaa4710SRishi Srivatsavai newval.forward_mb - brsum->forward_mb); 82394eaa4710SRishi Srivatsavai } 82404eaa4710SRishi Srivatsavai if (dladm_kstat_value(ksp, "forward_unknown", KSTAT_DATA_UINT64, 82414eaa4710SRishi Srivatsavai &newval.forward_unk) == DLADM_STATUS_OK) { 82424eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridges_unknown, 82434eaa4710SRishi Srivatsavai sizeof (bbuf->bridges_unknown), "%llu", 82444eaa4710SRishi Srivatsavai newval.forward_unk - brsum->forward_unk); 82454eaa4710SRishi Srivatsavai } 82464eaa4710SRishi Srivatsavai if (dladm_kstat_value(ksp, "recv", KSTAT_DATA_UINT64, 82474eaa4710SRishi Srivatsavai &newval.recv) == DLADM_STATUS_OK) { 82484eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridges_recv, 82494eaa4710SRishi Srivatsavai sizeof (bbuf->bridges_recv), "%llu", 82504eaa4710SRishi Srivatsavai newval.recv - brsum->recv); 82514eaa4710SRishi Srivatsavai } 82524eaa4710SRishi Srivatsavai if (dladm_kstat_value(ksp, "sent", KSTAT_DATA_UINT64, 82534eaa4710SRishi Srivatsavai &newval.sent) == DLADM_STATUS_OK) { 82544eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridges_sent, 82554eaa4710SRishi Srivatsavai sizeof (bbuf->bridges_sent), "%llu", 82564eaa4710SRishi Srivatsavai newval.sent - brsum->sent); 82574eaa4710SRishi Srivatsavai } 82584eaa4710SRishi Srivatsavai } 82594eaa4710SRishi Srivatsavai (void) kstat_close(kcp); 82604eaa4710SRishi Srivatsavai 82614eaa4710SRishi Srivatsavai /* Convert observability node name back to bridge name */ 82624eaa4710SRishi Srivatsavai if (!dladm_observe_to_bridge(link)) 82634eaa4710SRishi Srivatsavai return (DLADM_STATUS_NOTFOUND); 82644eaa4710SRishi Srivatsavai (void) strlcpy(bbuf->bridges_name, link, sizeof (bbuf->bridges_name)); 82654eaa4710SRishi Srivatsavai 82664eaa4710SRishi Srivatsavai *brsum = newval; 82674eaa4710SRishi Srivatsavai 82684eaa4710SRishi Srivatsavai return (DLADM_STATUS_OK); 82694eaa4710SRishi Srivatsavai } 82704eaa4710SRishi Srivatsavai 82714eaa4710SRishi Srivatsavai /* 82724eaa4710SRishi Srivatsavai * This structure carries around extra state information for the show-bridge 82734eaa4710SRishi Srivatsavai * command and allows us to use common support functions. 82744eaa4710SRishi Srivatsavai */ 82754eaa4710SRishi Srivatsavai typedef struct { 82764eaa4710SRishi Srivatsavai show_state_t state; 82774eaa4710SRishi Srivatsavai boolean_t show_stats; 82784eaa4710SRishi Srivatsavai const char *bridge; 82794eaa4710SRishi Srivatsavai } show_brstate_t; 82804eaa4710SRishi Srivatsavai 82814eaa4710SRishi Srivatsavai /* ARGSUSED */ 82824eaa4710SRishi Srivatsavai static int 82834eaa4710SRishi Srivatsavai show_bridge(dladm_handle_t handle, datalink_id_t linkid, void *arg) 82844eaa4710SRishi Srivatsavai { 82854eaa4710SRishi Srivatsavai show_brstate_t *brstate = arg; 82864eaa4710SRishi Srivatsavai void *buf; 82874eaa4710SRishi Srivatsavai 82884eaa4710SRishi Srivatsavai if (brstate->show_stats) { 82894eaa4710SRishi Srivatsavai bridge_statfields_buf_t bbuf; 82904eaa4710SRishi Srivatsavai 82914eaa4710SRishi Srivatsavai bzero(&bbuf, sizeof (bbuf)); 82924eaa4710SRishi Srivatsavai brstate->state.ls_status = print_bridge_stats(&brstate->state, 82934eaa4710SRishi Srivatsavai linkid, &bbuf); 82944eaa4710SRishi Srivatsavai buf = &bbuf; 82954eaa4710SRishi Srivatsavai } else { 82964eaa4710SRishi Srivatsavai bridge_fields_buf_t bbuf; 82974eaa4710SRishi Srivatsavai 82984eaa4710SRishi Srivatsavai bzero(&bbuf, sizeof (bbuf)); 82994eaa4710SRishi Srivatsavai brstate->state.ls_status = print_bridge(&brstate->state, linkid, 83004eaa4710SRishi Srivatsavai &bbuf); 83014eaa4710SRishi Srivatsavai buf = &bbuf; 83024eaa4710SRishi Srivatsavai } 83034eaa4710SRishi Srivatsavai if (brstate->state.ls_status == DLADM_STATUS_OK) 83044eaa4710SRishi Srivatsavai ofmt_print(brstate->state.ls_ofmt, buf); 83054eaa4710SRishi Srivatsavai return (DLADM_WALK_CONTINUE); 83064eaa4710SRishi Srivatsavai } 83074eaa4710SRishi Srivatsavai 83084eaa4710SRishi Srivatsavai static void 83094eaa4710SRishi Srivatsavai fmt_bool(char *buf, size_t buflen, int val) 83104eaa4710SRishi Srivatsavai { 83114eaa4710SRishi Srivatsavai (void) strlcpy(buf, val ? "yes" : "no", buflen); 83124eaa4710SRishi Srivatsavai } 83134eaa4710SRishi Srivatsavai 83144eaa4710SRishi Srivatsavai static dladm_status_t 83154eaa4710SRishi Srivatsavai print_bridge_link(show_state_t *state, datalink_id_t linkid, 83164eaa4710SRishi Srivatsavai bridge_link_fields_buf_t *bbuf) 83174eaa4710SRishi Srivatsavai { 83184eaa4710SRishi Srivatsavai datalink_class_t class; 83194eaa4710SRishi Srivatsavai uint32_t flags; 83204eaa4710SRishi Srivatsavai dladm_status_t status; 83214eaa4710SRishi Srivatsavai UID_STP_PORT_STATE_T stpstate; 83224eaa4710SRishi Srivatsavai 83234eaa4710SRishi Srivatsavai status = dladm_datalink_id2info(handle, linkid, &flags, &class, NULL, 83244eaa4710SRishi Srivatsavai bbuf->bridgel_link, sizeof (bbuf->bridgel_link)); 83254eaa4710SRishi Srivatsavai if (status != DLADM_STATUS_OK) 83264eaa4710SRishi Srivatsavai return (status); 83274eaa4710SRishi Srivatsavai 83284eaa4710SRishi Srivatsavai if (!(state->ls_flags & flags)) 83294eaa4710SRishi Srivatsavai return (DLADM_STATUS_NOTFOUND); 83304eaa4710SRishi Srivatsavai 83314eaa4710SRishi Srivatsavai if (dladm_bridge_link_state(handle, linkid, &stpstate) == 83324eaa4710SRishi Srivatsavai DLADM_STATUS_OK) { 83334eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridgel_index, 83344eaa4710SRishi Srivatsavai sizeof (bbuf->bridgel_index), "%u", stpstate.port_no); 83354eaa4710SRishi Srivatsavai if (dlsym(RTLD_PROBE, "STP_IN_state2str")) { 83364eaa4710SRishi Srivatsavai (void) strlcpy(bbuf->bridgel_state, 83374eaa4710SRishi Srivatsavai STP_IN_state2str(stpstate.state), 83384eaa4710SRishi Srivatsavai sizeof (bbuf->bridgel_state)); 83394eaa4710SRishi Srivatsavai } else { 83404eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridgel_state, 83414eaa4710SRishi Srivatsavai sizeof (bbuf->bridgel_state), "%u", 83424eaa4710SRishi Srivatsavai stpstate.state); 83434eaa4710SRishi Srivatsavai } 83444eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridgel_uptime, 83454eaa4710SRishi Srivatsavai sizeof (bbuf->bridgel_uptime), "%lu", stpstate.uptime); 83464eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridgel_opercost, 83474eaa4710SRishi Srivatsavai sizeof (bbuf->bridgel_opercost), "%lu", 83484eaa4710SRishi Srivatsavai stpstate.oper_port_path_cost); 83494eaa4710SRishi Srivatsavai fmt_bool(bbuf->bridgel_operp2p, sizeof (bbuf->bridgel_operp2p), 83504eaa4710SRishi Srivatsavai stpstate.oper_point2point); 83514eaa4710SRishi Srivatsavai fmt_bool(bbuf->bridgel_operedge, 83524eaa4710SRishi Srivatsavai sizeof (bbuf->bridgel_operedge), stpstate.oper_edge); 83534eaa4710SRishi Srivatsavai fmt_bridge_id(bbuf->bridgel_desroot, 83544eaa4710SRishi Srivatsavai sizeof (bbuf->bridgel_desroot), &stpstate.designated_root); 83554eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridgel_descost, 83564eaa4710SRishi Srivatsavai sizeof (bbuf->bridgel_descost), "%lu", 83574eaa4710SRishi Srivatsavai stpstate.designated_cost); 83584eaa4710SRishi Srivatsavai fmt_bridge_id(bbuf->bridgel_desbridge, 83594eaa4710SRishi Srivatsavai sizeof (bbuf->bridgel_desbridge), 83604eaa4710SRishi Srivatsavai &stpstate.designated_bridge); 83614eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridgel_desport, 83624eaa4710SRishi Srivatsavai sizeof (bbuf->bridgel_desport), "%u", 83634eaa4710SRishi Srivatsavai stpstate.designated_port); 83644eaa4710SRishi Srivatsavai fmt_bool(bbuf->bridgel_tcack, sizeof (bbuf->bridgel_tcack), 83654eaa4710SRishi Srivatsavai stpstate.top_change_ack); 83664eaa4710SRishi Srivatsavai } 83674eaa4710SRishi Srivatsavai return (DLADM_STATUS_OK); 83684eaa4710SRishi Srivatsavai } 83694eaa4710SRishi Srivatsavai 83704eaa4710SRishi Srivatsavai static dladm_status_t 83714eaa4710SRishi Srivatsavai print_bridge_link_stats(show_state_t *state, datalink_id_t linkid, 83724eaa4710SRishi Srivatsavai bridge_link_statfields_buf_t *bbuf) 83734eaa4710SRishi Srivatsavai { 83744eaa4710SRishi Srivatsavai datalink_class_t class; 83754eaa4710SRishi Srivatsavai uint32_t flags; 83764eaa4710SRishi Srivatsavai dladm_status_t status; 83774eaa4710SRishi Srivatsavai UID_STP_PORT_STATE_T stpstate; 83784eaa4710SRishi Srivatsavai kstat_ctl_t *kcp; 83794eaa4710SRishi Srivatsavai kstat_t *ksp; 83804eaa4710SRishi Srivatsavai char bridge[MAXLINKNAMELEN]; 83814eaa4710SRishi Srivatsavai char kstatname[MAXLINKNAMELEN*2 + 1]; 83824eaa4710SRishi Srivatsavai brlsum_t *brlsum = (brlsum_t *)&state->ls_prevstats; 83834eaa4710SRishi Srivatsavai brlsum_t newval; 83844eaa4710SRishi Srivatsavai 83854eaa4710SRishi Srivatsavai #ifndef lint 83864eaa4710SRishi Srivatsavai /* This is a compile-time assertion; optimizer normally fixes this */ 83874eaa4710SRishi Srivatsavai extern void brlsum_t_is_too_large(void); 83884eaa4710SRishi Srivatsavai 83894eaa4710SRishi Srivatsavai if (sizeof (*brlsum) > sizeof (state->ls_prevstats)) 83904eaa4710SRishi Srivatsavai brlsum_t_is_too_large(); 83914eaa4710SRishi Srivatsavai #endif 83924eaa4710SRishi Srivatsavai 83934eaa4710SRishi Srivatsavai if (state->ls_firstonly) { 83944eaa4710SRishi Srivatsavai if (state->ls_donefirst) 83954eaa4710SRishi Srivatsavai return (DLADM_WALK_CONTINUE); 83964eaa4710SRishi Srivatsavai state->ls_donefirst = B_TRUE; 83974eaa4710SRishi Srivatsavai } else { 83984eaa4710SRishi Srivatsavai bzero(brlsum, sizeof (*brlsum)); 83994eaa4710SRishi Srivatsavai } 84004eaa4710SRishi Srivatsavai bzero(&newval, sizeof (newval)); 84014eaa4710SRishi Srivatsavai 84024eaa4710SRishi Srivatsavai status = dladm_datalink_id2info(handle, linkid, &flags, &class, NULL, 84034eaa4710SRishi Srivatsavai bbuf->bridgels_link, sizeof (bbuf->bridgels_link)); 84044eaa4710SRishi Srivatsavai if (status != DLADM_STATUS_OK) 84054eaa4710SRishi Srivatsavai return (status); 84064eaa4710SRishi Srivatsavai 84074eaa4710SRishi Srivatsavai if (!(state->ls_flags & flags)) 84084eaa4710SRishi Srivatsavai return (DLADM_STATUS_NOTFOUND); 84094eaa4710SRishi Srivatsavai 84104eaa4710SRishi Srivatsavai if (dladm_bridge_link_state(handle, linkid, &stpstate) == 84114eaa4710SRishi Srivatsavai DLADM_STATUS_OK) { 84124eaa4710SRishi Srivatsavai newval.cfgbpdu = stpstate.rx_cfg_bpdu_cnt; 84134eaa4710SRishi Srivatsavai newval.tcnbpdu = stpstate.rx_tcn_bpdu_cnt; 84144eaa4710SRishi Srivatsavai newval.rstpbpdu = stpstate.rx_rstp_bpdu_cnt; 84154eaa4710SRishi Srivatsavai newval.txbpdu = stpstate.txCount; 84164eaa4710SRishi Srivatsavai 84174eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridgels_cfgbpdu, 84184eaa4710SRishi Srivatsavai sizeof (bbuf->bridgels_cfgbpdu), "%lu", 84194eaa4710SRishi Srivatsavai newval.cfgbpdu - brlsum->cfgbpdu); 84204eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridgels_tcnbpdu, 84214eaa4710SRishi Srivatsavai sizeof (bbuf->bridgels_tcnbpdu), "%lu", 84224eaa4710SRishi Srivatsavai newval.tcnbpdu - brlsum->tcnbpdu); 84234eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridgels_rstpbpdu, 84244eaa4710SRishi Srivatsavai sizeof (bbuf->bridgels_rstpbpdu), "%lu", 84254eaa4710SRishi Srivatsavai newval.rstpbpdu - brlsum->rstpbpdu); 84264eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridgels_txbpdu, 84274eaa4710SRishi Srivatsavai sizeof (bbuf->bridgels_txbpdu), "%lu", 84284eaa4710SRishi Srivatsavai newval.txbpdu - brlsum->txbpdu); 84294eaa4710SRishi Srivatsavai } 84304eaa4710SRishi Srivatsavai 84314eaa4710SRishi Srivatsavai if ((status = dladm_bridge_getlink(handle, linkid, bridge, 84324eaa4710SRishi Srivatsavai sizeof (bridge))) != DLADM_STATUS_OK) 84334eaa4710SRishi Srivatsavai goto bls_out; 84344eaa4710SRishi Srivatsavai (void) snprintf(kstatname, sizeof (kstatname), "%s0-%s", bridge, 84354eaa4710SRishi Srivatsavai bbuf->bridgels_link); 84364eaa4710SRishi Srivatsavai if ((kcp = kstat_open()) == NULL) { 84374eaa4710SRishi Srivatsavai warn("kstat open operation failed"); 84384eaa4710SRishi Srivatsavai goto bls_out; 84394eaa4710SRishi Srivatsavai } 84404eaa4710SRishi Srivatsavai if ((ksp = kstat_lookup(kcp, "bridge", 0, kstatname)) != NULL && 84414eaa4710SRishi Srivatsavai kstat_read(kcp, ksp, NULL) != -1) { 84424eaa4710SRishi Srivatsavai if (dladm_kstat_value(ksp, "drops", KSTAT_DATA_UINT64, 84434eaa4710SRishi Srivatsavai &newval.drops) != -1) { 84444eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridgels_drops, 84454eaa4710SRishi Srivatsavai sizeof (bbuf->bridgels_drops), "%llu", 84464eaa4710SRishi Srivatsavai newval.drops - brlsum->drops); 84474eaa4710SRishi Srivatsavai } 84484eaa4710SRishi Srivatsavai if (dladm_kstat_value(ksp, "recv", KSTAT_DATA_UINT64, 84494eaa4710SRishi Srivatsavai &newval.recv) != -1) { 84504eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridgels_recv, 84514eaa4710SRishi Srivatsavai sizeof (bbuf->bridgels_recv), "%llu", 84524eaa4710SRishi Srivatsavai newval.recv - brlsum->recv); 84534eaa4710SRishi Srivatsavai } 84544eaa4710SRishi Srivatsavai if (dladm_kstat_value(ksp, "xmit", KSTAT_DATA_UINT64, 84554eaa4710SRishi Srivatsavai &newval.xmit) != -1) { 84564eaa4710SRishi Srivatsavai (void) snprintf(bbuf->bridgels_xmit, 84574eaa4710SRishi Srivatsavai sizeof (bbuf->bridgels_xmit), "%llu", 84584eaa4710SRishi Srivatsavai newval.xmit - brlsum->xmit); 84594eaa4710SRishi Srivatsavai } 84604eaa4710SRishi Srivatsavai } 84614eaa4710SRishi Srivatsavai (void) kstat_close(kcp); 84624eaa4710SRishi Srivatsavai bls_out: 84634eaa4710SRishi Srivatsavai *brlsum = newval; 84644eaa4710SRishi Srivatsavai 84654eaa4710SRishi Srivatsavai return (status); 84664eaa4710SRishi Srivatsavai } 84674eaa4710SRishi Srivatsavai 84684eaa4710SRishi Srivatsavai static void 84694eaa4710SRishi Srivatsavai show_bridge_link(datalink_id_t linkid, show_brstate_t *brstate) 84704eaa4710SRishi Srivatsavai { 84714eaa4710SRishi Srivatsavai void *buf; 84724eaa4710SRishi Srivatsavai 84734eaa4710SRishi Srivatsavai if (brstate->show_stats) { 84744eaa4710SRishi Srivatsavai bridge_link_statfields_buf_t bbuf; 84754eaa4710SRishi Srivatsavai 84764eaa4710SRishi Srivatsavai bzero(&bbuf, sizeof (bbuf)); 84774eaa4710SRishi Srivatsavai brstate->state.ls_status = print_bridge_link_stats( 84784eaa4710SRishi Srivatsavai &brstate->state, linkid, &bbuf); 84794eaa4710SRishi Srivatsavai buf = &bbuf; 84804eaa4710SRishi Srivatsavai } else { 84814eaa4710SRishi Srivatsavai bridge_link_fields_buf_t bbuf; 84824eaa4710SRishi Srivatsavai 84834eaa4710SRishi Srivatsavai bzero(&bbuf, sizeof (bbuf)); 84844eaa4710SRishi Srivatsavai brstate->state.ls_status = print_bridge_link(&brstate->state, 84854eaa4710SRishi Srivatsavai linkid, &bbuf); 84864eaa4710SRishi Srivatsavai buf = &bbuf; 84874eaa4710SRishi Srivatsavai } 84884eaa4710SRishi Srivatsavai if (brstate->state.ls_status == DLADM_STATUS_OK) 84894eaa4710SRishi Srivatsavai ofmt_print(brstate->state.ls_ofmt, buf); 84904eaa4710SRishi Srivatsavai } 84914eaa4710SRishi Srivatsavai 84924eaa4710SRishi Srivatsavai /* ARGSUSED */ 84934eaa4710SRishi Srivatsavai static int 84944eaa4710SRishi Srivatsavai show_bridge_link_walk(dladm_handle_t handle, datalink_id_t linkid, void *arg) 84954eaa4710SRishi Srivatsavai { 84964eaa4710SRishi Srivatsavai show_brstate_t *brstate = arg; 84974eaa4710SRishi Srivatsavai char bridge[MAXLINKNAMELEN]; 84984eaa4710SRishi Srivatsavai 84994eaa4710SRishi Srivatsavai if (dladm_bridge_getlink(handle, linkid, bridge, sizeof (bridge)) == 85004eaa4710SRishi Srivatsavai DLADM_STATUS_OK && strcmp(bridge, brstate->bridge) == 0) { 85014eaa4710SRishi Srivatsavai show_bridge_link(linkid, brstate); 85024eaa4710SRishi Srivatsavai } 85034eaa4710SRishi Srivatsavai return (DLADM_WALK_CONTINUE); 85044eaa4710SRishi Srivatsavai } 85054eaa4710SRishi Srivatsavai 85064eaa4710SRishi Srivatsavai static void 85074eaa4710SRishi Srivatsavai show_bridge_fwd(dladm_handle_t handle, bridge_listfwd_t *blf, 85084eaa4710SRishi Srivatsavai show_state_t *state) 85094eaa4710SRishi Srivatsavai { 85104eaa4710SRishi Srivatsavai bridge_fwd_fields_buf_t bbuf; 85114eaa4710SRishi Srivatsavai 85124eaa4710SRishi Srivatsavai bzero(&bbuf, sizeof (bbuf)); 85134eaa4710SRishi Srivatsavai (void) snprintf(bbuf.bridgef_dest, sizeof (bbuf.bridgef_dest), 85144eaa4710SRishi Srivatsavai "%s", ether_ntoa((struct ether_addr *)blf->blf_dest)); 85154eaa4710SRishi Srivatsavai if (blf->blf_is_local) { 85164eaa4710SRishi Srivatsavai (void) strlcpy(bbuf.bridgef_flags, "L", 85174eaa4710SRishi Srivatsavai sizeof (bbuf.bridgef_flags)); 85184eaa4710SRishi Srivatsavai } else { 85194eaa4710SRishi Srivatsavai (void) snprintf(bbuf.bridgef_age, sizeof (bbuf.bridgef_age), 85204eaa4710SRishi Srivatsavai "%2d.%03d", blf->blf_ms_age / 1000, blf->blf_ms_age % 1000); 85214eaa4710SRishi Srivatsavai if (blf->blf_trill_nick != 0) { 85224eaa4710SRishi Srivatsavai (void) snprintf(bbuf.bridgef_output, 85234eaa4710SRishi Srivatsavai sizeof (bbuf.bridgef_output), "%u", 85244eaa4710SRishi Srivatsavai blf->blf_trill_nick); 85254eaa4710SRishi Srivatsavai } 85264eaa4710SRishi Srivatsavai } 85274eaa4710SRishi Srivatsavai if (blf->blf_linkid != DATALINK_INVALID_LINKID && 85284eaa4710SRishi Srivatsavai blf->blf_trill_nick == 0) { 85294eaa4710SRishi Srivatsavai state->ls_status = dladm_datalink_id2info(handle, 85304eaa4710SRishi Srivatsavai blf->blf_linkid, NULL, NULL, NULL, bbuf.bridgef_output, 85314eaa4710SRishi Srivatsavai sizeof (bbuf.bridgef_output)); 85324eaa4710SRishi Srivatsavai } 85334eaa4710SRishi Srivatsavai if (state->ls_status == DLADM_STATUS_OK) 85344eaa4710SRishi Srivatsavai ofmt_print(state->ls_ofmt, &bbuf); 85354eaa4710SRishi Srivatsavai } 85364eaa4710SRishi Srivatsavai 85374eaa4710SRishi Srivatsavai static void 85384eaa4710SRishi Srivatsavai show_bridge_trillnick(trill_listnick_t *tln, show_state_t *state) 85394eaa4710SRishi Srivatsavai { 85404eaa4710SRishi Srivatsavai bridge_trill_fields_buf_t bbuf; 85414eaa4710SRishi Srivatsavai 85424eaa4710SRishi Srivatsavai bzero(&bbuf, sizeof (bbuf)); 85434eaa4710SRishi Srivatsavai (void) snprintf(bbuf.bridget_nick, sizeof (bbuf.bridget_nick), 85444eaa4710SRishi Srivatsavai "%u", tln->tln_nick); 85454eaa4710SRishi Srivatsavai if (tln->tln_ours) { 85464eaa4710SRishi Srivatsavai (void) strlcpy(bbuf.bridget_flags, "L", 85474eaa4710SRishi Srivatsavai sizeof (bbuf.bridget_flags)); 85484eaa4710SRishi Srivatsavai } else { 85494eaa4710SRishi Srivatsavai state->ls_status = dladm_datalink_id2info(handle, 85504eaa4710SRishi Srivatsavai tln->tln_linkid, NULL, NULL, NULL, bbuf.bridget_link, 85514eaa4710SRishi Srivatsavai sizeof (bbuf.bridget_link)); 85524eaa4710SRishi Srivatsavai (void) snprintf(bbuf.bridget_nexthop, 85534eaa4710SRishi Srivatsavai sizeof (bbuf.bridget_nexthop), "%s", 85544eaa4710SRishi Srivatsavai ether_ntoa((struct ether_addr *)tln->tln_nexthop)); 85554eaa4710SRishi Srivatsavai } 85564eaa4710SRishi Srivatsavai if (state->ls_status == DLADM_STATUS_OK) 85574eaa4710SRishi Srivatsavai ofmt_print(state->ls_ofmt, &bbuf); 85584eaa4710SRishi Srivatsavai } 85594eaa4710SRishi Srivatsavai 85604eaa4710SRishi Srivatsavai static void 85614eaa4710SRishi Srivatsavai do_show_bridge(int argc, char **argv, const char *use) 85624eaa4710SRishi Srivatsavai { 85634eaa4710SRishi Srivatsavai int option; 85644eaa4710SRishi Srivatsavai enum { 85654eaa4710SRishi Srivatsavai bridgeMode, linkMode, fwdMode, trillMode 85664eaa4710SRishi Srivatsavai } op_mode = bridgeMode; 85674eaa4710SRishi Srivatsavai uint32_t flags = DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST; 85684eaa4710SRishi Srivatsavai boolean_t parsable = B_FALSE; 85694eaa4710SRishi Srivatsavai datalink_id_t linkid = DATALINK_ALL_LINKID; 85704eaa4710SRishi Srivatsavai int interval = 0; 85714eaa4710SRishi Srivatsavai show_brstate_t brstate; 85724eaa4710SRishi Srivatsavai dladm_status_t status; 85734eaa4710SRishi Srivatsavai char *fields_str = NULL; 85744eaa4710SRishi Srivatsavai /* default: bridge-related data */ 85754eaa4710SRishi Srivatsavai char *all_fields = "bridge,protect,address,priority,bmaxage," 85764eaa4710SRishi Srivatsavai "bhellotime,bfwddelay,forceproto,tctime,tccount,tchange," 85774eaa4710SRishi Srivatsavai "desroot,rootcost,rootport,maxage,hellotime,fwddelay,holdtime"; 85784eaa4710SRishi Srivatsavai char *default_fields = "bridge,protect,address,priority," 85794eaa4710SRishi Srivatsavai "desroot"; 85804eaa4710SRishi Srivatsavai char *all_statfields = "bridge,drops,forwards,mbcast," 85814eaa4710SRishi Srivatsavai "unknown,recv,sent"; 85824eaa4710SRishi Srivatsavai char *default_statfields = "bridge,drops,forwards,mbcast," 85834eaa4710SRishi Srivatsavai "unknown"; 85844eaa4710SRishi Srivatsavai /* -l: link-related data */ 85854eaa4710SRishi Srivatsavai char *all_link_fields = "link,index,state,uptime,opercost," 85864eaa4710SRishi Srivatsavai "operp2p,operedge,desroot,descost,desbridge,desport,tcack"; 85874eaa4710SRishi Srivatsavai char *default_link_fields = "link,state,uptime,desroot"; 85884eaa4710SRishi Srivatsavai char *all_link_statfields = "link,cfgbpdu,tcnbpdu,rstpbpdu," 85894eaa4710SRishi Srivatsavai "txbpdu,drops,recv,xmit"; 85904eaa4710SRishi Srivatsavai char *default_link_statfields = "link,drops,recv,xmit"; 85914eaa4710SRishi Srivatsavai /* -f: bridge forwarding table related data */ 85924eaa4710SRishi Srivatsavai char *default_fwd_fields = "dest,age,flags,output"; 85934eaa4710SRishi Srivatsavai /* -t: TRILL nickname table related data */ 85944eaa4710SRishi Srivatsavai char *default_trill_fields = "nick,flags,link,nexthop"; 85954eaa4710SRishi Srivatsavai char *default_str; 85964eaa4710SRishi Srivatsavai char *all_str; 85974eaa4710SRishi Srivatsavai ofmt_field_t *field_arr; 85984eaa4710SRishi Srivatsavai ofmt_handle_t ofmt; 85994eaa4710SRishi Srivatsavai ofmt_status_t oferr; 86004eaa4710SRishi Srivatsavai uint_t ofmtflags = 0; 86014eaa4710SRishi Srivatsavai 86024eaa4710SRishi Srivatsavai bzero(&brstate, sizeof (brstate)); 86034eaa4710SRishi Srivatsavai 86044eaa4710SRishi Srivatsavai opterr = 0; 86054eaa4710SRishi Srivatsavai while ((option = getopt_long(argc, argv, ":fi:lo:pst", 86064eaa4710SRishi Srivatsavai bridge_show_lopts, NULL)) != -1) { 86074eaa4710SRishi Srivatsavai switch (option) { 86084eaa4710SRishi Srivatsavai case 'f': 86094eaa4710SRishi Srivatsavai if (op_mode != bridgeMode && op_mode != fwdMode) 86104eaa4710SRishi Srivatsavai die("-f is incompatible with -l or -t"); 86114eaa4710SRishi Srivatsavai op_mode = fwdMode; 86124eaa4710SRishi Srivatsavai break; 86134eaa4710SRishi Srivatsavai case 'i': 86144eaa4710SRishi Srivatsavai if (interval != 0) 86154eaa4710SRishi Srivatsavai die_optdup(option); 86164eaa4710SRishi Srivatsavai if (!str2int(optarg, &interval) || interval == 0) 86174eaa4710SRishi Srivatsavai die("invalid interval value '%s'", optarg); 86184eaa4710SRishi Srivatsavai break; 86194eaa4710SRishi Srivatsavai case 'l': 86204eaa4710SRishi Srivatsavai if (op_mode != bridgeMode && op_mode != linkMode) 86214eaa4710SRishi Srivatsavai die("-l is incompatible with -f or -t"); 86224eaa4710SRishi Srivatsavai op_mode = linkMode; 86234eaa4710SRishi Srivatsavai break; 86244eaa4710SRishi Srivatsavai case 'o': 86254eaa4710SRishi Srivatsavai fields_str = optarg; 86264eaa4710SRishi Srivatsavai break; 86274eaa4710SRishi Srivatsavai case 'p': 86284eaa4710SRishi Srivatsavai if (parsable) 86294eaa4710SRishi Srivatsavai die_optdup(option); 86304eaa4710SRishi Srivatsavai parsable = B_TRUE; 86314eaa4710SRishi Srivatsavai break; 86324eaa4710SRishi Srivatsavai case 's': 86334eaa4710SRishi Srivatsavai if (brstate.show_stats) 86344eaa4710SRishi Srivatsavai die_optdup(option); 86354eaa4710SRishi Srivatsavai brstate.show_stats = B_TRUE; 86364eaa4710SRishi Srivatsavai break; 86374eaa4710SRishi Srivatsavai case 't': 86384eaa4710SRishi Srivatsavai if (op_mode != bridgeMode && op_mode != trillMode) 86394eaa4710SRishi Srivatsavai die("-t is incompatible with -f or -l"); 86404eaa4710SRishi Srivatsavai op_mode = trillMode; 86414eaa4710SRishi Srivatsavai break; 86424eaa4710SRishi Srivatsavai default: 86434eaa4710SRishi Srivatsavai die_opterr(optopt, option, use); 86444eaa4710SRishi Srivatsavai break; 86454eaa4710SRishi Srivatsavai } 86464eaa4710SRishi Srivatsavai } 86474eaa4710SRishi Srivatsavai 86484eaa4710SRishi Srivatsavai if (interval != 0 && !brstate.show_stats) 86494eaa4710SRishi Srivatsavai die("the -i option can be used only with -s"); 86504eaa4710SRishi Srivatsavai 86514eaa4710SRishi Srivatsavai if ((op_mode == fwdMode || op_mode == trillMode) && brstate.show_stats) 86524eaa4710SRishi Srivatsavai die("the -f/-t and -s options cannot be used together"); 86534eaa4710SRishi Srivatsavai 86544eaa4710SRishi Srivatsavai /* get the bridge name (optional last argument) */ 86554eaa4710SRishi Srivatsavai if (optind == (argc-1)) { 86564eaa4710SRishi Srivatsavai char lname[MAXLINKNAMELEN]; 86574eaa4710SRishi Srivatsavai uint32_t lnkflg; 86584eaa4710SRishi Srivatsavai datalink_class_t class; 86594eaa4710SRishi Srivatsavai 86604eaa4710SRishi Srivatsavai brstate.bridge = argv[optind]; 86614eaa4710SRishi Srivatsavai (void) snprintf(lname, sizeof (lname), "%s0", brstate.bridge); 86624eaa4710SRishi Srivatsavai if ((status = dladm_name2info(handle, lname, &linkid, &lnkflg, 86634eaa4710SRishi Srivatsavai &class, NULL)) != DLADM_STATUS_OK) { 86644eaa4710SRishi Srivatsavai die_dlerr(status, "bridge %s is not valid", 86654eaa4710SRishi Srivatsavai brstate.bridge); 86664eaa4710SRishi Srivatsavai } 86674eaa4710SRishi Srivatsavai 86684eaa4710SRishi Srivatsavai if (class != DATALINK_CLASS_BRIDGE) 86694eaa4710SRishi Srivatsavai die("%s is not a bridge", brstate.bridge); 86704eaa4710SRishi Srivatsavai 86714eaa4710SRishi Srivatsavai if (!(lnkflg & flags)) { 86724eaa4710SRishi Srivatsavai die_dlerr(DLADM_STATUS_BADARG, 86734eaa4710SRishi Srivatsavai "bridge %s is temporarily removed", brstate.bridge); 86744eaa4710SRishi Srivatsavai } 86754eaa4710SRishi Srivatsavai } else if (optind != argc) { 86764eaa4710SRishi Srivatsavai usage(); 86774eaa4710SRishi Srivatsavai } else if (op_mode != bridgeMode) { 86784eaa4710SRishi Srivatsavai die("bridge name required for -l, -f, or -t"); 86794eaa4710SRishi Srivatsavai return; 86804eaa4710SRishi Srivatsavai } 86814eaa4710SRishi Srivatsavai 86824eaa4710SRishi Srivatsavai brstate.state.ls_parsable = parsable; 86834eaa4710SRishi Srivatsavai brstate.state.ls_flags = flags; 86844eaa4710SRishi Srivatsavai brstate.state.ls_firstonly = (interval != 0); 86854eaa4710SRishi Srivatsavai 86864eaa4710SRishi Srivatsavai switch (op_mode) { 86874eaa4710SRishi Srivatsavai case bridgeMode: 86884eaa4710SRishi Srivatsavai if (brstate.show_stats) { 86894eaa4710SRishi Srivatsavai default_str = default_statfields; 86904eaa4710SRishi Srivatsavai all_str = all_statfields; 86914eaa4710SRishi Srivatsavai field_arr = bridge_statfields; 86924eaa4710SRishi Srivatsavai } else { 86934eaa4710SRishi Srivatsavai default_str = default_fields; 86944eaa4710SRishi Srivatsavai all_str = all_fields; 86954eaa4710SRishi Srivatsavai field_arr = bridge_fields; 86964eaa4710SRishi Srivatsavai } 86974eaa4710SRishi Srivatsavai break; 86984eaa4710SRishi Srivatsavai 86994eaa4710SRishi Srivatsavai case linkMode: 87004eaa4710SRishi Srivatsavai if (brstate.show_stats) { 87014eaa4710SRishi Srivatsavai default_str = default_link_statfields; 87024eaa4710SRishi Srivatsavai all_str = all_link_statfields; 87034eaa4710SRishi Srivatsavai field_arr = bridge_link_statfields; 87044eaa4710SRishi Srivatsavai } else { 87054eaa4710SRishi Srivatsavai default_str = default_link_fields; 87064eaa4710SRishi Srivatsavai all_str = all_link_fields; 87074eaa4710SRishi Srivatsavai field_arr = bridge_link_fields; 87084eaa4710SRishi Srivatsavai } 87094eaa4710SRishi Srivatsavai break; 87104eaa4710SRishi Srivatsavai 87114eaa4710SRishi Srivatsavai case fwdMode: 87124eaa4710SRishi Srivatsavai default_str = all_str = default_fwd_fields; 87134eaa4710SRishi Srivatsavai field_arr = bridge_fwd_fields; 87144eaa4710SRishi Srivatsavai break; 87154eaa4710SRishi Srivatsavai 87164eaa4710SRishi Srivatsavai case trillMode: 87174eaa4710SRishi Srivatsavai default_str = all_str = default_trill_fields; 87184eaa4710SRishi Srivatsavai field_arr = bridge_trill_fields; 87194eaa4710SRishi Srivatsavai break; 87204eaa4710SRishi Srivatsavai } 87214eaa4710SRishi Srivatsavai 87224eaa4710SRishi Srivatsavai if (fields_str == NULL) 87234eaa4710SRishi Srivatsavai fields_str = default_str; 87244eaa4710SRishi Srivatsavai else if (strcasecmp(fields_str, "all") == 0) 87254eaa4710SRishi Srivatsavai fields_str = all_str; 87264eaa4710SRishi Srivatsavai 87274eaa4710SRishi Srivatsavai if (parsable) 87284eaa4710SRishi Srivatsavai ofmtflags |= OFMT_PARSABLE; 87294eaa4710SRishi Srivatsavai oferr = ofmt_open(fields_str, field_arr, ofmtflags, 0, &ofmt); 87304eaa4710SRishi Srivatsavai dladm_ofmt_check(oferr, brstate.state.ls_parsable, ofmt); 87314eaa4710SRishi Srivatsavai brstate.state.ls_ofmt = ofmt; 87324eaa4710SRishi Srivatsavai 87334eaa4710SRishi Srivatsavai for (;;) { 87344eaa4710SRishi Srivatsavai brstate.state.ls_donefirst = B_FALSE; 87354eaa4710SRishi Srivatsavai switch (op_mode) { 87364eaa4710SRishi Srivatsavai case bridgeMode: 87374eaa4710SRishi Srivatsavai if (linkid == DATALINK_ALL_LINKID) { 87384eaa4710SRishi Srivatsavai (void) dladm_walk_datalink_id(show_bridge, 87394eaa4710SRishi Srivatsavai handle, &brstate, DATALINK_CLASS_BRIDGE, 87404eaa4710SRishi Srivatsavai DATALINK_ANY_MEDIATYPE, flags); 87414eaa4710SRishi Srivatsavai } else { 87424eaa4710SRishi Srivatsavai (void) show_bridge(handle, linkid, &brstate); 87434eaa4710SRishi Srivatsavai if (brstate.state.ls_status != 87444eaa4710SRishi Srivatsavai DLADM_STATUS_OK) { 87454eaa4710SRishi Srivatsavai die_dlerr(brstate.state.ls_status, 87464eaa4710SRishi Srivatsavai "failed to show bridge %s", 87474eaa4710SRishi Srivatsavai brstate.bridge); 87484eaa4710SRishi Srivatsavai } 87494eaa4710SRishi Srivatsavai } 87504eaa4710SRishi Srivatsavai break; 87514eaa4710SRishi Srivatsavai 87524eaa4710SRishi Srivatsavai case linkMode: { 87534eaa4710SRishi Srivatsavai datalink_id_t *dlp; 87544eaa4710SRishi Srivatsavai uint_t i, nlinks; 87554eaa4710SRishi Srivatsavai 87564eaa4710SRishi Srivatsavai dlp = dladm_bridge_get_portlist(brstate.bridge, 87574eaa4710SRishi Srivatsavai &nlinks); 87584eaa4710SRishi Srivatsavai if (dlp != NULL) { 87594eaa4710SRishi Srivatsavai for (i = 0; i < nlinks; i++) 87604eaa4710SRishi Srivatsavai show_bridge_link(dlp[i], &brstate); 87614eaa4710SRishi Srivatsavai dladm_bridge_free_portlist(dlp); 87624eaa4710SRishi Srivatsavai } else if (errno == ENOENT) { 87634eaa4710SRishi Srivatsavai /* bridge not running; iterate on libdladm */ 87644eaa4710SRishi Srivatsavai (void) dladm_walk_datalink_id( 87654eaa4710SRishi Srivatsavai show_bridge_link_walk, handle, 87664eaa4710SRishi Srivatsavai &brstate, DATALINK_CLASS_PHYS | 87674eaa4710SRishi Srivatsavai DATALINK_CLASS_AGGR | 87684eaa4710SRishi Srivatsavai DATALINK_CLASS_ETHERSTUB, 87694eaa4710SRishi Srivatsavai DATALINK_ANY_MEDIATYPE, flags); 87704eaa4710SRishi Srivatsavai } else { 87714eaa4710SRishi Srivatsavai die("unable to get port list for bridge %s: %s", 87724eaa4710SRishi Srivatsavai brstate.bridge, strerror(errno)); 87734eaa4710SRishi Srivatsavai } 87744eaa4710SRishi Srivatsavai break; 87754eaa4710SRishi Srivatsavai } 87764eaa4710SRishi Srivatsavai 87774eaa4710SRishi Srivatsavai case fwdMode: { 87784eaa4710SRishi Srivatsavai bridge_listfwd_t *blf; 87794eaa4710SRishi Srivatsavai uint_t i, nfwd; 87804eaa4710SRishi Srivatsavai 87814eaa4710SRishi Srivatsavai blf = dladm_bridge_get_fwdtable(handle, brstate.bridge, 87824eaa4710SRishi Srivatsavai &nfwd); 87834eaa4710SRishi Srivatsavai if (blf == NULL) { 87844eaa4710SRishi Srivatsavai die("unable to get forwarding entries for " 87854eaa4710SRishi Srivatsavai "bridge %s", brstate.bridge); 87864eaa4710SRishi Srivatsavai } else { 87874eaa4710SRishi Srivatsavai for (i = 0; i < nfwd; i++) 87884eaa4710SRishi Srivatsavai show_bridge_fwd(handle, blf + i, 87894eaa4710SRishi Srivatsavai &brstate.state); 87904eaa4710SRishi Srivatsavai dladm_bridge_free_fwdtable(blf); 87914eaa4710SRishi Srivatsavai } 87924eaa4710SRishi Srivatsavai break; 87934eaa4710SRishi Srivatsavai } 87944eaa4710SRishi Srivatsavai 87954eaa4710SRishi Srivatsavai case trillMode: { 87964eaa4710SRishi Srivatsavai trill_listnick_t *tln; 87974eaa4710SRishi Srivatsavai uint_t i, nnick; 87984eaa4710SRishi Srivatsavai 87994eaa4710SRishi Srivatsavai tln = dladm_bridge_get_trillnick(brstate.bridge, 88004eaa4710SRishi Srivatsavai &nnick); 88014eaa4710SRishi Srivatsavai if (tln == NULL) { 88024eaa4710SRishi Srivatsavai if (errno == ENOENT) 88034eaa4710SRishi Srivatsavai die("bridge %s is not running TRILL", 88044eaa4710SRishi Srivatsavai brstate.bridge); 88054eaa4710SRishi Srivatsavai else 88064eaa4710SRishi Srivatsavai die("unable to get TRILL nickname " 88074eaa4710SRishi Srivatsavai "entries for bridge %s", 88084eaa4710SRishi Srivatsavai brstate.bridge); 88094eaa4710SRishi Srivatsavai } else { 88104eaa4710SRishi Srivatsavai for (i = 0; i < nnick; i++) 88114eaa4710SRishi Srivatsavai show_bridge_trillnick(tln + i, 88124eaa4710SRishi Srivatsavai &brstate.state); 88134eaa4710SRishi Srivatsavai dladm_bridge_free_trillnick(tln); 88144eaa4710SRishi Srivatsavai } 88154eaa4710SRishi Srivatsavai break; 88164eaa4710SRishi Srivatsavai } 88174eaa4710SRishi Srivatsavai } 88184eaa4710SRishi Srivatsavai if (interval == 0) 88194eaa4710SRishi Srivatsavai break; 88204eaa4710SRishi Srivatsavai (void) sleep(interval); 88214eaa4710SRishi Srivatsavai } 88224eaa4710SRishi Srivatsavai } 88234eaa4710SRishi Srivatsavai 8824d62bc4baSyz147064 /* 8825d62bc4baSyz147064 * "-R" option support. It is used for live upgrading. Append dladm commands 8826d62bc4baSyz147064 * to a upgrade script which will be run when the alternative root boots up: 8827d62bc4baSyz147064 * 8828b9e076dcSyz147064 * - If the /etc/dladm/datalink.conf file exists on the alternative root, 8829b9e076dcSyz147064 * append dladm commands to the <altroot>/var/svc/profile/upgrade_datalink 8830b9e076dcSyz147064 * script. This script will be run as part of the network/physical service. 8831b9e076dcSyz147064 * We cannot defer this to /var/svc/profile/upgrade because then the 8832b9e076dcSyz147064 * configuration will not be able to take effect before network/physical 8833b9e076dcSyz147064 * plumbs various interfaces. 8834d62bc4baSyz147064 * 8835b9e076dcSyz147064 * - If the /etc/dladm/datalink.conf file does not exist on the alternative 8836b9e076dcSyz147064 * root, append dladm commands to the <altroot>/var/svc/profile/upgrade script, 8837b9e076dcSyz147064 * which will be run in the manifest-import service. 8838d62bc4baSyz147064 * 8839d62bc4baSyz147064 * Note that the SMF team is considering to move the manifest-import service 8840d62bc4baSyz147064 * to be run at the very begining of boot. Once that is done, the need for 8841d62bc4baSyz147064 * the /var/svc/profile/upgrade_datalink script will not exist any more. 8842d62bc4baSyz147064 */ 8843d62bc4baSyz147064 static void 8844d62bc4baSyz147064 altroot_cmd(char *altroot, int argc, char *argv[]) 8845d62bc4baSyz147064 { 8846d62bc4baSyz147064 char path[MAXPATHLEN]; 8847d62bc4baSyz147064 struct stat stbuf; 8848d62bc4baSyz147064 FILE *fp; 8849d62bc4baSyz147064 int i; 8850d62bc4baSyz147064 8851d62bc4baSyz147064 /* 8852b9e076dcSyz147064 * Check for the existence of the /etc/dladm/datalink.conf 8853b9e076dcSyz147064 * configuration file, and determine the name of script file. 8854d62bc4baSyz147064 */ 8855b9e076dcSyz147064 (void) snprintf(path, MAXPATHLEN, "/%s/etc/dladm/datalink.conf", 8856b9e076dcSyz147064 altroot); 8857d62bc4baSyz147064 if (stat(path, &stbuf) < 0) { 8858d62bc4baSyz147064 (void) snprintf(path, MAXPATHLEN, "/%s/%s", altroot, 8859d62bc4baSyz147064 SMF_UPGRADE_FILE); 8860d62bc4baSyz147064 } else { 8861d62bc4baSyz147064 (void) snprintf(path, MAXPATHLEN, "/%s/%s", altroot, 8862d62bc4baSyz147064 SMF_UPGRADEDATALINK_FILE); 8863d62bc4baSyz147064 } 8864d62bc4baSyz147064 8865d62bc4baSyz147064 if ((fp = fopen(path, "a+")) == NULL) 8866d62bc4baSyz147064 die("operation not supported on %s", altroot); 8867d62bc4baSyz147064 8868d62bc4baSyz147064 (void) fprintf(fp, "/sbin/dladm "); 8869d62bc4baSyz147064 for (i = 0; i < argc; i++) { 8870d62bc4baSyz147064 /* 8871d62bc4baSyz147064 * Directly write to the file if it is not the "-R <altroot>" 8872d62bc4baSyz147064 * option. In which case, skip it. 8873d62bc4baSyz147064 */ 8874d62bc4baSyz147064 if (strcmp(argv[i], "-R") != 0) 8875d62bc4baSyz147064 (void) fprintf(fp, "%s ", argv[i]); 8876d62bc4baSyz147064 else 8877d62bc4baSyz147064 i ++; 8878d62bc4baSyz147064 } 8879d62bc4baSyz147064 (void) fprintf(fp, "%s\n", SMF_DLADM_UPGRADE_MSG); 8880d62bc4baSyz147064 (void) fclose(fp); 88814ac67f02SAnurag S. Maskey dladm_close(handle); 88822b24ab6bSSebastien Roy exit(EXIT_SUCCESS); 8883d62bc4baSyz147064 } 8884d62bc4baSyz147064 8885d62bc4baSyz147064 /* 8886d62bc4baSyz147064 * Convert the string to an integer. Note that the string must not have any 8887d62bc4baSyz147064 * trailing non-integer characters. 8888d62bc4baSyz147064 */ 888933343a97Smeem static boolean_t 889033343a97Smeem str2int(const char *str, int *valp) 889133343a97Smeem { 889233343a97Smeem int val; 889333343a97Smeem char *endp = NULL; 889433343a97Smeem 889533343a97Smeem errno = 0; 889633343a97Smeem val = strtol(str, &endp, 10); 889733343a97Smeem if (errno != 0 || *endp != '\0') 889833343a97Smeem return (B_FALSE); 889933343a97Smeem 890033343a97Smeem *valp = val; 890133343a97Smeem return (B_TRUE); 890233343a97Smeem } 890333343a97Smeem 890433343a97Smeem /* PRINTFLIKE1 */ 890533343a97Smeem static void 890633343a97Smeem warn(const char *format, ...) 890733343a97Smeem { 890833343a97Smeem va_list alist; 890933343a97Smeem 891033343a97Smeem format = gettext(format); 891133343a97Smeem (void) fprintf(stderr, "%s: warning: ", progname); 891233343a97Smeem 891333343a97Smeem va_start(alist, format); 891433343a97Smeem (void) vfprintf(stderr, format, alist); 891533343a97Smeem va_end(alist); 891633343a97Smeem 89170dc2366fSVenugopal Iyer (void) putc('\n', stderr); 891833343a97Smeem } 891933343a97Smeem 892033343a97Smeem /* PRINTFLIKE2 */ 892133343a97Smeem static void 892233343a97Smeem warn_dlerr(dladm_status_t err, const char *format, ...) 892333343a97Smeem { 892433343a97Smeem va_list alist; 892533343a97Smeem char errmsg[DLADM_STRSIZE]; 892633343a97Smeem 892733343a97Smeem format = gettext(format); 892833343a97Smeem (void) fprintf(stderr, gettext("%s: warning: "), progname); 892933343a97Smeem 893033343a97Smeem va_start(alist, format); 893133343a97Smeem (void) vfprintf(stderr, format, alist); 893233343a97Smeem va_end(alist); 893333343a97Smeem (void) fprintf(stderr, ": %s\n", dladm_status2str(err, errmsg)); 893433343a97Smeem } 893533343a97Smeem 89364ac67f02SAnurag S. Maskey /* 89374ac67f02SAnurag S. Maskey * Also closes the dladm handle if it is not NULL. 89384ac67f02SAnurag S. Maskey */ 893933343a97Smeem /* PRINTFLIKE2 */ 894033343a97Smeem static void 894133343a97Smeem die_dlerr(dladm_status_t err, const char *format, ...) 894233343a97Smeem { 894333343a97Smeem va_list alist; 894433343a97Smeem char errmsg[DLADM_STRSIZE]; 894533343a97Smeem 894633343a97Smeem format = gettext(format); 894733343a97Smeem (void) fprintf(stderr, "%s: ", progname); 894833343a97Smeem 894933343a97Smeem va_start(alist, format); 895033343a97Smeem (void) vfprintf(stderr, format, alist); 895133343a97Smeem va_end(alist); 895233343a97Smeem (void) fprintf(stderr, ": %s\n", dladm_status2str(err, errmsg)); 895333343a97Smeem 89544ac67f02SAnurag S. Maskey /* close dladm handle if it was opened */ 89554ac67f02SAnurag S. Maskey if (handle != NULL) 89564ac67f02SAnurag S. Maskey dladm_close(handle); 89574ac67f02SAnurag S. Maskey 895833343a97Smeem exit(EXIT_FAILURE); 895933343a97Smeem } 896033343a97Smeem 896133343a97Smeem /* PRINTFLIKE1 */ 896233343a97Smeem static void 896333343a97Smeem die(const char *format, ...) 896433343a97Smeem { 896533343a97Smeem va_list alist; 896633343a97Smeem 896733343a97Smeem format = gettext(format); 896833343a97Smeem (void) fprintf(stderr, "%s: ", progname); 896933343a97Smeem 897033343a97Smeem va_start(alist, format); 897133343a97Smeem (void) vfprintf(stderr, format, alist); 897233343a97Smeem va_end(alist); 897333343a97Smeem 89740dc2366fSVenugopal Iyer (void) putc('\n', stderr); 89754ac67f02SAnurag S. Maskey 89764ac67f02SAnurag S. Maskey /* close dladm handle if it was opened */ 89774ac67f02SAnurag S. Maskey if (handle != NULL) 89784ac67f02SAnurag S. Maskey dladm_close(handle); 89794ac67f02SAnurag S. Maskey 898033343a97Smeem exit(EXIT_FAILURE); 898133343a97Smeem } 898233343a97Smeem 898333343a97Smeem static void 898433343a97Smeem die_optdup(int opt) 898533343a97Smeem { 898633343a97Smeem die("the option -%c cannot be specified more than once", opt); 898733343a97Smeem } 898833343a97Smeem 898933343a97Smeem static void 89908d5c46e6Sam223141 die_opterr(int opt, int opterr, const char *usage) 899133343a97Smeem { 899233343a97Smeem switch (opterr) { 899333343a97Smeem case ':': 89948d5c46e6Sam223141 die("option '-%c' requires a value\nusage: %s", opt, 89958d5c46e6Sam223141 gettext(usage)); 899633343a97Smeem break; 899733343a97Smeem case '?': 899833343a97Smeem default: 89998d5c46e6Sam223141 die("unrecognized option '-%c'\nusage: %s", opt, 90008d5c46e6Sam223141 gettext(usage)); 900133343a97Smeem break; 90020ba2cbe9Sxc151355 } 90030ba2cbe9Sxc151355 } 9004e7801d59Ssowmini 9005e7801d59Ssowmini static void 90064784fcbdSSowmini Varadhan show_ether_xprop(void *arg, dladm_ether_info_t *eattr) 9007e7801d59Ssowmini { 9008e7801d59Ssowmini print_ether_state_t *statep = arg; 9009e7801d59Ssowmini ether_fields_buf_t ebuf; 90104784fcbdSSowmini Varadhan int i; 9011e7801d59Ssowmini 90124784fcbdSSowmini Varadhan for (i = CAPABLE; i <= PEERADV; i++) { 9013e7801d59Ssowmini bzero(&ebuf, sizeof (ebuf)); 90144784fcbdSSowmini Varadhan (void) strlcpy(ebuf.eth_ptype, ptype[i], 90154784fcbdSSowmini Varadhan sizeof (ebuf.eth_ptype)); 90164784fcbdSSowmini Varadhan (void) dladm_ether_autoneg2str(ebuf.eth_autoneg, 90174784fcbdSSowmini Varadhan sizeof (ebuf.eth_autoneg), eattr, i); 90184784fcbdSSowmini Varadhan (void) dladm_ether_spdx2str(ebuf.eth_spdx, 90194784fcbdSSowmini Varadhan sizeof (ebuf.eth_spdx), eattr, i); 90204784fcbdSSowmini Varadhan (void) dladm_ether_pause2str(ebuf.eth_pause, 90214784fcbdSSowmini Varadhan sizeof (ebuf.eth_pause), eattr, i); 90224784fcbdSSowmini Varadhan (void) strlcpy(ebuf.eth_rem_fault, 90234784fcbdSSowmini Varadhan (eattr->lei_attr[i].le_fault ? "fault" : "none"), 90244784fcbdSSowmini Varadhan sizeof (ebuf.eth_rem_fault)); 90258002d411SSowmini Varadhan ofmt_print(statep->es_ofmt, &ebuf); 9026e7801d59Ssowmini } 9027e7801d59Ssowmini 9028e7801d59Ssowmini } 9029e7801d59Ssowmini 9030e7801d59Ssowmini static boolean_t 9031e7801d59Ssowmini link_is_ether(const char *link, datalink_id_t *linkid) 9032e7801d59Ssowmini { 9033e7801d59Ssowmini uint32_t media; 9034e7801d59Ssowmini datalink_class_t class; 9035e7801d59Ssowmini 90364ac67f02SAnurag S. Maskey if (dladm_name2info(handle, link, linkid, NULL, &class, &media) == 9037e7801d59Ssowmini DLADM_STATUS_OK) { 9038e7801d59Ssowmini if (class == DATALINK_CLASS_PHYS && media == DL_ETHER) 9039e7801d59Ssowmini return (B_TRUE); 9040e7801d59Ssowmini } 9041e7801d59Ssowmini return (B_FALSE); 9042e7801d59Ssowmini } 90438002d411SSowmini Varadhan 90448002d411SSowmini Varadhan /* 90458002d411SSowmini Varadhan * default output callback function that, when invoked, 90468002d411SSowmini Varadhan * prints string which is offset by ofmt_arg->ofmt_id within buf. 90478002d411SSowmini Varadhan */ 90488002d411SSowmini Varadhan static boolean_t 90498002d411SSowmini Varadhan print_default_cb(ofmt_arg_t *ofarg, char *buf, uint_t bufsize) 90508002d411SSowmini Varadhan { 90518002d411SSowmini Varadhan char *value; 90528002d411SSowmini Varadhan 90538002d411SSowmini Varadhan value = (char *)ofarg->ofmt_cbarg + ofarg->ofmt_id; 90548002d411SSowmini Varadhan (void) strlcpy(buf, value, bufsize); 90558002d411SSowmini Varadhan return (B_TRUE); 90568002d411SSowmini Varadhan } 90578002d411SSowmini Varadhan 90588002d411SSowmini Varadhan static void 90598002d411SSowmini Varadhan dladm_ofmt_check(ofmt_status_t oferr, boolean_t parsable, 90608002d411SSowmini Varadhan ofmt_handle_t ofmt) 90618002d411SSowmini Varadhan { 90628002d411SSowmini Varadhan char buf[OFMT_BUFSIZE]; 90638002d411SSowmini Varadhan 90648002d411SSowmini Varadhan if (oferr == OFMT_SUCCESS) 90658002d411SSowmini Varadhan return; 90668002d411SSowmini Varadhan (void) ofmt_strerror(ofmt, oferr, buf, sizeof (buf)); 90678002d411SSowmini Varadhan /* 90688002d411SSowmini Varadhan * All errors are considered fatal in parsable mode. 90698002d411SSowmini Varadhan * NOMEM errors are always fatal, regardless of mode. 90708002d411SSowmini Varadhan * For other errors, we print diagnostics in human-readable 90718002d411SSowmini Varadhan * mode and processs what we can. 90728002d411SSowmini Varadhan */ 90738002d411SSowmini Varadhan if (parsable || oferr == OFMT_ENOFIELDS) { 90748002d411SSowmini Varadhan ofmt_close(ofmt); 90758002d411SSowmini Varadhan die(buf); 90768002d411SSowmini Varadhan } else { 90778002d411SSowmini Varadhan warn(buf); 90788002d411SSowmini Varadhan } 90798002d411SSowmini Varadhan } 90801cfa752fSRamaswamy Tummala 90811cfa752fSRamaswamy Tummala /* 90821cfa752fSRamaswamy Tummala * Called from the walker dladm_walk_datalink_id() for each IB partition to 90831cfa752fSRamaswamy Tummala * display IB partition specific information. 90841cfa752fSRamaswamy Tummala */ 90851cfa752fSRamaswamy Tummala static dladm_status_t 90861cfa752fSRamaswamy Tummala print_part(show_part_state_t *state, datalink_id_t linkid) 90871cfa752fSRamaswamy Tummala { 90881cfa752fSRamaswamy Tummala dladm_part_attr_t attr; 90891cfa752fSRamaswamy Tummala dladm_status_t status; 90901cfa752fSRamaswamy Tummala dladm_conf_t conf; 90911cfa752fSRamaswamy Tummala char part_over[MAXLINKNAMELEN]; 90921cfa752fSRamaswamy Tummala char part_name[MAXLINKNAMELEN]; 90931cfa752fSRamaswamy Tummala part_fields_buf_t pbuf; 90941cfa752fSRamaswamy Tummala boolean_t force_in_conf = B_FALSE; 90951cfa752fSRamaswamy Tummala 90961cfa752fSRamaswamy Tummala /* 90971cfa752fSRamaswamy Tummala * Get the information about the IB partition from the partition 90981cfa752fSRamaswamy Tummala * datlink ID 'linkid'. 90991cfa752fSRamaswamy Tummala */ 91001cfa752fSRamaswamy Tummala if ((status = dladm_part_info(handle, linkid, &attr, state->ps_flags)) 91011cfa752fSRamaswamy Tummala != DLADM_STATUS_OK) 91021cfa752fSRamaswamy Tummala return (status); 91031cfa752fSRamaswamy Tummala 91041cfa752fSRamaswamy Tummala /* 91051cfa752fSRamaswamy Tummala * If an IB Phys link name was provided on the command line we have 91061cfa752fSRamaswamy Tummala * the Phys link's datalink ID in the ps_over_id field of the state 91071cfa752fSRamaswamy Tummala * structure. Proceed only if the IB partition represented by 'linkid' 91081cfa752fSRamaswamy Tummala * was created over Phys link denoted by ps_over_id. The 91091cfa752fSRamaswamy Tummala * 'dia_physlinkid' field of dladm_part_attr_t represents the IB Phys 91101cfa752fSRamaswamy Tummala * link over which the partition was created. 91111cfa752fSRamaswamy Tummala */ 91121cfa752fSRamaswamy Tummala if (state->ps_over_id != DATALINK_ALL_LINKID) 91131cfa752fSRamaswamy Tummala if (state->ps_over_id != attr.dia_physlinkid) 91141cfa752fSRamaswamy Tummala return (DLADM_STATUS_OK); 91151cfa752fSRamaswamy Tummala 91161cfa752fSRamaswamy Tummala /* 91171cfa752fSRamaswamy Tummala * The linkid argument passed to this function is the datalink ID 91181cfa752fSRamaswamy Tummala * of the IB Partition. Get the partitions name from this linkid. 91191cfa752fSRamaswamy Tummala */ 91201cfa752fSRamaswamy Tummala if (dladm_datalink_id2info(handle, linkid, NULL, NULL, 91211cfa752fSRamaswamy Tummala NULL, part_name, sizeof (part_name)) != DLADM_STATUS_OK) 91221cfa752fSRamaswamy Tummala return (DLADM_STATUS_BADARG); 91231cfa752fSRamaswamy Tummala 91241cfa752fSRamaswamy Tummala bzero(part_over, sizeof (part_over)); 91251cfa752fSRamaswamy Tummala 91261cfa752fSRamaswamy Tummala /* 91271cfa752fSRamaswamy Tummala * The 'dia_physlinkid' field contains the datalink ID of the IB Phys 91281cfa752fSRamaswamy Tummala * link over which the partition was created. Use this linkid to get the 91291cfa752fSRamaswamy Tummala * linkover field. 91301cfa752fSRamaswamy Tummala */ 91311cfa752fSRamaswamy Tummala if (dladm_datalink_id2info(handle, attr.dia_physlinkid, NULL, NULL, 91321cfa752fSRamaswamy Tummala NULL, part_over, sizeof (part_over)) != DLADM_STATUS_OK) 91331cfa752fSRamaswamy Tummala (void) sprintf(part_over, "?"); 91341cfa752fSRamaswamy Tummala state->ps_found = B_TRUE; 91351cfa752fSRamaswamy Tummala 91361cfa752fSRamaswamy Tummala /* 91371cfa752fSRamaswamy Tummala * Read the FFORCE field from this datalink's persistent configuration 91381cfa752fSRamaswamy Tummala * database line to determine if this datalink was created forcibly. 91391cfa752fSRamaswamy Tummala * If this datalink is a temporary datalink, then it will not have an 91401cfa752fSRamaswamy Tummala * entry in the persistent configuration, so check if force create flag 91411cfa752fSRamaswamy Tummala * is set in the partition attributes. 91421cfa752fSRamaswamy Tummala * 91431cfa752fSRamaswamy Tummala * We need this two level check since persistent partitions brought up 91441cfa752fSRamaswamy Tummala * by up-part during boot will have force create flag always set, since 91451cfa752fSRamaswamy Tummala * we want up-part to always succeed even if the port is currently down 91461cfa752fSRamaswamy Tummala * or P_Key is not yet available in the subnet. 91471cfa752fSRamaswamy Tummala */ 914832715170SCathy Zhou if ((status = dladm_getsnap_conf(handle, linkid, &conf)) == 91491cfa752fSRamaswamy Tummala DLADM_STATUS_OK) { 91501cfa752fSRamaswamy Tummala (void) dladm_get_conf_field(handle, conf, FFORCE, 91511cfa752fSRamaswamy Tummala &force_in_conf, sizeof (boolean_t)); 91521cfa752fSRamaswamy Tummala dladm_destroy_conf(handle, conf); 91531cfa752fSRamaswamy Tummala } else if (status == DLADM_STATUS_NOTFOUND) { 91541cfa752fSRamaswamy Tummala /* 91551cfa752fSRamaswamy Tummala * for a temp link the force create flag will determine 91561cfa752fSRamaswamy Tummala * whether it was created with force flag. 91571cfa752fSRamaswamy Tummala */ 9158c87dd6b7SRajkumar Sivaprakasam force_in_conf = ((attr.dia_flags & DLADM_PART_FORCE_CREATE) 91591cfa752fSRamaswamy Tummala != 0); 91601cfa752fSRamaswamy Tummala } 91611cfa752fSRamaswamy Tummala 91621cfa752fSRamaswamy Tummala (void) snprintf(pbuf.part_link, sizeof (pbuf.part_link), 91631cfa752fSRamaswamy Tummala "%s", part_name); 91641cfa752fSRamaswamy Tummala 91651cfa752fSRamaswamy Tummala (void) snprintf(pbuf.part_over, sizeof (pbuf.part_over), 91661cfa752fSRamaswamy Tummala "%s", part_over); 91671cfa752fSRamaswamy Tummala 91681cfa752fSRamaswamy Tummala (void) snprintf(pbuf.part_pkey, sizeof (pbuf.part_pkey), 91691cfa752fSRamaswamy Tummala "%X", attr.dia_pkey); 91701cfa752fSRamaswamy Tummala 91711cfa752fSRamaswamy Tummala (void) get_linkstate(pbuf.part_link, B_TRUE, pbuf.part_state); 91721cfa752fSRamaswamy Tummala 91731cfa752fSRamaswamy Tummala (void) snprintf(pbuf.part_flags, sizeof (pbuf.part_flags), 91741cfa752fSRamaswamy Tummala "%c----", force_in_conf ? 'f' : '-'); 91751cfa752fSRamaswamy Tummala 91761cfa752fSRamaswamy Tummala ofmt_print(state->ps_ofmt, &pbuf); 91771cfa752fSRamaswamy Tummala 91781cfa752fSRamaswamy Tummala return (DLADM_STATUS_OK); 91791cfa752fSRamaswamy Tummala } 91801cfa752fSRamaswamy Tummala 91811cfa752fSRamaswamy Tummala /* ARGSUSED */ 91821cfa752fSRamaswamy Tummala static int 91831cfa752fSRamaswamy Tummala show_part(dladm_handle_t dh, datalink_id_t linkid, void *arg) 91841cfa752fSRamaswamy Tummala { 91851cfa752fSRamaswamy Tummala ((show_part_state_t *)arg)->ps_status = print_part(arg, linkid); 91861cfa752fSRamaswamy Tummala return (DLADM_WALK_CONTINUE); 91871cfa752fSRamaswamy Tummala } 91881cfa752fSRamaswamy Tummala 91891cfa752fSRamaswamy Tummala /* 91901cfa752fSRamaswamy Tummala * Show the information about the IB partition objects. 91911cfa752fSRamaswamy Tummala */ 91921cfa752fSRamaswamy Tummala static void 91931cfa752fSRamaswamy Tummala do_show_part(int argc, char *argv[], const char *use) 91941cfa752fSRamaswamy Tummala { 91951cfa752fSRamaswamy Tummala int option; 91961cfa752fSRamaswamy Tummala boolean_t l_arg = B_FALSE; 91971cfa752fSRamaswamy Tummala uint32_t flags = DLADM_OPT_ACTIVE; 91981cfa752fSRamaswamy Tummala datalink_id_t linkid = DATALINK_ALL_LINKID; 91991cfa752fSRamaswamy Tummala datalink_id_t over_linkid = DATALINK_ALL_LINKID; 92001cfa752fSRamaswamy Tummala char over_link[MAXLINKNAMELEN]; 92011cfa752fSRamaswamy Tummala show_part_state_t state; 92021cfa752fSRamaswamy Tummala dladm_status_t status; 92031cfa752fSRamaswamy Tummala boolean_t o_arg = B_FALSE; 92041cfa752fSRamaswamy Tummala char *fields_str = NULL; 92051cfa752fSRamaswamy Tummala ofmt_handle_t ofmt; 92061cfa752fSRamaswamy Tummala ofmt_status_t oferr; 92071cfa752fSRamaswamy Tummala uint_t ofmtflags = 0; 92081cfa752fSRamaswamy Tummala 92091cfa752fSRamaswamy Tummala bzero(&state, sizeof (state)); 92101cfa752fSRamaswamy Tummala opterr = 0; 92111cfa752fSRamaswamy Tummala while ((option = getopt_long(argc, argv, ":pPl:o:", show_part_lopts, 92121cfa752fSRamaswamy Tummala NULL)) != -1) { 92131cfa752fSRamaswamy Tummala switch (option) { 92141cfa752fSRamaswamy Tummala case 'p': 92151cfa752fSRamaswamy Tummala state.ps_parsable = B_TRUE; 92161cfa752fSRamaswamy Tummala break; 92171cfa752fSRamaswamy Tummala case 'P': 92181cfa752fSRamaswamy Tummala flags = DLADM_OPT_PERSIST; 92191cfa752fSRamaswamy Tummala break; 92201cfa752fSRamaswamy Tummala case 'l': 92211cfa752fSRamaswamy Tummala /* 92221cfa752fSRamaswamy Tummala * The data link ID of the IB Phys link. When this 92231cfa752fSRamaswamy Tummala * argument is provided we list only the partition 92241cfa752fSRamaswamy Tummala * objects created over this IB Phys link. 92251cfa752fSRamaswamy Tummala */ 92261cfa752fSRamaswamy Tummala if (strlcpy(over_link, optarg, MAXLINKNAMELEN) >= 92271cfa752fSRamaswamy Tummala MAXLINKNAMELEN) 92281cfa752fSRamaswamy Tummala die("link name too long"); 92291cfa752fSRamaswamy Tummala 92301cfa752fSRamaswamy Tummala l_arg = B_TRUE; 92311cfa752fSRamaswamy Tummala break; 92321cfa752fSRamaswamy Tummala case 'o': 92331cfa752fSRamaswamy Tummala o_arg = B_TRUE; 92341cfa752fSRamaswamy Tummala fields_str = optarg; 92351cfa752fSRamaswamy Tummala break; 92361cfa752fSRamaswamy Tummala default: 92371cfa752fSRamaswamy Tummala die_opterr(optopt, option, use); 92381cfa752fSRamaswamy Tummala } 92391cfa752fSRamaswamy Tummala } 92401cfa752fSRamaswamy Tummala 92411cfa752fSRamaswamy Tummala /* 92421cfa752fSRamaswamy Tummala * Get the partition ID (optional last argument). 92431cfa752fSRamaswamy Tummala */ 92441cfa752fSRamaswamy Tummala if (optind == (argc - 1)) { 92451cfa752fSRamaswamy Tummala status = dladm_name2info(handle, argv[optind], &linkid, NULL, 92461cfa752fSRamaswamy Tummala NULL, NULL); 92471cfa752fSRamaswamy Tummala if (status != DLADM_STATUS_OK) { 92481cfa752fSRamaswamy Tummala die_dlerr(status, "invalid partition link name '%s'", 92491cfa752fSRamaswamy Tummala argv[optind]); 92501cfa752fSRamaswamy Tummala } 92511cfa752fSRamaswamy Tummala (void) strlcpy(state.ps_part, argv[optind], MAXLINKNAMELEN); 92521cfa752fSRamaswamy Tummala } else if (optind != argc) { 92531cfa752fSRamaswamy Tummala usage(); 92541cfa752fSRamaswamy Tummala } 92551cfa752fSRamaswamy Tummala 92561cfa752fSRamaswamy Tummala if (state.ps_parsable && !o_arg) 92571cfa752fSRamaswamy Tummala die("-p requires -o"); 92581cfa752fSRamaswamy Tummala 92591cfa752fSRamaswamy Tummala /* 92601cfa752fSRamaswamy Tummala * If an IB Phys link name was provided as an argument, then get its 92611cfa752fSRamaswamy Tummala * datalink ID. 92621cfa752fSRamaswamy Tummala */ 92631cfa752fSRamaswamy Tummala if (l_arg) { 92641cfa752fSRamaswamy Tummala status = dladm_name2info(handle, over_link, &over_linkid, NULL, 92651cfa752fSRamaswamy Tummala NULL, NULL); 92661cfa752fSRamaswamy Tummala if (status != DLADM_STATUS_OK) { 92671cfa752fSRamaswamy Tummala die_dlerr(status, "invalid link name '%s'", over_link); 92681cfa752fSRamaswamy Tummala } 92691cfa752fSRamaswamy Tummala } 92701cfa752fSRamaswamy Tummala 92711cfa752fSRamaswamy Tummala state.ps_over_id = over_linkid; /* IB Phys link ID */ 92721cfa752fSRamaswamy Tummala state.ps_found = B_FALSE; 92731cfa752fSRamaswamy Tummala state.ps_flags = flags; 92741cfa752fSRamaswamy Tummala 92751cfa752fSRamaswamy Tummala if (state.ps_parsable) 92761cfa752fSRamaswamy Tummala ofmtflags |= OFMT_PARSABLE; 92771cfa752fSRamaswamy Tummala oferr = ofmt_open(fields_str, part_fields, ofmtflags, 0, &ofmt); 92781cfa752fSRamaswamy Tummala dladm_ofmt_check(oferr, state.ps_parsable, ofmt); 92791cfa752fSRamaswamy Tummala state.ps_ofmt = ofmt; 92801cfa752fSRamaswamy Tummala 92811cfa752fSRamaswamy Tummala /* 92821cfa752fSRamaswamy Tummala * If a specific IB partition name was not provided as an argument, 92831cfa752fSRamaswamy Tummala * walk all the datalinks and display the information for all 92841cfa752fSRamaswamy Tummala * IB partitions. If IB Phys link was provided limit it to only 92851cfa752fSRamaswamy Tummala * IB partitions created over that IB Phys link. 92861cfa752fSRamaswamy Tummala */ 92871cfa752fSRamaswamy Tummala if (linkid == DATALINK_ALL_LINKID) { 92881cfa752fSRamaswamy Tummala (void) dladm_walk_datalink_id(show_part, handle, &state, 92891cfa752fSRamaswamy Tummala DATALINK_CLASS_PART, DATALINK_ANY_MEDIATYPE, flags); 92901cfa752fSRamaswamy Tummala } else { 92911cfa752fSRamaswamy Tummala (void) show_part(handle, linkid, &state); 92921cfa752fSRamaswamy Tummala if (state.ps_status != DLADM_STATUS_OK) { 92931cfa752fSRamaswamy Tummala ofmt_close(ofmt); 92941cfa752fSRamaswamy Tummala die_dlerr(state.ps_status, "failed to show IB partition" 92951cfa752fSRamaswamy Tummala " '%s'", state.ps_part); 92961cfa752fSRamaswamy Tummala } 92971cfa752fSRamaswamy Tummala } 92981cfa752fSRamaswamy Tummala ofmt_close(ofmt); 92991cfa752fSRamaswamy Tummala } 93001cfa752fSRamaswamy Tummala 93011cfa752fSRamaswamy Tummala 93021cfa752fSRamaswamy Tummala /* 93031cfa752fSRamaswamy Tummala * Called from the walker dladm_walk_datalink_id() for each IB Phys link to 93041cfa752fSRamaswamy Tummala * display IB specific information for these Phys links. 93051cfa752fSRamaswamy Tummala */ 93061cfa752fSRamaswamy Tummala static dladm_status_t 93071cfa752fSRamaswamy Tummala print_ib(show_ib_state_t *state, datalink_id_t phys_linkid) 93081cfa752fSRamaswamy Tummala { 93091cfa752fSRamaswamy Tummala dladm_ib_attr_t attr; 93101cfa752fSRamaswamy Tummala dladm_status_t status; 93111cfa752fSRamaswamy Tummala char linkname[MAXLINKNAMELEN]; 93121cfa752fSRamaswamy Tummala char pkeystr[MAXPKEYLEN]; 93131cfa752fSRamaswamy Tummala int i; 93141cfa752fSRamaswamy Tummala ib_fields_buf_t ibuf; 93151cfa752fSRamaswamy Tummala 93161cfa752fSRamaswamy Tummala bzero(&attr, sizeof (attr)); 93171cfa752fSRamaswamy Tummala 93181cfa752fSRamaswamy Tummala /* 93191cfa752fSRamaswamy Tummala * Get the attributes of the IB Phys link from active/Persistent config 93201cfa752fSRamaswamy Tummala * based on the flag passed. 93211cfa752fSRamaswamy Tummala */ 93221cfa752fSRamaswamy Tummala if ((status = dladm_ib_info(handle, phys_linkid, &attr, 93231cfa752fSRamaswamy Tummala state->is_flags)) != DLADM_STATUS_OK) 93241cfa752fSRamaswamy Tummala return (status); 93251cfa752fSRamaswamy Tummala 93261cfa752fSRamaswamy Tummala if ((state->is_link_id != DATALINK_ALL_LINKID) && (state->is_link_id 93271cfa752fSRamaswamy Tummala != attr.dia_physlinkid)) { 93281cfa752fSRamaswamy Tummala dladm_free_ib_info(&attr); 93291cfa752fSRamaswamy Tummala return (DLADM_STATUS_OK); 93301cfa752fSRamaswamy Tummala } 93311cfa752fSRamaswamy Tummala 93321cfa752fSRamaswamy Tummala /* 93331cfa752fSRamaswamy Tummala * Get the data link name for the phys_linkid. If we are doing show-ib 93341cfa752fSRamaswamy Tummala * for all IB Phys links, we have only the datalink IDs not the 93351cfa752fSRamaswamy Tummala * datalink name. 93361cfa752fSRamaswamy Tummala */ 93371cfa752fSRamaswamy Tummala if (dladm_datalink_id2info(handle, phys_linkid, NULL, NULL, NULL, 93381cfa752fSRamaswamy Tummala linkname, MAXLINKNAMELEN) != DLADM_STATUS_OK) 93391cfa752fSRamaswamy Tummala return (status); 93401cfa752fSRamaswamy Tummala 93411cfa752fSRamaswamy Tummala (void) snprintf(ibuf.ib_link, sizeof (ibuf.ib_link), 93421cfa752fSRamaswamy Tummala "%s", linkname); 93431cfa752fSRamaswamy Tummala 93441cfa752fSRamaswamy Tummala (void) snprintf(ibuf.ib_portnum, sizeof (ibuf.ib_portnum), 93451cfa752fSRamaswamy Tummala "%d", attr.dia_portnum); 93461cfa752fSRamaswamy Tummala 93471cfa752fSRamaswamy Tummala (void) snprintf(ibuf.ib_hcaguid, sizeof (ibuf.ib_hcaguid), 93481cfa752fSRamaswamy Tummala "%llX", attr.dia_hca_guid); 93491cfa752fSRamaswamy Tummala 93501cfa752fSRamaswamy Tummala (void) snprintf(ibuf.ib_portguid, sizeof (ibuf.ib_portguid), 93511cfa752fSRamaswamy Tummala "%llX", attr.dia_port_guid); 93521cfa752fSRamaswamy Tummala 93531cfa752fSRamaswamy Tummala (void) get_linkstate(linkname, B_TRUE, ibuf.ib_state); 93541cfa752fSRamaswamy Tummala 93551cfa752fSRamaswamy Tummala /* 93561cfa752fSRamaswamy Tummala * Create a comma separated list of pkeys from the pkey table returned 93571cfa752fSRamaswamy Tummala * by the IP over IB driver instance. 93581cfa752fSRamaswamy Tummala */ 93591cfa752fSRamaswamy Tummala bzero(ibuf.ib_pkeys, attr.dia_port_pkey_tbl_sz * sizeof (ib_pkey_t)); 93601cfa752fSRamaswamy Tummala for (i = 0; i < attr.dia_port_pkey_tbl_sz; i++) { 93611cfa752fSRamaswamy Tummala if (attr.dia_port_pkeys[i] != IB_PKEY_INVALID_FULL && 93621cfa752fSRamaswamy Tummala attr.dia_port_pkeys[i] != IB_PKEY_INVALID_LIMITED) { 93631cfa752fSRamaswamy Tummala if (i == 0) 93641cfa752fSRamaswamy Tummala (void) snprintf(pkeystr, MAXPKEYLEN, "%X", 93651cfa752fSRamaswamy Tummala attr.dia_port_pkeys[i]); 93661cfa752fSRamaswamy Tummala else 93671cfa752fSRamaswamy Tummala (void) snprintf(pkeystr, MAXPKEYLEN, ",%X", 93681cfa752fSRamaswamy Tummala attr.dia_port_pkeys[i]); 93691cfa752fSRamaswamy Tummala (void) strlcat(ibuf.ib_pkeys, pkeystr, MAXPKEYSTRSZ); 93701cfa752fSRamaswamy Tummala } 93711cfa752fSRamaswamy Tummala } 93721cfa752fSRamaswamy Tummala 93731cfa752fSRamaswamy Tummala dladm_free_ib_info(&attr); 93741cfa752fSRamaswamy Tummala 93751cfa752fSRamaswamy Tummala ofmt_print(state->is_ofmt, &ibuf); 93761cfa752fSRamaswamy Tummala 93771cfa752fSRamaswamy Tummala return (DLADM_STATUS_OK); 93781cfa752fSRamaswamy Tummala } 93791cfa752fSRamaswamy Tummala 93801cfa752fSRamaswamy Tummala /* ARGSUSED */ 93811cfa752fSRamaswamy Tummala static int 93821cfa752fSRamaswamy Tummala show_ib(dladm_handle_t dh, datalink_id_t linkid, void *arg) 93831cfa752fSRamaswamy Tummala { 93841cfa752fSRamaswamy Tummala ((show_ib_state_t *)arg)->is_status = print_ib(arg, linkid); 93851cfa752fSRamaswamy Tummala return (DLADM_WALK_CONTINUE); 93861cfa752fSRamaswamy Tummala } 93871cfa752fSRamaswamy Tummala 93881cfa752fSRamaswamy Tummala /* 93891cfa752fSRamaswamy Tummala * Show the properties of one/all IB Phys links. This is different from 93901cfa752fSRamaswamy Tummala * show-phys command since this will display IB specific information about the 93911cfa752fSRamaswamy Tummala * Phys link like, HCA GUID, PORT GUID, PKEYS active for this port etc. 93921cfa752fSRamaswamy Tummala */ 93931cfa752fSRamaswamy Tummala static void 93941cfa752fSRamaswamy Tummala do_show_ib(int argc, char *argv[], const char *use) 93951cfa752fSRamaswamy Tummala { 93961cfa752fSRamaswamy Tummala int option; 93971cfa752fSRamaswamy Tummala uint32_t flags = DLADM_OPT_ACTIVE; 93981cfa752fSRamaswamy Tummala datalink_id_t linkid = DATALINK_ALL_LINKID; 93991cfa752fSRamaswamy Tummala show_ib_state_t state; 94001cfa752fSRamaswamy Tummala dladm_status_t status; 94011cfa752fSRamaswamy Tummala boolean_t o_arg = B_FALSE; 94021cfa752fSRamaswamy Tummala char *fields_str = NULL; 94031cfa752fSRamaswamy Tummala ofmt_handle_t ofmt; 94041cfa752fSRamaswamy Tummala ofmt_status_t oferr; 94051cfa752fSRamaswamy Tummala uint_t ofmtflags = 0; 94061cfa752fSRamaswamy Tummala 94071cfa752fSRamaswamy Tummala bzero(&state, sizeof (state)); 94081cfa752fSRamaswamy Tummala opterr = 0; 94091cfa752fSRamaswamy Tummala while ((option = getopt_long(argc, argv, ":po:", show_lopts, 94101cfa752fSRamaswamy Tummala NULL)) != -1) { 94111cfa752fSRamaswamy Tummala switch (option) { 94121cfa752fSRamaswamy Tummala case 'p': 94131cfa752fSRamaswamy Tummala state.is_parsable = B_TRUE; 94141cfa752fSRamaswamy Tummala break; 94151cfa752fSRamaswamy Tummala case 'o': 94161cfa752fSRamaswamy Tummala o_arg = B_TRUE; 94171cfa752fSRamaswamy Tummala fields_str = optarg; 94181cfa752fSRamaswamy Tummala break; 94191cfa752fSRamaswamy Tummala default: 94201cfa752fSRamaswamy Tummala die_opterr(optopt, option, use); 94211cfa752fSRamaswamy Tummala } 94221cfa752fSRamaswamy Tummala } 94231cfa752fSRamaswamy Tummala 94241cfa752fSRamaswamy Tummala /* get IB Phys link ID (optional last argument) */ 94251cfa752fSRamaswamy Tummala if (optind == (argc - 1)) { 94261cfa752fSRamaswamy Tummala status = dladm_name2info(handle, argv[optind], &linkid, NULL, 94271cfa752fSRamaswamy Tummala NULL, NULL); 94281cfa752fSRamaswamy Tummala if (status != DLADM_STATUS_OK) { 94291cfa752fSRamaswamy Tummala die_dlerr(status, "invalid IB port name '%s'", 94301cfa752fSRamaswamy Tummala argv[optind]); 94311cfa752fSRamaswamy Tummala } 94321cfa752fSRamaswamy Tummala (void) strlcpy(state.is_link, argv[optind], MAXLINKNAMELEN); 94331cfa752fSRamaswamy Tummala } else if (optind != argc) { 94341cfa752fSRamaswamy Tummala usage(); 94351cfa752fSRamaswamy Tummala } 94361cfa752fSRamaswamy Tummala 94371cfa752fSRamaswamy Tummala if (state.is_parsable && !o_arg) 94381cfa752fSRamaswamy Tummala die("-p requires -o"); 94391cfa752fSRamaswamy Tummala 94401cfa752fSRamaswamy Tummala /* 94411cfa752fSRamaswamy Tummala * linkid is the data link ID of the IB Phys link. By default it will 94421cfa752fSRamaswamy Tummala * be DATALINK_ALL_LINKID. 94431cfa752fSRamaswamy Tummala */ 94441cfa752fSRamaswamy Tummala state.is_link_id = linkid; 94451cfa752fSRamaswamy Tummala state.is_flags = flags; 94461cfa752fSRamaswamy Tummala 94471cfa752fSRamaswamy Tummala if (state.is_parsable) 94481cfa752fSRamaswamy Tummala ofmtflags |= OFMT_PARSABLE; 94491cfa752fSRamaswamy Tummala oferr = ofmt_open(fields_str, ib_fields, ofmtflags, 0, &ofmt); 94501cfa752fSRamaswamy Tummala dladm_ofmt_check(oferr, state.is_parsable, ofmt); 94511cfa752fSRamaswamy Tummala state.is_ofmt = ofmt; 94521cfa752fSRamaswamy Tummala 94531cfa752fSRamaswamy Tummala /* 94541cfa752fSRamaswamy Tummala * If we are going to display the information for all IB Phys links 94551cfa752fSRamaswamy Tummala * then we'll walk through all the datalinks for datalinks of Phys 94561cfa752fSRamaswamy Tummala * class and media type IB. 94571cfa752fSRamaswamy Tummala */ 94581cfa752fSRamaswamy Tummala if (linkid == DATALINK_ALL_LINKID) { 94591cfa752fSRamaswamy Tummala (void) dladm_walk_datalink_id(show_ib, handle, &state, 94601cfa752fSRamaswamy Tummala DATALINK_CLASS_PHYS, DL_IB, flags); 94611cfa752fSRamaswamy Tummala } else { 94621cfa752fSRamaswamy Tummala /* 94631cfa752fSRamaswamy Tummala * We need to display the information only for the IB phys link 94641cfa752fSRamaswamy Tummala * linkid. Call show_ib for this link. 94651cfa752fSRamaswamy Tummala */ 94661cfa752fSRamaswamy Tummala (void) show_ib(handle, linkid, &state); 94671cfa752fSRamaswamy Tummala if (state.is_status != DLADM_STATUS_OK) { 94681cfa752fSRamaswamy Tummala ofmt_close(ofmt); 94691cfa752fSRamaswamy Tummala die_dlerr(state.is_status, "failed to show IB Phys link" 94701cfa752fSRamaswamy Tummala " '%s'", state.is_link); 94711cfa752fSRamaswamy Tummala } 94721cfa752fSRamaswamy Tummala } 94731cfa752fSRamaswamy Tummala ofmt_close(ofmt); 94741cfa752fSRamaswamy Tummala } 94751cfa752fSRamaswamy Tummala 94761cfa752fSRamaswamy Tummala /* 94771cfa752fSRamaswamy Tummala * Create an IP over Infiniband partition object over an IB Phys link. The IB 94781cfa752fSRamaswamy Tummala * Phys link is associated with an Infiniband HCA port. The IB partition object 94791cfa752fSRamaswamy Tummala * is created over a port, pkey combination. This partition object represents 94801cfa752fSRamaswamy Tummala * an instance of IP over IB interface. 94811cfa752fSRamaswamy Tummala */ 94821cfa752fSRamaswamy Tummala /* ARGSUSED */ 94831cfa752fSRamaswamy Tummala static void 94841cfa752fSRamaswamy Tummala do_create_part(int argc, char *argv[], const char *use) 94851cfa752fSRamaswamy Tummala { 94861cfa752fSRamaswamy Tummala int status, option; 94871cfa752fSRamaswamy Tummala int flags = DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST; 94881cfa752fSRamaswamy Tummala char *pname; 94891cfa752fSRamaswamy Tummala char *l_arg = NULL; 94901cfa752fSRamaswamy Tummala char *altroot = NULL; 94911cfa752fSRamaswamy Tummala datalink_id_t physlinkid = 0; 94921cfa752fSRamaswamy Tummala datalink_id_t partlinkid = 0; 9493c87dd6b7SRajkumar Sivaprakasam unsigned long opt_pkey; 94941cfa752fSRamaswamy Tummala ib_pkey_t pkey = 0; 94951cfa752fSRamaswamy Tummala char *endp = NULL; 94961cfa752fSRamaswamy Tummala char propstr[DLADM_STRSIZE]; 94971cfa752fSRamaswamy Tummala dladm_arg_list_t *proplist = NULL; 94981cfa752fSRamaswamy Tummala 94991cfa752fSRamaswamy Tummala propstr[0] = '\0'; 95001cfa752fSRamaswamy Tummala while ((option = getopt_long(argc, argv, ":tfl:P:R:p:", 95011cfa752fSRamaswamy Tummala part_lopts, NULL)) != -1) { 95021cfa752fSRamaswamy Tummala switch (option) { 95031cfa752fSRamaswamy Tummala case 't': 95041cfa752fSRamaswamy Tummala /* 95051cfa752fSRamaswamy Tummala * Create a temporary IB partition object. This 95061cfa752fSRamaswamy Tummala * instance is not entered into the persistent database 95071cfa752fSRamaswamy Tummala * so it will not be recreated automatically on a 95081cfa752fSRamaswamy Tummala * reboot. 95091cfa752fSRamaswamy Tummala */ 95101cfa752fSRamaswamy Tummala flags &= ~DLADM_OPT_PERSIST; 95111cfa752fSRamaswamy Tummala break; 95121cfa752fSRamaswamy Tummala case 'l': 95131cfa752fSRamaswamy Tummala /* 95141cfa752fSRamaswamy Tummala * The IB phys link over which the partition object will 95151cfa752fSRamaswamy Tummala * be created. 95161cfa752fSRamaswamy Tummala */ 95171cfa752fSRamaswamy Tummala l_arg = optarg; 95181cfa752fSRamaswamy Tummala break; 95191cfa752fSRamaswamy Tummala case 'R': 95201cfa752fSRamaswamy Tummala altroot = optarg; 95211cfa752fSRamaswamy Tummala break; 95221cfa752fSRamaswamy Tummala case 'p': 95231cfa752fSRamaswamy Tummala (void) strlcat(propstr, optarg, DLADM_STRSIZE); 95241cfa752fSRamaswamy Tummala if (strlcat(propstr, ",", DLADM_STRSIZE) >= 95251cfa752fSRamaswamy Tummala DLADM_STRSIZE) 95261cfa752fSRamaswamy Tummala die("property list too long '%s'", propstr); 95271cfa752fSRamaswamy Tummala break; 95281cfa752fSRamaswamy Tummala case 'P': 95291cfa752fSRamaswamy Tummala /* 95301cfa752fSRamaswamy Tummala * The P_Key for the port, pkey tuple of the partition 95311cfa752fSRamaswamy Tummala * object. This P_Key should exist in the IB subnet. 95321cfa752fSRamaswamy Tummala * The partition creation for a non-existent P_Key will 95331cfa752fSRamaswamy Tummala * fail unless the -f option is used. 95341cfa752fSRamaswamy Tummala * 95351cfa752fSRamaswamy Tummala * The P_Key is expected to be a hexadecimal number. 95361cfa752fSRamaswamy Tummala */ 9537c87dd6b7SRajkumar Sivaprakasam opt_pkey = strtoul(optarg, &endp, 16); 9538c87dd6b7SRajkumar Sivaprakasam if (errno == ERANGE || opt_pkey > USHRT_MAX || 9539c87dd6b7SRajkumar Sivaprakasam *endp != '\0') 95401cfa752fSRamaswamy Tummala die("Invalid pkey"); 9541c87dd6b7SRajkumar Sivaprakasam 9542c87dd6b7SRajkumar Sivaprakasam pkey = (ib_pkey_t)opt_pkey; 95431cfa752fSRamaswamy Tummala break; 95441cfa752fSRamaswamy Tummala case 'f': 95451cfa752fSRamaswamy Tummala flags |= DLADM_OPT_FORCE; 95461cfa752fSRamaswamy Tummala break; 95471cfa752fSRamaswamy Tummala default: 95481cfa752fSRamaswamy Tummala die_opterr(optopt, option, use); 95491cfa752fSRamaswamy Tummala break; 95501cfa752fSRamaswamy Tummala } 95511cfa752fSRamaswamy Tummala } 95521cfa752fSRamaswamy Tummala 95531cfa752fSRamaswamy Tummala /* check required options */ 95541cfa752fSRamaswamy Tummala if (!l_arg) 95551cfa752fSRamaswamy Tummala usage(); 95561cfa752fSRamaswamy Tummala 95571cfa752fSRamaswamy Tummala /* the partition name is a required operand */ 95581cfa752fSRamaswamy Tummala if (optind != (argc - 1)) 95591cfa752fSRamaswamy Tummala usage(); 95601cfa752fSRamaswamy Tummala 95611cfa752fSRamaswamy Tummala pname = argv[argc - 1]; 95621cfa752fSRamaswamy Tummala 95631cfa752fSRamaswamy Tummala /* 95641cfa752fSRamaswamy Tummala * Verify that the partition object's name is in the valid link name 95651cfa752fSRamaswamy Tummala * format. 95661cfa752fSRamaswamy Tummala */ 95671cfa752fSRamaswamy Tummala if (!dladm_valid_linkname(pname)) 95681cfa752fSRamaswamy Tummala die("Invalid link name '%s'", pname); 95691cfa752fSRamaswamy Tummala 95701cfa752fSRamaswamy Tummala /* pkey is a mandatory argument */ 95711cfa752fSRamaswamy Tummala if (pkey == 0) 95721cfa752fSRamaswamy Tummala usage(); 95731cfa752fSRamaswamy Tummala 95741cfa752fSRamaswamy Tummala if (altroot != NULL) 95751cfa752fSRamaswamy Tummala altroot_cmd(altroot, argc, argv); 95761cfa752fSRamaswamy Tummala 95771cfa752fSRamaswamy Tummala /* 95781cfa752fSRamaswamy Tummala * Get the data link id of the IB Phys link over which we will be 95791cfa752fSRamaswamy Tummala * creating partition object. 95801cfa752fSRamaswamy Tummala */ 95811cfa752fSRamaswamy Tummala if (dladm_name2info(handle, l_arg, 95821cfa752fSRamaswamy Tummala &physlinkid, NULL, NULL, NULL) != DLADM_STATUS_OK) 95831cfa752fSRamaswamy Tummala die("invalid link name '%s'", l_arg); 95841cfa752fSRamaswamy Tummala 95851cfa752fSRamaswamy Tummala /* 95861cfa752fSRamaswamy Tummala * parse the property list provided with -p option. 95871cfa752fSRamaswamy Tummala */ 95881cfa752fSRamaswamy Tummala if (dladm_parse_link_props(propstr, &proplist, B_FALSE) 95891cfa752fSRamaswamy Tummala != DLADM_STATUS_OK) 95901cfa752fSRamaswamy Tummala die("invalid IB partition property"); 95911cfa752fSRamaswamy Tummala 95921cfa752fSRamaswamy Tummala /* 95931cfa752fSRamaswamy Tummala * Call the library routine to create the partition object. 95941cfa752fSRamaswamy Tummala */ 95951cfa752fSRamaswamy Tummala status = dladm_part_create(handle, physlinkid, pkey, flags, pname, 95961cfa752fSRamaswamy Tummala &partlinkid, proplist); 95971cfa752fSRamaswamy Tummala if (status != DLADM_STATUS_OK) 95981cfa752fSRamaswamy Tummala die_dlerr(status, 95991cfa752fSRamaswamy Tummala "partition %x creation over %s failed", pkey, l_arg); 96001cfa752fSRamaswamy Tummala } 96011cfa752fSRamaswamy Tummala 96021cfa752fSRamaswamy Tummala /* 96031cfa752fSRamaswamy Tummala * Delete an IP over Infiniband partition object. The partition object should 96041cfa752fSRamaswamy Tummala * be unplumbed before attempting the delete. 96051cfa752fSRamaswamy Tummala */ 96061cfa752fSRamaswamy Tummala static void 96071cfa752fSRamaswamy Tummala do_delete_part(int argc, char *argv[], const char *use) 96081cfa752fSRamaswamy Tummala { 96091cfa752fSRamaswamy Tummala int option, flags = DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST; 96101cfa752fSRamaswamy Tummala int status; 96111cfa752fSRamaswamy Tummala char *altroot = NULL; 96121cfa752fSRamaswamy Tummala datalink_id_t partid; 96131cfa752fSRamaswamy Tummala 96141cfa752fSRamaswamy Tummala opterr = 0; 96151cfa752fSRamaswamy Tummala while ((option = getopt_long(argc, argv, "R:t", part_lopts, 96161cfa752fSRamaswamy Tummala NULL)) != -1) { 96171cfa752fSRamaswamy Tummala switch (option) { 96181cfa752fSRamaswamy Tummala case 't': 96191cfa752fSRamaswamy Tummala flags &= ~DLADM_OPT_PERSIST; 96201cfa752fSRamaswamy Tummala break; 96211cfa752fSRamaswamy Tummala case 'R': 96221cfa752fSRamaswamy Tummala altroot = optarg; 96231cfa752fSRamaswamy Tummala break; 96241cfa752fSRamaswamy Tummala default: 96251cfa752fSRamaswamy Tummala die_opterr(optopt, option, use); 96261cfa752fSRamaswamy Tummala } 96271cfa752fSRamaswamy Tummala } 96281cfa752fSRamaswamy Tummala 96291cfa752fSRamaswamy Tummala /* get partition name (required last argument) */ 96301cfa752fSRamaswamy Tummala if (optind != (argc - 1)) 96311cfa752fSRamaswamy Tummala usage(); 96321cfa752fSRamaswamy Tummala 96331cfa752fSRamaswamy Tummala if (altroot != NULL) 96341cfa752fSRamaswamy Tummala altroot_cmd(altroot, argc, argv); 96351cfa752fSRamaswamy Tummala 96361cfa752fSRamaswamy Tummala /* 96371cfa752fSRamaswamy Tummala * Get the data link id of the partition object given the partition 96381cfa752fSRamaswamy Tummala * name. 96391cfa752fSRamaswamy Tummala */ 96401cfa752fSRamaswamy Tummala status = dladm_name2info(handle, argv[optind], &partid, NULL, NULL, 96411cfa752fSRamaswamy Tummala NULL); 96421cfa752fSRamaswamy Tummala if (status != DLADM_STATUS_OK) 96431cfa752fSRamaswamy Tummala die("invalid link name '%s'", argv[optind]); 96441cfa752fSRamaswamy Tummala 96451cfa752fSRamaswamy Tummala /* 96461cfa752fSRamaswamy Tummala * Call the library routine to delete the IB partition. This will 96471cfa752fSRamaswamy Tummala * result in the IB partition object and all its resources getting 96481cfa752fSRamaswamy Tummala * deleted. 96491cfa752fSRamaswamy Tummala */ 96501cfa752fSRamaswamy Tummala status = dladm_part_delete(handle, partid, flags); 96511cfa752fSRamaswamy Tummala if (status != DLADM_STATUS_OK) 96521cfa752fSRamaswamy Tummala die_dlerr(status, "%s: partition deletion failed", 96531cfa752fSRamaswamy Tummala argv[optind]); 96541cfa752fSRamaswamy Tummala } 96551cfa752fSRamaswamy Tummala 96561cfa752fSRamaswamy Tummala /* 96571cfa752fSRamaswamy Tummala * Bring up all or one IB partition already present in the persistent database 96581cfa752fSRamaswamy Tummala * but not active yet. 96591cfa752fSRamaswamy Tummala * 96601cfa752fSRamaswamy Tummala * This sub-command is used during the system boot up to bring up all IB 96611cfa752fSRamaswamy Tummala * partitions present in the persistent database. This is similar to a 96621cfa752fSRamaswamy Tummala * create partition except that, the partitions are always created even if the 96631cfa752fSRamaswamy Tummala * HCA port is down or P_Key is not present in the IB subnet. This is similar 96641cfa752fSRamaswamy Tummala * to using the 'force' option while creating the partition except that the 'f' 96651cfa752fSRamaswamy Tummala * flag will be set in the flags field only if the create-part for this command 96661cfa752fSRamaswamy Tummala * was called with '-f' option. 96671cfa752fSRamaswamy Tummala */ 96681cfa752fSRamaswamy Tummala /* ARGSUSED */ 96691cfa752fSRamaswamy Tummala static void 96701cfa752fSRamaswamy Tummala do_up_part(int argc, char *argv[], const char *use) 96711cfa752fSRamaswamy Tummala { 96721cfa752fSRamaswamy Tummala datalink_id_t partid = DATALINK_ALL_LINKID; 96731cfa752fSRamaswamy Tummala dladm_status_t status; 96741cfa752fSRamaswamy Tummala 96751cfa752fSRamaswamy Tummala /* 96761cfa752fSRamaswamy Tummala * If a partition name was passed as an argument, get its data link 96771cfa752fSRamaswamy Tummala * id. By default we'll attempt to bring up all IB partition data 96781cfa752fSRamaswamy Tummala * links. 96791cfa752fSRamaswamy Tummala */ 96801cfa752fSRamaswamy Tummala if (argc == 2) { 96811cfa752fSRamaswamy Tummala status = dladm_name2info(handle, argv[argc - 1], &partid, NULL, 96821cfa752fSRamaswamy Tummala NULL, NULL); 96831cfa752fSRamaswamy Tummala if (status != DLADM_STATUS_OK) 96841cfa752fSRamaswamy Tummala return; 96851cfa752fSRamaswamy Tummala } else if (argc > 2) { 96861cfa752fSRamaswamy Tummala usage(); 96871cfa752fSRamaswamy Tummala } 96881cfa752fSRamaswamy Tummala 96891cfa752fSRamaswamy Tummala (void) dladm_part_up(handle, partid, 0); 96901cfa752fSRamaswamy Tummala } 9691