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 int i, j, k; 184 185 if (conn == NULL || target == NULL || iqn == NULL || addr == NULL) 186 return false; 187 pg = conn->portal->group; 188 189 SPDK_DEBUGLOG(SPDK_TRACE_ISCSI, "pg=%d, iqn=%s, addr=%s\n", 190 pg->tag, iqn, addr); 191 for (i = 0; i < target->maxmap; i++) { 192 /* skip excluding self portal group tag */ 193 if (pg != target->map[i].pg) 194 continue; 195 /* iqn is initiator group? */ 196 igp = target->map[i].ig; 197 for (j = 0; j < igp->ninitiators; j++) { 198 /* deny initiators */ 199 if (igp->initiators[j][0] == '!' 200 && (strcasecmp(&igp->initiators[j][1], "ALL") == 0 201 || strcasecmp(&igp->initiators[j][1], iqn) == 0)) { 202 /* NG */ 203 SPDK_DEBUGLOG(SPDK_TRACE_ISCSI, 204 "access denied from %s (%s) to %s (%s:%s,%d)\n", 205 iqn, addr, target->name, conn->portal->host, 206 conn->portal->port, conn->portal->group->tag); 207 return false; 208 } 209 /* allow initiators */ 210 if (strcasecmp(igp->initiators[j], "ALL") == 0 211 || strcasecmp(igp->initiators[j], iqn) == 0) { 212 /* OK iqn, check netmask */ 213 for (k = 0; k < igp->nnetmasks; k++) { 214 SPDK_DEBUGLOG(SPDK_TRACE_ISCSI, 215 "netmask=%s, addr=%s\n", 216 igp->netmasks[k], addr); 217 if (spdk_iscsi_tgt_node_allow_netmask(igp->netmasks[k], addr)) { 218 /* OK netmask */ 219 return true; 220 } 221 } 222 /* NG netmask in this group */ 223 } 224 } 225 } 226 227 /* NG */ 228 SPDK_DEBUGLOG(SPDK_TRACE_ISCSI, "access denied from %s (%s) to %s (%s:%s,%d)\n", 229 iqn, addr, target->name, conn->portal->host, 230 conn->portal->port, conn->portal->group->tag); 231 return false; 232 } 233 234 static bool 235 spdk_iscsi_tgt_node_visible(struct spdk_iscsi_tgt_node *target, const char *iqn) 236 { 237 struct spdk_iscsi_init_grp *igp; 238 int i, j; 239 240 if (target == NULL || iqn == NULL) 241 return false; 242 243 for (i = 0; i < target->maxmap; i++) { 244 /* iqn is initiator group? */ 245 igp = target->map[i].ig; 246 for (j = 0; j < igp->ninitiators; j++) { 247 if (igp->initiators[j][0] == '!' 248 && (strcasecmp(&igp->initiators[j][1], "ALL") == 0 249 || strcasecmp(&igp->initiators[j][1], iqn) == 0)) { 250 /* NG */ 251 return false; 252 } 253 if (strcasecmp(igp->initiators[j], "ALL") == 0 254 || strcasecmp(igp->initiators[j], iqn) == 0) { 255 /* OK iqn, no check addr */ 256 return true; 257 } 258 } 259 } 260 261 /* NG */ 262 return false; 263 } 264 265 int 266 spdk_iscsi_send_tgts(struct spdk_iscsi_conn *conn, const char *iiqn, 267 const char *iaddr, const char *tiqn, uint8_t *data, int alloc_len, 268 int data_len) 269 { 270 char buf[MAX_TMPBUF]; 271 struct spdk_iscsi_portal_grp *pg; 272 struct spdk_iscsi_portal *p; 273 struct spdk_iscsi_tgt_node *target; 274 char *host; 275 int total; 276 int len; 277 int rc; 278 int pg_tag; 279 int i, j, k; 280 281 if (conn == NULL) 282 return 0; 283 284 total = data_len; 285 if (alloc_len < 1) { 286 return 0; 287 } 288 if (total > alloc_len) { 289 total = alloc_len; 290 data[total - 1] = '\0'; 291 return total; 292 } 293 294 if (alloc_len - total < 1) { 295 SPDK_ERRLOG("data space small %d\n", alloc_len); 296 return total; 297 } 298 299 pthread_mutex_lock(&g_spdk_iscsi.mutex); 300 for (i = 0; i < MAX_ISCSI_TARGET_NODE; i++) { 301 target = g_spdk_iscsi.target[i]; 302 if (target == NULL) 303 continue; 304 if (strcasecmp(tiqn, "ALL") != 0 305 && strcasecmp(tiqn, target->name) != 0) { 306 continue; 307 } 308 rc = spdk_iscsi_tgt_node_visible(target, iiqn); 309 if (rc == 0) { 310 continue; 311 } 312 313 /* DO SENDTARGETS */ 314 len = snprintf((char *) data + total, alloc_len - total, 315 "TargetName=%s", target->name); 316 total += len + 1; 317 318 for (j = 0; j < target->maxmap; j++) { 319 pg_tag = target->map[j].pg->tag; 320 /* skip same pg_tag */ 321 for (k = 0; k < j; k++) { 322 if (target->map[k].pg->tag == pg_tag) { 323 goto skip_pg_tag; 324 } 325 } 326 /* write to data */ 327 TAILQ_FOREACH(pg, &g_spdk_iscsi.pg_head, tailq) { 328 if (pg->tag != pg_tag) 329 continue; 330 TAILQ_FOREACH(p, &pg->head, per_pg_tailq) { 331 if (alloc_len - total < 1) { 332 pthread_mutex_unlock(&g_spdk_iscsi.mutex); 333 SPDK_ERRLOG("data space small %d\n", alloc_len); 334 return total; 335 } 336 host = p->host; 337 /* wildcard? */ 338 if (strcasecmp(host, "[::]") == 0 339 || strcasecmp(host, "0.0.0.0") == 0) { 340 if (spdk_sock_is_ipv6(conn->sock)) { 341 snprintf(buf, sizeof buf, "[%s]", 342 conn->target_addr); 343 host = buf; 344 } else if (spdk_sock_is_ipv4(conn->sock)) { 345 snprintf(buf, sizeof buf, "%s", 346 conn->target_addr); 347 host = buf; 348 } else { 349 /* skip portal for the family */ 350 continue; 351 } 352 } 353 SPDK_DEBUGLOG(SPDK_TRACE_ISCSI, 354 "TargetAddress=%s:%s,%d\n", 355 host, p->port, pg->tag); 356 len = snprintf((char *) data + total, 357 alloc_len - total, 358 "TargetAddress=%s:%s,%d", 359 host, p->port, pg->tag); 360 total += len + 1; 361 } 362 } 363 skip_pg_tag: 364 ; 365 } 366 } 367 pthread_mutex_unlock(&g_spdk_iscsi.mutex); 368 369 return total; 370 } 371 372 struct spdk_iscsi_tgt_node * 373 spdk_iscsi_find_tgt_node(const char *target_name) 374 { 375 struct spdk_iscsi_tgt_node *target; 376 int i; 377 378 if (target_name == NULL) 379 return NULL; 380 for (i = 0; i < MAX_ISCSI_TARGET_NODE; i++) { 381 target = g_spdk_iscsi.target[i]; 382 if (target == NULL) 383 continue; 384 if (strcasecmp(target_name, target->name) == 0) { 385 return target; 386 } 387 } 388 SPDK_DEBUGLOG(SPDK_TRACE_ISCSI, "can't find target %s\n", target_name); 389 return NULL; 390 } 391 392 static int 393 spdk_check_iscsi_name(const char *name) 394 { 395 const unsigned char *up = (const unsigned char *) name; 396 size_t n; 397 398 /* valid iSCSI name? */ 399 for (n = 0; up[n] != 0; n++) { 400 if (up[n] > 0x00U && up[n] <= 0x2cU) 401 return -1; 402 if (up[n] == 0x2fU) 403 return -1; 404 if (up[n] >= 0x3bU && up[n] <= 0x40U) 405 return -1; 406 if (up[n] >= 0x5bU && up[n] <= 0x60U) 407 return -1; 408 if (up[n] >= 0x7bU && up[n] <= 0x7fU) 409 return -1; 410 if (isspace(up[n])) 411 return -1; 412 } 413 /* valid format? */ 414 if (strncasecmp(name, "iqn.", 4) == 0) { 415 /* iqn.YYYY-MM.reversed.domain.name */ 416 if (!isdigit(up[4]) || !isdigit(up[5]) || !isdigit(up[6]) 417 || !isdigit(up[7]) || up[8] != '-' || !isdigit(up[9]) 418 || !isdigit(up[10]) || up[11] != '.') { 419 SPDK_ERRLOG("invalid iqn format. " 420 "expect \"iqn.YYYY-MM.reversed.domain.name\"\n"); 421 return -1; 422 } 423 } else if (strncasecmp(name, "eui.", 4) == 0) { 424 /* EUI-64 -> 16bytes */ 425 /* XXX */ 426 } else if (strncasecmp(name, "naa.", 4) == 0) { 427 /* 64bit -> 16bytes, 128bit -> 32bytes */ 428 /* XXX */ 429 } 430 /* OK */ 431 return 0; 432 } 433 434 static void 435 spdk_iscsi_tgt_node_destruct(struct spdk_iscsi_tgt_node *target) 436 { 437 int i; 438 439 if (target == NULL) { 440 return; 441 } 442 443 free(target->name); 444 free(target->alias); 445 spdk_scsi_dev_destruct(target->dev); 446 for (i = 0; i < target->maxmap; i++) { 447 target->map[i].pg->ref--; 448 target->map[i].ig->ref--; 449 } 450 451 pthread_mutex_destroy(&target->mutex); 452 free(target); 453 } 454 455 static int spdk_get_next_available_tgt_number(void) 456 { 457 int i; 458 459 for (i = 0; i < MAX_ISCSI_TARGET_NODE; i++) { 460 if (g_spdk_iscsi.target[i] == NULL) 461 break; 462 } 463 return i; //Returns MAX_TARGET if none available. 464 } 465 466 static struct spdk_iscsi_tgt_node_map * 467 spdk_iscsi_tgt_node_add_map(struct spdk_iscsi_tgt_node *target, 468 int pg_tag, int ig_tag) 469 { 470 struct spdk_iscsi_tgt_node_map *map; 471 struct spdk_iscsi_portal_grp *pg; 472 struct spdk_iscsi_init_grp *ig; 473 474 if (target->maxmap >= MAX_TARGET_MAP) { 475 SPDK_ERRLOG("%s: no space for new map\n", target->name); 476 return NULL; 477 } 478 479 pthread_mutex_lock(&g_spdk_iscsi.mutex); 480 pg = spdk_iscsi_portal_grp_find_by_tag(pg_tag); 481 if (pg == NULL) { 482 pthread_mutex_unlock(&g_spdk_iscsi.mutex); 483 SPDK_ERRLOG("%s: PortalGroup%d not found\n", target->name, pg_tag); 484 return NULL; 485 } 486 if (pg->state != GROUP_READY) { 487 pthread_mutex_unlock(&g_spdk_iscsi.mutex); 488 SPDK_ERRLOG("%s: PortalGroup%d not active\n", target->name, pg_tag); 489 return NULL; 490 } 491 ig = spdk_iscsi_init_grp_find_by_tag(ig_tag); 492 if (ig == NULL) { 493 pthread_mutex_unlock(&g_spdk_iscsi.mutex); 494 SPDK_ERRLOG("%s: InitiatorGroup%d not found\n", target->name, ig_tag); 495 return NULL; 496 } 497 if (ig->state != GROUP_READY) { 498 pthread_mutex_unlock(&g_spdk_iscsi.mutex); 499 SPDK_ERRLOG("%s: InitiatorGroup%d not active\n", target->name, ig_tag); 500 return NULL; 501 } 502 pg->ref++; 503 ig->ref++; 504 pthread_mutex_unlock(&g_spdk_iscsi.mutex); 505 map = &target->map[target->maxmap]; 506 map->pg = pg; 507 map->ig = ig; 508 target->maxmap++; 509 510 return map; 511 } 512 513 _spdk_iscsi_tgt_node * 514 spdk_iscsi_tgt_node_construct(int target_index, 515 const char *name, const char *alias, 516 int *pg_tag_list, int *ig_tag_list, uint16_t num_maps, 517 char *lun_name_list[], int *lun_id_list, int num_luns, 518 int queue_depth, 519 int auth_chap_disabled, int auth_chap_required, int auth_chap_mutual, int auth_group, 520 int header_digest, int data_digest) 521 { 522 char fullname[MAX_TMPBUF], port_name[MAX_TMPBUF]; 523 struct spdk_iscsi_tgt_node *target; 524 struct spdk_iscsi_tgt_node_map *map; 525 struct spdk_iscsi_portal_grp *unique_portal_groups[SPDK_SCSI_DEV_MAX_PORTS]; 526 struct spdk_iscsi_portal_grp *pg; 527 int num_unique_portal_groups; 528 int i, j, rc; 529 530 if (auth_chap_disabled && auth_chap_required) { 531 SPDK_ERRLOG("auth_chap_disabled and auth_chap_required are mutually exclusive\n"); 532 return NULL; 533 } 534 535 if ((num_maps > MAX_TARGET_MAP) || (num_maps == 0)) { 536 SPDK_ERRLOG("num_maps = %d out of range\n", num_maps); 537 return NULL; 538 } 539 540 if (target_index == -1) 541 target_index = spdk_get_next_available_tgt_number(); 542 543 if (target_index >= MAX_ISCSI_TARGET_NODE) { 544 SPDK_ERRLOG("%d over maximum unit number\n", target_index); 545 return NULL; 546 } 547 548 if (g_spdk_iscsi.target[target_index] != NULL) { 549 SPDK_ERRLOG("tgt_node%d: duplicate unit\n", target_index); 550 return NULL; 551 } 552 553 if (name == NULL) { 554 SPDK_ERRLOG("TargetName not found\n"); 555 return NULL; 556 } 557 558 if (strncasecmp(name, "iqn.", 4) != 0 559 && strncasecmp(name, "eui.", 4) != 0 560 && strncasecmp(name, "naa.", 4) != 0) { 561 snprintf(fullname, sizeof(fullname), "%s:%s", g_spdk_iscsi.nodebase, name); 562 } else 563 snprintf(fullname, sizeof(fullname), "%s", name); 564 565 if (spdk_check_iscsi_name(fullname) != 0) { 566 SPDK_ERRLOG("TargetName %s contains an invalid character or format.\n", 567 name); 568 return NULL; 569 } 570 571 target = malloc(sizeof(*target)); 572 if (!target) { 573 SPDK_ERRLOG("could not allocate target\n"); 574 return NULL; 575 } 576 577 memset(target, 0, sizeof(*target)); 578 579 rc = pthread_mutex_init(&target->mutex, NULL); 580 if (rc != 0) { 581 SPDK_ERRLOG("tgt_node%d: mutex_init() failed\n", target->num); 582 spdk_iscsi_tgt_node_destruct(target); 583 return NULL; 584 } 585 586 target->num = target_index; 587 588 target->name = strdup(fullname); 589 if (!target->name) { 590 SPDK_ERRLOG("Could not allocate TargetName\n"); 591 spdk_iscsi_tgt_node_destruct(target); 592 return NULL; 593 } 594 595 if (alias == NULL) { 596 target->alias = NULL; 597 } else { 598 target->alias = strdup(alias); 599 if (!target->alias) { 600 SPDK_ERRLOG("Could not allocate TargetAlias\n"); 601 spdk_iscsi_tgt_node_destruct(target); 602 return NULL; 603 } 604 } 605 606 target->dev = spdk_scsi_dev_construct(name, lun_name_list, lun_id_list, num_luns, 607 SPDK_SPC_PROTOCOL_IDENTIFIER_ISCSI, NULL, NULL); 608 609 if (!target->dev) { 610 SPDK_ERRLOG("Could not construct SCSI device\n"); 611 spdk_iscsi_tgt_node_destruct(target); 612 return NULL; 613 } 614 615 num_unique_portal_groups = 0; 616 for (i = 0; i < num_maps; i++) { 617 map = spdk_iscsi_tgt_node_add_map(target, pg_tag_list[i], 618 ig_tag_list[i]); 619 620 if (map == NULL) { 621 SPDK_ERRLOG("could not add map to target\n"); 622 spdk_iscsi_tgt_node_destruct(target); 623 return NULL; 624 } 625 626 for (j = 0; j < num_unique_portal_groups; j++) { 627 if (unique_portal_groups[j] == map->pg) { 628 break; 629 } 630 } 631 632 if (j == SPDK_SCSI_DEV_MAX_PORTS) { 633 SPDK_ERRLOG("too many unique portal groups\n"); 634 spdk_iscsi_tgt_node_destruct(target); 635 return NULL; 636 } 637 638 if (j == num_unique_portal_groups) { 639 pg = map->pg; 640 snprintf(port_name, sizeof(port_name), "%s,t,0x%4.4x", 641 name, pg->tag); 642 spdk_scsi_dev_add_port(target->dev, pg->tag, port_name); 643 unique_portal_groups[j] = pg; 644 num_unique_portal_groups++; 645 } 646 } 647 648 target->auth_chap_disabled = auth_chap_disabled; 649 target->auth_chap_required = auth_chap_required; 650 target->auth_chap_mutual = auth_chap_mutual; 651 target->auth_group = auth_group; 652 target->header_digest = header_digest; 653 target->data_digest = data_digest; 654 655 if (queue_depth > SPDK_ISCSI_MAX_QUEUE_DEPTH) { 656 SPDK_DEBUGLOG(SPDK_TRACE_ISCSI, "QueueDepth %d > Max %d. Using %d instead.\n", 657 queue_depth, SPDK_ISCSI_MAX_QUEUE_DEPTH, 658 SPDK_ISCSI_MAX_QUEUE_DEPTH); 659 queue_depth = SPDK_ISCSI_MAX_QUEUE_DEPTH; 660 } 661 target->queue_depth = queue_depth; 662 663 pthread_mutex_lock(&g_spdk_iscsi.mutex); 664 g_spdk_iscsi.ntargets++; 665 g_spdk_iscsi.target[target->num] = target; 666 pthread_mutex_unlock(&g_spdk_iscsi.mutex); 667 668 return target; 669 } 670 671 static int 672 spdk_cf_add_iscsi_tgt_node(struct spdk_conf_section *sp) 673 { 674 char buf[MAX_TMPBUF]; 675 struct spdk_iscsi_tgt_node *target; 676 int pg_tag_list[MAX_TARGET_MAP], ig_tag_list[MAX_TARGET_MAP]; 677 int num_target_maps; 678 const char *alias, *pg_tag, *ig_tag; 679 const char *ag_tag; 680 const char *val, *name; 681 int target_num, auth_group, pg_tag_i, ig_tag_i; 682 int header_digest, data_digest; 683 int auth_chap_disabled, auth_chap_required, auth_chap_mutual; 684 int i; 685 int lun_id_list[SPDK_SCSI_DEV_MAX_LUN]; 686 char lun_name_array[SPDK_SCSI_DEV_MAX_LUN][SPDK_SCSI_LUN_MAX_NAME_LENGTH] = {}; 687 char *lun_name_list[SPDK_SCSI_DEV_MAX_LUN]; 688 int num_luns, queue_depth; 689 690 target_num = spdk_conf_section_get_num(sp); 691 692 SPDK_DEBUGLOG(SPDK_TRACE_ISCSI, "add unit %d\n", target_num); 693 694 data_digest = 0; 695 header_digest = 0; 696 697 name = spdk_conf_section_get_val(sp, "TargetName"); 698 699 if (name == NULL) { 700 SPDK_ERRLOG("tgt_node%d: TargetName not found\n", target_num); 701 return -1; 702 } 703 704 alias = spdk_conf_section_get_val(sp, "TargetAlias"); 705 706 /* Setup initiator and portal group mapping */ 707 val = spdk_conf_section_get_val(sp, "Mapping"); 708 if (val == NULL) { 709 /* no map */ 710 SPDK_ERRLOG("tgt_node%d: no Mapping\n", target_num); 711 return -1; 712 } 713 714 for (i = 0; i < MAX_TARGET_MAP; i++) { 715 val = spdk_conf_section_get_nmval(sp, "Mapping", i, 0); 716 if (val == NULL) 717 break; 718 pg_tag = spdk_conf_section_get_nmval(sp, "Mapping", i, 0); 719 ig_tag = spdk_conf_section_get_nmval(sp, "Mapping", i, 1); 720 if (pg_tag == NULL || ig_tag == NULL) { 721 SPDK_ERRLOG("tgt_node%d: mapping error\n", target_num); 722 return -1; 723 } 724 if (strncasecmp(pg_tag, "PortalGroup", 725 strlen("PortalGroup")) != 0 726 || sscanf(pg_tag, "%*[^0-9]%d", &pg_tag_i) != 1) { 727 SPDK_ERRLOG("tgt_node%d: mapping portal error\n", target_num); 728 return -1; 729 } 730 if (strncasecmp(ig_tag, "InitiatorGroup", 731 strlen("InitiatorGroup")) != 0 732 || sscanf(ig_tag, "%*[^0-9]%d", &ig_tag_i) != 1) { 733 SPDK_ERRLOG("tgt_node%d: mapping initiator error\n", target_num); 734 return -1; 735 } 736 if (pg_tag_i < 1 || ig_tag_i < 1) { 737 SPDK_ERRLOG("tgt_node%d: invalid group tag\n", target_num); 738 return -1; 739 } 740 pg_tag_list[i] = pg_tag_i; 741 ig_tag_list[i] = ig_tag_i; 742 } 743 744 num_target_maps = i; 745 746 /* Setup AuthMethod */ 747 val = spdk_conf_section_get_val(sp, "AuthMethod"); 748 auth_chap_disabled = 0; 749 auth_chap_required = 0; 750 auth_chap_mutual = 0; 751 if (val != NULL) { 752 for (i = 0; ; i++) { 753 val = spdk_conf_section_get_nmval(sp, "AuthMethod", 0, i); 754 if (val == NULL) 755 break; 756 if (strcasecmp(val, "CHAP") == 0) { 757 auth_chap_required = 1; 758 } else if (strcasecmp(val, "Mutual") == 0) { 759 auth_chap_mutual = 1; 760 } else if (strcasecmp(val, "Auto") == 0) { 761 auth_chap_disabled = 0; 762 auth_chap_required = 0; 763 auth_chap_mutual = 0; 764 } else if (strcasecmp(val, "None") == 0) { 765 auth_chap_disabled = 1; 766 auth_chap_required = 0; 767 auth_chap_mutual = 0; 768 } else { 769 SPDK_ERRLOG("tgt_node%d: unknown auth\n", target_num); 770 return -1; 771 } 772 } 773 if (auth_chap_mutual && !auth_chap_required) { 774 SPDK_ERRLOG("tgt_node%d: Mutual but not CHAP\n", target_num); 775 return -1; 776 } 777 } 778 if (auth_chap_disabled == 1) { 779 SPDK_DEBUGLOG(SPDK_TRACE_ISCSI, "AuthMethod None\n"); 780 } else if (auth_chap_required == 0) { 781 SPDK_DEBUGLOG(SPDK_TRACE_ISCSI, "AuthMethod Auto\n"); 782 } else { 783 SPDK_DEBUGLOG(SPDK_TRACE_ISCSI, "AuthMethod CHAP %s\n", 784 auth_chap_mutual ? "Mutual" : ""); 785 } 786 787 val = spdk_conf_section_get_val(sp, "AuthGroup"); 788 if (val == NULL) { 789 auth_group = 0; 790 } else { 791 ag_tag = val; 792 if (strcasecmp(ag_tag, "None") == 0) { 793 auth_group = 0; 794 } else { 795 if (strncasecmp(ag_tag, "AuthGroup", 796 strlen("AuthGroup")) != 0 797 || sscanf(ag_tag, "%*[^0-9]%d", &auth_group) != 1) { 798 SPDK_ERRLOG("tgt_node%d: auth group error\n", target_num); 799 return -1; 800 } 801 if (auth_group == 0) { 802 SPDK_ERRLOG("tgt_node%d: invalid auth group 0\n", target_num); 803 return -1; 804 } 805 } 806 } 807 if (auth_group == 0) { 808 SPDK_DEBUGLOG(SPDK_TRACE_ISCSI, "AuthGroup None\n"); 809 } else { 810 SPDK_DEBUGLOG(SPDK_TRACE_ISCSI, "AuthGroup AuthGroup%d\n", 811 auth_group); 812 } 813 814 val = spdk_conf_section_get_val(sp, "UseDigest"); 815 if (val != NULL) { 816 for (i = 0; ; i++) { 817 val = spdk_conf_section_get_nmval(sp, "UseDigest", 0, i); 818 if (val == NULL) 819 break; 820 if (strcasecmp(val, "Header") == 0) { 821 header_digest = 1; 822 } else if (strcasecmp(val, "Data") == 0) { 823 data_digest = 1; 824 } else if (strcasecmp(val, "Auto") == 0) { 825 header_digest = 0; 826 data_digest = 0; 827 } else { 828 SPDK_ERRLOG("tgt_node%d: unknown digest\n", target_num); 829 return -1; 830 } 831 } 832 } 833 if (header_digest == 0 && data_digest == 0) { 834 SPDK_DEBUGLOG(SPDK_TRACE_ISCSI, "UseDigest Auto\n"); 835 } else { 836 SPDK_DEBUGLOG(SPDK_TRACE_ISCSI, "UseDigest %s %s\n", 837 header_digest ? "Header" : "", 838 data_digest ? "Data" : ""); 839 } 840 841 val = spdk_conf_section_get_val(sp, "QueueDepth"); 842 if (val == NULL) { 843 queue_depth = SPDK_ISCSI_MAX_QUEUE_DEPTH; 844 } else { 845 queue_depth = (int) strtol(val, NULL, 10); 846 } 847 848 num_luns = 0; 849 850 for (i = 0; i < SPDK_SCSI_DEV_MAX_LUN; i++) { 851 snprintf(buf, sizeof(buf), "LUN%d", i); 852 val = spdk_conf_section_get_val(sp, buf); 853 if (val == NULL) { 854 continue; 855 } 856 857 snprintf(lun_name_array[num_luns], SPDK_SCSI_LUN_MAX_NAME_LENGTH, "%s", val); 858 lun_name_list[num_luns] = lun_name_array[num_luns]; 859 lun_id_list[num_luns] = i; 860 num_luns++; 861 } 862 863 if (num_luns == 0) { 864 SPDK_ERRLOG("tgt_node%d: No LUN specified for target %s.\n", target_num, name); 865 return -1; 866 } 867 868 target = spdk_iscsi_tgt_node_construct(target_num, name, alias, 869 pg_tag_list, ig_tag_list, num_target_maps, 870 lun_name_list, lun_id_list, num_luns, queue_depth, 871 auth_chap_disabled, auth_chap_required, 872 auth_chap_mutual, auth_group, 873 header_digest, data_digest); 874 875 if (target == NULL) { 876 SPDK_ERRLOG("tgt_node%d: add_iscsi_target_node error\n", target_num); 877 return -1; 878 } 879 880 spdk_scsi_dev_print(target->dev); 881 return 0; 882 } 883 884 int spdk_iscsi_init_tgt_nodes(void) 885 { 886 struct spdk_conf_section *sp; 887 int rc; 888 889 SPDK_DEBUGLOG(SPDK_TRACE_ISCSI, "spdk_iscsi_init_tgt_nodes\n"); 890 891 sp = spdk_conf_first_section(NULL); 892 while (sp != NULL) { 893 if (spdk_conf_section_match_prefix(sp, "TargetNode")) { 894 int tag = spdk_conf_section_get_num(sp); 895 896 if (tag > SPDK_TN_TAG_MAX) { 897 SPDK_ERRLOG("tag %d is invalid\n", tag); 898 return -1; 899 } 900 rc = spdk_cf_add_iscsi_tgt_node(sp); 901 if (rc < 0) { 902 SPDK_ERRLOG("spdk_cf_add_iscsi_tgt_node() failed\n"); 903 return -1; 904 } 905 } 906 sp = spdk_conf_next_section(sp); 907 } 908 return 0; 909 } 910 911 int 912 spdk_iscsi_shutdown_tgt_nodes(void) 913 { 914 struct spdk_iscsi_tgt_node *target; 915 int i; 916 917 pthread_mutex_lock(&g_spdk_iscsi.mutex); 918 for (i = 0; i < MAX_ISCSI_TARGET_NODE; i++) { 919 target = g_spdk_iscsi.target[i]; 920 if (target == NULL) 921 continue; 922 spdk_iscsi_tgt_node_destruct(target); 923 g_spdk_iscsi.ntargets--; 924 g_spdk_iscsi.target[i] = NULL; 925 } 926 pthread_mutex_unlock(&g_spdk_iscsi.mutex); 927 928 return 0; 929 } 930 931 int 932 spdk_iscsi_shutdown_tgt_node_by_name(const char *target_name) 933 { 934 struct spdk_iscsi_tgt_node *target; 935 int i = 0; 936 int ret = -1; 937 938 pthread_mutex_lock(&g_spdk_iscsi.mutex); 939 for (i = 0; i < MAX_ISCSI_TARGET_NODE; i++) { 940 target = g_spdk_iscsi.target[i]; 941 if (target == NULL) 942 continue; 943 944 if (strncmp(target_name, target->name, MAX_TMPBUF) == 0) { 945 spdk_iscsi_tgt_node_destruct(target); 946 g_spdk_iscsi.ntargets--; 947 g_spdk_iscsi.target[i] = NULL; 948 ret = 0; 949 break; 950 } 951 } 952 pthread_mutex_unlock(&g_spdk_iscsi.mutex); 953 954 return ret; 955 } 956 957 int 958 spdk_iscsi_tgt_node_cleanup_luns(struct spdk_iscsi_conn *conn, 959 struct spdk_iscsi_tgt_node *target) 960 { 961 int i; 962 struct spdk_iscsi_task *task; 963 964 for (i = 0; i < SPDK_SCSI_DEV_MAX_LUN; i++) { 965 struct spdk_scsi_lun *lun = spdk_scsi_dev_get_lun(target->dev, i); 966 967 if (!lun) 968 continue; 969 970 /* we create a fake management task per LUN to cleanup */ 971 task = spdk_iscsi_task_get(conn, NULL, spdk_iscsi_task_mgmt_cpl); 972 if (!task) { 973 SPDK_ERRLOG("Unable to acquire task\n"); 974 return -1; 975 } 976 977 task->scsi.target_port = conn->target_port; 978 task->scsi.initiator_port = conn->initiator_port; 979 task->scsi.lun = lun; 980 981 spdk_scsi_dev_queue_mgmt_task(target->dev, &task->scsi, SPDK_SCSI_TASK_FUNC_LUN_RESET); 982 } 983 984 return 0; 985 } 986 987 void spdk_iscsi_tgt_node_delete_map(struct spdk_iscsi_portal_grp *portal_group, 988 struct spdk_iscsi_init_grp *initiator_group) 989 { 990 struct spdk_iscsi_tgt_node *target; 991 int i = 0; 992 int j = 0; 993 int k = 0; 994 int flag = 0; 995 996 for (i = 0; i < MAX_ISCSI_TARGET_NODE; i++) { 997 target = g_spdk_iscsi.target[i]; 998 if (target == NULL) 999 continue; 1000 loop: 1001 flag = 0; 1002 for (j = 0; j < target->maxmap; j++) { 1003 if (portal_group) { 1004 if (target->map[j].pg->tag == portal_group->tag) { 1005 flag = 1; 1006 } 1007 } 1008 if (initiator_group) { 1009 if (target->map[j].ig->tag == initiator_group->tag) { 1010 flag = 1; 1011 } 1012 } 1013 1014 if (flag == 1) { 1015 target->map[j].pg->ref--; 1016 target->map[j].ig->ref--; 1017 for (k = j; k < target->maxmap - 1; k++) { 1018 target->map[k].pg = target->map[k + 1].pg; 1019 target->map[k].ig = target->map[k + 1].ig; 1020 } 1021 target->map[target->maxmap - 1].pg = NULL; 1022 target->map[target->maxmap - 1].ig = NULL; 1023 target->maxmap -= 1; 1024 goto loop; 1025 } 1026 } 1027 } 1028 } 1029