1*9815SRishi.Srivatsavai@Sun.COM /* 2*9815SRishi.Srivatsavai@Sun.COM * CDDL HEADER START 3*9815SRishi.Srivatsavai@Sun.COM * 4*9815SRishi.Srivatsavai@Sun.COM * The contents of this file are subject to the terms of the 5*9815SRishi.Srivatsavai@Sun.COM * Common Development and Distribution License (the "License"). 6*9815SRishi.Srivatsavai@Sun.COM * You may not use this file except in compliance with the License. 7*9815SRishi.Srivatsavai@Sun.COM * 8*9815SRishi.Srivatsavai@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*9815SRishi.Srivatsavai@Sun.COM * or http://www.opensolaris.org/os/licensing. 10*9815SRishi.Srivatsavai@Sun.COM * See the License for the specific language governing permissions 11*9815SRishi.Srivatsavai@Sun.COM * and limitations under the License. 12*9815SRishi.Srivatsavai@Sun.COM * 13*9815SRishi.Srivatsavai@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 14*9815SRishi.Srivatsavai@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*9815SRishi.Srivatsavai@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 16*9815SRishi.Srivatsavai@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 17*9815SRishi.Srivatsavai@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 18*9815SRishi.Srivatsavai@Sun.COM * 19*9815SRishi.Srivatsavai@Sun.COM * CDDL HEADER END 20*9815SRishi.Srivatsavai@Sun.COM */ 21*9815SRishi.Srivatsavai@Sun.COM /* 22*9815SRishi.Srivatsavai@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23*9815SRishi.Srivatsavai@Sun.COM * Use is subject to license terms. 24*9815SRishi.Srivatsavai@Sun.COM */ 25*9815SRishi.Srivatsavai@Sun.COM 26*9815SRishi.Srivatsavai@Sun.COM #include <sys/types.h> 27*9815SRishi.Srivatsavai@Sun.COM #include <string.h> 28*9815SRishi.Srivatsavai@Sun.COM #include <strings.h> 29*9815SRishi.Srivatsavai@Sun.COM #include <sys/mac.h> 30*9815SRishi.Srivatsavai@Sun.COM #include <sys/dls_mgmt.h> 31*9815SRishi.Srivatsavai@Sun.COM #include <sys/dlpi.h> 32*9815SRishi.Srivatsavai@Sun.COM #include <net/simnet.h> 33*9815SRishi.Srivatsavai@Sun.COM #include <errno.h> 34*9815SRishi.Srivatsavai@Sun.COM #include <unistd.h> 35*9815SRishi.Srivatsavai@Sun.COM 36*9815SRishi.Srivatsavai@Sun.COM #include <libdladm_impl.h> 37*9815SRishi.Srivatsavai@Sun.COM #include <libdllink.h> 38*9815SRishi.Srivatsavai@Sun.COM #include <libdlaggr.h> 39*9815SRishi.Srivatsavai@Sun.COM #include <libdlsim.h> 40*9815SRishi.Srivatsavai@Sun.COM 41*9815SRishi.Srivatsavai@Sun.COM static dladm_status_t dladm_simnet_persist_conf(dladm_handle_t, const char *, 42*9815SRishi.Srivatsavai@Sun.COM dladm_simnet_attr_t *); 43*9815SRishi.Srivatsavai@Sun.COM 44*9815SRishi.Srivatsavai@Sun.COM /* New simnet instance creation */ 45*9815SRishi.Srivatsavai@Sun.COM static dladm_status_t 46*9815SRishi.Srivatsavai@Sun.COM i_dladm_create_simnet(dladm_handle_t handle, dladm_simnet_attr_t *attrp) 47*9815SRishi.Srivatsavai@Sun.COM { 48*9815SRishi.Srivatsavai@Sun.COM int rc; 49*9815SRishi.Srivatsavai@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 50*9815SRishi.Srivatsavai@Sun.COM simnet_ioc_create_t ioc; 51*9815SRishi.Srivatsavai@Sun.COM 52*9815SRishi.Srivatsavai@Sun.COM bzero(&ioc, sizeof (ioc)); 53*9815SRishi.Srivatsavai@Sun.COM ioc.sic_link_id = attrp->sna_link_id; 54*9815SRishi.Srivatsavai@Sun.COM ioc.sic_type = attrp->sna_type; 55*9815SRishi.Srivatsavai@Sun.COM if (attrp->sna_mac_len > 0 && attrp->sna_mac_len <= MAXMACADDRLEN) { 56*9815SRishi.Srivatsavai@Sun.COM ioc.sic_mac_len = attrp->sna_mac_len; 57*9815SRishi.Srivatsavai@Sun.COM bcopy(attrp->sna_mac_addr, ioc.sic_mac_addr, ioc.sic_mac_len); 58*9815SRishi.Srivatsavai@Sun.COM } 59*9815SRishi.Srivatsavai@Sun.COM 60*9815SRishi.Srivatsavai@Sun.COM rc = ioctl(dladm_dld_fd(handle), SIMNET_IOC_CREATE, &ioc); 61*9815SRishi.Srivatsavai@Sun.COM if (rc < 0) 62*9815SRishi.Srivatsavai@Sun.COM status = dladm_errno2status(errno); 63*9815SRishi.Srivatsavai@Sun.COM 64*9815SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 65*9815SRishi.Srivatsavai@Sun.COM return (status); 66*9815SRishi.Srivatsavai@Sun.COM 67*9815SRishi.Srivatsavai@Sun.COM bcopy(ioc.sic_mac_addr, attrp->sna_mac_addr, MAXMACADDRLEN); 68*9815SRishi.Srivatsavai@Sun.COM attrp->sna_mac_len = ioc.sic_mac_len; 69*9815SRishi.Srivatsavai@Sun.COM return (status); 70*9815SRishi.Srivatsavai@Sun.COM } 71*9815SRishi.Srivatsavai@Sun.COM 72*9815SRishi.Srivatsavai@Sun.COM /* Modify existing simnet instance */ 73*9815SRishi.Srivatsavai@Sun.COM static dladm_status_t 74*9815SRishi.Srivatsavai@Sun.COM i_dladm_modify_simnet(dladm_handle_t handle, dladm_simnet_attr_t *attrp) 75*9815SRishi.Srivatsavai@Sun.COM { 76*9815SRishi.Srivatsavai@Sun.COM int rc; 77*9815SRishi.Srivatsavai@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 78*9815SRishi.Srivatsavai@Sun.COM simnet_ioc_modify_t ioc; 79*9815SRishi.Srivatsavai@Sun.COM 80*9815SRishi.Srivatsavai@Sun.COM bzero(&ioc, sizeof (ioc)); 81*9815SRishi.Srivatsavai@Sun.COM ioc.sim_link_id = attrp->sna_link_id; 82*9815SRishi.Srivatsavai@Sun.COM ioc.sim_peer_link_id = attrp->sna_peer_link_id; 83*9815SRishi.Srivatsavai@Sun.COM 84*9815SRishi.Srivatsavai@Sun.COM rc = ioctl(dladm_dld_fd(handle), SIMNET_IOC_MODIFY, &ioc); 85*9815SRishi.Srivatsavai@Sun.COM if (rc < 0) 86*9815SRishi.Srivatsavai@Sun.COM status = dladm_errno2status(errno); 87*9815SRishi.Srivatsavai@Sun.COM 88*9815SRishi.Srivatsavai@Sun.COM return (status); 89*9815SRishi.Srivatsavai@Sun.COM } 90*9815SRishi.Srivatsavai@Sun.COM 91*9815SRishi.Srivatsavai@Sun.COM /* Delete simnet instance */ 92*9815SRishi.Srivatsavai@Sun.COM static dladm_status_t 93*9815SRishi.Srivatsavai@Sun.COM i_dladm_delete_simnet(dladm_handle_t handle, dladm_simnet_attr_t *attrp) 94*9815SRishi.Srivatsavai@Sun.COM { 95*9815SRishi.Srivatsavai@Sun.COM int rc; 96*9815SRishi.Srivatsavai@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 97*9815SRishi.Srivatsavai@Sun.COM simnet_ioc_delete_t ioc; 98*9815SRishi.Srivatsavai@Sun.COM 99*9815SRishi.Srivatsavai@Sun.COM bzero(&ioc, sizeof (ioc)); 100*9815SRishi.Srivatsavai@Sun.COM ioc.sid_link_id = attrp->sna_link_id; 101*9815SRishi.Srivatsavai@Sun.COM 102*9815SRishi.Srivatsavai@Sun.COM rc = ioctl(dladm_dld_fd(handle), SIMNET_IOC_DELETE, &ioc); 103*9815SRishi.Srivatsavai@Sun.COM if (rc < 0) 104*9815SRishi.Srivatsavai@Sun.COM status = dladm_errno2status(errno); 105*9815SRishi.Srivatsavai@Sun.COM 106*9815SRishi.Srivatsavai@Sun.COM return (status); 107*9815SRishi.Srivatsavai@Sun.COM } 108*9815SRishi.Srivatsavai@Sun.COM 109*9815SRishi.Srivatsavai@Sun.COM /* Retrieve simnet instance information */ 110*9815SRishi.Srivatsavai@Sun.COM static dladm_status_t 111*9815SRishi.Srivatsavai@Sun.COM i_dladm_get_simnet_info(dladm_handle_t handle, dladm_simnet_attr_t *attrp) 112*9815SRishi.Srivatsavai@Sun.COM { 113*9815SRishi.Srivatsavai@Sun.COM int rc; 114*9815SRishi.Srivatsavai@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 115*9815SRishi.Srivatsavai@Sun.COM simnet_ioc_info_t ioc; 116*9815SRishi.Srivatsavai@Sun.COM 117*9815SRishi.Srivatsavai@Sun.COM bzero(&ioc, sizeof (ioc)); 118*9815SRishi.Srivatsavai@Sun.COM ioc.sii_link_id = attrp->sna_link_id; 119*9815SRishi.Srivatsavai@Sun.COM 120*9815SRishi.Srivatsavai@Sun.COM rc = ioctl(dladm_dld_fd(handle), SIMNET_IOC_INFO, &ioc); 121*9815SRishi.Srivatsavai@Sun.COM if (rc < 0) { 122*9815SRishi.Srivatsavai@Sun.COM status = dladm_errno2status(errno); 123*9815SRishi.Srivatsavai@Sun.COM return (status); 124*9815SRishi.Srivatsavai@Sun.COM } 125*9815SRishi.Srivatsavai@Sun.COM 126*9815SRishi.Srivatsavai@Sun.COM bcopy(ioc.sii_mac_addr, attrp->sna_mac_addr, MAXMACADDRLEN); 127*9815SRishi.Srivatsavai@Sun.COM attrp->sna_mac_len = ioc.sii_mac_len; 128*9815SRishi.Srivatsavai@Sun.COM attrp->sna_peer_link_id = ioc.sii_peer_link_id; 129*9815SRishi.Srivatsavai@Sun.COM attrp->sna_type = ioc.sii_type; 130*9815SRishi.Srivatsavai@Sun.COM return (status); 131*9815SRishi.Srivatsavai@Sun.COM } 132*9815SRishi.Srivatsavai@Sun.COM 133*9815SRishi.Srivatsavai@Sun.COM /* Retrieve simnet configuratin */ 134*9815SRishi.Srivatsavai@Sun.COM static dladm_status_t 135*9815SRishi.Srivatsavai@Sun.COM i_dladm_get_simnet_info_persist(dladm_handle_t handle, 136*9815SRishi.Srivatsavai@Sun.COM dladm_simnet_attr_t *attrp) 137*9815SRishi.Srivatsavai@Sun.COM { 138*9815SRishi.Srivatsavai@Sun.COM dladm_conf_t conf; 139*9815SRishi.Srivatsavai@Sun.COM dladm_status_t status; 140*9815SRishi.Srivatsavai@Sun.COM char macstr[ETHERADDRL * 3]; 141*9815SRishi.Srivatsavai@Sun.COM uint64_t u64; 142*9815SRishi.Srivatsavai@Sun.COM boolean_t mac_fixed; 143*9815SRishi.Srivatsavai@Sun.COM 144*9815SRishi.Srivatsavai@Sun.COM if ((status = dladm_read_conf(handle, attrp->sna_link_id, &conf)) != 145*9815SRishi.Srivatsavai@Sun.COM DLADM_STATUS_OK) 146*9815SRishi.Srivatsavai@Sun.COM return (status); 147*9815SRishi.Srivatsavai@Sun.COM 148*9815SRishi.Srivatsavai@Sun.COM status = dladm_get_conf_field(handle, conf, FSIMNETTYPE, &u64, 149*9815SRishi.Srivatsavai@Sun.COM sizeof (u64)); 150*9815SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 151*9815SRishi.Srivatsavai@Sun.COM goto done; 152*9815SRishi.Srivatsavai@Sun.COM attrp->sna_type = (uint_t)u64; 153*9815SRishi.Srivatsavai@Sun.COM 154*9815SRishi.Srivatsavai@Sun.COM status = dladm_get_conf_field(handle, conf, FMADDRLEN, &u64, 155*9815SRishi.Srivatsavai@Sun.COM sizeof (u64)); 156*9815SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 157*9815SRishi.Srivatsavai@Sun.COM goto done; 158*9815SRishi.Srivatsavai@Sun.COM attrp->sna_mac_len = (uint_t)u64; 159*9815SRishi.Srivatsavai@Sun.COM 160*9815SRishi.Srivatsavai@Sun.COM status = dladm_get_conf_field(handle, conf, FMACADDR, macstr, 161*9815SRishi.Srivatsavai@Sun.COM sizeof (macstr)); 162*9815SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 163*9815SRishi.Srivatsavai@Sun.COM goto done; 164*9815SRishi.Srivatsavai@Sun.COM (void) dladm_aggr_str2macaddr(macstr, &mac_fixed, attrp->sna_mac_addr); 165*9815SRishi.Srivatsavai@Sun.COM 166*9815SRishi.Srivatsavai@Sun.COM /* Peer field is optional and only set when peer is attached */ 167*9815SRishi.Srivatsavai@Sun.COM if (dladm_get_conf_field(handle, conf, FSIMNETPEER, &u64, 168*9815SRishi.Srivatsavai@Sun.COM sizeof (u64)) == DLADM_STATUS_OK) 169*9815SRishi.Srivatsavai@Sun.COM attrp->sna_peer_link_id = (datalink_id_t)u64; 170*9815SRishi.Srivatsavai@Sun.COM else 171*9815SRishi.Srivatsavai@Sun.COM attrp->sna_peer_link_id = DATALINK_INVALID_LINKID; 172*9815SRishi.Srivatsavai@Sun.COM done: 173*9815SRishi.Srivatsavai@Sun.COM dladm_destroy_conf(handle, conf); 174*9815SRishi.Srivatsavai@Sun.COM return (status); 175*9815SRishi.Srivatsavai@Sun.COM } 176*9815SRishi.Srivatsavai@Sun.COM 177*9815SRishi.Srivatsavai@Sun.COM dladm_status_t 178*9815SRishi.Srivatsavai@Sun.COM dladm_simnet_create(dladm_handle_t handle, const char *simnetname, 179*9815SRishi.Srivatsavai@Sun.COM uint_t media, uint32_t flags) 180*9815SRishi.Srivatsavai@Sun.COM { 181*9815SRishi.Srivatsavai@Sun.COM datalink_id_t simnet_id; 182*9815SRishi.Srivatsavai@Sun.COM dladm_status_t status; 183*9815SRishi.Srivatsavai@Sun.COM dladm_simnet_attr_t attr; 184*9815SRishi.Srivatsavai@Sun.COM 185*9815SRishi.Srivatsavai@Sun.COM if (!(flags & DLADM_OPT_ACTIVE)) 186*9815SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_NOTSUP); 187*9815SRishi.Srivatsavai@Sun.COM 188*9815SRishi.Srivatsavai@Sun.COM flags &= (DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST); 189*9815SRishi.Srivatsavai@Sun.COM if ((status = dladm_create_datalink_id(handle, simnetname, 190*9815SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_SIMNET, media, flags, 191*9815SRishi.Srivatsavai@Sun.COM &simnet_id)) != DLADM_STATUS_OK) 192*9815SRishi.Srivatsavai@Sun.COM return (status); 193*9815SRishi.Srivatsavai@Sun.COM 194*9815SRishi.Srivatsavai@Sun.COM bzero(&attr, sizeof (attr)); 195*9815SRishi.Srivatsavai@Sun.COM attr.sna_link_id = simnet_id; 196*9815SRishi.Srivatsavai@Sun.COM attr.sna_type = media; 197*9815SRishi.Srivatsavai@Sun.COM status = i_dladm_create_simnet(handle, &attr); 198*9815SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 199*9815SRishi.Srivatsavai@Sun.COM goto done; 200*9815SRishi.Srivatsavai@Sun.COM 201*9815SRishi.Srivatsavai@Sun.COM if (!(flags & DLADM_OPT_PERSIST)) 202*9815SRishi.Srivatsavai@Sun.COM goto done; 203*9815SRishi.Srivatsavai@Sun.COM 204*9815SRishi.Srivatsavai@Sun.COM status = dladm_simnet_persist_conf(handle, simnetname, &attr); 205*9815SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) { 206*9815SRishi.Srivatsavai@Sun.COM (void) i_dladm_delete_simnet(handle, &attr); 207*9815SRishi.Srivatsavai@Sun.COM goto done; 208*9815SRishi.Srivatsavai@Sun.COM } 209*9815SRishi.Srivatsavai@Sun.COM 210*9815SRishi.Srivatsavai@Sun.COM (void) dladm_set_linkprop(handle, simnet_id, NULL, NULL, 0, flags); 211*9815SRishi.Srivatsavai@Sun.COM 212*9815SRishi.Srivatsavai@Sun.COM done: 213*9815SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) { 214*9815SRishi.Srivatsavai@Sun.COM (void) dladm_destroy_datalink_id(handle, simnet_id, flags); 215*9815SRishi.Srivatsavai@Sun.COM } 216*9815SRishi.Srivatsavai@Sun.COM return (status); 217*9815SRishi.Srivatsavai@Sun.COM } 218*9815SRishi.Srivatsavai@Sun.COM 219*9815SRishi.Srivatsavai@Sun.COM /* Update existing simnet configuration */ 220*9815SRishi.Srivatsavai@Sun.COM static dladm_status_t 221*9815SRishi.Srivatsavai@Sun.COM i_dladm_simnet_update_conf(dladm_handle_t handle, datalink_id_t simnet_id, 222*9815SRishi.Srivatsavai@Sun.COM datalink_id_t peer_simnet_id) 223*9815SRishi.Srivatsavai@Sun.COM { 224*9815SRishi.Srivatsavai@Sun.COM dladm_status_t status; 225*9815SRishi.Srivatsavai@Sun.COM dladm_conf_t conf; 226*9815SRishi.Srivatsavai@Sun.COM uint64_t u64; 227*9815SRishi.Srivatsavai@Sun.COM 228*9815SRishi.Srivatsavai@Sun.COM status = dladm_read_conf(handle, simnet_id, &conf); 229*9815SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 230*9815SRishi.Srivatsavai@Sun.COM return (status); 231*9815SRishi.Srivatsavai@Sun.COM 232*9815SRishi.Srivatsavai@Sun.COM /* First clear previous peer if any in configuration */ 233*9815SRishi.Srivatsavai@Sun.COM (void) dladm_unset_conf_field(handle, conf, FSIMNETPEER); 234*9815SRishi.Srivatsavai@Sun.COM if (peer_simnet_id != DATALINK_INVALID_LINKID) { 235*9815SRishi.Srivatsavai@Sun.COM u64 = peer_simnet_id; 236*9815SRishi.Srivatsavai@Sun.COM if ((status = dladm_datalink_id2info(handle, 237*9815SRishi.Srivatsavai@Sun.COM peer_simnet_id, NULL, NULL, NULL, NULL, 238*9815SRishi.Srivatsavai@Sun.COM 0)) == DLADM_STATUS_OK) 239*9815SRishi.Srivatsavai@Sun.COM status = dladm_set_conf_field(handle, conf, 240*9815SRishi.Srivatsavai@Sun.COM FSIMNETPEER, DLADM_TYPE_UINT64, &u64); 241*9815SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 242*9815SRishi.Srivatsavai@Sun.COM goto fail; 243*9815SRishi.Srivatsavai@Sun.COM } 244*9815SRishi.Srivatsavai@Sun.COM 245*9815SRishi.Srivatsavai@Sun.COM status = dladm_write_conf(handle, conf); 246*9815SRishi.Srivatsavai@Sun.COM fail: 247*9815SRishi.Srivatsavai@Sun.COM dladm_destroy_conf(handle, conf); 248*9815SRishi.Srivatsavai@Sun.COM return (status); 249*9815SRishi.Srivatsavai@Sun.COM } 250*9815SRishi.Srivatsavai@Sun.COM 251*9815SRishi.Srivatsavai@Sun.COM /* Modify attached simnet peer */ 252*9815SRishi.Srivatsavai@Sun.COM dladm_status_t 253*9815SRishi.Srivatsavai@Sun.COM dladm_simnet_modify(dladm_handle_t handle, datalink_id_t simnet_id, 254*9815SRishi.Srivatsavai@Sun.COM datalink_id_t peer_simnet_id, uint32_t flags) 255*9815SRishi.Srivatsavai@Sun.COM { 256*9815SRishi.Srivatsavai@Sun.COM dladm_simnet_attr_t attr; 257*9815SRishi.Srivatsavai@Sun.COM dladm_simnet_attr_t prevattr; 258*9815SRishi.Srivatsavai@Sun.COM dladm_status_t status; 259*9815SRishi.Srivatsavai@Sun.COM datalink_class_t class; 260*9815SRishi.Srivatsavai@Sun.COM uint32_t linkflags; 261*9815SRishi.Srivatsavai@Sun.COM uint32_t peerlinkflags; 262*9815SRishi.Srivatsavai@Sun.COM 263*9815SRishi.Srivatsavai@Sun.COM if (!(flags & DLADM_OPT_ACTIVE)) 264*9815SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_NOTSUP); 265*9815SRishi.Srivatsavai@Sun.COM 266*9815SRishi.Srivatsavai@Sun.COM if ((dladm_datalink_id2info(handle, simnet_id, &linkflags, &class, 267*9815SRishi.Srivatsavai@Sun.COM NULL, NULL, 0) != DLADM_STATUS_OK)) 268*9815SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 269*9815SRishi.Srivatsavai@Sun.COM if (class != DATALINK_CLASS_SIMNET) 270*9815SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 271*9815SRishi.Srivatsavai@Sun.COM 272*9815SRishi.Srivatsavai@Sun.COM if (peer_simnet_id != DATALINK_INVALID_LINKID) { 273*9815SRishi.Srivatsavai@Sun.COM if (dladm_datalink_id2info(handle, peer_simnet_id, 274*9815SRishi.Srivatsavai@Sun.COM &peerlinkflags, &class, NULL, NULL, 0) != DLADM_STATUS_OK) 275*9815SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 276*9815SRishi.Srivatsavai@Sun.COM if (class != DATALINK_CLASS_SIMNET) 277*9815SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 278*9815SRishi.Srivatsavai@Sun.COM /* Check to ensure the peer link has identical flags */ 279*9815SRishi.Srivatsavai@Sun.COM if (peerlinkflags != linkflags) 280*9815SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 281*9815SRishi.Srivatsavai@Sun.COM } 282*9815SRishi.Srivatsavai@Sun.COM 283*9815SRishi.Srivatsavai@Sun.COM /* Retrieve previous attrs before modification */ 284*9815SRishi.Srivatsavai@Sun.COM bzero(&prevattr, sizeof (prevattr)); 285*9815SRishi.Srivatsavai@Sun.COM if ((status = dladm_simnet_info(handle, simnet_id, &prevattr, 286*9815SRishi.Srivatsavai@Sun.COM flags)) != DLADM_STATUS_OK) 287*9815SRishi.Srivatsavai@Sun.COM return (status); 288*9815SRishi.Srivatsavai@Sun.COM 289*9815SRishi.Srivatsavai@Sun.COM bzero(&attr, sizeof (attr)); 290*9815SRishi.Srivatsavai@Sun.COM attr.sna_link_id = simnet_id; 291*9815SRishi.Srivatsavai@Sun.COM attr.sna_peer_link_id = peer_simnet_id; 292*9815SRishi.Srivatsavai@Sun.COM status = i_dladm_modify_simnet(handle, &attr); 293*9815SRishi.Srivatsavai@Sun.COM if ((status != DLADM_STATUS_OK) || !(flags & DLADM_OPT_PERSIST)) 294*9815SRishi.Srivatsavai@Sun.COM return (status); 295*9815SRishi.Srivatsavai@Sun.COM 296*9815SRishi.Srivatsavai@Sun.COM /* First we clear link's existing peer field in config */ 297*9815SRishi.Srivatsavai@Sun.COM status = i_dladm_simnet_update_conf(handle, simnet_id, 298*9815SRishi.Srivatsavai@Sun.COM DATALINK_INVALID_LINKID); 299*9815SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 300*9815SRishi.Srivatsavai@Sun.COM return (status); 301*9815SRishi.Srivatsavai@Sun.COM 302*9815SRishi.Srivatsavai@Sun.COM /* Clear the previous peer link's existing peer field in config */ 303*9815SRishi.Srivatsavai@Sun.COM if (prevattr.sna_peer_link_id != DATALINK_INVALID_LINKID) { 304*9815SRishi.Srivatsavai@Sun.COM status = i_dladm_simnet_update_conf(handle, 305*9815SRishi.Srivatsavai@Sun.COM prevattr.sna_peer_link_id, DATALINK_INVALID_LINKID); 306*9815SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 307*9815SRishi.Srivatsavai@Sun.COM return (status); 308*9815SRishi.Srivatsavai@Sun.COM } 309*9815SRishi.Srivatsavai@Sun.COM 310*9815SRishi.Srivatsavai@Sun.COM /* Update the configuration in both simnets with any new peer link */ 311*9815SRishi.Srivatsavai@Sun.COM if (peer_simnet_id != DATALINK_INVALID_LINKID) { 312*9815SRishi.Srivatsavai@Sun.COM status = i_dladm_simnet_update_conf(handle, simnet_id, 313*9815SRishi.Srivatsavai@Sun.COM peer_simnet_id); 314*9815SRishi.Srivatsavai@Sun.COM if (status == DLADM_STATUS_OK) 315*9815SRishi.Srivatsavai@Sun.COM status = i_dladm_simnet_update_conf(handle, 316*9815SRishi.Srivatsavai@Sun.COM peer_simnet_id, simnet_id); 317*9815SRishi.Srivatsavai@Sun.COM } 318*9815SRishi.Srivatsavai@Sun.COM 319*9815SRishi.Srivatsavai@Sun.COM return (status); 320*9815SRishi.Srivatsavai@Sun.COM } 321*9815SRishi.Srivatsavai@Sun.COM 322*9815SRishi.Srivatsavai@Sun.COM dladm_status_t 323*9815SRishi.Srivatsavai@Sun.COM dladm_simnet_delete(dladm_handle_t handle, datalink_id_t simnet_id, 324*9815SRishi.Srivatsavai@Sun.COM uint32_t flags) 325*9815SRishi.Srivatsavai@Sun.COM { 326*9815SRishi.Srivatsavai@Sun.COM dladm_simnet_attr_t attr; 327*9815SRishi.Srivatsavai@Sun.COM dladm_simnet_attr_t prevattr; 328*9815SRishi.Srivatsavai@Sun.COM dladm_status_t status; 329*9815SRishi.Srivatsavai@Sun.COM datalink_class_t class; 330*9815SRishi.Srivatsavai@Sun.COM 331*9815SRishi.Srivatsavai@Sun.COM if ((dladm_datalink_id2info(handle, simnet_id, NULL, &class, 332*9815SRishi.Srivatsavai@Sun.COM NULL, NULL, 0) != DLADM_STATUS_OK)) 333*9815SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 334*9815SRishi.Srivatsavai@Sun.COM 335*9815SRishi.Srivatsavai@Sun.COM if (class != DATALINK_CLASS_SIMNET) 336*9815SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 337*9815SRishi.Srivatsavai@Sun.COM 338*9815SRishi.Srivatsavai@Sun.COM /* Check current simnet attributes before deletion */ 339*9815SRishi.Srivatsavai@Sun.COM flags &= (DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST); 340*9815SRishi.Srivatsavai@Sun.COM bzero(&prevattr, sizeof (prevattr)); 341*9815SRishi.Srivatsavai@Sun.COM if ((status = dladm_simnet_info(handle, simnet_id, &prevattr, 342*9815SRishi.Srivatsavai@Sun.COM flags)) != DLADM_STATUS_OK) 343*9815SRishi.Srivatsavai@Sun.COM return (status); 344*9815SRishi.Srivatsavai@Sun.COM 345*9815SRishi.Srivatsavai@Sun.COM bzero(&attr, sizeof (attr)); 346*9815SRishi.Srivatsavai@Sun.COM attr.sna_link_id = simnet_id; 347*9815SRishi.Srivatsavai@Sun.COM if (flags & DLADM_OPT_ACTIVE) { 348*9815SRishi.Srivatsavai@Sun.COM status = i_dladm_delete_simnet(handle, &attr); 349*9815SRishi.Srivatsavai@Sun.COM if (status == DLADM_STATUS_OK) { 350*9815SRishi.Srivatsavai@Sun.COM (void) dladm_set_linkprop(handle, simnet_id, NULL, 351*9815SRishi.Srivatsavai@Sun.COM NULL, 0, DLADM_OPT_ACTIVE); 352*9815SRishi.Srivatsavai@Sun.COM (void) dladm_destroy_datalink_id(handle, simnet_id, 353*9815SRishi.Srivatsavai@Sun.COM DLADM_OPT_ACTIVE); 354*9815SRishi.Srivatsavai@Sun.COM } else if (status != DLADM_STATUS_NOTFOUND) { 355*9815SRishi.Srivatsavai@Sun.COM return (status); 356*9815SRishi.Srivatsavai@Sun.COM } 357*9815SRishi.Srivatsavai@Sun.COM } 358*9815SRishi.Srivatsavai@Sun.COM 359*9815SRishi.Srivatsavai@Sun.COM if (flags & DLADM_OPT_PERSIST) { 360*9815SRishi.Srivatsavai@Sun.COM (void) dladm_destroy_datalink_id(handle, simnet_id, 361*9815SRishi.Srivatsavai@Sun.COM DLADM_OPT_PERSIST); 362*9815SRishi.Srivatsavai@Sun.COM (void) dladm_remove_conf(handle, simnet_id); 363*9815SRishi.Srivatsavai@Sun.COM 364*9815SRishi.Srivatsavai@Sun.COM /* Update any attached peer configuration */ 365*9815SRishi.Srivatsavai@Sun.COM if (prevattr.sna_peer_link_id != DATALINK_INVALID_LINKID) 366*9815SRishi.Srivatsavai@Sun.COM status = i_dladm_simnet_update_conf(handle, 367*9815SRishi.Srivatsavai@Sun.COM prevattr.sna_peer_link_id, DATALINK_INVALID_LINKID); 368*9815SRishi.Srivatsavai@Sun.COM } 369*9815SRishi.Srivatsavai@Sun.COM return (status); 370*9815SRishi.Srivatsavai@Sun.COM } 371*9815SRishi.Srivatsavai@Sun.COM 372*9815SRishi.Srivatsavai@Sun.COM /* Retrieve simnet information either active or from configuration */ 373*9815SRishi.Srivatsavai@Sun.COM dladm_status_t 374*9815SRishi.Srivatsavai@Sun.COM dladm_simnet_info(dladm_handle_t handle, datalink_id_t simnet_id, 375*9815SRishi.Srivatsavai@Sun.COM dladm_simnet_attr_t *attrp, uint32_t flags) 376*9815SRishi.Srivatsavai@Sun.COM { 377*9815SRishi.Srivatsavai@Sun.COM datalink_class_t class; 378*9815SRishi.Srivatsavai@Sun.COM dladm_status_t status; 379*9815SRishi.Srivatsavai@Sun.COM 380*9815SRishi.Srivatsavai@Sun.COM if ((dladm_datalink_id2info(handle, simnet_id, NULL, &class, 381*9815SRishi.Srivatsavai@Sun.COM NULL, NULL, 0) != DLADM_STATUS_OK)) 382*9815SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 383*9815SRishi.Srivatsavai@Sun.COM 384*9815SRishi.Srivatsavai@Sun.COM if (class != DATALINK_CLASS_SIMNET) 385*9815SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 386*9815SRishi.Srivatsavai@Sun.COM 387*9815SRishi.Srivatsavai@Sun.COM bzero(attrp, sizeof (attrp)); 388*9815SRishi.Srivatsavai@Sun.COM attrp->sna_link_id = simnet_id; 389*9815SRishi.Srivatsavai@Sun.COM 390*9815SRishi.Srivatsavai@Sun.COM if (flags & DLADM_OPT_ACTIVE) { 391*9815SRishi.Srivatsavai@Sun.COM status = i_dladm_get_simnet_info(handle, attrp); 392*9815SRishi.Srivatsavai@Sun.COM /* 393*9815SRishi.Srivatsavai@Sun.COM * If no active simnet found then return any simnet 394*9815SRishi.Srivatsavai@Sun.COM * from stored config if requested. 395*9815SRishi.Srivatsavai@Sun.COM */ 396*9815SRishi.Srivatsavai@Sun.COM if (status == DLADM_STATUS_NOTFOUND && 397*9815SRishi.Srivatsavai@Sun.COM (flags & DLADM_OPT_PERSIST)) 398*9815SRishi.Srivatsavai@Sun.COM return (i_dladm_get_simnet_info_persist(handle, attrp)); 399*9815SRishi.Srivatsavai@Sun.COM return (status); 400*9815SRishi.Srivatsavai@Sun.COM } else if (flags & DLADM_OPT_PERSIST) { 401*9815SRishi.Srivatsavai@Sun.COM return (i_dladm_get_simnet_info_persist(handle, attrp)); 402*9815SRishi.Srivatsavai@Sun.COM } else { 403*9815SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 404*9815SRishi.Srivatsavai@Sun.COM } 405*9815SRishi.Srivatsavai@Sun.COM } 406*9815SRishi.Srivatsavai@Sun.COM 407*9815SRishi.Srivatsavai@Sun.COM /* Bring up simnet from stored configuration */ 408*9815SRishi.Srivatsavai@Sun.COM static int 409*9815SRishi.Srivatsavai@Sun.COM i_dladm_simnet_up(dladm_handle_t handle, datalink_id_t simnet_id, void *arg) 410*9815SRishi.Srivatsavai@Sun.COM { 411*9815SRishi.Srivatsavai@Sun.COM dladm_status_t *statusp = arg; 412*9815SRishi.Srivatsavai@Sun.COM dladm_status_t status; 413*9815SRishi.Srivatsavai@Sun.COM dladm_simnet_attr_t attr; 414*9815SRishi.Srivatsavai@Sun.COM dladm_simnet_attr_t peer_attr; 415*9815SRishi.Srivatsavai@Sun.COM 416*9815SRishi.Srivatsavai@Sun.COM bzero(&attr, sizeof (attr)); 417*9815SRishi.Srivatsavai@Sun.COM attr.sna_link_id = simnet_id; 418*9815SRishi.Srivatsavai@Sun.COM status = dladm_simnet_info(handle, simnet_id, &attr, 419*9815SRishi.Srivatsavai@Sun.COM DLADM_OPT_PERSIST); 420*9815SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 421*9815SRishi.Srivatsavai@Sun.COM goto done; 422*9815SRishi.Srivatsavai@Sun.COM 423*9815SRishi.Srivatsavai@Sun.COM status = i_dladm_create_simnet(handle, &attr); 424*9815SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 425*9815SRishi.Srivatsavai@Sun.COM goto done; 426*9815SRishi.Srivatsavai@Sun.COM 427*9815SRishi.Srivatsavai@Sun.COM /* 428*9815SRishi.Srivatsavai@Sun.COM * When bringing up check if the peer link is available, if it 429*9815SRishi.Srivatsavai@Sun.COM * is then modify the simnet and attach the peer link. 430*9815SRishi.Srivatsavai@Sun.COM */ 431*9815SRishi.Srivatsavai@Sun.COM if ((attr.sna_peer_link_id != DATALINK_INVALID_LINKID) && 432*9815SRishi.Srivatsavai@Sun.COM (dladm_simnet_info(handle, attr.sna_peer_link_id, &peer_attr, 433*9815SRishi.Srivatsavai@Sun.COM DLADM_OPT_ACTIVE) == DLADM_STATUS_OK)) { 434*9815SRishi.Srivatsavai@Sun.COM status = i_dladm_modify_simnet(handle, &attr); 435*9815SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 436*9815SRishi.Srivatsavai@Sun.COM goto done; 437*9815SRishi.Srivatsavai@Sun.COM } 438*9815SRishi.Srivatsavai@Sun.COM 439*9815SRishi.Srivatsavai@Sun.COM if ((status = dladm_up_datalink_id(handle, simnet_id)) != 440*9815SRishi.Srivatsavai@Sun.COM DLADM_STATUS_OK) { 441*9815SRishi.Srivatsavai@Sun.COM (void) dladm_simnet_delete(handle, simnet_id, 442*9815SRishi.Srivatsavai@Sun.COM DLADM_OPT_PERSIST); 443*9815SRishi.Srivatsavai@Sun.COM goto done; 444*9815SRishi.Srivatsavai@Sun.COM } 445*9815SRishi.Srivatsavai@Sun.COM done: 446*9815SRishi.Srivatsavai@Sun.COM *statusp = status; 447*9815SRishi.Srivatsavai@Sun.COM return (DLADM_WALK_CONTINUE); 448*9815SRishi.Srivatsavai@Sun.COM } 449*9815SRishi.Srivatsavai@Sun.COM 450*9815SRishi.Srivatsavai@Sun.COM /* Bring up simnet instance(s) from configuration */ 451*9815SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 452*9815SRishi.Srivatsavai@Sun.COM dladm_status_t 453*9815SRishi.Srivatsavai@Sun.COM dladm_simnet_up(dladm_handle_t handle, datalink_id_t simnet_id, 454*9815SRishi.Srivatsavai@Sun.COM uint32_t flags) 455*9815SRishi.Srivatsavai@Sun.COM { 456*9815SRishi.Srivatsavai@Sun.COM dladm_status_t status; 457*9815SRishi.Srivatsavai@Sun.COM 458*9815SRishi.Srivatsavai@Sun.COM if (simnet_id == DATALINK_ALL_LINKID) { 459*9815SRishi.Srivatsavai@Sun.COM (void) dladm_walk_datalink_id(i_dladm_simnet_up, handle, 460*9815SRishi.Srivatsavai@Sun.COM &status, DATALINK_CLASS_SIMNET, DATALINK_ANY_MEDIATYPE, 461*9815SRishi.Srivatsavai@Sun.COM DLADM_OPT_PERSIST); 462*9815SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 463*9815SRishi.Srivatsavai@Sun.COM } else { 464*9815SRishi.Srivatsavai@Sun.COM (void) i_dladm_simnet_up(handle, simnet_id, &status); 465*9815SRishi.Srivatsavai@Sun.COM return (status); 466*9815SRishi.Srivatsavai@Sun.COM } 467*9815SRishi.Srivatsavai@Sun.COM } 468*9815SRishi.Srivatsavai@Sun.COM 469*9815SRishi.Srivatsavai@Sun.COM /* Store simnet configuration */ 470*9815SRishi.Srivatsavai@Sun.COM static dladm_status_t 471*9815SRishi.Srivatsavai@Sun.COM dladm_simnet_persist_conf(dladm_handle_t handle, const char *name, 472*9815SRishi.Srivatsavai@Sun.COM dladm_simnet_attr_t *attrp) 473*9815SRishi.Srivatsavai@Sun.COM { 474*9815SRishi.Srivatsavai@Sun.COM dladm_conf_t conf = DLADM_INVALID_CONF; 475*9815SRishi.Srivatsavai@Sun.COM dladm_status_t status; 476*9815SRishi.Srivatsavai@Sun.COM char mstr[ETHERADDRL * 3]; 477*9815SRishi.Srivatsavai@Sun.COM uint64_t u64; 478*9815SRishi.Srivatsavai@Sun.COM 479*9815SRishi.Srivatsavai@Sun.COM if ((status = dladm_create_conf(handle, name, attrp->sna_link_id, 480*9815SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_SIMNET, attrp->sna_type, &conf)) != DLADM_STATUS_OK) 481*9815SRishi.Srivatsavai@Sun.COM return (status); 482*9815SRishi.Srivatsavai@Sun.COM 483*9815SRishi.Srivatsavai@Sun.COM status = dladm_set_conf_field(handle, conf, FMACADDR, 484*9815SRishi.Srivatsavai@Sun.COM DLADM_TYPE_STR, dladm_aggr_macaddr2str(attrp->sna_mac_addr, mstr)); 485*9815SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 486*9815SRishi.Srivatsavai@Sun.COM goto done; 487*9815SRishi.Srivatsavai@Sun.COM 488*9815SRishi.Srivatsavai@Sun.COM u64 = attrp->sna_type; 489*9815SRishi.Srivatsavai@Sun.COM status = dladm_set_conf_field(handle, conf, FSIMNETTYPE, 490*9815SRishi.Srivatsavai@Sun.COM DLADM_TYPE_UINT64, &u64); 491*9815SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 492*9815SRishi.Srivatsavai@Sun.COM goto done; 493*9815SRishi.Srivatsavai@Sun.COM 494*9815SRishi.Srivatsavai@Sun.COM u64 = attrp->sna_mac_len; 495*9815SRishi.Srivatsavai@Sun.COM status = dladm_set_conf_field(handle, conf, FMADDRLEN, 496*9815SRishi.Srivatsavai@Sun.COM DLADM_TYPE_UINT64, &u64); 497*9815SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 498*9815SRishi.Srivatsavai@Sun.COM goto done; 499*9815SRishi.Srivatsavai@Sun.COM 500*9815SRishi.Srivatsavai@Sun.COM status = dladm_write_conf(handle, conf); 501*9815SRishi.Srivatsavai@Sun.COM done: 502*9815SRishi.Srivatsavai@Sun.COM dladm_destroy_conf(handle, conf); 503*9815SRishi.Srivatsavai@Sun.COM return (status); 504*9815SRishi.Srivatsavai@Sun.COM } 505