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> 33da14cebeSEric Cheng #include <fcntl.h> 34da14cebeSEric Cheng #include <unistd.h> 35da14cebeSEric Cheng #include <libdevinfo.h> 36da14cebeSEric Cheng #include <libdladm_impl.h> 37da14cebeSEric Cheng #include <libdlflow.h> 38da14cebeSEric Cheng #include <libdlflow_impl.h> 39da14cebeSEric Cheng #include <libintl.h> 40da14cebeSEric Cheng 41da14cebeSEric Cheng #include <dlfcn.h> 42da14cebeSEric Cheng #include <link.h> 43da14cebeSEric Cheng 44da14cebeSEric Cheng /* 45da14cebeSEric Cheng * XXX duplicate define 46da14cebeSEric Cheng */ 47da14cebeSEric Cheng #define DLADM_PROP_VAL_MAX 32 48da14cebeSEric Cheng 494ac67f02SAnurag S. Maskey static dladm_status_t i_dladm_set_flowprop_db(dladm_handle_t, const char *, 504ac67f02SAnurag S. Maskey const char *, char **, uint_t); 514ac67f02SAnurag S. Maskey static dladm_status_t i_dladm_get_flowprop_db(dladm_handle_t, const char *, 524ac67f02SAnurag S. Maskey const char *, char **, uint_t *); 53da14cebeSEric Cheng 54da14cebeSEric Cheng static fpd_getf_t do_get_maxbw; 55da14cebeSEric Cheng static fpd_setf_t do_set_maxbw; 56da14cebeSEric Cheng static fpd_checkf_t do_check_maxbw; 57da14cebeSEric Cheng 58da14cebeSEric Cheng static fpd_getf_t do_get_priority; 59da14cebeSEric Cheng static fpd_setf_t do_set_priority; 60da14cebeSEric Cheng static fpd_checkf_t do_check_priority; 61da14cebeSEric Cheng 62da14cebeSEric Cheng static fprop_desc_t prop_table[] = { 63da14cebeSEric Cheng { "maxbw", { "", NULL }, NULL, 0, B_FALSE, 64da14cebeSEric Cheng do_set_maxbw, NULL, 65da14cebeSEric Cheng do_get_maxbw, do_check_maxbw}, 66da14cebeSEric Cheng { "priority", { "", NULL }, NULL, 0, B_FALSE, 67da14cebeSEric Cheng do_set_priority, NULL, 68da14cebeSEric Cheng do_get_priority, do_check_priority} 69da14cebeSEric Cheng }; 70da14cebeSEric Cheng 71da14cebeSEric Cheng #define DLADM_MAX_FLOWPROPS (sizeof (prop_table) / sizeof (fprop_desc_t)) 72da14cebeSEric Cheng 73da14cebeSEric Cheng static prop_table_t prop_tbl = { 74da14cebeSEric Cheng prop_table, 75da14cebeSEric Cheng DLADM_MAX_FLOWPROPS 76da14cebeSEric Cheng }; 77da14cebeSEric Cheng 78da14cebeSEric Cheng static resource_prop_t rsrc_prop_table[] = { 79da14cebeSEric Cheng {"maxbw", do_extract_maxbw}, 80da14cebeSEric Cheng {"priority", do_extract_priority} 81da14cebeSEric Cheng }; 82da14cebeSEric Cheng #define DLADM_MAX_RSRC_PROP (sizeof (rsrc_prop_table) / \ 83da14cebeSEric Cheng sizeof (resource_prop_t)) 84da14cebeSEric Cheng 85da14cebeSEric Cheng static dladm_status_t flow_proplist_check(dladm_arg_list_t *); 86da14cebeSEric Cheng 87da14cebeSEric Cheng dladm_status_t 884ac67f02SAnurag S. Maskey dladm_set_flowprop(dladm_handle_t handle, const char *flow, 894ac67f02SAnurag S. Maskey const char *prop_name, char **prop_val, uint_t val_cnt, uint_t flags, 904ac67f02SAnurag S. Maskey char **errprop) 91da14cebeSEric Cheng { 92da14cebeSEric Cheng dladm_status_t status = DLADM_STATUS_BADARG; 93da14cebeSEric Cheng 94da14cebeSEric Cheng if (flow == NULL || (prop_val == NULL && val_cnt > 0) || 95da14cebeSEric Cheng (prop_val != NULL && val_cnt == 0) || flags == 0) 96da14cebeSEric Cheng return (DLADM_STATUS_BADARG); 97da14cebeSEric Cheng 98da14cebeSEric Cheng if ((flags & DLADM_OPT_ACTIVE) != 0) { 994ac67f02SAnurag S. Maskey status = i_dladm_set_prop_temp(handle, flow, prop_name, 1004ac67f02SAnurag S. Maskey prop_val, val_cnt, flags, errprop, &prop_tbl); 101da14cebeSEric Cheng if (status == DLADM_STATUS_TEMPONLY && 102da14cebeSEric Cheng (flags & DLADM_OPT_PERSIST) != 0) 103da14cebeSEric Cheng return (DLADM_STATUS_TEMPONLY); 104da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 105da14cebeSEric Cheng return (status); 106da14cebeSEric Cheng } 107da14cebeSEric Cheng if ((flags & DLADM_OPT_PERSIST) != 0) { 108da14cebeSEric Cheng if (i_dladm_is_prop_temponly(prop_name, errprop, &prop_tbl)) 109da14cebeSEric Cheng return (DLADM_STATUS_TEMPONLY); 110da14cebeSEric Cheng 1114ac67f02SAnurag S. Maskey status = i_dladm_set_flowprop_db(handle, flow, prop_name, 112da14cebeSEric Cheng prop_val, val_cnt); 113da14cebeSEric Cheng } 114da14cebeSEric Cheng return (status); 115da14cebeSEric Cheng } 116da14cebeSEric Cheng 117da14cebeSEric Cheng dladm_status_t 118da14cebeSEric Cheng dladm_walk_flowprop(int (*func)(void *, const char *), const char *flow, 119da14cebeSEric Cheng void *arg) 120da14cebeSEric Cheng { 121da14cebeSEric Cheng int i; 122da14cebeSEric Cheng 123da14cebeSEric Cheng if (flow == NULL || func == NULL) 124da14cebeSEric Cheng return (DLADM_STATUS_BADARG); 125da14cebeSEric Cheng 126da14cebeSEric Cheng /* Then show data-flow properties if there are any */ 127da14cebeSEric Cheng for (i = 0; i < DLADM_MAX_FLOWPROPS; i++) { 128da14cebeSEric Cheng if (func(arg, prop_table[i].pd_name) != DLADM_WALK_CONTINUE) 129da14cebeSEric Cheng break; 130da14cebeSEric Cheng } 131da14cebeSEric Cheng return (DLADM_STATUS_OK); 132da14cebeSEric Cheng } 133da14cebeSEric Cheng 134da14cebeSEric Cheng dladm_status_t 1354ac67f02SAnurag S. Maskey dladm_get_flowprop(dladm_handle_t handle, const char *flow, uint32_t type, 136da14cebeSEric Cheng const char *prop_name, char **prop_val, uint_t *val_cntp) 137da14cebeSEric Cheng { 138da14cebeSEric Cheng dladm_status_t status; 139da14cebeSEric Cheng 140da14cebeSEric Cheng if (flow == NULL || prop_name == NULL || prop_val == NULL || 141da14cebeSEric Cheng val_cntp == NULL || *val_cntp == 0) 142da14cebeSEric Cheng return (DLADM_STATUS_BADARG); 143da14cebeSEric Cheng 144da14cebeSEric Cheng if (type == DLADM_PROP_VAL_PERSISTENT) { 145da14cebeSEric Cheng if (i_dladm_is_prop_temponly(prop_name, NULL, &prop_tbl)) 146da14cebeSEric Cheng return (DLADM_STATUS_TEMPONLY); 1474ac67f02SAnurag S. Maskey return (i_dladm_get_flowprop_db(handle, flow, prop_name, 148da14cebeSEric Cheng prop_val, val_cntp)); 149da14cebeSEric Cheng } 150da14cebeSEric Cheng 1514ac67f02SAnurag S. Maskey status = i_dladm_get_prop_temp(handle, flow, type, prop_name, 152da14cebeSEric Cheng prop_val, val_cntp, &prop_tbl); 153da14cebeSEric Cheng if (status != DLADM_STATUS_NOTFOUND) 154da14cebeSEric Cheng return (status); 155da14cebeSEric Cheng 156da14cebeSEric Cheng return (DLADM_STATUS_BADARG); 157da14cebeSEric Cheng } 158da14cebeSEric Cheng 1594ac67f02SAnurag S. Maskey #define FLOWPROP_RW_DB(handle, statep, writeop) \ 1604ac67f02SAnurag S. Maskey (i_dladm_rw_db(handle, "/etc/dladm/flowprop.conf", \ 161da14cebeSEric Cheng S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH, process_prop_db, \ 162da14cebeSEric Cheng (statep), (writeop))) 163da14cebeSEric Cheng 164da14cebeSEric Cheng static dladm_status_t 1654ac67f02SAnurag S. Maskey i_dladm_set_flowprop_db(dladm_handle_t handle, const char *flow, 1664ac67f02SAnurag S. Maskey const char *prop_name, char **prop_val, uint_t val_cnt) 167da14cebeSEric Cheng { 168da14cebeSEric Cheng prop_db_state_t state; 169da14cebeSEric Cheng 170da14cebeSEric Cheng state.ls_op = process_prop_set; 171da14cebeSEric Cheng state.ls_name = flow; 172da14cebeSEric Cheng state.ls_propname = prop_name; 173da14cebeSEric Cheng state.ls_propval = prop_val; 174da14cebeSEric Cheng state.ls_valcntp = &val_cnt; 175da14cebeSEric Cheng state.ls_initop = NULL; 176da14cebeSEric Cheng 1774ac67f02SAnurag S. Maskey return (FLOWPROP_RW_DB(handle, &state, B_TRUE)); 178da14cebeSEric Cheng } 179da14cebeSEric Cheng 180da14cebeSEric Cheng static dladm_status_t 1814ac67f02SAnurag S. Maskey i_dladm_get_flowprop_db(dladm_handle_t handle, const char *flow, 1824ac67f02SAnurag S. Maskey const char *prop_name, char **prop_val, uint_t *val_cntp) 183da14cebeSEric Cheng { 184da14cebeSEric Cheng prop_db_state_t state; 185da14cebeSEric Cheng 186da14cebeSEric Cheng state.ls_op = process_prop_get; 187da14cebeSEric Cheng state.ls_name = flow; 188da14cebeSEric Cheng state.ls_propname = prop_name; 189da14cebeSEric Cheng state.ls_propval = prop_val; 190da14cebeSEric Cheng state.ls_valcntp = val_cntp; 191da14cebeSEric Cheng state.ls_initop = NULL; 192da14cebeSEric Cheng 1934ac67f02SAnurag S. Maskey return (FLOWPROP_RW_DB(handle, &state, B_FALSE)); 194da14cebeSEric Cheng } 195da14cebeSEric Cheng 196da14cebeSEric Cheng dladm_status_t 1974ac67f02SAnurag S. Maskey i_dladm_init_flowprop_db(dladm_handle_t handle) 198da14cebeSEric Cheng { 199da14cebeSEric Cheng prop_db_state_t state; 200da14cebeSEric Cheng 201da14cebeSEric Cheng state.ls_op = process_prop_init; 202da14cebeSEric Cheng state.ls_name = NULL; 203da14cebeSEric Cheng state.ls_propname = NULL; 204da14cebeSEric Cheng state.ls_propval = NULL; 205da14cebeSEric Cheng state.ls_valcntp = NULL; 206da14cebeSEric Cheng state.ls_initop = dladm_set_flowprop; 207da14cebeSEric Cheng 2084ac67f02SAnurag S. Maskey return (FLOWPROP_RW_DB(handle, &state, B_FALSE)); 209da14cebeSEric Cheng } 210da14cebeSEric Cheng 211da14cebeSEric Cheng #define MIN_INFO_SIZE (4 * 1024) 212da14cebeSEric Cheng 213da14cebeSEric Cheng dladm_status_t 2144ac67f02SAnurag S. Maskey dladm_flow_info(dladm_handle_t handle, const char *flow, 2154ac67f02SAnurag S. Maskey dladm_flow_attr_t *attr) 216da14cebeSEric Cheng { 217da14cebeSEric Cheng dld_ioc_walkflow_t *ioc; 2184ac67f02SAnurag S. Maskey int bufsize; 219da14cebeSEric Cheng dld_flowinfo_t *flowinfo; 220da14cebeSEric Cheng 221da14cebeSEric Cheng if ((flow == NULL) || (attr == NULL)) 222da14cebeSEric Cheng return (DLADM_STATUS_BADARG); 223da14cebeSEric Cheng 224da14cebeSEric Cheng bufsize = MIN_INFO_SIZE; 2254ac67f02SAnurag S. Maskey if ((ioc = calloc(1, bufsize)) == NULL) 226da14cebeSEric Cheng return (dladm_errno2status(errno)); 227da14cebeSEric Cheng 228da14cebeSEric Cheng (void) strlcpy(ioc->wf_name, flow, sizeof (ioc->wf_name)); 229da14cebeSEric Cheng ioc->wf_len = bufsize - sizeof (*ioc); 230da14cebeSEric Cheng 2314ac67f02SAnurag S. Maskey while (ioctl(dladm_dld_fd(handle), DLDIOC_WALKFLOW, ioc) < 0) { 232da14cebeSEric Cheng if (errno == ENOSPC) { 233da14cebeSEric Cheng bufsize *= 2; 234da14cebeSEric Cheng ioc = realloc(ioc, bufsize); 235da14cebeSEric Cheng if (ioc != NULL) { 236da14cebeSEric Cheng (void) strlcpy(ioc->wf_name, flow, 237da000602SGirish Moodalbail MAXFLOWNAMELEN); 238da14cebeSEric Cheng ioc->wf_len = bufsize - sizeof (*ioc); 239da14cebeSEric Cheng continue; 240da14cebeSEric Cheng } 241da14cebeSEric Cheng } 242da14cebeSEric Cheng free(ioc); 243da14cebeSEric Cheng return (dladm_errno2status(errno)); 244da14cebeSEric Cheng } 245da14cebeSEric Cheng 246da14cebeSEric Cheng bzero(attr, sizeof (*attr)); 247da14cebeSEric Cheng 248da14cebeSEric Cheng flowinfo = (dld_flowinfo_t *)(void *)(ioc + 1); 249da14cebeSEric Cheng 250da14cebeSEric Cheng attr->fa_linkid = flowinfo->fi_linkid; 251da14cebeSEric Cheng bcopy(&flowinfo->fi_flowname, &attr->fa_flowname, 252da14cebeSEric Cheng sizeof (attr->fa_flowname)); 253da14cebeSEric Cheng bcopy(&flowinfo->fi_flow_desc, &attr->fa_flow_desc, 254da14cebeSEric Cheng sizeof (attr->fa_flow_desc)); 255da14cebeSEric Cheng bcopy(&flowinfo->fi_resource_props, &attr->fa_resource_props, 256da14cebeSEric Cheng sizeof (attr->fa_resource_props)); 257da14cebeSEric Cheng 258da14cebeSEric Cheng free(ioc); 259da14cebeSEric Cheng return (DLADM_STATUS_OK); 260da14cebeSEric Cheng } 261da14cebeSEric Cheng 262da14cebeSEric Cheng /* ARGSUSED */ 263da14cebeSEric Cheng static dladm_status_t 2644ac67f02SAnurag S. Maskey do_get_maxbw(dladm_handle_t handle, const char *flow, char **prop_val, 2654ac67f02SAnurag S. Maskey uint_t *val_cnt) 266da14cebeSEric Cheng { 267da14cebeSEric Cheng mac_resource_props_t *mrp; 268da14cebeSEric Cheng char buf[DLADM_STRSIZE]; 269da14cebeSEric Cheng dladm_flow_attr_t fa; 270da14cebeSEric Cheng dladm_status_t status; 271da14cebeSEric Cheng 2724ac67f02SAnurag S. Maskey status = dladm_flow_info(handle, flow, &fa); 273da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 274da14cebeSEric Cheng return (status); 275da14cebeSEric Cheng mrp = &(fa.fa_resource_props); 276da14cebeSEric Cheng 277da14cebeSEric Cheng *val_cnt = 1; 278da14cebeSEric Cheng if (mrp->mrp_mask & MRP_MAXBW) { 279da14cebeSEric Cheng (void) snprintf(prop_val[0], DLADM_STRSIZE, "%s", 280da14cebeSEric Cheng dladm_bw2str(mrp->mrp_maxbw, buf)); 281da14cebeSEric Cheng } else { 282da14cebeSEric Cheng return (DLADM_STATUS_NOTSUP); 283da14cebeSEric Cheng } 284da14cebeSEric Cheng return (DLADM_STATUS_OK); 285da14cebeSEric Cheng } 286da14cebeSEric Cheng 287da14cebeSEric Cheng /* ARGSUSED */ 288da14cebeSEric Cheng static dladm_status_t 2894ac67f02SAnurag S. Maskey do_set_maxbw(dladm_handle_t handle, const char *flow, val_desc_t *vdp, 2904ac67f02SAnurag S. Maskey uint_t val_cnt) 291da14cebeSEric Cheng { 292da14cebeSEric Cheng dld_ioc_modifyflow_t attr; 293da14cebeSEric Cheng mac_resource_props_t mrp; 294da14cebeSEric Cheng void *val; 295da14cebeSEric Cheng 296da14cebeSEric Cheng if (val_cnt != 1) 297da14cebeSEric Cheng return (DLADM_STATUS_BADVALCNT); 298da14cebeSEric Cheng 299da14cebeSEric Cheng bzero(&mrp, sizeof (mrp)); 300da14cebeSEric Cheng if (vdp != NULL && (val = (void *)vdp->vd_val) != NULL) { 301da14cebeSEric Cheng bcopy(val, &mrp.mrp_maxbw, sizeof (int64_t)); 302da14cebeSEric Cheng free(val); 303da14cebeSEric Cheng } else { 304da14cebeSEric Cheng mrp.mrp_maxbw = MRP_MAXBW_RESETVAL; 305da14cebeSEric Cheng } 306da14cebeSEric Cheng mrp.mrp_mask = MRP_MAXBW; 307da14cebeSEric Cheng 308da14cebeSEric Cheng bzero(&attr, sizeof (attr)); 309da14cebeSEric Cheng (void) strlcpy(attr.mf_name, flow, sizeof (attr.mf_name)); 310da14cebeSEric Cheng bcopy(&mrp, &attr.mf_resource_props, sizeof (mac_resource_props_t)); 311da14cebeSEric Cheng 3124ac67f02SAnurag S. Maskey if (ioctl(dladm_dld_fd(handle), DLDIOC_MODIFYFLOW, &attr) < 0) 313da14cebeSEric Cheng return (dladm_errno2status(errno)); 314da14cebeSEric Cheng 315da14cebeSEric Cheng return (DLADM_STATUS_OK); 316da14cebeSEric Cheng } 317da14cebeSEric Cheng 318da14cebeSEric Cheng /* ARGSUSED */ 319da14cebeSEric Cheng static dladm_status_t 320da14cebeSEric Cheng do_check_maxbw(fprop_desc_t *pdp, char **prop_val, uint_t val_cnt, 321da14cebeSEric Cheng val_desc_t **vdpp) 322da14cebeSEric Cheng { 323da14cebeSEric Cheng uint64_t *maxbw; 324da14cebeSEric Cheng val_desc_t *vdp = NULL; 325da14cebeSEric Cheng dladm_status_t status = DLADM_STATUS_OK; 326da14cebeSEric Cheng 327da14cebeSEric Cheng if (val_cnt != 1) 328da14cebeSEric Cheng return (DLADM_STATUS_BADVALCNT); 329da14cebeSEric Cheng 330da14cebeSEric Cheng maxbw = malloc(sizeof (uint64_t)); 331da14cebeSEric Cheng if (maxbw == NULL) 332da14cebeSEric Cheng return (DLADM_STATUS_NOMEM); 333da14cebeSEric Cheng 334da14cebeSEric Cheng status = dladm_str2bw(*prop_val, maxbw); 335da14cebeSEric Cheng if (status != DLADM_STATUS_OK) { 336da14cebeSEric Cheng free(maxbw); 337da14cebeSEric Cheng return (status); 338da14cebeSEric Cheng } 339da14cebeSEric Cheng 340da14cebeSEric Cheng if ((*maxbw < MRP_MAXBW_MINVAL) && (*maxbw != 0)) { 341da14cebeSEric Cheng free(maxbw); 342da14cebeSEric Cheng return (DLADM_STATUS_MINMAXBW); 343da14cebeSEric Cheng } 344da14cebeSEric Cheng 345da14cebeSEric Cheng vdp = malloc(sizeof (val_desc_t)); 346da14cebeSEric Cheng if (vdp == NULL) { 347da14cebeSEric Cheng free(maxbw); 348da14cebeSEric Cheng return (DLADM_STATUS_NOMEM); 349da14cebeSEric Cheng } 350da14cebeSEric Cheng 351da14cebeSEric Cheng vdp->vd_val = (uintptr_t)maxbw; 352da14cebeSEric Cheng *vdpp = vdp; 353da14cebeSEric Cheng return (DLADM_STATUS_OK); 354da14cebeSEric Cheng } 355da14cebeSEric Cheng 356da14cebeSEric Cheng /* ARGSUSED */ 357da14cebeSEric Cheng static dladm_status_t 3584ac67f02SAnurag S. Maskey do_get_priority(dladm_handle_t handle, const char *flow, char **prop_val, 3594ac67f02SAnurag S. Maskey uint_t *val_cnt) 360da14cebeSEric Cheng { 361da14cebeSEric Cheng mac_resource_props_t *mrp; 362da14cebeSEric Cheng char buf[DLADM_STRSIZE]; 363da14cebeSEric Cheng dladm_flow_attr_t fa; 364da14cebeSEric Cheng dladm_status_t status; 365da14cebeSEric Cheng 366da14cebeSEric Cheng bzero(&fa, sizeof (dladm_flow_attr_t)); 3674ac67f02SAnurag S. Maskey status = dladm_flow_info(handle, flow, &fa); 368da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 369da14cebeSEric Cheng return (status); 370da14cebeSEric Cheng mrp = &(fa.fa_resource_props); 371da14cebeSEric Cheng 372da14cebeSEric Cheng *val_cnt = 1; 373da14cebeSEric Cheng if (mrp->mrp_mask & MRP_PRIORITY) { 374da14cebeSEric Cheng (void) snprintf(prop_val[0], DLADM_STRSIZE, "%s", 375da14cebeSEric Cheng dladm_pri2str(mrp->mrp_priority, buf)); 376da14cebeSEric Cheng } else { 377da14cebeSEric Cheng return (DLADM_STATUS_NOTSUP); 378da14cebeSEric Cheng } 379da14cebeSEric Cheng return (DLADM_STATUS_OK); 380da14cebeSEric Cheng } 381da14cebeSEric Cheng 382da14cebeSEric Cheng /* ARGSUSED */ 383da14cebeSEric Cheng static dladm_status_t 3844ac67f02SAnurag S. Maskey do_set_priority(dladm_handle_t handle, const char *flow, val_desc_t *vdp, 3854ac67f02SAnurag S. Maskey uint_t val_cnt) 386da14cebeSEric Cheng { 387da14cebeSEric Cheng dld_ioc_modifyflow_t attr; 388da14cebeSEric Cheng mac_resource_props_t mrp; 389da14cebeSEric Cheng void *val; 390da14cebeSEric Cheng 391da14cebeSEric Cheng if (val_cnt != 1) 392da14cebeSEric Cheng return (DLADM_STATUS_BADVALCNT); 393da14cebeSEric Cheng 394da14cebeSEric Cheng bzero(&mrp, sizeof (mrp)); 395da14cebeSEric Cheng if (vdp != NULL && (val = (void *)vdp->vd_val) != NULL) { 396da14cebeSEric Cheng bcopy(val, &mrp.mrp_priority, sizeof (mac_priority_level_t)); 397da14cebeSEric Cheng free(val); 398da14cebeSEric Cheng } else { 399da14cebeSEric Cheng mrp.mrp_priority = MPL_RESET; 400da14cebeSEric Cheng } 401da14cebeSEric Cheng mrp.mrp_mask = MRP_PRIORITY; 402da14cebeSEric Cheng 403da14cebeSEric Cheng bzero(&attr, sizeof (attr)); 404da14cebeSEric Cheng (void) strlcpy(attr.mf_name, flow, sizeof (attr.mf_name)); 405da14cebeSEric Cheng bcopy(&mrp, &attr.mf_resource_props, sizeof (mac_resource_props_t)); 406da14cebeSEric Cheng 4074ac67f02SAnurag S. Maskey if (ioctl(dladm_dld_fd(handle), DLDIOC_MODIFYFLOW, &attr) < 0) 408da14cebeSEric Cheng return (dladm_errno2status(errno)); 409da14cebeSEric Cheng 410da14cebeSEric Cheng return (DLADM_STATUS_OK); 411da14cebeSEric Cheng } 412da14cebeSEric Cheng 413da14cebeSEric Cheng /* ARGSUSED */ 414da14cebeSEric Cheng static dladm_status_t 415da14cebeSEric Cheng do_check_priority(fprop_desc_t *pdp, char **prop_val, uint_t val_cnt, 416da14cebeSEric Cheng val_desc_t **vdpp) 417da14cebeSEric Cheng { 418da14cebeSEric Cheng mac_priority_level_t *pri; 419da14cebeSEric Cheng val_desc_t *vdp = NULL; 420da14cebeSEric Cheng dladm_status_t status = DLADM_STATUS_OK; 421da14cebeSEric Cheng 422da14cebeSEric Cheng if (val_cnt != 1) 423da14cebeSEric Cheng return (DLADM_STATUS_BADVALCNT); 424da14cebeSEric Cheng 425da14cebeSEric Cheng pri = malloc(sizeof (mac_priority_level_t)); 426da14cebeSEric Cheng if (pri == NULL) 427da14cebeSEric Cheng return (DLADM_STATUS_NOMEM); 428da14cebeSEric Cheng 429da14cebeSEric Cheng status = dladm_str2pri(*prop_val, pri); 430da14cebeSEric Cheng if (status != DLADM_STATUS_OK) { 431da14cebeSEric Cheng free(pri); 432da14cebeSEric Cheng return (status); 433da14cebeSEric Cheng } 434da14cebeSEric Cheng 435da14cebeSEric Cheng if (*pri == -1) { 436da14cebeSEric Cheng free(pri); 437da14cebeSEric Cheng return (DLADM_STATUS_BADVAL); 438da14cebeSEric Cheng } 439da14cebeSEric Cheng 440da14cebeSEric Cheng vdp = malloc(sizeof (val_desc_t)); 441da14cebeSEric Cheng if (vdp == NULL) { 442da14cebeSEric Cheng free(pri); 443da14cebeSEric Cheng return (DLADM_STATUS_NOMEM); 444da14cebeSEric Cheng } 445da14cebeSEric Cheng 446da14cebeSEric Cheng vdp->vd_val = (uintptr_t)pri; 447da14cebeSEric Cheng *vdpp = vdp; 448da14cebeSEric Cheng return (DLADM_STATUS_OK); 449da14cebeSEric Cheng } 450da14cebeSEric Cheng 451da14cebeSEric Cheng static dladm_status_t 452da14cebeSEric Cheng flow_proplist_check(dladm_arg_list_t *proplist) 453da14cebeSEric Cheng { 454da14cebeSEric Cheng int i, j; 455da14cebeSEric Cheng boolean_t matched; 456da14cebeSEric Cheng 457da14cebeSEric Cheng for (i = 0; i < proplist->al_count; i++) { 458da14cebeSEric Cheng matched = B_FALSE; 459da14cebeSEric Cheng for (j = 0; j < DLADM_MAX_FLOWPROPS; j++) { 460da14cebeSEric Cheng if (strcmp(proplist->al_info[i].ai_name, 461da14cebeSEric Cheng prop_table[j].pd_name) == 0) 462da14cebeSEric Cheng matched = B_TRUE; 463da14cebeSEric Cheng } 464da14cebeSEric Cheng if (!matched) 465da14cebeSEric Cheng return (DLADM_STATUS_BADPROP); 466da14cebeSEric Cheng } 467da14cebeSEric Cheng return (DLADM_STATUS_OK); 468da14cebeSEric Cheng 469da14cebeSEric Cheng } 470da14cebeSEric Cheng 471da14cebeSEric Cheng dladm_status_t 472da14cebeSEric Cheng dladm_parse_flow_props(char *str, dladm_arg_list_t **listp, boolean_t novalues) 473da14cebeSEric Cheng { 474da14cebeSEric Cheng dladm_status_t status; 475da14cebeSEric Cheng 476da14cebeSEric Cheng status = dladm_parse_args(str, listp, novalues); 477da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 478da14cebeSEric Cheng return (status); 479da14cebeSEric Cheng 480*63a6526dSMichael Lim if (*listp != NULL && (status = flow_proplist_check(*listp) 481*63a6526dSMichael Lim != DLADM_STATUS_OK)) { 482da14cebeSEric Cheng dladm_free_props(*listp); 483da14cebeSEric Cheng return (status); 484da14cebeSEric Cheng } 485da14cebeSEric Cheng 486da14cebeSEric Cheng return (DLADM_STATUS_OK); 487da14cebeSEric Cheng } 488da14cebeSEric Cheng 489da14cebeSEric Cheng /* 490da14cebeSEric Cheng * Retrieve the named property from a proplist, check the value and 491da14cebeSEric Cheng * convert to a kernel structure. 492da14cebeSEric Cheng */ 493da14cebeSEric Cheng static dladm_status_t 494da14cebeSEric Cheng i_dladm_flow_proplist_extract_one(dladm_arg_list_t *proplist, 495da14cebeSEric Cheng const char *name, void *val) 496da14cebeSEric Cheng { 497da14cebeSEric Cheng dladm_status_t status; 498da14cebeSEric Cheng dladm_arg_info_t *aip = NULL; 499da14cebeSEric Cheng int i, j; 500da14cebeSEric Cheng 501da14cebeSEric Cheng /* Find named property in proplist */ 502da14cebeSEric Cheng for (i = 0; i < proplist->al_count; i++) { 503da14cebeSEric Cheng aip = &proplist->al_info[i]; 504da14cebeSEric Cheng if (strcasecmp(aip->ai_name, name) == 0) 505da14cebeSEric Cheng break; 506da14cebeSEric Cheng } 507da14cebeSEric Cheng 508da14cebeSEric Cheng /* Property not in list */ 509da14cebeSEric Cheng if (i == proplist->al_count) 510da14cebeSEric Cheng return (DLADM_STATUS_OK); 511da14cebeSEric Cheng 512da14cebeSEric Cheng for (i = 0; i < DLADM_MAX_FLOWPROPS; i++) { 513da14cebeSEric Cheng fprop_desc_t *pdp = &prop_table[i]; 514da14cebeSEric Cheng val_desc_t *vdp; 515da14cebeSEric Cheng 516da14cebeSEric Cheng vdp = malloc(sizeof (val_desc_t) * aip->ai_count); 517da14cebeSEric Cheng if (vdp == NULL) 518da14cebeSEric Cheng return (DLADM_STATUS_NOMEM); 519da14cebeSEric Cheng 520da14cebeSEric Cheng if (strcasecmp(aip->ai_name, pdp->pd_name) != 0) 521da14cebeSEric Cheng continue; 522da14cebeSEric Cheng 523da14cebeSEric Cheng if (aip->ai_val == NULL) 524da14cebeSEric Cheng return (DLADM_STATUS_BADARG); 525da14cebeSEric Cheng 526da14cebeSEric Cheng /* Check property value */ 527da14cebeSEric Cheng if (pdp->pd_check != NULL) { 528da14cebeSEric Cheng status = pdp->pd_check(pdp, aip->ai_val, 529da14cebeSEric Cheng aip->ai_count, &vdp); 530da14cebeSEric Cheng } else { 531da14cebeSEric Cheng status = DLADM_STATUS_BADARG; 532da14cebeSEric Cheng } 533da14cebeSEric Cheng 534da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 535da14cebeSEric Cheng return (status); 536da14cebeSEric Cheng 537da14cebeSEric Cheng for (j = 0; j < DLADM_MAX_RSRC_PROP; j++) { 538da14cebeSEric Cheng resource_prop_t *rpp = &rsrc_prop_table[j]; 539da14cebeSEric Cheng 540da14cebeSEric Cheng if (strcasecmp(aip->ai_name, rpp->rp_name) != 0) 541da14cebeSEric Cheng continue; 542da14cebeSEric Cheng 543da14cebeSEric Cheng /* Extract kernel structure */ 544da14cebeSEric Cheng if (rpp->rp_extract != NULL) { 545da14cebeSEric Cheng status = rpp->rp_extract(vdp, val, 546da14cebeSEric Cheng aip->ai_count); 547da14cebeSEric Cheng } else { 548da14cebeSEric Cheng status = DLADM_STATUS_BADARG; 549da14cebeSEric Cheng } 550da14cebeSEric Cheng break; 551da14cebeSEric Cheng } 552da14cebeSEric Cheng 553da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 554da14cebeSEric Cheng return (status); 555da14cebeSEric Cheng 556da14cebeSEric Cheng break; 557da14cebeSEric Cheng } 558da14cebeSEric Cheng return (status); 559da14cebeSEric Cheng } 560da14cebeSEric Cheng 561da14cebeSEric Cheng /* 562da14cebeSEric Cheng * Extract properties from a proplist and convert to mac_resource_props_t. 563da14cebeSEric Cheng */ 564da14cebeSEric Cheng dladm_status_t 565da14cebeSEric Cheng dladm_flow_proplist_extract(dladm_arg_list_t *proplist, 566da14cebeSEric Cheng mac_resource_props_t *mrp) 567da14cebeSEric Cheng { 568da14cebeSEric Cheng dladm_status_t status = DLADM_STATUS_OK; 569da14cebeSEric Cheng 570da14cebeSEric Cheng status = i_dladm_flow_proplist_extract_one(proplist, "maxbw", mrp); 571da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 572da14cebeSEric Cheng return (status); 573da14cebeSEric Cheng status = i_dladm_flow_proplist_extract_one(proplist, "priority", mrp); 574da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 575da14cebeSEric Cheng return (status); 576da14cebeSEric Cheng return (status); 577da14cebeSEric Cheng } 578da14cebeSEric Cheng 579da14cebeSEric Cheng dladm_status_t 5804ac67f02SAnurag S. Maskey i_dladm_set_flow_proplist_db(dladm_handle_t handle, char *flow, 5814ac67f02SAnurag S. Maskey dladm_arg_list_t *proplist) 582da14cebeSEric Cheng { 583da14cebeSEric Cheng dladm_status_t status, ssave = DLADM_STATUS_OK; 584da14cebeSEric Cheng dladm_arg_info_t ai; 585da14cebeSEric Cheng int i; 586da14cebeSEric Cheng 587da14cebeSEric Cheng for (i = 0; i < proplist->al_count; i++) { 588da14cebeSEric Cheng ai = proplist->al_info[i]; 5894ac67f02SAnurag S. Maskey status = i_dladm_set_flowprop_db(handle, flow, ai.ai_name, 590da14cebeSEric Cheng ai.ai_val, ai.ai_count); 591da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 592da14cebeSEric Cheng ssave = status; 593da14cebeSEric Cheng } 594da14cebeSEric Cheng return (ssave); 595da14cebeSEric Cheng } 596