1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (C) 2008-2012 Daisuke Aoyama <aoyama@peach.ne.jp>. 5 * Copyright (c) Intel Corporation. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * * Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * * Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in 16 * the documentation and/or other materials provided with the 17 * distribution. 18 * * Neither the name of Intel Corporation nor the names of its 19 * contributors may be used to endorse or promote products derived 20 * from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35 #include "spdk/stdinc.h" 36 37 #include "spdk/env.h" 38 #include "spdk/event.h" 39 #include "spdk/conf.h" 40 #include "spdk/net.h" 41 42 #include "spdk_internal/log.h" 43 44 #include "iscsi/iscsi.h" 45 #include "iscsi/conn.h" 46 #include "iscsi/tgt_node.h" 47 #include "iscsi/portal_grp.h" 48 #include "iscsi/init_grp.h" 49 #include "spdk/scsi.h" 50 #include "iscsi/task.h" 51 52 #define MAX_TMPBUF 1024 53 #define MAX_MASKBUF 128 54 55 static bool 56 spdk_iscsi_tgt_node_allow_ipv6(const char *netmask, const char *addr) 57 { 58 struct in6_addr in6_mask; 59 struct in6_addr in6_addr; 60 char mask[MAX_MASKBUF]; 61 const char *p; 62 size_t n; 63 int bits, bmask; 64 int i; 65 66 if (netmask[0] != '[') 67 return false; 68 p = strchr(netmask, ']'); 69 if (p == NULL) 70 return false; 71 n = p - (netmask + 1); 72 if (n + 1 > sizeof mask) 73 return false; 74 75 memcpy(mask, netmask + 1, n); 76 mask[n] = '\0'; 77 p++; 78 79 if (p[0] == '/') { 80 bits = (int) strtol(p + 1, NULL, 10); 81 if (bits < 0 || bits > 128) 82 return false; 83 } else { 84 bits = 128; 85 } 86 87 #if 0 88 SPDK_DEBUGLOG(SPDK_TRACE_ISCSI, "input %s\n", addr); 89 SPDK_DEBUGLOG(SPDK_TRACE_ISCSI, "mask %s / %d\n", mask, bits); 90 #endif 91 92 /* presentation to network order binary */ 93 if (inet_pton(AF_INET6, mask, &in6_mask) <= 0 94 || inet_pton(AF_INET6, addr, &in6_addr) <= 0) { 95 return false; 96 } 97 98 /* check 128bits */ 99 for (i = 0; i < (bits / 8); i++) { 100 if (in6_mask.s6_addr[i] != in6_addr.s6_addr[i]) 101 return false; 102 } 103 if (bits % 8) { 104 bmask = (0xffU << (8 - (bits % 8))) & 0xffU; 105 if ((in6_mask.s6_addr[i] & bmask) != (in6_addr.s6_addr[i] & bmask)) 106 return false; 107 } 108 109 /* match */ 110 return true; 111 } 112 113 static bool 114 spdk_iscsi_tgt_node_allow_ipv4(const char *netmask, const char *addr) 115 { 116 struct in_addr in4_mask; 117 struct in_addr in4_addr; 118 char mask[MAX_MASKBUF]; 119 const char *p; 120 uint32_t bmask; 121 size_t n; 122 int bits; 123 124 p = strchr(netmask, '/'); 125 if (p == NULL) { 126 p = netmask + strlen(netmask); 127 } 128 n = p - netmask; 129 if (n + 1 > sizeof mask) 130 return false; 131 132 memcpy(mask, netmask, n); 133 mask[n] = '\0'; 134 135 if (p[0] == '/') { 136 bits = (int) strtol(p + 1, NULL, 10); 137 if (bits < 0 || bits > 32) 138 return false; 139 } else { 140 bits = 32; 141 } 142 143 /* presentation to network order binary */ 144 if (inet_pton(AF_INET, mask, &in4_mask) <= 0 145 || inet_pton(AF_INET, addr, &in4_addr) <= 0) { 146 return false; 147 } 148 149 /* check 32bits */ 150 bmask = (0xffffffffULL << (32 - bits)) & 0xffffffffU; 151 if ((ntohl(in4_mask.s_addr) & bmask) != (ntohl(in4_addr.s_addr) & bmask)) 152 return false; 153 154 /* match */ 155 return true; 156 } 157 158 static bool 159 spdk_iscsi_tgt_node_allow_netmask(const char *netmask, const char *addr) 160 { 161 if (netmask == NULL || addr == NULL) 162 return false; 163 if (strcasecmp(netmask, "ALL") == 0) 164 return true; 165 if (netmask[0] == '[') { 166 /* IPv6 */ 167 if (spdk_iscsi_tgt_node_allow_ipv6(netmask, addr)) 168 return true; 169 } else { 170 /* IPv4 */ 171 if (spdk_iscsi_tgt_node_allow_ipv4(netmask, addr)) 172 return true; 173 } 174 return false; 175 } 176 177 bool 178 spdk_iscsi_tgt_node_access(struct spdk_iscsi_conn *conn, 179 struct spdk_iscsi_tgt_node *target, const char *iqn, const char *addr) 180 { 181 struct spdk_iscsi_portal_grp *pg; 182 struct spdk_iscsi_init_grp *igp; 183 struct spdk_iscsi_initiator_name *iname; 184 struct spdk_iscsi_initiator_netmask *imask; 185 int i; 186 187 if (conn == NULL || target == NULL || iqn == NULL || addr == NULL) 188 return false; 189 pg = conn->portal->group; 190 191 SPDK_DEBUGLOG(SPDK_TRACE_ISCSI, "pg=%d, iqn=%s, addr=%s\n", 192 pg->tag, iqn, addr); 193 for (i = 0; i < target->maxmap; i++) { 194 /* skip excluding self portal group tag */ 195 if (pg != target->map[i].pg) 196 continue; 197 igp = target->map[i].ig; 198 TAILQ_FOREACH(iname, &igp->initiator_head, tailq) { 199 /* denied if iqn is matched */ 200 if ((iname->name[0] == '!') 201 && (strcasecmp(&iname->name[1], "ALL") == 0 202 || strcasecmp(&iname->name[1], iqn) == 0)) { 203 goto denied; 204 } 205 /* allowed if iqn is matched */ 206 if (strcasecmp(iname->name, "ALL") == 0 207 || strcasecmp(iname->name, iqn) == 0) { 208 /* iqn is allowed, then check netmask */ 209 TAILQ_FOREACH(imask, &igp->netmask_head, tailq) { 210 SPDK_DEBUGLOG(SPDK_TRACE_ISCSI, 211 "netmask=%s, addr=%s\n", 212 imask->mask, addr); 213 if (spdk_iscsi_tgt_node_allow_netmask(imask->mask, addr)) { 214 return true; 215 } 216 } 217 /* netmask is denied in this initiator group */ 218 } 219 } 220 } 221 222 denied: 223 SPDK_DEBUGLOG(SPDK_TRACE_ISCSI, "access denied from %s (%s) to %s (%s:%s,%d)\n", 224 iqn, addr, target->name, conn->portal->host, 225 conn->portal->port, conn->portal->group->tag); 226 return false; 227 } 228 229 static bool 230 spdk_iscsi_tgt_node_visible(struct spdk_iscsi_tgt_node *target, const char *iqn) 231 { 232 struct spdk_iscsi_init_grp *igp; 233 struct spdk_iscsi_initiator_name *iname; 234 int i; 235 236 if (target == NULL || iqn == NULL) 237 return false; 238 239 for (i = 0; i < target->maxmap; i++) { 240 igp = target->map[i].ig; 241 TAILQ_FOREACH(iname, &igp->initiator_head, tailq) { 242 if ((iname->name[0] == '!') 243 && (strcasecmp(&iname->name[1], "ALL") == 0 244 || strcasecmp(&iname->name[1], iqn) == 0)) { 245 return false; 246 } 247 if (strcasecmp(iname->name, "ALL") == 0 248 || strcasecmp(iname->name, iqn) == 0) { 249 return true; 250 } 251 } 252 } 253 254 return false; 255 } 256 257 int 258 spdk_iscsi_send_tgts(struct spdk_iscsi_conn *conn, const char *iiqn, 259 const char *iaddr, const char *tiqn, uint8_t *data, int alloc_len, 260 int data_len) 261 { 262 char buf[MAX_TMPBUF]; 263 struct spdk_iscsi_portal_grp *pg; 264 struct spdk_iscsi_portal *p; 265 struct spdk_iscsi_tgt_node *target; 266 char *host; 267 int total; 268 int len; 269 int rc; 270 int pg_tag; 271 int i, j, k; 272 273 if (conn == NULL) 274 return 0; 275 276 total = data_len; 277 if (alloc_len < 1) { 278 return 0; 279 } 280 if (total > alloc_len) { 281 total = alloc_len; 282 data[total - 1] = '\0'; 283 return total; 284 } 285 286 if (alloc_len - total < 1) { 287 SPDK_ERRLOG("data space small %d\n", alloc_len); 288 return total; 289 } 290 291 pthread_mutex_lock(&g_spdk_iscsi.mutex); 292 for (i = 0; i < MAX_ISCSI_TARGET_NODE; i++) { 293 target = g_spdk_iscsi.target[i]; 294 if (target == NULL) 295 continue; 296 if (strcasecmp(tiqn, "ALL") != 0 297 && strcasecmp(tiqn, target->name) != 0) { 298 continue; 299 } 300 rc = spdk_iscsi_tgt_node_visible(target, iiqn); 301 if (rc == 0) { 302 continue; 303 } 304 305 /* DO SENDTARGETS */ 306 len = snprintf((char *) data + total, alloc_len - total, 307 "TargetName=%s", target->name); 308 total += len + 1; 309 310 for (j = 0; j < target->maxmap; j++) { 311 pg_tag = target->map[j].pg->tag; 312 /* skip same pg_tag */ 313 for (k = 0; k < j; k++) { 314 if (target->map[k].pg->tag == pg_tag) { 315 goto skip_pg_tag; 316 } 317 } 318 /* write to data */ 319 TAILQ_FOREACH(pg, &g_spdk_iscsi.pg_head, tailq) { 320 if (pg->tag != pg_tag) 321 continue; 322 TAILQ_FOREACH(p, &pg->head, per_pg_tailq) { 323 if (alloc_len - total < 1) { 324 pthread_mutex_unlock(&g_spdk_iscsi.mutex); 325 SPDK_ERRLOG("data space small %d\n", alloc_len); 326 return total; 327 } 328 host = p->host; 329 /* wildcard? */ 330 if (strcasecmp(host, "[::]") == 0 331 || strcasecmp(host, "0.0.0.0") == 0) { 332 if (spdk_sock_is_ipv6(conn->sock)) { 333 snprintf(buf, sizeof buf, "[%s]", 334 conn->target_addr); 335 host = buf; 336 } else if (spdk_sock_is_ipv4(conn->sock)) { 337 snprintf(buf, sizeof buf, "%s", 338 conn->target_addr); 339 host = buf; 340 } else { 341 /* skip portal for the family */ 342 continue; 343 } 344 } 345 SPDK_DEBUGLOG(SPDK_TRACE_ISCSI, 346 "TargetAddress=%s:%s,%d\n", 347 host, p->port, pg->tag); 348 len = snprintf((char *) data + total, 349 alloc_len - total, 350 "TargetAddress=%s:%s,%d", 351 host, p->port, pg->tag); 352 total += len + 1; 353 } 354 } 355 skip_pg_tag: 356 ; 357 } 358 } 359 pthread_mutex_unlock(&g_spdk_iscsi.mutex); 360 361 return total; 362 } 363 364 struct spdk_iscsi_tgt_node * 365 spdk_iscsi_find_tgt_node(const char *target_name) 366 { 367 struct spdk_iscsi_tgt_node *target; 368 int i; 369 370 if (target_name == NULL) 371 return NULL; 372 for (i = 0; i < MAX_ISCSI_TARGET_NODE; i++) { 373 target = g_spdk_iscsi.target[i]; 374 if (target == NULL) 375 continue; 376 if (strcasecmp(target_name, target->name) == 0) { 377 return target; 378 } 379 } 380 SPDK_DEBUGLOG(SPDK_TRACE_ISCSI, "can't find target %s\n", target_name); 381 return NULL; 382 } 383 384 static int 385 spdk_check_iscsi_name(const char *name) 386 { 387 const unsigned char *up = (const unsigned char *) name; 388 size_t n; 389 390 /* valid iSCSI name? */ 391 for (n = 0; up[n] != 0; n++) { 392 if (up[n] > 0x00U && up[n] <= 0x2cU) 393 return -1; 394 if (up[n] == 0x2fU) 395 return -1; 396 if (up[n] >= 0x3bU && up[n] <= 0x40U) 397 return -1; 398 if (up[n] >= 0x5bU && up[n] <= 0x60U) 399 return -1; 400 if (up[n] >= 0x7bU && up[n] <= 0x7fU) 401 return -1; 402 if (isspace(up[n])) 403 return -1; 404 } 405 /* valid format? */ 406 if (strncasecmp(name, "iqn.", 4) == 0) { 407 /* iqn.YYYY-MM.reversed.domain.name */ 408 if (!isdigit(up[4]) || !isdigit(up[5]) || !isdigit(up[6]) 409 || !isdigit(up[7]) || up[8] != '-' || !isdigit(up[9]) 410 || !isdigit(up[10]) || up[11] != '.') { 411 SPDK_ERRLOG("invalid iqn format. " 412 "expect \"iqn.YYYY-MM.reversed.domain.name\"\n"); 413 return -1; 414 } 415 } else if (strncasecmp(name, "eui.", 4) == 0) { 416 /* EUI-64 -> 16bytes */ 417 /* XXX */ 418 } else if (strncasecmp(name, "naa.", 4) == 0) { 419 /* 64bit -> 16bytes, 128bit -> 32bytes */ 420 /* XXX */ 421 } 422 /* OK */ 423 return 0; 424 } 425 426 static void 427 spdk_iscsi_tgt_node_destruct(struct spdk_iscsi_tgt_node *target) 428 { 429 int i; 430 431 if (target == NULL) { 432 return; 433 } 434 435 free(target->name); 436 free(target->alias); 437 spdk_scsi_dev_destruct(target->dev); 438 for (i = 0; i < target->maxmap; i++) { 439 target->map[i].pg->ref--; 440 target->map[i].ig->ref--; 441 } 442 443 pthread_mutex_destroy(&target->mutex); 444 free(target); 445 } 446 447 static int spdk_get_next_available_tgt_number(void) 448 { 449 int i; 450 451 for (i = 0; i < MAX_ISCSI_TARGET_NODE; i++) { 452 if (g_spdk_iscsi.target[i] == NULL) 453 break; 454 } 455 return i; //Returns MAX_TARGET if none available. 456 } 457 458 static struct spdk_iscsi_tgt_node_map * 459 spdk_iscsi_tgt_node_add_map(struct spdk_iscsi_tgt_node *target, 460 int pg_tag, int ig_tag) 461 { 462 struct spdk_iscsi_tgt_node_map *map; 463 struct spdk_iscsi_portal_grp *pg; 464 struct spdk_iscsi_init_grp *ig; 465 466 if (target->maxmap >= MAX_TARGET_MAP) { 467 SPDK_ERRLOG("%s: no space for new map\n", target->name); 468 return NULL; 469 } 470 471 pthread_mutex_lock(&g_spdk_iscsi.mutex); 472 pg = spdk_iscsi_portal_grp_find_by_tag(pg_tag); 473 if (pg == NULL) { 474 pthread_mutex_unlock(&g_spdk_iscsi.mutex); 475 SPDK_ERRLOG("%s: PortalGroup%d not found\n", target->name, pg_tag); 476 return NULL; 477 } 478 if (pg->state != GROUP_READY) { 479 pthread_mutex_unlock(&g_spdk_iscsi.mutex); 480 SPDK_ERRLOG("%s: PortalGroup%d not active\n", target->name, pg_tag); 481 return NULL; 482 } 483 ig = spdk_iscsi_init_grp_find_by_tag(ig_tag); 484 if (ig == NULL) { 485 pthread_mutex_unlock(&g_spdk_iscsi.mutex); 486 SPDK_ERRLOG("%s: InitiatorGroup%d not found\n", target->name, ig_tag); 487 return NULL; 488 } 489 if (ig->state != GROUP_READY) { 490 pthread_mutex_unlock(&g_spdk_iscsi.mutex); 491 SPDK_ERRLOG("%s: InitiatorGroup%d not active\n", target->name, ig_tag); 492 return NULL; 493 } 494 pg->ref++; 495 ig->ref++; 496 pthread_mutex_unlock(&g_spdk_iscsi.mutex); 497 map = &target->map[target->maxmap]; 498 map->pg = pg; 499 map->ig = ig; 500 target->maxmap++; 501 502 return map; 503 } 504 505 _spdk_iscsi_tgt_node * 506 spdk_iscsi_tgt_node_construct(int target_index, 507 const char *name, const char *alias, 508 int *pg_tag_list, int *ig_tag_list, uint16_t num_maps, 509 char *lun_name_list[], int *lun_id_list, int num_luns, 510 int queue_depth, 511 int auth_chap_disabled, int auth_chap_required, int auth_chap_mutual, int auth_group, 512 int header_digest, int data_digest) 513 { 514 char fullname[MAX_TMPBUF], port_name[MAX_TMPBUF]; 515 struct spdk_iscsi_tgt_node *target; 516 struct spdk_iscsi_tgt_node_map *map; 517 struct spdk_iscsi_portal_grp *unique_portal_groups[SPDK_SCSI_DEV_MAX_PORTS]; 518 struct spdk_iscsi_portal_grp *pg; 519 int num_unique_portal_groups; 520 int i, j, rc; 521 522 if (auth_chap_disabled && auth_chap_required) { 523 SPDK_ERRLOG("auth_chap_disabled and auth_chap_required are mutually exclusive\n"); 524 return NULL; 525 } 526 527 if ((num_maps > MAX_TARGET_MAP) || (num_maps == 0)) { 528 SPDK_ERRLOG("num_maps = %d out of range\n", num_maps); 529 return NULL; 530 } 531 532 if (target_index == -1) 533 target_index = spdk_get_next_available_tgt_number(); 534 535 if (target_index >= MAX_ISCSI_TARGET_NODE) { 536 SPDK_ERRLOG("%d over maximum unit number\n", target_index); 537 return NULL; 538 } 539 540 if (g_spdk_iscsi.target[target_index] != NULL) { 541 SPDK_ERRLOG("tgt_node%d: duplicate unit\n", target_index); 542 return NULL; 543 } 544 545 if (name == NULL) { 546 SPDK_ERRLOG("TargetName not found\n"); 547 return NULL; 548 } 549 550 if (strncasecmp(name, "iqn.", 4) != 0 551 && strncasecmp(name, "eui.", 4) != 0 552 && strncasecmp(name, "naa.", 4) != 0) { 553 snprintf(fullname, sizeof(fullname), "%s:%s", g_spdk_iscsi.nodebase, name); 554 } else 555 snprintf(fullname, sizeof(fullname), "%s", name); 556 557 if (spdk_check_iscsi_name(fullname) != 0) { 558 SPDK_ERRLOG("TargetName %s contains an invalid character or format.\n", 559 name); 560 return NULL; 561 } 562 563 target = malloc(sizeof(*target)); 564 if (!target) { 565 SPDK_ERRLOG("could not allocate target\n"); 566 return NULL; 567 } 568 569 memset(target, 0, sizeof(*target)); 570 571 rc = pthread_mutex_init(&target->mutex, NULL); 572 if (rc != 0) { 573 SPDK_ERRLOG("tgt_node%d: mutex_init() failed\n", target->num); 574 spdk_iscsi_tgt_node_destruct(target); 575 return NULL; 576 } 577 578 target->num = target_index; 579 580 target->name = strdup(fullname); 581 if (!target->name) { 582 SPDK_ERRLOG("Could not allocate TargetName\n"); 583 spdk_iscsi_tgt_node_destruct(target); 584 return NULL; 585 } 586 587 if (alias == NULL) { 588 target->alias = NULL; 589 } else { 590 target->alias = strdup(alias); 591 if (!target->alias) { 592 SPDK_ERRLOG("Could not allocate TargetAlias\n"); 593 spdk_iscsi_tgt_node_destruct(target); 594 return NULL; 595 } 596 } 597 598 target->dev = spdk_scsi_dev_construct(name, lun_name_list, lun_id_list, num_luns, 599 SPDK_SPC_PROTOCOL_IDENTIFIER_ISCSI, NULL, NULL); 600 601 if (!target->dev) { 602 SPDK_ERRLOG("Could not construct SCSI device\n"); 603 spdk_iscsi_tgt_node_destruct(target); 604 return NULL; 605 } 606 607 num_unique_portal_groups = 0; 608 for (i = 0; i < num_maps; i++) { 609 map = spdk_iscsi_tgt_node_add_map(target, pg_tag_list[i], 610 ig_tag_list[i]); 611 612 if (map == NULL) { 613 SPDK_ERRLOG("could not add map to target\n"); 614 spdk_iscsi_tgt_node_destruct(target); 615 return NULL; 616 } 617 618 for (j = 0; j < num_unique_portal_groups; j++) { 619 if (unique_portal_groups[j] == map->pg) { 620 break; 621 } 622 } 623 624 if (j == SPDK_SCSI_DEV_MAX_PORTS) { 625 SPDK_ERRLOG("too many unique portal groups\n"); 626 spdk_iscsi_tgt_node_destruct(target); 627 return NULL; 628 } 629 630 if (j == num_unique_portal_groups) { 631 pg = map->pg; 632 snprintf(port_name, sizeof(port_name), "%s,t,0x%4.4x", 633 name, pg->tag); 634 spdk_scsi_dev_add_port(target->dev, pg->tag, port_name); 635 unique_portal_groups[j] = pg; 636 num_unique_portal_groups++; 637 } 638 } 639 640 target->auth_chap_disabled = auth_chap_disabled; 641 target->auth_chap_required = auth_chap_required; 642 target->auth_chap_mutual = auth_chap_mutual; 643 target->auth_group = auth_group; 644 target->header_digest = header_digest; 645 target->data_digest = data_digest; 646 647 if (queue_depth > SPDK_ISCSI_MAX_QUEUE_DEPTH) { 648 SPDK_DEBUGLOG(SPDK_TRACE_ISCSI, "QueueDepth %d > Max %d. Using %d instead.\n", 649 queue_depth, SPDK_ISCSI_MAX_QUEUE_DEPTH, 650 SPDK_ISCSI_MAX_QUEUE_DEPTH); 651 queue_depth = SPDK_ISCSI_MAX_QUEUE_DEPTH; 652 } 653 target->queue_depth = queue_depth; 654 655 pthread_mutex_lock(&g_spdk_iscsi.mutex); 656 g_spdk_iscsi.ntargets++; 657 g_spdk_iscsi.target[target->num] = target; 658 pthread_mutex_unlock(&g_spdk_iscsi.mutex); 659 660 return target; 661 } 662 663 static int 664 spdk_cf_add_iscsi_tgt_node(struct spdk_conf_section *sp) 665 { 666 char buf[MAX_TMPBUF]; 667 struct spdk_iscsi_tgt_node *target; 668 int pg_tag_list[MAX_TARGET_MAP], ig_tag_list[MAX_TARGET_MAP]; 669 int num_target_maps; 670 const char *alias, *pg_tag, *ig_tag; 671 const char *ag_tag; 672 const char *val, *name; 673 int target_num, auth_group, pg_tag_i, ig_tag_i; 674 int header_digest, data_digest; 675 int auth_chap_disabled, auth_chap_required, auth_chap_mutual; 676 int i; 677 int lun_id_list[SPDK_SCSI_DEV_MAX_LUN]; 678 char lun_name_array[SPDK_SCSI_DEV_MAX_LUN][SPDK_SCSI_LUN_MAX_NAME_LENGTH] = {}; 679 char *lun_name_list[SPDK_SCSI_DEV_MAX_LUN]; 680 int num_luns, queue_depth; 681 682 target_num = spdk_conf_section_get_num(sp); 683 684 SPDK_DEBUGLOG(SPDK_TRACE_ISCSI, "add unit %d\n", target_num); 685 686 data_digest = 0; 687 header_digest = 0; 688 689 name = spdk_conf_section_get_val(sp, "TargetName"); 690 691 if (name == NULL) { 692 SPDK_ERRLOG("tgt_node%d: TargetName not found\n", target_num); 693 return -1; 694 } 695 696 alias = spdk_conf_section_get_val(sp, "TargetAlias"); 697 698 /* Setup initiator and portal group mapping */ 699 val = spdk_conf_section_get_val(sp, "Mapping"); 700 if (val == NULL) { 701 /* no map */ 702 SPDK_ERRLOG("tgt_node%d: no Mapping\n", target_num); 703 return -1; 704 } 705 706 for (i = 0; i < MAX_TARGET_MAP; i++) { 707 val = spdk_conf_section_get_nmval(sp, "Mapping", i, 0); 708 if (val == NULL) 709 break; 710 pg_tag = spdk_conf_section_get_nmval(sp, "Mapping", i, 0); 711 ig_tag = spdk_conf_section_get_nmval(sp, "Mapping", i, 1); 712 if (pg_tag == NULL || ig_tag == NULL) { 713 SPDK_ERRLOG("tgt_node%d: mapping error\n", target_num); 714 return -1; 715 } 716 if (strncasecmp(pg_tag, "PortalGroup", 717 strlen("PortalGroup")) != 0 718 || sscanf(pg_tag, "%*[^0-9]%d", &pg_tag_i) != 1) { 719 SPDK_ERRLOG("tgt_node%d: mapping portal error\n", target_num); 720 return -1; 721 } 722 if (strncasecmp(ig_tag, "InitiatorGroup", 723 strlen("InitiatorGroup")) != 0 724 || sscanf(ig_tag, "%*[^0-9]%d", &ig_tag_i) != 1) { 725 SPDK_ERRLOG("tgt_node%d: mapping initiator error\n", target_num); 726 return -1; 727 } 728 if (pg_tag_i < 1 || ig_tag_i < 1) { 729 SPDK_ERRLOG("tgt_node%d: invalid group tag\n", target_num); 730 return -1; 731 } 732 pg_tag_list[i] = pg_tag_i; 733 ig_tag_list[i] = ig_tag_i; 734 } 735 736 num_target_maps = i; 737 738 /* Setup AuthMethod */ 739 val = spdk_conf_section_get_val(sp, "AuthMethod"); 740 auth_chap_disabled = 0; 741 auth_chap_required = 0; 742 auth_chap_mutual = 0; 743 if (val != NULL) { 744 for (i = 0; ; i++) { 745 val = spdk_conf_section_get_nmval(sp, "AuthMethod", 0, i); 746 if (val == NULL) 747 break; 748 if (strcasecmp(val, "CHAP") == 0) { 749 auth_chap_required = 1; 750 } else if (strcasecmp(val, "Mutual") == 0) { 751 auth_chap_mutual = 1; 752 } else if (strcasecmp(val, "Auto") == 0) { 753 auth_chap_disabled = 0; 754 auth_chap_required = 0; 755 auth_chap_mutual = 0; 756 } else if (strcasecmp(val, "None") == 0) { 757 auth_chap_disabled = 1; 758 auth_chap_required = 0; 759 auth_chap_mutual = 0; 760 } else { 761 SPDK_ERRLOG("tgt_node%d: unknown auth\n", target_num); 762 return -1; 763 } 764 } 765 if (auth_chap_mutual && !auth_chap_required) { 766 SPDK_ERRLOG("tgt_node%d: Mutual but not CHAP\n", target_num); 767 return -1; 768 } 769 } 770 if (auth_chap_disabled == 1) { 771 SPDK_DEBUGLOG(SPDK_TRACE_ISCSI, "AuthMethod None\n"); 772 } else if (auth_chap_required == 0) { 773 SPDK_DEBUGLOG(SPDK_TRACE_ISCSI, "AuthMethod Auto\n"); 774 } else { 775 SPDK_DEBUGLOG(SPDK_TRACE_ISCSI, "AuthMethod CHAP %s\n", 776 auth_chap_mutual ? "Mutual" : ""); 777 } 778 779 val = spdk_conf_section_get_val(sp, "AuthGroup"); 780 if (val == NULL) { 781 auth_group = 0; 782 } else { 783 ag_tag = val; 784 if (strcasecmp(ag_tag, "None") == 0) { 785 auth_group = 0; 786 } else { 787 if (strncasecmp(ag_tag, "AuthGroup", 788 strlen("AuthGroup")) != 0 789 || sscanf(ag_tag, "%*[^0-9]%d", &auth_group) != 1) { 790 SPDK_ERRLOG("tgt_node%d: auth group error\n", target_num); 791 return -1; 792 } 793 if (auth_group == 0) { 794 SPDK_ERRLOG("tgt_node%d: invalid auth group 0\n", target_num); 795 return -1; 796 } 797 } 798 } 799 if (auth_group == 0) { 800 SPDK_DEBUGLOG(SPDK_TRACE_ISCSI, "AuthGroup None\n"); 801 } else { 802 SPDK_DEBUGLOG(SPDK_TRACE_ISCSI, "AuthGroup AuthGroup%d\n", 803 auth_group); 804 } 805 806 val = spdk_conf_section_get_val(sp, "UseDigest"); 807 if (val != NULL) { 808 for (i = 0; ; i++) { 809 val = spdk_conf_section_get_nmval(sp, "UseDigest", 0, i); 810 if (val == NULL) 811 break; 812 if (strcasecmp(val, "Header") == 0) { 813 header_digest = 1; 814 } else if (strcasecmp(val, "Data") == 0) { 815 data_digest = 1; 816 } else if (strcasecmp(val, "Auto") == 0) { 817 header_digest = 0; 818 data_digest = 0; 819 } else { 820 SPDK_ERRLOG("tgt_node%d: unknown digest\n", target_num); 821 return -1; 822 } 823 } 824 } 825 if (header_digest == 0 && data_digest == 0) { 826 SPDK_DEBUGLOG(SPDK_TRACE_ISCSI, "UseDigest Auto\n"); 827 } else { 828 SPDK_DEBUGLOG(SPDK_TRACE_ISCSI, "UseDigest %s %s\n", 829 header_digest ? "Header" : "", 830 data_digest ? "Data" : ""); 831 } 832 833 val = spdk_conf_section_get_val(sp, "QueueDepth"); 834 if (val == NULL) { 835 queue_depth = SPDK_ISCSI_MAX_QUEUE_DEPTH; 836 } else { 837 queue_depth = (int) strtol(val, NULL, 10); 838 } 839 840 num_luns = 0; 841 842 for (i = 0; i < SPDK_SCSI_DEV_MAX_LUN; i++) { 843 snprintf(buf, sizeof(buf), "LUN%d", i); 844 val = spdk_conf_section_get_val(sp, buf); 845 if (val == NULL) { 846 continue; 847 } 848 849 snprintf(lun_name_array[num_luns], SPDK_SCSI_LUN_MAX_NAME_LENGTH, "%s", val); 850 lun_name_list[num_luns] = lun_name_array[num_luns]; 851 lun_id_list[num_luns] = i; 852 num_luns++; 853 } 854 855 if (num_luns == 0) { 856 SPDK_ERRLOG("tgt_node%d: No LUN specified for target %s.\n", target_num, name); 857 return -1; 858 } 859 860 target = spdk_iscsi_tgt_node_construct(target_num, name, alias, 861 pg_tag_list, ig_tag_list, num_target_maps, 862 lun_name_list, lun_id_list, num_luns, queue_depth, 863 auth_chap_disabled, auth_chap_required, 864 auth_chap_mutual, auth_group, 865 header_digest, data_digest); 866 867 if (target == NULL) { 868 SPDK_ERRLOG("tgt_node%d: add_iscsi_target_node error\n", target_num); 869 return -1; 870 } 871 872 spdk_scsi_dev_print(target->dev); 873 return 0; 874 } 875 876 int spdk_iscsi_init_tgt_nodes(void) 877 { 878 struct spdk_conf_section *sp; 879 int rc; 880 881 SPDK_DEBUGLOG(SPDK_TRACE_ISCSI, "spdk_iscsi_init_tgt_nodes\n"); 882 883 sp = spdk_conf_first_section(NULL); 884 while (sp != NULL) { 885 if (spdk_conf_section_match_prefix(sp, "TargetNode")) { 886 int tag = spdk_conf_section_get_num(sp); 887 888 if (tag > SPDK_TN_TAG_MAX) { 889 SPDK_ERRLOG("tag %d is invalid\n", tag); 890 return -1; 891 } 892 rc = spdk_cf_add_iscsi_tgt_node(sp); 893 if (rc < 0) { 894 SPDK_ERRLOG("spdk_cf_add_iscsi_tgt_node() failed\n"); 895 return -1; 896 } 897 } 898 sp = spdk_conf_next_section(sp); 899 } 900 return 0; 901 } 902 903 int 904 spdk_iscsi_shutdown_tgt_nodes(void) 905 { 906 struct spdk_iscsi_tgt_node *target; 907 int i; 908 909 pthread_mutex_lock(&g_spdk_iscsi.mutex); 910 for (i = 0; i < MAX_ISCSI_TARGET_NODE; i++) { 911 target = g_spdk_iscsi.target[i]; 912 if (target == NULL) 913 continue; 914 spdk_iscsi_tgt_node_destruct(target); 915 g_spdk_iscsi.ntargets--; 916 g_spdk_iscsi.target[i] = NULL; 917 } 918 pthread_mutex_unlock(&g_spdk_iscsi.mutex); 919 920 return 0; 921 } 922 923 int 924 spdk_iscsi_shutdown_tgt_node_by_name(const char *target_name) 925 { 926 struct spdk_iscsi_tgt_node *target; 927 int i = 0; 928 int ret = -1; 929 930 pthread_mutex_lock(&g_spdk_iscsi.mutex); 931 for (i = 0; i < MAX_ISCSI_TARGET_NODE; i++) { 932 target = g_spdk_iscsi.target[i]; 933 if (target == NULL) 934 continue; 935 936 if (strncmp(target_name, target->name, MAX_TMPBUF) == 0) { 937 spdk_iscsi_tgt_node_destruct(target); 938 g_spdk_iscsi.ntargets--; 939 g_spdk_iscsi.target[i] = NULL; 940 ret = 0; 941 break; 942 } 943 } 944 pthread_mutex_unlock(&g_spdk_iscsi.mutex); 945 946 return ret; 947 } 948 949 int 950 spdk_iscsi_tgt_node_cleanup_luns(struct spdk_iscsi_conn *conn, 951 struct spdk_iscsi_tgt_node *target) 952 { 953 int i; 954 struct spdk_iscsi_task *task; 955 956 for (i = 0; i < SPDK_SCSI_DEV_MAX_LUN; i++) { 957 struct spdk_scsi_lun *lun = spdk_scsi_dev_get_lun(target->dev, i); 958 959 if (!lun) 960 continue; 961 962 /* we create a fake management task per LUN to cleanup */ 963 task = spdk_iscsi_task_get(conn, NULL, spdk_iscsi_task_mgmt_cpl); 964 if (!task) { 965 SPDK_ERRLOG("Unable to acquire task\n"); 966 return -1; 967 } 968 969 task->scsi.target_port = conn->target_port; 970 task->scsi.initiator_port = conn->initiator_port; 971 task->scsi.lun = lun; 972 973 spdk_scsi_dev_queue_mgmt_task(target->dev, &task->scsi, SPDK_SCSI_TASK_FUNC_LUN_RESET); 974 } 975 976 return 0; 977 } 978 979 void spdk_iscsi_tgt_node_delete_map(struct spdk_iscsi_portal_grp *portal_group, 980 struct spdk_iscsi_init_grp *initiator_group) 981 { 982 struct spdk_iscsi_tgt_node *target; 983 int i = 0; 984 int j = 0; 985 int k = 0; 986 int flag = 0; 987 988 for (i = 0; i < MAX_ISCSI_TARGET_NODE; i++) { 989 target = g_spdk_iscsi.target[i]; 990 if (target == NULL) 991 continue; 992 loop: 993 flag = 0; 994 for (j = 0; j < target->maxmap; j++) { 995 if (portal_group) { 996 if (target->map[j].pg->tag == portal_group->tag) { 997 flag = 1; 998 } 999 } 1000 if (initiator_group) { 1001 if (target->map[j].ig->tag == initiator_group->tag) { 1002 flag = 1; 1003 } 1004 } 1005 1006 if (flag == 1) { 1007 target->map[j].pg->ref--; 1008 target->map[j].ig->ref--; 1009 for (k = j; k < target->maxmap - 1; k++) { 1010 target->map[k].pg = target->map[k + 1].pg; 1011 target->map[k].ig = target->map[k + 1].ig; 1012 } 1013 target->map[target->maxmap - 1].pg = NULL; 1014 target->map[target->maxmap - 1].ig = NULL; 1015 target->maxmap -= 1; 1016 goto loop; 1017 } 1018 } 1019 } 1020 } 1021