linux/drivers/target/iscsi/iscsi_target_tpg.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*******************************************************************************
   3 * This file contains iSCSI Target Portal Group related functions.
   4 *
   5 * (c) Copyright 2007-2013 Datera, Inc.
   6 *
   7 * Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
   8 *
   9 ******************************************************************************/
  10
  11#include <linux/slab.h>
  12#include <target/target_core_base.h>
  13#include <target/target_core_fabric.h>
  14#include <target/iscsi/iscsi_target_core.h>
  15#include "iscsi_target_erl0.h"
  16#include "iscsi_target_login.h"
  17#include "iscsi_target_nodeattrib.h"
  18#include "iscsi_target_tpg.h"
  19#include "iscsi_target_util.h"
  20#include "iscsi_target.h"
  21#include "iscsi_target_parameters.h"
  22
  23#include <target/iscsi/iscsi_transport.h>
  24
  25struct iscsi_portal_group *iscsit_alloc_portal_group(struct iscsi_tiqn *tiqn, u16 tpgt)
  26{
  27        struct iscsi_portal_group *tpg;
  28
  29        tpg = kzalloc(sizeof(struct iscsi_portal_group), GFP_KERNEL);
  30        if (!tpg) {
  31                pr_err("Unable to allocate struct iscsi_portal_group\n");
  32                return NULL;
  33        }
  34
  35        tpg->tpgt = tpgt;
  36        tpg->tpg_state = TPG_STATE_FREE;
  37        tpg->tpg_tiqn = tiqn;
  38        INIT_LIST_HEAD(&tpg->tpg_gnp_list);
  39        INIT_LIST_HEAD(&tpg->tpg_list);
  40        mutex_init(&tpg->tpg_access_lock);
  41        sema_init(&tpg->np_login_sem, 1);
  42        spin_lock_init(&tpg->tpg_state_lock);
  43        spin_lock_init(&tpg->tpg_np_lock);
  44
  45        return tpg;
  46}
  47
  48static void iscsit_set_default_tpg_attribs(struct iscsi_portal_group *);
  49
  50int iscsit_load_discovery_tpg(void)
  51{
  52        struct iscsi_param *param;
  53        struct iscsi_portal_group *tpg;
  54        int ret;
  55
  56        tpg = iscsit_alloc_portal_group(NULL, 1);
  57        if (!tpg) {
  58                pr_err("Unable to allocate struct iscsi_portal_group\n");
  59                return -1;
  60        }
  61        /*
  62         * Save iscsi_ops pointer for special case discovery TPG that
  63         * doesn't exist as se_wwn->wwn_group within configfs.
  64         */
  65        tpg->tpg_se_tpg.se_tpg_tfo = &iscsi_ops;
  66        ret = core_tpg_register(NULL, &tpg->tpg_se_tpg, -1);
  67        if (ret < 0) {
  68                kfree(tpg);
  69                return -1;
  70        }
  71
  72        tpg->sid = 1; /* First Assigned LIO Session ID */
  73        iscsit_set_default_tpg_attribs(tpg);
  74
  75        if (iscsi_create_default_params(&tpg->param_list) < 0)
  76                goto out;
  77        /*
  78         * By default we disable authentication for discovery sessions,
  79         * this can be changed with:
  80         *
  81         * /sys/kernel/config/target/iscsi/discovery_auth/enforce_discovery_auth
  82         */
  83        param = iscsi_find_param_from_key(AUTHMETHOD, tpg->param_list);
  84        if (!param)
  85                goto free_pl_out;
  86
  87        if (iscsi_update_param_value(param, "CHAP,None") < 0)
  88                goto free_pl_out;
  89
  90        tpg->tpg_attrib.authentication = 0;
  91
  92        spin_lock(&tpg->tpg_state_lock);
  93        tpg->tpg_state  = TPG_STATE_ACTIVE;
  94        spin_unlock(&tpg->tpg_state_lock);
  95
  96        iscsit_global->discovery_tpg = tpg;
  97        pr_debug("CORE[0] - Allocated Discovery TPG\n");
  98
  99        return 0;
 100free_pl_out:
 101        iscsi_release_param_list(tpg->param_list);
 102out:
 103        if (tpg->sid == 1)
 104                core_tpg_deregister(&tpg->tpg_se_tpg);
 105        kfree(tpg);
 106        return -1;
 107}
 108
 109void iscsit_release_discovery_tpg(void)
 110{
 111        struct iscsi_portal_group *tpg = iscsit_global->discovery_tpg;
 112
 113        if (!tpg)
 114                return;
 115
 116        iscsi_release_param_list(tpg->param_list);
 117        core_tpg_deregister(&tpg->tpg_se_tpg);
 118
 119        kfree(tpg);
 120        iscsit_global->discovery_tpg = NULL;
 121}
 122
 123struct iscsi_portal_group *iscsit_get_tpg_from_np(
 124        struct iscsi_tiqn *tiqn,
 125        struct iscsi_np *np,
 126        struct iscsi_tpg_np **tpg_np_out)
 127{
 128        struct iscsi_portal_group *tpg = NULL;
 129        struct iscsi_tpg_np *tpg_np;
 130
 131        spin_lock(&tiqn->tiqn_tpg_lock);
 132        list_for_each_entry(tpg, &tiqn->tiqn_tpg_list, tpg_list) {
 133
 134                spin_lock(&tpg->tpg_state_lock);
 135                if (tpg->tpg_state != TPG_STATE_ACTIVE) {
 136                        spin_unlock(&tpg->tpg_state_lock);
 137                        continue;
 138                }
 139                spin_unlock(&tpg->tpg_state_lock);
 140
 141                spin_lock(&tpg->tpg_np_lock);
 142                list_for_each_entry(tpg_np, &tpg->tpg_gnp_list, tpg_np_list) {
 143                        if (tpg_np->tpg_np == np) {
 144                                *tpg_np_out = tpg_np;
 145                                kref_get(&tpg_np->tpg_np_kref);
 146                                spin_unlock(&tpg->tpg_np_lock);
 147                                spin_unlock(&tiqn->tiqn_tpg_lock);
 148                                return tpg;
 149                        }
 150                }
 151                spin_unlock(&tpg->tpg_np_lock);
 152        }
 153        spin_unlock(&tiqn->tiqn_tpg_lock);
 154
 155        return NULL;
 156}
 157
 158int iscsit_get_tpg(
 159        struct iscsi_portal_group *tpg)
 160{
 161        return mutex_lock_interruptible(&tpg->tpg_access_lock);
 162}
 163
 164void iscsit_put_tpg(struct iscsi_portal_group *tpg)
 165{
 166        mutex_unlock(&tpg->tpg_access_lock);
 167}
 168
 169static void iscsit_clear_tpg_np_login_thread(
 170        struct iscsi_tpg_np *tpg_np,
 171        struct iscsi_portal_group *tpg,
 172        bool shutdown)
 173{
 174        if (!tpg_np->tpg_np) {
 175                pr_err("struct iscsi_tpg_np->tpg_np is NULL!\n");
 176                return;
 177        }
 178
 179        if (shutdown)
 180                tpg_np->tpg_np->enabled = false;
 181        iscsit_reset_np_thread(tpg_np->tpg_np, tpg_np, tpg, shutdown);
 182}
 183
 184static void iscsit_clear_tpg_np_login_threads(
 185        struct iscsi_portal_group *tpg,
 186        bool shutdown)
 187{
 188        struct iscsi_tpg_np *tpg_np;
 189
 190        spin_lock(&tpg->tpg_np_lock);
 191        list_for_each_entry(tpg_np, &tpg->tpg_gnp_list, tpg_np_list) {
 192                if (!tpg_np->tpg_np) {
 193                        pr_err("struct iscsi_tpg_np->tpg_np is NULL!\n");
 194                        continue;
 195                }
 196                spin_unlock(&tpg->tpg_np_lock);
 197                iscsit_clear_tpg_np_login_thread(tpg_np, tpg, shutdown);
 198                spin_lock(&tpg->tpg_np_lock);
 199        }
 200        spin_unlock(&tpg->tpg_np_lock);
 201}
 202
 203void iscsit_tpg_dump_params(struct iscsi_portal_group *tpg)
 204{
 205        iscsi_print_params(tpg->param_list);
 206}
 207
 208static void iscsit_set_default_tpg_attribs(struct iscsi_portal_group *tpg)
 209{
 210        struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
 211
 212        a->authentication = TA_AUTHENTICATION;
 213        a->login_timeout = TA_LOGIN_TIMEOUT;
 214        a->netif_timeout = TA_NETIF_TIMEOUT;
 215        a->default_cmdsn_depth = TA_DEFAULT_CMDSN_DEPTH;
 216        a->generate_node_acls = TA_GENERATE_NODE_ACLS;
 217        a->cache_dynamic_acls = TA_CACHE_DYNAMIC_ACLS;
 218        a->demo_mode_write_protect = TA_DEMO_MODE_WRITE_PROTECT;
 219        a->prod_mode_write_protect = TA_PROD_MODE_WRITE_PROTECT;
 220        a->demo_mode_discovery = TA_DEMO_MODE_DISCOVERY;
 221        a->default_erl = TA_DEFAULT_ERL;
 222        a->t10_pi = TA_DEFAULT_T10_PI;
 223        a->fabric_prot_type = TA_DEFAULT_FABRIC_PROT_TYPE;
 224        a->tpg_enabled_sendtargets = TA_DEFAULT_TPG_ENABLED_SENDTARGETS;
 225        a->login_keys_workaround = TA_DEFAULT_LOGIN_KEYS_WORKAROUND;
 226}
 227
 228int iscsit_tpg_add_portal_group(struct iscsi_tiqn *tiqn, struct iscsi_portal_group *tpg)
 229{
 230        if (tpg->tpg_state != TPG_STATE_FREE) {
 231                pr_err("Unable to add iSCSI Target Portal Group: %d"
 232                        " while not in TPG_STATE_FREE state.\n", tpg->tpgt);
 233                return -EEXIST;
 234        }
 235        iscsit_set_default_tpg_attribs(tpg);
 236
 237        if (iscsi_create_default_params(&tpg->param_list) < 0)
 238                goto err_out;
 239
 240        tpg->tpg_attrib.tpg = tpg;
 241
 242        spin_lock(&tpg->tpg_state_lock);
 243        tpg->tpg_state  = TPG_STATE_INACTIVE;
 244        spin_unlock(&tpg->tpg_state_lock);
 245
 246        spin_lock(&tiqn->tiqn_tpg_lock);
 247        list_add_tail(&tpg->tpg_list, &tiqn->tiqn_tpg_list);
 248        tiqn->tiqn_ntpgs++;
 249        pr_debug("CORE[%s]_TPG[%hu] - Added iSCSI Target Portal Group\n",
 250                        tiqn->tiqn, tpg->tpgt);
 251        spin_unlock(&tiqn->tiqn_tpg_lock);
 252
 253        return 0;
 254err_out:
 255        if (tpg->param_list) {
 256                iscsi_release_param_list(tpg->param_list);
 257                tpg->param_list = NULL;
 258        }
 259        return -ENOMEM;
 260}
 261
 262int iscsit_tpg_del_portal_group(
 263        struct iscsi_tiqn *tiqn,
 264        struct iscsi_portal_group *tpg,
 265        int force)
 266{
 267        u8 old_state = tpg->tpg_state;
 268
 269        spin_lock(&tpg->tpg_state_lock);
 270        tpg->tpg_state = TPG_STATE_INACTIVE;
 271        spin_unlock(&tpg->tpg_state_lock);
 272
 273        if (iscsit_release_sessions_for_tpg(tpg, force) < 0) {
 274                pr_err("Unable to delete iSCSI Target Portal Group:"
 275                        " %hu while active sessions exist, and force=0\n",
 276                        tpg->tpgt);
 277                tpg->tpg_state = old_state;
 278                return -EPERM;
 279        }
 280
 281        if (tpg->param_list) {
 282                iscsi_release_param_list(tpg->param_list);
 283                tpg->param_list = NULL;
 284        }
 285
 286        core_tpg_deregister(&tpg->tpg_se_tpg);
 287
 288        spin_lock(&tpg->tpg_state_lock);
 289        tpg->tpg_state = TPG_STATE_FREE;
 290        spin_unlock(&tpg->tpg_state_lock);
 291
 292        spin_lock(&tiqn->tiqn_tpg_lock);
 293        tiqn->tiqn_ntpgs--;
 294        list_del(&tpg->tpg_list);
 295        spin_unlock(&tiqn->tiqn_tpg_lock);
 296
 297        pr_debug("CORE[%s]_TPG[%hu] - Deleted iSCSI Target Portal Group\n",
 298                        tiqn->tiqn, tpg->tpgt);
 299
 300        kfree(tpg);
 301        return 0;
 302}
 303
 304int iscsit_tpg_enable_portal_group(struct iscsi_portal_group *tpg)
 305{
 306        struct iscsi_param *param;
 307        struct iscsi_tiqn *tiqn = tpg->tpg_tiqn;
 308        int ret;
 309
 310        if (tpg->tpg_state == TPG_STATE_ACTIVE) {
 311                pr_err("iSCSI target portal group: %hu is already"
 312                        " active, ignoring request.\n", tpg->tpgt);
 313                return -EINVAL;
 314        }
 315        /*
 316         * Make sure that AuthMethod does not contain None as an option
 317         * unless explictly disabled.  Set the default to CHAP if authentication
 318         * is enforced (as per default), and remove the NONE option.
 319         */
 320        param = iscsi_find_param_from_key(AUTHMETHOD, tpg->param_list);
 321        if (!param)
 322                return -EINVAL;
 323
 324        if (tpg->tpg_attrib.authentication) {
 325                if (!strcmp(param->value, NONE)) {
 326                        ret = iscsi_update_param_value(param, CHAP);
 327                        if (ret)
 328                                goto err;
 329                }
 330
 331                ret = iscsit_ta_authentication(tpg, 1);
 332                if (ret < 0)
 333                        goto err;
 334        }
 335
 336        spin_lock(&tpg->tpg_state_lock);
 337        tpg->tpg_state = TPG_STATE_ACTIVE;
 338        spin_unlock(&tpg->tpg_state_lock);
 339
 340        spin_lock(&tiqn->tiqn_tpg_lock);
 341        tiqn->tiqn_active_tpgs++;
 342        pr_debug("iSCSI_TPG[%hu] - Enabled iSCSI Target Portal Group\n",
 343                        tpg->tpgt);
 344        spin_unlock(&tiqn->tiqn_tpg_lock);
 345
 346        return 0;
 347
 348err:
 349        return ret;
 350}
 351
 352int iscsit_tpg_disable_portal_group(struct iscsi_portal_group *tpg, int force)
 353{
 354        struct iscsi_tiqn *tiqn;
 355        u8 old_state = tpg->tpg_state;
 356
 357        spin_lock(&tpg->tpg_state_lock);
 358        if (tpg->tpg_state == TPG_STATE_INACTIVE) {
 359                pr_err("iSCSI Target Portal Group: %hu is already"
 360                        " inactive, ignoring request.\n", tpg->tpgt);
 361                spin_unlock(&tpg->tpg_state_lock);
 362                return -EINVAL;
 363        }
 364        tpg->tpg_state = TPG_STATE_INACTIVE;
 365        spin_unlock(&tpg->tpg_state_lock);
 366
 367        iscsit_clear_tpg_np_login_threads(tpg, false);
 368
 369        if (iscsit_release_sessions_for_tpg(tpg, force) < 0) {
 370                spin_lock(&tpg->tpg_state_lock);
 371                tpg->tpg_state = old_state;
 372                spin_unlock(&tpg->tpg_state_lock);
 373                pr_err("Unable to disable iSCSI Target Portal Group:"
 374                        " %hu while active sessions exist, and force=0\n",
 375                        tpg->tpgt);
 376                return -EPERM;
 377        }
 378
 379        tiqn = tpg->tpg_tiqn;
 380        if (!tiqn || (tpg == iscsit_global->discovery_tpg))
 381                return 0;
 382
 383        spin_lock(&tiqn->tiqn_tpg_lock);
 384        tiqn->tiqn_active_tpgs--;
 385        pr_debug("iSCSI_TPG[%hu] - Disabled iSCSI Target Portal Group\n",
 386                        tpg->tpgt);
 387        spin_unlock(&tiqn->tiqn_tpg_lock);
 388
 389        return 0;
 390}
 391
 392struct iscsi_node_attrib *iscsit_tpg_get_node_attrib(
 393        struct iscsi_session *sess)
 394{
 395        struct se_session *se_sess = sess->se_sess;
 396        struct se_node_acl *se_nacl = se_sess->se_node_acl;
 397        struct iscsi_node_acl *acl = container_of(se_nacl, struct iscsi_node_acl,
 398                                        se_node_acl);
 399
 400        return &acl->node_attrib;
 401}
 402
 403struct iscsi_tpg_np *iscsit_tpg_locate_child_np(
 404        struct iscsi_tpg_np *tpg_np,
 405        int network_transport)
 406{
 407        struct iscsi_tpg_np *tpg_np_child, *tpg_np_child_tmp;
 408
 409        spin_lock(&tpg_np->tpg_np_parent_lock);
 410        list_for_each_entry_safe(tpg_np_child, tpg_np_child_tmp,
 411                        &tpg_np->tpg_np_parent_list, tpg_np_child_list) {
 412                if (tpg_np_child->tpg_np->np_network_transport ==
 413                                network_transport) {
 414                        spin_unlock(&tpg_np->tpg_np_parent_lock);
 415                        return tpg_np_child;
 416                }
 417        }
 418        spin_unlock(&tpg_np->tpg_np_parent_lock);
 419
 420        return NULL;
 421}
 422
 423static bool iscsit_tpg_check_network_portal(
 424        struct iscsi_tiqn *tiqn,
 425        struct sockaddr_storage *sockaddr,
 426        int network_transport)
 427{
 428        struct iscsi_portal_group *tpg;
 429        struct iscsi_tpg_np *tpg_np;
 430        struct iscsi_np *np;
 431        bool match = false;
 432
 433        spin_lock(&tiqn->tiqn_tpg_lock);
 434        list_for_each_entry(tpg, &tiqn->tiqn_tpg_list, tpg_list) {
 435
 436                spin_lock(&tpg->tpg_np_lock);
 437                list_for_each_entry(tpg_np, &tpg->tpg_gnp_list, tpg_np_list) {
 438                        np = tpg_np->tpg_np;
 439
 440                        match = iscsit_check_np_match(sockaddr, np,
 441                                                network_transport);
 442                        if (match)
 443                                break;
 444                }
 445                spin_unlock(&tpg->tpg_np_lock);
 446        }
 447        spin_unlock(&tiqn->tiqn_tpg_lock);
 448
 449        return match;
 450}
 451
 452struct iscsi_tpg_np *iscsit_tpg_add_network_portal(
 453        struct iscsi_portal_group *tpg,
 454        struct sockaddr_storage *sockaddr,
 455        struct iscsi_tpg_np *tpg_np_parent,
 456        int network_transport)
 457{
 458        struct iscsi_np *np;
 459        struct iscsi_tpg_np *tpg_np;
 460
 461        if (!tpg_np_parent) {
 462                if (iscsit_tpg_check_network_portal(tpg->tpg_tiqn, sockaddr,
 463                                network_transport)) {
 464                        pr_err("Network Portal: %pISc already exists on a"
 465                                " different TPG on %s\n", sockaddr,
 466                                tpg->tpg_tiqn->tiqn);
 467                        return ERR_PTR(-EEXIST);
 468                }
 469        }
 470
 471        tpg_np = kzalloc(sizeof(struct iscsi_tpg_np), GFP_KERNEL);
 472        if (!tpg_np) {
 473                pr_err("Unable to allocate memory for"
 474                                " struct iscsi_tpg_np.\n");
 475                return ERR_PTR(-ENOMEM);
 476        }
 477
 478        np = iscsit_add_np(sockaddr, network_transport);
 479        if (IS_ERR(np)) {
 480                kfree(tpg_np);
 481                return ERR_CAST(np);
 482        }
 483
 484        INIT_LIST_HEAD(&tpg_np->tpg_np_list);
 485        INIT_LIST_HEAD(&tpg_np->tpg_np_child_list);
 486        INIT_LIST_HEAD(&tpg_np->tpg_np_parent_list);
 487        spin_lock_init(&tpg_np->tpg_np_parent_lock);
 488        init_completion(&tpg_np->tpg_np_comp);
 489        kref_init(&tpg_np->tpg_np_kref);
 490        tpg_np->tpg_np          = np;
 491        tpg_np->tpg             = tpg;
 492
 493        spin_lock(&tpg->tpg_np_lock);
 494        list_add_tail(&tpg_np->tpg_np_list, &tpg->tpg_gnp_list);
 495        tpg->num_tpg_nps++;
 496        if (tpg->tpg_tiqn)
 497                tpg->tpg_tiqn->tiqn_num_tpg_nps++;
 498        spin_unlock(&tpg->tpg_np_lock);
 499
 500        if (tpg_np_parent) {
 501                tpg_np->tpg_np_parent = tpg_np_parent;
 502                spin_lock(&tpg_np_parent->tpg_np_parent_lock);
 503                list_add_tail(&tpg_np->tpg_np_child_list,
 504                        &tpg_np_parent->tpg_np_parent_list);
 505                spin_unlock(&tpg_np_parent->tpg_np_parent_lock);
 506        }
 507
 508        pr_debug("CORE[%s] - Added Network Portal: %pISpc,%hu on %s\n",
 509                tpg->tpg_tiqn->tiqn, &np->np_sockaddr, tpg->tpgt,
 510                np->np_transport->name);
 511
 512        return tpg_np;
 513}
 514
 515static int iscsit_tpg_release_np(
 516        struct iscsi_tpg_np *tpg_np,
 517        struct iscsi_portal_group *tpg,
 518        struct iscsi_np *np)
 519{
 520        iscsit_clear_tpg_np_login_thread(tpg_np, tpg, true);
 521
 522        pr_debug("CORE[%s] - Removed Network Portal: %pISpc,%hu on %s\n",
 523                tpg->tpg_tiqn->tiqn, &np->np_sockaddr, tpg->tpgt,
 524                np->np_transport->name);
 525
 526        tpg_np->tpg_np = NULL;
 527        tpg_np->tpg = NULL;
 528        kfree(tpg_np);
 529        /*
 530         * iscsit_del_np() will shutdown struct iscsi_np when last TPG reference is released.
 531         */
 532        return iscsit_del_np(np);
 533}
 534
 535int iscsit_tpg_del_network_portal(
 536        struct iscsi_portal_group *tpg,
 537        struct iscsi_tpg_np *tpg_np)
 538{
 539        struct iscsi_np *np;
 540        struct iscsi_tpg_np *tpg_np_child, *tpg_np_child_tmp;
 541        int ret = 0;
 542
 543        np = tpg_np->tpg_np;
 544        if (!np) {
 545                pr_err("Unable to locate struct iscsi_np from"
 546                                " struct iscsi_tpg_np\n");
 547                return -EINVAL;
 548        }
 549
 550        if (!tpg_np->tpg_np_parent) {
 551                /*
 552                 * We are the parent tpg network portal.  Release all of the
 553                 * child tpg_np's (eg: the non ISCSI_TCP ones) on our parent
 554                 * list first.
 555                 */
 556                list_for_each_entry_safe(tpg_np_child, tpg_np_child_tmp,
 557                                &tpg_np->tpg_np_parent_list,
 558                                tpg_np_child_list) {
 559                        ret = iscsit_tpg_del_network_portal(tpg, tpg_np_child);
 560                        if (ret < 0)
 561                                pr_err("iscsit_tpg_del_network_portal()"
 562                                        " failed: %d\n", ret);
 563                }
 564        } else {
 565                /*
 566                 * We are not the parent ISCSI_TCP tpg network portal.  Release
 567                 * our own network portals from the child list.
 568                 */
 569                spin_lock(&tpg_np->tpg_np_parent->tpg_np_parent_lock);
 570                list_del(&tpg_np->tpg_np_child_list);
 571                spin_unlock(&tpg_np->tpg_np_parent->tpg_np_parent_lock);
 572        }
 573
 574        spin_lock(&tpg->tpg_np_lock);
 575        list_del(&tpg_np->tpg_np_list);
 576        tpg->num_tpg_nps--;
 577        if (tpg->tpg_tiqn)
 578                tpg->tpg_tiqn->tiqn_num_tpg_nps--;
 579        spin_unlock(&tpg->tpg_np_lock);
 580
 581        return iscsit_tpg_release_np(tpg_np, tpg, np);
 582}
 583
 584int iscsit_ta_authentication(struct iscsi_portal_group *tpg, u32 authentication)
 585{
 586        unsigned char buf1[256], buf2[256], *none = NULL;
 587        int len;
 588        struct iscsi_param *param;
 589        struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
 590
 591        if ((authentication != 1) && (authentication != 0)) {
 592                pr_err("Illegal value for authentication parameter:"
 593                        " %u, ignoring request.\n", authentication);
 594                return -EINVAL;
 595        }
 596
 597        memset(buf1, 0, sizeof(buf1));
 598        memset(buf2, 0, sizeof(buf2));
 599
 600        param = iscsi_find_param_from_key(AUTHMETHOD, tpg->param_list);
 601        if (!param)
 602                return -EINVAL;
 603
 604        if (authentication) {
 605                snprintf(buf1, sizeof(buf1), "%s", param->value);
 606                none = strstr(buf1, NONE);
 607                if (!none)
 608                        goto out;
 609                if (!strncmp(none + 4, ",", 1)) {
 610                        if (!strcmp(buf1, none))
 611                                sprintf(buf2, "%s", none+5);
 612                        else {
 613                                none--;
 614                                *none = '\0';
 615                                len = sprintf(buf2, "%s", buf1);
 616                                none += 5;
 617                                sprintf(buf2 + len, "%s", none);
 618                        }
 619                } else {
 620                        none--;
 621                        *none = '\0';
 622                        sprintf(buf2, "%s", buf1);
 623                }
 624                if (iscsi_update_param_value(param, buf2) < 0)
 625                        return -EINVAL;
 626        } else {
 627                snprintf(buf1, sizeof(buf1), "%s", param->value);
 628                none = strstr(buf1, NONE);
 629                if (none)
 630                        goto out;
 631                strlcat(buf1, "," NONE, sizeof(buf1));
 632                if (iscsi_update_param_value(param, buf1) < 0)
 633                        return -EINVAL;
 634        }
 635
 636out:
 637        a->authentication = authentication;
 638        pr_debug("%s iSCSI Authentication Methods for TPG: %hu.\n",
 639                a->authentication ? "Enforcing" : "Disabling", tpg->tpgt);
 640
 641        return 0;
 642}
 643
 644int iscsit_ta_login_timeout(
 645        struct iscsi_portal_group *tpg,
 646        u32 login_timeout)
 647{
 648        struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
 649
 650        if (login_timeout > TA_LOGIN_TIMEOUT_MAX) {
 651                pr_err("Requested Login Timeout %u larger than maximum"
 652                        " %u\n", login_timeout, TA_LOGIN_TIMEOUT_MAX);
 653                return -EINVAL;
 654        } else if (login_timeout < TA_LOGIN_TIMEOUT_MIN) {
 655                pr_err("Requested Logout Timeout %u smaller than"
 656                        " minimum %u\n", login_timeout, TA_LOGIN_TIMEOUT_MIN);
 657                return -EINVAL;
 658        }
 659
 660        a->login_timeout = login_timeout;
 661        pr_debug("Set Logout Timeout to %u for Target Portal Group"
 662                " %hu\n", a->login_timeout, tpg->tpgt);
 663
 664        return 0;
 665}
 666
 667int iscsit_ta_netif_timeout(
 668        struct iscsi_portal_group *tpg,
 669        u32 netif_timeout)
 670{
 671        struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
 672
 673        if (netif_timeout > TA_NETIF_TIMEOUT_MAX) {
 674                pr_err("Requested Network Interface Timeout %u larger"
 675                        " than maximum %u\n", netif_timeout,
 676                                TA_NETIF_TIMEOUT_MAX);
 677                return -EINVAL;
 678        } else if (netif_timeout < TA_NETIF_TIMEOUT_MIN) {
 679                pr_err("Requested Network Interface Timeout %u smaller"
 680                        " than minimum %u\n", netif_timeout,
 681                                TA_NETIF_TIMEOUT_MIN);
 682                return -EINVAL;
 683        }
 684
 685        a->netif_timeout = netif_timeout;
 686        pr_debug("Set Network Interface Timeout to %u for"
 687                " Target Portal Group %hu\n", a->netif_timeout, tpg->tpgt);
 688
 689        return 0;
 690}
 691
 692int iscsit_ta_generate_node_acls(
 693        struct iscsi_portal_group *tpg,
 694        u32 flag)
 695{
 696        struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
 697
 698        if ((flag != 0) && (flag != 1)) {
 699                pr_err("Illegal value %d\n", flag);
 700                return -EINVAL;
 701        }
 702
 703        a->generate_node_acls = flag;
 704        pr_debug("iSCSI_TPG[%hu] - Generate Initiator Portal Group ACLs: %s\n",
 705                tpg->tpgt, (a->generate_node_acls) ? "Enabled" : "Disabled");
 706
 707        if (flag == 1 && a->cache_dynamic_acls == 0) {
 708                pr_debug("Explicitly setting cache_dynamic_acls=1 when "
 709                        "generate_node_acls=1\n");
 710                a->cache_dynamic_acls = 1;
 711        }
 712
 713        return 0;
 714}
 715
 716int iscsit_ta_default_cmdsn_depth(
 717        struct iscsi_portal_group *tpg,
 718        u32 tcq_depth)
 719{
 720        struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
 721
 722        if (tcq_depth > TA_DEFAULT_CMDSN_DEPTH_MAX) {
 723                pr_err("Requested Default Queue Depth: %u larger"
 724                        " than maximum %u\n", tcq_depth,
 725                                TA_DEFAULT_CMDSN_DEPTH_MAX);
 726                return -EINVAL;
 727        } else if (tcq_depth < TA_DEFAULT_CMDSN_DEPTH_MIN) {
 728                pr_err("Requested Default Queue Depth: %u smaller"
 729                        " than minimum %u\n", tcq_depth,
 730                                TA_DEFAULT_CMDSN_DEPTH_MIN);
 731                return -EINVAL;
 732        }
 733
 734        a->default_cmdsn_depth = tcq_depth;
 735        pr_debug("iSCSI_TPG[%hu] - Set Default CmdSN TCQ Depth to %u\n",
 736                tpg->tpgt, a->default_cmdsn_depth);
 737
 738        return 0;
 739}
 740
 741int iscsit_ta_cache_dynamic_acls(
 742        struct iscsi_portal_group *tpg,
 743        u32 flag)
 744{
 745        struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
 746
 747        if ((flag != 0) && (flag != 1)) {
 748                pr_err("Illegal value %d\n", flag);
 749                return -EINVAL;
 750        }
 751
 752        if (a->generate_node_acls == 1 && flag == 0) {
 753                pr_debug("Skipping cache_dynamic_acls=0 when"
 754                        " generate_node_acls=1\n");
 755                return 0;
 756        }
 757
 758        a->cache_dynamic_acls = flag;
 759        pr_debug("iSCSI_TPG[%hu] - Cache Dynamic Initiator Portal Group"
 760                " ACLs %s\n", tpg->tpgt, (a->cache_dynamic_acls) ?
 761                "Enabled" : "Disabled");
 762
 763        return 0;
 764}
 765
 766int iscsit_ta_demo_mode_write_protect(
 767        struct iscsi_portal_group *tpg,
 768        u32 flag)
 769{
 770        struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
 771
 772        if ((flag != 0) && (flag != 1)) {
 773                pr_err("Illegal value %d\n", flag);
 774                return -EINVAL;
 775        }
 776
 777        a->demo_mode_write_protect = flag;
 778        pr_debug("iSCSI_TPG[%hu] - Demo Mode Write Protect bit: %s\n",
 779                tpg->tpgt, (a->demo_mode_write_protect) ? "ON" : "OFF");
 780
 781        return 0;
 782}
 783
 784int iscsit_ta_prod_mode_write_protect(
 785        struct iscsi_portal_group *tpg,
 786        u32 flag)
 787{
 788        struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
 789
 790        if ((flag != 0) && (flag != 1)) {
 791                pr_err("Illegal value %d\n", flag);
 792                return -EINVAL;
 793        }
 794
 795        a->prod_mode_write_protect = flag;
 796        pr_debug("iSCSI_TPG[%hu] - Production Mode Write Protect bit:"
 797                " %s\n", tpg->tpgt, (a->prod_mode_write_protect) ?
 798                "ON" : "OFF");
 799
 800        return 0;
 801}
 802
 803int iscsit_ta_demo_mode_discovery(
 804        struct iscsi_portal_group *tpg,
 805        u32 flag)
 806{
 807        struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
 808
 809        if ((flag != 0) && (flag != 1)) {
 810                pr_err("Illegal value %d\n", flag);
 811                return -EINVAL;
 812        }
 813
 814        a->demo_mode_discovery = flag;
 815        pr_debug("iSCSI_TPG[%hu] - Demo Mode Discovery bit:"
 816                " %s\n", tpg->tpgt, (a->demo_mode_discovery) ?
 817                "ON" : "OFF");
 818
 819        return 0;
 820}
 821
 822int iscsit_ta_default_erl(
 823        struct iscsi_portal_group *tpg,
 824        u32 default_erl)
 825{
 826        struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
 827
 828        if ((default_erl != 0) && (default_erl != 1) && (default_erl != 2)) {
 829                pr_err("Illegal value for default_erl: %u\n", default_erl);
 830                return -EINVAL;
 831        }
 832
 833        a->default_erl = default_erl;
 834        pr_debug("iSCSI_TPG[%hu] - DefaultERL: %u\n", tpg->tpgt, a->default_erl);
 835
 836        return 0;
 837}
 838
 839int iscsit_ta_t10_pi(
 840        struct iscsi_portal_group *tpg,
 841        u32 flag)
 842{
 843        struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
 844
 845        if ((flag != 0) && (flag != 1)) {
 846                pr_err("Illegal value %d\n", flag);
 847                return -EINVAL;
 848        }
 849
 850        a->t10_pi = flag;
 851        pr_debug("iSCSI_TPG[%hu] - T10 Protection information bit:"
 852                " %s\n", tpg->tpgt, (a->t10_pi) ?
 853                "ON" : "OFF");
 854
 855        return 0;
 856}
 857
 858int iscsit_ta_fabric_prot_type(
 859        struct iscsi_portal_group *tpg,
 860        u32 prot_type)
 861{
 862        struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
 863
 864        if ((prot_type != 0) && (prot_type != 1) && (prot_type != 3)) {
 865                pr_err("Illegal value for fabric_prot_type: %u\n", prot_type);
 866                return -EINVAL;
 867        }
 868
 869        a->fabric_prot_type = prot_type;
 870        pr_debug("iSCSI_TPG[%hu] - T10 Fabric Protection Type: %u\n",
 871                 tpg->tpgt, prot_type);
 872
 873        return 0;
 874}
 875
 876int iscsit_ta_tpg_enabled_sendtargets(
 877        struct iscsi_portal_group *tpg,
 878        u32 flag)
 879{
 880        struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
 881
 882        if ((flag != 0) && (flag != 1)) {
 883                pr_err("Illegal value %d\n", flag);
 884                return -EINVAL;
 885        }
 886
 887        a->tpg_enabled_sendtargets = flag;
 888        pr_debug("iSCSI_TPG[%hu] - TPG enabled bit required for SendTargets:"
 889                " %s\n", tpg->tpgt, (a->tpg_enabled_sendtargets) ? "ON" : "OFF");
 890
 891        return 0;
 892}
 893
 894int iscsit_ta_login_keys_workaround(
 895        struct iscsi_portal_group *tpg,
 896        u32 flag)
 897{
 898        struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
 899
 900        if ((flag != 0) && (flag != 1)) {
 901                pr_err("Illegal value %d\n", flag);
 902                return -EINVAL;
 903        }
 904
 905        a->login_keys_workaround = flag;
 906        pr_debug("iSCSI_TPG[%hu] - TPG enabled bit for login keys workaround: %s ",
 907                tpg->tpgt, (a->login_keys_workaround) ? "ON" : "OFF");
 908
 909        return 0;
 910}
 911