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