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