vlan_infos_t* get_vlan_infos() { char* links; int links_len = 0; dladm_walk_datalink_id( &count_links, handle, &links_len, DATALINK_CLASS_VLAN, DATALINK_ANY_MEDIATYPE, DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST ); char* links_it = links = malloc( links_len * MAXLINKNAMELEN ); dladm_walk_datalink_id( &collect_link_names, handle, &links_it, DATALINK_CLASS_VLAN, DATALINK_ANY_MEDIATYPE, DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST ); vlan_infos_t* infos = malloc_vlan_infos( links_len ); infos->len = links_len; for ( int i = 0; i < links_len; ++i ) { char* name = links + i * MAXLINKNAMELEN; datalink_id_t vlanid = { 0 }; dladm_vlan_attr_t vinfo; char parent[ MAXLINKNAMELEN ] = { 0 }; strcpy( infos->vlan_infos[ i ]->name, name ); if ( DLADM_STATUS_OK != dladm_name2info( handle, name, &vlanid, NULL, NULL, NULL ) ) { } else { dladm_vlan_info( handle, vlanid, &vinfo, DLADM_OPT_ACTIVE ); if ( DLADM_STATUS_OK != dladm_datalink_id2info( handle, vinfo.dv_linkid, NULL, NULL, NULL, parent, sizeof( parent ) ) ) { } else { infos->vlan_infos[ i ]->tag = vinfo.dv_vid; strcpy( infos->vlan_infos[ i ]->link, parent ); } } } free( links ); return infos; }
void get_interfaces_list(std::list<std::string> *interfaces) { dladm_init(); interfaces->clear(); uint32_t flags = DLADM_OPT_ACTIVE; (void) dladm_walk_datalink_id(dladm_callback, g_handle, interfaces, (datalink_class_t) DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE, flags); dladm_finish(); return; }
/* ARGSUSED */ static void flow_stats(const char *flow, datalink_id_t linkid, uint_t interval, char *fields_str, show_flow_state_t *state) { dladm_flow_attr_t attr; ofmt_handle_t ofmt; ofmt_status_t oferr; uint_t ofmtflags = 0; oferr = ofmt_open(fields_str, flow_s_fields, ofmtflags, 0, &ofmt); flowadm_ofmt_check(oferr, state->fs_parsable, ofmt); state->fs_ofmt = ofmt; if (flow != NULL && dladm_flow_info(handle, flow, &attr) != DLADM_STATUS_OK) die("invalid flow %s", flow); /* * If an interval is specified, continuously show the stats * for only the first flow. */ state->fs_firstonly = (interval != 0); for (;;) { state->fs_donefirst = B_FALSE; /* Show stats for named flow */ if (flow != NULL) { state->fs_flow = flow; (void) show_flow_stats(handle, &attr, state); /* Show all stats on a link */ } else if (linkid != DATALINK_INVALID_LINKID) { (void) dladm_walk_flow(show_flow_stats, handle, linkid, state, B_FALSE); /* Show all stats by datalink */ } else { (void) dladm_walk_datalink_id(show_link_flow_stats, handle, state, DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE, DLADM_OPT_ACTIVE); } if (interval == 0) break; (void) fflush(stdout); (void) sleep(interval); } ofmt_close(ofmt); }
static void dump_all_flow_stats(dladm_flow_attr_t *attrp, void *arg, datalink_id_t linkid, boolean_t flow_arg) { /* Show stats for named flow */ if (flow_arg) { (void) dump_one_flow_stats(handle, attrp, arg); /* Show stats for flows on one link */ } else if (linkid != DATALINK_INVALID_LINKID) { (void) dladm_walk_flow(dump_one_flow_stats, handle, linkid, arg, B_FALSE); /* Show stats for all flows on all links */ } else { (void) dladm_walk_datalink_id(dump_link_flow_stats, handle, arg, DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE, DLADM_OPT_ACTIVE); } }
/* * ipmgmt_net_from_gz_init() initializes exclusive-IP stack non-global zones by * extracting configuration that has been saved in the kernel and applying * that information to the appropriate datalinks for the zone. If an ifname * argument is passed in, only the selected IP interface corresponding to * datalink will be initialized, otherwise all datalinks will be plumbed for IP * and IP address and route information will be configured. */ ipadm_status_t ipadm_init_net_from_gz(ipadm_handle_t iph, char *ifname, void (*persist_if)(char *, boolean_t, boolean_t)) { ngz_walk_data_t nwd; uint64_t flags; dladm_handle_t dlh = iph->iph_dlh; datalink_id_t linkid; if (iph->iph_zoneid == GLOBAL_ZONEID) return (IPADM_NOTSUP); if (ifname != NULL && i_ipadm_get_flags(iph, ifname, AF_INET, &flags) != IPADM_SUCCESS && i_ipadm_get_flags(iph, ifname, AF_INET6, &flags) != IPADM_SUCCESS) return (IPADM_ENXIO); if (ifname != NULL && !(flags & IFF_L3PROTECT)) return (IPADM_SUCCESS); /* nothing to initialize */ nwd.ngz_iph = iph; nwd.ngz_zoneid = iph->iph_zoneid; nwd.ngz_ifname = ifname; nwd.ngz_persist_if = persist_if; nwd.ngz_s10c = i_ipadm_zone_is_s10c(iph->iph_zoneid); nwd.ngz_ipstatus = IPADM_SUCCESS; if (ifname != NULL) { if (dladm_name2info(dlh, ifname, &linkid, NULL, NULL, NULL) != DLADM_STATUS_OK) { return (IPADM_ENXIO); } (void) i_ipadm_zone_network_attr(dlh, linkid, &nwd); } else { (void) dladm_walk_datalink_id(i_ipadm_zone_network_attr, dlh, &nwd, DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE, DLADM_OPT_PERSIST); } return (nwd.ngz_ipstatus); }
int main(int argc, char *argv[]) { dladm_status_t status; int option; boolean_t r_arg = B_FALSE; boolean_t t_arg = B_FALSE; boolean_t p_arg = B_FALSE; boolean_t i_arg = B_FALSE; boolean_t o_arg = B_FALSE; boolean_t u_arg = B_FALSE; boolean_t A_arg = B_FALSE; boolean_t flow_arg = B_FALSE; datalink_id_t linkid = DATALINK_ALL_LINKID; char linkname[MAXLINKNAMELEN]; char flowname[MAXFLOWNAMELEN]; uint32_t interval = 0; char unit = '\0'; show_flow_state_t state; char *fields_str = NULL; char *o_fields_str = NULL; char *zonename = NULL; char *total_stat_fields = "flow,ipkts,rbytes,ierrs,opkts,obytes,oerrs"; char *rx_stat_fields = "flow,ipkts,rbytes,ierrs"; char *tx_stat_fields = "flow,opkts,obytes,oerrs"; ofmt_handle_t ofmt; ofmt_status_t oferr; uint_t ofmtflags = OFMT_RIGHTJUST; dladm_flow_attr_t attr; (void) setlocale(LC_ALL, ""); #if !defined(TEXT_DOMAIN) #define TEXT_DOMAIN "SYS_TEST" #endif (void) textdomain(TEXT_DOMAIN); progname = argv[0]; /* Open the libdladm handle */ if ((status = dladm_open(&handle)) != DLADM_STATUS_OK) die_dlerr(status, "could not open /dev/dld"); linkname[0] = '\0'; bzero(&state, sizeof (state)); opterr = 0; while ((option = getopt_long(argc, argv, ":rtApi:o:u:l:hz:", NULL, NULL)) != -1) { switch (option) { case 'r': if (r_arg) die_optdup(option); r_arg = B_TRUE; break; case 't': if (t_arg) die_optdup(option); t_arg = B_TRUE; break; case 'A': if (A_arg) die_optdup(option); A_arg = B_TRUE; break; case 'p': if (p_arg) die_optdup(option); p_arg = B_TRUE; break; case 'i': if (i_arg) die_optdup(option); i_arg = B_TRUE; if (!dladm_str2interval(optarg, &interval)) die("invalid interval value '%s'", optarg); break; case 'o': o_arg = B_TRUE; o_fields_str = optarg; break; case 'u': if (u_arg) die_optdup(option); u_arg = B_TRUE; if (!flowstat_unit(optarg, &unit)) die("invalid unit value '%s'," "unit must be R|K|M|G|T|P", optarg); break; case 'l': if (strlcpy(linkname, optarg, MAXLINKNAMELEN) >= MAXLINKNAMELEN) die("link name too long\n"); break; case 'h': if (r_arg || t_arg || p_arg || o_arg || u_arg || i_arg || A_arg) { die("the option -h is not compatible with " "-r, -t, -p, -o, -u, -i, -A"); } do_show_history(argc, argv); return (0); break; case 'z': zonename = optarg; break; default: die_opterr(optopt, option, usage_ermsg); break; } } if (r_arg && t_arg) die("the option -t and -r are not compatible"); if (u_arg && p_arg) die("the option -u and -p are not compatible"); if (p_arg && !o_arg) die("-p requires -o"); if (p_arg && strcasecmp(o_fields_str, "all") == 0) die("\"-o all\" is invalid with -p"); if (A_arg && (r_arg || t_arg || p_arg || o_arg || u_arg || i_arg)) die("the option -A is not compatible with " "-r, -t, -p, -o, -u, -i"); if (linkname[0] != '\0') { if (dladm_zname2info(handle, zonename, linkname, &linkid, NULL, NULL, NULL) != DLADM_STATUS_OK) die("invalid link '%s'", linkname); } /* get flow name (optional last argument) */ if (optind == (argc-1)) { if (strlcpy(flowname, argv[optind], MAXFLOWNAMELEN) >= MAXFLOWNAMELEN) die("flow name too long"); flow_arg = B_TRUE; } else if (optind != argc) { usage(); } if (flow_arg && dladm_flow_info(handle, flowname, &attr) != DLADM_STATUS_OK) die("invalid flow %s", flowname); if (A_arg) { dump_all_flow_stats(&attr, &state, linkid, flow_arg); return (0); } state.fs_unit = unit; state.fs_parsable = p_arg; if (state.fs_parsable) ofmtflags |= OFMT_PARSABLE; if (r_arg) fields_str = rx_stat_fields; else if (t_arg) fields_str = tx_stat_fields; else fields_str = total_stat_fields; if (o_arg) { fields_str = (strcasecmp(o_fields_str, "all") == 0) ? fields_str : o_fields_str; } oferr = ofmt_open(fields_str, flow_s_fields, ofmtflags, 0, &ofmt); ofmt_check(oferr, state.fs_parsable, ofmt, die, warn); state.fs_ofmt = ofmt; for (;;) { /* Show stats for named flow */ if (flow_arg) { (void) query_flow_stats(handle, &attr, &state); /* Show stats for flows on one link */ } else if (linkid != DATALINK_INVALID_LINKID) { (void) dladm_walk_flow(query_flow_stats, handle, linkid, &state, B_FALSE); /* Show stats for all flows on all links */ } else { (void) dladm_walk_datalink_id(query_link_flow_stats, handle, &state, DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE, DLADM_OPT_ACTIVE); } if (interval == 0) break; (void) fflush(stdout); cleanup_removed_flows(&state); (void) sleep(interval); } ofmt_close(ofmt); dladm_close(handle); return (0); }
static void do_show_flowprop(int argc, char **argv) { int option; dladm_arg_list_t *proplist = NULL; show_flowprop_state_t state; char *fields_str = NULL; ofmt_handle_t ofmt; ofmt_status_t oferr; uint_t ofmtflags = 0; opterr = 0; state.fs_propvals = NULL; state.fs_line = NULL; state.fs_parsable = B_FALSE; state.fs_persist = B_FALSE; state.fs_header = B_TRUE; state.fs_retstatus = DLADM_STATUS_OK; state.fs_linkid = DATALINK_INVALID_LINKID; state.fs_flow = NULL; while ((option = getopt_long(argc, argv, ":p:cPl:o:", prop_longopts, NULL)) != -1) { switch (option) { case 'p': if (dladm_parse_flow_props(optarg, &proplist, B_TRUE) != DLADM_STATUS_OK) die("invalid flow properties specified"); break; case 'c': state.fs_parsable = B_TRUE; ofmtflags |= OFMT_PARSABLE; break; case 'P': state.fs_persist = B_TRUE; break; case 'l': if (dladm_name2info(handle, optarg, &state.fs_linkid, NULL, NULL, NULL) != DLADM_STATUS_OK) die("invalid link '%s'", optarg); break; case 'o': fields_str = optarg; break; default: die_opterr(optopt, option); break; } } if (optind == (argc - 1)) { if (strlen(argv[optind]) >= MAXFLOWNAMELEN) die("flow name too long"); state.fs_flow = argv[optind]; } else if (optind != argc) { usage(); } state.fs_proplist = proplist; state.fs_status = DLADM_STATUS_OK; oferr = ofmt_open(fields_str, flowprop_fields, ofmtflags, 0, &ofmt); flowadm_ofmt_check(oferr, state.fs_parsable, ofmt); state.fs_ofmt = ofmt; /* Show properties for one flow */ if (state.fs_flow != NULL) { show_flowprop_one_flow(&state, state.fs_flow); /* Show properties for all flows on one link */ } else if (state.fs_linkid != DATALINK_INVALID_LINKID) { (void) show_flowprop_onelink(handle, state.fs_linkid, &state); /* Show properties for all flows on all links */ } else { (void) dladm_walk_datalink_id(show_flowprop_onelink, handle, &state, DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE, DLADM_OPT_ACTIVE); } dladm_free_props(proplist); ofmt_close(ofmt); }
static void do_show_flow(int argc, char *argv[]) { char flowname[MAXFLOWNAMELEN]; char linkname[MAXLINKNAMELEN]; datalink_id_t linkid = DATALINK_ALL_LINKID; int option; boolean_t s_arg = B_FALSE; boolean_t S_arg = B_FALSE; boolean_t i_arg = B_FALSE; boolean_t l_arg = B_FALSE; boolean_t o_arg = B_FALSE; uint32_t interval = 0; show_flow_state_t state; char *fields_str = NULL; ofmt_handle_t ofmt; ofmt_status_t oferr; uint_t ofmtflags = 0; bzero(&state, sizeof (state)); opterr = 0; while ((option = getopt_long(argc, argv, ":pPsSi:l:o:", longopts, NULL)) != -1) { switch (option) { case 'p': state.fs_parsable = B_TRUE; ofmtflags |= OFMT_PARSABLE; break; case 'P': state.fs_persist = B_TRUE; break; case 's': if (s_arg) die_optdup(option); s_arg = B_TRUE; break; case 'S': if (S_arg) die_optdup(option); S_arg = B_TRUE; break; case 'o': if (o_arg) die_optdup(option); o_arg = B_TRUE; fields_str = optarg; break; case 'i': if (i_arg) die_optdup(option); i_arg = B_TRUE; if (!dladm_str2interval(optarg, &interval)) die("invalid interval value '%s'", optarg); break; case 'l': if (strlcpy(linkname, optarg, MAXLINKNAMELEN) >= MAXLINKNAMELEN) die("link name too long\n"); if (dladm_name2info(handle, linkname, &linkid, NULL, NULL, NULL) != DLADM_STATUS_OK) die("invalid link '%s'", linkname); l_arg = B_TRUE; break; default: die_opterr(optopt, option); break; } } if (i_arg && !(s_arg || S_arg)) die("the -i option can be used only with -s or -S"); if (s_arg && S_arg) die("the -s option cannot be used with -S"); /* get flow name (optional last argument */ if (optind == (argc-1)) { if (strlcpy(flowname, argv[optind], MAXFLOWNAMELEN) >= MAXFLOWNAMELEN) die("flow name too long"); state.fs_flow = flowname; } if (S_arg) { dladm_continuous(handle, linkid, state.fs_flow, interval, FLOW_REPORT); return; } if (s_arg) { flow_stats(state.fs_flow, linkid, interval, fields_str, &state); return; } oferr = ofmt_open(fields_str, flow_fields, ofmtflags, 0, &ofmt); flowadm_ofmt_check(oferr, state.fs_parsable, ofmt); state.fs_ofmt = ofmt; /* Show attributes of one flow */ if (state.fs_flow != NULL) { show_one_flow(&state, state.fs_flow); /* Show attributes of flows on one link */ } else if (l_arg) { (void) show_flows_onelink(handle, linkid, &state); /* Show attributes of all flows on all links */ } else { (void) dladm_walk_datalink_id(show_flows_onelink, handle, &state, DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE, DLADM_OPT_ACTIVE); } ofmt_close(ofmt); }
int main(int argc, char *argv[]) { int c; dladm_status_t status; const char *outfile = NULL; uint_t count = 0; dltran_progname = basename(argv[0]); while ((c = getopt(argc, argv, ":xvw:")) != -1) { switch (c) { case 'v': dltran_verbose = B_TRUE; break; case 'x': dltran_hex = B_TRUE; break; case 'w': dltran_write = B_TRUE; outfile = optarg; break; case ':': dltran_usage("option -%c requires an " "operand\n", optopt); return (2); case '?': default: dltran_usage("unknown option: -%c\n", optopt); return (2); } } argc -= optind; argv += optind; if (dltran_verbose) count++; if (dltran_hex) count++; if (dltran_write) count++; if (count > 1) { (void) fprintf(stderr, "only one of -v, -w, and -x may be " "specified\n"); return (2); } if (dltran_write) { if ((dltran_outfd = open(outfile, O_RDWR | O_TRUNC | O_CREAT, 0644)) < 0) { (void) fprintf(stderr, "failed to open output file " "%s: %s\n", outfile, strerror(errno)); return (1); } } if ((status = dladm_open(&dltran_hdl)) != DLADM_STATUS_OK) { (void) fprintf(stderr, "failed to open /dev/dld: %s\n", dladm_status2str(status, dltran_dlerrmsg)); return (1); } if (argc == 0) { (void) dladm_walk_datalink_id(dltran_dump_transceivers, dltran_hdl, NULL, DATALINK_CLASS_PHYS, DATALINK_ANY_MEDIATYPE, DLADM_OPT_ACTIVE); } else { int i; char *c; for (i = 0; i < argc; i++) { uint_t tran; uint_t *tranidp = NULL; datalink_id_t linkid; if ((c = strrchr(argv[i], '/')) != NULL) { unsigned long u; char *eptr; c++; errno = 0; u = strtoul(c, &eptr, 10); if (errno != 0 || *eptr != '\0' || u >= UINT_MAX) { (void) fprintf(stderr, "failed to " "parse link/transceiver: %s\n", argv[i]); return (1); } c--; *c = '\0'; tran = (uint_t)u; tranidp = &tran; } if ((status = dladm_name2info(dltran_hdl, argv[i], &linkid, NULL, NULL, NULL)) != DLADM_STATUS_OK) { (void) fprintf(stderr, "failed to get link " "id for link %s: %s\n", argv[i], dladm_status2str(status, dltran_dlerrmsg)); return (1); } (void) dltran_dump_transceivers(dltran_hdl, linkid, tranidp); } } return (dltran_errors != 0 ? 1 : 0); }