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 /*
220dc2366fSVenugopal 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[] = {
64c0e21d6aSToomas Soome { "maxbw", { "", 0 }, NULL, 0, B_FALSE,
65da14cebeSEric Cheng do_set_maxbw, NULL,
66da14cebeSEric Cheng do_get_maxbw, do_check_maxbw},
670dc2366fSVenugopal 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[] = {
800dc2366fSVenugopal Iyer {"maxbw", extract_maxbw},
810dc2366fSVenugopal 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
dladm_set_flowprop(dladm_handle_t handle,const char * flow,const char * prop_name,char ** prop_val,uint_t val_cnt,uint_t flags,char ** errprop)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
dladm_walk_flowprop(int (* func)(void *,const char *),const char * flow,void * arg)119da14cebeSEric Cheng dladm_walk_flowprop(int (*func)(void *, const char *), const char *flow,
120da14cebeSEric Cheng void *arg)
121da14cebeSEric Cheng {
122*4202e8bfSToomas Soome uint_t 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
dladm_get_flowprop(dladm_handle_t handle,const char * flow,uint32_t type,const char * prop_name,char ** prop_val,uint_t * val_cntp)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
i_dladm_set_flowprop_db(dladm_handle_t handle,const char * flow,const char * prop_name,char ** prop_val,uint_t val_cnt)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
i_dladm_get_flowprop_db(dladm_handle_t handle,const char * flow,const char * prop_name,char ** prop_val,uint_t * val_cntp)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
i_dladm_init_flowprop_db(dladm_handle_t handle)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
dladm_flow_info(dladm_handle_t handle,const char * flow,dladm_flow_attr_t * attr)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
do_get_maxbw(dladm_handle_t handle,const char * flow,char ** prop_val,uint_t * val_cnt)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;
269c0e21d6aSToomas Soome 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
do_set_maxbw(dladm_handle_t handle,const char * flow,val_desc_t * vdp,uint_t val_cnt)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 static dladm_status_t
do_check_maxbw(fprop_desc_t * pdp __unused,char ** prop_val,uint_t val_cnt,val_desc_t ** vdpp)32020535e13SToomas Soome do_check_maxbw(fprop_desc_t *pdp __unused, 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
do_get_priority(dladm_handle_t handle,const char * flow,char ** prop_val,uint_t * val_cnt)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;
362c0e21d6aSToomas Soome 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
do_set_priority(dladm_handle_t handle,const char * flow,val_desc_t * vdp,uint_t val_cnt)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
390da14cebeSEric Cheng if (val_cnt != 1)
391da14cebeSEric Cheng return (DLADM_STATUS_BADVALCNT);
392da14cebeSEric Cheng
393da14cebeSEric Cheng bzero(&mrp, sizeof (mrp));
3940dc2366fSVenugopal Iyer if (vdp != NULL) {
3950dc2366fSVenugopal Iyer bcopy(&vdp->vd_val, &mrp.mrp_priority,
3960dc2366fSVenugopal Iyer sizeof (mac_priority_level_t));
397da14cebeSEric Cheng } else {
398da14cebeSEric Cheng mrp.mrp_priority = MPL_RESET;
399da14cebeSEric Cheng }
400da14cebeSEric Cheng mrp.mrp_mask = MRP_PRIORITY;
401da14cebeSEric Cheng
402da14cebeSEric Cheng bzero(&attr, sizeof (attr));
403da14cebeSEric Cheng (void) strlcpy(attr.mf_name, flow, sizeof (attr.mf_name));
404da14cebeSEric Cheng bcopy(&mrp, &attr.mf_resource_props, sizeof (mac_resource_props_t));
405da14cebeSEric Cheng
4064ac67f02SAnurag S. Maskey if (ioctl(dladm_dld_fd(handle), DLDIOC_MODIFYFLOW, &attr) < 0)
407da14cebeSEric Cheng return (dladm_errno2status(errno));
408da14cebeSEric Cheng
409da14cebeSEric Cheng return (DLADM_STATUS_OK);
410da14cebeSEric Cheng }
411da14cebeSEric Cheng
412da14cebeSEric Cheng static dladm_status_t
do_check_priority(fprop_desc_t * pdp __unused,char ** prop_val,uint_t val_cnt,val_desc_t ** vdpp)41320535e13SToomas Soome do_check_priority(fprop_desc_t *pdp __unused, char **prop_val, uint_t val_cnt,
414da14cebeSEric Cheng val_desc_t **vdpp)
415da14cebeSEric Cheng {
4160dc2366fSVenugopal Iyer mac_priority_level_t pri;
417da14cebeSEric Cheng val_desc_t *vdp = NULL;
418da14cebeSEric Cheng dladm_status_t status = DLADM_STATUS_OK;
419da14cebeSEric Cheng
420da14cebeSEric Cheng if (val_cnt != 1)
421da14cebeSEric Cheng return (DLADM_STATUS_BADVALCNT);
422da14cebeSEric Cheng
4230dc2366fSVenugopal Iyer status = dladm_str2pri(*prop_val, &pri);
4240dc2366fSVenugopal Iyer if (status != DLADM_STATUS_OK)
425da14cebeSEric Cheng return (status);
426da14cebeSEric Cheng
427da14cebeSEric Cheng vdp = malloc(sizeof (val_desc_t));
4280dc2366fSVenugopal Iyer if (vdp == NULL)
429da14cebeSEric Cheng return (DLADM_STATUS_NOMEM);
430da14cebeSEric Cheng
4310dc2366fSVenugopal Iyer vdp->vd_val = (uint_t)pri;
432da14cebeSEric Cheng *vdpp = vdp;
433da14cebeSEric Cheng return (DLADM_STATUS_OK);
434da14cebeSEric Cheng }
435da14cebeSEric Cheng
436da14cebeSEric Cheng static dladm_status_t
flow_proplist_check(dladm_arg_list_t * proplist)437da14cebeSEric Cheng flow_proplist_check(dladm_arg_list_t *proplist)
438da14cebeSEric Cheng {
439*4202e8bfSToomas Soome uint_t i, j;
440da14cebeSEric Cheng boolean_t matched;
441da14cebeSEric Cheng
442da14cebeSEric Cheng for (i = 0; i < proplist->al_count; i++) {
443da14cebeSEric Cheng matched = B_FALSE;
444da14cebeSEric Cheng for (j = 0; j < DLADM_MAX_FLOWPROPS; j++) {
445da14cebeSEric Cheng if (strcmp(proplist->al_info[i].ai_name,
446da14cebeSEric Cheng prop_table[j].pd_name) == 0)
447da14cebeSEric Cheng matched = B_TRUE;
448da14cebeSEric Cheng }
449da14cebeSEric Cheng if (!matched)
450da14cebeSEric Cheng return (DLADM_STATUS_BADPROP);
451da14cebeSEric Cheng }
452da14cebeSEric Cheng return (DLADM_STATUS_OK);
453da14cebeSEric Cheng
454da14cebeSEric Cheng }
455da14cebeSEric Cheng
456da14cebeSEric Cheng dladm_status_t
dladm_parse_flow_props(char * str,dladm_arg_list_t ** listp,boolean_t novalues)457da14cebeSEric Cheng dladm_parse_flow_props(char *str, dladm_arg_list_t **listp, boolean_t novalues)
458da14cebeSEric Cheng {
459da14cebeSEric Cheng dladm_status_t status;
460da14cebeSEric Cheng
461da14cebeSEric Cheng status = dladm_parse_args(str, listp, novalues);
462da14cebeSEric Cheng if (status != DLADM_STATUS_OK)
463da14cebeSEric Cheng return (status);
464da14cebeSEric Cheng
46563a6526dSMichael Lim if (*listp != NULL && (status = flow_proplist_check(*listp)
46663a6526dSMichael Lim != DLADM_STATUS_OK)) {
467da14cebeSEric Cheng dladm_free_props(*listp);
468da14cebeSEric Cheng return (status);
469da14cebeSEric Cheng }
470da14cebeSEric Cheng
471da14cebeSEric Cheng return (DLADM_STATUS_OK);
472da14cebeSEric Cheng }
473da14cebeSEric Cheng
474da14cebeSEric Cheng /*
475da14cebeSEric Cheng * Retrieve the named property from a proplist, check the value and
476da14cebeSEric Cheng * convert to a kernel structure.
477da14cebeSEric Cheng */
478da14cebeSEric Cheng static dladm_status_t
i_dladm_flow_proplist_extract_one(dladm_arg_list_t * proplist,const char * name,void * arg)479da14cebeSEric Cheng i_dladm_flow_proplist_extract_one(dladm_arg_list_t *proplist,
48025ec3e3dSEric Cheng const char *name, void *arg)
481da14cebeSEric Cheng {
482f7952617SToomas Soome dladm_status_t status = DLADM_STATUS_OK;
483da14cebeSEric Cheng dladm_arg_info_t *aip = NULL;
484*4202e8bfSToomas Soome uint_t i, j;
485da14cebeSEric Cheng
486da14cebeSEric Cheng /* Find named property in proplist */
487da14cebeSEric Cheng for (i = 0; i < proplist->al_count; i++) {
488da14cebeSEric Cheng aip = &proplist->al_info[i];
489da14cebeSEric Cheng if (strcasecmp(aip->ai_name, name) == 0)
490da14cebeSEric Cheng break;
491da14cebeSEric Cheng }
492da14cebeSEric Cheng
493da14cebeSEric Cheng /* Property not in list */
494da14cebeSEric Cheng if (i == proplist->al_count)
495da14cebeSEric Cheng return (DLADM_STATUS_OK);
496da14cebeSEric Cheng
49750e95a06SToomas Soome if (aip->ai_val[0] == NULL)
49850e95a06SToomas Soome return (DLADM_STATUS_BADARG);
49950e95a06SToomas Soome
500da14cebeSEric Cheng for (i = 0; i < DLADM_MAX_FLOWPROPS; i++) {
501da14cebeSEric Cheng fprop_desc_t *pdp = &prop_table[i];
502da14cebeSEric Cheng val_desc_t *vdp;
503da14cebeSEric Cheng
504da14cebeSEric Cheng vdp = malloc(sizeof (val_desc_t) * aip->ai_count);
505da14cebeSEric Cheng if (vdp == NULL)
506da14cebeSEric Cheng return (DLADM_STATUS_NOMEM);
507da14cebeSEric Cheng
508da14cebeSEric Cheng if (strcasecmp(aip->ai_name, pdp->pd_name) != 0)
509da14cebeSEric Cheng continue;
510da14cebeSEric Cheng
511da14cebeSEric Cheng /* Check property value */
512da14cebeSEric Cheng if (pdp->pd_check != NULL) {
513da14cebeSEric Cheng status = pdp->pd_check(pdp, aip->ai_val,
514da14cebeSEric Cheng aip->ai_count, &vdp);
515da14cebeSEric Cheng } else {
516da14cebeSEric Cheng status = DLADM_STATUS_BADARG;
517da14cebeSEric Cheng }
518da14cebeSEric Cheng
519da14cebeSEric Cheng if (status != DLADM_STATUS_OK)
520da14cebeSEric Cheng return (status);
521da14cebeSEric Cheng
522da14cebeSEric Cheng for (j = 0; j < DLADM_MAX_RSRC_PROP; j++) {
523da14cebeSEric Cheng resource_prop_t *rpp = &rsrc_prop_table[j];
524da14cebeSEric Cheng
525da14cebeSEric Cheng if (strcasecmp(aip->ai_name, rpp->rp_name) != 0)
526da14cebeSEric Cheng continue;
527da14cebeSEric Cheng
528da14cebeSEric Cheng /* Extract kernel structure */
529da14cebeSEric Cheng if (rpp->rp_extract != NULL) {
53025ec3e3dSEric Cheng status = rpp->rp_extract(vdp,
53125ec3e3dSEric Cheng aip->ai_count, arg);
532da14cebeSEric Cheng } else {
533da14cebeSEric Cheng status = DLADM_STATUS_BADARG;
534da14cebeSEric Cheng }
535da14cebeSEric Cheng break;
536da14cebeSEric Cheng }
537da14cebeSEric Cheng
538da14cebeSEric Cheng if (status != DLADM_STATUS_OK)
539da14cebeSEric Cheng return (status);
540da14cebeSEric Cheng
541da14cebeSEric Cheng break;
542da14cebeSEric Cheng }
543da14cebeSEric Cheng return (status);
544da14cebeSEric Cheng }
545da14cebeSEric Cheng
546da14cebeSEric Cheng /*
547da14cebeSEric Cheng * Extract properties from a proplist and convert to mac_resource_props_t.
548da14cebeSEric Cheng */
549da14cebeSEric Cheng dladm_status_t
dladm_flow_proplist_extract(dladm_arg_list_t * proplist,mac_resource_props_t * mrp)550da14cebeSEric Cheng dladm_flow_proplist_extract(dladm_arg_list_t *proplist,
551da14cebeSEric Cheng mac_resource_props_t *mrp)
552da14cebeSEric Cheng {
553da14cebeSEric Cheng dladm_status_t status = DLADM_STATUS_OK;
554da14cebeSEric Cheng
555da14cebeSEric Cheng status = i_dladm_flow_proplist_extract_one(proplist, "maxbw", mrp);
556da14cebeSEric Cheng if (status != DLADM_STATUS_OK)
557da14cebeSEric Cheng return (status);
558da14cebeSEric Cheng status = i_dladm_flow_proplist_extract_one(proplist, "priority", mrp);
559da14cebeSEric Cheng if (status != DLADM_STATUS_OK)
560da14cebeSEric Cheng return (status);
561da14cebeSEric Cheng return (status);
562da14cebeSEric Cheng }
563da14cebeSEric Cheng
564da14cebeSEric Cheng dladm_status_t
i_dladm_set_flow_proplist_db(dladm_handle_t handle,char * flow,dladm_arg_list_t * proplist)5654ac67f02SAnurag S. Maskey i_dladm_set_flow_proplist_db(dladm_handle_t handle, char *flow,
5664ac67f02SAnurag S. Maskey dladm_arg_list_t *proplist)
567da14cebeSEric Cheng {
568da14cebeSEric Cheng dladm_status_t status, ssave = DLADM_STATUS_OK;
569da14cebeSEric Cheng dladm_arg_info_t ai;
570*4202e8bfSToomas Soome uint_t i;
571da14cebeSEric Cheng
572da14cebeSEric Cheng for (i = 0; i < proplist->al_count; i++) {
573da14cebeSEric Cheng ai = proplist->al_info[i];
5744ac67f02SAnurag S. Maskey status = i_dladm_set_flowprop_db(handle, flow, ai.ai_name,
575da14cebeSEric Cheng ai.ai_val, ai.ai_count);
576da14cebeSEric Cheng if (status != DLADM_STATUS_OK)
577da14cebeSEric Cheng ssave = status;
578da14cebeSEric Cheng }
579da14cebeSEric Cheng return (ssave);
580da14cebeSEric Cheng }
581