19815SRishi.Srivatsavai@Sun.COM /* 29815SRishi.Srivatsavai@Sun.COM * CDDL HEADER START 39815SRishi.Srivatsavai@Sun.COM * 49815SRishi.Srivatsavai@Sun.COM * The contents of this file are subject to the terms of the 59815SRishi.Srivatsavai@Sun.COM * Common Development and Distribution License (the "License"). 69815SRishi.Srivatsavai@Sun.COM * You may not use this file except in compliance with the License. 79815SRishi.Srivatsavai@Sun.COM * 89815SRishi.Srivatsavai@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 99815SRishi.Srivatsavai@Sun.COM * or http://www.opensolaris.org/os/licensing. 109815SRishi.Srivatsavai@Sun.COM * See the License for the specific language governing permissions 119815SRishi.Srivatsavai@Sun.COM * and limitations under the License. 129815SRishi.Srivatsavai@Sun.COM * 139815SRishi.Srivatsavai@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 149815SRishi.Srivatsavai@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 159815SRishi.Srivatsavai@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 169815SRishi.Srivatsavai@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 179815SRishi.Srivatsavai@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 189815SRishi.Srivatsavai@Sun.COM * 199815SRishi.Srivatsavai@Sun.COM * CDDL HEADER END 209815SRishi.Srivatsavai@Sun.COM */ 219815SRishi.Srivatsavai@Sun.COM /* 229815SRishi.Srivatsavai@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 239815SRishi.Srivatsavai@Sun.COM * Use is subject to license terms. 249815SRishi.Srivatsavai@Sun.COM */ 259815SRishi.Srivatsavai@Sun.COM 269815SRishi.Srivatsavai@Sun.COM #include <sys/types.h> 279815SRishi.Srivatsavai@Sun.COM #include <string.h> 289815SRishi.Srivatsavai@Sun.COM #include <strings.h> 299815SRishi.Srivatsavai@Sun.COM #include <sys/mac.h> 309815SRishi.Srivatsavai@Sun.COM #include <sys/dls_mgmt.h> 319815SRishi.Srivatsavai@Sun.COM #include <sys/dlpi.h> 329815SRishi.Srivatsavai@Sun.COM #include <net/simnet.h> 339815SRishi.Srivatsavai@Sun.COM #include <errno.h> 349815SRishi.Srivatsavai@Sun.COM #include <unistd.h> 359815SRishi.Srivatsavai@Sun.COM 369815SRishi.Srivatsavai@Sun.COM #include <libdladm_impl.h> 379815SRishi.Srivatsavai@Sun.COM #include <libdllink.h> 389815SRishi.Srivatsavai@Sun.COM #include <libdlaggr.h> 399815SRishi.Srivatsavai@Sun.COM #include <libdlsim.h> 409815SRishi.Srivatsavai@Sun.COM 419815SRishi.Srivatsavai@Sun.COM static dladm_status_t dladm_simnet_persist_conf(dladm_handle_t, const char *, 429815SRishi.Srivatsavai@Sun.COM dladm_simnet_attr_t *); 439815SRishi.Srivatsavai@Sun.COM 449815SRishi.Srivatsavai@Sun.COM /* New simnet instance creation */ 459815SRishi.Srivatsavai@Sun.COM static dladm_status_t 469815SRishi.Srivatsavai@Sun.COM i_dladm_create_simnet(dladm_handle_t handle, dladm_simnet_attr_t *attrp) 479815SRishi.Srivatsavai@Sun.COM { 489815SRishi.Srivatsavai@Sun.COM int rc; 499815SRishi.Srivatsavai@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 509815SRishi.Srivatsavai@Sun.COM simnet_ioc_create_t ioc; 519815SRishi.Srivatsavai@Sun.COM 529815SRishi.Srivatsavai@Sun.COM bzero(&ioc, sizeof (ioc)); 539815SRishi.Srivatsavai@Sun.COM ioc.sic_link_id = attrp->sna_link_id; 549815SRishi.Srivatsavai@Sun.COM ioc.sic_type = attrp->sna_type; 559815SRishi.Srivatsavai@Sun.COM if (attrp->sna_mac_len > 0 && attrp->sna_mac_len <= MAXMACADDRLEN) { 569815SRishi.Srivatsavai@Sun.COM ioc.sic_mac_len = attrp->sna_mac_len; 579815SRishi.Srivatsavai@Sun.COM bcopy(attrp->sna_mac_addr, ioc.sic_mac_addr, ioc.sic_mac_len); 589815SRishi.Srivatsavai@Sun.COM } 599815SRishi.Srivatsavai@Sun.COM 609815SRishi.Srivatsavai@Sun.COM rc = ioctl(dladm_dld_fd(handle), SIMNET_IOC_CREATE, &ioc); 619815SRishi.Srivatsavai@Sun.COM if (rc < 0) 629815SRishi.Srivatsavai@Sun.COM status = dladm_errno2status(errno); 639815SRishi.Srivatsavai@Sun.COM 649815SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 659815SRishi.Srivatsavai@Sun.COM return (status); 669815SRishi.Srivatsavai@Sun.COM 679815SRishi.Srivatsavai@Sun.COM bcopy(ioc.sic_mac_addr, attrp->sna_mac_addr, MAXMACADDRLEN); 689815SRishi.Srivatsavai@Sun.COM attrp->sna_mac_len = ioc.sic_mac_len; 699815SRishi.Srivatsavai@Sun.COM return (status); 709815SRishi.Srivatsavai@Sun.COM } 719815SRishi.Srivatsavai@Sun.COM 729815SRishi.Srivatsavai@Sun.COM /* Modify existing simnet instance */ 739815SRishi.Srivatsavai@Sun.COM static dladm_status_t 749815SRishi.Srivatsavai@Sun.COM i_dladm_modify_simnet(dladm_handle_t handle, dladm_simnet_attr_t *attrp) 759815SRishi.Srivatsavai@Sun.COM { 769815SRishi.Srivatsavai@Sun.COM int rc; 779815SRishi.Srivatsavai@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 789815SRishi.Srivatsavai@Sun.COM simnet_ioc_modify_t ioc; 799815SRishi.Srivatsavai@Sun.COM 809815SRishi.Srivatsavai@Sun.COM bzero(&ioc, sizeof (ioc)); 819815SRishi.Srivatsavai@Sun.COM ioc.sim_link_id = attrp->sna_link_id; 829815SRishi.Srivatsavai@Sun.COM ioc.sim_peer_link_id = attrp->sna_peer_link_id; 839815SRishi.Srivatsavai@Sun.COM 849815SRishi.Srivatsavai@Sun.COM rc = ioctl(dladm_dld_fd(handle), SIMNET_IOC_MODIFY, &ioc); 859815SRishi.Srivatsavai@Sun.COM if (rc < 0) 869815SRishi.Srivatsavai@Sun.COM status = dladm_errno2status(errno); 879815SRishi.Srivatsavai@Sun.COM 889815SRishi.Srivatsavai@Sun.COM return (status); 899815SRishi.Srivatsavai@Sun.COM } 909815SRishi.Srivatsavai@Sun.COM 919815SRishi.Srivatsavai@Sun.COM /* Delete simnet instance */ 929815SRishi.Srivatsavai@Sun.COM static dladm_status_t 939815SRishi.Srivatsavai@Sun.COM i_dladm_delete_simnet(dladm_handle_t handle, dladm_simnet_attr_t *attrp) 949815SRishi.Srivatsavai@Sun.COM { 959815SRishi.Srivatsavai@Sun.COM int rc; 969815SRishi.Srivatsavai@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 979815SRishi.Srivatsavai@Sun.COM simnet_ioc_delete_t ioc; 989815SRishi.Srivatsavai@Sun.COM 999815SRishi.Srivatsavai@Sun.COM bzero(&ioc, sizeof (ioc)); 1009815SRishi.Srivatsavai@Sun.COM ioc.sid_link_id = attrp->sna_link_id; 1019815SRishi.Srivatsavai@Sun.COM 1029815SRishi.Srivatsavai@Sun.COM rc = ioctl(dladm_dld_fd(handle), SIMNET_IOC_DELETE, &ioc); 1039815SRishi.Srivatsavai@Sun.COM if (rc < 0) 1049815SRishi.Srivatsavai@Sun.COM status = dladm_errno2status(errno); 1059815SRishi.Srivatsavai@Sun.COM 1069815SRishi.Srivatsavai@Sun.COM return (status); 1079815SRishi.Srivatsavai@Sun.COM } 1089815SRishi.Srivatsavai@Sun.COM 1099815SRishi.Srivatsavai@Sun.COM /* Retrieve simnet instance information */ 1109815SRishi.Srivatsavai@Sun.COM static dladm_status_t 1119815SRishi.Srivatsavai@Sun.COM i_dladm_get_simnet_info(dladm_handle_t handle, dladm_simnet_attr_t *attrp) 1129815SRishi.Srivatsavai@Sun.COM { 1139815SRishi.Srivatsavai@Sun.COM int rc; 1149815SRishi.Srivatsavai@Sun.COM dladm_status_t status = DLADM_STATUS_OK; 1159815SRishi.Srivatsavai@Sun.COM simnet_ioc_info_t ioc; 1169815SRishi.Srivatsavai@Sun.COM 1179815SRishi.Srivatsavai@Sun.COM bzero(&ioc, sizeof (ioc)); 1189815SRishi.Srivatsavai@Sun.COM ioc.sii_link_id = attrp->sna_link_id; 1199815SRishi.Srivatsavai@Sun.COM 1209815SRishi.Srivatsavai@Sun.COM rc = ioctl(dladm_dld_fd(handle), SIMNET_IOC_INFO, &ioc); 1219815SRishi.Srivatsavai@Sun.COM if (rc < 0) { 1229815SRishi.Srivatsavai@Sun.COM status = dladm_errno2status(errno); 1239815SRishi.Srivatsavai@Sun.COM return (status); 1249815SRishi.Srivatsavai@Sun.COM } 1259815SRishi.Srivatsavai@Sun.COM 1269815SRishi.Srivatsavai@Sun.COM bcopy(ioc.sii_mac_addr, attrp->sna_mac_addr, MAXMACADDRLEN); 1279815SRishi.Srivatsavai@Sun.COM attrp->sna_mac_len = ioc.sii_mac_len; 1289815SRishi.Srivatsavai@Sun.COM attrp->sna_peer_link_id = ioc.sii_peer_link_id; 1299815SRishi.Srivatsavai@Sun.COM attrp->sna_type = ioc.sii_type; 1309815SRishi.Srivatsavai@Sun.COM return (status); 1319815SRishi.Srivatsavai@Sun.COM } 1329815SRishi.Srivatsavai@Sun.COM 1339815SRishi.Srivatsavai@Sun.COM /* Retrieve simnet configuratin */ 1349815SRishi.Srivatsavai@Sun.COM static dladm_status_t 1359815SRishi.Srivatsavai@Sun.COM i_dladm_get_simnet_info_persist(dladm_handle_t handle, 1369815SRishi.Srivatsavai@Sun.COM dladm_simnet_attr_t *attrp) 1379815SRishi.Srivatsavai@Sun.COM { 1389815SRishi.Srivatsavai@Sun.COM dladm_conf_t conf; 1399815SRishi.Srivatsavai@Sun.COM dladm_status_t status; 1409815SRishi.Srivatsavai@Sun.COM char macstr[ETHERADDRL * 3]; 141*10616SSebastien.Roy@Sun.COM char simnetpeer[MAXLINKNAMELEN]; 1429815SRishi.Srivatsavai@Sun.COM uint64_t u64; 1439815SRishi.Srivatsavai@Sun.COM boolean_t mac_fixed; 1449815SRishi.Srivatsavai@Sun.COM 1459815SRishi.Srivatsavai@Sun.COM if ((status = dladm_read_conf(handle, attrp->sna_link_id, &conf)) != 1469815SRishi.Srivatsavai@Sun.COM DLADM_STATUS_OK) 1479815SRishi.Srivatsavai@Sun.COM return (status); 1489815SRishi.Srivatsavai@Sun.COM 1499815SRishi.Srivatsavai@Sun.COM status = dladm_get_conf_field(handle, conf, FSIMNETTYPE, &u64, 1509815SRishi.Srivatsavai@Sun.COM sizeof (u64)); 1519815SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 1529815SRishi.Srivatsavai@Sun.COM goto done; 1539815SRishi.Srivatsavai@Sun.COM attrp->sna_type = (uint_t)u64; 1549815SRishi.Srivatsavai@Sun.COM 1559815SRishi.Srivatsavai@Sun.COM status = dladm_get_conf_field(handle, conf, FMADDRLEN, &u64, 1569815SRishi.Srivatsavai@Sun.COM sizeof (u64)); 1579815SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 1589815SRishi.Srivatsavai@Sun.COM goto done; 1599815SRishi.Srivatsavai@Sun.COM attrp->sna_mac_len = (uint_t)u64; 1609815SRishi.Srivatsavai@Sun.COM 1619815SRishi.Srivatsavai@Sun.COM status = dladm_get_conf_field(handle, conf, FMACADDR, macstr, 1629815SRishi.Srivatsavai@Sun.COM sizeof (macstr)); 1639815SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 1649815SRishi.Srivatsavai@Sun.COM goto done; 1659815SRishi.Srivatsavai@Sun.COM (void) dladm_aggr_str2macaddr(macstr, &mac_fixed, attrp->sna_mac_addr); 1669815SRishi.Srivatsavai@Sun.COM 1679815SRishi.Srivatsavai@Sun.COM /* Peer field is optional and only set when peer is attached */ 168*10616SSebastien.Roy@Sun.COM if (dladm_get_conf_field(handle, conf, FSIMNETPEER, simnetpeer, 169*10616SSebastien.Roy@Sun.COM sizeof (simnetpeer)) == DLADM_STATUS_OK) { 170*10616SSebastien.Roy@Sun.COM status = dladm_name2info(handle, simnetpeer, 171*10616SSebastien.Roy@Sun.COM &attrp->sna_peer_link_id, NULL, NULL, NULL); 172*10616SSebastien.Roy@Sun.COM } else { 1739815SRishi.Srivatsavai@Sun.COM attrp->sna_peer_link_id = DATALINK_INVALID_LINKID; 174*10616SSebastien.Roy@Sun.COM } 1759815SRishi.Srivatsavai@Sun.COM done: 1769815SRishi.Srivatsavai@Sun.COM dladm_destroy_conf(handle, conf); 1779815SRishi.Srivatsavai@Sun.COM return (status); 1789815SRishi.Srivatsavai@Sun.COM } 1799815SRishi.Srivatsavai@Sun.COM 1809815SRishi.Srivatsavai@Sun.COM dladm_status_t 1819815SRishi.Srivatsavai@Sun.COM dladm_simnet_create(dladm_handle_t handle, const char *simnetname, 1829815SRishi.Srivatsavai@Sun.COM uint_t media, uint32_t flags) 1839815SRishi.Srivatsavai@Sun.COM { 1849815SRishi.Srivatsavai@Sun.COM datalink_id_t simnet_id; 1859815SRishi.Srivatsavai@Sun.COM dladm_status_t status; 1869815SRishi.Srivatsavai@Sun.COM dladm_simnet_attr_t attr; 1879815SRishi.Srivatsavai@Sun.COM 1889815SRishi.Srivatsavai@Sun.COM if (!(flags & DLADM_OPT_ACTIVE)) 1899815SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_NOTSUP); 1909815SRishi.Srivatsavai@Sun.COM 1919815SRishi.Srivatsavai@Sun.COM flags &= (DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST); 1929815SRishi.Srivatsavai@Sun.COM if ((status = dladm_create_datalink_id(handle, simnetname, 1939815SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_SIMNET, media, flags, 1949815SRishi.Srivatsavai@Sun.COM &simnet_id)) != DLADM_STATUS_OK) 1959815SRishi.Srivatsavai@Sun.COM return (status); 1969815SRishi.Srivatsavai@Sun.COM 1979815SRishi.Srivatsavai@Sun.COM bzero(&attr, sizeof (attr)); 1989815SRishi.Srivatsavai@Sun.COM attr.sna_link_id = simnet_id; 1999815SRishi.Srivatsavai@Sun.COM attr.sna_type = media; 2009815SRishi.Srivatsavai@Sun.COM status = i_dladm_create_simnet(handle, &attr); 2019815SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 2029815SRishi.Srivatsavai@Sun.COM goto done; 2039815SRishi.Srivatsavai@Sun.COM 2049815SRishi.Srivatsavai@Sun.COM if (!(flags & DLADM_OPT_PERSIST)) 2059815SRishi.Srivatsavai@Sun.COM goto done; 2069815SRishi.Srivatsavai@Sun.COM 2079815SRishi.Srivatsavai@Sun.COM status = dladm_simnet_persist_conf(handle, simnetname, &attr); 2089815SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) { 2099815SRishi.Srivatsavai@Sun.COM (void) i_dladm_delete_simnet(handle, &attr); 2109815SRishi.Srivatsavai@Sun.COM goto done; 2119815SRishi.Srivatsavai@Sun.COM } 2129815SRishi.Srivatsavai@Sun.COM 2139815SRishi.Srivatsavai@Sun.COM (void) dladm_set_linkprop(handle, simnet_id, NULL, NULL, 0, flags); 2149815SRishi.Srivatsavai@Sun.COM 2159815SRishi.Srivatsavai@Sun.COM done: 2169815SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) { 2179815SRishi.Srivatsavai@Sun.COM (void) dladm_destroy_datalink_id(handle, simnet_id, flags); 2189815SRishi.Srivatsavai@Sun.COM } 2199815SRishi.Srivatsavai@Sun.COM return (status); 2209815SRishi.Srivatsavai@Sun.COM } 2219815SRishi.Srivatsavai@Sun.COM 2229815SRishi.Srivatsavai@Sun.COM /* Update existing simnet configuration */ 2239815SRishi.Srivatsavai@Sun.COM static dladm_status_t 2249815SRishi.Srivatsavai@Sun.COM i_dladm_simnet_update_conf(dladm_handle_t handle, datalink_id_t simnet_id, 2259815SRishi.Srivatsavai@Sun.COM datalink_id_t peer_simnet_id) 2269815SRishi.Srivatsavai@Sun.COM { 2279815SRishi.Srivatsavai@Sun.COM dladm_status_t status; 2289815SRishi.Srivatsavai@Sun.COM dladm_conf_t conf; 229*10616SSebastien.Roy@Sun.COM char simnetpeer[MAXLINKNAMELEN]; 2309815SRishi.Srivatsavai@Sun.COM 2319815SRishi.Srivatsavai@Sun.COM status = dladm_read_conf(handle, simnet_id, &conf); 2329815SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 2339815SRishi.Srivatsavai@Sun.COM return (status); 2349815SRishi.Srivatsavai@Sun.COM 2359815SRishi.Srivatsavai@Sun.COM /* First clear previous peer if any in configuration */ 2369815SRishi.Srivatsavai@Sun.COM (void) dladm_unset_conf_field(handle, conf, FSIMNETPEER); 2379815SRishi.Srivatsavai@Sun.COM if (peer_simnet_id != DATALINK_INVALID_LINKID) { 2389815SRishi.Srivatsavai@Sun.COM if ((status = dladm_datalink_id2info(handle, 239*10616SSebastien.Roy@Sun.COM peer_simnet_id, NULL, NULL, NULL, simnetpeer, 240*10616SSebastien.Roy@Sun.COM sizeof (simnetpeer))) == DLADM_STATUS_OK) { 2419815SRishi.Srivatsavai@Sun.COM status = dladm_set_conf_field(handle, conf, 242*10616SSebastien.Roy@Sun.COM FSIMNETPEER, DLADM_TYPE_STR, simnetpeer); 243*10616SSebastien.Roy@Sun.COM } 2449815SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 2459815SRishi.Srivatsavai@Sun.COM goto fail; 2469815SRishi.Srivatsavai@Sun.COM } 2479815SRishi.Srivatsavai@Sun.COM 2489815SRishi.Srivatsavai@Sun.COM status = dladm_write_conf(handle, conf); 2499815SRishi.Srivatsavai@Sun.COM fail: 2509815SRishi.Srivatsavai@Sun.COM dladm_destroy_conf(handle, conf); 2519815SRishi.Srivatsavai@Sun.COM return (status); 2529815SRishi.Srivatsavai@Sun.COM } 2539815SRishi.Srivatsavai@Sun.COM 2549815SRishi.Srivatsavai@Sun.COM /* Modify attached simnet peer */ 2559815SRishi.Srivatsavai@Sun.COM dladm_status_t 2569815SRishi.Srivatsavai@Sun.COM dladm_simnet_modify(dladm_handle_t handle, datalink_id_t simnet_id, 2579815SRishi.Srivatsavai@Sun.COM datalink_id_t peer_simnet_id, uint32_t flags) 2589815SRishi.Srivatsavai@Sun.COM { 2599815SRishi.Srivatsavai@Sun.COM dladm_simnet_attr_t attr; 2609815SRishi.Srivatsavai@Sun.COM dladm_simnet_attr_t prevattr; 2619815SRishi.Srivatsavai@Sun.COM dladm_status_t status; 2629815SRishi.Srivatsavai@Sun.COM datalink_class_t class; 2639815SRishi.Srivatsavai@Sun.COM uint32_t linkflags; 2649815SRishi.Srivatsavai@Sun.COM uint32_t peerlinkflags; 2659815SRishi.Srivatsavai@Sun.COM 2669815SRishi.Srivatsavai@Sun.COM if (!(flags & DLADM_OPT_ACTIVE)) 2679815SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_NOTSUP); 2689815SRishi.Srivatsavai@Sun.COM 2699815SRishi.Srivatsavai@Sun.COM if ((dladm_datalink_id2info(handle, simnet_id, &linkflags, &class, 2709815SRishi.Srivatsavai@Sun.COM NULL, NULL, 0) != DLADM_STATUS_OK)) 2719815SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 2729815SRishi.Srivatsavai@Sun.COM if (class != DATALINK_CLASS_SIMNET) 2739815SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 2749815SRishi.Srivatsavai@Sun.COM 2759815SRishi.Srivatsavai@Sun.COM if (peer_simnet_id != DATALINK_INVALID_LINKID) { 2769815SRishi.Srivatsavai@Sun.COM if (dladm_datalink_id2info(handle, peer_simnet_id, 2779815SRishi.Srivatsavai@Sun.COM &peerlinkflags, &class, NULL, NULL, 0) != DLADM_STATUS_OK) 2789815SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 2799815SRishi.Srivatsavai@Sun.COM if (class != DATALINK_CLASS_SIMNET) 2809815SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 2819815SRishi.Srivatsavai@Sun.COM /* Check to ensure the peer link has identical flags */ 2829815SRishi.Srivatsavai@Sun.COM if (peerlinkflags != linkflags) 2839815SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 2849815SRishi.Srivatsavai@Sun.COM } 2859815SRishi.Srivatsavai@Sun.COM 2869815SRishi.Srivatsavai@Sun.COM /* Retrieve previous attrs before modification */ 2879815SRishi.Srivatsavai@Sun.COM bzero(&prevattr, sizeof (prevattr)); 2889815SRishi.Srivatsavai@Sun.COM if ((status = dladm_simnet_info(handle, simnet_id, &prevattr, 2899815SRishi.Srivatsavai@Sun.COM flags)) != DLADM_STATUS_OK) 2909815SRishi.Srivatsavai@Sun.COM return (status); 2919815SRishi.Srivatsavai@Sun.COM 2929815SRishi.Srivatsavai@Sun.COM bzero(&attr, sizeof (attr)); 2939815SRishi.Srivatsavai@Sun.COM attr.sna_link_id = simnet_id; 2949815SRishi.Srivatsavai@Sun.COM attr.sna_peer_link_id = peer_simnet_id; 2959815SRishi.Srivatsavai@Sun.COM status = i_dladm_modify_simnet(handle, &attr); 2969815SRishi.Srivatsavai@Sun.COM if ((status != DLADM_STATUS_OK) || !(flags & DLADM_OPT_PERSIST)) 2979815SRishi.Srivatsavai@Sun.COM return (status); 2989815SRishi.Srivatsavai@Sun.COM 2999815SRishi.Srivatsavai@Sun.COM /* First we clear link's existing peer field in config */ 3009815SRishi.Srivatsavai@Sun.COM status = i_dladm_simnet_update_conf(handle, simnet_id, 3019815SRishi.Srivatsavai@Sun.COM DATALINK_INVALID_LINKID); 3029815SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 3039815SRishi.Srivatsavai@Sun.COM return (status); 3049815SRishi.Srivatsavai@Sun.COM 3059815SRishi.Srivatsavai@Sun.COM /* Clear the previous peer link's existing peer field in config */ 3069815SRishi.Srivatsavai@Sun.COM if (prevattr.sna_peer_link_id != DATALINK_INVALID_LINKID) { 3079815SRishi.Srivatsavai@Sun.COM status = i_dladm_simnet_update_conf(handle, 3089815SRishi.Srivatsavai@Sun.COM prevattr.sna_peer_link_id, DATALINK_INVALID_LINKID); 3099815SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 3109815SRishi.Srivatsavai@Sun.COM return (status); 3119815SRishi.Srivatsavai@Sun.COM } 3129815SRishi.Srivatsavai@Sun.COM 3139815SRishi.Srivatsavai@Sun.COM /* Update the configuration in both simnets with any new peer link */ 3149815SRishi.Srivatsavai@Sun.COM if (peer_simnet_id != DATALINK_INVALID_LINKID) { 3159815SRishi.Srivatsavai@Sun.COM status = i_dladm_simnet_update_conf(handle, simnet_id, 3169815SRishi.Srivatsavai@Sun.COM peer_simnet_id); 3179815SRishi.Srivatsavai@Sun.COM if (status == DLADM_STATUS_OK) 3189815SRishi.Srivatsavai@Sun.COM status = i_dladm_simnet_update_conf(handle, 3199815SRishi.Srivatsavai@Sun.COM peer_simnet_id, simnet_id); 3209815SRishi.Srivatsavai@Sun.COM } 3219815SRishi.Srivatsavai@Sun.COM 3229815SRishi.Srivatsavai@Sun.COM return (status); 3239815SRishi.Srivatsavai@Sun.COM } 3249815SRishi.Srivatsavai@Sun.COM 3259815SRishi.Srivatsavai@Sun.COM dladm_status_t 3269815SRishi.Srivatsavai@Sun.COM dladm_simnet_delete(dladm_handle_t handle, datalink_id_t simnet_id, 3279815SRishi.Srivatsavai@Sun.COM uint32_t flags) 3289815SRishi.Srivatsavai@Sun.COM { 3299815SRishi.Srivatsavai@Sun.COM dladm_simnet_attr_t attr; 3309815SRishi.Srivatsavai@Sun.COM dladm_simnet_attr_t prevattr; 3319815SRishi.Srivatsavai@Sun.COM dladm_status_t status; 3329815SRishi.Srivatsavai@Sun.COM datalink_class_t class; 3339815SRishi.Srivatsavai@Sun.COM 3349815SRishi.Srivatsavai@Sun.COM if ((dladm_datalink_id2info(handle, simnet_id, NULL, &class, 3359815SRishi.Srivatsavai@Sun.COM NULL, NULL, 0) != DLADM_STATUS_OK)) 3369815SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 3379815SRishi.Srivatsavai@Sun.COM 3389815SRishi.Srivatsavai@Sun.COM if (class != DATALINK_CLASS_SIMNET) 3399815SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 3409815SRishi.Srivatsavai@Sun.COM 3419815SRishi.Srivatsavai@Sun.COM /* Check current simnet attributes before deletion */ 3429815SRishi.Srivatsavai@Sun.COM flags &= (DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST); 3439815SRishi.Srivatsavai@Sun.COM bzero(&prevattr, sizeof (prevattr)); 3449815SRishi.Srivatsavai@Sun.COM if ((status = dladm_simnet_info(handle, simnet_id, &prevattr, 3459815SRishi.Srivatsavai@Sun.COM flags)) != DLADM_STATUS_OK) 3469815SRishi.Srivatsavai@Sun.COM return (status); 3479815SRishi.Srivatsavai@Sun.COM 3489815SRishi.Srivatsavai@Sun.COM bzero(&attr, sizeof (attr)); 3499815SRishi.Srivatsavai@Sun.COM attr.sna_link_id = simnet_id; 3509815SRishi.Srivatsavai@Sun.COM if (flags & DLADM_OPT_ACTIVE) { 3519815SRishi.Srivatsavai@Sun.COM status = i_dladm_delete_simnet(handle, &attr); 3529815SRishi.Srivatsavai@Sun.COM if (status == DLADM_STATUS_OK) { 3539815SRishi.Srivatsavai@Sun.COM (void) dladm_set_linkprop(handle, simnet_id, NULL, 3549815SRishi.Srivatsavai@Sun.COM NULL, 0, DLADM_OPT_ACTIVE); 3559815SRishi.Srivatsavai@Sun.COM (void) dladm_destroy_datalink_id(handle, simnet_id, 3569815SRishi.Srivatsavai@Sun.COM DLADM_OPT_ACTIVE); 3579815SRishi.Srivatsavai@Sun.COM } else if (status != DLADM_STATUS_NOTFOUND) { 3589815SRishi.Srivatsavai@Sun.COM return (status); 3599815SRishi.Srivatsavai@Sun.COM } 3609815SRishi.Srivatsavai@Sun.COM } 3619815SRishi.Srivatsavai@Sun.COM 3629815SRishi.Srivatsavai@Sun.COM if (flags & DLADM_OPT_PERSIST) { 363*10616SSebastien.Roy@Sun.COM (void) dladm_remove_conf(handle, simnet_id); 3649815SRishi.Srivatsavai@Sun.COM (void) dladm_destroy_datalink_id(handle, simnet_id, 3659815SRishi.Srivatsavai@Sun.COM DLADM_OPT_PERSIST); 3669815SRishi.Srivatsavai@Sun.COM 3679815SRishi.Srivatsavai@Sun.COM /* Update any attached peer configuration */ 3689815SRishi.Srivatsavai@Sun.COM if (prevattr.sna_peer_link_id != DATALINK_INVALID_LINKID) 3699815SRishi.Srivatsavai@Sun.COM status = i_dladm_simnet_update_conf(handle, 3709815SRishi.Srivatsavai@Sun.COM prevattr.sna_peer_link_id, DATALINK_INVALID_LINKID); 3719815SRishi.Srivatsavai@Sun.COM } 3729815SRishi.Srivatsavai@Sun.COM return (status); 3739815SRishi.Srivatsavai@Sun.COM } 3749815SRishi.Srivatsavai@Sun.COM 3759815SRishi.Srivatsavai@Sun.COM /* Retrieve simnet information either active or from configuration */ 3769815SRishi.Srivatsavai@Sun.COM dladm_status_t 3779815SRishi.Srivatsavai@Sun.COM dladm_simnet_info(dladm_handle_t handle, datalink_id_t simnet_id, 3789815SRishi.Srivatsavai@Sun.COM dladm_simnet_attr_t *attrp, uint32_t flags) 3799815SRishi.Srivatsavai@Sun.COM { 3809815SRishi.Srivatsavai@Sun.COM datalink_class_t class; 3819815SRishi.Srivatsavai@Sun.COM dladm_status_t status; 3829815SRishi.Srivatsavai@Sun.COM 3839815SRishi.Srivatsavai@Sun.COM if ((dladm_datalink_id2info(handle, simnet_id, NULL, &class, 3849815SRishi.Srivatsavai@Sun.COM NULL, NULL, 0) != DLADM_STATUS_OK)) 3859815SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 3869815SRishi.Srivatsavai@Sun.COM 3879815SRishi.Srivatsavai@Sun.COM if (class != DATALINK_CLASS_SIMNET) 3889815SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 3899815SRishi.Srivatsavai@Sun.COM 3909815SRishi.Srivatsavai@Sun.COM bzero(attrp, sizeof (attrp)); 3919815SRishi.Srivatsavai@Sun.COM attrp->sna_link_id = simnet_id; 3929815SRishi.Srivatsavai@Sun.COM 3939815SRishi.Srivatsavai@Sun.COM if (flags & DLADM_OPT_ACTIVE) { 3949815SRishi.Srivatsavai@Sun.COM status = i_dladm_get_simnet_info(handle, attrp); 3959815SRishi.Srivatsavai@Sun.COM /* 3969815SRishi.Srivatsavai@Sun.COM * If no active simnet found then return any simnet 3979815SRishi.Srivatsavai@Sun.COM * from stored config if requested. 3989815SRishi.Srivatsavai@Sun.COM */ 3999815SRishi.Srivatsavai@Sun.COM if (status == DLADM_STATUS_NOTFOUND && 4009815SRishi.Srivatsavai@Sun.COM (flags & DLADM_OPT_PERSIST)) 4019815SRishi.Srivatsavai@Sun.COM return (i_dladm_get_simnet_info_persist(handle, attrp)); 4029815SRishi.Srivatsavai@Sun.COM return (status); 4039815SRishi.Srivatsavai@Sun.COM } else if (flags & DLADM_OPT_PERSIST) { 4049815SRishi.Srivatsavai@Sun.COM return (i_dladm_get_simnet_info_persist(handle, attrp)); 4059815SRishi.Srivatsavai@Sun.COM } else { 4069815SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_BADARG); 4079815SRishi.Srivatsavai@Sun.COM } 4089815SRishi.Srivatsavai@Sun.COM } 4099815SRishi.Srivatsavai@Sun.COM 4109815SRishi.Srivatsavai@Sun.COM /* Bring up simnet from stored configuration */ 4119815SRishi.Srivatsavai@Sun.COM static int 4129815SRishi.Srivatsavai@Sun.COM i_dladm_simnet_up(dladm_handle_t handle, datalink_id_t simnet_id, void *arg) 4139815SRishi.Srivatsavai@Sun.COM { 4149815SRishi.Srivatsavai@Sun.COM dladm_status_t *statusp = arg; 4159815SRishi.Srivatsavai@Sun.COM dladm_status_t status; 4169815SRishi.Srivatsavai@Sun.COM dladm_simnet_attr_t attr; 4179815SRishi.Srivatsavai@Sun.COM dladm_simnet_attr_t peer_attr; 4189815SRishi.Srivatsavai@Sun.COM 4199815SRishi.Srivatsavai@Sun.COM bzero(&attr, sizeof (attr)); 4209815SRishi.Srivatsavai@Sun.COM attr.sna_link_id = simnet_id; 4219815SRishi.Srivatsavai@Sun.COM status = dladm_simnet_info(handle, simnet_id, &attr, 4229815SRishi.Srivatsavai@Sun.COM DLADM_OPT_PERSIST); 4239815SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 4249815SRishi.Srivatsavai@Sun.COM goto done; 4259815SRishi.Srivatsavai@Sun.COM 4269815SRishi.Srivatsavai@Sun.COM status = i_dladm_create_simnet(handle, &attr); 4279815SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 4289815SRishi.Srivatsavai@Sun.COM goto done; 4299815SRishi.Srivatsavai@Sun.COM 4309815SRishi.Srivatsavai@Sun.COM /* 4319815SRishi.Srivatsavai@Sun.COM * When bringing up check if the peer link is available, if it 4329815SRishi.Srivatsavai@Sun.COM * is then modify the simnet and attach the peer link. 4339815SRishi.Srivatsavai@Sun.COM */ 4349815SRishi.Srivatsavai@Sun.COM if ((attr.sna_peer_link_id != DATALINK_INVALID_LINKID) && 4359815SRishi.Srivatsavai@Sun.COM (dladm_simnet_info(handle, attr.sna_peer_link_id, &peer_attr, 4369815SRishi.Srivatsavai@Sun.COM DLADM_OPT_ACTIVE) == DLADM_STATUS_OK)) { 4379815SRishi.Srivatsavai@Sun.COM status = i_dladm_modify_simnet(handle, &attr); 4389815SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 4399815SRishi.Srivatsavai@Sun.COM goto done; 4409815SRishi.Srivatsavai@Sun.COM } 4419815SRishi.Srivatsavai@Sun.COM 4429815SRishi.Srivatsavai@Sun.COM if ((status = dladm_up_datalink_id(handle, simnet_id)) != 4439815SRishi.Srivatsavai@Sun.COM DLADM_STATUS_OK) { 4449815SRishi.Srivatsavai@Sun.COM (void) dladm_simnet_delete(handle, simnet_id, 4459815SRishi.Srivatsavai@Sun.COM DLADM_OPT_PERSIST); 4469815SRishi.Srivatsavai@Sun.COM goto done; 4479815SRishi.Srivatsavai@Sun.COM } 4489815SRishi.Srivatsavai@Sun.COM done: 4499815SRishi.Srivatsavai@Sun.COM *statusp = status; 4509815SRishi.Srivatsavai@Sun.COM return (DLADM_WALK_CONTINUE); 4519815SRishi.Srivatsavai@Sun.COM } 4529815SRishi.Srivatsavai@Sun.COM 4539815SRishi.Srivatsavai@Sun.COM /* Bring up simnet instance(s) from configuration */ 4549815SRishi.Srivatsavai@Sun.COM /* ARGSUSED */ 4559815SRishi.Srivatsavai@Sun.COM dladm_status_t 4569815SRishi.Srivatsavai@Sun.COM dladm_simnet_up(dladm_handle_t handle, datalink_id_t simnet_id, 4579815SRishi.Srivatsavai@Sun.COM uint32_t flags) 4589815SRishi.Srivatsavai@Sun.COM { 4599815SRishi.Srivatsavai@Sun.COM dladm_status_t status; 4609815SRishi.Srivatsavai@Sun.COM 4619815SRishi.Srivatsavai@Sun.COM if (simnet_id == DATALINK_ALL_LINKID) { 4629815SRishi.Srivatsavai@Sun.COM (void) dladm_walk_datalink_id(i_dladm_simnet_up, handle, 4639815SRishi.Srivatsavai@Sun.COM &status, DATALINK_CLASS_SIMNET, DATALINK_ANY_MEDIATYPE, 4649815SRishi.Srivatsavai@Sun.COM DLADM_OPT_PERSIST); 4659815SRishi.Srivatsavai@Sun.COM return (DLADM_STATUS_OK); 4669815SRishi.Srivatsavai@Sun.COM } else { 4679815SRishi.Srivatsavai@Sun.COM (void) i_dladm_simnet_up(handle, simnet_id, &status); 4689815SRishi.Srivatsavai@Sun.COM return (status); 4699815SRishi.Srivatsavai@Sun.COM } 4709815SRishi.Srivatsavai@Sun.COM } 4719815SRishi.Srivatsavai@Sun.COM 4729815SRishi.Srivatsavai@Sun.COM /* Store simnet configuration */ 4739815SRishi.Srivatsavai@Sun.COM static dladm_status_t 4749815SRishi.Srivatsavai@Sun.COM dladm_simnet_persist_conf(dladm_handle_t handle, const char *name, 4759815SRishi.Srivatsavai@Sun.COM dladm_simnet_attr_t *attrp) 4769815SRishi.Srivatsavai@Sun.COM { 4779815SRishi.Srivatsavai@Sun.COM dladm_conf_t conf = DLADM_INVALID_CONF; 4789815SRishi.Srivatsavai@Sun.COM dladm_status_t status; 4799815SRishi.Srivatsavai@Sun.COM char mstr[ETHERADDRL * 3]; 4809815SRishi.Srivatsavai@Sun.COM uint64_t u64; 4819815SRishi.Srivatsavai@Sun.COM 4829815SRishi.Srivatsavai@Sun.COM if ((status = dladm_create_conf(handle, name, attrp->sna_link_id, 4839815SRishi.Srivatsavai@Sun.COM DATALINK_CLASS_SIMNET, attrp->sna_type, &conf)) != DLADM_STATUS_OK) 4849815SRishi.Srivatsavai@Sun.COM return (status); 4859815SRishi.Srivatsavai@Sun.COM 4869815SRishi.Srivatsavai@Sun.COM status = dladm_set_conf_field(handle, conf, FMACADDR, 4879815SRishi.Srivatsavai@Sun.COM DLADM_TYPE_STR, dladm_aggr_macaddr2str(attrp->sna_mac_addr, mstr)); 4889815SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 4899815SRishi.Srivatsavai@Sun.COM goto done; 4909815SRishi.Srivatsavai@Sun.COM 4919815SRishi.Srivatsavai@Sun.COM u64 = attrp->sna_type; 4929815SRishi.Srivatsavai@Sun.COM status = dladm_set_conf_field(handle, conf, FSIMNETTYPE, 4939815SRishi.Srivatsavai@Sun.COM DLADM_TYPE_UINT64, &u64); 4949815SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 4959815SRishi.Srivatsavai@Sun.COM goto done; 4969815SRishi.Srivatsavai@Sun.COM 4979815SRishi.Srivatsavai@Sun.COM u64 = attrp->sna_mac_len; 4989815SRishi.Srivatsavai@Sun.COM status = dladm_set_conf_field(handle, conf, FMADDRLEN, 4999815SRishi.Srivatsavai@Sun.COM DLADM_TYPE_UINT64, &u64); 5009815SRishi.Srivatsavai@Sun.COM if (status != DLADM_STATUS_OK) 5019815SRishi.Srivatsavai@Sun.COM goto done; 5029815SRishi.Srivatsavai@Sun.COM 5039815SRishi.Srivatsavai@Sun.COM status = dladm_write_conf(handle, conf); 5049815SRishi.Srivatsavai@Sun.COM done: 5059815SRishi.Srivatsavai@Sun.COM dladm_destroy_conf(handle, conf); 5069815SRishi.Srivatsavai@Sun.COM return (status); 5079815SRishi.Srivatsavai@Sun.COM } 508