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