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 "iscsi.h" 27 #include "nvfile.h" 28 #include "persistent.h" 29 #include <sys/scsi/adapters/iscsi_if.h> 30 #include <netinet/in.h> 31 32 /* 33 * MAX_KEY_SIZE needs to be the same size of the ISCSI_MAX_NAME_LEN 34 * plus space for a ',' and a string form of tpgt (5 bytes). 35 */ 36 #define MAX_KEY_SIZE (ISCSI_MAX_NAME_LEN + 5) 37 38 /* 39 * Name identifiers for the various types of data 40 */ 41 #define DISCOVERY_METHOD_ID "DiscMethod" 42 #define NODE_NAME_ID "NodeName" 43 #define NODE_ALIAS_ID "NodeAlias" 44 #define STATIC_ADDR_ID "StaticAddr" 45 #define STATIC_ADDR2_ID "StaticAddr2" 46 #define DISCOVERY_ADDR_ID "DiscAddr" 47 #define ISNS_SERVER_ADDR_ID "ISNSAddr" 48 #define LOGIN_PARAMS_ID "Login" 49 #define CHAP_PARAMS_ID "Chap" 50 #define RADIUS_PARAMS_ID "Radius" 51 #define BIDIR_AUTH_PARAMS_ID "BidirAuth" 52 #define SESSION_PARAMS_ID "Session" 53 54 /* 55 * Local Global Variables 56 */ 57 static kmutex_t static_addr_data_lock; 58 static kmutex_t disc_addr_data_lock; 59 static kmutex_t isns_addr_data_lock; 60 static kmutex_t param_data_lock; 61 static kmutex_t chap_data_lock; 62 static kmutex_t auth_data_lock; 63 64 /* 65 * Local Function Prototypes 66 */ 67 static boolean_t persistent_disc_meth_common(iSCSIDiscoveryMethod_t method, 68 boolean_t do_clear); 69 static void persistent_static_addr_upgrade_to_v2(); 70 71 /* 72 * persistent_init_disc_addr_oids - Oid is stored with discovery address 73 * however oids are not persisted and the discovery address oids need to 74 * be regenerated during initialization. 75 */ 76 static void persistent_init_disc_addr_oids() 77 { 78 uint32_t addr_count = 0; 79 void *void_p = NULL; 80 entry_t e; 81 uint32_t i, curr_count; 82 83 /* 84 * Using two loops here as as addresses are updated and readded we get 85 * into an infinite loop while doing persistent_disc_addr_next if we 86 * update the entry as we go. The first loop will get the number of 87 * addresses that need to be updated and the second will update that 88 * many addresses. 89 */ 90 persistent_disc_addr_lock(); 91 while (persistent_disc_addr_next(&void_p, &e) == B_TRUE) { 92 addr_count++; 93 } 94 persistent_disc_addr_unlock(); 95 96 for (i = 0; i < addr_count; i++) { 97 curr_count = 0; 98 99 void_p = NULL; 100 persistent_disc_addr_lock(); 101 102 /* Use curr_count to skip previously updated addresses */ 103 while (persistent_disc_addr_next(&void_p, &e) == 104 B_TRUE && i < curr_count) { 105 curr_count++; 106 } 107 persistent_disc_addr_unlock(); 108 109 mutex_enter(&iscsi_oid_mutex); 110 e.e_oid = iscsi_oid++; 111 mutex_exit(&iscsi_oid_mutex); 112 113 if (persistent_disc_addr_set(&e) == B_FALSE) { 114 break; 115 } 116 } 117 } 118 119 /* 120 * persistent_init_static_addr_oids - Oid is stored with static address 121 * however oids are not persisted and the static address oids need to 122 * be regenerated during initialization. 123 */ 124 static void persistent_init_static_addr_oids() 125 { 126 uint32_t addr_count = 0; 127 void *void_p = NULL; 128 entry_t e; 129 uint32_t i, curr_count; 130 char *target_name; 131 132 /* 133 * Solaris 10 Update 1/2 initially had a database 134 * that didn't support the multiple static-config 135 * entries to the same target. The below call 136 * will check if the database is still of that 137 * old structure and upgrade it. It will leave 138 * the old records incase a down grade of the 139 * software is required. 140 */ 141 persistent_static_addr_upgrade_to_v2(); 142 143 /* 144 * Using two loops here as as addresses are updated and readded we get 145 * into an infinite loop while doing persistent_disc_addr_next if we 146 * update the entry as we go. The first loop will get the number of 147 * addresses that need to be updated and the second will update that 148 * many addresses. 149 */ 150 target_name = kmem_alloc(MAX_KEY_SIZE, KM_SLEEP); 151 persistent_static_addr_lock(); 152 while (persistent_static_addr_next(&void_p, target_name, &e) == 153 B_TRUE) { 154 addr_count++; 155 } 156 157 for (i = 0; i < addr_count; i++) { 158 curr_count = 0; 159 160 void_p = NULL; 161 162 /* Use curr_count to skip previously updated addresses */ 163 while ((persistent_static_addr_next( 164 &void_p, target_name, &e) == B_TRUE) && 165 (i < curr_count)) { 166 curr_count++; 167 } 168 169 mutex_enter(&iscsi_oid_mutex); 170 e.e_oid = iscsi_oid++; 171 mutex_exit(&iscsi_oid_mutex); 172 173 if (persistent_static_addr_set(target_name, &e) == B_FALSE) { 174 break; 175 } 176 } 177 persistent_static_addr_unlock(); 178 kmem_free(target_name, MAX_KEY_SIZE); 179 } 180 181 /* 182 * persistent_static_addr_upgrade_to_v2 - checks to see if the 183 * STATIC_ADDR2_ID exists in the persistent store tree. If not 184 * found then it converts the STATIC_ADDR_ID data into the 185 * STATIC_ADDR2_ID format and saves the branch. 186 */ 187 static void 188 persistent_static_addr_upgrade_to_v2() 189 { 190 entry_t e; 191 char *target_name; 192 char *c_end; 193 void *void_p = NULL; 194 195 /* 196 * Check is version 2 of STATIC_ADDR list exists. 197 */ 198 target_name = kmem_zalloc(MAX_KEY_SIZE, KM_SLEEP); 199 persistent_static_addr_lock(); 200 if (nvf_list_check(STATIC_ADDR2_ID) == B_FALSE) { 201 /* 202 * We need to upgrade any existing 203 * STATIC_ADDR data to version 2. Loop 204 * thru all old entries and set new version 205 * values. 206 */ 207 while (nvf_data_next(STATIC_ADDR_ID, &void_p, 208 target_name, (void *)&e, sizeof (e)) == B_TRUE) { 209 /* Convert STATIC_ADDR to STATIC_ADDR2 */ 210 c_end = strchr(target_name, ','); 211 if (c_end == NULL) { 212 continue; 213 } 214 *c_end = '\0'; 215 /* Add updated record */ 216 (void) persistent_static_addr_set(target_name, &e); 217 } 218 } 219 persistent_static_addr_unlock(); 220 kmem_free(target_name, MAX_KEY_SIZE); 221 } 222 223 /* 224 * persistent_init -- initialize use of the persistent store 225 */ 226 boolean_t 227 persistent_init(boolean_t restart) 228 { 229 boolean_t rval; 230 231 if (restart == B_FALSE) { 232 nvf_init(); 233 mutex_init(&static_addr_data_lock, NULL, MUTEX_DRIVER, NULL); 234 mutex_init(&disc_addr_data_lock, NULL, MUTEX_DRIVER, NULL); 235 mutex_init(&isns_addr_data_lock, NULL, MUTEX_DRIVER, NULL); 236 mutex_init(¶m_data_lock, NULL, MUTEX_DRIVER, NULL); 237 mutex_init(&chap_data_lock, NULL, MUTEX_DRIVER, NULL); 238 mutex_init(&auth_data_lock, NULL, MUTEX_DRIVER, NULL); 239 } 240 241 rval = nvf_load(); 242 243 if (rval) { 244 persistent_init_disc_addr_oids(); 245 persistent_init_static_addr_oids(); 246 } 247 248 return (rval); 249 } 250 251 /* 252 * persistent_fini -- finish using the persistent store 253 */ 254 void 255 persistent_fini(void) 256 { 257 nvf_fini(); 258 259 mutex_destroy(&static_addr_data_lock); 260 mutex_destroy(&disc_addr_data_lock); 261 mutex_destroy(¶m_data_lock); 262 mutex_destroy(&chap_data_lock); 263 mutex_destroy(&auth_data_lock); 264 } 265 266 267 /* 268 * +--------------------------------------------------------------------+ 269 * | Discovery Method Interfaces | 270 * +--------------------------------------------------------------------+ 271 */ 272 273 /* 274 * persistent_disc_meth_set -- enable a specific discovery method 275 */ 276 boolean_t 277 persistent_disc_meth_set(iSCSIDiscoveryMethod_t method) 278 { 279 return (persistent_disc_meth_common(method, B_FALSE)); 280 } 281 282 /* 283 * persistent_disc_meth_get -- return the status of all discovery methods as 284 * found in the persistent store 285 */ 286 iSCSIDiscoveryMethod_t 287 persistent_disc_meth_get(void) 288 { 289 boolean_t rval; 290 iSCSIDiscoveryMethod_t methods; 291 292 rval = nvf_node_value_get(DISCOVERY_METHOD_ID, (uint32_t *)&methods); 293 if (rval == B_FALSE) { 294 methods = iSCSIDiscoveryMethodUnknown; 295 } 296 297 return (methods); 298 } 299 300 /* 301 * persistent_disc_meth_clear -- disable a specific discovery method 302 */ 303 boolean_t 304 persistent_disc_meth_clear(iSCSIDiscoveryMethod_t method) 305 { 306 return (persistent_disc_meth_common(method, B_TRUE)); 307 } 308 309 310 311 /* 312 * persistent_disc_meth_common - common function used to set or clear the 313 * status of a discovery method in the persistent store. 314 */ 315 static boolean_t 316 persistent_disc_meth_common(iSCSIDiscoveryMethod_t method, boolean_t do_clear) 317 { 318 boolean_t rval; 319 iSCSIDiscoveryMethod_t discovery_types = iSCSIDiscoveryMethodUnknown; 320 321 (void) nvf_node_value_get(DISCOVERY_METHOD_ID, 322 (uint32_t *)&discovery_types); 323 if (do_clear) { 324 discovery_types &= ~method; 325 } else { 326 discovery_types |= method; 327 } 328 329 rval = nvf_node_value_set(DISCOVERY_METHOD_ID, discovery_types); 330 331 return (rval); 332 } 333 334 335 336 /* 337 * +--------------------------------------------------------------------+ 338 * | Node/Initiator Name Interfaces | 339 * +--------------------------------------------------------------------+ 340 */ 341 342 /* 343 * persistent_initiator_name_set -- sets the node's initiator name 344 */ 345 boolean_t 346 persistent_initiator_name_set(char *p) 347 { 348 return (nvf_node_name_set(NODE_NAME_ID, p)); 349 } 350 351 /* 352 * persistent_initiator_name_get -- returns the node's initiator name 353 */ 354 boolean_t 355 persistent_initiator_name_get(char *p, int size) 356 { 357 return (nvf_node_name_get(NODE_NAME_ID, p, size)); 358 } 359 360 361 /* 362 * +--------------------------------------------------------------------+ 363 * | Node/Initiator Alias Interfaces | 364 * +--------------------------------------------------------------------+ 365 */ 366 367 /* 368 * persistent_alias_name_set -- sets the node's initiator name alias 369 */ 370 boolean_t 371 persistent_alias_name_set(char *p) 372 { 373 return (nvf_node_name_set(NODE_ALIAS_ID, p)); 374 } 375 376 /* 377 * persistent_initiator_name_get -- returns the node's initiator name alias 378 */ 379 boolean_t 380 persistent_alias_name_get(char *p, int size) 381 { 382 return (nvf_node_name_get(NODE_ALIAS_ID, p, size)); 383 } 384 385 386 /* 387 * +--------------------------------------------------------------------+ 388 * | Static Target Address Interfaces | 389 * +--------------------------------------------------------------------+ 390 */ 391 392 /* 393 * persistent_static_addr_set -- store hostname, IP address, and port 394 * information for a specific target. 395 */ 396 boolean_t 397 persistent_static_addr_set(char *target_name, entry_t *e) 398 { 399 boolean_t rval; 400 char *key; 401 char *ip_str; 402 403 ASSERT(target_name != NULL); 404 ASSERT(e != NULL); 405 ASSERT(mutex_owned(&static_addr_data_lock)); 406 407 key = kmem_zalloc(MAX_KEY_SIZE, KM_SLEEP); 408 ip_str = kmem_zalloc(INET6_ADDRSTRLEN, KM_SLEEP); 409 if (e->e_insize == sizeof (struct in_addr)) { 410 (void) inet_ntop(AF_INET, &e->e_u.u_in4, 411 ip_str, INET6_ADDRSTRLEN); 412 } else { 413 (void) inet_ntop(AF_INET6, &e->e_u.u_in6, 414 ip_str, INET6_ADDRSTRLEN); 415 } 416 417 if (snprintf(key, MAX_KEY_SIZE - 1, "%s,%s:%d,%d", 418 target_name, ip_str, e->e_port, e->e_tpgt) >= MAX_KEY_SIZE) { 419 kmem_free(key, MAX_KEY_SIZE); 420 kmem_free(ip_str, INET6_ADDRSTRLEN); 421 return (B_FALSE); 422 } 423 424 rval = nvf_data_set(STATIC_ADDR2_ID, key, (void *)e, 425 sizeof (entry_t)); 426 427 kmem_free(key, MAX_KEY_SIZE); 428 kmem_free(ip_str, INET6_ADDRSTRLEN); 429 return (rval); 430 } 431 432 /* 433 * persistent_static_addr_next -- get the next target's hostname, IP address, 434 * and port information. 435 * 436 * The first time this function is called, the argument (void **v) 437 * should be a pointer to a value of NULL which causes this function to obtain 438 * the first static target element. 439 * 440 * This function assumes the associated static address lock is held. 441 * 442 * Returns B_TRUE when data is valid. B_FALSE returned when data is 443 * not available (end of configured targets has been reached). 444 * 445 */ 446 boolean_t 447 persistent_static_addr_next(void **v, char *target_name, entry_t *e) 448 { 449 boolean_t rval; 450 char *c_end, *key; 451 452 ASSERT(v != NULL); 453 ASSERT(target_name != NULL); 454 ASSERT(e != NULL); 455 ASSERT(mutex_owned(&static_addr_data_lock)); 456 457 key = kmem_zalloc(MAX_KEY_SIZE, KM_SLEEP); 458 rval = nvf_data_next(STATIC_ADDR2_ID, v, key, 459 (void *)e, sizeof (*e)); 460 461 /* extract target_name */ 462 c_end = strchr(key, ','); 463 if (c_end == NULL) { 464 kmem_free(key, MAX_KEY_SIZE); 465 return (B_FALSE); 466 } 467 *c_end = '\0'; 468 /* copy target name */ 469 (void) strcpy(target_name, key); 470 471 kmem_free(key, MAX_KEY_SIZE); 472 473 return (rval); 474 } 475 476 /* 477 * persistent_static_addr_clear -- remove the next hostname, IP address, and 478 * port information for a specific target from the configured static targets. 479 */ 480 boolean_t 481 persistent_static_addr_clear(uint32_t oid) 482 { 483 boolean_t rval = B_FALSE; 484 void *void_p = NULL; 485 entry_t e; 486 char *key; 487 char *target_name; 488 char *ip_str; 489 490 /* Find the entry based on oid then record the name and tpgt */ 491 target_name = kmem_zalloc(MAX_KEY_SIZE, KM_SLEEP); 492 persistent_static_addr_lock(); 493 while (persistent_static_addr_next( 494 &void_p, target_name, &e) == B_TRUE) { 495 if (e.e_oid == oid) { 496 break; 497 } 498 } 499 500 /* If we found a match clear the entry */ 501 if (e.e_oid == oid) { 502 ip_str = kmem_zalloc(INET6_ADDRSTRLEN, KM_SLEEP); 503 key = kmem_zalloc(MAX_KEY_SIZE, KM_SLEEP); 504 if (e.e_insize == sizeof (struct in_addr)) { 505 (void) inet_ntop(AF_INET, &e.e_u.u_in4, 506 ip_str, INET6_ADDRSTRLEN); 507 } else { 508 (void) inet_ntop(AF_INET6, &e.e_u.u_in6, 509 ip_str, INET6_ADDRSTRLEN); 510 } 511 512 if (snprintf(key, MAX_KEY_SIZE - 1, "%s,%s:%d,%d", 513 target_name, ip_str, e.e_port, e.e_tpgt) >= MAX_KEY_SIZE) { 514 persistent_static_addr_unlock(); 515 kmem_free(key, MAX_KEY_SIZE); 516 kmem_free(ip_str, INET6_ADDRSTRLEN); 517 kmem_free(target_name, MAX_KEY_SIZE); 518 return (B_FALSE); 519 } 520 521 rval = nvf_data_clear(STATIC_ADDR2_ID, key); 522 kmem_free(key, MAX_KEY_SIZE); 523 kmem_free(ip_str, INET6_ADDRSTRLEN); 524 } 525 persistent_static_addr_unlock(); 526 kmem_free(target_name, MAX_KEY_SIZE); 527 528 return (rval); 529 } 530 531 532 /* 533 * persistent_static_addr_lock -- lock access to static targets. This 534 * ensures static targets are unchanged while the lock is held. The 535 * lock should be grabbed while walking through the static targets. 536 */ 537 void 538 persistent_static_addr_lock(void) 539 { 540 mutex_enter(&static_addr_data_lock); 541 } 542 543 /* 544 * persistent_static_addr_unlock -- unlock access to the configured of static 545 * targets. 546 */ 547 void 548 persistent_static_addr_unlock(void) 549 { 550 mutex_exit(&static_addr_data_lock); 551 } 552 553 554 /* 555 * +--------------------------------------------------------------------+ 556 * | ISNS Server Address Interfaces | 557 * +--------------------------------------------------------------------+ 558 */ 559 560 /* 561 * persistent_addr_set -- store entry address information 562 */ 563 boolean_t 564 persistent_isns_addr_set(entry_t *e) 565 { 566 char name[INET6_ADDRSTRLEN]; 567 boolean_t rval; 568 569 /* 570 * Create name from given discovery address - SendTargets discovery 571 * nodes do not have an associated node name. A name is manufactured 572 * from the IP address given. 573 */ 574 if (e->e_insize == sizeof (struct in_addr)) { 575 (void) inet_ntop(AF_INET, &e->e_u.u_in4, name, sizeof (name)); 576 } else { 577 (void) inet_ntop(AF_INET6, &e->e_u.u_in6, name, sizeof (name)); 578 } 579 580 mutex_enter(&isns_addr_data_lock); 581 rval = nvf_data_set(ISNS_SERVER_ADDR_ID, name, 582 (void *)e, sizeof (entry_t)); 583 mutex_exit(&isns_addr_data_lock); 584 585 return (rval); 586 } 587 588 /* 589 * persistent_disc_addr_next -- get the next iSCSI discovery node's address 590 * and port information. 591 * 592 * The first time this function is called, the argument (void **v) 593 * should be a pointer to a value of NULL which causes this function to obtain 594 * the first discovery address element. 595 * 596 * This function assumes the associated disccovery address lock is held. 597 * 598 * Returns B_TRUE when data is valid. B_FALSE returned when data is 599 * not available (end of configured discovery addresses has been reached). 600 * 601 */ 602 boolean_t 603 persistent_isns_addr_next(void **v, entry_t *e) 604 { 605 char name[INET6_ADDRSTRLEN]; 606 607 ASSERT(mutex_owned(&isns_addr_data_lock)); 608 609 return (nvf_data_next(ISNS_SERVER_ADDR_ID, v, name, 610 (void *)e, sizeof (*e))); 611 } 612 613 /* 614 * persistent_disc_addr_clear -- remove IP address and port information from 615 * the configured SendTargets discovery nodes. 616 */ 617 boolean_t 618 persistent_isns_addr_clear(entry_t *e) 619 { 620 char name[INET6_ADDRSTRLEN]; 621 boolean_t rval; 622 623 /* 624 * Create name from given discovery address - SendTargets discovery 625 * nodes do not have an associated node name. A name is manufactured 626 * from the IP address given. 627 */ 628 if (e->e_insize == sizeof (struct in_addr)) { 629 (void) inet_ntop(AF_INET, &e->e_u.u_in4, name, sizeof (name)); 630 } else { 631 (void) inet_ntop(AF_INET6, &e->e_u.u_in6, name, sizeof (name)); 632 } 633 634 mutex_enter(&static_addr_data_lock); 635 rval = nvf_data_clear(ISNS_SERVER_ADDR_ID, name); 636 mutex_exit(&static_addr_data_lock); 637 638 return (rval); 639 } 640 641 642 /* 643 * persistent_disc_addr_lock -- lock access to the SendTargets discovery 644 * addresses. This ensures discovery addresses are unchanged while the lock 645 * is held. The lock should be grabbed while walking through the discovery 646 * addresses 647 */ 648 void 649 persistent_isns_addr_lock(void) 650 { 651 mutex_enter(&isns_addr_data_lock); 652 } 653 654 /* 655 * persistent_disc_addr_unlock -- unlock access to discovery addresses. 656 */ 657 void 658 persistent_isns_addr_unlock(void) 659 { 660 mutex_exit(&isns_addr_data_lock); 661 } 662 663 /* 664 * +--------------------------------------------------------------------+ 665 * | Discovery Address Interfaces | 666 * +--------------------------------------------------------------------+ 667 */ 668 669 /* 670 * persistent_disc_addr_set -- store IP address, and port information for 671 * for an iSCSI discovery node that provides target information via a 672 * SendTargets response. 673 */ 674 boolean_t 675 persistent_disc_addr_set(entry_t *e) 676 { 677 char name[INET6_ADDRSTRLEN]; 678 boolean_t rval; 679 680 /* 681 * Create name from given discovery address - SendTargets discovery 682 * nodes do not have an associated node name. A name is manufactured 683 * from the IP address given. 684 */ 685 if (e->e_insize == sizeof (struct in_addr)) { 686 (void) inet_ntop(AF_INET, &e->e_u.u_in4, name, sizeof (name)); 687 } else { 688 (void) inet_ntop(AF_INET6, &e->e_u.u_in6, name, sizeof (name)); 689 } 690 691 mutex_enter(&disc_addr_data_lock); 692 rval = nvf_data_set(DISCOVERY_ADDR_ID, name, 693 (void *)e, sizeof (entry_t)); 694 mutex_exit(&disc_addr_data_lock); 695 696 return (rval); 697 } 698 699 /* 700 * persistent_disc_addr_next -- get the next iSCSI discovery node's address 701 * and port information. 702 * 703 * The first time this function is called, the argument (void **v) 704 * should be a pointer to a value of NULL which causes this function to obtain 705 * the first discovery address element. 706 * 707 * This function assumes the associated disccovery address lock is held. 708 * 709 * Returns B_TRUE when data is valid. B_FALSE returned when data is 710 * not available (end of configured discovery addresses has been reached). 711 * 712 */ 713 boolean_t 714 persistent_disc_addr_next(void **v, entry_t *e) 715 { 716 char name[INET6_ADDRSTRLEN]; 717 718 ASSERT(mutex_owned(&disc_addr_data_lock)); 719 720 return (nvf_data_next(DISCOVERY_ADDR_ID, v, name, 721 (void *)e, sizeof (*e))); 722 } 723 724 /* 725 * persistent_disc_addr_clear -- remove IP address and port information from 726 * the configured SendTargets discovery nodes. 727 */ 728 boolean_t 729 persistent_disc_addr_clear(entry_t *e) 730 { 731 char name[INET6_ADDRSTRLEN]; 732 boolean_t rval; 733 734 /* 735 * Create name from given discovery address - SendTargets discovery 736 * nodes do not have an associated node name. A name is manufactured 737 * from the IP address given. 738 */ 739 if (e->e_insize == sizeof (struct in_addr)) { 740 (void) inet_ntop(AF_INET, &e->e_u.u_in4, name, sizeof (name)); 741 } else { 742 (void) inet_ntop(AF_INET6, &e->e_u.u_in6, name, sizeof (name)); 743 } 744 745 mutex_enter(&static_addr_data_lock); 746 rval = nvf_data_clear(DISCOVERY_ADDR_ID, name); 747 mutex_exit(&static_addr_data_lock); 748 749 return (rval); 750 } 751 752 753 /* 754 * persistent_disc_addr_lock -- lock access to the SendTargets discovery 755 * addresses. This ensures discovery addresses are unchanged while the lock 756 * is held. The lock should be grabbed while walking through the discovery 757 * addresses 758 */ 759 void 760 persistent_disc_addr_lock(void) 761 { 762 mutex_enter(&disc_addr_data_lock); 763 } 764 765 /* 766 * persistent_disc_addr_unlock -- unlock access to discovery addresses. 767 */ 768 void 769 persistent_disc_addr_unlock(void) 770 { 771 mutex_exit(&disc_addr_data_lock); 772 } 773 774 775 /* 776 * +--------------------------------------------------------------------+ 777 * | Login Parameter Interfaces | 778 * +--------------------------------------------------------------------+ 779 */ 780 781 /* 782 * persistent_param_set -- store login parameters for a specific target 783 */ 784 boolean_t 785 persistent_param_set(char *node, persistent_param_t *param) 786 { 787 boolean_t rval; 788 789 mutex_enter(¶m_data_lock); 790 rval = nvf_data_set(LOGIN_PARAMS_ID, node, 791 (void *)param, sizeof (persistent_param_t)); 792 mutex_exit(¶m_data_lock); 793 794 return (rval); 795 } 796 797 /* 798 * persistent_param_get -- obtain login parameters for a specific target 799 */ 800 boolean_t 801 persistent_param_get(char *node, persistent_param_t *param) 802 { 803 return (nvf_data_get(LOGIN_PARAMS_ID, node, 804 (void *)param, sizeof (*param))); 805 } 806 807 /* 808 * persistent_param_next -- get the next target's login parameters. 809 * 810 * The first time this function is called, the argument (void **v) 811 * should be a pointer to a value of NULL which causes this function to obtain 812 * the first target's login parameters. 813 * 814 * This function assumes the associated login parameter lock is held. 815 * 816 * Returns B_TRUE when data in *param is valid. B_FALSE returned when no 817 * more data is available (end of configured target login parameters). 818 */ 819 boolean_t 820 persistent_param_next(void **v, char *node, persistent_param_t *param) 821 { 822 ASSERT(mutex_owned(¶m_data_lock)); 823 824 return (nvf_data_next(LOGIN_PARAMS_ID, v, node, 825 (void *)param, sizeof (*param))); 826 } 827 828 /* 829 * persistent_param_clear -- remove login parameters for a specific target 830 */ 831 boolean_t 832 persistent_param_clear(char *node) 833 { 834 boolean_t rval1, rval2; 835 836 mutex_enter(¶m_data_lock); 837 rval1 = nvf_data_clear(LOGIN_PARAMS_ID, node); 838 rval2 = nvf_data_clear(SESSION_PARAMS_ID, node); 839 mutex_exit(¶m_data_lock); 840 841 return (((rval1 == B_TRUE) || (rval2 == B_TRUE)) ? B_TRUE : B_FALSE); 842 } 843 844 /* 845 * persistent_param_lock -- lock access to login parameters. This 846 * ensures the login parameters will be unchanged while the lock is held. 847 * The lock should be grabbed while walking through the login parameters. 848 */ 849 void 850 persistent_param_lock(void) 851 { 852 mutex_enter(¶m_data_lock); 853 } 854 855 /* 856 * persistent_param_unlock -- unlock access to login parameters. 857 */ 858 void 859 persistent_param_unlock(void) 860 { 861 mutex_exit(¶m_data_lock); 862 } 863 864 /* 865 * +--------------------------------------------------------------------+ 866 * | Session Config Interfaces | 867 * +--------------------------------------------------------------------+ 868 */ 869 870 871 /* 872 * persistent_set_config_session -- store configured sessions 873 * for a specific target 874 */ 875 boolean_t 876 persistent_set_config_session(char *node, iscsi_config_sess_t *ics) 877 { 878 boolean_t rval; 879 int size; 880 881 /* 882 * Make ics_out match ics_in. Since when someone gets 883 * this information the in value becomes the out. 884 */ 885 ics->ics_out = ics->ics_in; 886 887 /* calculate size */ 888 size = ISCSI_SESSION_CONFIG_SIZE(ics->ics_in); 889 890 mutex_enter(¶m_data_lock); 891 rval = nvf_data_set(SESSION_PARAMS_ID, node, (void *)ics, size); 892 mutex_exit(¶m_data_lock); 893 894 return (rval); 895 } 896 897 /* 898 * persistent_get_config_session -- obtain configured sessions 899 * for a specific target 900 */ 901 boolean_t 902 persistent_get_config_session(char *node, iscsi_config_sess_t *ics) 903 { 904 boolean_t status; 905 int in; 906 int size; 907 908 ASSERT(ics->ics_in >= 1); 909 910 /* record caller buffer size */ 911 in = ics->ics_in; 912 913 /* Get base config_sess information */ 914 size = ISCSI_SESSION_CONFIG_SIZE(in); 915 status = nvf_data_get(SESSION_PARAMS_ID, node, 916 (void *)ics, size); 917 918 /* reset the in size */ 919 ics->ics_in = in; 920 921 return (status); 922 } 923 924 /* 925 * +--------------------------------------------------------------------+ 926 * | CHAP Parameter Interfaces | 927 * +--------------------------------------------------------------------+ 928 */ 929 930 /* 931 * persistent_chap_set -- store CHAP parameters for a specific target 932 */ 933 boolean_t 934 persistent_chap_set(char *node, iscsi_chap_props_t *chap) 935 { 936 boolean_t rval; 937 938 mutex_enter(&chap_data_lock); 939 rval = nvf_data_set(CHAP_PARAMS_ID, node, 940 (void *)chap, sizeof (iscsi_chap_props_t)); 941 mutex_exit(&chap_data_lock); 942 943 return (rval); 944 } 945 946 /* 947 * persistent_chap_get -- obtain CHAP parameters for a specific target 948 */ 949 boolean_t 950 persistent_chap_get(char *node, iscsi_chap_props_t *chap) 951 { 952 return (nvf_data_get(CHAP_PARAMS_ID, node, 953 (void *)chap, sizeof (*chap))); 954 } 955 956 /* 957 * persistent_chap_next -- copy the next target's chap parameters. 958 * 959 * The first time this function is called, the argument (void **v) 960 * should be a pointer to a value of NULL which causes this function to obtain 961 * the first target's login parameters. 962 * 963 * This function assumes the associated chap parameter lock is held. 964 * 965 * Returns B_TRUE when data in *param is valid. B_FALSE returned when no 966 * more data is available. 967 */ 968 boolean_t 969 persistent_chap_next(void **v, char *node, iscsi_chap_props_t *chap) 970 { 971 ASSERT(mutex_owned(&chap_data_lock)); 972 973 return (nvf_data_next(CHAP_PARAMS_ID, v, node, 974 (void *)chap, sizeof (*chap))); 975 } 976 977 /* 978 * persistent_chap_clear -- remove CHAP parameters for a specific target 979 */ 980 boolean_t 981 persistent_chap_clear(char *node) 982 { 983 boolean_t rval; 984 985 mutex_enter(&chap_data_lock); 986 rval = nvf_data_clear(CHAP_PARAMS_ID, node); 987 mutex_exit(&chap_data_lock); 988 989 return (rval); 990 } 991 992 /* 993 * persistent_chap_lock -- lock access to chap parameters. This 994 * ensures the chap parameters will be unchanged while the lock is held. 995 * The lock should be grabbed while walking through the chap parameters. 996 */ 997 void 998 persistent_chap_lock(void) 999 { 1000 mutex_enter(&chap_data_lock); 1001 } 1002 1003 /* 1004 * persistent_chap_unlock -- unlock access to chap parameters. 1005 */ 1006 void 1007 persistent_chap_unlock(void) 1008 { 1009 mutex_exit(&chap_data_lock); 1010 } 1011 1012 1013 /* 1014 * +--------------------------------------------------------------------+ 1015 * | RADIUS Configuration Interfaces | 1016 * +--------------------------------------------------------------------+ 1017 */ 1018 1019 /* 1020 * persistent_radius_set -- stores the RADIUS configuration info 1021 */ 1022 boolean_t 1023 persistent_radius_set(iscsi_radius_props_t *radius) 1024 { 1025 return (nvf_node_data_set(RADIUS_PARAMS_ID, (void *)radius, 1026 sizeof (iscsi_radius_props_t))); 1027 } 1028 1029 /* 1030 * persistent_radius_get -- obtain the RADIUS configuration info 1031 */ 1032 iscsi_nvfile_status_t 1033 persistent_radius_get(iscsi_radius_props_t *radius) 1034 { 1035 return (nvf_node_data_get(RADIUS_PARAMS_ID, 1036 (void *)radius, sizeof (*radius))); 1037 } 1038 1039 1040 /* 1041 * +--------------------------------------------------------------------+ 1042 * | Authentication Configuration Interface | 1043 * +--------------------------------------------------------------------+ 1044 */ 1045 1046 /* 1047 * persistent_auth_set -- stores the bidirectional authentication settings 1048 * for a specific target 1049 */ 1050 boolean_t 1051 persistent_auth_set(char *node, iscsi_auth_props_t *auth) 1052 { 1053 boolean_t rval; 1054 1055 mutex_enter(&auth_data_lock); 1056 rval = nvf_data_set(BIDIR_AUTH_PARAMS_ID, node, 1057 (void *)auth, sizeof (iscsi_auth_props_t)); 1058 mutex_exit(&auth_data_lock); 1059 1060 return (rval); 1061 } 1062 1063 /* 1064 * persistent_auth_get -- gets the bidirectional authentication settings 1065 * for a specific target 1066 */ 1067 boolean_t 1068 persistent_auth_get(char *node, iscsi_auth_props_t *auth) 1069 { 1070 return (nvf_data_get(BIDIR_AUTH_PARAMS_ID, node, 1071 (void *)auth, sizeof (*auth))); 1072 } 1073 1074 /* 1075 * persistent_auth_next -- get the next target's bidirectional authentication 1076 * parameters. 1077 * 1078 * The first time this function is called, the argument (void **v) 1079 * should be a pointer to a value of NULL which causes this function to obtain 1080 * the first target's login parameters. 1081 * 1082 * This function assumes the associated bidirectional authentication lock is 1083 * held. 1084 * 1085 * Returns B_TRUE when data in *param is valid. B_FALSE returned when no 1086 * more data is available. 1087 */ 1088 boolean_t 1089 persistent_auth_next(void **v, char *node, iscsi_auth_props_t *auth) 1090 { 1091 ASSERT(mutex_owned(&auth_data_lock)); 1092 1093 return (nvf_data_next(BIDIR_AUTH_PARAMS_ID, v, node, 1094 (void *)auth, sizeof (*auth))); 1095 } 1096 1097 /* 1098 * persistent_auth_clear -- remove bidirectional authentication parameters for 1099 * a specific target 1100 */ 1101 boolean_t 1102 persistent_auth_clear(char *node) 1103 { 1104 boolean_t rval; 1105 1106 mutex_enter(&auth_data_lock); 1107 rval = nvf_data_clear(BIDIR_AUTH_PARAMS_ID, node); 1108 mutex_exit(&auth_data_lock); 1109 1110 return (rval); 1111 } 1112 1113 /* 1114 * persistent_auth_lock -- lock access to bidirectional authentication 1115 * parameters. This ensures the authentication parameters will be unchanged 1116 * while the lock is held. The lock should be grabbed while walking through 1117 * the authentication parameters. 1118 */ 1119 void 1120 persistent_auth_lock(void) 1121 { 1122 mutex_enter(&auth_data_lock); 1123 } 1124 1125 /* 1126 * persistent_auth_unlock -- unlock access to bidirectional authentication 1127 * parameters. 1128 */ 1129 void 1130 persistent_auth_unlock(void) 1131 { 1132 mutex_exit(&auth_data_lock); 1133 } 1134 1135 1136 /* 1137 * +--------------------------------------------------------------------+ 1138 * | Debug Functions | 1139 * +--------------------------------------------------------------------+ 1140 */ 1141 1142 #define BITBUF_LEN 128 1143 1144 /* 1145 * persistent_dump_data -- dump contents of persistent store 1146 */ 1147 void 1148 persistent_dump_data(void) 1149 { 1150 boolean_t rval; 1151 char *name; 1152 iSCSIDiscoveryMethod_t methods; 1153 char *bitbuf; 1154 iscsi_radius_props_t *radius; 1155 entry_t *entry; 1156 void *v; 1157 char *addr_buf; 1158 persistent_param_t *param; 1159 uint32_t param_id; 1160 char *param_name; 1161 iscsi_chap_props_t *chap; 1162 iscsi_auth_props_t *auth; 1163 1164 name = (char *)kmem_alloc(ISCSI_MAX_NAME_LEN, KM_SLEEP); 1165 addr_buf = (char *)kmem_alloc(INET6_ADDRSTRLEN, KM_SLEEP); 1166 bitbuf = (char *)kmem_alloc(BITBUF_LEN, KM_SLEEP); 1167 1168 rval = persistent_initiator_name_get(name, ISCSI_MAX_NAME_LEN); 1169 if (rval == B_TRUE) { 1170 cmn_err(CE_CONT, " Node Name: %s\n", name); 1171 } 1172 1173 rval = persistent_alias_name_get(name, ISCSI_MAX_NAME_LEN); 1174 if (rval == B_TRUE) { 1175 cmn_err(CE_CONT, " Node Alias: %s\n", name); 1176 } 1177 1178 methods = persistent_disc_meth_get(); 1179 if (methods != iSCSIDiscoveryMethodUnknown) { 1180 cmn_err(CE_CONT, " Methods: <%s>\n", 1181 prt_bitmap(methods, 1182 "\003SendTarget\002iSNS\001SLP\000Static", 1183 bitbuf, BITBUF_LEN)); 1184 } 1185 1186 radius = (iscsi_radius_props_t *)kmem_alloc(sizeof (*radius), 1187 KM_SLEEP); 1188 if (persistent_radius_get(radius) == ISCSI_NVFILE_SUCCESS) { 1189 cmn_err(CE_CONT, " <------ RADIUS Configuration ------>\n"); 1190 if (radius->r_insize == sizeof (struct in_addr)) { 1191 (void) inet_ntop(AF_INET, &radius->r_addr.u_in4, 1192 addr_buf, INET6_ADDRSTRLEN); 1193 } else { 1194 (void) inet_ntop(AF_INET6, &radius->r_addr.u_in6, 1195 addr_buf, INET6_ADDRSTRLEN); 1196 } 1197 cmn_err(CE_CONT, " IP: %s, port %d\n", addr_buf, 1198 radius->r_port); 1199 } 1200 kmem_free(radius, sizeof (*radius)); 1201 1202 entry = (entry_t *)kmem_alloc(sizeof (*entry), KM_SLEEP); 1203 v = NULL; 1204 cmn_err(CE_CONT, 1205 " <------ Static Target Discovery Addresses ------>\n"); 1206 persistent_static_addr_lock(); 1207 while (persistent_static_addr_next(&v, name, entry) == B_TRUE) { 1208 cmn_err(CE_CONT, " Target Name: %s TPGT: %d\n", 1209 name, entry->e_tpgt); 1210 if (entry->e_insize == sizeof (struct in_addr)) { 1211 (void) inet_ntop(AF_INET, &entry->e_u.u_in4, 1212 addr_buf, INET6_ADDRSTRLEN); 1213 } else { 1214 (void) inet_ntop(AF_INET6, &entry->e_u.u_in6, 1215 addr_buf, INET6_ADDRSTRLEN); 1216 } 1217 cmn_err(CE_CONT, 1218 " IP: %s, port %d\n", addr_buf, entry->e_port); 1219 } 1220 persistent_static_addr_unlock(); 1221 1222 v = NULL; 1223 cmn_err(CE_CONT, 1224 " <------ SendTargets Discovery Addresses ------>\n"); 1225 persistent_disc_addr_lock(); 1226 while (persistent_disc_addr_next(&v, entry) == B_TRUE) { 1227 if (entry->e_insize == sizeof (struct in_addr)) { 1228 (void) inet_ntop(AF_INET, &entry->e_u.u_in4, 1229 addr_buf, INET6_ADDRSTRLEN); 1230 } else { 1231 (void) inet_ntop(AF_INET6, &entry->e_u.u_in6, 1232 addr_buf, INET6_ADDRSTRLEN); 1233 } 1234 cmn_err(CE_CONT, 1235 " IP: %s, port %d\n", addr_buf, entry->e_port); 1236 } 1237 persistent_disc_addr_unlock(); 1238 1239 v = NULL; 1240 cmn_err(CE_CONT, 1241 " <------ ISNS Server Discovery Addresses ------>\n"); 1242 persistent_isns_addr_lock(); 1243 while (persistent_isns_addr_next(&v, entry) == B_TRUE) { 1244 if (entry->e_insize == sizeof (struct in_addr)) { 1245 (void) inet_ntop(AF_INET, &entry->e_u.u_in4, 1246 addr_buf, INET6_ADDRSTRLEN); 1247 } else { 1248 (void) inet_ntop(AF_INET6, &entry->e_u.u_in6, 1249 addr_buf, INET6_ADDRSTRLEN); 1250 } 1251 cmn_err(CE_CONT, 1252 " IP: %s, port %d\n", addr_buf, entry->e_port); 1253 } 1254 persistent_isns_addr_unlock(); 1255 kmem_free(entry, sizeof (*entry)); 1256 1257 param = (persistent_param_t *)kmem_alloc(sizeof (*param), KM_SLEEP); 1258 v = NULL; 1259 cmn_err(CE_CONT, " <------ Overriden Login Parameters ------>\n"); 1260 persistent_param_lock(); 1261 while (persistent_param_next(&v, name, param) == B_TRUE) { 1262 cmn_err(CE_CONT, " Host: %s\n", name); 1263 cmn_err(CE_CONT, " Bitmap: <%s>\n", 1264 prt_bitmap(param->p_bitmap, 1265 "\015DDIG\014HDIG\013SEGLEN\012OUT_R2T\011" 1266 "DATAPDU\010MAXCONN\007BURST\006R2T\005" 1267 "IMMDATA\004FIRSTBURST\003LEVEL\002T2WAIT" 1268 "\001T2RETAIN\000SEQIN", bitbuf, BITBUF_LEN)); 1269 for (param_id = 0; param_id < ISCSI_NUM_LOGIN_PARAM; 1270 param_id++) { 1271 if (param->p_bitmap & (1 << param_id)) { 1272 param_name = utils_map_param(param_id); 1273 if (param_name == NULL) { 1274 param_name = "Param_Not_Found"; 1275 } 1276 switch (param_id) { 1277 case ISCSI_LOGIN_PARAM_DATA_SEQUENCE_IN_ORDER: 1278 cmn_err(CE_CONT, " %s = %s", 1279 param_name, (param->p_params. 1280 data_sequence_in_order == B_TRUE) ? 1281 "True" : "False"); 1282 break; 1283 case ISCSI_LOGIN_PARAM_INITIAL_R2T: 1284 cmn_err(CE_CONT, " %s = %s", 1285 param_name, (param->p_params. 1286 initial_r2t == B_TRUE) ? 1287 "True" : "False"); 1288 break; 1289 case ISCSI_LOGIN_PARAM_DATA_PDU_IN_ORDER: 1290 cmn_err(CE_CONT, " %s = %s", 1291 param_name, (param->p_params. 1292 data_pdu_in_order == B_TRUE) ? 1293 "True" : "False"); 1294 break; 1295 case ISCSI_LOGIN_PARAM_HEADER_DIGEST: 1296 cmn_err(CE_CONT, " %s = %d", 1297 param_name, param->p_params. 1298 header_digest); 1299 break; 1300 case ISCSI_LOGIN_PARAM_DATA_DIGEST: 1301 cmn_err(CE_CONT, " %s = %d", 1302 param_name, param->p_params. 1303 data_digest); 1304 break; 1305 case ISCSI_LOGIN_PARAM_DEFAULT_TIME_2_RETAIN: 1306 cmn_err(CE_CONT, " %s = %d", 1307 param_name, param->p_params. 1308 default_time_to_retain); 1309 break; 1310 case ISCSI_LOGIN_PARAM_DEFAULT_TIME_2_WAIT: 1311 cmn_err(CE_CONT, " %s = %d", 1312 param_name, param->p_params. 1313 default_time_to_wait); 1314 break; 1315 case ISCSI_LOGIN_PARAM_MAX_RECV_DATA_SEGMENT_LENGTH: 1316 cmn_err(CE_CONT, " %s = %d", 1317 param_name, param->p_params. 1318 max_recv_data_seg_len); 1319 break; 1320 case ISCSI_LOGIN_PARAM_FIRST_BURST_LENGTH: 1321 cmn_err(CE_CONT, " %s = %d", 1322 param_name, param->p_params. 1323 first_burst_length); 1324 break; 1325 case ISCSI_LOGIN_PARAM_MAX_BURST_LENGTH: 1326 cmn_err(CE_CONT, " %s = %d", 1327 param_name, param->p_params. 1328 max_burst_length); 1329 break; 1330 case ISCSI_LOGIN_PARAM_MAX_CONNECTIONS: 1331 cmn_err(CE_CONT, " %s = %d", 1332 param_name, param->p_params. 1333 max_connections); 1334 break; 1335 case ISCSI_LOGIN_PARAM_OUTSTANDING_R2T: 1336 cmn_err(CE_CONT, " %s = %d", 1337 param_name, param->p_params. 1338 max_outstanding_r2t); 1339 break; 1340 case ISCSI_LOGIN_PARAM_ERROR_RECOVERY_LEVEL: 1341 cmn_err(CE_CONT, " %s = %d", 1342 param_name, param->p_params. 1343 error_recovery_level); 1344 break; 1345 default: 1346 break; 1347 } 1348 } 1349 } 1350 } 1351 persistent_param_unlock(); 1352 kmem_free(param, sizeof (*param)); 1353 1354 chap = (iscsi_chap_props_t *)kmem_alloc(sizeof (*chap), KM_SLEEP); 1355 v = NULL; 1356 cmn_err(CE_CONT, " <------ Chap Parameters ------>\n"); 1357 persistent_chap_lock(); 1358 while (persistent_chap_next(&v, name, chap) == B_TRUE) { 1359 cmn_err(CE_CONT, " Host: %s\n", name); 1360 cmn_err(CE_CONT, " User: %s Secret: %s\n", 1361 chap->c_user, chap->c_secret); 1362 } 1363 persistent_chap_unlock(); 1364 kmem_free(chap, sizeof (*chap)); 1365 1366 auth = (iscsi_auth_props_t *)kmem_alloc(sizeof (*auth), KM_SLEEP); 1367 v = NULL; 1368 cmn_err(CE_CONT, " <------ Bidirectional Authentication ------>\n"); 1369 persistent_auth_lock(); 1370 while (persistent_auth_next(&v, name, auth) == B_TRUE) { 1371 cmn_err(CE_CONT, " Host: %s\n", name); 1372 cmn_err(CE_CONT, " Bidir Auth = %s\n", 1373 (auth->a_bi_auth == B_TRUE) ? "True" : "False"); 1374 } 1375 persistent_auth_unlock(); 1376 kmem_free(auth, sizeof (*auth)); 1377 1378 1379 kmem_free(bitbuf, BITBUF_LEN); 1380 kmem_free(addr_buf, INET6_ADDRSTRLEN); 1381 kmem_free(name, ISCSI_MAX_NAME_LEN); 1382 } 1383