12a8164dfSZhong Wang /* 22a8164dfSZhong Wang * CDDL HEADER START 32a8164dfSZhong Wang * 42a8164dfSZhong Wang * The contents of this file are subject to the terms of the 52a8164dfSZhong Wang * Common Development and Distribution License (the "License"). 62a8164dfSZhong Wang * You may not use this file except in compliance with the License. 72a8164dfSZhong Wang * 82a8164dfSZhong Wang * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 92a8164dfSZhong Wang * or http://www.opensolaris.org/os/licensing. 102a8164dfSZhong Wang * See the License for the specific language governing permissions 112a8164dfSZhong Wang * and limitations under the License. 122a8164dfSZhong Wang * 132a8164dfSZhong Wang * When distributing Covered Code, include this CDDL HEADER in each 142a8164dfSZhong Wang * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 152a8164dfSZhong Wang * If applicable, add the following below this CDDL HEADER, with the 162a8164dfSZhong Wang * fields enclosed by brackets "[]" replaced with your own identifying 172a8164dfSZhong Wang * information: Portions Copyright [yyyy] [name of copyright owner] 182a8164dfSZhong Wang * 192a8164dfSZhong Wang * CDDL HEADER END 202a8164dfSZhong Wang */ 212a8164dfSZhong Wang /* 222a8164dfSZhong Wang * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 232a8164dfSZhong Wang * Use is subject to license terms. 242a8164dfSZhong Wang */ 252a8164dfSZhong Wang 262a8164dfSZhong Wang #include "fcinfo.h" 272a8164dfSZhong Wang #include <libintl.h> 282a8164dfSZhong Wang #include <fcntl.h> 292a8164dfSZhong Wang #include <errno.h> 302a8164dfSZhong Wang #include <assert.h> 312a8164dfSZhong Wang #include <ctype.h> 322a8164dfSZhong Wang #include <sys/list.h> 332a8164dfSZhong Wang #include <stddef.h> 342a8164dfSZhong Wang #include <strings.h> 352a8164dfSZhong Wang #include <libfcoe.h> 362a8164dfSZhong Wang #include <libscf.h> 372a8164dfSZhong Wang #include <syslog.h> 382a8164dfSZhong Wang 392a8164dfSZhong Wang static const char *FCOE_DRIVER_PATH = "/devices/fcoe:admin"; 402a8164dfSZhong Wang 412a8164dfSZhong Wang static char * 422a8164dfSZhong Wang WWN2str(char *buf, FCOE_PORT_WWN *wwn) { 432a8164dfSZhong Wang int j; 442a8164dfSZhong Wang unsigned char *pc = (unsigned char *)&(wwn->wwn[0]); 452a8164dfSZhong Wang buf[0] = '\0'; 462a8164dfSZhong Wang for (j = 0; j < 16; j += 2) { 472a8164dfSZhong Wang sprintf(&buf[j], "%02X", (int)*pc++); 482a8164dfSZhong Wang } 492a8164dfSZhong Wang return (buf); 502a8164dfSZhong Wang } 512a8164dfSZhong Wang 522a8164dfSZhong Wang static int 532a8164dfSZhong Wang isValidWWN(char *wwn) 542a8164dfSZhong Wang { 552a8164dfSZhong Wang int index; 562a8164dfSZhong Wang 572a8164dfSZhong Wang if (wwn == NULL) { 582a8164dfSZhong Wang return (0); 592a8164dfSZhong Wang } 602a8164dfSZhong Wang 612a8164dfSZhong Wang if (strlen(wwn) != 16) { 622a8164dfSZhong Wang return (0); 632a8164dfSZhong Wang } 642a8164dfSZhong Wang 652a8164dfSZhong Wang for (index = 0; index < 16; index++) { 662a8164dfSZhong Wang if (isxdigit(wwn[index])) { 672a8164dfSZhong Wang continue; 682a8164dfSZhong Wang } 692a8164dfSZhong Wang return (0); 702a8164dfSZhong Wang } 712a8164dfSZhong Wang return (1); 722a8164dfSZhong Wang } 732a8164dfSZhong Wang 742a8164dfSZhong Wang static uint64_t wwnconvert(uchar_t *wwn) 752a8164dfSZhong Wang { 762a8164dfSZhong Wang uint64_t tmp; 772a8164dfSZhong Wang memcpy(&tmp, wwn, sizeof (uint64_t)); 782a8164dfSZhong Wang return (ntohll(tmp)); 792a8164dfSZhong Wang } 802a8164dfSZhong Wang 812a8164dfSZhong Wang /* 822a8164dfSZhong Wang * prints out all the HBA port information 832a8164dfSZhong Wang */ 842a8164dfSZhong Wang void 852a8164dfSZhong Wang printFCOEPortInfo(FCOE_PORT_ATTRIBUTE *attr) 862a8164dfSZhong Wang { 872a8164dfSZhong Wang int i; 882a8164dfSZhong Wang if (attr == NULL) { 892a8164dfSZhong Wang return; 902a8164dfSZhong Wang } 912a8164dfSZhong Wang fprintf(stdout, gettext("HBA Port WWN: %016llx\n"), 922a8164dfSZhong Wang wwnconvert((unsigned char *)&attr->port_wwn)); 932a8164dfSZhong Wang 942a8164dfSZhong Wang fprintf(stdout, gettext("\tPort Type: %s\n"), 952a8164dfSZhong Wang (attr->port_type == 0) ? "Initiator" : "Target"); 962a8164dfSZhong Wang 972a8164dfSZhong Wang fprintf(stdout, gettext("\tMAC Name: %s\n"), attr->mac_link_name); 982a8164dfSZhong Wang 992a8164dfSZhong Wang fprintf(stdout, gettext("\tMTU Size: %d\n"), attr->mtu_size); 1002a8164dfSZhong Wang 1012a8164dfSZhong Wang fprintf(stdout, gettext("\tMAC Factory Address: ")); 1022a8164dfSZhong Wang for (i = 0; i < 6; i++) { 1032a8164dfSZhong Wang fprintf(stdout, gettext("%02x"), attr->mac_factory_addr[i]); 1042a8164dfSZhong Wang } 1052a8164dfSZhong Wang fprintf(stdout, gettext("\n\tMAC Current Address: ")); 1062a8164dfSZhong Wang for (i = 0; i < 6; i++) { 1072a8164dfSZhong Wang fprintf(stdout, gettext("%02x"), attr->mac_current_addr[i]); 1082a8164dfSZhong Wang } 1092a8164dfSZhong Wang fprintf(stdout, gettext("\n\tPromiscuous Mode: %s\n"), 1102a8164dfSZhong Wang attr->mac_promisc == 1 ? "On" : "Off"); 1112a8164dfSZhong Wang } 1122a8164dfSZhong Wang 1132a8164dfSZhong Wang /* 1142a8164dfSZhong Wang * Initialize scf fcoe service access 1152a8164dfSZhong Wang * handle - returned handle 1162a8164dfSZhong Wang * service - returned service handle 1172a8164dfSZhong Wang */ 1182a8164dfSZhong Wang static int 1192a8164dfSZhong Wang fcoe_cfg_scf_init(scf_handle_t **handle, scf_service_t **service) 1202a8164dfSZhong Wang { 1212a8164dfSZhong Wang scf_scope_t *scope = NULL; 1222a8164dfSZhong Wang int ret; 1232a8164dfSZhong Wang 1242a8164dfSZhong Wang if ((*handle = scf_handle_create(SCF_VERSION)) == NULL) { 1252a8164dfSZhong Wang syslog(LOG_ERR, "scf_handle_create failed - %s", 1262a8164dfSZhong Wang scf_strerror(scf_error())); 1272a8164dfSZhong Wang ret = FCOE_ERROR; 1282a8164dfSZhong Wang goto err; 1292a8164dfSZhong Wang } 1302a8164dfSZhong Wang 1312a8164dfSZhong Wang if (scf_handle_bind(*handle) == -1) { 1322a8164dfSZhong Wang syslog(LOG_ERR, "scf_handle_bind failed - %s", 1332a8164dfSZhong Wang scf_strerror(scf_error())); 1342a8164dfSZhong Wang ret = FCOE_ERROR; 1352a8164dfSZhong Wang goto err; 1362a8164dfSZhong Wang } 1372a8164dfSZhong Wang 1382a8164dfSZhong Wang if ((*service = scf_service_create(*handle)) == NULL) { 1392a8164dfSZhong Wang syslog(LOG_ERR, "scf_service_create failed - %s", 1402a8164dfSZhong Wang scf_strerror(scf_error())); 1412a8164dfSZhong Wang ret = FCOE_ERROR; 1422a8164dfSZhong Wang goto err; 1432a8164dfSZhong Wang } 1442a8164dfSZhong Wang 1452a8164dfSZhong Wang if ((scope = scf_scope_create(*handle)) == NULL) { 1462a8164dfSZhong Wang syslog(LOG_ERR, "scf_scope_create failed - %s", 1472a8164dfSZhong Wang scf_strerror(scf_error())); 1482a8164dfSZhong Wang ret = FCOE_ERROR; 1492a8164dfSZhong Wang goto err; 1502a8164dfSZhong Wang } 1512a8164dfSZhong Wang 1522a8164dfSZhong Wang if (scf_handle_get_scope(*handle, SCF_SCOPE_LOCAL, scope) == -1) { 1532a8164dfSZhong Wang syslog(LOG_ERR, "scf_handle_get_scope failed - %s", 1542a8164dfSZhong Wang scf_strerror(scf_error())); 1552a8164dfSZhong Wang ret = FCOE_ERROR; 1562a8164dfSZhong Wang goto err; 1572a8164dfSZhong Wang } 1582a8164dfSZhong Wang 1592a8164dfSZhong Wang if (scf_scope_get_service(scope, FCOE_SERVICE, *service) == -1) { 1602a8164dfSZhong Wang syslog(LOG_ERR, "scf_scope_get_service failed - %s", 1612a8164dfSZhong Wang scf_strerror(scf_error())); 1622a8164dfSZhong Wang ret = FCOE_ERROR_SERVICE_NOT_FOUND; 1632a8164dfSZhong Wang goto err; 1642a8164dfSZhong Wang } 1652a8164dfSZhong Wang 1662a8164dfSZhong Wang scf_scope_destroy(scope); 1672a8164dfSZhong Wang 1682a8164dfSZhong Wang return (FCOE_SUCCESS); 1692a8164dfSZhong Wang 1702a8164dfSZhong Wang err: 1712a8164dfSZhong Wang if (*handle != NULL) { 1722a8164dfSZhong Wang scf_handle_destroy(*handle); 1732a8164dfSZhong Wang } 1742a8164dfSZhong Wang if (*service != NULL) { 1752a8164dfSZhong Wang scf_service_destroy(*service); 1762a8164dfSZhong Wang *service = NULL; 1772a8164dfSZhong Wang } 1782a8164dfSZhong Wang if (scope != NULL) { 1792a8164dfSZhong Wang scf_scope_destroy(scope); 1802a8164dfSZhong Wang } 1812a8164dfSZhong Wang return (ret); 1822a8164dfSZhong Wang } 1832a8164dfSZhong Wang 1842a8164dfSZhong Wang 1852a8164dfSZhong Wang static int 1862a8164dfSZhong Wang fcoe_adm_add_remove_scf_entry(char *mac_name, 1872a8164dfSZhong Wang char *pwwn, char *nwwn, 1882a8164dfSZhong Wang int is_target, int is_promiscuous, int addRemoveFlag) 1892a8164dfSZhong Wang { 1902a8164dfSZhong Wang scf_handle_t *handle = NULL; 1912a8164dfSZhong Wang scf_service_t *svc = NULL; 1922a8164dfSZhong Wang scf_propertygroup_t *pg = NULL; 1932a8164dfSZhong Wang scf_transaction_t *tran = NULL; 1942a8164dfSZhong Wang scf_transaction_entry_t *entry = NULL; 1952a8164dfSZhong Wang scf_property_t *prop = NULL; 1962a8164dfSZhong Wang scf_value_t *valueLookup = NULL; 1972a8164dfSZhong Wang scf_iter_t *valueIter = NULL; 1982a8164dfSZhong Wang scf_value_t **valueSet = NULL; 1992a8164dfSZhong Wang int ret = FCOE_SUCCESS; 2002a8164dfSZhong Wang boolean_t createProp = B_FALSE; 2012a8164dfSZhong Wang int lastAlloc = 0; 2022a8164dfSZhong Wang char buf[FCOE_PORT_LIST_LENGTH] = {0}; 2032a8164dfSZhong Wang char memberName[FCOE_PORT_LIST_LENGTH] = {0}; 2042a8164dfSZhong Wang boolean_t found = B_FALSE; 2052a8164dfSZhong Wang int i = 0; 2062a8164dfSZhong Wang int valueArraySize = 0; 2072a8164dfSZhong Wang int commitRet; 2082a8164dfSZhong Wang 2092a8164dfSZhong Wang sprintf(memberName, "%s:%s:%s:%d:%d", mac_name, pwwn, nwwn, 2102a8164dfSZhong Wang is_target, is_promiscuous); 2112a8164dfSZhong Wang 2122a8164dfSZhong Wang ret = fcoe_cfg_scf_init(&handle, &svc); 2132a8164dfSZhong Wang if (ret != FCOE_SUCCESS) { 2142a8164dfSZhong Wang goto out; 2152a8164dfSZhong Wang } 2162a8164dfSZhong Wang 2172a8164dfSZhong Wang if (((pg = scf_pg_create(handle)) == NULL) || 2182a8164dfSZhong Wang ((tran = scf_transaction_create(handle)) == NULL) || 2192a8164dfSZhong Wang ((entry = scf_entry_create(handle)) == NULL) || 2202a8164dfSZhong Wang ((prop = scf_property_create(handle)) == NULL) || 2212a8164dfSZhong Wang ((valueIter = scf_iter_create(handle)) == NULL)) { 2222a8164dfSZhong Wang ret = FCOE_ERROR; 2232a8164dfSZhong Wang goto out; 2242a8164dfSZhong Wang } 2252a8164dfSZhong Wang 2262a8164dfSZhong Wang /* get property group or create it */ 2272a8164dfSZhong Wang if (scf_service_get_pg(svc, FCOE_PG_NAME, pg) == -1) { 2282a8164dfSZhong Wang if ((scf_error() == SCF_ERROR_NOT_FOUND)) { 2292a8164dfSZhong Wang if (scf_service_add_pg(svc, FCOE_PG_NAME, 2302a8164dfSZhong Wang SCF_GROUP_APPLICATION, 0, pg) == -1) { 2312a8164dfSZhong Wang syslog(LOG_ERR, "add pg failed - %s", 2322a8164dfSZhong Wang scf_strerror(scf_error())); 2332a8164dfSZhong Wang ret = FCOE_ERROR; 2342a8164dfSZhong Wang } else { 2352a8164dfSZhong Wang createProp = B_TRUE; 2362a8164dfSZhong Wang } 2372a8164dfSZhong Wang } else { 2382a8164dfSZhong Wang syslog(LOG_ERR, "get pg failed - %s", 2392a8164dfSZhong Wang scf_strerror(scf_error())); 2402a8164dfSZhong Wang ret = FCOE_ERROR; 2412a8164dfSZhong Wang } 2422a8164dfSZhong Wang if (ret != FCOE_SUCCESS) { 2432a8164dfSZhong Wang goto out; 2442a8164dfSZhong Wang } 2452a8164dfSZhong Wang } 2462a8164dfSZhong Wang 2472a8164dfSZhong Wang /* to make sure property exists */ 2482a8164dfSZhong Wang if (createProp == B_FALSE) { 2492a8164dfSZhong Wang if (scf_pg_get_property(pg, FCOE_PORT_LIST, prop) == -1) { 2502a8164dfSZhong Wang if ((scf_error() == SCF_ERROR_NOT_FOUND)) { 2512a8164dfSZhong Wang createProp = B_TRUE; 2522a8164dfSZhong Wang } else { 2532a8164dfSZhong Wang syslog(LOG_ERR, "get property failed - %s", 2542a8164dfSZhong Wang scf_strerror(scf_error())); 2552a8164dfSZhong Wang ret = FCOE_ERROR; 2562a8164dfSZhong Wang goto out; 2572a8164dfSZhong Wang } 2582a8164dfSZhong Wang } 2592a8164dfSZhong Wang } 2602a8164dfSZhong Wang 2612a8164dfSZhong Wang /* Begin the transaction */ 2622a8164dfSZhong Wang if (scf_transaction_start(tran, pg) == -1) { 2632a8164dfSZhong Wang syslog(LOG_ERR, "start transaction failed - %s", 2642a8164dfSZhong Wang scf_strerror(scf_error())); 2652a8164dfSZhong Wang ret = FCOE_ERROR; 2662a8164dfSZhong Wang goto out; 2672a8164dfSZhong Wang } 2682a8164dfSZhong Wang 2692a8164dfSZhong Wang valueSet = (scf_value_t **)calloc(1, sizeof (*valueSet) 2702a8164dfSZhong Wang * (lastAlloc = PORT_LIST_ALLOC)); 2712a8164dfSZhong Wang if (valueSet == NULL) { 2722a8164dfSZhong Wang ret = FCOE_ERROR_NOMEM; 2732a8164dfSZhong Wang goto out; 2742a8164dfSZhong Wang } 2752a8164dfSZhong Wang 2762a8164dfSZhong Wang if (createProp) { 2772a8164dfSZhong Wang if (scf_transaction_property_new(tran, entry, FCOE_PORT_LIST, 2782a8164dfSZhong Wang SCF_TYPE_USTRING) == -1) { 2792a8164dfSZhong Wang if (scf_error() == SCF_ERROR_EXISTS) { 2802a8164dfSZhong Wang ret = FCOE_ERROR_EXISTS; 2812a8164dfSZhong Wang } else { 2822a8164dfSZhong Wang syslog(LOG_ERR, 2832a8164dfSZhong Wang "transaction property new failed - %s", 2842a8164dfSZhong Wang scf_strerror(scf_error())); 2852a8164dfSZhong Wang ret = FCOE_ERROR; 2862a8164dfSZhong Wang } 2872a8164dfSZhong Wang goto out; 2882a8164dfSZhong Wang } 2892a8164dfSZhong Wang } else { 2902a8164dfSZhong Wang if (scf_transaction_property_change(tran, entry, 2912a8164dfSZhong Wang FCOE_PORT_LIST, SCF_TYPE_USTRING) == -1) { 2922a8164dfSZhong Wang syslog(LOG_ERR, 2932a8164dfSZhong Wang "transaction property change failed - %s", 2942a8164dfSZhong Wang scf_strerror(scf_error())); 2952a8164dfSZhong Wang ret = FCOE_ERROR; 2962a8164dfSZhong Wang goto out; 2972a8164dfSZhong Wang } 2982a8164dfSZhong Wang 2992a8164dfSZhong Wang if (scf_pg_get_property(pg, FCOE_PORT_LIST, prop) == -1) { 3002a8164dfSZhong Wang syslog(LOG_ERR, "get property failed - %s", 3012a8164dfSZhong Wang scf_strerror(scf_error())); 3022a8164dfSZhong Wang ret = FCOE_ERROR; 3032a8164dfSZhong Wang goto out; 3042a8164dfSZhong Wang } 3052a8164dfSZhong Wang 3062a8164dfSZhong Wang valueLookup = scf_value_create(handle); 3072a8164dfSZhong Wang if (valueLookup == NULL) { 3082a8164dfSZhong Wang syslog(LOG_ERR, "scf value alloc failed - %s", 3092a8164dfSZhong Wang scf_strerror(scf_error())); 3102a8164dfSZhong Wang ret = FCOE_ERROR; 3112a8164dfSZhong Wang goto out; 3122a8164dfSZhong Wang } 3132a8164dfSZhong Wang 3142a8164dfSZhong Wang if (scf_iter_property_values(valueIter, prop) == -1) { 3152a8164dfSZhong Wang syslog(LOG_ERR, "iter value failed - %s", 3162a8164dfSZhong Wang scf_strerror(scf_error())); 3172a8164dfSZhong Wang ret = FCOE_ERROR; 3182a8164dfSZhong Wang goto out; 3192a8164dfSZhong Wang } 3202a8164dfSZhong Wang 3212a8164dfSZhong Wang while (scf_iter_next_value(valueIter, valueLookup) == 1) { 3222a8164dfSZhong Wang char *macnameIter = NULL; 3232a8164dfSZhong Wang char buftmp[FCOE_PORT_LIST_LENGTH] = {0}; 3242a8164dfSZhong Wang 3252a8164dfSZhong Wang bzero(buf, sizeof (buf)); 3262a8164dfSZhong Wang if (scf_value_get_ustring(valueLookup, 3272a8164dfSZhong Wang buf, MAXNAMELEN) == -1) { 3282a8164dfSZhong Wang syslog(LOG_ERR, "iter value failed- %s", 3292a8164dfSZhong Wang scf_strerror(scf_error())); 3302a8164dfSZhong Wang ret = FCOE_ERROR; 3312a8164dfSZhong Wang break; 3322a8164dfSZhong Wang } 3332a8164dfSZhong Wang strcpy(buftmp, buf); 3342a8164dfSZhong Wang macnameIter = strtok(buftmp, ":"); 3352a8164dfSZhong Wang if (bcmp(macnameIter, mac_name, 3362a8164dfSZhong Wang strlen(mac_name)) == 0) { 3372a8164dfSZhong Wang if (addRemoveFlag == FCOE_SCF_ADD) { 3382a8164dfSZhong Wang ret = FCOE_ERROR_EXISTS; 3392a8164dfSZhong Wang break; 3402a8164dfSZhong Wang } else { 3412a8164dfSZhong Wang found = B_TRUE; 3422a8164dfSZhong Wang continue; 3432a8164dfSZhong Wang } 3442a8164dfSZhong Wang } 3452a8164dfSZhong Wang 3462a8164dfSZhong Wang valueSet[i] = scf_value_create(handle); 3472a8164dfSZhong Wang if (valueSet[i] == NULL) { 3482a8164dfSZhong Wang syslog(LOG_ERR, "scf value alloc failed - %s", 3492a8164dfSZhong Wang scf_strerror(scf_error())); 3502a8164dfSZhong Wang ret = FCOE_ERROR; 3512a8164dfSZhong Wang break; 3522a8164dfSZhong Wang } 3532a8164dfSZhong Wang 3542a8164dfSZhong Wang if (scf_value_set_ustring(valueSet[i], buf) == -1) { 3552a8164dfSZhong Wang syslog(LOG_ERR, "set value failed 1- %s", 3562a8164dfSZhong Wang scf_strerror(scf_error())); 3572a8164dfSZhong Wang ret = FCOE_ERROR; 3582a8164dfSZhong Wang break; 3592a8164dfSZhong Wang } 3602a8164dfSZhong Wang 3612a8164dfSZhong Wang if (scf_entry_add_value(entry, valueSet[i]) == -1) { 3622a8164dfSZhong Wang syslog(LOG_ERR, "add value failed - %s", 3632a8164dfSZhong Wang scf_strerror(scf_error())); 3642a8164dfSZhong Wang ret = FCOE_ERROR; 3652a8164dfSZhong Wang break; 3662a8164dfSZhong Wang } 3672a8164dfSZhong Wang 3682a8164dfSZhong Wang i++; 3692a8164dfSZhong Wang 3702a8164dfSZhong Wang if (i >= lastAlloc) { 3712a8164dfSZhong Wang lastAlloc += PORT_LIST_ALLOC; 3722a8164dfSZhong Wang valueSet = realloc(valueSet, 3732a8164dfSZhong Wang sizeof (*valueSet) * lastAlloc); 3742a8164dfSZhong Wang if (valueSet == NULL) { 3752a8164dfSZhong Wang ret = FCOE_ERROR; 3762a8164dfSZhong Wang break; 3772a8164dfSZhong Wang } 3782a8164dfSZhong Wang } 3792a8164dfSZhong Wang } 3802a8164dfSZhong Wang } 3812a8164dfSZhong Wang 3822a8164dfSZhong Wang valueArraySize = i; 3832a8164dfSZhong Wang if (!found && (addRemoveFlag == FCOE_SCF_REMOVE)) { 3842a8164dfSZhong Wang ret = FCOE_ERROR_MEMBER_NOT_FOUND; 3852a8164dfSZhong Wang } 3862a8164dfSZhong Wang if (ret != FCOE_SUCCESS) { 3872a8164dfSZhong Wang goto out; 3882a8164dfSZhong Wang } 3892a8164dfSZhong Wang 3902a8164dfSZhong Wang if (addRemoveFlag == FCOE_SCF_ADD) { 3912a8164dfSZhong Wang /* 3922a8164dfSZhong Wang * Now create the new entry 3932a8164dfSZhong Wang */ 3942a8164dfSZhong Wang valueSet[i] = scf_value_create(handle); 3952a8164dfSZhong Wang if (valueSet[i] == NULL) { 3962a8164dfSZhong Wang syslog(LOG_ERR, "scf value alloc failed - %s", 3972a8164dfSZhong Wang scf_strerror(scf_error())); 3982a8164dfSZhong Wang ret = FCOE_ERROR; 3992a8164dfSZhong Wang goto out; 4002a8164dfSZhong Wang } else { 4012a8164dfSZhong Wang valueArraySize++; 4022a8164dfSZhong Wang } 4032a8164dfSZhong Wang 4042a8164dfSZhong Wang /* 4052a8164dfSZhong Wang * Set the new member name 4062a8164dfSZhong Wang */ 4072a8164dfSZhong Wang if (scf_value_set_ustring(valueSet[i], memberName) == -1) { 4082a8164dfSZhong Wang syslog(LOG_ERR, "set value failed 2- %s", 4092a8164dfSZhong Wang scf_strerror(scf_error())); 4102a8164dfSZhong Wang ret = FCOE_ERROR; 4112a8164dfSZhong Wang goto out; 4122a8164dfSZhong Wang } 4132a8164dfSZhong Wang 4142a8164dfSZhong Wang /* 4152a8164dfSZhong Wang * Add the new member 4162a8164dfSZhong Wang */ 4172a8164dfSZhong Wang if (scf_entry_add_value(entry, valueSet[i]) == -1) { 4182a8164dfSZhong Wang syslog(LOG_ERR, "add value failed - %s", 4192a8164dfSZhong Wang scf_strerror(scf_error())); 4202a8164dfSZhong Wang ret = FCOE_ERROR; 4212a8164dfSZhong Wang goto out; 4222a8164dfSZhong Wang } 4232a8164dfSZhong Wang } 4242a8164dfSZhong Wang 4252a8164dfSZhong Wang if ((commitRet = scf_transaction_commit(tran)) != 1) { 4262a8164dfSZhong Wang syslog(LOG_ERR, "transaction commit failed - %s", 4272a8164dfSZhong Wang scf_strerror(scf_error())); 4282a8164dfSZhong Wang if (commitRet == 0) { 4292a8164dfSZhong Wang ret = FCOE_ERROR_BUSY; 4302a8164dfSZhong Wang } else { 4312a8164dfSZhong Wang ret = FCOE_ERROR; 4322a8164dfSZhong Wang } 4332a8164dfSZhong Wang goto out; 4342a8164dfSZhong Wang } 4352a8164dfSZhong Wang 4362a8164dfSZhong Wang out: 4372a8164dfSZhong Wang /* 4382a8164dfSZhong Wang * Free resources 4392a8164dfSZhong Wang */ 4402a8164dfSZhong Wang if (handle != NULL) { 4412a8164dfSZhong Wang scf_handle_destroy(handle); 4422a8164dfSZhong Wang } 4432a8164dfSZhong Wang if (svc != NULL) { 4442a8164dfSZhong Wang scf_service_destroy(svc); 4452a8164dfSZhong Wang } 4462a8164dfSZhong Wang if (pg != NULL) { 4472a8164dfSZhong Wang scf_pg_destroy(pg); 4482a8164dfSZhong Wang } 4492a8164dfSZhong Wang if (tran != NULL) { 4502a8164dfSZhong Wang scf_transaction_destroy(tran); 4512a8164dfSZhong Wang } 4522a8164dfSZhong Wang if (entry != NULL) { 4532a8164dfSZhong Wang scf_entry_destroy(entry); 4542a8164dfSZhong Wang } 4552a8164dfSZhong Wang if (prop != NULL) { 4562a8164dfSZhong Wang scf_property_destroy(prop); 4572a8164dfSZhong Wang } 4582a8164dfSZhong Wang if (valueIter != NULL) { 4592a8164dfSZhong Wang scf_iter_destroy(valueIter); 4602a8164dfSZhong Wang } 4612a8164dfSZhong Wang if (valueLookup != NULL) { 4622a8164dfSZhong Wang scf_value_destroy(valueLookup); 4632a8164dfSZhong Wang } 4642a8164dfSZhong Wang 4652a8164dfSZhong Wang /* 4662a8164dfSZhong Wang * Free valueSet scf resources 4672a8164dfSZhong Wang */ 4682a8164dfSZhong Wang if (valueArraySize > 0) { 4692a8164dfSZhong Wang for (i = 0; i < valueArraySize; i++) { 4702a8164dfSZhong Wang scf_value_destroy(valueSet[i]); 4712a8164dfSZhong Wang } 4722a8164dfSZhong Wang } 4732a8164dfSZhong Wang /* 4742a8164dfSZhong Wang * Now free the pointer array to the resources 4752a8164dfSZhong Wang */ 4762a8164dfSZhong Wang if (valueSet != NULL) { 4772a8164dfSZhong Wang free(valueSet); 4782a8164dfSZhong Wang } 4792a8164dfSZhong Wang 4802a8164dfSZhong Wang return (ret); 4812a8164dfSZhong Wang } 4822a8164dfSZhong Wang 4832a8164dfSZhong Wang int 4842a8164dfSZhong Wang fcoe_adm_create_port(int objects, char *argv[], 4852a8164dfSZhong Wang cmdOptions_t *options) 4862a8164dfSZhong Wang { 4872a8164dfSZhong Wang FCOE_STATUS status = FCOE_STATUS_OK; 4882a8164dfSZhong Wang uint64_t nodeWWN, portWWN; 4892a8164dfSZhong Wang FCOE_PORT_WWN pwwn, nwwn; 4902a8164dfSZhong Wang FCOE_UINT8 macLinkName[FCOE_MAX_MAC_NAME_LEN]; 4912a8164dfSZhong Wang FCOE_UINT8 promiscuous = 0; 4922a8164dfSZhong Wang int createini = 0, createtgt = 0; 4932a8164dfSZhong Wang 4942a8164dfSZhong Wang /* check the mac name operand */ 4952a8164dfSZhong Wang assert(objects == 1); 4962a8164dfSZhong Wang 4972a8164dfSZhong Wang strcpy((char *)macLinkName, argv[0]); 4982a8164dfSZhong Wang bzero(&pwwn, 8); 4992a8164dfSZhong Wang bzero(&nwwn, 8); 5002a8164dfSZhong Wang 5012a8164dfSZhong Wang for (; options->optval; options++) { 5022a8164dfSZhong Wang switch (options->optval) { 5032a8164dfSZhong Wang case 'i': 5042a8164dfSZhong Wang createini = 1; 5052a8164dfSZhong Wang break; 5062a8164dfSZhong Wang 5072a8164dfSZhong Wang case 't': 5082a8164dfSZhong Wang createtgt = 1; 5092a8164dfSZhong Wang break; 5102a8164dfSZhong Wang case 'p': 5112a8164dfSZhong Wang if (!isValidWWN(options->optarg)) { 5122a8164dfSZhong Wang fprintf(stderr, 5132a8164dfSZhong Wang gettext("Error: Invalid Port WWN\n")); 5142a8164dfSZhong Wang return (1); 5152a8164dfSZhong Wang } 5162a8164dfSZhong Wang sscanf(options->optarg, "%016llx", &portWWN); 5172a8164dfSZhong Wang portWWN = htonll(portWWN); 5182a8164dfSZhong Wang memcpy(&pwwn, &portWWN, sizeof (portWWN)); 5192a8164dfSZhong Wang break; 5202a8164dfSZhong Wang 5212a8164dfSZhong Wang case 'n': 5222a8164dfSZhong Wang if (!isValidWWN(options->optarg)) { 5232a8164dfSZhong Wang fprintf(stderr, 5242a8164dfSZhong Wang gettext("Error: Invalid Node WWN\n")); 5252a8164dfSZhong Wang return (1); 5262a8164dfSZhong Wang } 5272a8164dfSZhong Wang sscanf(options->optarg, "%016llx", &nodeWWN); 5282a8164dfSZhong Wang nodeWWN = htonll(nodeWWN); 5292a8164dfSZhong Wang memcpy(&nwwn, &nodeWWN, sizeof (nodeWWN)); 5302a8164dfSZhong Wang break; 5312a8164dfSZhong Wang case 'f': 5322a8164dfSZhong Wang promiscuous = 1; 5332a8164dfSZhong Wang break; 5342a8164dfSZhong Wang 5352a8164dfSZhong Wang default: 5362a8164dfSZhong Wang fprintf(stderr, gettext("Error: Illegal option: %c\n"), 5372a8164dfSZhong Wang options->optval); 5382a8164dfSZhong Wang return (1); 5392a8164dfSZhong Wang } 5402a8164dfSZhong Wang } 5412a8164dfSZhong Wang 5422a8164dfSZhong Wang if (createini == 1 && createtgt == 1) { 5432a8164dfSZhong Wang fprintf(stderr, "Error: Option -i and -t should " 5442a8164dfSZhong Wang "not be both specified\n"); 5452a8164dfSZhong Wang return (1); 5462a8164dfSZhong Wang } 5472a8164dfSZhong Wang status = FCOE_CreatePort(macLinkName, 5482a8164dfSZhong Wang createtgt == 1 ? FCOE_PORTTYPE_TARGET : 5492a8164dfSZhong Wang FCOE_PORTTYPE_INITIATOR, pwwn, nwwn, promiscuous); 5502a8164dfSZhong Wang 5512a8164dfSZhong Wang if (status != FCOE_STATUS_OK) { 5522a8164dfSZhong Wang switch (status) { 5532a8164dfSZhong Wang case FCOE_STATUS_ERROR_BUSY: 5542a8164dfSZhong Wang fprintf(stderr, 5552a8164dfSZhong Wang gettext("Error: fcoe driver is busy\n")); 5562a8164dfSZhong Wang break; 5572a8164dfSZhong Wang 5582a8164dfSZhong Wang case FCOE_STATUS_ERROR_ALREADY: 5592a8164dfSZhong Wang fprintf(stderr, 5602a8164dfSZhong Wang gettext("Error: Existing FCoE port " 5612a8164dfSZhong Wang "found on the specified MAC link\n")); 5622a8164dfSZhong Wang break; 5632a8164dfSZhong Wang 5642a8164dfSZhong Wang case FCOE_STATUS_ERROR_PERM: 5652a8164dfSZhong Wang fprintf(stderr, 5662a8164dfSZhong Wang gettext("Error: Not enough permission to " 5672a8164dfSZhong Wang "open fcoe device\n")); 5682a8164dfSZhong Wang break; 5692a8164dfSZhong Wang 5702a8164dfSZhong Wang case FCOE_STATUS_ERROR_OPEN_DEV: 5712a8164dfSZhong Wang fprintf(stderr, 5722a8164dfSZhong Wang gettext("Error: Failed to open fcoe device\n")); 5732a8164dfSZhong Wang break; 5742a8164dfSZhong Wang 5752a8164dfSZhong Wang case FCOE_STATUS_ERROR_WWN_SAME: 5762a8164dfSZhong Wang fprintf(stderr, 5772a8164dfSZhong Wang gettext("Error: Port WWN is same as Node " 5782a8164dfSZhong Wang "WWN\n")); 5792a8164dfSZhong Wang break; 5802a8164dfSZhong Wang 5812a8164dfSZhong Wang case FCOE_STATUS_ERROR_MAC_LEN: 5822a8164dfSZhong Wang fprintf(stderr, 5832a8164dfSZhong Wang gettext("Error: MAC name exceeds maximum " 5842a8164dfSZhong Wang "length\n")); 5852a8164dfSZhong Wang break; 5862a8164dfSZhong Wang 5872a8164dfSZhong Wang case FCOE_STATUS_ERROR_PWWN_CONFLICTED: 5882a8164dfSZhong Wang fprintf(stderr, 5892a8164dfSZhong Wang gettext("Error: The specified Port WWN " 5902a8164dfSZhong Wang "is already in use\n")); 5912a8164dfSZhong Wang break; 5922a8164dfSZhong Wang 5932a8164dfSZhong Wang case FCOE_STATUS_ERROR_NWWN_CONFLICTED: 5942a8164dfSZhong Wang fprintf(stderr, 5952a8164dfSZhong Wang gettext("Error: The specified Node WWN " 5962a8164dfSZhong Wang "is already in use\n")); 5972a8164dfSZhong Wang break; 5982a8164dfSZhong Wang 5992a8164dfSZhong Wang case FCOE_STATUS_ERROR_NEED_JUMBO_FRAME: 6002a8164dfSZhong Wang fprintf(stderr, 6012a8164dfSZhong Wang gettext("Error: MTU size of the specified " 6022a8164dfSZhong Wang "MAC link needs to be increased to 2500 " 6032a8164dfSZhong Wang "or above\n")); 6042a8164dfSZhong Wang break; 6052a8164dfSZhong Wang 6062a8164dfSZhong Wang case FCOE_STATUS_ERROR_CREATE_MAC: 6072a8164dfSZhong Wang fprintf(stderr, 6082a8164dfSZhong Wang gettext("Error: Out of memory\n")); 6092a8164dfSZhong Wang break; 6102a8164dfSZhong Wang 6112a8164dfSZhong Wang 6122a8164dfSZhong Wang case FCOE_STATUS_ERROR_OPEN_MAC: 6132a8164dfSZhong Wang fprintf(stderr, 6142a8164dfSZhong Wang gettext("Error: Failed to open the " 6152a8164dfSZhong Wang "specified MAC link\n")); 6162a8164dfSZhong Wang break; 6172a8164dfSZhong Wang 6182a8164dfSZhong Wang case FCOE_STATUS_ERROR_CREATE_PORT: 6192a8164dfSZhong Wang fprintf(stderr, 6202a8164dfSZhong Wang gettext("Error: Failed to create FCoE " 6212a8164dfSZhong Wang "port on the specified MAC link\n")); 6222a8164dfSZhong Wang break; 6232a8164dfSZhong Wang 624*d4401b99SKelly Hu case FCOE_STATUS_ERROR_CLASS_UNSUPPORT: 6252a8164dfSZhong Wang fprintf(stderr, 626*d4401b99SKelly Hu gettext("Error: Link class other than physical " 627*d4401b99SKelly Hu "link is not supported\n")); 628*d4401b99SKelly Hu break; 629*d4401b99SKelly Hu 630*d4401b99SKelly Hu case FCOE_STATUS_ERROR_GET_LINKINFO: 631*d4401b99SKelly Hu fprintf(stderr, 632*d4401b99SKelly Hu gettext("Error: Failed to get link infomation " 633*d4401b99SKelly Hu "for %s\n"), macLinkName); 6342a8164dfSZhong Wang break; 6352a8164dfSZhong Wang 6362a8164dfSZhong Wang case FCOE_STATUS_ERROR: 6372a8164dfSZhong Wang default: 6382a8164dfSZhong Wang fprintf(stderr, 6392a8164dfSZhong Wang gettext("Error: Due to reason code %d\n"), status); 6402a8164dfSZhong Wang } 6412a8164dfSZhong Wang return (1); 6422a8164dfSZhong Wang } else { 6432a8164dfSZhong Wang char cpwwn[17], cnwwn[17]; 6442a8164dfSZhong Wang 6452a8164dfSZhong Wang WWN2str(cpwwn, &pwwn); 6462a8164dfSZhong Wang WWN2str(cnwwn, &nwwn); 6472a8164dfSZhong Wang 6482a8164dfSZhong Wang fcoe_adm_add_remove_scf_entry((char *)macLinkName, 6492a8164dfSZhong Wang cpwwn, 6502a8164dfSZhong Wang cnwwn, 6512a8164dfSZhong Wang createtgt, 6522a8164dfSZhong Wang promiscuous, 6532a8164dfSZhong Wang FCOE_SCF_ADD); 6542a8164dfSZhong Wang return (0); 6552a8164dfSZhong Wang } 6562a8164dfSZhong Wang } 6572a8164dfSZhong Wang 6582a8164dfSZhong Wang int 6592a8164dfSZhong Wang fcoe_adm_delete_port(int objects, char *argv[]) 6602a8164dfSZhong Wang { 6612a8164dfSZhong Wang FCOE_STATUS status; 6622a8164dfSZhong Wang FCOE_UINT8 *macLinkName; 6632a8164dfSZhong Wang 6642a8164dfSZhong Wang /* check the mac name operand */ 6652a8164dfSZhong Wang assert(objects == 1); 6662a8164dfSZhong Wang 6672a8164dfSZhong Wang macLinkName = (FCOE_UINT8 *) argv[0]; 6682a8164dfSZhong Wang 6692a8164dfSZhong Wang status = FCOE_DeletePort(macLinkName); 6702a8164dfSZhong Wang if (status != FCOE_STATUS_OK) { 6712a8164dfSZhong Wang switch (status) { 6722a8164dfSZhong Wang case FCOE_STATUS_ERROR_BUSY: 6732a8164dfSZhong Wang fprintf(stderr, 6742a8164dfSZhong Wang gettext("Error: fcoe driver is busy\n")); 6752a8164dfSZhong Wang break; 6762a8164dfSZhong Wang 6772a8164dfSZhong Wang case FCOE_STATUS_ERROR_ALREADY: 6782a8164dfSZhong Wang fprintf(stderr, 6792a8164dfSZhong Wang gettext("Error: FCoE port not found on the " 6802a8164dfSZhong Wang "specified MAC link\n")); 6812a8164dfSZhong Wang break; 6822a8164dfSZhong Wang 6832a8164dfSZhong Wang case FCOE_STATUS_ERROR_PERM: 6842a8164dfSZhong Wang fprintf(stderr, 6852a8164dfSZhong Wang gettext("Error: Not enough permission to " 6862a8164dfSZhong Wang "open fcoe device\n")); 6872a8164dfSZhong Wang break; 6882a8164dfSZhong Wang 6892a8164dfSZhong Wang case FCOE_STATUS_ERROR_MAC_LEN: 6902a8164dfSZhong Wang fprintf(stderr, 6912a8164dfSZhong Wang gettext("Failed: MAC name exceeds maximum " 6922a8164dfSZhong Wang "length 32\n")); 6932a8164dfSZhong Wang break; 6942a8164dfSZhong Wang 6952a8164dfSZhong Wang case FCOE_STATUS_ERROR_OPEN_DEV: 6962a8164dfSZhong Wang fprintf(stderr, 6972a8164dfSZhong Wang gettext("Error: Failed to open fcoe device\n")); 6982a8164dfSZhong Wang break; 6992a8164dfSZhong Wang 7002a8164dfSZhong Wang case FCOE_STATUS_ERROR_MAC_NOT_FOUND: 7012a8164dfSZhong Wang fprintf(stderr, 7022a8164dfSZhong Wang gettext("Error: FCoE port not found on the " 7032a8164dfSZhong Wang "specified MAC link\n")); 7042a8164dfSZhong Wang break; 7052a8164dfSZhong Wang 7062a8164dfSZhong Wang case FCOE_STATUS_ERROR_OFFLINE_DEV: 7072a8164dfSZhong Wang fprintf(stderr, 7082a8164dfSZhong Wang gettext("Error: Please use stmfadm to offline " 7092a8164dfSZhong Wang "the FCoE target first\n")); 7102a8164dfSZhong Wang break; 7112a8164dfSZhong Wang 712*d4401b99SKelly Hu case FCOE_STATUS_ERROR_GET_LINKINFO: 713*d4401b99SKelly Hu fprintf(stderr, 714*d4401b99SKelly Hu gettext("Error: Failed to get link information " 715*d4401b99SKelly Hu "for %s\n"), macLinkName); 716*d4401b99SKelly Hu break; 717*d4401b99SKelly Hu 7182a8164dfSZhong Wang case FCOE_STATUS_ERROR: 7192a8164dfSZhong Wang default: 7202a8164dfSZhong Wang fprintf(stderr, 7212a8164dfSZhong Wang gettext("Error: Due to reason code %d\n"), status); 7222a8164dfSZhong Wang } 7232a8164dfSZhong Wang return (1); 7242a8164dfSZhong Wang } else { 7252a8164dfSZhong Wang fcoe_adm_add_remove_scf_entry((char *)macLinkName, 7262a8164dfSZhong Wang "", 7272a8164dfSZhong Wang "", 7282a8164dfSZhong Wang 0, 7292a8164dfSZhong Wang 0, 7302a8164dfSZhong Wang FCOE_SCF_REMOVE); 7312a8164dfSZhong Wang return (0); 7322a8164dfSZhong Wang } 7332a8164dfSZhong Wang } 7342a8164dfSZhong Wang 7352a8164dfSZhong Wang int 7362a8164dfSZhong Wang fcoe_adm_list_ports(cmdOptions_t *options) 7372a8164dfSZhong Wang { 7382a8164dfSZhong Wang FCOE_STATUS status; 7392a8164dfSZhong Wang int showini = 0, showtgt = 0; 7402a8164dfSZhong Wang FCOE_UINT32 port_num; 7412a8164dfSZhong Wang FCOE_PORT_ATTRIBUTE *portlist = NULL; 7422a8164dfSZhong Wang int i; 7432a8164dfSZhong Wang int ret; 7442a8164dfSZhong Wang 7452a8164dfSZhong Wang for (; options->optval; options++) { 7462a8164dfSZhong Wang switch (options->optval) { 7472a8164dfSZhong Wang case 'i': 7482a8164dfSZhong Wang showini = 1; 7492a8164dfSZhong Wang break; 7502a8164dfSZhong Wang 7512a8164dfSZhong Wang case 't': 7522a8164dfSZhong Wang showtgt = 1; 7532a8164dfSZhong Wang break; 7542a8164dfSZhong Wang 7552a8164dfSZhong Wang default: 7562a8164dfSZhong Wang fprintf(stderr, gettext("Error: Illegal option: %c\n"), 7572a8164dfSZhong Wang options->optval); 7582a8164dfSZhong Wang return (1); 7592a8164dfSZhong Wang } 7602a8164dfSZhong Wang } 7612a8164dfSZhong Wang if (showini == 0 && showtgt == 0) { 7622a8164dfSZhong Wang showini = 1; 7632a8164dfSZhong Wang showtgt = 1; 7642a8164dfSZhong Wang } 7652a8164dfSZhong Wang 7662a8164dfSZhong Wang status = FCOE_GetPortList(&port_num, &portlist); 7672a8164dfSZhong Wang 7682a8164dfSZhong Wang if (status != FCOE_STATUS_OK) { 7692a8164dfSZhong Wang switch (status) { 7702a8164dfSZhong Wang case FCOE_STATUS_ERROR_BUSY: 7712a8164dfSZhong Wang fprintf(stderr, 7722a8164dfSZhong Wang gettext("Error: fcoe driver is busy\n")); 7732a8164dfSZhong Wang break; 7742a8164dfSZhong Wang 7752a8164dfSZhong Wang case FCOE_STATUS_ERROR_PERM: 7762a8164dfSZhong Wang fprintf(stderr, 7772a8164dfSZhong Wang gettext("Error: Not enough permission to " 7782a8164dfSZhong Wang "open fcoe device\n")); 7792a8164dfSZhong Wang break; 7802a8164dfSZhong Wang 7812a8164dfSZhong Wang case FCOE_STATUS_ERROR_OPEN_DEV: 7822a8164dfSZhong Wang fprintf(stderr, 7832a8164dfSZhong Wang gettext("Error: Failed to open fcoe device\n")); 7842a8164dfSZhong Wang break; 7852a8164dfSZhong Wang 7862a8164dfSZhong Wang case FCOE_STATUS_ERROR_INVAL_ARG: 7872a8164dfSZhong Wang fprintf(stderr, 7882a8164dfSZhong Wang gettext("Error: Invalid argument\n")); 7892a8164dfSZhong Wang break; 7902a8164dfSZhong Wang 7912a8164dfSZhong Wang case FCOE_STATUS_ERROR_MORE_DATA: 7922a8164dfSZhong Wang fprintf(stderr, 7932a8164dfSZhong Wang gettext("Error: More data\n")); 7942a8164dfSZhong Wang break; 7952a8164dfSZhong Wang 7962a8164dfSZhong Wang case FCOE_STATUS_ERROR: 7972a8164dfSZhong Wang default: 7982a8164dfSZhong Wang fprintf(stderr, 7992a8164dfSZhong Wang gettext("Error: Due to reason code %d\n"), status); 8002a8164dfSZhong Wang } 8012a8164dfSZhong Wang ret = 1; 8022a8164dfSZhong Wang } else { 8032a8164dfSZhong Wang if (port_num == 0) { 8042a8164dfSZhong Wang fprintf(stdout, gettext("No FCoE Ports Found!\n")); 8052a8164dfSZhong Wang } else { 8062a8164dfSZhong Wang for (i = 0; i < port_num; i++) { 8072a8164dfSZhong Wang if ((portlist[i].port_type == 8082a8164dfSZhong Wang FCOE_PORTTYPE_INITIATOR && 8092a8164dfSZhong Wang showini == 1) || (showtgt == 1 && 8102a8164dfSZhong Wang portlist[i].port_type == 8112a8164dfSZhong Wang FCOE_PORTTYPE_TARGET)) { 8122a8164dfSZhong Wang printFCOEPortInfo(&portlist[i]); 8132a8164dfSZhong Wang } 8142a8164dfSZhong Wang } 8152a8164dfSZhong Wang } 8162a8164dfSZhong Wang ret = 0; 8172a8164dfSZhong Wang } 8182a8164dfSZhong Wang 8192a8164dfSZhong Wang if (portlist != NULL) { 8202a8164dfSZhong Wang free(portlist); 8212a8164dfSZhong Wang } 8222a8164dfSZhong Wang return (ret); 8232a8164dfSZhong Wang 8242a8164dfSZhong Wang } 8252a8164dfSZhong Wang 8262a8164dfSZhong Wang int 8272a8164dfSZhong Wang fcoe_adm_create_portlist(cmdOptions_t *options) 8282a8164dfSZhong Wang { 8292a8164dfSZhong Wang scf_handle_t *handle = NULL; 8302a8164dfSZhong Wang scf_service_t *svc = NULL; 8312a8164dfSZhong Wang scf_propertygroup_t *pg = NULL; 8322a8164dfSZhong Wang scf_transaction_t *tran = NULL; 8332a8164dfSZhong Wang scf_transaction_entry_t *entry = NULL; 8342a8164dfSZhong Wang scf_property_t *prop = NULL; 8352a8164dfSZhong Wang scf_value_t *valueLookup = NULL; 8362a8164dfSZhong Wang scf_iter_t *valueIter = NULL; 8372a8164dfSZhong Wang char buf[FCOE_PORT_LIST_LENGTH] = {0}; 8382a8164dfSZhong Wang int commitRet; 8392a8164dfSZhong Wang int create_target = 0, create_initiator = 0; 8402a8164dfSZhong Wang 8412a8164dfSZhong Wang /* Check what type of port list will be created */ 8422a8164dfSZhong Wang for (; options->optval; options++) { 8432a8164dfSZhong Wang switch (options->optval) { 8442a8164dfSZhong Wang case 'i': 8452a8164dfSZhong Wang create_initiator = 1; 8462a8164dfSZhong Wang break; 8472a8164dfSZhong Wang case 't': 8482a8164dfSZhong Wang create_target = 1; 8492a8164dfSZhong Wang break; 8502a8164dfSZhong Wang default: 8512a8164dfSZhong Wang fprintf(stderr, gettext("Error: Illegal option: %c\n"), 8522a8164dfSZhong Wang options->optval); 8532a8164dfSZhong Wang return (1); 8542a8164dfSZhong Wang } 8552a8164dfSZhong Wang } 8562a8164dfSZhong Wang 8572a8164dfSZhong Wang if (create_initiator == 0 && create_target == 0) { 8582a8164dfSZhong Wang create_initiator = 1; 8592a8164dfSZhong Wang create_target = 1; 8602a8164dfSZhong Wang } 8612a8164dfSZhong Wang 8622a8164dfSZhong Wang commitRet = fcoe_cfg_scf_init(&handle, &svc); 8632a8164dfSZhong Wang if (commitRet != FCOE_SUCCESS) { 8642a8164dfSZhong Wang goto out; 8652a8164dfSZhong Wang } 8662a8164dfSZhong Wang 8672a8164dfSZhong Wang if (((pg = scf_pg_create(handle)) == NULL) || 8682a8164dfSZhong Wang ((tran = scf_transaction_create(handle)) == NULL) || 8692a8164dfSZhong Wang ((entry = scf_entry_create(handle)) == NULL) || 8702a8164dfSZhong Wang ((prop = scf_property_create(handle)) == NULL) || 8712a8164dfSZhong Wang ((valueIter = scf_iter_create(handle)) == NULL)) { 8722a8164dfSZhong Wang goto out; 8732a8164dfSZhong Wang } 8742a8164dfSZhong Wang 8752a8164dfSZhong Wang /* get property group or create it */ 8762a8164dfSZhong Wang if (scf_service_get_pg(svc, FCOE_PG_NAME, pg) == -1) { 8772a8164dfSZhong Wang goto out; 8782a8164dfSZhong Wang } 8792a8164dfSZhong Wang 8802a8164dfSZhong Wang if (scf_pg_get_property(pg, FCOE_PORT_LIST, prop) == -1) { 8812a8164dfSZhong Wang syslog(LOG_ERR, "get property failed - %s", 8822a8164dfSZhong Wang scf_strerror(scf_error())); 8832a8164dfSZhong Wang goto out; 8842a8164dfSZhong Wang } 8852a8164dfSZhong Wang 8862a8164dfSZhong Wang valueLookup = scf_value_create(handle); 8872a8164dfSZhong Wang if (valueLookup == NULL) { 8882a8164dfSZhong Wang syslog(LOG_ERR, "scf value alloc failed - %s", 8892a8164dfSZhong Wang scf_strerror(scf_error())); 8902a8164dfSZhong Wang goto out; 8912a8164dfSZhong Wang } 8922a8164dfSZhong Wang 8932a8164dfSZhong Wang if (scf_iter_property_values(valueIter, prop) == -1) { 8942a8164dfSZhong Wang syslog(LOG_ERR, "iter value failed - %s", 8952a8164dfSZhong Wang scf_strerror(scf_error())); 8962a8164dfSZhong Wang goto out; 8972a8164dfSZhong Wang } 8982a8164dfSZhong Wang while (scf_iter_next_value(valueIter, valueLookup) == 1) { 8992a8164dfSZhong Wang uint8_t *macLinkName = NULL; 9002a8164dfSZhong Wang char *remainder = NULL; 9012a8164dfSZhong Wang FCOE_PORT_WWN pwwn, nwwn; 9022a8164dfSZhong Wang uint64_t nodeWWN, portWWN; 9032a8164dfSZhong Wang int is_target, is_promiscuous; 9042a8164dfSZhong Wang 9052a8164dfSZhong Wang bzero(buf, sizeof (buf)); 9062a8164dfSZhong Wang bzero(&pwwn, sizeof (pwwn)); 9072a8164dfSZhong Wang bzero(&nwwn, sizeof (nwwn)); 9082a8164dfSZhong Wang if (scf_value_get_ustring(valueLookup, buf, MAXNAMELEN) == -1) { 9092a8164dfSZhong Wang syslog(LOG_ERR, "iter value failed - %s", 9102a8164dfSZhong Wang scf_strerror(scf_error())); 9112a8164dfSZhong Wang break; 9122a8164dfSZhong Wang } 9132a8164dfSZhong Wang macLinkName = (uint8_t *)strtok(buf, ":"); 9142a8164dfSZhong Wang remainder = strtok(NULL, "#"); 9152a8164dfSZhong Wang sscanf(remainder, "%016llx:%016llx:%d:%d", 9162a8164dfSZhong Wang &portWWN, &nodeWWN, &is_target, &is_promiscuous); 9172a8164dfSZhong Wang if ((!create_target && is_target) || 9182a8164dfSZhong Wang (!create_initiator && !is_target)) { 9192a8164dfSZhong Wang continue; 9202a8164dfSZhong Wang } 9212a8164dfSZhong Wang 9222a8164dfSZhong Wang nodeWWN = htonll(nodeWWN); 9232a8164dfSZhong Wang memcpy(&nwwn, &nodeWWN, sizeof (nodeWWN)); 9242a8164dfSZhong Wang portWWN = htonll(portWWN); 9252a8164dfSZhong Wang memcpy(&pwwn, &portWWN, sizeof (portWWN)); 9262a8164dfSZhong Wang 9272a8164dfSZhong Wang FCOE_CreatePort(macLinkName, 9282a8164dfSZhong Wang is_target ? FCOE_PORTTYPE_TARGET : FCOE_PORTTYPE_INITIATOR, 9292a8164dfSZhong Wang pwwn, nwwn, is_promiscuous); 9302a8164dfSZhong Wang } 9312a8164dfSZhong Wang 9322a8164dfSZhong Wang out: 9332a8164dfSZhong Wang /* 9342a8164dfSZhong Wang * Free resources 9352a8164dfSZhong Wang */ 9362a8164dfSZhong Wang if (handle != NULL) { 9372a8164dfSZhong Wang scf_handle_destroy(handle); 9382a8164dfSZhong Wang } 9392a8164dfSZhong Wang if (svc != NULL) { 9402a8164dfSZhong Wang scf_service_destroy(svc); 9412a8164dfSZhong Wang } 9422a8164dfSZhong Wang if (pg != NULL) { 9432a8164dfSZhong Wang scf_pg_destroy(pg); 9442a8164dfSZhong Wang } 9452a8164dfSZhong Wang if (tran != NULL) { 9462a8164dfSZhong Wang scf_transaction_destroy(tran); 9472a8164dfSZhong Wang } 9482a8164dfSZhong Wang if (entry != NULL) { 9492a8164dfSZhong Wang scf_entry_destroy(entry); 9502a8164dfSZhong Wang } 9512a8164dfSZhong Wang if (prop != NULL) { 9522a8164dfSZhong Wang scf_property_destroy(prop); 9532a8164dfSZhong Wang } 9542a8164dfSZhong Wang if (valueIter != NULL) { 9552a8164dfSZhong Wang scf_iter_destroy(valueIter); 9562a8164dfSZhong Wang } 9572a8164dfSZhong Wang if (valueLookup != NULL) { 9582a8164dfSZhong Wang scf_value_destroy(valueLookup); 9592a8164dfSZhong Wang } 9602a8164dfSZhong Wang 9612a8164dfSZhong Wang return (0); 9622a8164dfSZhong Wang } 963