46 #include <priv.h>
47 #include <limits.h>
48 #include <termios.h>
49 #include <pwd.h>
50 #include <auth_attr.h>
51 #include <auth_list.h>
52 #include <libintl.h>
53 #include <libdevinfo.h>
54 #include <libdlpi.h>
55 #include <libdladm.h>
56 #include <libdllink.h>
57 #include <libdlstat.h>
58 #include <libdlaggr.h>
59 #include <libdlwlan.h>
60 #include <libdlvlan.h>
61 #include <libdlvnic.h>
62 #include <libdlib.h>
63 #include <libdlether.h>
64 #include <libdliptun.h>
65 #include <libdlsim.h>
66 #include <libdlbridge.h>
67 #include <libdloverlay.h>
68 #include <libinetutil.h>
69 #include <libvrrpadm.h>
70 #include <bsm/adt.h>
71 #include <bsm/adt_event.h>
72 #include <libdlvnic.h>
73 #include <sys/types.h>
74 #include <sys/socket.h>
75 #include <sys/ib/ib_types.h>
76 #include <sys/processor.h>
77 #include <netinet/in.h>
78 #include <arpa/inet.h>
79 #include <net/if_types.h>
80 #include <stddef.h>
81 #include <stp_in.h>
82 #include <ofmt.h>
83 #include <libcustr.h>
84
85 #define MAXPORT 256
209 typedef void cmdfunc_t(int, char **, const char *);
210
211 static cmdfunc_t do_show_link, do_show_wifi, do_show_phys;
212 static cmdfunc_t do_create_aggr, do_delete_aggr, do_add_aggr, do_remove_aggr;
213 static cmdfunc_t do_modify_aggr, do_show_aggr, do_up_aggr;
214 static cmdfunc_t do_scan_wifi, do_connect_wifi, do_disconnect_wifi;
215 static cmdfunc_t do_show_linkprop, do_set_linkprop, do_reset_linkprop;
216 static cmdfunc_t do_create_secobj, do_delete_secobj, do_show_secobj;
217 static cmdfunc_t do_init_linkprop, do_init_secobj;
218 static cmdfunc_t do_create_vlan, do_delete_vlan, do_up_vlan, do_show_vlan;
219 static cmdfunc_t do_rename_link, do_delete_phys, do_init_phys;
220 static cmdfunc_t do_show_linkmap;
221 static cmdfunc_t do_show_ether;
222 static cmdfunc_t do_create_vnic, do_delete_vnic, do_show_vnic;
223 static cmdfunc_t do_up_vnic;
224 static cmdfunc_t do_create_part, do_delete_part, do_show_part, do_show_ib;
225 static cmdfunc_t do_up_part;
226 static cmdfunc_t do_create_etherstub, do_delete_etherstub, do_show_etherstub;
227 static cmdfunc_t do_create_simnet, do_modify_simnet;
228 static cmdfunc_t do_delete_simnet, do_show_simnet, do_up_simnet;
229 static cmdfunc_t do_show_usage;
230 static cmdfunc_t do_create_bridge, do_modify_bridge, do_delete_bridge;
231 static cmdfunc_t do_add_bridge, do_remove_bridge, do_show_bridge;
232 static cmdfunc_t do_create_iptun, do_modify_iptun, do_delete_iptun;
233 static cmdfunc_t do_show_iptun, do_up_iptun, do_down_iptun;
234 static cmdfunc_t do_create_overlay, do_delete_overlay, do_modify_overlay;
235 static cmdfunc_t do_show_overlay, do_up_overlay;
236
237 static void do_up_vnic_common(int, char **, const char *, boolean_t);
238
239 static int show_part(dladm_handle_t, datalink_id_t, void *);
240
241 static void altroot_cmd(char *, int, char **);
242 static int show_linkprop_onelink(dladm_handle_t, datalink_id_t, void *);
243
244 static void link_stats(datalink_id_t, uint_t, char *, show_state_t *);
245 static void aggr_stats(datalink_id_t, show_grp_state_t *, uint_t);
246 static void vnic_stats(show_vnic_state_t *, uint32_t);
247
248 static int get_one_kstat(const char *, const char *, uint8_t,
374 "\t\t [-R <root-dir>] <part-link>" },
375 { "delete-part", do_delete_part,
376 " delete-part [-t] [-R <root-dir>] <part-link>"},
377 { "show-part", do_show_part,
378 " show-part [-pP] [-o <field>,...][-l <linkover>]\n"
379 "\t\t [<part-link>]" },
380 { "show-ib", do_show_ib,
381 " show-ib [-p] [-o <field>,...] [<link>]\n" },
382 { "up-part", do_up_part, NULL },
383 { "create-etherstub", do_create_etherstub,
384 " create-etherstub [-t] <link>" },
385 { "delete-etherstub", do_delete_etherstub,
386 " delete-etherstub [-t] <link>" },
387 { "show-etherstub", do_show_etherstub,
388 " show-etherstub [-t] [<link>]\n" },
389 { "create-simnet", do_create_simnet, NULL },
390 { "modify-simnet", do_modify_simnet, NULL },
391 { "delete-simnet", do_delete_simnet, NULL },
392 { "show-simnet", do_show_simnet, NULL },
393 { "up-simnet", do_up_simnet, NULL },
394 { "create-bridge", do_create_bridge,
395 " create-bridge [-R <root-dir>] [-P <protect>] "
396 "[-p <priority>]\n"
397 "\t\t [-m <max-age>] [-h <hello-time>] [-d <forward-delay>]\n"
398 "\t\t [-f <force-protocol>] [-l <link>]... <bridge>" },
399 { "modify-bridge", do_modify_bridge,
400 " modify-bridge [-R <root-dir>] [-P <protect>] "
401 "[-p <priority>]\n"
402 "\t\t [-m <max-age>] [-h <hello-time>] [-d <forward-delay>]\n"
403 "\t\t [-f <force-protocol>] <bridge>" },
404 { "delete-bridge", do_delete_bridge,
405 " delete-bridge [-R <root-dir>] <bridge>" },
406 { "add-bridge", do_add_bridge,
407 " add-bridge [-R <root-dir>] -l <link> [-l <link>]... "
408 "<bridge>" },
409 { "remove-bridge", do_remove_bridge,
410 " remove-bridge [-R <root-dir>] -l <link> [-l <link>]... "
411 "<bridge>" },
412 { "show-bridge", do_show_bridge,
413 " show-bridge [-p] [-o <field>,...] [-s [-i <interval>]] "
572 {"root-dir", required_argument, 0, 'R' },
573 { NULL, 0, NULL, 0 }
574 };
575
576 static const struct option usage_opts[] = {
577 {"file", required_argument, 0, 'f' },
578 {"format", required_argument, 0, 'F' },
579 {"start", required_argument, 0, 's' },
580 {"stop", required_argument, 0, 'e' },
581 { NULL, 0, NULL, 0 }
582 };
583
584 static const struct option simnet_lopts[] = {
585 {"temporary", no_argument, 0, 't' },
586 {"root-dir", required_argument, 0, 'R' },
587 {"media", required_argument, 0, 'm' },
588 {"peer", required_argument, 0, 'p' },
589 { NULL, 0, NULL, 0 }
590 };
591
592 static const struct option bridge_lopts[] = {
593 { "protect", required_argument, 0, 'P' },
594 { "root-dir", required_argument, 0, 'R' },
595 { "forward-delay", required_argument, 0, 'd' },
596 { "force-protocol", required_argument, 0, 'f' },
597 { "hello-time", required_argument, 0, 'h' },
598 { "link", required_argument, 0, 'l' },
599 { "max-age", required_argument, 0, 'm' },
600 { "priority", required_argument, 0, 'p' },
601 { NULL, 0, NULL, 0 }
602 };
603
604 static const struct option bridge_show_lopts[] = {
605 { "forwarding", no_argument, 0, 'f' },
606 { "interval", required_argument, 0, 'i' },
607 { "link", no_argument, 0, 'l' },
608 { "output", required_argument, 0, 'o' },
609 { "parsable", no_argument, 0, 'p' },
610 { "parseable", no_argument, 0, 'p' },
611 { "statistics", no_argument, 0, 's' },
1121 {
1122 char simnet_name[DLPI_LINKNAME_MAX];
1123 char simnet_media[DLADM_STRSIZE];
1124 char simnet_macaddr[18];
1125 char simnet_otherlink[DLPI_LINKNAME_MAX];
1126 } simnet_fields_buf_t;
1127
1128 static const ofmt_field_t simnet_fields[] = {
1129 { "LINK", 12,
1130 offsetof(simnet_fields_buf_t, simnet_name), print_default_cb},
1131 { "MEDIA", 20,
1132 offsetof(simnet_fields_buf_t, simnet_media), print_default_cb},
1133 { "MACADDRESS", 18,
1134 offsetof(simnet_fields_buf_t, simnet_macaddr), print_default_cb},
1135 { "OTHERLINK", 12,
1136 offsetof(simnet_fields_buf_t, simnet_otherlink), print_default_cb},
1137 { NULL, 0, 0, NULL}}
1138 ;
1139
1140 /*
1141 * structures for 'dladm show-usage'
1142 */
1143
1144 typedef struct usage_fields_buf_s {
1145 char usage_link[12];
1146 char usage_duration[10];
1147 char usage_ipackets[9];
1148 char usage_rbytes[10];
1149 char usage_opackets[9];
1150 char usage_obytes[10];
1151 char usage_bandwidth[15];
1152 } usage_fields_buf_t;
1153
1154 static const ofmt_field_t usage_fields[] = {
1155 { "LINK", 13,
1156 offsetof(usage_fields_buf_t, usage_link), print_default_cb},
1157 { "DURATION", 11,
1158 offsetof(usage_fields_buf_t, usage_duration), print_default_cb},
1159 { "IPACKETS", 10,
1160 offsetof(usage_fields_buf_t, usage_ipackets), print_default_cb},
2880 break;
2881 }
2882
2883 case DATALINK_CLASS_SIMNET: {
2884 dladm_simnet_attr_t slinfo;
2885
2886 if (dladm_simnet_info(handle, linkid, &slinfo, flags) !=
2887 DLADM_STATUS_OK) {
2888 (void) strcpy(lbuf->link_over, "?");
2889 break;
2890 }
2891 if (slinfo.sna_peer_link_id != DATALINK_INVALID_LINKID) {
2892 if (dladm_datalink_id2info(handle,
2893 slinfo.sna_peer_link_id, NULL, NULL, NULL,
2894 lbuf->link_over, sizeof (lbuf->link_over)) !=
2895 DLADM_STATUS_OK)
2896 (void) strcpy(lbuf->link_over, "?");
2897 }
2898 break;
2899 }
2900 }
2901 }
2902
2903 static dladm_status_t
2904 print_link(show_state_t *state, datalink_id_t linkid, link_fields_buf_t *lbuf)
2905 {
2906 char link[MAXLINKNAMELEN];
2907 datalink_class_t class;
2908 uint_t mtu;
2909 uint32_t flags;
2910 dladm_status_t status;
2911
2912 if ((status = dladm_datalink_id2info(handle, linkid, &flags, &class,
2913 NULL, link, sizeof (link))) != DLADM_STATUS_OK) {
2914 goto done;
2915 }
2916
2917 if (!(state->ls_flags & flags)) {
2918 status = DLADM_STATUS_NOTFOUND;
2919 goto done;
2920 }
5736 if (state.ls_parsable)
5737 ofmtflags |= OFMT_PARSABLE;
5738 oferr = ofmt_open(fields_str, simnet_fields, ofmtflags, 0, &ofmt);
5739 ofmt_check(oferr, state.ls_parsable, ofmt, die, warn);
5740 state.ls_ofmt = ofmt;
5741
5742 if (linkid == DATALINK_ALL_LINKID) {
5743 (void) dladm_walk_datalink_id(show_simnet, handle, &state,
5744 DATALINK_CLASS_SIMNET, DATALINK_ANY_MEDIATYPE, flags);
5745 } else {
5746 (void) show_simnet(handle, linkid, &state);
5747 if (state.ls_status != DLADM_STATUS_OK) {
5748 ofmt_close(ofmt);
5749 die_dlerr(state.ls_status, "failed to show simnet %s",
5750 argv[optind]);
5751 }
5752 }
5753 ofmt_close(ofmt);
5754 }
5755
5756 static void
5757 link_stats(datalink_id_t linkid, uint_t interval, char *fields_str,
5758 show_state_t *state)
5759 {
5760 ofmt_handle_t ofmt;
5761 ofmt_status_t oferr;
5762 uint_t ofmtflags = 0;
5763
5764 if (state->ls_parsable)
5765 ofmtflags |= OFMT_PARSABLE;
5766 oferr = ofmt_open(fields_str, link_s_fields, ofmtflags, 0, &ofmt);
5767 ofmt_check(oferr, state->ls_parsable, ofmt, die, warn);
5768 state->ls_ofmt = ofmt;
5769
5770 /*
5771 * If an interval is specified, continuously show the stats
5772 * only for the first MAC port.
5773 */
5774 state->ls_firstonly = (interval != 0);
5775
5776 for (;;) {
8015 MIN_FWDELAY(cfg));
8016 } else {
8017 die("max age too large: need age <= %d or forward "
8018 "delay >= %d",
8019 MAX_MAXAGE(cfg), MIN_FWDELAY(cfg));
8020 }
8021 }
8022
8023 if (altroot != NULL)
8024 altroot_cmd(altroot, argc, argv);
8025
8026 for (n = 0; n < nlink; n++) {
8027 datalink_class_t class;
8028 uint32_t media;
8029 char pointless[DLADM_STRSIZE];
8030
8031 if (dladm_name2info(handle, links[n], &linkids[n], NULL, &class,
8032 &media) != DLADM_STATUS_OK)
8033 die("invalid link name '%s'", links[n]);
8034 if (class & ~(DATALINK_CLASS_PHYS | DATALINK_CLASS_AGGR |
8035 DATALINK_CLASS_ETHERSTUB | DATALINK_CLASS_SIMNET))
8036 die("%s %s cannot be bridged",
8037 dladm_class2str(class, pointless), links[n]);
8038 if (media != DL_ETHER && media != DL_100VG &&
8039 media != DL_ETH_CSMA && media != DL_100BT)
8040 die("%s interface %s cannot be bridged",
8041 dladm_media2str(media, pointless), links[n]);
8042 }
8043
8044 if (func == brCreate)
8045 flags |= DLADM_OPT_CREATE;
8046
8047 if (func != brAdd) {
8048 status = dladm_bridge_configure(handle, bridge, &cfg, brprot,
8049 flags);
8050 if (status != DLADM_STATUS_OK)
8051 die_dlerr(status, "create operation failed");
8052 }
8053
8054 status = DLADM_STATUS_OK;
8055 for (n = 0; n < nlink; n++) {
|
46 #include <priv.h>
47 #include <limits.h>
48 #include <termios.h>
49 #include <pwd.h>
50 #include <auth_attr.h>
51 #include <auth_list.h>
52 #include <libintl.h>
53 #include <libdevinfo.h>
54 #include <libdlpi.h>
55 #include <libdladm.h>
56 #include <libdllink.h>
57 #include <libdlstat.h>
58 #include <libdlaggr.h>
59 #include <libdlwlan.h>
60 #include <libdlvlan.h>
61 #include <libdlvnic.h>
62 #include <libdlib.h>
63 #include <libdlether.h>
64 #include <libdliptun.h>
65 #include <libdlsim.h>
66 #include <libdlfeth.h>
67 #include <libdlbridge.h>
68 #include <libdloverlay.h>
69 #include <libinetutil.h>
70 #include <libvrrpadm.h>
71 #include <bsm/adt.h>
72 #include <bsm/adt_event.h>
73 #include <libdlvnic.h>
74 #include <sys/types.h>
75 #include <sys/socket.h>
76 #include <sys/ib/ib_types.h>
77 #include <sys/processor.h>
78 #include <netinet/in.h>
79 #include <arpa/inet.h>
80 #include <net/if_types.h>
81 #include <stddef.h>
82 #include <stp_in.h>
83 #include <ofmt.h>
84 #include <libcustr.h>
85
86 #define MAXPORT 256
210 typedef void cmdfunc_t(int, char **, const char *);
211
212 static cmdfunc_t do_show_link, do_show_wifi, do_show_phys;
213 static cmdfunc_t do_create_aggr, do_delete_aggr, do_add_aggr, do_remove_aggr;
214 static cmdfunc_t do_modify_aggr, do_show_aggr, do_up_aggr;
215 static cmdfunc_t do_scan_wifi, do_connect_wifi, do_disconnect_wifi;
216 static cmdfunc_t do_show_linkprop, do_set_linkprop, do_reset_linkprop;
217 static cmdfunc_t do_create_secobj, do_delete_secobj, do_show_secobj;
218 static cmdfunc_t do_init_linkprop, do_init_secobj;
219 static cmdfunc_t do_create_vlan, do_delete_vlan, do_up_vlan, do_show_vlan;
220 static cmdfunc_t do_rename_link, do_delete_phys, do_init_phys;
221 static cmdfunc_t do_show_linkmap;
222 static cmdfunc_t do_show_ether;
223 static cmdfunc_t do_create_vnic, do_delete_vnic, do_show_vnic;
224 static cmdfunc_t do_up_vnic;
225 static cmdfunc_t do_create_part, do_delete_part, do_show_part, do_show_ib;
226 static cmdfunc_t do_up_part;
227 static cmdfunc_t do_create_etherstub, do_delete_etherstub, do_show_etherstub;
228 static cmdfunc_t do_create_simnet, do_modify_simnet;
229 static cmdfunc_t do_delete_simnet, do_show_simnet, do_up_simnet;
230 static cmdfunc_t do_create_feth, do_delete_feth, do_show_feth, do_up_feth;
231 static cmdfunc_t do_show_usage;
232 static cmdfunc_t do_create_bridge, do_modify_bridge, do_delete_bridge;
233 static cmdfunc_t do_add_bridge, do_remove_bridge, do_show_bridge;
234 static cmdfunc_t do_create_iptun, do_modify_iptun, do_delete_iptun;
235 static cmdfunc_t do_show_iptun, do_up_iptun, do_down_iptun;
236 static cmdfunc_t do_create_overlay, do_delete_overlay, do_modify_overlay;
237 static cmdfunc_t do_show_overlay, do_up_overlay;
238
239 static void do_up_vnic_common(int, char **, const char *, boolean_t);
240
241 static int show_part(dladm_handle_t, datalink_id_t, void *);
242
243 static void altroot_cmd(char *, int, char **);
244 static int show_linkprop_onelink(dladm_handle_t, datalink_id_t, void *);
245
246 static void link_stats(datalink_id_t, uint_t, char *, show_state_t *);
247 static void aggr_stats(datalink_id_t, show_grp_state_t *, uint_t);
248 static void vnic_stats(show_vnic_state_t *, uint32_t);
249
250 static int get_one_kstat(const char *, const char *, uint8_t,
376 "\t\t [-R <root-dir>] <part-link>" },
377 { "delete-part", do_delete_part,
378 " delete-part [-t] [-R <root-dir>] <part-link>"},
379 { "show-part", do_show_part,
380 " show-part [-pP] [-o <field>,...][-l <linkover>]\n"
381 "\t\t [<part-link>]" },
382 { "show-ib", do_show_ib,
383 " show-ib [-p] [-o <field>,...] [<link>]\n" },
384 { "up-part", do_up_part, NULL },
385 { "create-etherstub", do_create_etherstub,
386 " create-etherstub [-t] <link>" },
387 { "delete-etherstub", do_delete_etherstub,
388 " delete-etherstub [-t] <link>" },
389 { "show-etherstub", do_show_etherstub,
390 " show-etherstub [-t] [<link>]\n" },
391 { "create-simnet", do_create_simnet, NULL },
392 { "modify-simnet", do_modify_simnet, NULL },
393 { "delete-simnet", do_delete_simnet, NULL },
394 { "show-simnet", do_show_simnet, NULL },
395 { "up-simnet", do_up_simnet, NULL },
396 { "create-feth", do_create_feth,
397 " create-feth [-t] [-s] [-R <root-dir>] [-m <mac address>] "
398 "<feth-link>" },
399 { "delete-feth", do_delete_feth,
400 " delete-feth [-R <root-dir>] <feth-link>" },
401 { "show-feth", do_show_feth,
402 " show-feth [-p] [-o <field>,...] [-P] [<feth-link>]" },
403 { "up-feth", do_up_feth,
404 " up-feth <feth-link>\n" },
405 { "create-bridge", do_create_bridge,
406 " create-bridge [-R <root-dir>] [-P <protect>] "
407 "[-p <priority>]\n"
408 "\t\t [-m <max-age>] [-h <hello-time>] [-d <forward-delay>]\n"
409 "\t\t [-f <force-protocol>] [-l <link>]... <bridge>" },
410 { "modify-bridge", do_modify_bridge,
411 " modify-bridge [-R <root-dir>] [-P <protect>] "
412 "[-p <priority>]\n"
413 "\t\t [-m <max-age>] [-h <hello-time>] [-d <forward-delay>]\n"
414 "\t\t [-f <force-protocol>] <bridge>" },
415 { "delete-bridge", do_delete_bridge,
416 " delete-bridge [-R <root-dir>] <bridge>" },
417 { "add-bridge", do_add_bridge,
418 " add-bridge [-R <root-dir>] -l <link> [-l <link>]... "
419 "<bridge>" },
420 { "remove-bridge", do_remove_bridge,
421 " remove-bridge [-R <root-dir>] -l <link> [-l <link>]... "
422 "<bridge>" },
423 { "show-bridge", do_show_bridge,
424 " show-bridge [-p] [-o <field>,...] [-s [-i <interval>]] "
583 {"root-dir", required_argument, 0, 'R' },
584 { NULL, 0, NULL, 0 }
585 };
586
587 static const struct option usage_opts[] = {
588 {"file", required_argument, 0, 'f' },
589 {"format", required_argument, 0, 'F' },
590 {"start", required_argument, 0, 's' },
591 {"stop", required_argument, 0, 'e' },
592 { NULL, 0, NULL, 0 }
593 };
594
595 static const struct option simnet_lopts[] = {
596 {"temporary", no_argument, 0, 't' },
597 {"root-dir", required_argument, 0, 'R' },
598 {"media", required_argument, 0, 'm' },
599 {"peer", required_argument, 0, 'p' },
600 { NULL, 0, NULL, 0 }
601 };
602
603 static const struct option feth_lopts[] = {
604 {"temporary", no_argument,0, 't' },
605 {"root-dir", required_argument, 0, 'R' },
606 { NULL, 0, NULL, 0 }
607 };
608
609 static const struct option bridge_lopts[] = {
610 { "protect", required_argument, 0, 'P' },
611 { "root-dir", required_argument, 0, 'R' },
612 { "forward-delay", required_argument, 0, 'd' },
613 { "force-protocol", required_argument, 0, 'f' },
614 { "hello-time", required_argument, 0, 'h' },
615 { "link", required_argument, 0, 'l' },
616 { "max-age", required_argument, 0, 'm' },
617 { "priority", required_argument, 0, 'p' },
618 { NULL, 0, NULL, 0 }
619 };
620
621 static const struct option bridge_show_lopts[] = {
622 { "forwarding", no_argument, 0, 'f' },
623 { "interval", required_argument, 0, 'i' },
624 { "link", no_argument, 0, 'l' },
625 { "output", required_argument, 0, 'o' },
626 { "parsable", no_argument, 0, 'p' },
627 { "parseable", no_argument, 0, 'p' },
628 { "statistics", no_argument, 0, 's' },
1138 {
1139 char simnet_name[DLPI_LINKNAME_MAX];
1140 char simnet_media[DLADM_STRSIZE];
1141 char simnet_macaddr[18];
1142 char simnet_otherlink[DLPI_LINKNAME_MAX];
1143 } simnet_fields_buf_t;
1144
1145 static const ofmt_field_t simnet_fields[] = {
1146 { "LINK", 12,
1147 offsetof(simnet_fields_buf_t, simnet_name), print_default_cb},
1148 { "MEDIA", 20,
1149 offsetof(simnet_fields_buf_t, simnet_media), print_default_cb},
1150 { "MACADDRESS", 18,
1151 offsetof(simnet_fields_buf_t, simnet_macaddr), print_default_cb},
1152 { "OTHERLINK", 12,
1153 offsetof(simnet_fields_buf_t, simnet_otherlink), print_default_cb},
1154 { NULL, 0, 0, NULL}}
1155 ;
1156
1157 /*
1158 * structures for 'dladm show-feth'
1159 */
1160
1161 typedef struct feth_fields_buf_s
1162 {
1163 char feth_name[DLPI_LINKNAME_MAX];
1164 char feth_macaddr[18];
1165 } feth_fields_buf_t;
1166
1167 static const ofmt_field_t feth_fields[] = {
1168 { "LINK",12,
1169 offsetof(feth_fields_buf_t, feth_name), print_default_cb},
1170 { "MACADDRESS",18,
1171 offsetof(feth_fields_buf_t, feth_macaddr), print_default_cb},
1172 { NULL,0, 0, NULL}}
1173 ;
1174
1175 /*
1176 * structures for 'dladm show-usage'
1177 */
1178
1179 typedef struct usage_fields_buf_s {
1180 char usage_link[12];
1181 char usage_duration[10];
1182 char usage_ipackets[9];
1183 char usage_rbytes[10];
1184 char usage_opackets[9];
1185 char usage_obytes[10];
1186 char usage_bandwidth[15];
1187 } usage_fields_buf_t;
1188
1189 static const ofmt_field_t usage_fields[] = {
1190 { "LINK", 13,
1191 offsetof(usage_fields_buf_t, usage_link), print_default_cb},
1192 { "DURATION", 11,
1193 offsetof(usage_fields_buf_t, usage_duration), print_default_cb},
1194 { "IPACKETS", 10,
1195 offsetof(usage_fields_buf_t, usage_ipackets), print_default_cb},
2915 break;
2916 }
2917
2918 case DATALINK_CLASS_SIMNET: {
2919 dladm_simnet_attr_t slinfo;
2920
2921 if (dladm_simnet_info(handle, linkid, &slinfo, flags) !=
2922 DLADM_STATUS_OK) {
2923 (void) strcpy(lbuf->link_over, "?");
2924 break;
2925 }
2926 if (slinfo.sna_peer_link_id != DATALINK_INVALID_LINKID) {
2927 if (dladm_datalink_id2info(handle,
2928 slinfo.sna_peer_link_id, NULL, NULL, NULL,
2929 lbuf->link_over, sizeof (lbuf->link_over)) !=
2930 DLADM_STATUS_OK)
2931 (void) strcpy(lbuf->link_over, "?");
2932 }
2933 break;
2934 }
2935
2936 case DATALINK_CLASS_FETH: {
2937 (void) strcpy(lbuf->link_over, "--");
2938 break;
2939 }
2940 }
2941 }
2942
2943 static dladm_status_t
2944 print_link(show_state_t *state, datalink_id_t linkid, link_fields_buf_t *lbuf)
2945 {
2946 char link[MAXLINKNAMELEN];
2947 datalink_class_t class;
2948 uint_t mtu;
2949 uint32_t flags;
2950 dladm_status_t status;
2951
2952 if ((status = dladm_datalink_id2info(handle, linkid, &flags, &class,
2953 NULL, link, sizeof (link))) != DLADM_STATUS_OK) {
2954 goto done;
2955 }
2956
2957 if (!(state->ls_flags & flags)) {
2958 status = DLADM_STATUS_NOTFOUND;
2959 goto done;
2960 }
5776 if (state.ls_parsable)
5777 ofmtflags |= OFMT_PARSABLE;
5778 oferr = ofmt_open(fields_str, simnet_fields, ofmtflags, 0, &ofmt);
5779 ofmt_check(oferr, state.ls_parsable, ofmt, die, warn);
5780 state.ls_ofmt = ofmt;
5781
5782 if (linkid == DATALINK_ALL_LINKID) {
5783 (void) dladm_walk_datalink_id(show_simnet, handle, &state,
5784 DATALINK_CLASS_SIMNET, DATALINK_ANY_MEDIATYPE, flags);
5785 } else {
5786 (void) show_simnet(handle, linkid, &state);
5787 if (state.ls_status != DLADM_STATUS_OK) {
5788 ofmt_close(ofmt);
5789 die_dlerr(state.ls_status, "failed to show simnet %s",
5790 argv[optind]);
5791 }
5792 }
5793 ofmt_close(ofmt);
5794 }
5795
5796 /* ARGSUSED */
5797 static void
5798 do_up_feth(int argc, char *argv[], const char *use)
5799 {
5800 (void) dladm_feth_up(handle, DATALINK_ALL_LINKID, 0);
5801 }
5802
5803 static void
5804 do_create_feth(int argc, char *argv[], const char *use)
5805 {
5806 uint32_t flags;
5807 char *altroot = NULL;
5808 int option;
5809 dladm_status_t status;
5810 char name[MAXLINKNAMELEN];
5811 boolean_t mac_provided = B_FALSE;
5812 boolean_t mac_fixed;
5813 uint8_t mac_addr[ETHERADDRL];
5814
5815 name[0] = '\0';
5816 flags = DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST;
5817
5818 opterr = 0;
5819 while ((option = getopt_long(argc, argv, ":tsR:m:",
5820 feth_lopts, NULL)) != -1) {
5821 switch (option) {
5822 case 't':
5823 flags &= ~DLADM_OPT_PERSIST;
5824 break;
5825 case 's':
5826 flags |= FETH_FLAG_SINGLESHOT;
5827 break;
5828 case 'R':
5829 altroot = optarg;
5830 break;
5831 case 'm':
5832 if (mac_provided == B_TRUE)
5833 die("cannot specify -m option twice");
5834
5835 if (!dladm_aggr_str2macaddr(optarg, &mac_fixed, mac_addr)) {
5836 die("invalid MAC address");
5837 }
5838 mac_provided = B_TRUE;
5839 printf("have mac address\n");
5840 break;
5841 default:
5842 die_opterr(optopt, option, use);
5843 }
5844 }
5845
5846 /* the simnet id is the required operand */
5847 if (optind != (argc - 1))
5848 usage();
5849
5850 if (strlcpy(name, argv[optind], MAXLINKNAMELEN) >= MAXLINKNAMELEN)
5851 die("link name too long '%s'", argv[optind]);
5852
5853 if (!dladm_valid_linkname(name))
5854 die("invalid link name '%s'", name);
5855
5856 if (altroot != NULL)
5857 altroot_cmd(altroot, argc, argv);
5858
5859 if(mac_provided)
5860 status = dladm_feth_create_mac(handle, name, flags, mac_addr);
5861 else
5862 status = dladm_feth_create(handle, name, flags);
5863 if (status != DLADM_STATUS_OK)
5864 die_dlerr(status, "feth creation failed");
5865 }
5866
5867 static void
5868 do_delete_feth(int argc, char *argv[], const char *use)
5869 {
5870 int option;
5871 uint32_t flags = DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST;
5872 datalink_id_t linkid;
5873 char *altroot = NULL;
5874 dladm_status_t status;
5875 dladm_feth_attr_t flinfo;
5876
5877 opterr = 0;
5878 while ((option = getopt_long(argc, argv, ":R:", feth_lopts,
5879 NULL)) != -1) {
5880 switch (option) {
5881 case 'R':
5882 altroot = optarg;
5883 break;
5884 default:
5885 die_opterr(optopt, option, use);
5886 }
5887 }
5888
5889 /* get feth name (required last argument) */
5890 if (optind != (argc - 1))
5891 usage();
5892
5893 if (!dladm_valid_linkname(argv[optind]))
5894 die("invalid link name '%s'", argv[optind]);
5895
5896 if (altroot != NULL)
5897 altroot_cmd(altroot, argc, argv);
5898
5899 status = dladm_name2info(handle, argv[optind], &linkid, NULL, NULL,
5900 NULL);
5901 if (status != DLADM_STATUS_OK)
5902 die("feth '%s' not found", argv[optind]);
5903
5904 if ((status = dladm_feth_info(handle, linkid, &flinfo,
5905 flags)) != DLADM_STATUS_OK)
5906 die_dlerr(status, "failed to retrieve feth information");
5907
5908 status = dladm_feth_delete(handle, linkid, flags);
5909 if (status != DLADM_STATUS_OK)
5910 die_dlerr(status, "feth deletion failed");
5911 }
5912
5913 static dladm_status_t
5914 print_feth(show_state_t *state, datalink_id_t linkid)
5915 {
5916 dladm_feth_attr_t flinfo;
5917 uint32_t flags;
5918 dladm_status_t status;
5919 feth_fields_buf_t flbuf;
5920 char mstr[ETHERADDRL * 3];
5921
5922 bzero(&flbuf, sizeof (flbuf));
5923 if ((status = dladm_datalink_id2info(handle, linkid, &flags, NULL, NULL,
5924 flbuf.feth_name, sizeof (flbuf.feth_name)))
5925 != DLADM_STATUS_OK)
5926 return (status);
5927
5928 if (!(state->ls_flags & flags))
5929 return (DLADM_STATUS_NOTFOUND);
5930
5931 if ((status = dladm_feth_info(handle, linkid, &flinfo,
5932 state->ls_flags)) != DLADM_STATUS_OK)
5933 return (status);
5934
5935 if (flinfo.sna_mac_len > sizeof (flbuf.feth_macaddr))
5936 return (DLADM_STATUS_BADVAL);
5937
5938 (void) strlcpy(flbuf.feth_macaddr,
5939 dladm_aggr_macaddr2str(flinfo.sna_mac_addr, mstr),
5940 sizeof (flbuf.feth_macaddr));
5941
5942 ofmt_print(state->ls_ofmt, &flbuf);
5943 return (status);
5944 }
5945
5946 /* ARGSUSED */
5947 static int
5948 show_feth(dladm_handle_t dh, datalink_id_t linkid, void *arg)
5949 {
5950 show_state_t* state = arg;
5951
5952 state->ls_status = print_feth(state, linkid);
5953 return (DLADM_WALK_CONTINUE);
5954 }
5955
5956 static void
5957 do_show_feth(int argc, char *argv[], const char *use)
5958 {
5959 int option;
5960 uint32_t flags = DLADM_OPT_ACTIVE;
5961 boolean_t p_arg = B_FALSE;
5962 datalink_id_t linkid = DATALINK_ALL_LINKID;
5963 show_state_t state;
5964 dladm_status_t status;
5965 boolean_t o_arg = B_FALSE;
5966 ofmt_handle_t ofmt;
5967 ofmt_status_t oferr;
5968 char *all_fields = "link,macaddress";
5969 char *fields_str = all_fields;
5970 uint_t ofmtflags = 0;
5971
5972 bzero(&state, sizeof (state));
5973
5974 opterr = 0;
5975 while ((option = getopt_long(argc, argv, ":pPo:",
5976 show_lopts, NULL)) != -1) {
5977 switch (option) {
5978 case 'p':
5979 if (p_arg)
5980 die_optdup(option);
5981
5982 p_arg = B_TRUE;
5983 state.ls_parsable = p_arg;
5984 break;
5985 case 'P':
5986 if (flags != DLADM_OPT_ACTIVE)
5987 die_optdup(option);
5988
5989 flags = DLADM_OPT_PERSIST;
5990 break;
5991 case 'o':
5992 o_arg = B_TRUE;
5993 fields_str = optarg;
5994 break;
5995 default:
5996 die_opterr(optopt, option, use);
5997 break;
5998 }
5999 }
6000
6001 if (p_arg && !o_arg)
6002 die("-p requires -o");
6003
6004 if (strcasecmp(fields_str, "all") == 0) {
6005 if (p_arg)
6006 die("\"-o all\" is invalid with -p");
6007 fields_str = all_fields;
6008 }
6009
6010 /* get link name (optional last argument) */
6011 if (optind == (argc-1)) {
6012 if ((status = dladm_name2info(handle, argv[optind], &linkid,
6013 NULL, NULL, NULL)) != DLADM_STATUS_OK) {
6014 die_dlerr(status, "link %s is not valid", argv[optind]);
6015 }
6016 } else if (optind != argc) {
6017 usage();
6018 }
6019
6020 state.ls_flags = flags;
6021 state.ls_donefirst = B_FALSE;
6022 if (state.ls_parsable)
6023 ofmtflags |= OFMT_PARSABLE;
6024 oferr = ofmt_open(fields_str, feth_fields, ofmtflags, 0, &ofmt);
6025 ofmt_check(oferr, state.ls_parsable, ofmt, die, warn);
6026 state.ls_ofmt = ofmt;
6027
6028 if (linkid == DATALINK_ALL_LINKID) {
6029 (void) dladm_walk_datalink_id(show_feth, handle, &state,
6030 DATALINK_CLASS_FETH, DATALINK_ANY_MEDIATYPE, flags);
6031 } else {
6032 (void) show_feth(handle, linkid, &state);
6033 if (state.ls_status != DLADM_STATUS_OK) {
6034 ofmt_close(ofmt);
6035 die_dlerr(state.ls_status, "failed to show feth %s",
6036 argv[optind]);
6037 }
6038 }
6039 ofmt_close(ofmt);
6040 }
6041
6042 static void
6043 link_stats(datalink_id_t linkid, uint_t interval, char *fields_str,
6044 show_state_t *state)
6045 {
6046 ofmt_handle_t ofmt;
6047 ofmt_status_t oferr;
6048 uint_t ofmtflags = 0;
6049
6050 if (state->ls_parsable)
6051 ofmtflags |= OFMT_PARSABLE;
6052 oferr = ofmt_open(fields_str, link_s_fields, ofmtflags, 0, &ofmt);
6053 ofmt_check(oferr, state->ls_parsable, ofmt, die, warn);
6054 state->ls_ofmt = ofmt;
6055
6056 /*
6057 * If an interval is specified, continuously show the stats
6058 * only for the first MAC port.
6059 */
6060 state->ls_firstonly = (interval != 0);
6061
6062 for (;;) {
8301 MIN_FWDELAY(cfg));
8302 } else {
8303 die("max age too large: need age <= %d or forward "
8304 "delay >= %d",
8305 MAX_MAXAGE(cfg), MIN_FWDELAY(cfg));
8306 }
8307 }
8308
8309 if (altroot != NULL)
8310 altroot_cmd(altroot, argc, argv);
8311
8312 for (n = 0; n < nlink; n++) {
8313 datalink_class_t class;
8314 uint32_t media;
8315 char pointless[DLADM_STRSIZE];
8316
8317 if (dladm_name2info(handle, links[n], &linkids[n], NULL, &class,
8318 &media) != DLADM_STATUS_OK)
8319 die("invalid link name '%s'", links[n]);
8320 if (class & ~(DATALINK_CLASS_PHYS | DATALINK_CLASS_AGGR |
8321 DATALINK_CLASS_ETHERSTUB | DATALINK_CLASS_SIMNET |
8322 DATALINK_CLASS_FETH))
8323 die("%s %s cannot be bridged",
8324 dladm_class2str(class, pointless), links[n]);
8325 if (media != DL_ETHER && media != DL_100VG &&
8326 media != DL_ETH_CSMA && media != DL_100BT)
8327 die("%s interface %s cannot be bridged",
8328 dladm_media2str(media, pointless), links[n]);
8329 }
8330
8331 if (func == brCreate)
8332 flags |= DLADM_OPT_CREATE;
8333
8334 if (func != brAdd) {
8335 status = dladm_bridge_configure(handle, bridge, &cfg, brprot,
8336 flags);
8337 if (status != DLADM_STATUS_OK)
8338 die_dlerr(status, "create operation failed");
8339 }
8340
8341 status = DLADM_STATUS_OK;
8342 for (n = 0; n < nlink; n++) {
|