1*2a8164dfSZhong Wang /* 2*2a8164dfSZhong Wang * CDDL HEADER START 3*2a8164dfSZhong Wang * 4*2a8164dfSZhong Wang * The contents of this file are subject to the terms of the 5*2a8164dfSZhong Wang * Common Development and Distribution License (the "License"). 6*2a8164dfSZhong Wang * You may not use this file except in compliance with the License. 7*2a8164dfSZhong Wang * 8*2a8164dfSZhong Wang * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*2a8164dfSZhong Wang * or http://www.opensolaris.org/os/licensing. 10*2a8164dfSZhong Wang * See the License for the specific language governing permissions 11*2a8164dfSZhong Wang * and limitations under the License. 12*2a8164dfSZhong Wang * 13*2a8164dfSZhong Wang * When distributing Covered Code, include this CDDL HEADER in each 14*2a8164dfSZhong Wang * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*2a8164dfSZhong Wang * If applicable, add the following below this CDDL HEADER, with the 16*2a8164dfSZhong Wang * fields enclosed by brackets "[]" replaced with your own identifying 17*2a8164dfSZhong Wang * information: Portions Copyright [yyyy] [name of copyright owner] 18*2a8164dfSZhong Wang * 19*2a8164dfSZhong Wang * CDDL HEADER END 20*2a8164dfSZhong Wang */ 21*2a8164dfSZhong Wang /* 22*2a8164dfSZhong Wang * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23*2a8164dfSZhong Wang * Use is subject to license terms. 24*2a8164dfSZhong Wang */ 25*2a8164dfSZhong Wang 26*2a8164dfSZhong Wang #include "fcinfo.h" 27*2a8164dfSZhong Wang #include <libintl.h> 28*2a8164dfSZhong Wang #include <fcntl.h> 29*2a8164dfSZhong Wang #include <errno.h> 30*2a8164dfSZhong Wang #include <assert.h> 31*2a8164dfSZhong Wang #include <ctype.h> 32*2a8164dfSZhong Wang #include <sys/list.h> 33*2a8164dfSZhong Wang #include <stddef.h> 34*2a8164dfSZhong Wang #include <strings.h> 35*2a8164dfSZhong Wang #include <libfcoe.h> 36*2a8164dfSZhong Wang #include <libscf.h> 37*2a8164dfSZhong Wang #include <syslog.h> 38*2a8164dfSZhong Wang 39*2a8164dfSZhong Wang static const char *FCOE_DRIVER_PATH = "/devices/fcoe:admin"; 40*2a8164dfSZhong Wang 41*2a8164dfSZhong Wang static char * 42*2a8164dfSZhong Wang WWN2str(char *buf, FCOE_PORT_WWN *wwn) { 43*2a8164dfSZhong Wang int j; 44*2a8164dfSZhong Wang unsigned char *pc = (unsigned char *)&(wwn->wwn[0]); 45*2a8164dfSZhong Wang buf[0] = '\0'; 46*2a8164dfSZhong Wang for (j = 0; j < 16; j += 2) { 47*2a8164dfSZhong Wang sprintf(&buf[j], "%02X", (int)*pc++); 48*2a8164dfSZhong Wang } 49*2a8164dfSZhong Wang return (buf); 50*2a8164dfSZhong Wang } 51*2a8164dfSZhong Wang 52*2a8164dfSZhong Wang static int 53*2a8164dfSZhong Wang isValidWWN(char *wwn) 54*2a8164dfSZhong Wang { 55*2a8164dfSZhong Wang int index; 56*2a8164dfSZhong Wang 57*2a8164dfSZhong Wang if (wwn == NULL) { 58*2a8164dfSZhong Wang return (0); 59*2a8164dfSZhong Wang } 60*2a8164dfSZhong Wang 61*2a8164dfSZhong Wang if (strlen(wwn) != 16) { 62*2a8164dfSZhong Wang return (0); 63*2a8164dfSZhong Wang } 64*2a8164dfSZhong Wang 65*2a8164dfSZhong Wang for (index = 0; index < 16; index++) { 66*2a8164dfSZhong Wang if (isxdigit(wwn[index])) { 67*2a8164dfSZhong Wang continue; 68*2a8164dfSZhong Wang } 69*2a8164dfSZhong Wang return (0); 70*2a8164dfSZhong Wang } 71*2a8164dfSZhong Wang return (1); 72*2a8164dfSZhong Wang } 73*2a8164dfSZhong Wang 74*2a8164dfSZhong Wang static uint64_t wwnconvert(uchar_t *wwn) 75*2a8164dfSZhong Wang { 76*2a8164dfSZhong Wang uint64_t tmp; 77*2a8164dfSZhong Wang memcpy(&tmp, wwn, sizeof (uint64_t)); 78*2a8164dfSZhong Wang return (ntohll(tmp)); 79*2a8164dfSZhong Wang } 80*2a8164dfSZhong Wang 81*2a8164dfSZhong Wang /* 82*2a8164dfSZhong Wang * prints out all the HBA port information 83*2a8164dfSZhong Wang */ 84*2a8164dfSZhong Wang void 85*2a8164dfSZhong Wang printFCOEPortInfo(FCOE_PORT_ATTRIBUTE *attr) 86*2a8164dfSZhong Wang { 87*2a8164dfSZhong Wang int i; 88*2a8164dfSZhong Wang if (attr == NULL) { 89*2a8164dfSZhong Wang return; 90*2a8164dfSZhong Wang } 91*2a8164dfSZhong Wang fprintf(stdout, gettext("HBA Port WWN: %016llx\n"), 92*2a8164dfSZhong Wang wwnconvert((unsigned char *)&attr->port_wwn)); 93*2a8164dfSZhong Wang 94*2a8164dfSZhong Wang fprintf(stdout, gettext("\tPort Type: %s\n"), 95*2a8164dfSZhong Wang (attr->port_type == 0) ? "Initiator" : "Target"); 96*2a8164dfSZhong Wang 97*2a8164dfSZhong Wang fprintf(stdout, gettext("\tMAC Name: %s\n"), attr->mac_link_name); 98*2a8164dfSZhong Wang 99*2a8164dfSZhong Wang fprintf(stdout, gettext("\tMTU Size: %d\n"), attr->mtu_size); 100*2a8164dfSZhong Wang 101*2a8164dfSZhong Wang fprintf(stdout, gettext("\tMAC Factory Address: ")); 102*2a8164dfSZhong Wang for (i = 0; i < 6; i++) { 103*2a8164dfSZhong Wang fprintf(stdout, gettext("%02x"), attr->mac_factory_addr[i]); 104*2a8164dfSZhong Wang } 105*2a8164dfSZhong Wang fprintf(stdout, gettext("\n\tMAC Current Address: ")); 106*2a8164dfSZhong Wang for (i = 0; i < 6; i++) { 107*2a8164dfSZhong Wang fprintf(stdout, gettext("%02x"), attr->mac_current_addr[i]); 108*2a8164dfSZhong Wang } 109*2a8164dfSZhong Wang fprintf(stdout, gettext("\n\tPromiscuous Mode: %s\n"), 110*2a8164dfSZhong Wang attr->mac_promisc == 1 ? "On" : "Off"); 111*2a8164dfSZhong Wang } 112*2a8164dfSZhong Wang 113*2a8164dfSZhong Wang /* 114*2a8164dfSZhong Wang * Initialize scf fcoe service access 115*2a8164dfSZhong Wang * handle - returned handle 116*2a8164dfSZhong Wang * service - returned service handle 117*2a8164dfSZhong Wang */ 118*2a8164dfSZhong Wang static int 119*2a8164dfSZhong Wang fcoe_cfg_scf_init(scf_handle_t **handle, scf_service_t **service) 120*2a8164dfSZhong Wang { 121*2a8164dfSZhong Wang scf_scope_t *scope = NULL; 122*2a8164dfSZhong Wang int ret; 123*2a8164dfSZhong Wang 124*2a8164dfSZhong Wang if ((*handle = scf_handle_create(SCF_VERSION)) == NULL) { 125*2a8164dfSZhong Wang syslog(LOG_ERR, "scf_handle_create failed - %s", 126*2a8164dfSZhong Wang scf_strerror(scf_error())); 127*2a8164dfSZhong Wang ret = FCOE_ERROR; 128*2a8164dfSZhong Wang goto err; 129*2a8164dfSZhong Wang } 130*2a8164dfSZhong Wang 131*2a8164dfSZhong Wang if (scf_handle_bind(*handle) == -1) { 132*2a8164dfSZhong Wang syslog(LOG_ERR, "scf_handle_bind failed - %s", 133*2a8164dfSZhong Wang scf_strerror(scf_error())); 134*2a8164dfSZhong Wang ret = FCOE_ERROR; 135*2a8164dfSZhong Wang goto err; 136*2a8164dfSZhong Wang } 137*2a8164dfSZhong Wang 138*2a8164dfSZhong Wang if ((*service = scf_service_create(*handle)) == NULL) { 139*2a8164dfSZhong Wang syslog(LOG_ERR, "scf_service_create failed - %s", 140*2a8164dfSZhong Wang scf_strerror(scf_error())); 141*2a8164dfSZhong Wang ret = FCOE_ERROR; 142*2a8164dfSZhong Wang goto err; 143*2a8164dfSZhong Wang } 144*2a8164dfSZhong Wang 145*2a8164dfSZhong Wang if ((scope = scf_scope_create(*handle)) == NULL) { 146*2a8164dfSZhong Wang syslog(LOG_ERR, "scf_scope_create failed - %s", 147*2a8164dfSZhong Wang scf_strerror(scf_error())); 148*2a8164dfSZhong Wang ret = FCOE_ERROR; 149*2a8164dfSZhong Wang goto err; 150*2a8164dfSZhong Wang } 151*2a8164dfSZhong Wang 152*2a8164dfSZhong Wang if (scf_handle_get_scope(*handle, SCF_SCOPE_LOCAL, scope) == -1) { 153*2a8164dfSZhong Wang syslog(LOG_ERR, "scf_handle_get_scope failed - %s", 154*2a8164dfSZhong Wang scf_strerror(scf_error())); 155*2a8164dfSZhong Wang ret = FCOE_ERROR; 156*2a8164dfSZhong Wang goto err; 157*2a8164dfSZhong Wang } 158*2a8164dfSZhong Wang 159*2a8164dfSZhong Wang if (scf_scope_get_service(scope, FCOE_SERVICE, *service) == -1) { 160*2a8164dfSZhong Wang syslog(LOG_ERR, "scf_scope_get_service failed - %s", 161*2a8164dfSZhong Wang scf_strerror(scf_error())); 162*2a8164dfSZhong Wang ret = FCOE_ERROR_SERVICE_NOT_FOUND; 163*2a8164dfSZhong Wang goto err; 164*2a8164dfSZhong Wang } 165*2a8164dfSZhong Wang 166*2a8164dfSZhong Wang scf_scope_destroy(scope); 167*2a8164dfSZhong Wang 168*2a8164dfSZhong Wang return (FCOE_SUCCESS); 169*2a8164dfSZhong Wang 170*2a8164dfSZhong Wang err: 171*2a8164dfSZhong Wang if (*handle != NULL) { 172*2a8164dfSZhong Wang scf_handle_destroy(*handle); 173*2a8164dfSZhong Wang } 174*2a8164dfSZhong Wang if (*service != NULL) { 175*2a8164dfSZhong Wang scf_service_destroy(*service); 176*2a8164dfSZhong Wang *service = NULL; 177*2a8164dfSZhong Wang } 178*2a8164dfSZhong Wang if (scope != NULL) { 179*2a8164dfSZhong Wang scf_scope_destroy(scope); 180*2a8164dfSZhong Wang } 181*2a8164dfSZhong Wang return (ret); 182*2a8164dfSZhong Wang } 183*2a8164dfSZhong Wang 184*2a8164dfSZhong Wang 185*2a8164dfSZhong Wang static int 186*2a8164dfSZhong Wang fcoe_adm_add_remove_scf_entry(char *mac_name, 187*2a8164dfSZhong Wang char *pwwn, char *nwwn, 188*2a8164dfSZhong Wang int is_target, int is_promiscuous, int addRemoveFlag) 189*2a8164dfSZhong Wang { 190*2a8164dfSZhong Wang scf_handle_t *handle = NULL; 191*2a8164dfSZhong Wang scf_service_t *svc = NULL; 192*2a8164dfSZhong Wang scf_propertygroup_t *pg = NULL; 193*2a8164dfSZhong Wang scf_transaction_t *tran = NULL; 194*2a8164dfSZhong Wang scf_transaction_entry_t *entry = NULL; 195*2a8164dfSZhong Wang scf_property_t *prop = NULL; 196*2a8164dfSZhong Wang scf_value_t *valueLookup = NULL; 197*2a8164dfSZhong Wang scf_iter_t *valueIter = NULL; 198*2a8164dfSZhong Wang scf_value_t **valueSet = NULL; 199*2a8164dfSZhong Wang int ret = FCOE_SUCCESS; 200*2a8164dfSZhong Wang boolean_t createProp = B_FALSE; 201*2a8164dfSZhong Wang int lastAlloc = 0; 202*2a8164dfSZhong Wang char buf[FCOE_PORT_LIST_LENGTH] = {0}; 203*2a8164dfSZhong Wang char memberName[FCOE_PORT_LIST_LENGTH] = {0}; 204*2a8164dfSZhong Wang boolean_t found = B_FALSE; 205*2a8164dfSZhong Wang int i = 0; 206*2a8164dfSZhong Wang int valueArraySize = 0; 207*2a8164dfSZhong Wang int commitRet; 208*2a8164dfSZhong Wang 209*2a8164dfSZhong Wang sprintf(memberName, "%s:%s:%s:%d:%d", mac_name, pwwn, nwwn, 210*2a8164dfSZhong Wang is_target, is_promiscuous); 211*2a8164dfSZhong Wang 212*2a8164dfSZhong Wang ret = fcoe_cfg_scf_init(&handle, &svc); 213*2a8164dfSZhong Wang if (ret != FCOE_SUCCESS) { 214*2a8164dfSZhong Wang goto out; 215*2a8164dfSZhong Wang } 216*2a8164dfSZhong Wang 217*2a8164dfSZhong Wang if (((pg = scf_pg_create(handle)) == NULL) || 218*2a8164dfSZhong Wang ((tran = scf_transaction_create(handle)) == NULL) || 219*2a8164dfSZhong Wang ((entry = scf_entry_create(handle)) == NULL) || 220*2a8164dfSZhong Wang ((prop = scf_property_create(handle)) == NULL) || 221*2a8164dfSZhong Wang ((valueIter = scf_iter_create(handle)) == NULL)) { 222*2a8164dfSZhong Wang ret = FCOE_ERROR; 223*2a8164dfSZhong Wang goto out; 224*2a8164dfSZhong Wang } 225*2a8164dfSZhong Wang 226*2a8164dfSZhong Wang /* get property group or create it */ 227*2a8164dfSZhong Wang if (scf_service_get_pg(svc, FCOE_PG_NAME, pg) == -1) { 228*2a8164dfSZhong Wang if ((scf_error() == SCF_ERROR_NOT_FOUND)) { 229*2a8164dfSZhong Wang if (scf_service_add_pg(svc, FCOE_PG_NAME, 230*2a8164dfSZhong Wang SCF_GROUP_APPLICATION, 0, pg) == -1) { 231*2a8164dfSZhong Wang syslog(LOG_ERR, "add pg failed - %s", 232*2a8164dfSZhong Wang scf_strerror(scf_error())); 233*2a8164dfSZhong Wang ret = FCOE_ERROR; 234*2a8164dfSZhong Wang } else { 235*2a8164dfSZhong Wang createProp = B_TRUE; 236*2a8164dfSZhong Wang } 237*2a8164dfSZhong Wang } else { 238*2a8164dfSZhong Wang syslog(LOG_ERR, "get pg failed - %s", 239*2a8164dfSZhong Wang scf_strerror(scf_error())); 240*2a8164dfSZhong Wang ret = FCOE_ERROR; 241*2a8164dfSZhong Wang } 242*2a8164dfSZhong Wang if (ret != FCOE_SUCCESS) { 243*2a8164dfSZhong Wang goto out; 244*2a8164dfSZhong Wang } 245*2a8164dfSZhong Wang } 246*2a8164dfSZhong Wang 247*2a8164dfSZhong Wang /* to make sure property exists */ 248*2a8164dfSZhong Wang if (createProp == B_FALSE) { 249*2a8164dfSZhong Wang if (scf_pg_get_property(pg, FCOE_PORT_LIST, prop) == -1) { 250*2a8164dfSZhong Wang if ((scf_error() == SCF_ERROR_NOT_FOUND)) { 251*2a8164dfSZhong Wang createProp = B_TRUE; 252*2a8164dfSZhong Wang } else { 253*2a8164dfSZhong Wang syslog(LOG_ERR, "get property failed - %s", 254*2a8164dfSZhong Wang scf_strerror(scf_error())); 255*2a8164dfSZhong Wang ret = FCOE_ERROR; 256*2a8164dfSZhong Wang goto out; 257*2a8164dfSZhong Wang } 258*2a8164dfSZhong Wang } 259*2a8164dfSZhong Wang } 260*2a8164dfSZhong Wang 261*2a8164dfSZhong Wang /* Begin the transaction */ 262*2a8164dfSZhong Wang if (scf_transaction_start(tran, pg) == -1) { 263*2a8164dfSZhong Wang syslog(LOG_ERR, "start transaction failed - %s", 264*2a8164dfSZhong Wang scf_strerror(scf_error())); 265*2a8164dfSZhong Wang ret = FCOE_ERROR; 266*2a8164dfSZhong Wang goto out; 267*2a8164dfSZhong Wang } 268*2a8164dfSZhong Wang 269*2a8164dfSZhong Wang valueSet = (scf_value_t **)calloc(1, sizeof (*valueSet) 270*2a8164dfSZhong Wang * (lastAlloc = PORT_LIST_ALLOC)); 271*2a8164dfSZhong Wang if (valueSet == NULL) { 272*2a8164dfSZhong Wang ret = FCOE_ERROR_NOMEM; 273*2a8164dfSZhong Wang goto out; 274*2a8164dfSZhong Wang } 275*2a8164dfSZhong Wang 276*2a8164dfSZhong Wang if (createProp) { 277*2a8164dfSZhong Wang if (scf_transaction_property_new(tran, entry, FCOE_PORT_LIST, 278*2a8164dfSZhong Wang SCF_TYPE_USTRING) == -1) { 279*2a8164dfSZhong Wang if (scf_error() == SCF_ERROR_EXISTS) { 280*2a8164dfSZhong Wang ret = FCOE_ERROR_EXISTS; 281*2a8164dfSZhong Wang } else { 282*2a8164dfSZhong Wang syslog(LOG_ERR, 283*2a8164dfSZhong Wang "transaction property new failed - %s", 284*2a8164dfSZhong Wang scf_strerror(scf_error())); 285*2a8164dfSZhong Wang ret = FCOE_ERROR; 286*2a8164dfSZhong Wang } 287*2a8164dfSZhong Wang goto out; 288*2a8164dfSZhong Wang } 289*2a8164dfSZhong Wang } else { 290*2a8164dfSZhong Wang if (scf_transaction_property_change(tran, entry, 291*2a8164dfSZhong Wang FCOE_PORT_LIST, SCF_TYPE_USTRING) == -1) { 292*2a8164dfSZhong Wang syslog(LOG_ERR, 293*2a8164dfSZhong Wang "transaction property change failed - %s", 294*2a8164dfSZhong Wang scf_strerror(scf_error())); 295*2a8164dfSZhong Wang ret = FCOE_ERROR; 296*2a8164dfSZhong Wang goto out; 297*2a8164dfSZhong Wang } 298*2a8164dfSZhong Wang 299*2a8164dfSZhong Wang if (scf_pg_get_property(pg, FCOE_PORT_LIST, prop) == -1) { 300*2a8164dfSZhong Wang syslog(LOG_ERR, "get property failed - %s", 301*2a8164dfSZhong Wang scf_strerror(scf_error())); 302*2a8164dfSZhong Wang ret = FCOE_ERROR; 303*2a8164dfSZhong Wang goto out; 304*2a8164dfSZhong Wang } 305*2a8164dfSZhong Wang 306*2a8164dfSZhong Wang valueLookup = scf_value_create(handle); 307*2a8164dfSZhong Wang if (valueLookup == NULL) { 308*2a8164dfSZhong Wang syslog(LOG_ERR, "scf value alloc failed - %s", 309*2a8164dfSZhong Wang scf_strerror(scf_error())); 310*2a8164dfSZhong Wang ret = FCOE_ERROR; 311*2a8164dfSZhong Wang goto out; 312*2a8164dfSZhong Wang } 313*2a8164dfSZhong Wang 314*2a8164dfSZhong Wang if (scf_iter_property_values(valueIter, prop) == -1) { 315*2a8164dfSZhong Wang syslog(LOG_ERR, "iter value failed - %s", 316*2a8164dfSZhong Wang scf_strerror(scf_error())); 317*2a8164dfSZhong Wang ret = FCOE_ERROR; 318*2a8164dfSZhong Wang goto out; 319*2a8164dfSZhong Wang } 320*2a8164dfSZhong Wang 321*2a8164dfSZhong Wang while (scf_iter_next_value(valueIter, valueLookup) == 1) { 322*2a8164dfSZhong Wang char *macnameIter = NULL; 323*2a8164dfSZhong Wang char buftmp[FCOE_PORT_LIST_LENGTH] = {0}; 324*2a8164dfSZhong Wang 325*2a8164dfSZhong Wang bzero(buf, sizeof (buf)); 326*2a8164dfSZhong Wang if (scf_value_get_ustring(valueLookup, 327*2a8164dfSZhong Wang buf, MAXNAMELEN) == -1) { 328*2a8164dfSZhong Wang syslog(LOG_ERR, "iter value failed- %s", 329*2a8164dfSZhong Wang scf_strerror(scf_error())); 330*2a8164dfSZhong Wang ret = FCOE_ERROR; 331*2a8164dfSZhong Wang break; 332*2a8164dfSZhong Wang } 333*2a8164dfSZhong Wang strcpy(buftmp, buf); 334*2a8164dfSZhong Wang macnameIter = strtok(buftmp, ":"); 335*2a8164dfSZhong Wang if (bcmp(macnameIter, mac_name, 336*2a8164dfSZhong Wang strlen(mac_name)) == 0) { 337*2a8164dfSZhong Wang if (addRemoveFlag == FCOE_SCF_ADD) { 338*2a8164dfSZhong Wang ret = FCOE_ERROR_EXISTS; 339*2a8164dfSZhong Wang break; 340*2a8164dfSZhong Wang } else { 341*2a8164dfSZhong Wang found = B_TRUE; 342*2a8164dfSZhong Wang continue; 343*2a8164dfSZhong Wang } 344*2a8164dfSZhong Wang } 345*2a8164dfSZhong Wang 346*2a8164dfSZhong Wang valueSet[i] = scf_value_create(handle); 347*2a8164dfSZhong Wang if (valueSet[i] == NULL) { 348*2a8164dfSZhong Wang syslog(LOG_ERR, "scf value alloc failed - %s", 349*2a8164dfSZhong Wang scf_strerror(scf_error())); 350*2a8164dfSZhong Wang ret = FCOE_ERROR; 351*2a8164dfSZhong Wang break; 352*2a8164dfSZhong Wang } 353*2a8164dfSZhong Wang 354*2a8164dfSZhong Wang if (scf_value_set_ustring(valueSet[i], buf) == -1) { 355*2a8164dfSZhong Wang syslog(LOG_ERR, "set value failed 1- %s", 356*2a8164dfSZhong Wang scf_strerror(scf_error())); 357*2a8164dfSZhong Wang ret = FCOE_ERROR; 358*2a8164dfSZhong Wang break; 359*2a8164dfSZhong Wang } 360*2a8164dfSZhong Wang 361*2a8164dfSZhong Wang if (scf_entry_add_value(entry, valueSet[i]) == -1) { 362*2a8164dfSZhong Wang syslog(LOG_ERR, "add value failed - %s", 363*2a8164dfSZhong Wang scf_strerror(scf_error())); 364*2a8164dfSZhong Wang ret = FCOE_ERROR; 365*2a8164dfSZhong Wang break; 366*2a8164dfSZhong Wang } 367*2a8164dfSZhong Wang 368*2a8164dfSZhong Wang i++; 369*2a8164dfSZhong Wang 370*2a8164dfSZhong Wang if (i >= lastAlloc) { 371*2a8164dfSZhong Wang lastAlloc += PORT_LIST_ALLOC; 372*2a8164dfSZhong Wang valueSet = realloc(valueSet, 373*2a8164dfSZhong Wang sizeof (*valueSet) * lastAlloc); 374*2a8164dfSZhong Wang if (valueSet == NULL) { 375*2a8164dfSZhong Wang ret = FCOE_ERROR; 376*2a8164dfSZhong Wang break; 377*2a8164dfSZhong Wang } 378*2a8164dfSZhong Wang } 379*2a8164dfSZhong Wang } 380*2a8164dfSZhong Wang } 381*2a8164dfSZhong Wang 382*2a8164dfSZhong Wang valueArraySize = i; 383*2a8164dfSZhong Wang if (!found && (addRemoveFlag == FCOE_SCF_REMOVE)) { 384*2a8164dfSZhong Wang ret = FCOE_ERROR_MEMBER_NOT_FOUND; 385*2a8164dfSZhong Wang } 386*2a8164dfSZhong Wang if (ret != FCOE_SUCCESS) { 387*2a8164dfSZhong Wang goto out; 388*2a8164dfSZhong Wang } 389*2a8164dfSZhong Wang 390*2a8164dfSZhong Wang if (addRemoveFlag == FCOE_SCF_ADD) { 391*2a8164dfSZhong Wang /* 392*2a8164dfSZhong Wang * Now create the new entry 393*2a8164dfSZhong Wang */ 394*2a8164dfSZhong Wang valueSet[i] = scf_value_create(handle); 395*2a8164dfSZhong Wang if (valueSet[i] == NULL) { 396*2a8164dfSZhong Wang syslog(LOG_ERR, "scf value alloc failed - %s", 397*2a8164dfSZhong Wang scf_strerror(scf_error())); 398*2a8164dfSZhong Wang ret = FCOE_ERROR; 399*2a8164dfSZhong Wang goto out; 400*2a8164dfSZhong Wang } else { 401*2a8164dfSZhong Wang valueArraySize++; 402*2a8164dfSZhong Wang } 403*2a8164dfSZhong Wang 404*2a8164dfSZhong Wang /* 405*2a8164dfSZhong Wang * Set the new member name 406*2a8164dfSZhong Wang */ 407*2a8164dfSZhong Wang if (scf_value_set_ustring(valueSet[i], memberName) == -1) { 408*2a8164dfSZhong Wang syslog(LOG_ERR, "set value failed 2- %s", 409*2a8164dfSZhong Wang scf_strerror(scf_error())); 410*2a8164dfSZhong Wang ret = FCOE_ERROR; 411*2a8164dfSZhong Wang goto out; 412*2a8164dfSZhong Wang } 413*2a8164dfSZhong Wang 414*2a8164dfSZhong Wang /* 415*2a8164dfSZhong Wang * Add the new member 416*2a8164dfSZhong Wang */ 417*2a8164dfSZhong Wang if (scf_entry_add_value(entry, valueSet[i]) == -1) { 418*2a8164dfSZhong Wang syslog(LOG_ERR, "add value failed - %s", 419*2a8164dfSZhong Wang scf_strerror(scf_error())); 420*2a8164dfSZhong Wang ret = FCOE_ERROR; 421*2a8164dfSZhong Wang goto out; 422*2a8164dfSZhong Wang } 423*2a8164dfSZhong Wang } 424*2a8164dfSZhong Wang 425*2a8164dfSZhong Wang if ((commitRet = scf_transaction_commit(tran)) != 1) { 426*2a8164dfSZhong Wang syslog(LOG_ERR, "transaction commit failed - %s", 427*2a8164dfSZhong Wang scf_strerror(scf_error())); 428*2a8164dfSZhong Wang if (commitRet == 0) { 429*2a8164dfSZhong Wang ret = FCOE_ERROR_BUSY; 430*2a8164dfSZhong Wang } else { 431*2a8164dfSZhong Wang ret = FCOE_ERROR; 432*2a8164dfSZhong Wang } 433*2a8164dfSZhong Wang goto out; 434*2a8164dfSZhong Wang } 435*2a8164dfSZhong Wang 436*2a8164dfSZhong Wang out: 437*2a8164dfSZhong Wang /* 438*2a8164dfSZhong Wang * Free resources 439*2a8164dfSZhong Wang */ 440*2a8164dfSZhong Wang if (handle != NULL) { 441*2a8164dfSZhong Wang scf_handle_destroy(handle); 442*2a8164dfSZhong Wang } 443*2a8164dfSZhong Wang if (svc != NULL) { 444*2a8164dfSZhong Wang scf_service_destroy(svc); 445*2a8164dfSZhong Wang } 446*2a8164dfSZhong Wang if (pg != NULL) { 447*2a8164dfSZhong Wang scf_pg_destroy(pg); 448*2a8164dfSZhong Wang } 449*2a8164dfSZhong Wang if (tran != NULL) { 450*2a8164dfSZhong Wang scf_transaction_destroy(tran); 451*2a8164dfSZhong Wang } 452*2a8164dfSZhong Wang if (entry != NULL) { 453*2a8164dfSZhong Wang scf_entry_destroy(entry); 454*2a8164dfSZhong Wang } 455*2a8164dfSZhong Wang if (prop != NULL) { 456*2a8164dfSZhong Wang scf_property_destroy(prop); 457*2a8164dfSZhong Wang } 458*2a8164dfSZhong Wang if (valueIter != NULL) { 459*2a8164dfSZhong Wang scf_iter_destroy(valueIter); 460*2a8164dfSZhong Wang } 461*2a8164dfSZhong Wang if (valueLookup != NULL) { 462*2a8164dfSZhong Wang scf_value_destroy(valueLookup); 463*2a8164dfSZhong Wang } 464*2a8164dfSZhong Wang 465*2a8164dfSZhong Wang /* 466*2a8164dfSZhong Wang * Free valueSet scf resources 467*2a8164dfSZhong Wang */ 468*2a8164dfSZhong Wang if (valueArraySize > 0) { 469*2a8164dfSZhong Wang for (i = 0; i < valueArraySize; i++) { 470*2a8164dfSZhong Wang scf_value_destroy(valueSet[i]); 471*2a8164dfSZhong Wang } 472*2a8164dfSZhong Wang } 473*2a8164dfSZhong Wang /* 474*2a8164dfSZhong Wang * Now free the pointer array to the resources 475*2a8164dfSZhong Wang */ 476*2a8164dfSZhong Wang if (valueSet != NULL) { 477*2a8164dfSZhong Wang free(valueSet); 478*2a8164dfSZhong Wang } 479*2a8164dfSZhong Wang 480*2a8164dfSZhong Wang return (ret); 481*2a8164dfSZhong Wang } 482*2a8164dfSZhong Wang 483*2a8164dfSZhong Wang int 484*2a8164dfSZhong Wang fcoe_adm_create_port(int objects, char *argv[], 485*2a8164dfSZhong Wang cmdOptions_t *options) 486*2a8164dfSZhong Wang { 487*2a8164dfSZhong Wang FCOE_STATUS status = FCOE_STATUS_OK; 488*2a8164dfSZhong Wang uint64_t nodeWWN, portWWN; 489*2a8164dfSZhong Wang FCOE_PORT_WWN pwwn, nwwn; 490*2a8164dfSZhong Wang FCOE_UINT8 macLinkName[FCOE_MAX_MAC_NAME_LEN]; 491*2a8164dfSZhong Wang FCOE_UINT8 promiscuous = 0; 492*2a8164dfSZhong Wang int createini = 0, createtgt = 0; 493*2a8164dfSZhong Wang 494*2a8164dfSZhong Wang /* check the mac name operand */ 495*2a8164dfSZhong Wang assert(objects == 1); 496*2a8164dfSZhong Wang 497*2a8164dfSZhong Wang strcpy((char *)macLinkName, argv[0]); 498*2a8164dfSZhong Wang bzero(&pwwn, 8); 499*2a8164dfSZhong Wang bzero(&nwwn, 8); 500*2a8164dfSZhong Wang 501*2a8164dfSZhong Wang for (; options->optval; options++) { 502*2a8164dfSZhong Wang switch (options->optval) { 503*2a8164dfSZhong Wang case 'i': 504*2a8164dfSZhong Wang createini = 1; 505*2a8164dfSZhong Wang break; 506*2a8164dfSZhong Wang 507*2a8164dfSZhong Wang case 't': 508*2a8164dfSZhong Wang createtgt = 1; 509*2a8164dfSZhong Wang break; 510*2a8164dfSZhong Wang case 'p': 511*2a8164dfSZhong Wang if (!isValidWWN(options->optarg)) { 512*2a8164dfSZhong Wang fprintf(stderr, 513*2a8164dfSZhong Wang gettext("Error: Invalid Port WWN\n")); 514*2a8164dfSZhong Wang return (1); 515*2a8164dfSZhong Wang } 516*2a8164dfSZhong Wang sscanf(options->optarg, "%016llx", &portWWN); 517*2a8164dfSZhong Wang portWWN = htonll(portWWN); 518*2a8164dfSZhong Wang memcpy(&pwwn, &portWWN, sizeof (portWWN)); 519*2a8164dfSZhong Wang break; 520*2a8164dfSZhong Wang 521*2a8164dfSZhong Wang case 'n': 522*2a8164dfSZhong Wang if (!isValidWWN(options->optarg)) { 523*2a8164dfSZhong Wang fprintf(stderr, 524*2a8164dfSZhong Wang gettext("Error: Invalid Node WWN\n")); 525*2a8164dfSZhong Wang return (1); 526*2a8164dfSZhong Wang } 527*2a8164dfSZhong Wang sscanf(options->optarg, "%016llx", &nodeWWN); 528*2a8164dfSZhong Wang nodeWWN = htonll(nodeWWN); 529*2a8164dfSZhong Wang memcpy(&nwwn, &nodeWWN, sizeof (nodeWWN)); 530*2a8164dfSZhong Wang break; 531*2a8164dfSZhong Wang case 'f': 532*2a8164dfSZhong Wang promiscuous = 1; 533*2a8164dfSZhong Wang break; 534*2a8164dfSZhong Wang 535*2a8164dfSZhong Wang default: 536*2a8164dfSZhong Wang fprintf(stderr, gettext("Error: Illegal option: %c\n"), 537*2a8164dfSZhong Wang options->optval); 538*2a8164dfSZhong Wang return (1); 539*2a8164dfSZhong Wang } 540*2a8164dfSZhong Wang } 541*2a8164dfSZhong Wang 542*2a8164dfSZhong Wang if (createini == 1 && createtgt == 1) { 543*2a8164dfSZhong Wang fprintf(stderr, "Error: Option -i and -t should " 544*2a8164dfSZhong Wang "not be both specified\n"); 545*2a8164dfSZhong Wang return (1); 546*2a8164dfSZhong Wang } 547*2a8164dfSZhong Wang status = FCOE_CreatePort(macLinkName, 548*2a8164dfSZhong Wang createtgt == 1 ? FCOE_PORTTYPE_TARGET : 549*2a8164dfSZhong Wang FCOE_PORTTYPE_INITIATOR, pwwn, nwwn, promiscuous); 550*2a8164dfSZhong Wang 551*2a8164dfSZhong Wang if (status != FCOE_STATUS_OK) { 552*2a8164dfSZhong Wang switch (status) { 553*2a8164dfSZhong Wang case FCOE_STATUS_ERROR_BUSY: 554*2a8164dfSZhong Wang fprintf(stderr, 555*2a8164dfSZhong Wang gettext("Error: fcoe driver is busy\n")); 556*2a8164dfSZhong Wang break; 557*2a8164dfSZhong Wang 558*2a8164dfSZhong Wang case FCOE_STATUS_ERROR_ALREADY: 559*2a8164dfSZhong Wang fprintf(stderr, 560*2a8164dfSZhong Wang gettext("Error: Existing FCoE port " 561*2a8164dfSZhong Wang "found on the specified MAC link\n")); 562*2a8164dfSZhong Wang break; 563*2a8164dfSZhong Wang 564*2a8164dfSZhong Wang case FCOE_STATUS_ERROR_PERM: 565*2a8164dfSZhong Wang fprintf(stderr, 566*2a8164dfSZhong Wang gettext("Error: Not enough permission to " 567*2a8164dfSZhong Wang "open fcoe device\n")); 568*2a8164dfSZhong Wang break; 569*2a8164dfSZhong Wang 570*2a8164dfSZhong Wang case FCOE_STATUS_ERROR_OPEN_DEV: 571*2a8164dfSZhong Wang fprintf(stderr, 572*2a8164dfSZhong Wang gettext("Error: Failed to open fcoe device\n")); 573*2a8164dfSZhong Wang break; 574*2a8164dfSZhong Wang 575*2a8164dfSZhong Wang case FCOE_STATUS_ERROR_WWN_SAME: 576*2a8164dfSZhong Wang fprintf(stderr, 577*2a8164dfSZhong Wang gettext("Error: Port WWN is same as Node " 578*2a8164dfSZhong Wang "WWN\n")); 579*2a8164dfSZhong Wang break; 580*2a8164dfSZhong Wang 581*2a8164dfSZhong Wang case FCOE_STATUS_ERROR_MAC_LEN: 582*2a8164dfSZhong Wang fprintf(stderr, 583*2a8164dfSZhong Wang gettext("Error: MAC name exceeds maximum " 584*2a8164dfSZhong Wang "length\n")); 585*2a8164dfSZhong Wang break; 586*2a8164dfSZhong Wang 587*2a8164dfSZhong Wang case FCOE_STATUS_ERROR_PWWN_CONFLICTED: 588*2a8164dfSZhong Wang fprintf(stderr, 589*2a8164dfSZhong Wang gettext("Error: The specified Port WWN " 590*2a8164dfSZhong Wang "is already in use\n")); 591*2a8164dfSZhong Wang break; 592*2a8164dfSZhong Wang 593*2a8164dfSZhong Wang case FCOE_STATUS_ERROR_NWWN_CONFLICTED: 594*2a8164dfSZhong Wang fprintf(stderr, 595*2a8164dfSZhong Wang gettext("Error: The specified Node WWN " 596*2a8164dfSZhong Wang "is already in use\n")); 597*2a8164dfSZhong Wang break; 598*2a8164dfSZhong Wang 599*2a8164dfSZhong Wang case FCOE_STATUS_ERROR_NEED_JUMBO_FRAME: 600*2a8164dfSZhong Wang fprintf(stderr, 601*2a8164dfSZhong Wang gettext("Error: MTU size of the specified " 602*2a8164dfSZhong Wang "MAC link needs to be increased to 2500 " 603*2a8164dfSZhong Wang "or above\n")); 604*2a8164dfSZhong Wang break; 605*2a8164dfSZhong Wang 606*2a8164dfSZhong Wang case FCOE_STATUS_ERROR_CREATE_MAC: 607*2a8164dfSZhong Wang fprintf(stderr, 608*2a8164dfSZhong Wang gettext("Error: Out of memory\n")); 609*2a8164dfSZhong Wang break; 610*2a8164dfSZhong Wang 611*2a8164dfSZhong Wang 612*2a8164dfSZhong Wang case FCOE_STATUS_ERROR_OPEN_MAC: 613*2a8164dfSZhong Wang fprintf(stderr, 614*2a8164dfSZhong Wang gettext("Error: Failed to open the " 615*2a8164dfSZhong Wang "specified MAC link\n")); 616*2a8164dfSZhong Wang break; 617*2a8164dfSZhong Wang 618*2a8164dfSZhong Wang case FCOE_STATUS_ERROR_CREATE_PORT: 619*2a8164dfSZhong Wang fprintf(stderr, 620*2a8164dfSZhong Wang gettext("Error: Failed to create FCoE " 621*2a8164dfSZhong Wang "port on the specified MAC link\n")); 622*2a8164dfSZhong Wang break; 623*2a8164dfSZhong Wang 624*2a8164dfSZhong Wang case FCOE_STATUS_ERROR_VNIC_UNSUPPORT: 625*2a8164dfSZhong Wang fprintf(stderr, 626*2a8164dfSZhong Wang gettext("Error: VNIC is not supported\n")); 627*2a8164dfSZhong Wang break; 628*2a8164dfSZhong Wang 629*2a8164dfSZhong Wang case FCOE_STATUS_ERROR: 630*2a8164dfSZhong Wang default: 631*2a8164dfSZhong Wang fprintf(stderr, 632*2a8164dfSZhong Wang gettext("Error: Due to reason code %d\n"), status); 633*2a8164dfSZhong Wang } 634*2a8164dfSZhong Wang return (1); 635*2a8164dfSZhong Wang } else { 636*2a8164dfSZhong Wang char cpwwn[17], cnwwn[17]; 637*2a8164dfSZhong Wang 638*2a8164dfSZhong Wang WWN2str(cpwwn, &pwwn); 639*2a8164dfSZhong Wang WWN2str(cnwwn, &nwwn); 640*2a8164dfSZhong Wang 641*2a8164dfSZhong Wang fcoe_adm_add_remove_scf_entry((char *)macLinkName, 642*2a8164dfSZhong Wang cpwwn, 643*2a8164dfSZhong Wang cnwwn, 644*2a8164dfSZhong Wang createtgt, 645*2a8164dfSZhong Wang promiscuous, 646*2a8164dfSZhong Wang FCOE_SCF_ADD); 647*2a8164dfSZhong Wang return (0); 648*2a8164dfSZhong Wang } 649*2a8164dfSZhong Wang } 650*2a8164dfSZhong Wang 651*2a8164dfSZhong Wang int 652*2a8164dfSZhong Wang fcoe_adm_delete_port(int objects, char *argv[]) 653*2a8164dfSZhong Wang { 654*2a8164dfSZhong Wang FCOE_STATUS status; 655*2a8164dfSZhong Wang FCOE_UINT8 *macLinkName; 656*2a8164dfSZhong Wang 657*2a8164dfSZhong Wang /* check the mac name operand */ 658*2a8164dfSZhong Wang assert(objects == 1); 659*2a8164dfSZhong Wang 660*2a8164dfSZhong Wang macLinkName = (FCOE_UINT8 *) argv[0]; 661*2a8164dfSZhong Wang 662*2a8164dfSZhong Wang status = FCOE_DeletePort(macLinkName); 663*2a8164dfSZhong Wang if (status != FCOE_STATUS_OK) { 664*2a8164dfSZhong Wang switch (status) { 665*2a8164dfSZhong Wang case FCOE_STATUS_ERROR_BUSY: 666*2a8164dfSZhong Wang fprintf(stderr, 667*2a8164dfSZhong Wang gettext("Error: fcoe driver is busy\n")); 668*2a8164dfSZhong Wang break; 669*2a8164dfSZhong Wang 670*2a8164dfSZhong Wang case FCOE_STATUS_ERROR_ALREADY: 671*2a8164dfSZhong Wang fprintf(stderr, 672*2a8164dfSZhong Wang gettext("Error: FCoE port not found on the " 673*2a8164dfSZhong Wang "specified MAC link\n")); 674*2a8164dfSZhong Wang break; 675*2a8164dfSZhong Wang 676*2a8164dfSZhong Wang case FCOE_STATUS_ERROR_PERM: 677*2a8164dfSZhong Wang fprintf(stderr, 678*2a8164dfSZhong Wang gettext("Error: Not enough permission to " 679*2a8164dfSZhong Wang "open fcoe device\n")); 680*2a8164dfSZhong Wang break; 681*2a8164dfSZhong Wang 682*2a8164dfSZhong Wang case FCOE_STATUS_ERROR_MAC_LEN: 683*2a8164dfSZhong Wang fprintf(stderr, 684*2a8164dfSZhong Wang gettext("Failed: MAC name exceeds maximum " 685*2a8164dfSZhong Wang "length 32\n")); 686*2a8164dfSZhong Wang break; 687*2a8164dfSZhong Wang 688*2a8164dfSZhong Wang case FCOE_STATUS_ERROR_OPEN_DEV: 689*2a8164dfSZhong Wang fprintf(stderr, 690*2a8164dfSZhong Wang gettext("Error: Failed to open fcoe device\n")); 691*2a8164dfSZhong Wang break; 692*2a8164dfSZhong Wang 693*2a8164dfSZhong Wang case FCOE_STATUS_ERROR_MAC_NOT_FOUND: 694*2a8164dfSZhong Wang fprintf(stderr, 695*2a8164dfSZhong Wang gettext("Error: FCoE port not found on the " 696*2a8164dfSZhong Wang "specified MAC link\n")); 697*2a8164dfSZhong Wang break; 698*2a8164dfSZhong Wang 699*2a8164dfSZhong Wang case FCOE_STATUS_ERROR_OFFLINE_DEV: 700*2a8164dfSZhong Wang fprintf(stderr, 701*2a8164dfSZhong Wang gettext("Error: Please use stmfadm to offline " 702*2a8164dfSZhong Wang "the FCoE target first\n")); 703*2a8164dfSZhong Wang break; 704*2a8164dfSZhong Wang 705*2a8164dfSZhong Wang case FCOE_STATUS_ERROR: 706*2a8164dfSZhong Wang default: 707*2a8164dfSZhong Wang fprintf(stderr, 708*2a8164dfSZhong Wang gettext("Error: Due to reason code %d\n"), status); 709*2a8164dfSZhong Wang } 710*2a8164dfSZhong Wang return (1); 711*2a8164dfSZhong Wang } else { 712*2a8164dfSZhong Wang fcoe_adm_add_remove_scf_entry((char *)macLinkName, 713*2a8164dfSZhong Wang "", 714*2a8164dfSZhong Wang "", 715*2a8164dfSZhong Wang 0, 716*2a8164dfSZhong Wang 0, 717*2a8164dfSZhong Wang FCOE_SCF_REMOVE); 718*2a8164dfSZhong Wang return (0); 719*2a8164dfSZhong Wang } 720*2a8164dfSZhong Wang } 721*2a8164dfSZhong Wang 722*2a8164dfSZhong Wang int 723*2a8164dfSZhong Wang fcoe_adm_list_ports(cmdOptions_t *options) 724*2a8164dfSZhong Wang { 725*2a8164dfSZhong Wang FCOE_STATUS status; 726*2a8164dfSZhong Wang int showini = 0, showtgt = 0; 727*2a8164dfSZhong Wang FCOE_UINT32 port_num; 728*2a8164dfSZhong Wang FCOE_PORT_ATTRIBUTE *portlist = NULL; 729*2a8164dfSZhong Wang int i; 730*2a8164dfSZhong Wang int ret; 731*2a8164dfSZhong Wang 732*2a8164dfSZhong Wang for (; options->optval; options++) { 733*2a8164dfSZhong Wang switch (options->optval) { 734*2a8164dfSZhong Wang case 'i': 735*2a8164dfSZhong Wang showini = 1; 736*2a8164dfSZhong Wang break; 737*2a8164dfSZhong Wang 738*2a8164dfSZhong Wang case 't': 739*2a8164dfSZhong Wang showtgt = 1; 740*2a8164dfSZhong Wang break; 741*2a8164dfSZhong Wang 742*2a8164dfSZhong Wang default: 743*2a8164dfSZhong Wang fprintf(stderr, gettext("Error: Illegal option: %c\n"), 744*2a8164dfSZhong Wang options->optval); 745*2a8164dfSZhong Wang return (1); 746*2a8164dfSZhong Wang } 747*2a8164dfSZhong Wang } 748*2a8164dfSZhong Wang if (showini == 0 && showtgt == 0) { 749*2a8164dfSZhong Wang showini = 1; 750*2a8164dfSZhong Wang showtgt = 1; 751*2a8164dfSZhong Wang } 752*2a8164dfSZhong Wang 753*2a8164dfSZhong Wang status = FCOE_GetPortList(&port_num, &portlist); 754*2a8164dfSZhong Wang 755*2a8164dfSZhong Wang if (status != FCOE_STATUS_OK) { 756*2a8164dfSZhong Wang switch (status) { 757*2a8164dfSZhong Wang case FCOE_STATUS_ERROR_BUSY: 758*2a8164dfSZhong Wang fprintf(stderr, 759*2a8164dfSZhong Wang gettext("Error: fcoe driver is busy\n")); 760*2a8164dfSZhong Wang break; 761*2a8164dfSZhong Wang 762*2a8164dfSZhong Wang case FCOE_STATUS_ERROR_PERM: 763*2a8164dfSZhong Wang fprintf(stderr, 764*2a8164dfSZhong Wang gettext("Error: Not enough permission to " 765*2a8164dfSZhong Wang "open fcoe device\n")); 766*2a8164dfSZhong Wang break; 767*2a8164dfSZhong Wang 768*2a8164dfSZhong Wang case FCOE_STATUS_ERROR_OPEN_DEV: 769*2a8164dfSZhong Wang fprintf(stderr, 770*2a8164dfSZhong Wang gettext("Error: Failed to open fcoe device\n")); 771*2a8164dfSZhong Wang break; 772*2a8164dfSZhong Wang 773*2a8164dfSZhong Wang case FCOE_STATUS_ERROR_INVAL_ARG: 774*2a8164dfSZhong Wang fprintf(stderr, 775*2a8164dfSZhong Wang gettext("Error: Invalid argument\n")); 776*2a8164dfSZhong Wang break; 777*2a8164dfSZhong Wang 778*2a8164dfSZhong Wang case FCOE_STATUS_ERROR_MORE_DATA: 779*2a8164dfSZhong Wang fprintf(stderr, 780*2a8164dfSZhong Wang gettext("Error: More data\n")); 781*2a8164dfSZhong Wang break; 782*2a8164dfSZhong Wang 783*2a8164dfSZhong Wang case FCOE_STATUS_ERROR: 784*2a8164dfSZhong Wang default: 785*2a8164dfSZhong Wang fprintf(stderr, 786*2a8164dfSZhong Wang gettext("Error: Due to reason code %d\n"), status); 787*2a8164dfSZhong Wang } 788*2a8164dfSZhong Wang ret = 1; 789*2a8164dfSZhong Wang } else { 790*2a8164dfSZhong Wang if (port_num == 0) { 791*2a8164dfSZhong Wang fprintf(stdout, gettext("No FCoE Ports Found!\n")); 792*2a8164dfSZhong Wang } else { 793*2a8164dfSZhong Wang for (i = 0; i < port_num; i++) { 794*2a8164dfSZhong Wang if ((portlist[i].port_type == 795*2a8164dfSZhong Wang FCOE_PORTTYPE_INITIATOR && 796*2a8164dfSZhong Wang showini == 1) || (showtgt == 1 && 797*2a8164dfSZhong Wang portlist[i].port_type == 798*2a8164dfSZhong Wang FCOE_PORTTYPE_TARGET)) { 799*2a8164dfSZhong Wang printFCOEPortInfo(&portlist[i]); 800*2a8164dfSZhong Wang } 801*2a8164dfSZhong Wang } 802*2a8164dfSZhong Wang } 803*2a8164dfSZhong Wang ret = 0; 804*2a8164dfSZhong Wang } 805*2a8164dfSZhong Wang 806*2a8164dfSZhong Wang if (portlist != NULL) { 807*2a8164dfSZhong Wang free(portlist); 808*2a8164dfSZhong Wang } 809*2a8164dfSZhong Wang return (ret); 810*2a8164dfSZhong Wang 811*2a8164dfSZhong Wang } 812*2a8164dfSZhong Wang 813*2a8164dfSZhong Wang int 814*2a8164dfSZhong Wang fcoe_adm_create_portlist(cmdOptions_t *options) 815*2a8164dfSZhong Wang { 816*2a8164dfSZhong Wang scf_handle_t *handle = NULL; 817*2a8164dfSZhong Wang scf_service_t *svc = NULL; 818*2a8164dfSZhong Wang scf_propertygroup_t *pg = NULL; 819*2a8164dfSZhong Wang scf_transaction_t *tran = NULL; 820*2a8164dfSZhong Wang scf_transaction_entry_t *entry = NULL; 821*2a8164dfSZhong Wang scf_property_t *prop = NULL; 822*2a8164dfSZhong Wang scf_value_t *valueLookup = NULL; 823*2a8164dfSZhong Wang scf_iter_t *valueIter = NULL; 824*2a8164dfSZhong Wang char buf[FCOE_PORT_LIST_LENGTH] = {0}; 825*2a8164dfSZhong Wang int commitRet; 826*2a8164dfSZhong Wang int create_target = 0, create_initiator = 0; 827*2a8164dfSZhong Wang 828*2a8164dfSZhong Wang /* Check what type of port list will be created */ 829*2a8164dfSZhong Wang for (; options->optval; options++) { 830*2a8164dfSZhong Wang switch (options->optval) { 831*2a8164dfSZhong Wang case 'i': 832*2a8164dfSZhong Wang create_initiator = 1; 833*2a8164dfSZhong Wang break; 834*2a8164dfSZhong Wang case 't': 835*2a8164dfSZhong Wang create_target = 1; 836*2a8164dfSZhong Wang break; 837*2a8164dfSZhong Wang default: 838*2a8164dfSZhong Wang fprintf(stderr, gettext("Error: Illegal option: %c\n"), 839*2a8164dfSZhong Wang options->optval); 840*2a8164dfSZhong Wang return (1); 841*2a8164dfSZhong Wang } 842*2a8164dfSZhong Wang } 843*2a8164dfSZhong Wang 844*2a8164dfSZhong Wang if (create_initiator == 0 && create_target == 0) { 845*2a8164dfSZhong Wang create_initiator = 1; 846*2a8164dfSZhong Wang create_target = 1; 847*2a8164dfSZhong Wang } 848*2a8164dfSZhong Wang 849*2a8164dfSZhong Wang commitRet = fcoe_cfg_scf_init(&handle, &svc); 850*2a8164dfSZhong Wang if (commitRet != FCOE_SUCCESS) { 851*2a8164dfSZhong Wang goto out; 852*2a8164dfSZhong Wang } 853*2a8164dfSZhong Wang 854*2a8164dfSZhong Wang if (((pg = scf_pg_create(handle)) == NULL) || 855*2a8164dfSZhong Wang ((tran = scf_transaction_create(handle)) == NULL) || 856*2a8164dfSZhong Wang ((entry = scf_entry_create(handle)) == NULL) || 857*2a8164dfSZhong Wang ((prop = scf_property_create(handle)) == NULL) || 858*2a8164dfSZhong Wang ((valueIter = scf_iter_create(handle)) == NULL)) { 859*2a8164dfSZhong Wang goto out; 860*2a8164dfSZhong Wang } 861*2a8164dfSZhong Wang 862*2a8164dfSZhong Wang /* get property group or create it */ 863*2a8164dfSZhong Wang if (scf_service_get_pg(svc, FCOE_PG_NAME, pg) == -1) { 864*2a8164dfSZhong Wang goto out; 865*2a8164dfSZhong Wang } 866*2a8164dfSZhong Wang 867*2a8164dfSZhong Wang if (scf_pg_get_property(pg, FCOE_PORT_LIST, prop) == -1) { 868*2a8164dfSZhong Wang syslog(LOG_ERR, "get property failed - %s", 869*2a8164dfSZhong Wang scf_strerror(scf_error())); 870*2a8164dfSZhong Wang goto out; 871*2a8164dfSZhong Wang } 872*2a8164dfSZhong Wang 873*2a8164dfSZhong Wang valueLookup = scf_value_create(handle); 874*2a8164dfSZhong Wang if (valueLookup == NULL) { 875*2a8164dfSZhong Wang syslog(LOG_ERR, "scf value alloc failed - %s", 876*2a8164dfSZhong Wang scf_strerror(scf_error())); 877*2a8164dfSZhong Wang goto out; 878*2a8164dfSZhong Wang } 879*2a8164dfSZhong Wang 880*2a8164dfSZhong Wang if (scf_iter_property_values(valueIter, prop) == -1) { 881*2a8164dfSZhong Wang syslog(LOG_ERR, "iter value failed - %s", 882*2a8164dfSZhong Wang scf_strerror(scf_error())); 883*2a8164dfSZhong Wang goto out; 884*2a8164dfSZhong Wang } 885*2a8164dfSZhong Wang while (scf_iter_next_value(valueIter, valueLookup) == 1) { 886*2a8164dfSZhong Wang uint8_t *macLinkName = NULL; 887*2a8164dfSZhong Wang char *remainder = NULL; 888*2a8164dfSZhong Wang FCOE_PORT_WWN pwwn, nwwn; 889*2a8164dfSZhong Wang uint64_t nodeWWN, portWWN; 890*2a8164dfSZhong Wang int is_target, is_promiscuous; 891*2a8164dfSZhong Wang 892*2a8164dfSZhong Wang bzero(buf, sizeof (buf)); 893*2a8164dfSZhong Wang bzero(&pwwn, sizeof (pwwn)); 894*2a8164dfSZhong Wang bzero(&nwwn, sizeof (nwwn)); 895*2a8164dfSZhong Wang if (scf_value_get_ustring(valueLookup, buf, MAXNAMELEN) == -1) { 896*2a8164dfSZhong Wang syslog(LOG_ERR, "iter value failed - %s", 897*2a8164dfSZhong Wang scf_strerror(scf_error())); 898*2a8164dfSZhong Wang break; 899*2a8164dfSZhong Wang } 900*2a8164dfSZhong Wang macLinkName = (uint8_t *)strtok(buf, ":"); 901*2a8164dfSZhong Wang remainder = strtok(NULL, "#"); 902*2a8164dfSZhong Wang sscanf(remainder, "%016llx:%016llx:%d:%d", 903*2a8164dfSZhong Wang &portWWN, &nodeWWN, &is_target, &is_promiscuous); 904*2a8164dfSZhong Wang if ((!create_target && is_target) || 905*2a8164dfSZhong Wang (!create_initiator && !is_target)) { 906*2a8164dfSZhong Wang continue; 907*2a8164dfSZhong Wang } 908*2a8164dfSZhong Wang 909*2a8164dfSZhong Wang nodeWWN = htonll(nodeWWN); 910*2a8164dfSZhong Wang memcpy(&nwwn, &nodeWWN, sizeof (nodeWWN)); 911*2a8164dfSZhong Wang portWWN = htonll(portWWN); 912*2a8164dfSZhong Wang memcpy(&pwwn, &portWWN, sizeof (portWWN)); 913*2a8164dfSZhong Wang 914*2a8164dfSZhong Wang FCOE_CreatePort(macLinkName, 915*2a8164dfSZhong Wang is_target ? FCOE_PORTTYPE_TARGET : FCOE_PORTTYPE_INITIATOR, 916*2a8164dfSZhong Wang pwwn, nwwn, is_promiscuous); 917*2a8164dfSZhong Wang } 918*2a8164dfSZhong Wang 919*2a8164dfSZhong Wang out: 920*2a8164dfSZhong Wang /* 921*2a8164dfSZhong Wang * Free resources 922*2a8164dfSZhong Wang */ 923*2a8164dfSZhong Wang if (handle != NULL) { 924*2a8164dfSZhong Wang scf_handle_destroy(handle); 925*2a8164dfSZhong Wang } 926*2a8164dfSZhong Wang if (svc != NULL) { 927*2a8164dfSZhong Wang scf_service_destroy(svc); 928*2a8164dfSZhong Wang } 929*2a8164dfSZhong Wang if (pg != NULL) { 930*2a8164dfSZhong Wang scf_pg_destroy(pg); 931*2a8164dfSZhong Wang } 932*2a8164dfSZhong Wang if (tran != NULL) { 933*2a8164dfSZhong Wang scf_transaction_destroy(tran); 934*2a8164dfSZhong Wang } 935*2a8164dfSZhong Wang if (entry != NULL) { 936*2a8164dfSZhong Wang scf_entry_destroy(entry); 937*2a8164dfSZhong Wang } 938*2a8164dfSZhong Wang if (prop != NULL) { 939*2a8164dfSZhong Wang scf_property_destroy(prop); 940*2a8164dfSZhong Wang } 941*2a8164dfSZhong Wang if (valueIter != NULL) { 942*2a8164dfSZhong Wang scf_iter_destroy(valueIter); 943*2a8164dfSZhong Wang } 944*2a8164dfSZhong Wang if (valueLookup != NULL) { 945*2a8164dfSZhong Wang scf_value_destroy(valueLookup); 946*2a8164dfSZhong Wang } 947*2a8164dfSZhong Wang 948*2a8164dfSZhong Wang return (0); 949*2a8164dfSZhong Wang } 950