1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* 27 * Flows ioctls implementation. 28 */ 29 30 #include <sys/dld.h> 31 #include <sys/mac_provider.h> 32 #include <sys/mac_client.h> 33 #include <sys/mac_client_priv.h> 34 35 /* 36 * Implements flow add, remove, modify ioctls. 37 */ 38 int 39 dld_add_flow(datalink_id_t linkid, char *flow_name, flow_desc_t *flow_desc, 40 mac_resource_props_t *mrp) 41 { 42 return (mac_link_flow_add(linkid, flow_name, flow_desc, mrp)); 43 } 44 45 int 46 dld_remove_flow(char *flow_name) 47 { 48 return (mac_link_flow_remove(flow_name)); 49 } 50 51 int 52 dld_modify_flow(char *flow_name, mac_resource_props_t *mrp) 53 { 54 return (mac_link_flow_modify(flow_name, mrp)); 55 } 56 57 58 /* 59 * Callback function and structure used by dld_walk_flow(). 60 */ 61 typedef struct flowinfo_state_s { 62 int fi_bufsize; 63 int fi_nflows; 64 uchar_t *fi_fl; 65 } flowinfo_state_t; 66 67 static int 68 dld_walk_flow_cb(mac_flowinfo_t *finfo, void *arg) 69 { 70 flowinfo_state_t *statep = arg; 71 dld_flowinfo_t fi; 72 73 if (statep->fi_bufsize < sizeof (dld_flowinfo_t)) 74 return (ENOSPC); 75 76 (void) strlcpy(fi.fi_flowname, finfo->fi_flow_name, 77 sizeof (fi.fi_flowname)); 78 fi.fi_linkid = finfo->fi_link_id; 79 fi.fi_flow_desc = finfo->fi_flow_desc; 80 fi.fi_resource_props = finfo->fi_resource_props; 81 82 if (copyout(&fi, statep->fi_fl, sizeof (fi)) != 0) { 83 return (EFAULT); 84 } 85 statep->fi_nflows++; 86 statep->fi_bufsize -= sizeof (dld_flowinfo_t); 87 statep->fi_fl += sizeof (dld_flowinfo_t); 88 return (0); 89 } 90 91 /* 92 * Implements flow walk ioctl. 93 * Retrieves a specific flow or a list of flows from the specified link. 94 * ENOSPC is returned a bigger buffer is needed. 95 */ 96 int 97 dld_walk_flow(dld_ioc_walkflow_t *wf, intptr_t uaddr) 98 { 99 flowinfo_state_t state; 100 mac_flowinfo_t finfo; 101 int err = 0; 102 103 state.fi_bufsize = wf->wf_len; 104 state.fi_fl = (uchar_t *)uaddr + sizeof (*wf); 105 state.fi_nflows = 0; 106 107 if (wf->wf_name[0] == '\0') { 108 err = mac_link_flow_walk(wf->wf_linkid, dld_walk_flow_cb, 109 &state); 110 } else { 111 err = mac_link_flow_info(wf->wf_name, &finfo); 112 if (err != 0) 113 return (err); 114 115 err = dld_walk_flow_cb(&finfo, &state); 116 } 117 wf->wf_nflows = state.fi_nflows; 118 return (err); 119 } 120