1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <sys/cpuvar.h> 27 #include <sys/types.h> 28 #include <sys/conf.h> 29 #include <sys/file.h> 30 #include <sys/ddi.h> 31 #include <sys/sunddi.h> 32 #include <sys/socket.h> 33 #include <inet/tcp.h> 34 #include <sys/sdt.h> 35 36 #include <sys/stmf.h> 37 #include <sys/stmf_ioctl.h> 38 #include <sys/portif.h> 39 #include <sys/idm/idm.h> 40 #include <sys/idm/idm_so.h> 41 #include <sys/iscsit/iscsit_common.h> 42 #include <sys/iscsit/isns_protocol.h> 43 #include <iscsit.h> 44 #include <iscsit_isns.h> 45 46 /* local defines */ 47 #define MAX_XID (2^16) 48 #define ISNS_IDLE_TIME 60 49 #define MAX_RETRY (3) 50 51 #define VALID_NAME(NAME, LEN) \ 52 ((LEN) > 0 && (NAME)[0] != 0 && (NAME)[(LEN) - 1] == 0) 53 54 static kmutex_t isns_mutex; 55 static kthread_t *isns_monitor_thr_id; 56 57 static kcondvar_t isns_idle_cv; 58 static boolean_t isns_idle; 59 60 static uint16_t xid; 61 #define GET_XID() atomic_inc_16_nv(&xid) 62 63 static clock_t monitor_idle_interval; 64 65 #define ISNS_GLOBAL_LOCK() \ 66 mutex_enter(&iscsit_global.global_isns_cfg.isns_mutex) 67 68 #define ISNS_GLOBAL_LOCK_HELD() \ 69 MUTEX_HELD(&iscsit_global.global_isns_cfg.isns_mutex) 70 71 #define ISNS_GLOBAL_UNLOCK() \ 72 mutex_exit(&iscsit_global.global_isns_cfg.isns_mutex) 73 74 /* 75 * iSNS ESI thread state 76 */ 77 78 static kmutex_t isns_esi_mutex; 79 static kcondvar_t isns_esi_cv; 80 static list_t esi_list; 81 static uint32_t isns_esi_max_interval = 0; 82 83 /* 84 * List of portals. 85 */ 86 87 static list_t portal_list; 88 static uint32_t portal_list_count = 0; 89 90 /* How many of our portals are not "default"? */ 91 static uint32_t nondefault_portals = 0; 92 93 /* 94 * Our entity identifier (fully-qualified hostname) 95 */ 96 static char *isns_eid = NULL; 97 98 /* 99 * Our list of targets 100 */ 101 static avl_tree_t isns_target_list; 102 103 static void 104 isnst_start(); 105 106 static void 107 isnst_stop(); 108 109 static void 110 iscsit_set_isns(boolean_t state); 111 112 static int 113 iscsit_add_isns(it_portal_t *cfg_svr); 114 115 static void 116 iscsit_delete_isns(iscsit_isns_svr_t *svr); 117 118 static iscsit_isns_svr_t * 119 iscsit_isns_svr_lookup(struct sockaddr_storage *sa); 120 121 static void 122 isnst_monitor(void *arg); 123 124 static int 125 isnst_monitor_one_server(iscsit_isns_svr_t *svr, boolean_t enabled); 126 127 static int 128 isnst_update_target(iscsit_tgt_t *target, isns_reg_type_t reg); 129 130 static int 131 isnst_update_one_server(iscsit_isns_svr_t *svr, iscsit_tgt_t *target, 132 isns_reg_type_t reg); 133 134 static int isnst_register(iscsit_isns_svr_t *svr, iscsit_tgt_t *target, 135 isns_reg_type_t regtype); 136 static int isnst_deregister(iscsit_isns_svr_t *svr, char *node); 137 138 static size_t 139 isnst_make_dereg_pdu(isns_pdu_t **pdu, char *node); 140 141 static int 142 isnst_verify_rsp(isns_pdu_t *pdu, isns_pdu_t *rsp); 143 144 static uint16_t 145 isnst_pdu_get_op(isns_pdu_t *pdu, uint8_t **pp); 146 147 static size_t 148 isnst_make_reg_pdu(isns_pdu_t **pdu, iscsit_tgt_t *target, 149 boolean_t svr_registered, isns_reg_type_t regtype); 150 151 static size_t 152 isnst_create_pdu_header(uint16_t func_id, isns_pdu_t **pdu, uint16_t flags); 153 154 static int 155 isnst_add_attr(isns_pdu_t *pdu, 156 size_t max_pdu_size, 157 uint32_t attr_id, 158 uint32_t attr_len, 159 void *attr_data, 160 uint32_t attr_numeric_data); 161 162 static int 163 isnst_send_pdu(void *so, isns_pdu_t *pdu); 164 165 static size_t 166 isnst_rcv_pdu(void *so, isns_pdu_t **pdu); 167 168 static void * 169 isnst_open_so(struct sockaddr_storage *sa); 170 171 static void 172 isnst_close_so(void *); 173 174 static void 175 isnst_esi_thread(void *arg); 176 177 static boolean_t 178 isnst_handle_esi_req(struct sonode *so, isns_pdu_t *pdu, size_t pl_size); 179 180 static void isnst_esi_start(isns_portal_list_t *portal); 181 static void isnst_esi_stop(); 182 static void isnst_esi_stop_thread(isns_esi_tinfo_t *tinfop); 183 static void isnst_esi_check(); 184 static void isnst_esi_start_thread(isns_esi_tinfo_t *tinfop); 185 static isns_target_t *isnst_add_to_target_list(iscsit_tgt_t *target); 186 int isnst_tgt_avl_compare(const void *t1, const void *t2); 187 static void isnst_get_target_list(void); 188 static void isnst_set_server_status(iscsit_isns_svr_t *svr, 189 boolean_t registered); 190 static void isnst_wakeup_monitor(void); 191 static void isns_remove_portal(isns_portal_list_t *p); 192 static void isnst_add_default_portals(); 193 static int isnst_add_default_portal_attrs(isns_pdu_t *pdu, size_t pdu_size); 194 static void isnst_remove_default_portals(); 195 static boolean_t isnst_retry_registration(int rsp_status_code); 196 197 it_cfg_status_t 198 isnst_config_merge(it_config_t *cfg) 199 { 200 boolean_t new_isns_state = B_FALSE; 201 iscsit_isns_svr_t *isns_svr, *next_isns_svr; 202 it_portal_t *cfg_isns_svr; 203 204 /* 205 * Determine whether iSNS is enabled in the new config. 206 * Isns property may not be set up yet. 207 */ 208 (void) nvlist_lookup_boolean_value(cfg->config_global_properties, 209 PROP_ISNS_ENABLED, &new_isns_state); 210 211 ISNS_GLOBAL_LOCK(); 212 213 /* Delete iSNS servers that are no longer part of the config */ 214 for (isns_svr = list_head(&iscsit_global.global_isns_cfg.isns_svrs); 215 isns_svr != NULL; 216 isns_svr = next_isns_svr) { 217 next_isns_svr = list_next( 218 &iscsit_global.global_isns_cfg.isns_svrs, isns_svr); 219 if (it_sns_svr_lookup(cfg, &isns_svr->svr_sa) == NULL) 220 iscsit_delete_isns(isns_svr); 221 } 222 223 /* Add new iSNS servers */ 224 for (cfg_isns_svr = cfg->config_isns_svr_list; 225 cfg_isns_svr != NULL; 226 cfg_isns_svr = cfg_isns_svr->next) { 227 isns_svr = iscsit_isns_svr_lookup(&cfg_isns_svr->portal_addr); 228 if (isns_svr == NULL) { 229 if (iscsit_add_isns(cfg_isns_svr) != 0) { 230 /* Shouldn't happen */ 231 ISNS_GLOBAL_UNLOCK(); 232 return (ITCFG_MISC_ERR); 233 } 234 } 235 } 236 237 /* Start/Stop iSNS if necessary */ 238 if (iscsit_global.global_isns_cfg.isns_state != new_isns_state) { 239 iscsit_set_isns(new_isns_state); 240 } 241 242 ISNS_GLOBAL_UNLOCK(); 243 244 /* 245 * There is no "modify case" since the user specifies a complete 246 * server list each time. A modify is the same as a remove+add. 247 */ 248 249 return (0); 250 } 251 252 int 253 iscsit_isns_init(iscsit_hostinfo_t *hostinfo) 254 { 255 mutex_init(&iscsit_global.global_isns_cfg.isns_mutex, NULL, 256 MUTEX_DEFAULT, NULL); 257 258 ISNS_GLOBAL_LOCK(); 259 iscsit_global.global_isns_cfg.isns_state = B_FALSE; 260 list_create(&iscsit_global.global_isns_cfg.isns_svrs, 261 sizeof (iscsit_isns_svr_t), offsetof(iscsit_isns_svr_t, svr_ln)); 262 list_create(&portal_list, sizeof (isns_portal_list_t), 263 offsetof(isns_portal_list_t, portal_ln)); 264 list_create(&esi_list, sizeof (isns_esi_tinfo_t), 265 offsetof(isns_esi_tinfo_t, esi_ln)); 266 portal_list_count = 0; 267 isns_eid = kmem_alloc(hostinfo->length, KM_SLEEP); 268 if (hostinfo->length > ISCSIT_MAX_HOSTNAME_LEN) 269 hostinfo->length = ISCSIT_MAX_HOSTNAME_LEN; 270 (void) strlcpy(isns_eid, hostinfo->fqhn, hostinfo->length); 271 avl_create(&isns_target_list, isnst_tgt_avl_compare, 272 sizeof (isns_target_t), offsetof(isns_target_t, target_node)); 273 /* 274 * The iscsi global lock is not held here, but it is held when 275 * isnst_start is called, so we need to acquire it only in this 276 * case. 277 */ 278 ISCSIT_GLOBAL_LOCK(RW_READER); 279 isnst_get_target_list(); 280 ISCSIT_GLOBAL_UNLOCK(); 281 282 /* initialize isns client */ 283 mutex_init(&isns_mutex, NULL, MUTEX_DEFAULT, NULL); 284 mutex_init(&isns_esi_mutex, NULL, MUTEX_DEFAULT, NULL); 285 isns_monitor_thr_id = NULL; 286 monitor_idle_interval = ISNS_IDLE_TIME * drv_usectohz(1000000); 287 cv_init(&isns_idle_cv, NULL, CV_DEFAULT, NULL); 288 cv_init(&isns_esi_cv, NULL, CV_DEFAULT, NULL); 289 isns_idle = B_TRUE; 290 xid = 0; 291 ISNS_GLOBAL_UNLOCK(); 292 293 return (0); 294 } 295 296 static void 297 isnst_esi_stop_thread(isns_esi_tinfo_t *tinfop) 298 { 299 ASSERT(ISNS_GLOBAL_LOCK_HELD()); 300 ASSERT(mutex_owned(&isns_esi_mutex)); 301 302 list_remove(&esi_list, tinfop); 303 304 /* 305 * The only way to break a thread waiting in soaccept() is to signal 306 * it with EINTR. See idm_so_tgt_svc_offline for more detail. 307 */ 308 tinfop->esi_so->so_error = EINTR; 309 cv_signal(&tinfop->esi_so->so_connind_cv); 310 311 /* 312 * Must also drop the global lock in case the esi thread is running 313 * and trying to update the server timestamps. 314 */ 315 mutex_exit(&isns_esi_mutex); 316 ISNS_GLOBAL_UNLOCK(); 317 thread_join(tinfop->esi_thread_did); 318 ISNS_GLOBAL_LOCK(); 319 mutex_enter(&isns_esi_mutex); 320 321 tinfop->esi_portal->portal_esi = NULL; 322 kmem_free(tinfop, sizeof (isns_esi_tinfo_t)); 323 } 324 325 static void 326 isnst_esi_stop() 327 { 328 /* 329 * Basically, we just wait for all the threads to stop. They 330 * should already be in the process of shutting down. 331 */ 332 333 ASSERT(ISNS_GLOBAL_LOCK_HELD()); 334 335 ISNS_GLOBAL_UNLOCK(); 336 mutex_enter(&isns_esi_mutex); 337 while (!list_is_empty(&esi_list)) { 338 cv_wait(&isns_esi_cv, &isns_esi_mutex); 339 } 340 mutex_exit(&isns_esi_mutex); 341 ISNS_GLOBAL_LOCK(); 342 } 343 344 void 345 iscsit_isns_fini() 346 { 347 ISNS_GLOBAL_LOCK(); 348 iscsit_set_isns(B_FALSE); 349 ISNS_GLOBAL_UNLOCK(); 350 351 mutex_enter(&isns_mutex); 352 while (isns_monitor_thr_id != NULL) { 353 cv_wait(&isns_idle_cv, &isns_mutex); 354 } 355 mutex_exit(&isns_mutex); 356 357 ISNS_GLOBAL_LOCK(); 358 mutex_destroy(&isns_mutex); 359 cv_destroy(&isns_idle_cv); 360 list_destroy(&esi_list); 361 mutex_destroy(&isns_esi_mutex); 362 cv_destroy(&isns_esi_cv); 363 364 /* 365 * Free our EID and target list. 366 */ 367 368 if (isns_eid) { 369 kmem_free(isns_eid, strlen(isns_eid) + 1); 370 isns_eid = NULL; 371 } 372 373 iscsit_global.global_isns_cfg.isns_state = B_FALSE; 374 avl_destroy(&isns_target_list); 375 list_destroy(&iscsit_global.global_isns_cfg.isns_svrs); 376 list_destroy(&portal_list); 377 portal_list_count = 0; 378 ISNS_GLOBAL_UNLOCK(); 379 380 mutex_destroy(&iscsit_global.global_isns_cfg.isns_mutex); 381 } 382 383 static void 384 iscsit_set_isns(boolean_t state) 385 { 386 iscsit_isns_svr_t *svr; 387 388 ASSERT(ISNS_GLOBAL_LOCK_HELD()); 389 390 /* reset retry count for all servers */ 391 for (svr = list_head(&iscsit_global.global_isns_cfg.isns_svrs); 392 svr != NULL; 393 svr = list_next(&iscsit_global.global_isns_cfg.isns_svrs, svr)) { 394 svr->svr_retry_count = 0; 395 } 396 397 /* 398 * Update state and isns stop flag 399 */ 400 iscsit_global.global_isns_cfg.isns_state = state; 401 402 if (state) { 403 isnst_start(); 404 } else { 405 isnst_stop(); 406 } 407 } 408 409 int 410 iscsit_add_isns(it_portal_t *cfg_svr) 411 { 412 iscsit_isns_svr_t *svr; 413 414 ASSERT(ISNS_GLOBAL_LOCK_HELD()); 415 416 svr = kmem_zalloc(sizeof (iscsit_isns_svr_t), KM_SLEEP); 417 bcopy(&cfg_svr->portal_addr, &svr->svr_sa, 418 sizeof (struct sockaddr_storage)); 419 420 /* put it on the global isns server list */ 421 list_insert_tail(&iscsit_global.global_isns_cfg.isns_svrs, svr); 422 423 /* 424 * Register targets with this server if iSNS is enabled. 425 */ 426 427 if (iscsit_global.global_isns_cfg.isns_state && 428 (isnst_update_one_server(svr, NULL, ISNS_REGISTER_ALL) == 0)) { 429 isnst_set_server_status(svr, B_TRUE); 430 } 431 432 return (0); 433 } 434 435 void 436 iscsit_delete_isns(iscsit_isns_svr_t *svr) 437 { 438 boolean_t need_dereg; 439 440 ASSERT(ISNS_GLOBAL_LOCK_HELD()); 441 442 list_remove(&iscsit_global.global_isns_cfg.isns_svrs, svr); 443 444 /* talk to this server if isns monitor is running */ 445 mutex_enter(&isns_mutex); 446 if (isns_monitor_thr_id != NULL) { 447 need_dereg = B_TRUE; 448 } else { 449 need_dereg = B_FALSE; 450 } 451 mutex_exit(&isns_mutex); 452 453 if (need_dereg) { 454 (void) isnst_monitor_one_server(svr, B_FALSE); 455 } 456 457 /* free the memory */ 458 kmem_free(svr, sizeof (*svr)); 459 } 460 461 static iscsit_isns_svr_t * 462 iscsit_isns_svr_lookup(struct sockaddr_storage *sa) 463 { 464 iscsit_isns_svr_t *svr; 465 it_portal_t portal1; 466 467 ASSERT(ISNS_GLOBAL_LOCK_HELD()); 468 469 bcopy(sa, &portal1.portal_addr, sizeof (struct sockaddr_storage)); 470 471 for (svr = list_head(&iscsit_global.global_isns_cfg.isns_svrs); 472 svr != NULL; 473 svr = list_next(&iscsit_global.global_isns_cfg.isns_svrs, svr)) { 474 if (it_sa_compare(&svr->svr_sa, sa) == 0) 475 return (svr); 476 } 477 478 return (NULL); 479 } 480 481 int 482 iscsit_isns_register(iscsit_tgt_t *target) 483 { 484 int rc = 0; 485 486 ISNS_GLOBAL_LOCK(); 487 488 (void) isnst_add_to_target_list(target); 489 490 if (iscsit_global.global_isns_cfg.isns_state == B_FALSE) { 491 ISNS_GLOBAL_UNLOCK(); 492 return (rc); 493 } 494 495 rc = isnst_update_target(target, ISNS_REGISTER_TARGET); 496 497 ISNS_GLOBAL_UNLOCK(); 498 499 return (rc); 500 } 501 502 int 503 iscsit_isns_deregister(iscsit_tgt_t *target) 504 { 505 void *itarget; 506 isns_target_t tmptgt; 507 iscsit_isns_svr_t *svr; 508 list_t *global; 509 510 ISNS_GLOBAL_LOCK(); 511 512 if (iscsit_global.global_isns_cfg.isns_state == B_FALSE) { 513 tmptgt.target = target; 514 515 if ((itarget = avl_find(&isns_target_list, &tmptgt, NULL)) 516 != NULL) { 517 avl_remove(&isns_target_list, itarget); 518 kmem_free(itarget, sizeof (isns_target_t)); 519 } 520 521 ISNS_GLOBAL_UNLOCK(); 522 return (0); 523 } 524 525 /* 526 * Don't worry about dereg failures. 527 */ 528 (void) isnst_update_target(target, ISNS_DEREGISTER_TARGET); 529 530 /* 531 * Remove the target from the list regardless of the status. 532 */ 533 534 tmptgt.target = target; 535 if ((itarget = avl_find(&isns_target_list, &tmptgt, NULL)) != NULL) { 536 avl_remove(&isns_target_list, itarget); 537 kmem_free(itarget, sizeof (isns_target_t)); 538 } 539 540 /* 541 * If there are no more targets, mark the server as 542 * unregistered. 543 */ 544 545 if (avl_numnodes(&isns_target_list) == 0) { 546 global = &iscsit_global.global_isns_cfg.isns_svrs; 547 for (svr = list_head(global); svr != NULL; 548 svr = list_next(global, svr)) { 549 isnst_set_server_status(svr, B_FALSE); 550 } 551 } 552 553 ISNS_GLOBAL_UNLOCK(); 554 555 return (0); 556 } 557 558 /* 559 * This function is called by iscsit when a target's configuration 560 * has changed. 561 */ 562 563 void 564 iscsit_isns_target_update(iscsit_tgt_t *target) 565 { 566 ISNS_GLOBAL_LOCK(); 567 568 if (iscsit_global.global_isns_cfg.isns_state == B_FALSE) { 569 ISNS_GLOBAL_UNLOCK(); 570 return; 571 } 572 573 (void) isnst_update_target(target, ISNS_UPDATE_TARGET); 574 575 ISNS_GLOBAL_UNLOCK(); 576 } 577 578 static void 579 isnst_start() 580 { 581 ASSERT(ISNS_GLOBAL_LOCK_HELD()); 582 583 /* 584 * Get target and portal lists, then start ESI threads for each portal. 585 */ 586 587 isnst_get_target_list(); 588 isnst_add_default_portals(); 589 590 /* 591 * Create a thread for monitoring server communications 592 */ 593 mutex_enter(&isns_mutex); 594 if (isns_monitor_thr_id == NULL) { 595 isns_monitor_thr_id = thread_create(NULL, 0, 596 isnst_monitor, NULL, 0, &p0, TS_RUN, minclsyspri); 597 } 598 mutex_exit(&isns_mutex); 599 } 600 601 static void 602 isnst_wakeup_monitor(void) 603 { 604 mutex_enter(&isns_mutex); 605 isns_idle = B_FALSE; 606 cv_signal(&isns_idle_cv); 607 mutex_exit(&isns_mutex); 608 } 609 610 static void 611 isnst_stop() 612 { 613 isns_target_t *itarget; 614 615 while ((itarget = avl_first(&isns_target_list)) != NULL) { 616 avl_remove(&isns_target_list, itarget); 617 kmem_free(itarget, sizeof (isns_target_t)); 618 } 619 620 isnst_remove_default_portals(); 621 isnst_esi_stop(); 622 isnst_wakeup_monitor(); 623 } 624 625 /* 626 * isnst_update_server_timestamp 627 * 628 * When we receive an ESI request, update the timestamp for the server. 629 * If we don't receive one for the specified period of time, we'll attempt 630 * to re-register. 631 */ 632 633 static void 634 isnst_update_server_timestamp(struct sonode *so) 635 { 636 iscsit_isns_svr_t *svr; 637 struct in_addr *sin = NULL, *svr_in; 638 struct in6_addr *sin6 = NULL, *svr_in6; 639 640 if (so->so_faddr_sa->sa_family == AF_INET) { 641 sin = &((struct sockaddr_in *) 642 ((void *)so->so_faddr_sa))->sin_addr; 643 } else { 644 sin6 = &((struct sockaddr_in6 *) 645 ((void *)so->so_faddr_sa))->sin6_addr; 646 } 647 648 /* 649 * Find the server and update the timestamp 650 */ 651 652 ISNS_GLOBAL_LOCK(); 653 for (svr = list_head(&iscsit_global.global_isns_cfg.isns_svrs); 654 svr != NULL; 655 svr = list_next(&iscsit_global.global_isns_cfg.isns_svrs, svr)) { 656 if (sin6 == NULL) { 657 if (svr->svr_sa.ss_family == AF_INET) { 658 svr_in = &((struct sockaddr_in *)&svr->svr_sa)-> 659 sin_addr; 660 if (bcmp(svr_in, sin, sizeof (in_addr_t)) 661 == 0) { 662 break; 663 } 664 } 665 } else { 666 if (svr->svr_sa.ss_family == AF_INET6) { 667 svr_in6 = &((struct sockaddr_in6 *) 668 &svr->svr_sa)->sin6_addr; 669 if (bcmp(svr_in6, sin6, 670 sizeof (in6_addr_t)) == 0) { 671 break; 672 } 673 } 674 } 675 } 676 677 if (svr != NULL) { 678 svr->svr_last_msg = ddi_get_lbolt(); 679 } 680 ISNS_GLOBAL_UNLOCK(); 681 } 682 683 /* 684 * isnst_monitor 685 * 686 * This function monitors registration status for each server. 687 */ 688 689 /*ARGSUSED*/ 690 static void 691 isnst_monitor(void *arg) 692 { 693 iscsit_isns_svr_t *svr; 694 list_t *svr_list; 695 boolean_t enabled; 696 697 svr_list = &iscsit_global.global_isns_cfg.isns_svrs; 698 699 do { 700 ISNS_GLOBAL_LOCK(); 701 enabled = iscsit_global.global_isns_cfg.isns_state; 702 for (svr = list_head(svr_list); svr != NULL; 703 svr = list_next(svr_list, svr)) { 704 if (isnst_monitor_one_server(svr, enabled) != 0) { 705 svr->svr_retry_count++; 706 } else { 707 svr->svr_retry_count = 0; 708 } 709 } 710 711 /* 712 * Attempted registrations, especially to unreachable 713 * servers, can take time. Thus, we check the isns_state 714 * again here. 715 */ 716 enabled = iscsit_global.global_isns_cfg.isns_state; 717 ISNS_GLOBAL_UNLOCK(); 718 719 /* 720 * Keep the while loop running while isns is enabled. 721 * If isns_idle is FALSE, we have more work to do, so 722 * no waiting. 723 */ 724 725 mutex_enter(&isns_mutex); 726 727 if (enabled && isns_idle) { 728 (void) cv_timedwait(&isns_idle_cv, &isns_mutex, 729 ddi_get_lbolt() + monitor_idle_interval); 730 } 731 732 isns_idle = B_TRUE; 733 mutex_exit(&isns_mutex); 734 } while (enabled); 735 736 mutex_enter(&isns_mutex); 737 isns_monitor_thr_id = NULL; 738 cv_signal(&isns_idle_cv); 739 mutex_exit(&isns_mutex); 740 741 /* terminate the thread at the last */ 742 thread_exit(); 743 } 744 745 static int 746 isnst_monitor_one_server(iscsit_isns_svr_t *svr, boolean_t enabled) 747 { 748 int rc = 0; 749 struct sonode *so; 750 751 ASSERT(ISNS_GLOBAL_LOCK_HELD()); 752 753 /* 754 * First, take care of the case where iSNS is no longer enabled. 755 * 756 * If we're still registered, deregister. Regardless, mark the 757 * server as not registered. 758 */ 759 760 if (enabled == B_FALSE) { 761 if (svr->svr_registered == B_TRUE) { 762 /* 763 * Doesn't matter if this fails. We're disabled. 764 */ 765 so = isnst_open_so(&svr->svr_sa); 766 if (so != NULL) { 767 (void) isnst_update_one_server(svr, NULL, 768 ISNS_DEREGISTER_ALL); 769 isnst_close_so(so); 770 } 771 } 772 773 isnst_set_server_status(svr, B_FALSE); 774 return (0); 775 } 776 777 /* 778 * If there are no targets, we're done. 779 */ 780 781 if (avl_numnodes(&isns_target_list) == 0) { 782 return (0); 783 } 784 785 /* 786 * At this point, we know iSNS is enabled. 787 * 788 * If we've received an ESI request from the server recently 789 * (within MAX_ESI_INTERVALS * the max interval length), 790 * no need to continue. 791 */ 792 793 if (svr->svr_registered == B_TRUE) { 794 if (ddi_get_lbolt() < (svr->svr_last_msg + 795 drv_usectohz(isns_esi_max_interval * 1000000 * 796 MAX_ESI_INTERVALS))) { 797 return (0); 798 } 799 } else { 800 /* 801 * We're not registered... Try to register now. 802 */ 803 if ((rc = isnst_update_one_server(svr, NULL, 804 ISNS_REGISTER_ALL)) == 0) { 805 isnst_set_server_status(svr, B_TRUE); 806 } 807 } 808 809 return (rc); 810 } 811 812 static int 813 isnst_update_target(iscsit_tgt_t *target, isns_reg_type_t reg) 814 { 815 iscsit_isns_svr_t *svr; 816 int rc = 0, curr_rc; 817 818 ASSERT(ISNS_GLOBAL_LOCK_HELD()); 819 ASSERT(iscsit_global.global_isns_cfg.isns_state == B_TRUE); 820 821 for (svr = list_head(&iscsit_global.global_isns_cfg.isns_svrs); 822 svr != NULL; 823 svr = list_next(&iscsit_global.global_isns_cfg.isns_svrs, svr)) { 824 /* 825 * Only return success if they all succeed. Let the caller 826 * deal with any failure. 827 */ 828 829 curr_rc = isnst_update_one_server(svr, target, reg); 830 831 if (curr_rc == 0) { 832 if (reg == ISNS_REGISTER_TARGET) { 833 isnst_set_server_status(svr, B_TRUE); 834 } 835 } else if (rc == 0) { 836 rc = curr_rc; 837 } 838 } 839 840 return (rc); 841 } 842 843 static int 844 isnst_update_one_server(iscsit_isns_svr_t *svr, iscsit_tgt_t *target, 845 isns_reg_type_t reg) 846 { 847 int rc = 0; 848 849 switch (reg) { 850 case ISNS_DEREGISTER_TARGET: 851 rc = isnst_deregister(svr, target->target_name); 852 break; 853 854 case ISNS_DEREGISTER_ALL: 855 rc = isnst_deregister(svr, NULL); 856 break; 857 858 case ISNS_UPDATE_TARGET: 859 case ISNS_REGISTER_TARGET: 860 rc = isnst_register(svr, target, reg); 861 break; 862 863 case ISNS_REGISTER_ALL: 864 rc = isnst_register(svr, NULL, reg); 865 break; 866 867 default: 868 ASSERT(0); 869 /* NOTREACHED */ 870 } 871 872 return (rc); 873 } 874 875 /* 876 * isnst_retry_registration 877 * 878 * This function checks the return value from a registration pdu and 879 * determines whether or not we should retry this request. If the 880 * request is retried, it will do so as an "update", which means we 881 * re-register everything. 882 */ 883 884 static boolean_t 885 isnst_retry_registration(int rsp_status_code) 886 { 887 boolean_t retry; 888 889 /* 890 * Currently, we will attempt to retry for "Invalid Registration", 891 * "Source Unauthorized", or "Busy" errors. Any other errors should 892 * be handled by the caller if necessary. 893 */ 894 895 switch (rsp_status_code) { 896 case ISNS_RSP_INVALID_REGIS: 897 case ISNS_RSP_SRC_UNAUTHORIZED: 898 case ISNS_RSP_BUSY: 899 retry = B_TRUE; 900 break; 901 default: 902 retry = B_FALSE; 903 break; 904 } 905 906 return (retry); 907 } 908 909 static int 910 isnst_register(iscsit_isns_svr_t *svr, iscsit_tgt_t *target, 911 isns_reg_type_t regtype) 912 { 913 struct sonode *so; 914 int rc = 0; 915 isns_pdu_t *pdu, *rsp; 916 size_t pdu_size, rsp_size; 917 isns_target_t *itarget, tmptgt; 918 boolean_t retry_reg = B_TRUE; 919 920 /* 921 * Registration is a tricky thing. In order to keep things simple, 922 * we don't want to keep track of which targets are registered to 923 * which server. We rely on the target state machine to tell us 924 * when a target is online or offline, which prompts us to either 925 * register or deregister that target. 926 * 927 * When iscsit_isns_init is called, get a list of targets. Those that 928 * are online will need to be registered. In this case, target 929 * will be NULL. 930 * 931 * What this means is that if svr_registered == B_FALSE, that's 932 * when we'll register the network entity as well. 933 */ 934 935 if ((avl_numnodes(&isns_target_list) == 0) && (target == NULL)) { 936 return (0); 937 } 938 939 /* 940 * If the target is already registered and we're not doing an 941 * update registration, just return. 942 */ 943 944 if (target != NULL) { 945 tmptgt.target = target; 946 itarget = avl_find(&isns_target_list, &tmptgt, NULL); 947 ASSERT(itarget); 948 if ((itarget->target_registered == B_TRUE) && 949 (regtype != ISNS_UPDATE_TARGET)) { 950 return (0); 951 } 952 } 953 954 isnst_esi_check(); 955 956 /* create TCP connection to the isns server */ 957 so = isnst_open_so(&svr->svr_sa); 958 959 if (so == NULL) { 960 isnst_set_server_status(svr, B_FALSE); 961 return (-1); 962 } 963 964 while (retry_reg) { 965 pdu_size = isnst_make_reg_pdu(&pdu, target, svr->svr_registered, 966 regtype); 967 if (pdu_size == 0) { 968 isnst_close_so(so); 969 return (-1); 970 } 971 972 rc = isnst_send_pdu(so, pdu); 973 if (rc != 0) { 974 kmem_free(pdu, pdu_size); 975 isnst_close_so(so); 976 return (rc); 977 } 978 979 rsp_size = isnst_rcv_pdu(so, &rsp); 980 if (rsp_size == 0) { 981 kmem_free(pdu, pdu_size); 982 isnst_close_so(so); 983 return (-1); 984 } 985 986 rc = isnst_verify_rsp(pdu, rsp); 987 988 /* 989 * If we got a registration error, the server may be out of 990 * sync. In this case, we may re-try the registration as 991 * a "target update", which causes us to re-register everything. 992 */ 993 994 if ((retry_reg = isnst_retry_registration(rc)) == B_TRUE) { 995 if (regtype == ISNS_UPDATE_TARGET) { 996 /* 997 * If registration failed on an update, there 998 * is something terribly wrong, possibly with 999 * the server. 1000 */ 1001 rc = -1; 1002 retry_reg = B_FALSE; 1003 isnst_set_server_status(svr, B_FALSE); 1004 } else { 1005 regtype = ISNS_UPDATE_TARGET; 1006 } 1007 } 1008 1009 kmem_free(pdu, pdu_size); 1010 kmem_free(rsp, rsp_size); 1011 } 1012 1013 isnst_close_so(so); 1014 1015 /* 1016 * If it succeeded, mark all registered targets as such 1017 */ 1018 if (rc == 0) { 1019 if ((target != NULL) && (regtype != ISNS_UPDATE_TARGET)) { 1020 /* itarget initialized above */ 1021 itarget->target_registered = B_TRUE; 1022 } else { 1023 itarget = avl_first(&isns_target_list); 1024 while (itarget) { 1025 itarget->target_registered = B_TRUE; 1026 itarget = AVL_NEXT(&isns_target_list, itarget); 1027 } 1028 } 1029 } 1030 1031 return (rc); 1032 } 1033 1034 static isns_portal_list_t * 1035 isns_lookup_portal(struct sockaddr_storage *p) 1036 { 1037 isns_portal_list_t *portal; 1038 1039 portal = list_head(&portal_list); 1040 1041 while (portal != NULL) { 1042 if (bcmp(p, &portal->portal_addr, 1043 sizeof (struct sockaddr_storage)) == 0) { 1044 return (portal); 1045 } 1046 portal = list_next(&portal_list, portal); 1047 } 1048 1049 return (NULL); 1050 } 1051 1052 static void 1053 isns_remove_portal(isns_portal_list_t *p) 1054 { 1055 list_remove(&portal_list, p); 1056 kmem_free(p, sizeof (isns_portal_list_t)); 1057 portal_list_count--; 1058 } 1059 1060 static isns_target_t * 1061 isnst_add_to_target_list(iscsit_tgt_t *target) 1062 { 1063 isns_target_t *itarget, tmptgt; 1064 1065 ASSERT(ISNS_GLOBAL_LOCK_HELD()); 1066 1067 /* 1068 * Make sure this target isn't already in our list. If it is, 1069 * perhaps it has just moved from offline to online. 1070 */ 1071 1072 tmptgt.target = target; 1073 if ((itarget = (isns_target_t *)avl_find(&isns_target_list, 1074 &tmptgt, NULL)) == NULL) { 1075 itarget = kmem_zalloc(sizeof (isns_target_t), KM_NOSLEEP); 1076 1077 /* 1078 * If we can't get memory, we're not going to be able to 1079 * register this target. This needs to be fixed up. 1080 */ 1081 if (itarget == NULL) 1082 return (NULL); 1083 1084 itarget->target = target; 1085 avl_add(&isns_target_list, itarget); 1086 } 1087 1088 return (itarget); 1089 } 1090 1091 static int 1092 isnst_add_default_portal_attrs(isns_pdu_t *pdu, size_t pdu_size) 1093 { 1094 isns_portal_list_t *portal; 1095 struct sockaddr_in *in; 1096 struct sockaddr_in6 *in6; 1097 int idx = 0; 1098 uint32_t attr_data; 1099 void *inaddrp; 1100 1101 portal = list_head(&portal_list); 1102 1103 while (portal) { 1104 if (idx == nondefault_portals) { 1105 break; 1106 } 1107 1108 if (portal->portal_iscsit == NULL) { 1109 in = (struct sockaddr_in *)&portal->portal_addr; 1110 1111 if (in->sin_family == AF_INET) { 1112 attr_data = sizeof (in_addr_t); 1113 inaddrp = (void *)&in->sin_addr; 1114 } else if (in->sin_family == AF_INET6) { 1115 in6 = (struct sockaddr_in6 *) 1116 &portal->portal_addr; 1117 attr_data = sizeof (in6_addr_t); 1118 inaddrp = (void *)&in6->sin6_addr; 1119 } else { 1120 return (-1); 1121 } 1122 1123 if (isnst_add_attr(pdu, pdu_size, 1124 ISNS_PG_PORTAL_IP_ADDR_ATTR_ID, 16, inaddrp, 1125 attr_data) != 0) { 1126 return (-1); 1127 } 1128 1129 /* Portal Group Portal Port */ 1130 if (isnst_add_attr(pdu, pdu_size, 1131 ISNS_PG_PORTAL_PORT_ATTR_ID, 4, 0, 1132 ntohs(in->sin_port)) != 0) { 1133 return (-1); 1134 } 1135 1136 idx++; 1137 } 1138 1139 portal = list_next(&portal_list, portal); 1140 } 1141 1142 return (0); 1143 } 1144 1145 static size_t 1146 isnst_make_reg_pdu(isns_pdu_t **pdu, iscsit_tgt_t *target, 1147 boolean_t svr_registered, isns_reg_type_t regtype) 1148 { 1149 size_t pdu_size; 1150 iscsit_tpgt_t *tpgt; 1151 iscsit_tpg_t *tpg; 1152 iscsit_portal_t *tp; 1153 char *str; 1154 int len; 1155 isns_portal_list_t *portal; 1156 isns_esi_tinfo_t *tinfop; 1157 isns_target_t *itarget; 1158 iscsit_tgt_t *src; 1159 boolean_t reg_all = B_FALSE; 1160 uint16_t flags = 0; 1161 1162 ASSERT(ISNS_GLOBAL_LOCK_HELD()); 1163 1164 /* 1165 * Find a source attribute for this registration. 1166 * 1167 * If we're already registered, registering for the first time, or 1168 * updating a target, we'll use the target_name of the first target 1169 * in our list. 1170 * 1171 * The alternate case is that we're registering for the first time, 1172 * but target is non-NULL. In that case, we have no targets in our 1173 * list yet, so we use the passed in target's name. 1174 */ 1175 1176 if (svr_registered || (target == NULL) || 1177 (regtype == ISNS_UPDATE_TARGET)) { 1178 ASSERT(avl_numnodes(&isns_target_list) != 0); 1179 itarget = (isns_target_t *)avl_first(&isns_target_list); 1180 src = itarget->target; 1181 } else { 1182 src = target; 1183 } 1184 1185 /* 1186 * No target means we're registering everything. A regtype of 1187 * ISNS_UPDATE_TARGET means we're re-registering everything. 1188 * Whether we're registering or re-registering depends on if 1189 * we're already registered. 1190 */ 1191 1192 if ((target == NULL) || (regtype == ISNS_UPDATE_TARGET)) { 1193 reg_all = B_TRUE; 1194 target = src; /* This will be the 1st tgt in our list */ 1195 1196 /* 1197 * If we're already registered, this will be a replacement 1198 * registration. In this case, we need to make sure our 1199 * source attribute is an already registered target. 1200 */ 1201 if (svr_registered) { 1202 flags = ISNS_FLAG_REPLACE_REG; 1203 while (itarget->target_registered == B_FALSE) { 1204 itarget = AVL_NEXT(&isns_target_list, 1205 itarget); 1206 } 1207 src = itarget->target; 1208 /* Reset itarget to the beginning of our list */ 1209 itarget = (isns_target_t *)avl_first(&isns_target_list); 1210 } 1211 } 1212 1213 pdu_size = isnst_create_pdu_header(ISNS_DEV_ATTR_REG, pdu, flags); 1214 if (pdu_size == 0) { 1215 return (0); 1216 } 1217 1218 len = strlen(src->target_name) + 1; 1219 if (isnst_add_attr(*pdu, pdu_size, ISNS_ISCSI_NAME_ATTR_ID, 1220 len, src->target_name, 0) != 0) { 1221 goto pdu_error; 1222 } 1223 1224 /* 1225 * Message Key Attributes - EID 1226 */ 1227 len = strlen(isns_eid) + 1; 1228 1229 if (isnst_add_attr(*pdu, pdu_size, ISNS_EID_ATTR_ID, 1230 len, isns_eid, 0) != 0) { 1231 goto pdu_error; 1232 } 1233 1234 /* Delimiter */ 1235 if (isnst_add_attr(*pdu, pdu_size, ISNS_DELIMITER_ATTR_ID, 1236 0, 0, 0) != 0) { 1237 goto pdu_error; 1238 } 1239 1240 /* 1241 * Operating Attributes 1242 */ 1243 if (isnst_add_attr(*pdu, pdu_size, ISNS_EID_ATTR_ID, len, 1244 isns_eid, 0) != 0) { 1245 goto pdu_error; 1246 } 1247 1248 /* ENTITY Protocol - Section 6.2.2 */ 1249 if (isnst_add_attr(*pdu, pdu_size, ISNS_ENTITY_PROTOCOL_ATTR_ID, 1250 4, 0, ISNS_ENTITY_PROTOCOL_ISCSI) != 0) { 1251 goto pdu_error; 1252 } 1253 1254 /* 1255 * Network entity portal information - only on the first registration. 1256 */ 1257 1258 if (svr_registered == B_FALSE) { 1259 struct sockaddr_in *sin; 1260 int addrsize; 1261 1262 portal = list_head(&portal_list); 1263 1264 while (portal != NULL) { 1265 sin = (struct sockaddr_in *)&portal->portal_addr; 1266 tinfop = portal->portal_esi; 1267 1268 if (portal->portal_iscsit == NULL) { 1269 if (sin->sin_family == AF_INET) { 1270 addrsize = sizeof (struct in_addr); 1271 } else { 1272 addrsize = sizeof (struct in6_addr); 1273 } 1274 1275 /* Portal IP Address */ 1276 if (isnst_add_attr(*pdu, pdu_size, 1277 ISNS_PORTAL_IP_ADDR_ATTR_ID, 16, 1278 &sin->sin_addr, addrsize) != 0) { 1279 goto pdu_error; 1280 } 1281 1282 /* Portal Port */ 1283 if (isnst_add_attr(*pdu, pdu_size, 1284 ISNS_PORTAL_PORT_ATTR_ID, 4, 0, 1285 ntohs(sin->sin_port)) != 0) { 1286 goto pdu_error; 1287 } 1288 1289 if (tinfop && tinfop->esi_port) { 1290 /* ESI interval and port */ 1291 if (isnst_add_attr(*pdu, pdu_size, 1292 ISNS_ESI_INTERVAL_ATTR_ID, 4, 1293 NULL, 20) != 0) { 1294 goto pdu_error; 1295 } 1296 1297 if (isnst_add_attr(*pdu, pdu_size, 1298 ISNS_ESI_PORT_ATTR_ID, 4, NULL, 1299 tinfop->esi_port) != 0) { 1300 goto pdu_error; 1301 } 1302 } 1303 } 1304 1305 portal = list_next(&portal_list, portal); 1306 } 1307 } 1308 1309 do { 1310 /* Hold the target mutex */ 1311 mutex_enter(&target->target_mutex); 1312 1313 /* iSCSI Name - Section 6.4.1 */ 1314 str = target->target_name; 1315 len = strlen(str) + 1; 1316 if (isnst_add_attr(*pdu, pdu_size, ISNS_ISCSI_NAME_ATTR_ID, 1317 len, str, 0) != 0) { 1318 mutex_exit(&target->target_mutex); 1319 goto pdu_error; 1320 } 1321 1322 /* iSCSI Node Type */ 1323 if (isnst_add_attr(*pdu, pdu_size, 1324 ISNS_ISCSI_NODE_TYPE_ATTR_ID, 4, 0, 1325 ISNS_TARGET_NODE_TYPE) != 0) { 1326 mutex_exit(&target->target_mutex); 1327 goto pdu_error; 1328 } 1329 1330 /* iSCSI Alias */ 1331 #if 0 1332 str = target->target_alias; 1333 #else 1334 str = "Solaris iSCSI Target"; 1335 #endif 1336 if (str != NULL) { 1337 len = strlen(str) + 1; 1338 if (isnst_add_attr(*pdu, pdu_size, 1339 ISNS_ISCSI_ALIAS_ATTR_ID, len, str, 0) != 0) { 1340 mutex_exit(&target->target_mutex); 1341 goto pdu_error; 1342 } 1343 } 1344 1345 /* for each target portal group (start)... */ 1346 tpgt = avl_first(&target->target_tpgt_list); 1347 ASSERT(tpgt != NULL); 1348 do { 1349 /* no need to explicitly register default PG */ 1350 if ((tpgt->tpgt_tag == ISCSIT_DEFAULT_TPGT) && 1351 (avl_numnodes(&target->target_tpgt_list) == 1)) { 1352 tpgt = AVL_NEXT(&target->target_tpgt_list, 1353 tpgt); 1354 continue; 1355 } 1356 1357 tpg = tpgt->tpgt_tpg; 1358 mutex_enter(&tpg->tpg_mutex); 1359 1360 tp = avl_first(&tpg->tpg_portal_list); 1361 1362 /* Portal Group Tag */ 1363 if (isnst_add_attr(*pdu, pdu_size, 1364 ISNS_PG_TAG_ATTR_ID, 4, 0, tpgt->tpgt_tag) != 0) { 1365 mutex_exit(&tpg->tpg_mutex); 1366 mutex_exit(&target->target_mutex); 1367 goto pdu_error; 1368 } 1369 1370 ASSERT(tp != NULL); 1371 do { 1372 struct sockaddr_storage *ss; 1373 struct sockaddr_in *in; 1374 struct sockaddr_in6 *in6; 1375 uint32_t attr_numeric_data; 1376 void *inaddrp; 1377 1378 ss = &tp->portal_addr; 1379 in = (struct sockaddr_in *)ss; 1380 in6 = (struct sockaddr_in6 *)ss; 1381 1382 if (ss->ss_family == AF_INET) { 1383 attr_numeric_data = sizeof (in_addr_t); 1384 inaddrp = (void *)&in->sin_addr; 1385 } else if (ss->ss_family == AF_INET6) { 1386 attr_numeric_data = sizeof (in6_addr_t); 1387 inaddrp = (void *)&in6->sin6_addr; 1388 } else if (ss->ss_family == 0) { 1389 /* 1390 * Need to add all default portals 1391 */ 1392 attr_numeric_data = 0; 1393 } else { 1394 cmn_err(CE_WARN, "Unknown address " 1395 "family for portal %p", (void *)tp); 1396 mutex_exit(&tpg->tpg_mutex); 1397 mutex_exit(&target->target_mutex); 1398 goto pdu_error; 1399 } 1400 1401 if (attr_numeric_data == 0) { 1402 if (isnst_add_default_portal_attrs(*pdu, 1403 pdu_size) != 0) { 1404 mutex_exit(&tpg->tpg_mutex); 1405 mutex_exit(&target-> 1406 target_mutex); 1407 goto pdu_error; 1408 } 1409 } else { 1410 /* Portal Group Portal IP Address */ 1411 if (isnst_add_attr(*pdu, pdu_size, 1412 ISNS_PG_PORTAL_IP_ADDR_ATTR_ID, 16, 1413 inaddrp, attr_numeric_data) != 0) { 1414 mutex_exit(&tpg->tpg_mutex); 1415 mutex_exit(&target-> 1416 target_mutex); 1417 goto pdu_error; 1418 } 1419 1420 /* Portal Group Portal Port */ 1421 if (isnst_add_attr(*pdu, pdu_size, 1422 ISNS_PG_PORTAL_PORT_ATTR_ID, 1423 4, 0, ntohs(in->sin_port)) != 0) { 1424 mutex_exit(&tpg->tpg_mutex); 1425 mutex_exit(&target-> 1426 target_mutex); 1427 goto pdu_error; 1428 } 1429 } 1430 1431 tp = AVL_NEXT(&tpg->tpg_portal_list, tp); 1432 } while (tp != NULL); 1433 1434 mutex_exit(&tpg->tpg_mutex); 1435 tpgt = AVL_NEXT(&target->target_tpgt_list, tpgt); 1436 } while (tpgt != NULL); 1437 /* for each target portal group (end)... */ 1438 1439 mutex_exit(&target->target_mutex); 1440 1441 if (reg_all) { 1442 itarget = AVL_NEXT(&isns_target_list, itarget); 1443 if (itarget) { 1444 target = itarget->target; 1445 } else { 1446 target = NULL; 1447 } 1448 } 1449 } while ((reg_all == B_TRUE) && (target != NULL)); 1450 1451 return (pdu_size); 1452 1453 pdu_error: 1454 /* packet too large, no memory */ 1455 kmem_free(*pdu, pdu_size); 1456 *pdu = NULL; 1457 1458 return (0); 1459 } 1460 1461 static int 1462 isnst_deregister(iscsit_isns_svr_t *svr, char *node) 1463 { 1464 int rc; 1465 isns_pdu_t *pdu, *rsp; 1466 size_t pdu_size, rsp_size; 1467 struct sonode *so; 1468 1469 if ((svr->svr_registered == B_FALSE) || 1470 (avl_numnodes(&isns_target_list) == 0)) { 1471 return (0); 1472 } 1473 1474 so = isnst_open_so(&svr->svr_sa); 1475 1476 if (so == NULL) { 1477 return (-1); 1478 } 1479 1480 pdu_size = isnst_make_dereg_pdu(&pdu, node); 1481 if (pdu_size == 0) { 1482 isnst_close_so(so); 1483 return (-1); 1484 } 1485 1486 rc = isnst_send_pdu(so, pdu); 1487 if (rc != 0) { 1488 isnst_close_so(so); 1489 kmem_free(pdu, pdu_size); 1490 return (rc); 1491 } 1492 1493 rsp_size = isnst_rcv_pdu(so, &rsp); 1494 if (rsp_size == 0) { 1495 isnst_close_so(so); 1496 kmem_free(pdu, pdu_size); 1497 return (-1); 1498 } 1499 1500 rc = isnst_verify_rsp(pdu, rsp); 1501 1502 isnst_close_so(so); 1503 kmem_free(pdu, pdu_size); 1504 kmem_free(rsp, rsp_size); 1505 1506 return (rc); 1507 } 1508 1509 static size_t 1510 isnst_make_dereg_pdu(isns_pdu_t **pdu, char *node) 1511 { 1512 size_t pdu_size; 1513 int len; 1514 isns_target_t *itarget; 1515 iscsit_tgt_t *target; 1516 int num_targets; 1517 1518 /* 1519 * create DevDereg Message with all of target nodes 1520 */ 1521 pdu_size = isnst_create_pdu_header(ISNS_DEV_DEREG, pdu, 0); 1522 if (pdu_size == 0) { 1523 return (0); 1524 } 1525 1526 /* 1527 * Source attribute - Must be a storage node in the same 1528 * network entity. We'll just grab the first one in the list. 1529 * If it's the only online target, we turn this into a total 1530 * deregistration regardless of the value of "node". 1531 */ 1532 1533 num_targets = avl_numnodes(&isns_target_list); 1534 itarget = avl_first(&isns_target_list); 1535 target = itarget->target; 1536 1537 len = strlen(target->target_name) + 1; 1538 if (isnst_add_attr(*pdu, pdu_size, ISNS_ISCSI_NAME_ATTR_ID, 1539 len, target->target_name, 0) != 0) { 1540 goto dereg_pdu_error; 1541 } 1542 1543 /* Delimiter */ 1544 if (isnst_add_attr(*pdu, pdu_size, ISNS_DELIMITER_ATTR_ID, 1545 0, 0, 0) != 0) { 1546 goto dereg_pdu_error; 1547 } 1548 1549 /* 1550 * Operating attributes 1551 */ 1552 if ((node == NULL) || (num_targets == 1)) { 1553 /* dereg everything */ 1554 len = strlen(isns_eid) + 1; 1555 if (isnst_add_attr(*pdu, pdu_size, ISNS_EID_ATTR_ID, 1556 len, isns_eid, 0) != 0) { 1557 goto dereg_pdu_error; 1558 } 1559 } else { 1560 /* dereg one target only */ 1561 len = strlen(node) + 1; 1562 if (isnst_add_attr(*pdu, pdu_size, ISNS_ISCSI_NAME_ATTR_ID, 1563 len, node, 0) != 0) { 1564 goto dereg_pdu_error; 1565 } 1566 } 1567 1568 return (pdu_size); 1569 1570 dereg_pdu_error: 1571 kmem_free(*pdu, pdu_size); 1572 *pdu = NULL; 1573 1574 return (0); 1575 } 1576 1577 static int 1578 isnst_verify_rsp(isns_pdu_t *pdu, isns_pdu_t *rsp) 1579 { 1580 uint16_t func_id; 1581 uint16_t payload_len, rsp_payload_len; 1582 isns_resp_t *resp; 1583 uint8_t *pp; 1584 isns_tlv_t *attr; 1585 uint32_t attr_len, attr_id, esi_interval; 1586 1587 /* validate response function id */ 1588 func_id = ntohs(rsp->func_id); 1589 switch (ntohs(pdu->func_id)) { 1590 case ISNS_DEV_ATTR_REG: 1591 if (func_id != ISNS_DEV_ATTR_REG_RSP) { 1592 return (-1); 1593 } 1594 1595 /* 1596 * Get the ESI interval returned by the server. It could 1597 * be different than what we asked for. We never know which 1598 * portal a request may come in on, and any server could demand 1599 * any interval. We'll simply keep track of the largest interval 1600 * for use in monitoring. 1601 */ 1602 1603 rsp_payload_len = isnst_pdu_get_op(rsp, &pp); 1604 attr = (isns_tlv_t *)((void *)pp); 1605 1606 while (rsp_payload_len) { 1607 attr_len = ntohl(attr->attr_len); 1608 attr_id = ntohl(attr->attr_id); 1609 1610 if (attr_id == ISNS_ESI_INTERVAL_ATTR_ID) { 1611 esi_interval = 1612 ntohl(*((uint32_t *) 1613 ((void *)(&attr->attr_value)))); 1614 1615 if (esi_interval > isns_esi_max_interval) 1616 isns_esi_max_interval = esi_interval; 1617 1618 break; 1619 } 1620 1621 rsp_payload_len -= (8 + attr_len); 1622 attr = (isns_tlv_t *) 1623 ((void *)((uint8_t *)attr + attr_len + 8)); 1624 } 1625 1626 break; 1627 case ISNS_DEV_DEREG: 1628 if (func_id != ISNS_DEV_DEREG_RSP) { 1629 return (-1); 1630 } 1631 break; 1632 default: 1633 ASSERT(0); 1634 break; 1635 } 1636 1637 /* verify response transaction id */ 1638 if (ntohs(rsp->xid) != ntohs(pdu->xid)) { 1639 return (-1); 1640 } 1641 1642 /* check the error code */ 1643 payload_len = ntohs(rsp->payload_len); 1644 resp = (isns_resp_t *)((void *)&rsp->payload[0]); 1645 if (payload_len < 4) { 1646 return (-1); 1647 } 1648 1649 return (ntohl(resp->status)); 1650 } 1651 1652 static uint16_t 1653 isnst_pdu_get_op(isns_pdu_t *pdu, uint8_t **pp) 1654 { 1655 uint8_t *payload; 1656 uint16_t payload_len; 1657 isns_resp_t *resp; 1658 isns_tlv_t *attr; 1659 uint32_t attr_id; 1660 uint32_t tlv_len; 1661 1662 /* get payload */ 1663 payload_len = ntohs(pdu->payload_len); 1664 resp = (isns_resp_t *)((void *)&pdu->payload[0]); 1665 1666 /* find the operating attributes */ 1667 ASSERT(payload_len >= 4); 1668 payload_len -= 4; 1669 payload = &resp->data[0]; 1670 1671 while (payload_len >= 8) { 1672 attr = (isns_tlv_t *)((void *)payload); 1673 tlv_len = 8 + ntohl(attr->attr_len); 1674 if (payload_len >= tlv_len) { 1675 payload += tlv_len; 1676 payload_len -= tlv_len; 1677 attr_id = ntohl(attr->attr_id); 1678 if (attr_id == ISNS_DELIMITER_ATTR_ID) { 1679 break; 1680 } 1681 } else { 1682 /* mal-formed packet */ 1683 payload = NULL; 1684 payload_len = 0; 1685 } 1686 } 1687 1688 *pp = payload; 1689 1690 return (payload_len); 1691 } 1692 1693 static size_t 1694 isnst_create_pdu_header(uint16_t func_id, isns_pdu_t **pdu, uint16_t flags) 1695 { 1696 size_t pdu_size = ISNSP_MAX_PDU_SIZE; 1697 1698 *pdu = (isns_pdu_t *)kmem_zalloc(pdu_size, KM_NOSLEEP); 1699 if (*pdu != NULL) { 1700 (*pdu)->version = htons((uint16_t)ISNSP_VERSION); 1701 (*pdu)->func_id = htons((uint16_t)func_id); 1702 (*pdu)->payload_len = htons(0); 1703 (*pdu)->flags = htons(flags); 1704 1705 (*pdu)->xid = htons(GET_XID()); 1706 (*pdu)->seq = htons(0); 1707 } else { 1708 pdu_size = 0; 1709 } 1710 1711 return (pdu_size); 1712 } 1713 1714 static int 1715 isnst_add_attr(isns_pdu_t *pdu, 1716 size_t max_pdu_size, 1717 uint32_t attr_id, 1718 uint32_t attr_len, 1719 void *attr_data, 1720 uint32_t attr_numeric_data) 1721 { 1722 isns_tlv_t *attr_tlv; 1723 uint8_t *payload_ptr; 1724 uint16_t payload_len; 1725 uint32_t normalized_attr_len; 1726 uint64_t attr_tlv_len; 1727 1728 /* The attribute length must be 4-byte aligned. Section 5.1.3. */ 1729 normalized_attr_len = (attr_len % 4) == 0 ? 1730 (attr_len) : (attr_len + (4 - (attr_len % 4))); 1731 attr_tlv_len = ISNS_TLV_ATTR_ID_LEN + 1732 ISNS_TLV_ATTR_LEN_LEN + normalized_attr_len; 1733 1734 /* Check if we are going to exceed the maximum PDU length. */ 1735 payload_len = ntohs(pdu->payload_len); 1736 if ((payload_len + attr_tlv_len) > max_pdu_size) { 1737 return (1); 1738 } 1739 1740 attr_tlv = (isns_tlv_t *)kmem_zalloc(attr_tlv_len, KM_SLEEP); 1741 1742 attr_tlv->attr_id = htonl(attr_id); 1743 1744 switch (attr_id) { 1745 case ISNS_DELIMITER_ATTR_ID: 1746 break; 1747 1748 case ISNS_PORTAL_IP_ADDR_ATTR_ID: 1749 case ISNS_PG_PORTAL_IP_ADDR_ATTR_ID: 1750 if (attr_numeric_data == sizeof (in_addr_t)) { 1751 /* IPv4 */ 1752 attr_tlv->attr_value[10] = 0xFF; 1753 attr_tlv->attr_value[11] = 0xFF; 1754 bcopy(attr_data, ((attr_tlv->attr_value) + 12), 1755 sizeof (in_addr_t)); 1756 } else if (attr_numeric_data == sizeof (in6_addr_t)) { 1757 /* IPv6 */ 1758 bcopy(attr_data, attr_tlv->attr_value, 1759 sizeof (in6_addr_t)); 1760 } else if (attr_numeric_data == 0) { 1761 /* EMPTY */ 1762 /* Do nothing */ 1763 } else { 1764 kmem_free(attr_tlv, attr_tlv_len); 1765 attr_tlv = NULL; 1766 return (1); 1767 } 1768 break; 1769 1770 case ISNS_EID_ATTR_ID: 1771 case ISNS_ISCSI_NAME_ATTR_ID: 1772 case ISNS_ISCSI_ALIAS_ATTR_ID: 1773 case ISNS_PG_ISCSI_NAME_ATTR_ID: 1774 if (attr_len && attr_data) { 1775 bcopy((char *)attr_data, 1776 attr_tlv->attr_value, attr_len); 1777 } 1778 break; 1779 1780 default: 1781 if (attr_len == 8) { 1782 *(uint64_t *)((void *)attr_tlv->attr_value) = 1783 BE_64((uint64_t)attr_numeric_data); 1784 } else if (attr_len == 4) { 1785 *(uint32_t *)((void *)attr_tlv->attr_value) = 1786 htonl((uint32_t)attr_numeric_data); 1787 } 1788 break; 1789 } 1790 1791 attr_tlv->attr_len = htonl(normalized_attr_len); 1792 /* 1793 * Convert the network byte ordered payload length to host byte 1794 * ordered for local address calculation. 1795 */ 1796 payload_len = ntohs(pdu->payload_len); 1797 payload_ptr = pdu->payload + payload_len; 1798 bcopy(attr_tlv, payload_ptr, attr_tlv_len); 1799 payload_len += attr_tlv_len; 1800 1801 /* 1802 * Convert the host byte ordered payload length back to network 1803 * byte ordered - it's now ready to be sent on the wire. 1804 */ 1805 pdu->payload_len = htons(payload_len); 1806 1807 kmem_free(attr_tlv, attr_tlv_len); 1808 attr_tlv = NULL; 1809 1810 return (0); 1811 } 1812 1813 static int 1814 isnst_send_pdu(void *so, isns_pdu_t *pdu) 1815 { 1816 size_t total_len, payload_len, send_len; 1817 uint8_t *payload; 1818 uint16_t flags, seq; 1819 1820 iovec_t iov[2]; 1821 int rc; 1822 1823 /* update pdu flags */ 1824 flags = ntohs(pdu->flags); 1825 flags |= ISNS_FLAG_CLIENT; 1826 flags |= ISNS_FLAG_FIRST_PDU; 1827 1828 /* initalize sequence number */ 1829 seq = 0; 1830 1831 payload = pdu->payload; 1832 1833 /* total payload length */ 1834 total_len = ntohs(pdu->payload_len); 1835 1836 /* fill in the pdu header */ 1837 iov[0].iov_base = (void *)pdu; 1838 iov[0].iov_len = ISNSP_HEADER_SIZE; 1839 1840 do { 1841 /* split the payload accordingly */ 1842 if (total_len > ISNSP_MAX_PAYLOAD_SIZE) { 1843 payload_len = ISNSP_MAX_PAYLOAD_SIZE; 1844 } else { 1845 payload_len = total_len; 1846 /* set the last pdu flag */ 1847 flags |= ISNS_FLAG_LAST_PDU; 1848 } 1849 1850 /* set back the pdu flags */ 1851 pdu->flags = htons(flags); 1852 /* set the sequence number */ 1853 pdu->seq = htons(seq); 1854 /* set the payload length */ 1855 pdu->payload_len = htons(payload_len); 1856 1857 /* fill in the payload */ 1858 iov[1].iov_base = (void *)payload; 1859 iov[1].iov_len = payload_len; 1860 1861 DTRACE_PROBE3(isnst__pdu__send, uint16_t, ntohs(pdu->func_id), 1862 uint16_t, ntohs(pdu->payload_len), caddr_t, pdu); 1863 1864 /* send the pdu */ 1865 send_len = ISNSP_HEADER_SIZE + payload_len; 1866 rc = idm_iov_sosend(so, &iov[0], 2, send_len); 1867 1868 flags &= ~ISNS_FLAG_FIRST_PDU; 1869 payload += payload_len; 1870 total_len -= payload_len; 1871 1872 /* increase the sequence number */ 1873 seq ++; 1874 1875 } while (rc == 0 && total_len > 0); 1876 1877 return (rc); 1878 } 1879 1880 static size_t 1881 isnst_rcv_pdu(void *so, isns_pdu_t **pdu) 1882 { 1883 size_t total_pdu_len; 1884 size_t total_payload_len; 1885 size_t payload_len; 1886 size_t combined_len; 1887 isns_pdu_t tmp_pdu_hdr; 1888 isns_pdu_t *combined_pdu; 1889 uint8_t *payload; 1890 uint8_t *combined_payload; 1891 1892 uint16_t flags; 1893 uint16_t seq; 1894 1895 *pdu = NULL; 1896 total_pdu_len = total_payload_len = 0; 1897 payload = NULL; 1898 seq = 0; 1899 1900 do { 1901 /* receive the pdu header */ 1902 if (idm_sorecv(so, &tmp_pdu_hdr, ISNSP_HEADER_SIZE) != 0 || 1903 ntohs(tmp_pdu_hdr.seq) != seq) { 1904 goto rcv_error; 1905 } 1906 1907 /* receive the payload */ 1908 payload_len = ntohs(tmp_pdu_hdr.payload_len); 1909 payload = kmem_alloc(payload_len, KM_SLEEP); 1910 if (idm_sorecv(so, payload, payload_len) != 0) { 1911 goto rcv_error; 1912 } 1913 1914 /* combine the pdu if it is not the first one */ 1915 if (total_pdu_len > 0) { 1916 combined_len = total_pdu_len + payload_len; 1917 combined_pdu = kmem_alloc(combined_len, KM_SLEEP); 1918 bcopy(*pdu, combined_pdu, total_pdu_len); 1919 combined_payload = 1920 &combined_pdu->payload[total_payload_len]; 1921 bcopy(payload, combined_payload, payload_len); 1922 kmem_free(*pdu, total_pdu_len); 1923 kmem_free(payload, payload_len); 1924 *pdu = combined_pdu; 1925 total_payload_len += payload_len; 1926 total_pdu_len += payload_len; 1927 (*pdu)->payload_len = htons(total_payload_len); 1928 } else { 1929 total_payload_len = payload_len; 1930 total_pdu_len = ISNSP_HEADER_SIZE + payload_len; 1931 *pdu = kmem_alloc(total_pdu_len, KM_SLEEP); 1932 bcopy(&tmp_pdu_hdr, *pdu, ISNSP_HEADER_SIZE); 1933 bcopy(payload, &(*pdu)->payload[0], payload_len); 1934 kmem_free(payload, payload_len); 1935 } 1936 payload = NULL; 1937 1938 /* the flags of pdu which is just received */ 1939 flags = ntohs(tmp_pdu_hdr.flags); 1940 1941 /* increase sequence number by one */ 1942 seq ++; 1943 } while ((flags & ISNS_FLAG_LAST_PDU) == 0); 1944 1945 DTRACE_PROBE3(isnst__pdu__recv, uint16_t, ntohs((*pdu)->func_id), 1946 size_t, total_payload_len, caddr_t, *pdu); 1947 1948 return (total_pdu_len); 1949 1950 rcv_error: 1951 if (*pdu != NULL) { 1952 kmem_free(*pdu, total_pdu_len); 1953 *pdu = NULL; 1954 } 1955 if (payload != NULL) { 1956 kmem_free(payload, payload_len); 1957 } 1958 return (0); 1959 } 1960 1961 static void * 1962 isnst_open_so(struct sockaddr_storage *sa) 1963 { 1964 int sa_sz; 1965 struct sonode *so; 1966 1967 /* determin local IP address */ 1968 if (sa->ss_family == AF_INET) { 1969 /* IPv4 */ 1970 sa_sz = sizeof (struct sockaddr_in); 1971 1972 /* Create socket */ 1973 so = idm_socreate(AF_INET, SOCK_STREAM, 0); 1974 } else { 1975 /* IPv6 */ 1976 sa_sz = sizeof (struct sockaddr_in6); 1977 1978 /* Create socket */ 1979 so = idm_socreate(AF_INET6, SOCK_STREAM, 0); 1980 } 1981 1982 if (so != NULL) { 1983 if (soconnect(so, (struct sockaddr *)sa, sa_sz, 0, 0) != 0) { 1984 /* not calling isnst_close_so() to */ 1985 /* make dtrace output look clear */ 1986 idm_soshutdown(so); 1987 idm_sodestroy(so); 1988 so = NULL; 1989 } 1990 } 1991 1992 if (so == NULL) { 1993 struct sockaddr_in *sin; 1994 struct sockaddr_in6 *sin6; 1995 char s[INET6_ADDRSTRLEN]; 1996 void *ip; 1997 uint16_t port; 1998 sin = (struct sockaddr_in *)sa; 1999 port = ntohs(sin->sin_port); 2000 if (sa->ss_family == AF_INET) { 2001 ip = (void *)&sin->sin_addr.s_addr; 2002 (void) inet_ntop(AF_INET, ip, s, sizeof (s)); 2003 } else { 2004 sin6 = (struct sockaddr_in6 *)sa; 2005 ip = (void *)&sin6->sin6_addr.s6_addr; 2006 (void) inet_ntop(AF_INET6, ip, s, sizeof (s)); 2007 } 2008 cmn_err(CE_WARN, "open iSNS Server %s:%u failed", s, port); 2009 } 2010 2011 return (so); 2012 } 2013 2014 static void 2015 isnst_close_so(void *so) 2016 { 2017 idm_soshutdown(so); 2018 idm_sodestroy(so); 2019 } 2020 2021 2022 /* 2023 * ESI handling 2024 */ 2025 2026 static void 2027 isnst_esi_start_thread(isns_esi_tinfo_t *tinfop) 2028 { 2029 tinfop->esi_thread_running = B_FALSE; 2030 tinfop->esi_thread_failed = B_FALSE; 2031 tinfop->esi_registered = B_FALSE; 2032 tinfop->esi_thread = thread_create(NULL, 0, isnst_esi_thread, 2033 (void *)tinfop, 0, &p0, TS_RUN, minclsyspri); 2034 2035 mutex_enter(&isns_esi_mutex); 2036 list_insert_tail(&esi_list, tinfop); 2037 2038 /* 2039 * Wait for the thread to start 2040 */ 2041 2042 while (!tinfop->esi_thread_running && !tinfop->esi_thread_failed) { 2043 cv_wait(&isns_esi_cv, &isns_esi_mutex); 2044 } 2045 2046 mutex_exit(&isns_esi_mutex); 2047 } 2048 2049 static void 2050 isnst_esi_start(isns_portal_list_t *portal) 2051 { 2052 isns_esi_tinfo_t *tinfop; 2053 2054 ASSERT(ISNS_GLOBAL_LOCK_HELD()); 2055 2056 /* 2057 * Allocate our ESI thread info structure 2058 */ 2059 2060 tinfop = (isns_esi_tinfo_t *) 2061 kmem_zalloc(sizeof (isns_esi_tinfo_t), KM_NOSLEEP); 2062 2063 if (tinfop == NULL) { 2064 cmn_err(CE_WARN, "isnst_esi_start: Cant alloc ESI"); 2065 return; 2066 } 2067 2068 tinfop->esi_portal = portal; 2069 portal->portal_esi = tinfop; 2070 isnst_esi_start_thread(tinfop); 2071 } 2072 2073 /* 2074 * isnst_esi_check 2075 * 2076 * Verify that all the ESI threads are running and try to restart any that 2077 * failed for any reason. 2078 */ 2079 2080 static void 2081 isnst_esi_check() 2082 { 2083 isns_portal_list_t *portal; 2084 isns_esi_tinfo_t *tinfop; 2085 2086 /* 2087 * Now, threads for new portals or those which stopped for some other 2088 * reason will be started. 2089 */ 2090 2091 portal = list_head(&portal_list); 2092 2093 while (portal) { 2094 tinfop = portal->portal_esi; 2095 2096 if (tinfop && (!tinfop->esi_thread_running || 2097 tinfop->esi_thread_failed)) { 2098 isnst_esi_start_thread(tinfop); 2099 } 2100 2101 portal = list_next(&portal_list, portal); 2102 } 2103 } 2104 2105 /* 2106 * isnst_esi_thread 2107 * 2108 * This function listens on a socket for incoming connections from an 2109 * iSNS server until told to stop. 2110 */ 2111 2112 static void 2113 isnst_esi_thread(void *arg) 2114 { 2115 isns_esi_tinfo_t *tinfop; 2116 struct sonode *newso; 2117 struct sockaddr_in sin; 2118 struct sockaddr_in6 sin6; 2119 uint32_t on; 2120 int rc; 2121 isns_pdu_t *pdu; 2122 size_t pl_size; 2123 int family; 2124 2125 tinfop = (isns_esi_tinfo_t *)arg; 2126 tinfop->esi_thread_did = curthread->t_did; 2127 2128 /* 2129 * Create a socket to listen for requests from the iSNS server. 2130 */ 2131 2132 if (tinfop->esi_portal->portal_addr.ss_family == AF_INET) { 2133 family = AF_INET; 2134 } else { 2135 family = AF_INET6; 2136 } 2137 2138 2139 if ((tinfop->esi_so = 2140 idm_socreate(family, SOCK_STREAM, 0)) == NULL) { 2141 cmn_err(CE_WARN, 2142 "isnst_esi_thread: Unable to create socket"); 2143 tinfop->esi_thread_failed = B_TRUE; 2144 mutex_enter(&isns_esi_mutex); 2145 cv_signal(&isns_esi_cv); 2146 mutex_exit(&isns_esi_mutex); 2147 thread_exit(); 2148 } 2149 2150 /* 2151 * Set options, bind, and listen until we're told to stop 2152 */ 2153 2154 switch (family) { 2155 case AF_INET: 2156 bzero(&sin, sizeof (sin)); 2157 sin.sin_family = AF_INET; 2158 sin.sin_port = htons(0); 2159 bcopy(((caddr_t)&tinfop->esi_portal->portal_addr + 2160 offsetof(struct sockaddr_in, sin_addr)), 2161 &sin.sin_addr.s_addr, sizeof (in_addr_t)); 2162 on = 1; 2163 2164 (void) sosetsockopt(tinfop->esi_so, SOL_SOCKET, SO_REUSEADDR, 2165 (char *)&on, sizeof (on)); 2166 2167 if (sobind(tinfop->esi_so, (struct sockaddr *)&sin, 2168 sizeof (sin), 0, 0) != 0) { 2169 idm_sodestroy(tinfop->esi_so); 2170 tinfop->esi_so = NULL; 2171 tinfop->esi_thread_failed = B_TRUE; 2172 } else { 2173 tinfop->esi_port = ntohs(((struct sockaddr_in *) 2174 ((void *)tinfop->esi_so->so_laddr_sa))->sin_port); 2175 } 2176 2177 break; 2178 2179 case AF_INET6: 2180 bzero(&sin6, sizeof (sin6)); 2181 sin6.sin6_family = AF_INET6; 2182 sin6.sin6_port = htons(0); 2183 bcopy(((caddr_t)&tinfop->esi_portal->portal_addr + 2184 offsetof(struct sockaddr_in6, sin6_addr)), 2185 &sin6.sin6_addr.s6_addr, sizeof (in6_addr_t)); 2186 on = 1; 2187 2188 (void) sosetsockopt(tinfop->esi_so, SOL_SOCKET, 2189 SO_REUSEADDR, (char *)&on, sizeof (on)); 2190 2191 if (sobind(tinfop->esi_so, (struct sockaddr *)&sin6, 2192 sizeof (sin6), 0, 0) != 0) { 2193 idm_sodestroy(tinfop->esi_so); 2194 tinfop->esi_so = NULL; 2195 tinfop->esi_thread_failed = B_TRUE; 2196 } else { 2197 tinfop->esi_port = ntohs(((struct sockaddr_in6 *) 2198 ((void *)tinfop->esi_so->so_laddr_sa))->sin6_port); 2199 } 2200 2201 break; 2202 } 2203 2204 if (tinfop->esi_thread_failed) { 2205 cmn_err(CE_WARN, "Unable to bind socket for ESI"); 2206 goto esi_thread_exit; 2207 } 2208 2209 if ((rc = solisten(tinfop->esi_so, 5)) != 0) { 2210 cmn_err(CE_WARN, "isnst_esi_thread: listen failure 0x%x", rc); 2211 goto esi_thread_exit; 2212 } 2213 2214 mutex_enter(&isns_esi_mutex); 2215 /* 2216 * Mark the thread as running and the portal as no longer new. 2217 */ 2218 tinfop->esi_thread_running = B_TRUE; 2219 cv_signal(&isns_esi_cv); 2220 2221 while (tinfop->esi_thread_running && !tinfop->esi_thread_failed) { 2222 mutex_exit(&isns_esi_mutex); 2223 2224 if ((rc = soaccept(tinfop->esi_so, 0, &newso)) != 0) { 2225 mutex_enter(&isns_esi_mutex); 2226 /* 2227 * If we were interrupted with EINTR, it's not 2228 * really a failure. 2229 */ 2230 if (rc != EINTR) { 2231 cmn_err(CE_WARN, "isnst_esi_thread: " 2232 "accept failure (0x%x)", rc); 2233 tinfop->esi_thread_failed = B_TRUE; 2234 } 2235 2236 tinfop->esi_thread_running = B_FALSE; 2237 continue; 2238 } 2239 2240 mutex_enter(&isns_esi_mutex); 2241 2242 pl_size = isnst_rcv_pdu(newso, &pdu); 2243 2244 if (pl_size == 0) { 2245 cmn_err(CE_WARN, "isnst_esi_thread: rcv_pdu failure"); 2246 tinfop->esi_thread_failed = B_TRUE; 2247 continue; 2248 } 2249 2250 if (isnst_handle_esi_req(newso, pdu, pl_size) == B_TRUE) { 2251 tinfop->esi_registered = B_TRUE; 2252 } 2253 2254 (void) soshutdown(newso, SHUT_RDWR); 2255 2256 /* 2257 * Do not hold the esi mutex during server timestamp 2258 * update. It requires the isns global lock, which may 2259 * be held during other functions that also require 2260 * the esi_mutex (potential deadlock). 2261 */ 2262 mutex_exit(&isns_esi_mutex); 2263 isnst_update_server_timestamp(newso); 2264 mutex_enter(&isns_esi_mutex); 2265 } 2266 mutex_exit(&isns_esi_mutex); 2267 esi_thread_exit: 2268 idm_soshutdown(tinfop->esi_so); 2269 idm_sodestroy(tinfop->esi_so); 2270 mutex_enter(&isns_esi_mutex); 2271 tinfop->esi_thread_running = B_FALSE; 2272 tinfop->esi_so = NULL; 2273 tinfop->esi_port = 0; 2274 tinfop->esi_registered = B_FALSE; 2275 cv_signal(&isns_esi_cv); 2276 mutex_exit(&isns_esi_mutex); 2277 thread_exit(); 2278 } 2279 2280 /* 2281 * Handle an incoming ESI request 2282 */ 2283 2284 static boolean_t 2285 isnst_handle_esi_req(struct sonode *so, isns_pdu_t *pdu, size_t pl_size) 2286 { 2287 isns_pdu_t *rsp_pdu; 2288 isns_resp_t *rsp; 2289 size_t pl_len, rsp_size; 2290 boolean_t esirv = B_TRUE; 2291 2292 if (ntohs(pdu->func_id) != ISNS_ESI) { 2293 cmn_err(CE_WARN, "isnst_handle_esi_req: Unexpected func 0x%x", 2294 pdu->func_id); 2295 kmem_free(pdu, pl_size); 2296 return (B_FALSE); 2297 } 2298 2299 pl_len = ntohs(pdu->payload_len) + 4 /* ISNS_STATUS_SZ */; 2300 2301 if (pl_len > ISNSP_MAX_PAYLOAD_SIZE) { 2302 cmn_err(CE_WARN, "isnst_handle_esi_req: PDU payload too large " 2303 " (%ld bytes)", pl_len); 2304 kmem_free(pdu, pl_size); 2305 return (B_FALSE); 2306 } 2307 2308 rsp_size = isnst_create_pdu_header(ISNS_ESI_RSP, &rsp_pdu, 0); 2309 2310 if (rsp_size == 0) { 2311 cmn_err(CE_WARN, "isnst_handle_esi_req: Can't get rsp pdu"); 2312 kmem_free(pdu, pl_size); 2313 return (B_FALSE); 2314 } 2315 2316 rsp = (isns_resp_t *)((void *)(&rsp_pdu->payload[0])); 2317 2318 /* Use xid from the request pdu */ 2319 rsp_pdu->xid = pdu->xid; 2320 rsp->status = htonl(ISNS_RSP_SUCCESSFUL); 2321 2322 /* Copy original data */ 2323 bcopy(pdu->payload, rsp->data, pl_len - 4); 2324 rsp_pdu->payload_len = htons(pl_len); 2325 2326 if (isnst_send_pdu(so, rsp_pdu) != 0) { 2327 cmn_err(CE_WARN, "isnst_handle_esi_req: Send response failed"); 2328 esirv = B_FALSE; 2329 } 2330 2331 kmem_free(rsp_pdu, rsp_size); 2332 kmem_free(pdu, pl_size); 2333 2334 return (esirv); 2335 } 2336 2337 int 2338 isnst_tgt_avl_compare(const void *t1, const void *t2) 2339 { 2340 const isns_target_t *tgt1 = t1; 2341 const isns_target_t *tgt2 = t2; 2342 2343 /* 2344 * Sort by target (pointer to iscsit_tgt_t). 2345 */ 2346 2347 if (tgt1->target < tgt2->target) { 2348 return (-1); 2349 } else if (tgt1->target > tgt2->target) { 2350 return (1); 2351 } 2352 2353 return (0); 2354 } 2355 2356 static void 2357 isnst_get_target_list(void) 2358 { 2359 iscsit_tgt_t *tgt, *next_tgt; 2360 2361 /* 2362 * Initialize our list of targets with those from the global 2363 * list that are online. 2364 */ 2365 2366 for (tgt = avl_first(&iscsit_global.global_target_list); tgt != NULL; 2367 tgt = next_tgt) { 2368 next_tgt = AVL_NEXT(&iscsit_global.global_target_list, tgt); 2369 if (tgt->target_state == TS_STMF_ONLINE) { 2370 (void) isnst_add_to_target_list(tgt); 2371 } 2372 } 2373 } 2374 2375 static void 2376 isnst_set_server_status(iscsit_isns_svr_t *svr, boolean_t registered) 2377 { 2378 ASSERT(ISNS_GLOBAL_LOCK_HELD()); 2379 2380 if (registered == B_TRUE) { 2381 svr->svr_registered = B_TRUE; 2382 svr->svr_last_msg = ddi_get_lbolt(); 2383 } else { 2384 svr->svr_registered = B_FALSE; 2385 } 2386 } 2387 2388 static void 2389 isnst_add_default_portals() 2390 { 2391 idm_addr_list_t *default_portal_list; 2392 idm_addr_t *dportal; 2393 isns_portal_list_t *portal; 2394 struct sockaddr_in *sin; 2395 struct sockaddr_in6 *sin6; 2396 uint32_t dpl_size, idx; 2397 2398 ASSERT(ISNS_GLOBAL_LOCK_HELD()); 2399 2400 dpl_size = idm_get_ipaddr(&default_portal_list); 2401 2402 if (dpl_size == 0) { 2403 cmn_err(CE_WARN, "isnst_add_default_portals: " 2404 "No default portals"); 2405 return; 2406 } 2407 2408 for (idx = 0; idx < default_portal_list->al_out_cnt; idx++) { 2409 dportal = &default_portal_list->al_addrs[idx]; 2410 2411 if (dportal->a_addr.i_insize == 0) { 2412 continue; 2413 } 2414 2415 portal = kmem_zalloc(sizeof (isns_portal_list_t), KM_SLEEP); 2416 portal->portal_iscsit = NULL; /* Default portal */ 2417 2418 if (dportal->a_addr.i_insize == sizeof (struct in_addr)) { 2419 sin = (struct sockaddr_in *)&portal->portal_addr; 2420 sin->sin_family = AF_INET; 2421 sin->sin_port = htons(ISCSI_LISTEN_PORT); 2422 sin->sin_addr = dportal->a_addr.i_addr.in4; 2423 } else { 2424 sin6 = (struct sockaddr_in6 *)&portal->portal_addr; 2425 sin->sin_family = AF_INET6; 2426 sin6->sin6_port = htons(ISCSI_LISTEN_PORT); 2427 sin6->sin6_addr = dportal->a_addr.i_addr.in6; 2428 } 2429 2430 list_insert_tail(&portal_list, portal); 2431 isnst_esi_start(portal); 2432 } 2433 2434 kmem_free(default_portal_list, dpl_size); 2435 } 2436 2437 static void 2438 isnst_remove_default_portals() 2439 { 2440 isns_portal_list_t *portal, *next; 2441 2442 ASSERT(ISNS_GLOBAL_LOCK_HELD()); 2443 2444 portal = list_head(&portal_list); 2445 2446 while (portal) { 2447 next = list_next(&portal_list, portal); 2448 2449 if (portal->portal_iscsit == NULL) { 2450 mutex_enter(&isns_esi_mutex); 2451 isnst_esi_stop_thread(portal->portal_esi); 2452 mutex_exit(&isns_esi_mutex); 2453 isns_remove_portal(portal); 2454 } 2455 2456 portal = next; 2457 } 2458 } 2459 2460 /* 2461 * These functions are called by iscsit proper when a portal comes online 2462 * or goes offline. 2463 */ 2464 2465 void 2466 iscsit_isns_portal_online(iscsit_portal_t *portal) 2467 { 2468 isns_portal_list_t *iportal, *new_portal; 2469 struct sockaddr_in *sin; 2470 2471 ISNS_GLOBAL_LOCK(); 2472 2473 iportal = isns_lookup_portal(&portal->portal_addr); 2474 sin = (struct sockaddr_in *)&portal->portal_addr; 2475 2476 /* 2477 * If sin_family is 0, it's a "default" portal. It's possible 2478 * sin_family may be non-zero, so check portal_iscsit. If it's NULL, 2479 * it's a default portal as well. 2480 */ 2481 2482 if ((sin->sin_family == 0) || 2483 (iportal && (iportal->portal_iscsit == NULL))) { 2484 ISNS_GLOBAL_UNLOCK(); 2485 return; 2486 } 2487 2488 ASSERT(iportal == NULL); 2489 2490 new_portal = kmem_zalloc(sizeof (isns_portal_list_t), KM_SLEEP); 2491 new_portal->portal_addr = portal->portal_addr; 2492 sin = (struct sockaddr_in *)&new_portal->portal_addr; 2493 new_portal->portal_iscsit = portal; 2494 list_insert_tail(&portal_list, new_portal); 2495 portal_list_count++; 2496 nondefault_portals++; 2497 2498 ISNS_GLOBAL_UNLOCK(); 2499 } 2500 2501 void 2502 iscsit_isns_portal_offline(iscsit_portal_t *portal) 2503 { 2504 isns_portal_list_t *iportal = NULL; 2505 struct sockaddr_in *sin; 2506 boolean_t default_portals = B_FALSE; 2507 2508 ISNS_GLOBAL_LOCK(); 2509 2510 /* 2511 * Stop the ESI thread for this portal 2512 */ 2513 2514 iportal = isns_lookup_portal(&portal->portal_addr); 2515 sin = (struct sockaddr_in *)&portal->portal_addr; 2516 2517 if ((sin->sin_family == 0) || 2518 (iportal && (iportal->portal_iscsit == NULL))) { 2519 default_portals = B_TRUE; 2520 } else { 2521 iportal = isns_lookup_portal(&portal->portal_addr); 2522 ASSERT(iportal); 2523 } 2524 2525 if (!default_portals) { 2526 isns_remove_portal(iportal); 2527 nondefault_portals--; 2528 } 2529 2530 ISNS_GLOBAL_UNLOCK(); 2531 } 2532