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 /* 22*0dc2366fSVenugopal Iyer * Copyright 2010 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}, 67*0dc2366fSVenugopal Iyer { "priority", { "", MPL_RESET }, 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[] = { 80*0dc2366fSVenugopal Iyer {"maxbw", extract_maxbw}, 81*0dc2366fSVenugopal Iyer {"priority", 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 391da14cebeSEric Cheng if (val_cnt != 1) 392da14cebeSEric Cheng return (DLADM_STATUS_BADVALCNT); 393da14cebeSEric Cheng 394da14cebeSEric Cheng bzero(&mrp, sizeof (mrp)); 395*0dc2366fSVenugopal Iyer if (vdp != NULL) { 396*0dc2366fSVenugopal Iyer bcopy(&vdp->vd_val, &mrp.mrp_priority, 397*0dc2366fSVenugopal Iyer sizeof (mac_priority_level_t)); 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 { 418*0dc2366fSVenugopal Iyer 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 425*0dc2366fSVenugopal Iyer status = dladm_str2pri(*prop_val, &pri); 426*0dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK) 427da14cebeSEric Cheng return (status); 428da14cebeSEric Cheng 429*0dc2366fSVenugopal Iyer if (pri == -1) 430da14cebeSEric Cheng return (DLADM_STATUS_BADVAL); 431da14cebeSEric Cheng 432da14cebeSEric Cheng vdp = malloc(sizeof (val_desc_t)); 433*0dc2366fSVenugopal Iyer if (vdp == NULL) 434da14cebeSEric Cheng return (DLADM_STATUS_NOMEM); 435da14cebeSEric Cheng 436*0dc2366fSVenugopal Iyer vdp->vd_val = (uint_t)pri; 437da14cebeSEric Cheng *vdpp = vdp; 438da14cebeSEric Cheng return (DLADM_STATUS_OK); 439da14cebeSEric Cheng } 440da14cebeSEric Cheng 441da14cebeSEric Cheng static dladm_status_t 442da14cebeSEric Cheng flow_proplist_check(dladm_arg_list_t *proplist) 443da14cebeSEric Cheng { 444da14cebeSEric Cheng int i, j; 445da14cebeSEric Cheng boolean_t matched; 446da14cebeSEric Cheng 447da14cebeSEric Cheng for (i = 0; i < proplist->al_count; i++) { 448da14cebeSEric Cheng matched = B_FALSE; 449da14cebeSEric Cheng for (j = 0; j < DLADM_MAX_FLOWPROPS; j++) { 450da14cebeSEric Cheng if (strcmp(proplist->al_info[i].ai_name, 451da14cebeSEric Cheng prop_table[j].pd_name) == 0) 452da14cebeSEric Cheng matched = B_TRUE; 453da14cebeSEric Cheng } 454da14cebeSEric Cheng if (!matched) 455da14cebeSEric Cheng return (DLADM_STATUS_BADPROP); 456da14cebeSEric Cheng } 457da14cebeSEric Cheng return (DLADM_STATUS_OK); 458da14cebeSEric Cheng 459da14cebeSEric Cheng } 460da14cebeSEric Cheng 461da14cebeSEric Cheng dladm_status_t 462da14cebeSEric Cheng dladm_parse_flow_props(char *str, dladm_arg_list_t **listp, boolean_t novalues) 463da14cebeSEric Cheng { 464da14cebeSEric Cheng dladm_status_t status; 465da14cebeSEric Cheng 466da14cebeSEric Cheng status = dladm_parse_args(str, listp, novalues); 467da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 468da14cebeSEric Cheng return (status); 469da14cebeSEric Cheng 47063a6526dSMichael Lim if (*listp != NULL && (status = flow_proplist_check(*listp) 47163a6526dSMichael Lim != DLADM_STATUS_OK)) { 472da14cebeSEric Cheng dladm_free_props(*listp); 473da14cebeSEric Cheng return (status); 474da14cebeSEric Cheng } 475da14cebeSEric Cheng 476da14cebeSEric Cheng return (DLADM_STATUS_OK); 477da14cebeSEric Cheng } 478da14cebeSEric Cheng 479da14cebeSEric Cheng /* 480da14cebeSEric Cheng * Retrieve the named property from a proplist, check the value and 481da14cebeSEric Cheng * convert to a kernel structure. 482da14cebeSEric Cheng */ 483da14cebeSEric Cheng static dladm_status_t 484da14cebeSEric Cheng i_dladm_flow_proplist_extract_one(dladm_arg_list_t *proplist, 48525ec3e3dSEric Cheng const char *name, void *arg) 486da14cebeSEric Cheng { 487da14cebeSEric Cheng dladm_status_t status; 488da14cebeSEric Cheng dladm_arg_info_t *aip = NULL; 489da14cebeSEric Cheng int i, j; 490da14cebeSEric Cheng 491da14cebeSEric Cheng /* Find named property in proplist */ 492da14cebeSEric Cheng for (i = 0; i < proplist->al_count; i++) { 493da14cebeSEric Cheng aip = &proplist->al_info[i]; 494da14cebeSEric Cheng if (strcasecmp(aip->ai_name, name) == 0) 495da14cebeSEric Cheng break; 496da14cebeSEric Cheng } 497da14cebeSEric Cheng 498da14cebeSEric Cheng /* Property not in list */ 499da14cebeSEric Cheng if (i == proplist->al_count) 500da14cebeSEric Cheng return (DLADM_STATUS_OK); 501da14cebeSEric Cheng 502da14cebeSEric Cheng for (i = 0; i < DLADM_MAX_FLOWPROPS; i++) { 503da14cebeSEric Cheng fprop_desc_t *pdp = &prop_table[i]; 504da14cebeSEric Cheng val_desc_t *vdp; 505da14cebeSEric Cheng 506da14cebeSEric Cheng vdp = malloc(sizeof (val_desc_t) * aip->ai_count); 507da14cebeSEric Cheng if (vdp == NULL) 508da14cebeSEric Cheng return (DLADM_STATUS_NOMEM); 509da14cebeSEric Cheng 510da14cebeSEric Cheng if (strcasecmp(aip->ai_name, pdp->pd_name) != 0) 511da14cebeSEric Cheng continue; 512da14cebeSEric Cheng 513da14cebeSEric Cheng if (aip->ai_val == NULL) 514da14cebeSEric Cheng return (DLADM_STATUS_BADARG); 515da14cebeSEric Cheng 516da14cebeSEric Cheng /* Check property value */ 517da14cebeSEric Cheng if (pdp->pd_check != NULL) { 518da14cebeSEric Cheng status = pdp->pd_check(pdp, aip->ai_val, 519da14cebeSEric Cheng aip->ai_count, &vdp); 520da14cebeSEric Cheng } else { 521da14cebeSEric Cheng status = DLADM_STATUS_BADARG; 522da14cebeSEric Cheng } 523da14cebeSEric Cheng 524da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 525da14cebeSEric Cheng return (status); 526da14cebeSEric Cheng 527da14cebeSEric Cheng for (j = 0; j < DLADM_MAX_RSRC_PROP; j++) { 528da14cebeSEric Cheng resource_prop_t *rpp = &rsrc_prop_table[j]; 529da14cebeSEric Cheng 530da14cebeSEric Cheng if (strcasecmp(aip->ai_name, rpp->rp_name) != 0) 531da14cebeSEric Cheng continue; 532da14cebeSEric Cheng 533da14cebeSEric Cheng /* Extract kernel structure */ 534da14cebeSEric Cheng if (rpp->rp_extract != NULL) { 53525ec3e3dSEric Cheng status = rpp->rp_extract(vdp, 53625ec3e3dSEric Cheng aip->ai_count, arg); 537da14cebeSEric Cheng } else { 538da14cebeSEric Cheng status = DLADM_STATUS_BADARG; 539da14cebeSEric Cheng } 540da14cebeSEric Cheng break; 541da14cebeSEric Cheng } 542da14cebeSEric Cheng 543da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 544da14cebeSEric Cheng return (status); 545da14cebeSEric Cheng 546da14cebeSEric Cheng break; 547da14cebeSEric Cheng } 548da14cebeSEric Cheng return (status); 549da14cebeSEric Cheng } 550da14cebeSEric Cheng 551da14cebeSEric Cheng /* 552da14cebeSEric Cheng * Extract properties from a proplist and convert to mac_resource_props_t. 553da14cebeSEric Cheng */ 554da14cebeSEric Cheng dladm_status_t 555da14cebeSEric Cheng dladm_flow_proplist_extract(dladm_arg_list_t *proplist, 556da14cebeSEric Cheng mac_resource_props_t *mrp) 557da14cebeSEric Cheng { 558da14cebeSEric Cheng dladm_status_t status = DLADM_STATUS_OK; 559da14cebeSEric Cheng 560da14cebeSEric Cheng status = i_dladm_flow_proplist_extract_one(proplist, "maxbw", mrp); 561da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 562da14cebeSEric Cheng return (status); 563da14cebeSEric Cheng status = i_dladm_flow_proplist_extract_one(proplist, "priority", mrp); 564da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 565da14cebeSEric Cheng return (status); 566da14cebeSEric Cheng return (status); 567da14cebeSEric Cheng } 568da14cebeSEric Cheng 569da14cebeSEric Cheng dladm_status_t 5704ac67f02SAnurag S. Maskey i_dladm_set_flow_proplist_db(dladm_handle_t handle, char *flow, 5714ac67f02SAnurag S. Maskey dladm_arg_list_t *proplist) 572da14cebeSEric Cheng { 573da14cebeSEric Cheng dladm_status_t status, ssave = DLADM_STATUS_OK; 574da14cebeSEric Cheng dladm_arg_info_t ai; 575da14cebeSEric Cheng int i; 576da14cebeSEric Cheng 577da14cebeSEric Cheng for (i = 0; i < proplist->al_count; i++) { 578da14cebeSEric Cheng ai = proplist->al_info[i]; 5794ac67f02SAnurag S. Maskey status = i_dladm_set_flowprop_db(handle, flow, ai.ai_name, 580da14cebeSEric Cheng ai.ai_val, ai.ai_count); 581da14cebeSEric Cheng if (status != DLADM_STATUS_OK) 582da14cebeSEric Cheng ssave = status; 583da14cebeSEric Cheng } 584da14cebeSEric Cheng return (ssave); 585da14cebeSEric Cheng } 586