1da14cebeSEric Cheng /* 2da14cebeSEric Cheng * CDDL HEADER START 3da14cebeSEric Cheng * 4da14cebeSEric Cheng * The contents of this file are subject to the terms of the 5da14cebeSEric Cheng * Common Development and Distribution License (the "License"). 6da14cebeSEric Cheng * You may not use this file except in compliance with the License. 7da14cebeSEric Cheng * 8da14cebeSEric Cheng * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9da14cebeSEric Cheng * or http://www.opensolaris.org/os/licensing. 10da14cebeSEric Cheng * See the License for the specific language governing permissions 11da14cebeSEric Cheng * and limitations under the License. 12da14cebeSEric Cheng * 13da14cebeSEric Cheng * When distributing Covered Code, include this CDDL HEADER in each 14da14cebeSEric Cheng * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15da14cebeSEric Cheng * If applicable, add the following below this CDDL HEADER, with the 16da14cebeSEric Cheng * fields enclosed by brackets "[]" replaced with your own identifying 17da14cebeSEric Cheng * information: Portions Copyright [yyyy] [name of copyright owner] 18da14cebeSEric Cheng * 19da14cebeSEric Cheng * CDDL HEADER END 20da14cebeSEric Cheng */ 21da14cebeSEric Cheng /* 22da000602SGirish Moodalbail * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23da14cebeSEric Cheng * Use is subject to license terms. 24da14cebeSEric Cheng */ 25da14cebeSEric Cheng 26da14cebeSEric Cheng #include <stdlib.h> 27da14cebeSEric Cheng #include <strings.h> 28da14cebeSEric Cheng #include <errno.h> 29da14cebeSEric Cheng #include <ctype.h> 30da14cebeSEric Cheng #include <sys/types.h> 31da14cebeSEric Cheng #include <sys/stat.h> 32da14cebeSEric Cheng #include <sys/dld.h> 3382a2fc47SJames Carlson #include <sys/dld_ioc.h> 34da14cebeSEric Cheng #include <fcntl.h> 35da14cebeSEric Cheng #include <unistd.h> 36da14cebeSEric Cheng #include <libdevinfo.h> 37da14cebeSEric Cheng #include <libdladm_impl.h> 38da14cebeSEric Cheng #include <libdlflow.h> 39da14cebeSEric Cheng #include <libdlflow_impl.h> 40da14cebeSEric Cheng #include <libintl.h> 41da14cebeSEric Cheng 42da14cebeSEric Cheng #include <dlfcn.h> 43da14cebeSEric Cheng #include <link.h> 44da14cebeSEric Cheng 45da14cebeSEric Cheng /* 46da14cebeSEric Cheng * XXX duplicate define 47da14cebeSEric Cheng */ 48da14cebeSEric Cheng #define DLADM_PROP_VAL_MAX 32 49da14cebeSEric Cheng 504ac67f02SAnurag S. Maskey static dladm_status_t i_dladm_set_flowprop_db(dladm_handle_t, const char *, 514ac67f02SAnurag S. Maskey const char *, char **, uint_t); 524ac67f02SAnurag S. Maskey static dladm_status_t i_dladm_get_flowprop_db(dladm_handle_t, const char *, 534ac67f02SAnurag S. Maskey const char *, char **, uint_t *); 54da14cebeSEric Cheng 55da14cebeSEric Cheng static fpd_getf_t do_get_maxbw; 56da14cebeSEric Cheng static fpd_setf_t do_set_maxbw; 57da14cebeSEric Cheng static fpd_checkf_t do_check_maxbw; 58da14cebeSEric Cheng 59da14cebeSEric Cheng static fpd_getf_t do_get_priority; 60da14cebeSEric Cheng static fpd_setf_t do_set_priority; 61da14cebeSEric Cheng static fpd_checkf_t do_check_priority; 62da14cebeSEric Cheng 63da14cebeSEric Cheng static fprop_desc_t prop_table[] = { 64da14cebeSEric Cheng { "maxbw", { "", NULL }, NULL, 0, B_FALSE, 65da14cebeSEric Cheng do_set_maxbw, NULL, 66da14cebeSEric Cheng do_get_maxbw, do_check_maxbw}, 67da14cebeSEric Cheng { "priority", { "", NULL }, NULL, 0, B_FALSE, 68da14cebeSEric Cheng do_set_priority, NULL, 69da14cebeSEric Cheng do_get_priority, do_check_priority} 70da14cebeSEric Cheng }; 71da14cebeSEric Cheng 72da14cebeSEric Cheng #define DLADM_MAX_FLOWPROPS (sizeof (prop_table) / sizeof (fprop_desc_t)) 73da14cebeSEric Cheng 74da14cebeSEric Cheng static prop_table_t prop_tbl = { 75da14cebeSEric Cheng prop_table, 76da14cebeSEric Cheng DLADM_MAX_FLOWPROPS 77da14cebeSEric Cheng }; 78da14cebeSEric Cheng 79da14cebeSEric Cheng static resource_prop_t rsrc_prop_table[] = { 80da14cebeSEric Cheng {"maxbw", do_extract_maxbw}, 81da14cebeSEric Cheng {"priority", do_extract_priority} 82da14cebeSEric Cheng }; 83da14cebeSEric Cheng #define DLADM_MAX_RSRC_PROP (sizeof (rsrc_prop_table) / \ 84da14cebeSEric Cheng sizeof (resource_prop_t)) 85da14cebeSEric Cheng 86da14cebeSEric Cheng static dladm_status_t flow_proplist_check(dladm_arg_list_t *); 87da14cebeSEric Cheng 88da14cebeSEric Cheng dladm_status_t 894ac67f02SAnurag S. Maskey dladm_set_flowprop(dladm_handle_t handle, const char *flow, 904ac67f02SAnurag S. Maskey const char *prop_name, char **prop_val, uint_t val_cnt, uint_t flags, 914ac67f02SAnurag S. Maskey char **errprop) 92da14cebeSEric Cheng { 93da14cebeSEric Cheng dladm_status_t status = DLADM_STATUS_BADARG; 94da14cebeSEric Cheng 95da14cebeSEric Cheng if (flow == NULL || (prop_val == NULL && val_cnt > 0) || 96da14cebeSEric Cheng (prop_val != NULL && val_cnt == 0) || flags == 0) 97da14cebeSEric Cheng return (DLADM_STATUS_BADARG); 98da14cebeSEric Cheng 99da14cebeSEric Cheng if ((flags & DLADM_OPT_ACTIVE) != 0) { 1004ac67f02SAnurag S. Maskey status = i_dladm_set_prop_temp(handle, flow, prop_name, 1014ac67f02SAnurag S. Maskey prop_val, val_cnt, flags, errprop, &prop_tbl); 102da14cebeSEric Cheng if (status == DLADM_STATUS_TEMPONLY && 103da14cebeSEric Cheng (flags & DLADM_OPT_PERSIST) != 0) 104da14cebeSEric Cheng return (DLADM_STATUS_TEMPONLY); 105da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 106da14cebeSEric Cheng return (status); 107da14cebeSEric Cheng } 108da14cebeSEric Cheng if ((flags & DLADM_OPT_PERSIST) != 0) { 109da14cebeSEric Cheng if (i_dladm_is_prop_temponly(prop_name, errprop, &prop_tbl)) 110da14cebeSEric Cheng return (DLADM_STATUS_TEMPONLY); 111da14cebeSEric Cheng 1124ac67f02SAnurag S. Maskey status = i_dladm_set_flowprop_db(handle, flow, prop_name, 113da14cebeSEric Cheng prop_val, val_cnt); 114da14cebeSEric Cheng } 115da14cebeSEric Cheng return (status); 116da14cebeSEric Cheng } 117da14cebeSEric Cheng 118da14cebeSEric Cheng dladm_status_t 119da14cebeSEric Cheng dladm_walk_flowprop(int (*func)(void *, const char *), const char *flow, 120da14cebeSEric Cheng void *arg) 121da14cebeSEric Cheng { 122da14cebeSEric Cheng int i; 123da14cebeSEric Cheng 124da14cebeSEric Cheng if (flow == NULL || func == NULL) 125da14cebeSEric Cheng return (DLADM_STATUS_BADARG); 126da14cebeSEric Cheng 127da14cebeSEric Cheng /* Then show data-flow properties if there are any */ 128da14cebeSEric Cheng for (i = 0; i < DLADM_MAX_FLOWPROPS; i++) { 129da14cebeSEric Cheng if (func(arg, prop_table[i].pd_name) != DLADM_WALK_CONTINUE) 130da14cebeSEric Cheng break; 131da14cebeSEric Cheng } 132da14cebeSEric Cheng return (DLADM_STATUS_OK); 133da14cebeSEric Cheng } 134da14cebeSEric Cheng 135da14cebeSEric Cheng dladm_status_t 1364ac67f02SAnurag S. Maskey dladm_get_flowprop(dladm_handle_t handle, const char *flow, uint32_t type, 137da14cebeSEric Cheng const char *prop_name, char **prop_val, uint_t *val_cntp) 138da14cebeSEric Cheng { 139da14cebeSEric Cheng dladm_status_t status; 140da14cebeSEric Cheng 141da14cebeSEric Cheng if (flow == NULL || prop_name == NULL || prop_val == NULL || 142da14cebeSEric Cheng val_cntp == NULL || *val_cntp == 0) 143da14cebeSEric Cheng return (DLADM_STATUS_BADARG); 144da14cebeSEric Cheng 145da14cebeSEric Cheng if (type == DLADM_PROP_VAL_PERSISTENT) { 146da14cebeSEric Cheng if (i_dladm_is_prop_temponly(prop_name, NULL, &prop_tbl)) 147da14cebeSEric Cheng return (DLADM_STATUS_TEMPONLY); 1484ac67f02SAnurag S. Maskey return (i_dladm_get_flowprop_db(handle, flow, prop_name, 149da14cebeSEric Cheng prop_val, val_cntp)); 150da14cebeSEric Cheng } 151da14cebeSEric Cheng 1524ac67f02SAnurag S. Maskey status = i_dladm_get_prop_temp(handle, flow, type, prop_name, 153da14cebeSEric Cheng prop_val, val_cntp, &prop_tbl); 154da14cebeSEric Cheng if (status != DLADM_STATUS_NOTFOUND) 155da14cebeSEric Cheng return (status); 156da14cebeSEric Cheng 157da14cebeSEric Cheng return (DLADM_STATUS_BADARG); 158da14cebeSEric Cheng } 159da14cebeSEric Cheng 1604ac67f02SAnurag S. Maskey #define FLOWPROP_RW_DB(handle, statep, writeop) \ 1614ac67f02SAnurag S. Maskey (i_dladm_rw_db(handle, "/etc/dladm/flowprop.conf", \ 162da14cebeSEric Cheng S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH, process_prop_db, \ 163da14cebeSEric Cheng (statep), (writeop))) 164da14cebeSEric Cheng 165da14cebeSEric Cheng static dladm_status_t 1664ac67f02SAnurag S. Maskey i_dladm_set_flowprop_db(dladm_handle_t handle, const char *flow, 1674ac67f02SAnurag S. Maskey const char *prop_name, char **prop_val, uint_t val_cnt) 168da14cebeSEric Cheng { 169da14cebeSEric Cheng prop_db_state_t state; 170da14cebeSEric Cheng 171da14cebeSEric Cheng state.ls_op = process_prop_set; 172da14cebeSEric Cheng state.ls_name = flow; 173da14cebeSEric Cheng state.ls_propname = prop_name; 174da14cebeSEric Cheng state.ls_propval = prop_val; 175da14cebeSEric Cheng state.ls_valcntp = &val_cnt; 176da14cebeSEric Cheng state.ls_initop = NULL; 177da14cebeSEric Cheng 1784ac67f02SAnurag S. Maskey return (FLOWPROP_RW_DB(handle, &state, B_TRUE)); 179da14cebeSEric Cheng } 180da14cebeSEric Cheng 181da14cebeSEric Cheng static dladm_status_t 1824ac67f02SAnurag S. Maskey i_dladm_get_flowprop_db(dladm_handle_t handle, const char *flow, 1834ac67f02SAnurag S. Maskey const char *prop_name, char **prop_val, uint_t *val_cntp) 184da14cebeSEric Cheng { 185da14cebeSEric Cheng prop_db_state_t state; 186da14cebeSEric Cheng 187da14cebeSEric Cheng state.ls_op = process_prop_get; 188da14cebeSEric Cheng state.ls_name = flow; 189da14cebeSEric Cheng state.ls_propname = prop_name; 190da14cebeSEric Cheng state.ls_propval = prop_val; 191da14cebeSEric Cheng state.ls_valcntp = val_cntp; 192da14cebeSEric Cheng state.ls_initop = NULL; 193da14cebeSEric Cheng 1944ac67f02SAnurag S. Maskey return (FLOWPROP_RW_DB(handle, &state, B_FALSE)); 195da14cebeSEric Cheng } 196da14cebeSEric Cheng 197da14cebeSEric Cheng dladm_status_t 1984ac67f02SAnurag S. Maskey i_dladm_init_flowprop_db(dladm_handle_t handle) 199da14cebeSEric Cheng { 200da14cebeSEric Cheng prop_db_state_t state; 201da14cebeSEric Cheng 202da14cebeSEric Cheng state.ls_op = process_prop_init; 203da14cebeSEric Cheng state.ls_name = NULL; 204da14cebeSEric Cheng state.ls_propname = NULL; 205da14cebeSEric Cheng state.ls_propval = NULL; 206da14cebeSEric Cheng state.ls_valcntp = NULL; 207da14cebeSEric Cheng state.ls_initop = dladm_set_flowprop; 208da14cebeSEric Cheng 2094ac67f02SAnurag S. Maskey return (FLOWPROP_RW_DB(handle, &state, B_FALSE)); 210da14cebeSEric Cheng } 211da14cebeSEric Cheng 212da14cebeSEric Cheng #define MIN_INFO_SIZE (4 * 1024) 213da14cebeSEric Cheng 214da14cebeSEric Cheng dladm_status_t 2154ac67f02SAnurag S. Maskey dladm_flow_info(dladm_handle_t handle, const char *flow, 2164ac67f02SAnurag S. Maskey dladm_flow_attr_t *attr) 217da14cebeSEric Cheng { 218da14cebeSEric Cheng dld_ioc_walkflow_t *ioc; 2194ac67f02SAnurag S. Maskey int bufsize; 220da14cebeSEric Cheng dld_flowinfo_t *flowinfo; 221da14cebeSEric Cheng 222da14cebeSEric Cheng if ((flow == NULL) || (attr == NULL)) 223da14cebeSEric Cheng return (DLADM_STATUS_BADARG); 224da14cebeSEric Cheng 225da14cebeSEric Cheng bufsize = MIN_INFO_SIZE; 2264ac67f02SAnurag S. Maskey if ((ioc = calloc(1, bufsize)) == NULL) 227da14cebeSEric Cheng return (dladm_errno2status(errno)); 228da14cebeSEric Cheng 229da14cebeSEric Cheng (void) strlcpy(ioc->wf_name, flow, sizeof (ioc->wf_name)); 230da14cebeSEric Cheng ioc->wf_len = bufsize - sizeof (*ioc); 231da14cebeSEric Cheng 2324ac67f02SAnurag S. Maskey while (ioctl(dladm_dld_fd(handle), DLDIOC_WALKFLOW, ioc) < 0) { 233da14cebeSEric Cheng if (errno == ENOSPC) { 234da14cebeSEric Cheng bufsize *= 2; 235da14cebeSEric Cheng ioc = realloc(ioc, bufsize); 236da14cebeSEric Cheng if (ioc != NULL) { 237da14cebeSEric Cheng (void) strlcpy(ioc->wf_name, flow, 238da000602SGirish Moodalbail MAXFLOWNAMELEN); 239da14cebeSEric Cheng ioc->wf_len = bufsize - sizeof (*ioc); 240da14cebeSEric Cheng continue; 241da14cebeSEric Cheng } 242da14cebeSEric Cheng } 243da14cebeSEric Cheng free(ioc); 244da14cebeSEric Cheng return (dladm_errno2status(errno)); 245da14cebeSEric Cheng } 246da14cebeSEric Cheng 247da14cebeSEric Cheng bzero(attr, sizeof (*attr)); 248da14cebeSEric Cheng 249da14cebeSEric Cheng flowinfo = (dld_flowinfo_t *)(void *)(ioc + 1); 250da14cebeSEric Cheng 251da14cebeSEric Cheng attr->fa_linkid = flowinfo->fi_linkid; 252da14cebeSEric Cheng bcopy(&flowinfo->fi_flowname, &attr->fa_flowname, 253da14cebeSEric Cheng sizeof (attr->fa_flowname)); 254da14cebeSEric Cheng bcopy(&flowinfo->fi_flow_desc, &attr->fa_flow_desc, 255da14cebeSEric Cheng sizeof (attr->fa_flow_desc)); 256da14cebeSEric Cheng bcopy(&flowinfo->fi_resource_props, &attr->fa_resource_props, 257da14cebeSEric Cheng sizeof (attr->fa_resource_props)); 258da14cebeSEric Cheng 259da14cebeSEric Cheng free(ioc); 260da14cebeSEric Cheng return (DLADM_STATUS_OK); 261da14cebeSEric Cheng } 262da14cebeSEric Cheng 263da14cebeSEric Cheng /* ARGSUSED */ 264da14cebeSEric Cheng static dladm_status_t 2654ac67f02SAnurag S. Maskey do_get_maxbw(dladm_handle_t handle, const char *flow, char **prop_val, 2664ac67f02SAnurag S. Maskey uint_t *val_cnt) 267da14cebeSEric Cheng { 268da14cebeSEric Cheng mac_resource_props_t *mrp; 269da14cebeSEric Cheng char buf[DLADM_STRSIZE]; 270da14cebeSEric Cheng dladm_flow_attr_t fa; 271da14cebeSEric Cheng dladm_status_t status; 272da14cebeSEric Cheng 2734ac67f02SAnurag S. Maskey status = dladm_flow_info(handle, flow, &fa); 274da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 275da14cebeSEric Cheng return (status); 276da14cebeSEric Cheng mrp = &(fa.fa_resource_props); 277da14cebeSEric Cheng 278da14cebeSEric Cheng *val_cnt = 1; 279da14cebeSEric Cheng if (mrp->mrp_mask & MRP_MAXBW) { 280da14cebeSEric Cheng (void) snprintf(prop_val[0], DLADM_STRSIZE, "%s", 281da14cebeSEric Cheng dladm_bw2str(mrp->mrp_maxbw, buf)); 282da14cebeSEric Cheng } else { 283da14cebeSEric Cheng return (DLADM_STATUS_NOTSUP); 284da14cebeSEric Cheng } 285da14cebeSEric Cheng return (DLADM_STATUS_OK); 286da14cebeSEric Cheng } 287da14cebeSEric Cheng 288da14cebeSEric Cheng /* ARGSUSED */ 289da14cebeSEric Cheng static dladm_status_t 2904ac67f02SAnurag S. Maskey do_set_maxbw(dladm_handle_t handle, const char *flow, val_desc_t *vdp, 2914ac67f02SAnurag S. Maskey uint_t val_cnt) 292da14cebeSEric Cheng { 293da14cebeSEric Cheng dld_ioc_modifyflow_t attr; 294da14cebeSEric Cheng mac_resource_props_t mrp; 295da14cebeSEric Cheng void *val; 296da14cebeSEric Cheng 297da14cebeSEric Cheng if (val_cnt != 1) 298da14cebeSEric Cheng return (DLADM_STATUS_BADVALCNT); 299da14cebeSEric Cheng 300da14cebeSEric Cheng bzero(&mrp, sizeof (mrp)); 301da14cebeSEric Cheng if (vdp != NULL && (val = (void *)vdp->vd_val) != NULL) { 302da14cebeSEric Cheng bcopy(val, &mrp.mrp_maxbw, sizeof (int64_t)); 303da14cebeSEric Cheng free(val); 304da14cebeSEric Cheng } else { 305da14cebeSEric Cheng mrp.mrp_maxbw = MRP_MAXBW_RESETVAL; 306da14cebeSEric Cheng } 307da14cebeSEric Cheng mrp.mrp_mask = MRP_MAXBW; 308da14cebeSEric Cheng 309da14cebeSEric Cheng bzero(&attr, sizeof (attr)); 310da14cebeSEric Cheng (void) strlcpy(attr.mf_name, flow, sizeof (attr.mf_name)); 311da14cebeSEric Cheng bcopy(&mrp, &attr.mf_resource_props, sizeof (mac_resource_props_t)); 312da14cebeSEric Cheng 3134ac67f02SAnurag S. Maskey if (ioctl(dladm_dld_fd(handle), DLDIOC_MODIFYFLOW, &attr) < 0) 314da14cebeSEric Cheng return (dladm_errno2status(errno)); 315da14cebeSEric Cheng 316da14cebeSEric Cheng return (DLADM_STATUS_OK); 317da14cebeSEric Cheng } 318da14cebeSEric Cheng 319da14cebeSEric Cheng /* ARGSUSED */ 320da14cebeSEric Cheng static dladm_status_t 321da14cebeSEric Cheng do_check_maxbw(fprop_desc_t *pdp, char **prop_val, uint_t val_cnt, 322da14cebeSEric Cheng val_desc_t **vdpp) 323da14cebeSEric Cheng { 324da14cebeSEric Cheng uint64_t *maxbw; 325da14cebeSEric Cheng val_desc_t *vdp = NULL; 326da14cebeSEric Cheng dladm_status_t status = DLADM_STATUS_OK; 327da14cebeSEric Cheng 328da14cebeSEric Cheng if (val_cnt != 1) 329da14cebeSEric Cheng return (DLADM_STATUS_BADVALCNT); 330da14cebeSEric Cheng 331da14cebeSEric Cheng maxbw = malloc(sizeof (uint64_t)); 332da14cebeSEric Cheng if (maxbw == NULL) 333da14cebeSEric Cheng return (DLADM_STATUS_NOMEM); 334da14cebeSEric Cheng 335da14cebeSEric Cheng status = dladm_str2bw(*prop_val, maxbw); 336da14cebeSEric Cheng if (status != DLADM_STATUS_OK) { 337da14cebeSEric Cheng free(maxbw); 338da14cebeSEric Cheng return (status); 339da14cebeSEric Cheng } 340da14cebeSEric Cheng 341da14cebeSEric Cheng if ((*maxbw < MRP_MAXBW_MINVAL) && (*maxbw != 0)) { 342da14cebeSEric Cheng free(maxbw); 343da14cebeSEric Cheng return (DLADM_STATUS_MINMAXBW); 344da14cebeSEric Cheng } 345da14cebeSEric Cheng 346da14cebeSEric Cheng vdp = malloc(sizeof (val_desc_t)); 347da14cebeSEric Cheng if (vdp == NULL) { 348da14cebeSEric Cheng free(maxbw); 349da14cebeSEric Cheng return (DLADM_STATUS_NOMEM); 350da14cebeSEric Cheng } 351da14cebeSEric Cheng 352da14cebeSEric Cheng vdp->vd_val = (uintptr_t)maxbw; 353da14cebeSEric Cheng *vdpp = vdp; 354da14cebeSEric Cheng return (DLADM_STATUS_OK); 355da14cebeSEric Cheng } 356da14cebeSEric Cheng 357da14cebeSEric Cheng /* ARGSUSED */ 358da14cebeSEric Cheng static dladm_status_t 3594ac67f02SAnurag S. Maskey do_get_priority(dladm_handle_t handle, const char *flow, char **prop_val, 3604ac67f02SAnurag S. Maskey uint_t *val_cnt) 361da14cebeSEric Cheng { 362da14cebeSEric Cheng mac_resource_props_t *mrp; 363da14cebeSEric Cheng char buf[DLADM_STRSIZE]; 364da14cebeSEric Cheng dladm_flow_attr_t fa; 365da14cebeSEric Cheng dladm_status_t status; 366da14cebeSEric Cheng 367da14cebeSEric Cheng bzero(&fa, sizeof (dladm_flow_attr_t)); 3684ac67f02SAnurag S. Maskey status = dladm_flow_info(handle, flow, &fa); 369da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 370da14cebeSEric Cheng return (status); 371da14cebeSEric Cheng mrp = &(fa.fa_resource_props); 372da14cebeSEric Cheng 373da14cebeSEric Cheng *val_cnt = 1; 374da14cebeSEric Cheng if (mrp->mrp_mask & MRP_PRIORITY) { 375da14cebeSEric Cheng (void) snprintf(prop_val[0], DLADM_STRSIZE, "%s", 376da14cebeSEric Cheng dladm_pri2str(mrp->mrp_priority, buf)); 377da14cebeSEric Cheng } else { 378da14cebeSEric Cheng return (DLADM_STATUS_NOTSUP); 379da14cebeSEric Cheng } 380da14cebeSEric Cheng return (DLADM_STATUS_OK); 381da14cebeSEric Cheng } 382da14cebeSEric Cheng 383da14cebeSEric Cheng /* ARGSUSED */ 384da14cebeSEric Cheng static dladm_status_t 3854ac67f02SAnurag S. Maskey do_set_priority(dladm_handle_t handle, const char *flow, val_desc_t *vdp, 3864ac67f02SAnurag S. Maskey uint_t val_cnt) 387da14cebeSEric Cheng { 388da14cebeSEric Cheng dld_ioc_modifyflow_t attr; 389da14cebeSEric Cheng mac_resource_props_t mrp; 390da14cebeSEric Cheng void *val; 391da14cebeSEric Cheng 392da14cebeSEric Cheng if (val_cnt != 1) 393da14cebeSEric Cheng return (DLADM_STATUS_BADVALCNT); 394da14cebeSEric Cheng 395da14cebeSEric Cheng bzero(&mrp, sizeof (mrp)); 396da14cebeSEric Cheng if (vdp != NULL && (val = (void *)vdp->vd_val) != NULL) { 397da14cebeSEric Cheng bcopy(val, &mrp.mrp_priority, sizeof (mac_priority_level_t)); 398da14cebeSEric Cheng free(val); 399da14cebeSEric Cheng } else { 400da14cebeSEric Cheng mrp.mrp_priority = MPL_RESET; 401da14cebeSEric Cheng } 402da14cebeSEric Cheng mrp.mrp_mask = MRP_PRIORITY; 403da14cebeSEric Cheng 404da14cebeSEric Cheng bzero(&attr, sizeof (attr)); 405da14cebeSEric Cheng (void) strlcpy(attr.mf_name, flow, sizeof (attr.mf_name)); 406da14cebeSEric Cheng bcopy(&mrp, &attr.mf_resource_props, sizeof (mac_resource_props_t)); 407da14cebeSEric Cheng 4084ac67f02SAnurag S. Maskey if (ioctl(dladm_dld_fd(handle), DLDIOC_MODIFYFLOW, &attr) < 0) 409da14cebeSEric Cheng return (dladm_errno2status(errno)); 410da14cebeSEric Cheng 411da14cebeSEric Cheng return (DLADM_STATUS_OK); 412da14cebeSEric Cheng } 413da14cebeSEric Cheng 414da14cebeSEric Cheng /* ARGSUSED */ 415da14cebeSEric Cheng static dladm_status_t 416da14cebeSEric Cheng do_check_priority(fprop_desc_t *pdp, char **prop_val, uint_t val_cnt, 417da14cebeSEric Cheng val_desc_t **vdpp) 418da14cebeSEric Cheng { 419da14cebeSEric Cheng mac_priority_level_t *pri; 420da14cebeSEric Cheng val_desc_t *vdp = NULL; 421da14cebeSEric Cheng dladm_status_t status = DLADM_STATUS_OK; 422da14cebeSEric Cheng 423da14cebeSEric Cheng if (val_cnt != 1) 424da14cebeSEric Cheng return (DLADM_STATUS_BADVALCNT); 425da14cebeSEric Cheng 426da14cebeSEric Cheng pri = malloc(sizeof (mac_priority_level_t)); 427da14cebeSEric Cheng if (pri == NULL) 428da14cebeSEric Cheng return (DLADM_STATUS_NOMEM); 429da14cebeSEric Cheng 430da14cebeSEric Cheng status = dladm_str2pri(*prop_val, pri); 431da14cebeSEric Cheng if (status != DLADM_STATUS_OK) { 432da14cebeSEric Cheng free(pri); 433da14cebeSEric Cheng return (status); 434da14cebeSEric Cheng } 435da14cebeSEric Cheng 436da14cebeSEric Cheng if (*pri == -1) { 437da14cebeSEric Cheng free(pri); 438da14cebeSEric Cheng return (DLADM_STATUS_BADVAL); 439da14cebeSEric Cheng } 440da14cebeSEric Cheng 441da14cebeSEric Cheng vdp = malloc(sizeof (val_desc_t)); 442da14cebeSEric Cheng if (vdp == NULL) { 443da14cebeSEric Cheng free(pri); 444da14cebeSEric Cheng return (DLADM_STATUS_NOMEM); 445da14cebeSEric Cheng } 446da14cebeSEric Cheng 447da14cebeSEric Cheng vdp->vd_val = (uintptr_t)pri; 448da14cebeSEric Cheng *vdpp = vdp; 449da14cebeSEric Cheng return (DLADM_STATUS_OK); 450da14cebeSEric Cheng } 451da14cebeSEric Cheng 452da14cebeSEric Cheng static dladm_status_t 453da14cebeSEric Cheng flow_proplist_check(dladm_arg_list_t *proplist) 454da14cebeSEric Cheng { 455da14cebeSEric Cheng int i, j; 456da14cebeSEric Cheng boolean_t matched; 457da14cebeSEric Cheng 458da14cebeSEric Cheng for (i = 0; i < proplist->al_count; i++) { 459da14cebeSEric Cheng matched = B_FALSE; 460da14cebeSEric Cheng for (j = 0; j < DLADM_MAX_FLOWPROPS; j++) { 461da14cebeSEric Cheng if (strcmp(proplist->al_info[i].ai_name, 462da14cebeSEric Cheng prop_table[j].pd_name) == 0) 463da14cebeSEric Cheng matched = B_TRUE; 464da14cebeSEric Cheng } 465da14cebeSEric Cheng if (!matched) 466da14cebeSEric Cheng return (DLADM_STATUS_BADPROP); 467da14cebeSEric Cheng } 468da14cebeSEric Cheng return (DLADM_STATUS_OK); 469da14cebeSEric Cheng 470da14cebeSEric Cheng } 471da14cebeSEric Cheng 472da14cebeSEric Cheng dladm_status_t 473da14cebeSEric Cheng dladm_parse_flow_props(char *str, dladm_arg_list_t **listp, boolean_t novalues) 474da14cebeSEric Cheng { 475da14cebeSEric Cheng dladm_status_t status; 476da14cebeSEric Cheng 477da14cebeSEric Cheng status = dladm_parse_args(str, listp, novalues); 478da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 479da14cebeSEric Cheng return (status); 480da14cebeSEric Cheng 48163a6526dSMichael Lim if (*listp != NULL && (status = flow_proplist_check(*listp) 48263a6526dSMichael Lim != DLADM_STATUS_OK)) { 483da14cebeSEric Cheng dladm_free_props(*listp); 484da14cebeSEric Cheng return (status); 485da14cebeSEric Cheng } 486da14cebeSEric Cheng 487da14cebeSEric Cheng return (DLADM_STATUS_OK); 488da14cebeSEric Cheng } 489da14cebeSEric Cheng 490da14cebeSEric Cheng /* 491da14cebeSEric Cheng * Retrieve the named property from a proplist, check the value and 492da14cebeSEric Cheng * convert to a kernel structure. 493da14cebeSEric Cheng */ 494da14cebeSEric Cheng static dladm_status_t 495da14cebeSEric Cheng i_dladm_flow_proplist_extract_one(dladm_arg_list_t *proplist, 496*25ec3e3dSEric Cheng const char *name, void *arg) 497da14cebeSEric Cheng { 498da14cebeSEric Cheng dladm_status_t status; 499da14cebeSEric Cheng dladm_arg_info_t *aip = NULL; 500da14cebeSEric Cheng int i, j; 501da14cebeSEric Cheng 502da14cebeSEric Cheng /* Find named property in proplist */ 503da14cebeSEric Cheng for (i = 0; i < proplist->al_count; i++) { 504da14cebeSEric Cheng aip = &proplist->al_info[i]; 505da14cebeSEric Cheng if (strcasecmp(aip->ai_name, name) == 0) 506da14cebeSEric Cheng break; 507da14cebeSEric Cheng } 508da14cebeSEric Cheng 509da14cebeSEric Cheng /* Property not in list */ 510da14cebeSEric Cheng if (i == proplist->al_count) 511da14cebeSEric Cheng return (DLADM_STATUS_OK); 512da14cebeSEric Cheng 513da14cebeSEric Cheng for (i = 0; i < DLADM_MAX_FLOWPROPS; i++) { 514da14cebeSEric Cheng fprop_desc_t *pdp = &prop_table[i]; 515da14cebeSEric Cheng val_desc_t *vdp; 516da14cebeSEric Cheng 517da14cebeSEric Cheng vdp = malloc(sizeof (val_desc_t) * aip->ai_count); 518da14cebeSEric Cheng if (vdp == NULL) 519da14cebeSEric Cheng return (DLADM_STATUS_NOMEM); 520da14cebeSEric Cheng 521da14cebeSEric Cheng if (strcasecmp(aip->ai_name, pdp->pd_name) != 0) 522da14cebeSEric Cheng continue; 523da14cebeSEric Cheng 524da14cebeSEric Cheng if (aip->ai_val == NULL) 525da14cebeSEric Cheng return (DLADM_STATUS_BADARG); 526da14cebeSEric Cheng 527da14cebeSEric Cheng /* Check property value */ 528da14cebeSEric Cheng if (pdp->pd_check != NULL) { 529da14cebeSEric Cheng status = pdp->pd_check(pdp, aip->ai_val, 530da14cebeSEric Cheng aip->ai_count, &vdp); 531da14cebeSEric Cheng } else { 532da14cebeSEric Cheng status = DLADM_STATUS_BADARG; 533da14cebeSEric Cheng } 534da14cebeSEric Cheng 535da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 536da14cebeSEric Cheng return (status); 537da14cebeSEric Cheng 538da14cebeSEric Cheng for (j = 0; j < DLADM_MAX_RSRC_PROP; j++) { 539da14cebeSEric Cheng resource_prop_t *rpp = &rsrc_prop_table[j]; 540da14cebeSEric Cheng 541da14cebeSEric Cheng if (strcasecmp(aip->ai_name, rpp->rp_name) != 0) 542da14cebeSEric Cheng continue; 543da14cebeSEric Cheng 544da14cebeSEric Cheng /* Extract kernel structure */ 545da14cebeSEric Cheng if (rpp->rp_extract != NULL) { 546*25ec3e3dSEric Cheng status = rpp->rp_extract(vdp, 547*25ec3e3dSEric Cheng aip->ai_count, arg); 548da14cebeSEric Cheng } else { 549da14cebeSEric Cheng status = DLADM_STATUS_BADARG; 550da14cebeSEric Cheng } 551da14cebeSEric Cheng break; 552da14cebeSEric Cheng } 553da14cebeSEric Cheng 554da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 555da14cebeSEric Cheng return (status); 556da14cebeSEric Cheng 557da14cebeSEric Cheng break; 558da14cebeSEric Cheng } 559da14cebeSEric Cheng return (status); 560da14cebeSEric Cheng } 561da14cebeSEric Cheng 562da14cebeSEric Cheng /* 563da14cebeSEric Cheng * Extract properties from a proplist and convert to mac_resource_props_t. 564da14cebeSEric Cheng */ 565da14cebeSEric Cheng dladm_status_t 566da14cebeSEric Cheng dladm_flow_proplist_extract(dladm_arg_list_t *proplist, 567da14cebeSEric Cheng mac_resource_props_t *mrp) 568da14cebeSEric Cheng { 569da14cebeSEric Cheng dladm_status_t status = DLADM_STATUS_OK; 570da14cebeSEric Cheng 571da14cebeSEric Cheng status = i_dladm_flow_proplist_extract_one(proplist, "maxbw", mrp); 572da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 573da14cebeSEric Cheng return (status); 574da14cebeSEric Cheng status = i_dladm_flow_proplist_extract_one(proplist, "priority", mrp); 575da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 576da14cebeSEric Cheng return (status); 577da14cebeSEric Cheng return (status); 578da14cebeSEric Cheng } 579da14cebeSEric Cheng 580da14cebeSEric Cheng dladm_status_t 5814ac67f02SAnurag S. Maskey i_dladm_set_flow_proplist_db(dladm_handle_t handle, char *flow, 5824ac67f02SAnurag S. Maskey dladm_arg_list_t *proplist) 583da14cebeSEric Cheng { 584da14cebeSEric Cheng dladm_status_t status, ssave = DLADM_STATUS_OK; 585da14cebeSEric Cheng dladm_arg_info_t ai; 586da14cebeSEric Cheng int i; 587da14cebeSEric Cheng 588da14cebeSEric Cheng for (i = 0; i < proplist->al_count; i++) { 589da14cebeSEric Cheng ai = proplist->al_info[i]; 5904ac67f02SAnurag S. Maskey status = i_dladm_set_flowprop_db(handle, flow, ai.ai_name, 591da14cebeSEric Cheng ai.ai_val, ai.ai_count); 592da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 593da14cebeSEric Cheng ssave = status; 594da14cebeSEric Cheng } 595da14cebeSEric Cheng return (ssave); 596da14cebeSEric Cheng } 597