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