66 #include <libdlvnic.h>
67 #include <sys/types.h>
68 #include <sys/socket.h>
69 #include <sys/ib/ib_types.h>
70 #include <sys/processor.h>
71 #include <netinet/in.h>
72 #include <arpa/inet.h>
73 #include <net/if_types.h>
74 #include <stddef.h>
75 #include <stp_in.h>
76 #include <ofmt.h>
77
78 #define MAXPORT 256
79 #define MAXVNIC 256
80 #define BUFLEN(lim, ptr) (((lim) > (ptr)) ? ((lim) - (ptr)) : 0)
81 #define MAXLINELEN 1024
82 #define SMF_UPGRADE_FILE "/var/svc/profile/upgrade"
83 #define SMF_UPGRADEDATALINK_FILE "/var/svc/profile/upgrade_datalink"
84 #define SMF_DLADM_UPGRADE_MSG " # added by dladm(1M)"
85 #define DLADM_DEFAULT_COL 80
86
87 /*
88 * used by the wifi show-* commands to set up ofmt_field_t structures.
89 */
90 #define WIFI_CMD_SCAN 0x00000001
91 #define WIFI_CMD_SHOW 0x00000002
92 #define WIFI_CMD_ALL (WIFI_CMD_SCAN | WIFI_CMD_SHOW)
93
94 /* No larger than pktsum_t */
95 typedef struct brsum_s {
96 uint64_t drops;
97 uint64_t forward_dir;
98 uint64_t forward_mb;
99 uint64_t forward_unk;
100 uint64_t recv;
101 uint64_t sent;
102 } brsum_t;
103
104 /* No larger than pktsum_t */
105 typedef struct brlsum_s {
202 static cmdfunc_t do_scan_wifi, do_connect_wifi, do_disconnect_wifi;
203 static cmdfunc_t do_show_linkprop, do_set_linkprop, do_reset_linkprop;
204 static cmdfunc_t do_create_secobj, do_delete_secobj, do_show_secobj;
205 static cmdfunc_t do_init_linkprop, do_init_secobj;
206 static cmdfunc_t do_create_vlan, do_delete_vlan, do_up_vlan, do_show_vlan;
207 static cmdfunc_t do_rename_link, do_delete_phys, do_init_phys;
208 static cmdfunc_t do_show_linkmap;
209 static cmdfunc_t do_show_ether;
210 static cmdfunc_t do_create_vnic, do_delete_vnic, do_show_vnic;
211 static cmdfunc_t do_up_vnic;
212 static cmdfunc_t do_create_part, do_delete_part, do_show_part, do_show_ib;
213 static cmdfunc_t do_up_part;
214 static cmdfunc_t do_create_etherstub, do_delete_etherstub, do_show_etherstub;
215 static cmdfunc_t do_create_simnet, do_modify_simnet;
216 static cmdfunc_t do_delete_simnet, do_show_simnet, do_up_simnet;
217 static cmdfunc_t do_show_usage;
218 static cmdfunc_t do_create_bridge, do_modify_bridge, do_delete_bridge;
219 static cmdfunc_t do_add_bridge, do_remove_bridge, do_show_bridge;
220 static cmdfunc_t do_create_iptun, do_modify_iptun, do_delete_iptun;
221 static cmdfunc_t do_show_iptun, do_up_iptun, do_down_iptun;
222
223 static void do_up_vnic_common(int, char **, const char *, boolean_t);
224
225 static int show_part(dladm_handle_t, datalink_id_t, void *);
226
227 static void altroot_cmd(char *, int, char **);
228 static int show_linkprop_onelink(dladm_handle_t, datalink_id_t, void *);
229
230 static void link_stats(datalink_id_t, uint_t, char *, show_state_t *);
231 static void aggr_stats(datalink_id_t, show_grp_state_t *, uint_t);
232 static void vnic_stats(show_vnic_state_t *, uint32_t);
233
234 static int get_one_kstat(const char *, const char *, uint8_t,
235 void *, boolean_t);
236 static void get_mac_stats(const char *, pktsum_t *);
237 static void get_link_stats(const char *, pktsum_t *);
238 static uint64_t get_ifspeed(const char *, boolean_t);
239 static const char *get_linkstate(const char *, boolean_t, char *);
240 static const char *get_linkduplex(const char *, boolean_t, char *);
241
250 static boolean_t link_is_ether(const char *, datalink_id_t *);
251
252 static boolean_t str2int(const char *, int *);
253 static void die(const char *, ...);
254 static void die_optdup(int);
255 static void die_opterr(int, int, const char *);
256 static void die_dlerr(dladm_status_t, const char *, ...);
257 static void warn(const char *, ...);
258 static void warn_dlerr(dladm_status_t, const char *, ...);
259
260 typedef struct cmd {
261 char *c_name;
262 cmdfunc_t *c_fn;
263 const char *c_usage;
264 } cmd_t;
265
266 static cmd_t cmds[] = {
267 { "rename-link", do_rename_link,
268 " rename-link <oldlink> <newlink>" },
269 { "show-link", do_show_link,
270 " show-link [-pP] [-o <field>,..] [-s [-i <interval>]] "
271 "[<link>]\n" },
272 { "create-aggr", do_create_aggr,
273 " create-aggr [-t] [-P <policy>] [-L <mode>] [-T <time>] "
274 "[-u <address>]\n"
275 "\t\t -l <link> [-l <link>...] <link>" },
276 { "delete-aggr", do_delete_aggr,
277 " delete-aggr [-t] <link>" },
278 { "add-aggr", do_add_aggr,
279 " add-aggr [-t] -l <link> [-l <link>...] <link>" },
280 { "remove-aggr", do_remove_aggr,
281 " remove-aggr [-t] -l <link> [-l <link>...] <link>" },
282 { "modify-aggr", do_modify_aggr,
283 " modify-aggr [-t] [-P <policy>] [-L <mode>] [-T <time>] "
284 "[-u <address>]\n"
285 "\t\t <link>" },
286 { "show-aggr", do_show_aggr,
287 " show-aggr [-pPLx] [-o <field>,..] [-s [-i <interval>]] "
288 "[<link>]\n" },
289 { "up-aggr", do_up_aggr, NULL },
290 { "scan-wifi", do_scan_wifi,
291 " scan-wifi [-p] [-o <field>,...] [<link>]" },
292 { "connect-wifi", do_connect_wifi,
293 " connect-wifi [-e <essid>] [-i <bssid>] [-k <key>,...] "
294 "[-s wep|wpa]\n"
295 "\t\t [-a open|shared] [-b bss|ibss] [-c] [-m a|b|g] "
296 "[-T <time>]\n"
297 "\t\t [<link>]" },
298 { "disconnect-wifi", do_disconnect_wifi,
299 " disconnect-wifi [-a] [<link>]" },
300 { "show-wifi", do_show_wifi,
301 " show-wifi [-p] [-o <field>,...] [<link>]\n" },
302 { "set-linkprop", do_set_linkprop,
303 " set-linkprop [-t] -p <prop>=<value>[,...] <name>" },
304 { "reset-linkprop", do_reset_linkprop,
305 " reset-linkprop [-t] [-p <prop>,...] <name>" },
306 { "show-linkprop", do_show_linkprop,
307 " show-linkprop [-cP] [-o <field>,...] [-p <prop>,...] "
308 "<name>\n" },
309 { "show-ether", do_show_ether,
310 " show-ether [-px][-o <field>,...] <link>\n" },
311 { "create-secobj", do_create_secobj,
312 " create-secobj [-t] [-f <file>] -c <class> <secobj>" },
313 { "delete-secobj", do_delete_secobj,
314 " delete-secobj [-t] <secobj>[,...]" },
315 { "show-secobj", do_show_secobj,
316 " show-secobj [-pP] [-o <field>,...] [<secobj>,...]\n" },
317 { "init-linkprop", do_init_linkprop, NULL },
318 { "init-secobj", do_init_secobj, NULL },
319 { "create-vlan", do_create_vlan,
320 " create-vlan [-ft] -l <link> -v <vid> [link]" },
321 { "delete-vlan", do_delete_vlan,
322 " delete-vlan [-t] <link>" },
323 { "show-vlan", do_show_vlan,
324 " show-vlan [-pP] [-o <field>,..] [<link>]\n" },
325 { "up-vlan", do_up_vlan, NULL },
326 { "create-iptun", do_create_iptun,
327 " create-iptun [-t] -T <type> "
328 "[-a {local|remote}=<addr>,...] <link>]" },
329 { "delete-iptun", do_delete_iptun,
330 " delete-iptun [-t] <link>" },
331 { "modify-iptun", do_modify_iptun,
332 " modify-iptun [-t] -a {local|remote}=<addr>,... <link>" },
333 { "show-iptun", do_show_iptun,
334 " show-iptun [-pP] [-o <field>,..] [<link>]\n" },
335 { "up-iptun", do_up_iptun, NULL },
336 { "down-iptun", do_down_iptun, NULL },
337 { "delete-phys", do_delete_phys,
338 " delete-phys <link>" },
339 { "show-phys", do_show_phys,
340 " show-phys [-pP] [-o <field>,..] [-H] [<link>]\n"},
341 { "init-phys", do_init_phys, NULL },
342 { "show-linkmap", do_show_linkmap, NULL },
343 { "create-vnic", do_create_vnic,
344 " create-vnic [-t] -l <link> [-m <value> | auto |\n"
345 "\t\t {factory [-n <slot-id>]} | {random [-r <prefix>]} |\n"
346 "\t\t {vrrp -V <vrid> -A {inet | inet6}} [-v <vid> [-f]]\n"
347 "\t\t [-p <prop>=<value>[,...]] <vnic-link>" },
348 { "delete-vnic", do_delete_vnic,
349 " delete-vnic [-t] <vnic-link>" },
350 { "show-vnic", do_show_vnic,
351 " show-vnic [-pP] [-l <link>] [-s [-i <interval>]] "
352 "[<link>]\n" },
353 { "up-vnic", do_up_vnic, NULL },
354 { "create-part", do_create_part,
355 " create-part [-t] [-f] -l <link> [-P <pkey>]\n"
356 "\t\t [-R <root-dir>] <part-link>" },
357 { "delete-part", do_delete_part,
358 " delete-part [-t] [-R <root-dir>] <part-link>"},
359 { "show-part", do_show_part,
360 " show-part [-pP] [-o <field>,...][-l <linkover>]\n"
361 "\t\t [<part-link>]" },
362 { "show-ib", do_show_ib,
363 " show-ib [-p] [-o <field>,...] [<link>]\n" },
364 { "up-part", do_up_part, NULL },
365 { "create-etherstub", do_create_etherstub,
366 " create-etherstub [-t] <link>" },
367 { "delete-etherstub", do_delete_etherstub,
368 " delete-etherstub [-t] <link>" },
369 { "show-etherstub", do_show_etherstub,
370 " show-etherstub [-t] [<link>]\n" },
371 { "create-simnet", do_create_simnet, NULL },
372 { "modify-simnet", do_modify_simnet, NULL },
373 { "delete-simnet", do_delete_simnet, NULL },
374 { "show-simnet", do_show_simnet, NULL },
375 { "up-simnet", do_up_simnet, NULL },
376 { "create-bridge", do_create_bridge,
377 " create-bridge [-R <root-dir>] [-P <protect>] "
378 "[-p <priority>]\n"
379 "\t\t [-m <max-age>] [-h <hello-time>] [-d <forward-delay>]\n"
380 "\t\t [-f <force-protocol>] [-l <link>]... <bridge>" },
381 { "modify-bridge", do_modify_bridge,
382 " modify-bridge [-R <root-dir>] [-P <protect>] "
383 "[-p <priority>]\n"
384 "\t\t [-m <max-age>] [-h <hello-time>] [-d <forward-delay>]\n"
385 "\t\t [-f <force-protocol>] <bridge>" },
386 { "delete-bridge", do_delete_bridge,
387 " delete-bridge [-R <root-dir>] <bridge>" },
388 { "add-bridge", do_add_bridge,
389 " add-bridge [-R <root-dir>] -l <link> [-l <link>]... "
390 "<bridge>" },
391 { "remove-bridge", do_remove_bridge,
392 " remove-bridge [-R <root-dir>] -l <link> [-l <link>]... "
393 "<bridge>" },
394 { "show-bridge", do_show_bridge,
395 " show-bridge [-p] [-o <field>,...] [-s [-i <interval>]] "
396 "[<bridge>]\n"
397 " show-bridge -l [-p] [-o <field>,...] [-s [-i <interval>]]"
398 " <bridge>\n"
399 " show-bridge -f [-p] [-o <field>,...] [-s [-i <interval>]]"
400 " <bridge>\n"
401 " show-bridge -t [-p] [-o <field>,...] [-s [-i <interval>]]"
402 " <bridge>\n" },
403 { "show-usage", do_show_usage,
404 " show-usage [-a] [-d | -F <format>] "
405 "[-s <DD/MM/YYYY,HH:MM:SS>]\n"
406 "\t\t [-e <DD/MM/YYYY,HH:MM:SS>] -f <logfile> [<link>]" }
407 };
408
409 static const struct option lopts[] = {
410 {"vlan-id", required_argument, 0, 'v'},
411 {"output", required_argument, 0, 'o'},
412 {"dev", required_argument, 0, 'd'},
413 {"policy", required_argument, 0, 'P'},
414 {"lacp-mode", required_argument, 0, 'L'},
415 {"lacp-timer", required_argument, 0, 'T'},
416 {"unicast", required_argument, 0, 'u'},
417 {"temporary", no_argument, 0, 't'},
418 {"root-dir", required_argument, 0, 'R'},
419 {"link", required_argument, 0, 'l'},
420 {"forcible", no_argument, 0, 'f'},
421 {"bw-limit", required_argument, 0, 'b'},
422 {"mac-address", required_argument, 0, 'm'},
423 {"slot", required_argument, 0, 'n'},
424 { 0, 0, 0, 0 }
425 };
426
1119 } usage_fields_buf_t;
1120
1121 static const ofmt_field_t usage_fields[] = {
1122 { "LINK", 13,
1123 offsetof(usage_fields_buf_t, usage_link), print_default_cb},
1124 { "DURATION", 11,
1125 offsetof(usage_fields_buf_t, usage_duration), print_default_cb},
1126 { "IPACKETS", 10,
1127 offsetof(usage_fields_buf_t, usage_ipackets), print_default_cb},
1128 { "RBYTES", 11,
1129 offsetof(usage_fields_buf_t, usage_rbytes), print_default_cb},
1130 { "OPACKETS", 10,
1131 offsetof(usage_fields_buf_t, usage_opackets), print_default_cb},
1132 { "OBYTES", 11,
1133 offsetof(usage_fields_buf_t, usage_obytes), print_default_cb},
1134 { "BANDWIDTH", 15,
1135 offsetof(usage_fields_buf_t, usage_bandwidth), print_default_cb},
1136 { NULL, 0, 0, NULL}}
1137 ;
1138
1139
1140 /*
1141 * structures for 'dladm show-usage link'
1142 */
1143
1144 typedef struct usage_l_fields_buf_s {
1145 char usage_l_link[12];
1146 char usage_l_stime[13];
1147 char usage_l_etime[13];
1148 char usage_l_rbytes[8];
1149 char usage_l_obytes[8];
1150 char usage_l_bandwidth[14];
1151 } usage_l_fields_buf_t;
1152
1153 static const ofmt_field_t usage_l_fields[] = {
1154 /* name, field width, offset */
1155 { "LINK", 13,
1156 offsetof(usage_l_fields_buf_t, usage_l_link), print_default_cb},
1157 { "START", 14,
1158 offsetof(usage_l_fields_buf_t, usage_l_stime), print_default_cb},
1159 { "END", 14,
1422 offsetof(bridge_trill_fields_buf_t, bridget_link), print_default_cb },
1423 { "NEXTHOP", 17,
1424 offsetof(bridge_trill_fields_buf_t, bridget_nexthop), print_default_cb },
1425 { NULL, 0, 0, NULL}};
1426
1427 static char *progname;
1428 static sig_atomic_t signalled;
1429
1430 /*
1431 * Handle to libdladm. Opened in main() before the sub-command
1432 * specific function is called.
1433 */
1434 static dladm_handle_t handle = NULL;
1435
1436 #define DLADM_ETHERSTUB_NAME "etherstub"
1437 #define DLADM_IS_ETHERSTUB(id) (id == DATALINK_INVALID_LINKID)
1438
1439 static void
1440 usage(void)
1441 {
1442 int i;
1443 cmd_t *cmdp;
1444 (void) fprintf(stderr, gettext("usage: dladm <subcommand> <args> ..."
1445 "\n"));
1446 for (i = 0; i < sizeof (cmds) / sizeof (cmds[0]); i++) {
1447 cmdp = &cmds[i];
1448 if (cmdp->c_usage != NULL)
1449 (void) fprintf(stderr, "%s\n", gettext(cmdp->c_usage));
1450 }
1451
1452 /* close dladm handle if it was opened */
1453 if (handle != NULL)
1454 dladm_close(handle);
1455
1456 exit(EXIT_FAILURE);
1457 }
1458
1459 int
1460 main(int argc, char *argv[])
1461 {
1462 int i;
1463 cmd_t *cmdp;
1464 dladm_status_t status;
1465
1466 (void) setlocale(LC_ALL, "");
1467 #if !defined(TEXT_DOMAIN)
1468 #define TEXT_DOMAIN "SYS_TEST"
1469 #endif
1470 (void) textdomain(TEXT_DOMAIN);
1471
1472 progname = argv[0];
1473
1474 if (argc < 2)
1475 usage();
1476
1477 for (i = 0; i < sizeof (cmds) / sizeof (cmds[0]); i++) {
1478 cmdp = &cmds[i];
1479 if (strcmp(argv[1], cmdp->c_name) == 0) {
1480 /* Open the libdladm handle */
1481 if ((status = dladm_open(&handle)) != DLADM_STATUS_OK) {
1482 die_dlerr(status,
1483 "could not open /dev/dld");
1484 }
1485
1486 cmdp->c_fn(argc - 1, &argv[1], cmdp->c_usage);
1487
1488 dladm_close(handle);
1489 return (EXIT_SUCCESS);
1490 }
1491 }
1492
1493 (void) fprintf(stderr, gettext("%s: unknown subcommand '%s'\n"),
1494 progname, argv[1]);
1495 usage();
1496 return (EXIT_FAILURE);
1497 }
1498
1499 /*ARGSUSED*/
1500 static int
1501 show_usage_date(dladm_usage_t *usage, void *arg)
1502 {
1503 show_usage_state_t *state = (show_usage_state_t *)arg;
1504 time_t stime;
1505 char timebuf[20];
1506 dladm_status_t status;
1507 uint32_t flags;
1508
1509 /*
1510 * Only show usage information for existing links unless '-a'
1511 * is specified.
1512 */
1513 if (!state->us_showall) {
1514 if ((status = dladm_name2info(handle, usage->du_name,
1515 NULL, &flags, NULL, NULL)) != DLADM_STATUS_OK) {
1516 return (status);
1517 }
1518 if ((flags & DLADM_OPT_ACTIVE) == 0)
|
66 #include <libdlvnic.h>
67 #include <sys/types.h>
68 #include <sys/socket.h>
69 #include <sys/ib/ib_types.h>
70 #include <sys/processor.h>
71 #include <netinet/in.h>
72 #include <arpa/inet.h>
73 #include <net/if_types.h>
74 #include <stddef.h>
75 #include <stp_in.h>
76 #include <ofmt.h>
77
78 #define MAXPORT 256
79 #define MAXVNIC 256
80 #define BUFLEN(lim, ptr) (((lim) > (ptr)) ? ((lim) - (ptr)) : 0)
81 #define MAXLINELEN 1024
82 #define SMF_UPGRADE_FILE "/var/svc/profile/upgrade"
83 #define SMF_UPGRADEDATALINK_FILE "/var/svc/profile/upgrade_datalink"
84 #define SMF_DLADM_UPGRADE_MSG " # added by dladm(1M)"
85 #define DLADM_DEFAULT_COL 80
86 #define DLADM_DEFAULT_CMD "show-link"
87
88 /*
89 * used by the wifi show-* commands to set up ofmt_field_t structures.
90 */
91 #define WIFI_CMD_SCAN 0x00000001
92 #define WIFI_CMD_SHOW 0x00000002
93 #define WIFI_CMD_ALL (WIFI_CMD_SCAN | WIFI_CMD_SHOW)
94
95 /* No larger than pktsum_t */
96 typedef struct brsum_s {
97 uint64_t drops;
98 uint64_t forward_dir;
99 uint64_t forward_mb;
100 uint64_t forward_unk;
101 uint64_t recv;
102 uint64_t sent;
103 } brsum_t;
104
105 /* No larger than pktsum_t */
106 typedef struct brlsum_s {
203 static cmdfunc_t do_scan_wifi, do_connect_wifi, do_disconnect_wifi;
204 static cmdfunc_t do_show_linkprop, do_set_linkprop, do_reset_linkprop;
205 static cmdfunc_t do_create_secobj, do_delete_secobj, do_show_secobj;
206 static cmdfunc_t do_init_linkprop, do_init_secobj;
207 static cmdfunc_t do_create_vlan, do_delete_vlan, do_up_vlan, do_show_vlan;
208 static cmdfunc_t do_rename_link, do_delete_phys, do_init_phys;
209 static cmdfunc_t do_show_linkmap;
210 static cmdfunc_t do_show_ether;
211 static cmdfunc_t do_create_vnic, do_delete_vnic, do_show_vnic;
212 static cmdfunc_t do_up_vnic;
213 static cmdfunc_t do_create_part, do_delete_part, do_show_part, do_show_ib;
214 static cmdfunc_t do_up_part;
215 static cmdfunc_t do_create_etherstub, do_delete_etherstub, do_show_etherstub;
216 static cmdfunc_t do_create_simnet, do_modify_simnet;
217 static cmdfunc_t do_delete_simnet, do_show_simnet, do_up_simnet;
218 static cmdfunc_t do_show_usage;
219 static cmdfunc_t do_create_bridge, do_modify_bridge, do_delete_bridge;
220 static cmdfunc_t do_add_bridge, do_remove_bridge, do_show_bridge;
221 static cmdfunc_t do_create_iptun, do_modify_iptun, do_delete_iptun;
222 static cmdfunc_t do_show_iptun, do_up_iptun, do_down_iptun;
223 static cmdfunc_t do_help;
224
225 static void do_up_vnic_common(int, char **, const char *, boolean_t);
226
227 static int show_part(dladm_handle_t, datalink_id_t, void *);
228
229 static void altroot_cmd(char *, int, char **);
230 static int show_linkprop_onelink(dladm_handle_t, datalink_id_t, void *);
231
232 static void link_stats(datalink_id_t, uint_t, char *, show_state_t *);
233 static void aggr_stats(datalink_id_t, show_grp_state_t *, uint_t);
234 static void vnic_stats(show_vnic_state_t *, uint32_t);
235
236 static int get_one_kstat(const char *, const char *, uint8_t,
237 void *, boolean_t);
238 static void get_mac_stats(const char *, pktsum_t *);
239 static void get_link_stats(const char *, pktsum_t *);
240 static uint64_t get_ifspeed(const char *, boolean_t);
241 static const char *get_linkstate(const char *, boolean_t, char *);
242 static const char *get_linkduplex(const char *, boolean_t, char *);
243
252 static boolean_t link_is_ether(const char *, datalink_id_t *);
253
254 static boolean_t str2int(const char *, int *);
255 static void die(const char *, ...);
256 static void die_optdup(int);
257 static void die_opterr(int, int, const char *);
258 static void die_dlerr(dladm_status_t, const char *, ...);
259 static void warn(const char *, ...);
260 static void warn_dlerr(dladm_status_t, const char *, ...);
261
262 typedef struct cmd {
263 char *c_name;
264 cmdfunc_t *c_fn;
265 const char *c_usage;
266 } cmd_t;
267
268 static cmd_t cmds[] = {
269 { "rename-link", do_rename_link,
270 " rename-link <oldlink> <newlink>" },
271 { "show-link", do_show_link,
272 " show-link [-P] [[-p] -o <field>,..] "
273 "[-s [-i <interval>]] [<link>]" },
274 { "create-aggr", do_create_aggr,
275 " create-aggr [-t] [-P <policy>] [-L <mode>] [-T <time>] "
276 "[-u <address>]\n"
277 "\t\t -l <link> [-l <link>...] <link>" },
278 { "delete-aggr", do_delete_aggr,
279 " delete-aggr [-t] <link>" },
280 { "add-aggr", do_add_aggr,
281 " add-aggr [-t] -l <link> [-l <link>...] <link>" },
282 { "remove-aggr", do_remove_aggr,
283 " remove-aggr [-t] -l <link> [-l <link>...] <link>" },
284 { "modify-aggr", do_modify_aggr,
285 " modify-aggr [-t] [-P <policy>] [-L <mode>] [-T <time>] "
286 "[-u <address>]\n"
287 "\t\t <link>" },
288 { "show-aggr", do_show_aggr,
289 " show-aggr [-PLx] [[-p] -o <field>,..] "
290 "[-s [-i <interval>]] [<link>]" },
291 { "up-aggr", do_up_aggr, NULL },
292 { "scan-wifi", do_scan_wifi,
293 " scan-wifi [[-p] -o <field>,...] [<link>]" },
294 { "connect-wifi", do_connect_wifi,
295 " connect-wifi [-e <essid>] [-i <bssid>] [-k <key>,...] "
296 "[-s wep|wpa]\n"
297 "\t\t [-a open|shared] [-b bss|ibss] [-c] [-m a|b|g] "
298 "[-T <time>]\n"
299 "\t\t [<link>]" },
300 { "disconnect-wifi", do_disconnect_wifi,
301 " disconnect-wifi [-a] [<link>]" },
302 { "show-wifi", do_show_wifi,
303 " show-wifi [[-p] -o <field>,...] [<link>]" },
304 { "set-linkprop", do_set_linkprop,
305 " set-linkprop [-t] -p <prop>=<value>[,...] <name>" },
306 { "reset-linkprop", do_reset_linkprop,
307 " reset-linkprop [-t] [-p <prop>,...] <name>" },
308 { "show-linkprop", do_show_linkprop,
309 " show-linkprop [-cP] [-o <field>,...] [-p <prop>,...] "
310 "<name>" },
311 { "show-ether", do_show_ether,
312 " show-ether [-x] [[-p] -o <field>,...] <link>" },
313 { "create-secobj", do_create_secobj,
314 " create-secobj [-t] [-f <file>] -c <class> <secobj>" },
315 { "delete-secobj", do_delete_secobj,
316 " delete-secobj [-t] <secobj>[,...]" },
317 { "show-secobj", do_show_secobj,
318 " show-secobj [-P] [[-p] -o <field>,...] [<secobj>,...]" },
319 { "init-linkprop", do_init_linkprop, NULL },
320 { "init-secobj", do_init_secobj, NULL },
321 { "create-vlan", do_create_vlan,
322 " create-vlan [-ft] -l <link> -v <vid> [link]" },
323 { "delete-vlan", do_delete_vlan,
324 " delete-vlan [-t] <link>" },
325 { "show-vlan", do_show_vlan,
326 " show-vlan [-P] [[-p] -o <field>,...] [<link>]" },
327 { "up-vlan", do_up_vlan, NULL },
328 { "create-iptun", do_create_iptun,
329 " create-iptun [-t] -T <type> "
330 "[-a {local|remote}=<addr>,...] <link>]" },
331 { "delete-iptun", do_delete_iptun,
332 " delete-iptun [-t] <link>" },
333 { "modify-iptun", do_modify_iptun,
334 " modify-iptun [-t] -a {local|remote}=<addr>,... <link>" },
335 { "show-iptun", do_show_iptun,
336 " show-iptun [-P] [[-p] -o <field>,...] [<link>]" },
337 { "up-iptun", do_up_iptun, NULL },
338 { "down-iptun", do_down_iptun, NULL },
339 { "delete-phys", do_delete_phys,
340 " delete-phys <link>" },
341 { "show-phys", do_show_phys,
342 " show-phys [-P] [[-p] -o <field>,...] [-H] [<link>]" },
343 { "init-phys", do_init_phys, NULL },
344 { "show-linkmap", do_show_linkmap, NULL },
345 { "create-vnic", do_create_vnic,
346 " create-vnic [-t] -l <link> [-m <value> | auto |\n"
347 "\t\t {factory [-n <slot-id>]} | {random [-r <prefix>]} |\n"
348 "\t\t {vrrp -V <vrid> -A {inet | inet6}} [-v <vid> [-f]]\n"
349 "\t\t [-p <prop>=<value>[,...]] [-R root-dir] <vnic-link>" },
350 { "delete-vnic", do_delete_vnic,
351 " delete-vnic [-t] <vnic-link>" },
352 { "show-vnic", do_show_vnic,
353 " show-vnic [-P] [[-p] -o <field>,...] [-l <link>] "
354 "[-s [-i <interval>]] [<link>]" },
355 { "up-vnic", do_up_vnic, NULL },
356 { "create-part", do_create_part,
357 " create-part [-t] [-f] -l <link> [-P <pkey>]\n"
358 "\t\t [-R <root-dir>] <part-link>" },
359 { "delete-part", do_delete_part,
360 " delete-part [-t] [-R <root-dir>] <part-link>"},
361 { "show-part", do_show_part,
362 " show-part [-P] [[-p] -o <field>,...] [-l <linkover>]\n"
363 "\t\t [<part-link>]" },
364 { "show-ib", do_show_ib,
365 " show-ib [[-p] -o <field>,...] [<link>]" },
366 { "up-part", do_up_part, NULL },
367 { "create-etherstub", do_create_etherstub,
368 " create-etherstub [-t] <link>" },
369 { "delete-etherstub", do_delete_etherstub,
370 " delete-etherstub [-t] <link>" },
371 { "show-etherstub", do_show_etherstub,
372 " show-etherstub [-t] [<link>]\n" },
373 { "create-simnet", do_create_simnet, NULL },
374 { "modify-simnet", do_modify_simnet, NULL },
375 { "delete-simnet", do_delete_simnet, NULL },
376 { "show-simnet", do_show_simnet, NULL },
377 { "up-simnet", do_up_simnet, NULL },
378 { "create-bridge", do_create_bridge,
379 " create-bridge [-R <root-dir>] [-P <protect>] "
380 "[-p <priority>]\n"
381 "\t\t [-m <max-age>] [-h <hello-time>] [-d <forward-delay>]\n"
382 "\t\t [-f <force-protocol>] [-l <link>]... <bridge>" },
383 { "modify-bridge", do_modify_bridge,
384 " modify-bridge [-R <root-dir>] [-P <protect>] "
385 "[-p <priority>]\n"
386 "\t\t [-m <max-age>] [-h <hello-time>] [-d <forward-delay>]\n"
387 "\t\t [-f <force-protocol>] <bridge>" },
388 { "delete-bridge", do_delete_bridge,
389 " delete-bridge [-R <root-dir>] <bridge>" },
390 { "add-bridge", do_add_bridge,
391 " add-bridge [-R <root-dir>] -l <link> [-l <link>]... "
392 "<bridge>" },
393 { "remove-bridge", do_remove_bridge,
394 " remove-bridge [-R <root-dir>] -l <link> [-l <link>]... "
395 "<bridge>" },
396 { "show-bridge", do_show_bridge,
397 " show-bridge [[-p] -o <field>,...] [-s [-i <interval>]] "
398 "[<bridge>]\n"
399 " show-bridge -l [[-p] -o <field>,...] [-s [-i <interval>]]"
400 " <bridge>\n"
401 " show-bridge -f [[-p] -o <field>,...] [-s [-i <interval>]]"
402 " <bridge>\n"
403 " show-bridge -t [[-p] -o <field>,...] [-s [-i <interval>]]"
404 " <bridge>" },
405 { "show-usage", do_show_usage,
406 " show-usage [-a] [-d | -F <format>] "
407 "[-s <DD/MM/YYYY,HH:MM:SS>]\n"
408 "\t\t [-e <DD/MM/YYYY,HH:MM:SS>] -f <logfile> [<link>]" },
409 { "help", do_help,
410 " help [<subcommand>]" }
411 };
412
413 static const struct option lopts[] = {
414 {"vlan-id", required_argument, 0, 'v'},
415 {"output", required_argument, 0, 'o'},
416 {"dev", required_argument, 0, 'd'},
417 {"policy", required_argument, 0, 'P'},
418 {"lacp-mode", required_argument, 0, 'L'},
419 {"lacp-timer", required_argument, 0, 'T'},
420 {"unicast", required_argument, 0, 'u'},
421 {"temporary", no_argument, 0, 't'},
422 {"root-dir", required_argument, 0, 'R'},
423 {"link", required_argument, 0, 'l'},
424 {"forcible", no_argument, 0, 'f'},
425 {"bw-limit", required_argument, 0, 'b'},
426 {"mac-address", required_argument, 0, 'm'},
427 {"slot", required_argument, 0, 'n'},
428 { 0, 0, 0, 0 }
429 };
430
1123 } usage_fields_buf_t;
1124
1125 static const ofmt_field_t usage_fields[] = {
1126 { "LINK", 13,
1127 offsetof(usage_fields_buf_t, usage_link), print_default_cb},
1128 { "DURATION", 11,
1129 offsetof(usage_fields_buf_t, usage_duration), print_default_cb},
1130 { "IPACKETS", 10,
1131 offsetof(usage_fields_buf_t, usage_ipackets), print_default_cb},
1132 { "RBYTES", 11,
1133 offsetof(usage_fields_buf_t, usage_rbytes), print_default_cb},
1134 { "OPACKETS", 10,
1135 offsetof(usage_fields_buf_t, usage_opackets), print_default_cb},
1136 { "OBYTES", 11,
1137 offsetof(usage_fields_buf_t, usage_obytes), print_default_cb},
1138 { "BANDWIDTH", 15,
1139 offsetof(usage_fields_buf_t, usage_bandwidth), print_default_cb},
1140 { NULL, 0, 0, NULL}}
1141 ;
1142
1143 /*
1144 * structures for 'dladm show-usage link'
1145 */
1146
1147 typedef struct usage_l_fields_buf_s {
1148 char usage_l_link[12];
1149 char usage_l_stime[13];
1150 char usage_l_etime[13];
1151 char usage_l_rbytes[8];
1152 char usage_l_obytes[8];
1153 char usage_l_bandwidth[14];
1154 } usage_l_fields_buf_t;
1155
1156 static const ofmt_field_t usage_l_fields[] = {
1157 /* name, field width, offset */
1158 { "LINK", 13,
1159 offsetof(usage_l_fields_buf_t, usage_l_link), print_default_cb},
1160 { "START", 14,
1161 offsetof(usage_l_fields_buf_t, usage_l_stime), print_default_cb},
1162 { "END", 14,
1425 offsetof(bridge_trill_fields_buf_t, bridget_link), print_default_cb },
1426 { "NEXTHOP", 17,
1427 offsetof(bridge_trill_fields_buf_t, bridget_nexthop), print_default_cb },
1428 { NULL, 0, 0, NULL}};
1429
1430 static char *progname;
1431 static sig_atomic_t signalled;
1432
1433 /*
1434 * Handle to libdladm. Opened in main() before the sub-command
1435 * specific function is called.
1436 */
1437 static dladm_handle_t handle = NULL;
1438
1439 #define DLADM_ETHERSTUB_NAME "etherstub"
1440 #define DLADM_IS_ETHERSTUB(id) (id == DATALINK_INVALID_LINKID)
1441
1442 static void
1443 usage(void)
1444 {
1445 (void) fprintf(stderr, gettext("For more information, run: %s help\n"),
1446 progname);
1447
1448 /* close dladm handle if it was opened */
1449 if (handle != NULL)
1450 dladm_close(handle);
1451
1452 exit(EXIT_FAILURE);
1453 }
1454
1455 int
1456 main(int argc, char *argv[])
1457 {
1458 int i;
1459 cmd_t *cmdp;
1460 dladm_status_t status;
1461
1462 (void) setlocale(LC_ALL, "");
1463 #if !defined(TEXT_DOMAIN)
1464 #define TEXT_DOMAIN "SYS_TEST"
1465 #endif
1466 (void) textdomain(TEXT_DOMAIN);
1467
1468 progname = argv[0];
1469
1470 if (argc < 2) {
1471 argv[1] = DLADM_DEFAULT_CMD;
1472 argc++;
1473 }
1474
1475 for (i = 0; i < sizeof (cmds) / sizeof (cmds[0]); i++) {
1476 cmdp = &cmds[i];
1477 if (strcmp(argv[1], cmdp->c_name) == 0) {
1478 /* Open the libdladm handle */
1479 if ((status = dladm_open(&handle)) != DLADM_STATUS_OK) {
1480 die_dlerr(status,
1481 "could not open /dev/dld");
1482 }
1483
1484 cmdp->c_fn(argc - 1, &argv[1], cmdp->c_usage);
1485
1486 dladm_close(handle);
1487 return (EXIT_SUCCESS);
1488 }
1489 }
1490
1491 (void) fprintf(stderr, gettext("%s: unknown subcommand '%s'\n"),
1492 progname, argv[1]);
1493 usage();
1494 return (EXIT_FAILURE);
1495 }
1496
1497 static int
1498 help_compare(const void *cmd1, const void *cmd2)
1499 {
1500 cmd_t *cmd1p = (cmd_t *)cmd1;
1501 cmd_t *cmd2p = (cmd_t *)cmd2;
1502
1503 return (strcmp(cmd1p->c_name, cmd2p->c_name));
1504 }
1505
1506 static void
1507 do_help(int argc, char *argv[], const char *use)
1508 {
1509 size_t nelems;
1510 int i, j, ncols = 3;
1511 boolean_t found = B_FALSE;
1512
1513 _NOTE(ARGUNUSED(use));
1514
1515 nelems = sizeof (cmds) / sizeof (cmd_t);
1516
1517 if (argc < 2) {
1518 qsort(cmds, nelems, sizeof (cmd_t), help_compare);
1519
1520 (void) fprintf(stderr, gettext(
1521 "usage: dladm help <subcommand>\n"
1522 "Subcommands are:\n"));
1523
1524 for (i = 0, j = 0; i < nelems; i++) {
1525 if (cmds[i].c_usage == NULL)
1526 continue;
1527
1528 (void) fprintf(stderr, "%-20s", cmds[i].c_name);
1529
1530 if (++j % ncols == 0)
1531 (void) putc('\n', stderr);
1532 }
1533
1534 if (j % ncols != 0)
1535 (void) putc('\n', stderr);
1536 } else {
1537 for (i = 0; i < nelems; i++) {
1538 if (strcmp(argv[1], cmds[i].c_name) == 0) {
1539 (void) fprintf(stderr, "usage:\n%s\n",
1540 gettext(cmds[i].c_usage));
1541 found = B_TRUE;
1542 break;
1543 }
1544 }
1545
1546 if (!found) {
1547 (void) fprintf(stderr, gettext(
1548 "%s: unknown subcommand '%s'\n"),
1549 progname, argv[1]);
1550 usage();
1551 }
1552 }
1553 }
1554
1555 /*ARGSUSED*/
1556 static int
1557 show_usage_date(dladm_usage_t *usage, void *arg)
1558 {
1559 show_usage_state_t *state = (show_usage_state_t *)arg;
1560 time_t stime;
1561 char timebuf[20];
1562 dladm_status_t status;
1563 uint32_t flags;
1564
1565 /*
1566 * Only show usage information for existing links unless '-a'
1567 * is specified.
1568 */
1569 if (!state->us_showall) {
1570 if ((status = dladm_name2info(handle, usage->du_name,
1571 NULL, &flags, NULL, NULL)) != DLADM_STATUS_OK) {
1572 return (status);
1573 }
1574 if ((flags & DLADM_OPT_ACTIVE) == 0)
|