162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*******************************************************************************
362306a36Sopenharmony_ci * This file contains the configfs implementation for iSCSI Target mode
462306a36Sopenharmony_ci * from the LIO-Target Project.
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * (c) Copyright 2007-2013 Datera, Inc.
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci * Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
962306a36Sopenharmony_ci *
1062306a36Sopenharmony_ci ****************************************************************************/
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#include <linux/configfs.h>
1362306a36Sopenharmony_ci#include <linux/ctype.h>
1462306a36Sopenharmony_ci#include <linux/export.h>
1562306a36Sopenharmony_ci#include <linux/inet.h>
1662306a36Sopenharmony_ci#include <linux/module.h>
1762306a36Sopenharmony_ci#include <net/ipv6.h>
1862306a36Sopenharmony_ci#include <target/target_core_base.h>
1962306a36Sopenharmony_ci#include <target/target_core_fabric.h>
2062306a36Sopenharmony_ci#include <target/iscsi/iscsi_transport.h>
2162306a36Sopenharmony_ci#include <target/iscsi/iscsi_target_core.h>
2262306a36Sopenharmony_ci#include "iscsi_target_parameters.h"
2362306a36Sopenharmony_ci#include "iscsi_target_device.h"
2462306a36Sopenharmony_ci#include "iscsi_target_erl0.h"
2562306a36Sopenharmony_ci#include "iscsi_target_nodeattrib.h"
2662306a36Sopenharmony_ci#include "iscsi_target_tpg.h"
2762306a36Sopenharmony_ci#include "iscsi_target_util.h"
2862306a36Sopenharmony_ci#include "iscsi_target.h"
2962306a36Sopenharmony_ci#include <target/iscsi/iscsi_target_stat.h>
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci/* Start items for lio_target_portal_cit */
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_cistatic inline struct iscsi_tpg_np *to_iscsi_tpg_np(struct config_item *item)
3562306a36Sopenharmony_ci{
3662306a36Sopenharmony_ci	return container_of(to_tpg_np(item), struct iscsi_tpg_np, se_tpg_np);
3762306a36Sopenharmony_ci}
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_cistatic ssize_t lio_target_np_driver_show(struct config_item *item, char *page,
4062306a36Sopenharmony_ci					 enum iscsit_transport_type type)
4162306a36Sopenharmony_ci{
4262306a36Sopenharmony_ci	struct iscsi_tpg_np *tpg_np = to_iscsi_tpg_np(item);
4362306a36Sopenharmony_ci	struct iscsi_tpg_np *tpg_np_new;
4462306a36Sopenharmony_ci	ssize_t rb;
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci	tpg_np_new = iscsit_tpg_locate_child_np(tpg_np, type);
4762306a36Sopenharmony_ci	if (tpg_np_new)
4862306a36Sopenharmony_ci		rb = sysfs_emit(page, "1\n");
4962306a36Sopenharmony_ci	else
5062306a36Sopenharmony_ci		rb = sysfs_emit(page, "0\n");
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci	return rb;
5362306a36Sopenharmony_ci}
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_cistatic ssize_t lio_target_np_driver_store(struct config_item *item,
5662306a36Sopenharmony_ci		const char *page, size_t count, enum iscsit_transport_type type,
5762306a36Sopenharmony_ci		const char *mod_name)
5862306a36Sopenharmony_ci{
5962306a36Sopenharmony_ci	struct iscsi_tpg_np *tpg_np = to_iscsi_tpg_np(item);
6062306a36Sopenharmony_ci	struct iscsi_np *np;
6162306a36Sopenharmony_ci	struct iscsi_portal_group *tpg;
6262306a36Sopenharmony_ci	struct iscsi_tpg_np *tpg_np_new = NULL;
6362306a36Sopenharmony_ci	u32 op;
6462306a36Sopenharmony_ci	int rc;
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci	rc = kstrtou32(page, 0, &op);
6762306a36Sopenharmony_ci	if (rc)
6862306a36Sopenharmony_ci		return rc;
6962306a36Sopenharmony_ci	if ((op != 1) && (op != 0)) {
7062306a36Sopenharmony_ci		pr_err("Illegal value for tpg_enable: %u\n", op);
7162306a36Sopenharmony_ci		return -EINVAL;
7262306a36Sopenharmony_ci	}
7362306a36Sopenharmony_ci	np = tpg_np->tpg_np;
7462306a36Sopenharmony_ci	if (!np) {
7562306a36Sopenharmony_ci		pr_err("Unable to locate struct iscsi_np from"
7662306a36Sopenharmony_ci				" struct iscsi_tpg_np\n");
7762306a36Sopenharmony_ci		return -EINVAL;
7862306a36Sopenharmony_ci	}
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci	tpg = tpg_np->tpg;
8162306a36Sopenharmony_ci	if (iscsit_get_tpg(tpg) < 0)
8262306a36Sopenharmony_ci		return -EINVAL;
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci	if (op) {
8562306a36Sopenharmony_ci		if (strlen(mod_name)) {
8662306a36Sopenharmony_ci			rc = request_module(mod_name);
8762306a36Sopenharmony_ci			if (rc != 0) {
8862306a36Sopenharmony_ci				pr_warn("Unable to request_module for %s\n",
8962306a36Sopenharmony_ci					mod_name);
9062306a36Sopenharmony_ci				rc = 0;
9162306a36Sopenharmony_ci			}
9262306a36Sopenharmony_ci		}
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci		tpg_np_new = iscsit_tpg_add_network_portal(tpg,
9562306a36Sopenharmony_ci					&np->np_sockaddr, tpg_np, type);
9662306a36Sopenharmony_ci		if (IS_ERR(tpg_np_new)) {
9762306a36Sopenharmony_ci			rc = PTR_ERR(tpg_np_new);
9862306a36Sopenharmony_ci			goto out;
9962306a36Sopenharmony_ci		}
10062306a36Sopenharmony_ci	} else {
10162306a36Sopenharmony_ci		tpg_np_new = iscsit_tpg_locate_child_np(tpg_np, type);
10262306a36Sopenharmony_ci		if (tpg_np_new) {
10362306a36Sopenharmony_ci			rc = iscsit_tpg_del_network_portal(tpg, tpg_np_new);
10462306a36Sopenharmony_ci			if (rc < 0)
10562306a36Sopenharmony_ci				goto out;
10662306a36Sopenharmony_ci		}
10762306a36Sopenharmony_ci	}
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ci	iscsit_put_tpg(tpg);
11062306a36Sopenharmony_ci	return count;
11162306a36Sopenharmony_ciout:
11262306a36Sopenharmony_ci	iscsit_put_tpg(tpg);
11362306a36Sopenharmony_ci	return rc;
11462306a36Sopenharmony_ci}
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_cistatic ssize_t lio_target_np_iser_show(struct config_item *item, char *page)
11762306a36Sopenharmony_ci{
11862306a36Sopenharmony_ci	return lio_target_np_driver_show(item, page, ISCSI_INFINIBAND);
11962306a36Sopenharmony_ci}
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_cistatic ssize_t lio_target_np_iser_store(struct config_item *item,
12262306a36Sopenharmony_ci					const char *page, size_t count)
12362306a36Sopenharmony_ci{
12462306a36Sopenharmony_ci	return lio_target_np_driver_store(item, page, count,
12562306a36Sopenharmony_ci					  ISCSI_INFINIBAND, "ib_isert");
12662306a36Sopenharmony_ci}
12762306a36Sopenharmony_ciCONFIGFS_ATTR(lio_target_np_, iser);
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_cistatic ssize_t lio_target_np_cxgbit_show(struct config_item *item, char *page)
13062306a36Sopenharmony_ci{
13162306a36Sopenharmony_ci	return lio_target_np_driver_show(item, page, ISCSI_CXGBIT);
13262306a36Sopenharmony_ci}
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_cistatic ssize_t lio_target_np_cxgbit_store(struct config_item *item,
13562306a36Sopenharmony_ci					  const char *page, size_t count)
13662306a36Sopenharmony_ci{
13762306a36Sopenharmony_ci	return lio_target_np_driver_store(item, page, count,
13862306a36Sopenharmony_ci					  ISCSI_CXGBIT, "cxgbit");
13962306a36Sopenharmony_ci}
14062306a36Sopenharmony_ciCONFIGFS_ATTR(lio_target_np_, cxgbit);
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_cistatic struct configfs_attribute *lio_target_portal_attrs[] = {
14362306a36Sopenharmony_ci	&lio_target_np_attr_iser,
14462306a36Sopenharmony_ci	&lio_target_np_attr_cxgbit,
14562306a36Sopenharmony_ci	NULL,
14662306a36Sopenharmony_ci};
14762306a36Sopenharmony_ci
14862306a36Sopenharmony_ci/* Stop items for lio_target_portal_cit */
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_ci/* Start items for lio_target_np_cit */
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_ci#define MAX_PORTAL_LEN		256
15362306a36Sopenharmony_ci
15462306a36Sopenharmony_cistatic struct se_tpg_np *lio_target_call_addnptotpg(
15562306a36Sopenharmony_ci	struct se_portal_group *se_tpg,
15662306a36Sopenharmony_ci	struct config_group *group,
15762306a36Sopenharmony_ci	const char *name)
15862306a36Sopenharmony_ci{
15962306a36Sopenharmony_ci	struct iscsi_portal_group *tpg;
16062306a36Sopenharmony_ci	struct iscsi_tpg_np *tpg_np;
16162306a36Sopenharmony_ci	char *str, *str2, *ip_str, *port_str;
16262306a36Sopenharmony_ci	struct sockaddr_storage sockaddr = { };
16362306a36Sopenharmony_ci	int ret;
16462306a36Sopenharmony_ci	char buf[MAX_PORTAL_LEN + 1] = { };
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_ci	if (strlen(name) > MAX_PORTAL_LEN) {
16762306a36Sopenharmony_ci		pr_err("strlen(name): %d exceeds MAX_PORTAL_LEN: %d\n",
16862306a36Sopenharmony_ci			(int)strlen(name), MAX_PORTAL_LEN);
16962306a36Sopenharmony_ci		return ERR_PTR(-EOVERFLOW);
17062306a36Sopenharmony_ci	}
17162306a36Sopenharmony_ci	snprintf(buf, MAX_PORTAL_LEN + 1, "%s", name);
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_ci	str = strstr(buf, "[");
17462306a36Sopenharmony_ci	if (str) {
17562306a36Sopenharmony_ci		str2 = strstr(str, "]");
17662306a36Sopenharmony_ci		if (!str2) {
17762306a36Sopenharmony_ci			pr_err("Unable to locate trailing \"]\""
17862306a36Sopenharmony_ci				" in IPv6 iSCSI network portal address\n");
17962306a36Sopenharmony_ci			return ERR_PTR(-EINVAL);
18062306a36Sopenharmony_ci		}
18162306a36Sopenharmony_ci
18262306a36Sopenharmony_ci		ip_str = str + 1; /* Skip over leading "[" */
18362306a36Sopenharmony_ci		*str2 = '\0'; /* Terminate the unbracketed IPv6 address */
18462306a36Sopenharmony_ci		str2++; /* Skip over the \0 */
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_ci		port_str = strstr(str2, ":");
18762306a36Sopenharmony_ci		if (!port_str) {
18862306a36Sopenharmony_ci			pr_err("Unable to locate \":port\""
18962306a36Sopenharmony_ci				" in IPv6 iSCSI network portal address\n");
19062306a36Sopenharmony_ci			return ERR_PTR(-EINVAL);
19162306a36Sopenharmony_ci		}
19262306a36Sopenharmony_ci		*port_str = '\0'; /* Terminate string for IP */
19362306a36Sopenharmony_ci		port_str++; /* Skip over ":" */
19462306a36Sopenharmony_ci	} else {
19562306a36Sopenharmony_ci		ip_str = &buf[0];
19662306a36Sopenharmony_ci		port_str = strstr(ip_str, ":");
19762306a36Sopenharmony_ci		if (!port_str) {
19862306a36Sopenharmony_ci			pr_err("Unable to locate \":port\""
19962306a36Sopenharmony_ci				" in IPv4 iSCSI network portal address\n");
20062306a36Sopenharmony_ci			return ERR_PTR(-EINVAL);
20162306a36Sopenharmony_ci		}
20262306a36Sopenharmony_ci		*port_str = '\0'; /* Terminate string for IP */
20362306a36Sopenharmony_ci		port_str++; /* Skip over ":" */
20462306a36Sopenharmony_ci	}
20562306a36Sopenharmony_ci
20662306a36Sopenharmony_ci	ret = inet_pton_with_scope(&init_net, AF_UNSPEC, ip_str,
20762306a36Sopenharmony_ci			port_str, &sockaddr);
20862306a36Sopenharmony_ci	if (ret) {
20962306a36Sopenharmony_ci		pr_err("malformed ip/port passed: %s\n", name);
21062306a36Sopenharmony_ci		return ERR_PTR(ret);
21162306a36Sopenharmony_ci	}
21262306a36Sopenharmony_ci
21362306a36Sopenharmony_ci	tpg = to_iscsi_tpg(se_tpg);
21462306a36Sopenharmony_ci	ret = iscsit_get_tpg(tpg);
21562306a36Sopenharmony_ci	if (ret < 0)
21662306a36Sopenharmony_ci		return ERR_PTR(-EINVAL);
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_ci	pr_debug("LIO_Target_ConfigFS: REGISTER -> %s TPGT: %hu"
21962306a36Sopenharmony_ci		" PORTAL: %s\n",
22062306a36Sopenharmony_ci		config_item_name(&se_tpg->se_tpg_wwn->wwn_group.cg_item),
22162306a36Sopenharmony_ci		tpg->tpgt, name);
22262306a36Sopenharmony_ci	/*
22362306a36Sopenharmony_ci	 * Assume ISCSI_TCP by default.  Other network portals for other
22462306a36Sopenharmony_ci	 * iSCSI fabrics:
22562306a36Sopenharmony_ci	 *
22662306a36Sopenharmony_ci	 * Traditional iSCSI over SCTP (initial support)
22762306a36Sopenharmony_ci	 * iSER/TCP (TODO, hardware available)
22862306a36Sopenharmony_ci	 * iSER/SCTP (TODO, software emulation with osc-iwarp)
22962306a36Sopenharmony_ci	 * iSER/IB (TODO, hardware available)
23062306a36Sopenharmony_ci	 *
23162306a36Sopenharmony_ci	 * can be enabled with attributes under
23262306a36Sopenharmony_ci	 * sys/kernel/config/iscsi/$IQN/$TPG/np/$IP:$PORT/
23362306a36Sopenharmony_ci	 *
23462306a36Sopenharmony_ci	 */
23562306a36Sopenharmony_ci	tpg_np = iscsit_tpg_add_network_portal(tpg, &sockaddr, NULL,
23662306a36Sopenharmony_ci				ISCSI_TCP);
23762306a36Sopenharmony_ci	if (IS_ERR(tpg_np)) {
23862306a36Sopenharmony_ci		iscsit_put_tpg(tpg);
23962306a36Sopenharmony_ci		return ERR_CAST(tpg_np);
24062306a36Sopenharmony_ci	}
24162306a36Sopenharmony_ci	pr_debug("LIO_Target_ConfigFS: addnptotpg done!\n");
24262306a36Sopenharmony_ci
24362306a36Sopenharmony_ci	iscsit_put_tpg(tpg);
24462306a36Sopenharmony_ci	return &tpg_np->se_tpg_np;
24562306a36Sopenharmony_ci}
24662306a36Sopenharmony_ci
24762306a36Sopenharmony_cistatic void lio_target_call_delnpfromtpg(
24862306a36Sopenharmony_ci	struct se_tpg_np *se_tpg_np)
24962306a36Sopenharmony_ci{
25062306a36Sopenharmony_ci	struct iscsi_portal_group *tpg;
25162306a36Sopenharmony_ci	struct iscsi_tpg_np *tpg_np;
25262306a36Sopenharmony_ci	struct se_portal_group *se_tpg;
25362306a36Sopenharmony_ci	int ret;
25462306a36Sopenharmony_ci
25562306a36Sopenharmony_ci	tpg_np = container_of(se_tpg_np, struct iscsi_tpg_np, se_tpg_np);
25662306a36Sopenharmony_ci	tpg = tpg_np->tpg;
25762306a36Sopenharmony_ci	ret = iscsit_get_tpg(tpg);
25862306a36Sopenharmony_ci	if (ret < 0)
25962306a36Sopenharmony_ci		return;
26062306a36Sopenharmony_ci
26162306a36Sopenharmony_ci	se_tpg = &tpg->tpg_se_tpg;
26262306a36Sopenharmony_ci	pr_debug("LIO_Target_ConfigFS: DEREGISTER -> %s TPGT: %hu"
26362306a36Sopenharmony_ci		" PORTAL: %pISpc\n", config_item_name(&se_tpg->se_tpg_wwn->wwn_group.cg_item),
26462306a36Sopenharmony_ci		tpg->tpgt, &tpg_np->tpg_np->np_sockaddr);
26562306a36Sopenharmony_ci
26662306a36Sopenharmony_ci	ret = iscsit_tpg_del_network_portal(tpg, tpg_np);
26762306a36Sopenharmony_ci	if (ret < 0)
26862306a36Sopenharmony_ci		goto out;
26962306a36Sopenharmony_ci
27062306a36Sopenharmony_ci	pr_debug("LIO_Target_ConfigFS: delnpfromtpg done!\n");
27162306a36Sopenharmony_ciout:
27262306a36Sopenharmony_ci	iscsit_put_tpg(tpg);
27362306a36Sopenharmony_ci}
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_ci/* End items for lio_target_np_cit */
27662306a36Sopenharmony_ci
27762306a36Sopenharmony_ci/* Start items for lio_target_nacl_attrib_cit */
27862306a36Sopenharmony_ci
27962306a36Sopenharmony_ci#define ISCSI_NACL_ATTR(name)						\
28062306a36Sopenharmony_cistatic ssize_t iscsi_nacl_attrib_##name##_show(struct config_item *item,\
28162306a36Sopenharmony_ci		char *page)						\
28262306a36Sopenharmony_ci{									\
28362306a36Sopenharmony_ci	struct se_node_acl *se_nacl = attrib_to_nacl(item);		\
28462306a36Sopenharmony_ci	struct iscsi_node_acl *nacl = to_iscsi_nacl(se_nacl);		\
28562306a36Sopenharmony_ci	return sysfs_emit(page, "%u\n", nacl->node_attrib.name);		\
28662306a36Sopenharmony_ci}									\
28762306a36Sopenharmony_ci									\
28862306a36Sopenharmony_cistatic ssize_t iscsi_nacl_attrib_##name##_store(struct config_item *item,\
28962306a36Sopenharmony_ci		const char *page, size_t count)				\
29062306a36Sopenharmony_ci{									\
29162306a36Sopenharmony_ci	struct se_node_acl *se_nacl = attrib_to_nacl(item);		\
29262306a36Sopenharmony_ci	struct iscsi_node_acl *nacl = to_iscsi_nacl(se_nacl);		\
29362306a36Sopenharmony_ci	u32 val;							\
29462306a36Sopenharmony_ci	int ret;							\
29562306a36Sopenharmony_ci									\
29662306a36Sopenharmony_ci	ret = kstrtou32(page, 0, &val);					\
29762306a36Sopenharmony_ci	if (ret)							\
29862306a36Sopenharmony_ci		return ret;						\
29962306a36Sopenharmony_ci	ret = iscsit_na_##name(nacl, val);				\
30062306a36Sopenharmony_ci	if (ret < 0)							\
30162306a36Sopenharmony_ci		return ret;						\
30262306a36Sopenharmony_ci									\
30362306a36Sopenharmony_ci	return count;							\
30462306a36Sopenharmony_ci}									\
30562306a36Sopenharmony_ci									\
30662306a36Sopenharmony_ciCONFIGFS_ATTR(iscsi_nacl_attrib_, name)
30762306a36Sopenharmony_ci
30862306a36Sopenharmony_ciISCSI_NACL_ATTR(dataout_timeout);
30962306a36Sopenharmony_ciISCSI_NACL_ATTR(dataout_timeout_retries);
31062306a36Sopenharmony_ciISCSI_NACL_ATTR(default_erl);
31162306a36Sopenharmony_ciISCSI_NACL_ATTR(nopin_timeout);
31262306a36Sopenharmony_ciISCSI_NACL_ATTR(nopin_response_timeout);
31362306a36Sopenharmony_ciISCSI_NACL_ATTR(random_datain_pdu_offsets);
31462306a36Sopenharmony_ciISCSI_NACL_ATTR(random_datain_seq_offsets);
31562306a36Sopenharmony_ciISCSI_NACL_ATTR(random_r2t_offsets);
31662306a36Sopenharmony_ci
31762306a36Sopenharmony_cistatic ssize_t iscsi_nacl_attrib_authentication_show(struct config_item *item,
31862306a36Sopenharmony_ci		char *page)
31962306a36Sopenharmony_ci{
32062306a36Sopenharmony_ci	struct se_node_acl *se_nacl = attrib_to_nacl(item);
32162306a36Sopenharmony_ci	struct iscsi_node_acl *nacl = to_iscsi_nacl(se_nacl);
32262306a36Sopenharmony_ci
32362306a36Sopenharmony_ci	return sysfs_emit(page, "%d\n", nacl->node_attrib.authentication);
32462306a36Sopenharmony_ci}
32562306a36Sopenharmony_ci
32662306a36Sopenharmony_cistatic ssize_t iscsi_nacl_attrib_authentication_store(struct config_item *item,
32762306a36Sopenharmony_ci		const char *page, size_t count)
32862306a36Sopenharmony_ci{
32962306a36Sopenharmony_ci	struct se_node_acl *se_nacl = attrib_to_nacl(item);
33062306a36Sopenharmony_ci	struct iscsi_node_acl *nacl = to_iscsi_nacl(se_nacl);
33162306a36Sopenharmony_ci	s32 val;
33262306a36Sopenharmony_ci	int ret;
33362306a36Sopenharmony_ci
33462306a36Sopenharmony_ci	ret = kstrtos32(page, 0, &val);
33562306a36Sopenharmony_ci	if (ret)
33662306a36Sopenharmony_ci		return ret;
33762306a36Sopenharmony_ci	if (val != 0 && val != 1 && val != NA_AUTHENTICATION_INHERITED)
33862306a36Sopenharmony_ci		return -EINVAL;
33962306a36Sopenharmony_ci
34062306a36Sopenharmony_ci	nacl->node_attrib.authentication = val;
34162306a36Sopenharmony_ci
34262306a36Sopenharmony_ci	return count;
34362306a36Sopenharmony_ci}
34462306a36Sopenharmony_ci
34562306a36Sopenharmony_ciCONFIGFS_ATTR(iscsi_nacl_attrib_, authentication);
34662306a36Sopenharmony_ci
34762306a36Sopenharmony_cistatic struct configfs_attribute *lio_target_nacl_attrib_attrs[] = {
34862306a36Sopenharmony_ci	&iscsi_nacl_attrib_attr_dataout_timeout,
34962306a36Sopenharmony_ci	&iscsi_nacl_attrib_attr_dataout_timeout_retries,
35062306a36Sopenharmony_ci	&iscsi_nacl_attrib_attr_default_erl,
35162306a36Sopenharmony_ci	&iscsi_nacl_attrib_attr_nopin_timeout,
35262306a36Sopenharmony_ci	&iscsi_nacl_attrib_attr_nopin_response_timeout,
35362306a36Sopenharmony_ci	&iscsi_nacl_attrib_attr_random_datain_pdu_offsets,
35462306a36Sopenharmony_ci	&iscsi_nacl_attrib_attr_random_datain_seq_offsets,
35562306a36Sopenharmony_ci	&iscsi_nacl_attrib_attr_random_r2t_offsets,
35662306a36Sopenharmony_ci	&iscsi_nacl_attrib_attr_authentication,
35762306a36Sopenharmony_ci	NULL,
35862306a36Sopenharmony_ci};
35962306a36Sopenharmony_ci
36062306a36Sopenharmony_ci/* End items for lio_target_nacl_attrib_cit */
36162306a36Sopenharmony_ci
36262306a36Sopenharmony_ci/* Start items for lio_target_nacl_auth_cit */
36362306a36Sopenharmony_ci
36462306a36Sopenharmony_ci#define __DEF_NACL_AUTH_STR(prefix, name, flags)			\
36562306a36Sopenharmony_cistatic ssize_t __iscsi_##prefix##_##name##_show(			\
36662306a36Sopenharmony_ci	struct iscsi_node_acl *nacl,					\
36762306a36Sopenharmony_ci	char *page)							\
36862306a36Sopenharmony_ci{									\
36962306a36Sopenharmony_ci	struct iscsi_node_auth *auth = &nacl->node_auth;		\
37062306a36Sopenharmony_ci									\
37162306a36Sopenharmony_ci	if (!capable(CAP_SYS_ADMIN))					\
37262306a36Sopenharmony_ci		return -EPERM;						\
37362306a36Sopenharmony_ci	return snprintf(page, PAGE_SIZE, "%s\n", auth->name);		\
37462306a36Sopenharmony_ci}									\
37562306a36Sopenharmony_ci									\
37662306a36Sopenharmony_cistatic ssize_t __iscsi_##prefix##_##name##_store(			\
37762306a36Sopenharmony_ci	struct iscsi_node_acl *nacl,					\
37862306a36Sopenharmony_ci	const char *page,						\
37962306a36Sopenharmony_ci	size_t count)							\
38062306a36Sopenharmony_ci{									\
38162306a36Sopenharmony_ci	struct iscsi_node_auth *auth = &nacl->node_auth;		\
38262306a36Sopenharmony_ci									\
38362306a36Sopenharmony_ci	if (!capable(CAP_SYS_ADMIN))					\
38462306a36Sopenharmony_ci		return -EPERM;						\
38562306a36Sopenharmony_ci	if (count >= sizeof(auth->name))				\
38662306a36Sopenharmony_ci		return -EINVAL;						\
38762306a36Sopenharmony_ci	snprintf(auth->name, sizeof(auth->name), "%s", page);		\
38862306a36Sopenharmony_ci	if (!strncmp("NULL", auth->name, 4))				\
38962306a36Sopenharmony_ci		auth->naf_flags &= ~flags;				\
39062306a36Sopenharmony_ci	else								\
39162306a36Sopenharmony_ci		auth->naf_flags |= flags;				\
39262306a36Sopenharmony_ci									\
39362306a36Sopenharmony_ci	if ((auth->naf_flags & NAF_USERID_IN_SET) &&			\
39462306a36Sopenharmony_ci	    (auth->naf_flags & NAF_PASSWORD_IN_SET))			\
39562306a36Sopenharmony_ci		auth->authenticate_target = 1;				\
39662306a36Sopenharmony_ci	else								\
39762306a36Sopenharmony_ci		auth->authenticate_target = 0;				\
39862306a36Sopenharmony_ci									\
39962306a36Sopenharmony_ci	return count;							\
40062306a36Sopenharmony_ci}
40162306a36Sopenharmony_ci
40262306a36Sopenharmony_ci#define DEF_NACL_AUTH_STR(name, flags)					\
40362306a36Sopenharmony_ci	__DEF_NACL_AUTH_STR(nacl_auth, name, flags)			\
40462306a36Sopenharmony_cistatic ssize_t iscsi_nacl_auth_##name##_show(struct config_item *item,	\
40562306a36Sopenharmony_ci		char *page)						\
40662306a36Sopenharmony_ci{									\
40762306a36Sopenharmony_ci	struct se_node_acl *nacl = auth_to_nacl(item);			\
40862306a36Sopenharmony_ci	return __iscsi_nacl_auth_##name##_show(to_iscsi_nacl(nacl), page);	\
40962306a36Sopenharmony_ci}									\
41062306a36Sopenharmony_cistatic ssize_t iscsi_nacl_auth_##name##_store(struct config_item *item,	\
41162306a36Sopenharmony_ci		const char *page, size_t count)				\
41262306a36Sopenharmony_ci{									\
41362306a36Sopenharmony_ci	struct se_node_acl *nacl = auth_to_nacl(item);			\
41462306a36Sopenharmony_ci	return __iscsi_nacl_auth_##name##_store(to_iscsi_nacl(nacl),	\
41562306a36Sopenharmony_ci						page, count); \
41662306a36Sopenharmony_ci}									\
41762306a36Sopenharmony_ci									\
41862306a36Sopenharmony_ciCONFIGFS_ATTR(iscsi_nacl_auth_, name)
41962306a36Sopenharmony_ci
42062306a36Sopenharmony_ci/*
42162306a36Sopenharmony_ci * One-way authentication userid
42262306a36Sopenharmony_ci */
42362306a36Sopenharmony_ciDEF_NACL_AUTH_STR(userid, NAF_USERID_SET);
42462306a36Sopenharmony_ciDEF_NACL_AUTH_STR(password, NAF_PASSWORD_SET);
42562306a36Sopenharmony_ciDEF_NACL_AUTH_STR(userid_mutual, NAF_USERID_IN_SET);
42662306a36Sopenharmony_ciDEF_NACL_AUTH_STR(password_mutual, NAF_PASSWORD_IN_SET);
42762306a36Sopenharmony_ci
42862306a36Sopenharmony_ci#define __DEF_NACL_AUTH_INT(prefix, name)				\
42962306a36Sopenharmony_cistatic ssize_t __iscsi_##prefix##_##name##_show(				\
43062306a36Sopenharmony_ci	struct iscsi_node_acl *nacl,					\
43162306a36Sopenharmony_ci	char *page)							\
43262306a36Sopenharmony_ci{									\
43362306a36Sopenharmony_ci	struct iscsi_node_auth *auth = &nacl->node_auth;		\
43462306a36Sopenharmony_ci									\
43562306a36Sopenharmony_ci	if (!capable(CAP_SYS_ADMIN))					\
43662306a36Sopenharmony_ci		return -EPERM;						\
43762306a36Sopenharmony_ci									\
43862306a36Sopenharmony_ci	return snprintf(page, PAGE_SIZE, "%d\n", auth->name);		\
43962306a36Sopenharmony_ci}
44062306a36Sopenharmony_ci
44162306a36Sopenharmony_ci#define DEF_NACL_AUTH_INT(name)						\
44262306a36Sopenharmony_ci	__DEF_NACL_AUTH_INT(nacl_auth, name)				\
44362306a36Sopenharmony_cistatic ssize_t iscsi_nacl_auth_##name##_show(struct config_item *item,	\
44462306a36Sopenharmony_ci		char *page)						\
44562306a36Sopenharmony_ci{									\
44662306a36Sopenharmony_ci	struct se_node_acl *nacl = auth_to_nacl(item);			\
44762306a36Sopenharmony_ci	return __iscsi_nacl_auth_##name##_show(to_iscsi_nacl(nacl), page);	\
44862306a36Sopenharmony_ci}									\
44962306a36Sopenharmony_ci									\
45062306a36Sopenharmony_ciCONFIGFS_ATTR_RO(iscsi_nacl_auth_, name)
45162306a36Sopenharmony_ci
45262306a36Sopenharmony_ciDEF_NACL_AUTH_INT(authenticate_target);
45362306a36Sopenharmony_ci
45462306a36Sopenharmony_cistatic struct configfs_attribute *lio_target_nacl_auth_attrs[] = {
45562306a36Sopenharmony_ci	&iscsi_nacl_auth_attr_userid,
45662306a36Sopenharmony_ci	&iscsi_nacl_auth_attr_password,
45762306a36Sopenharmony_ci	&iscsi_nacl_auth_attr_authenticate_target,
45862306a36Sopenharmony_ci	&iscsi_nacl_auth_attr_userid_mutual,
45962306a36Sopenharmony_ci	&iscsi_nacl_auth_attr_password_mutual,
46062306a36Sopenharmony_ci	NULL,
46162306a36Sopenharmony_ci};
46262306a36Sopenharmony_ci
46362306a36Sopenharmony_ci/* End items for lio_target_nacl_auth_cit */
46462306a36Sopenharmony_ci
46562306a36Sopenharmony_ci/* Start items for lio_target_nacl_param_cit */
46662306a36Sopenharmony_ci
46762306a36Sopenharmony_ci#define ISCSI_NACL_PARAM(name)						\
46862306a36Sopenharmony_cistatic ssize_t iscsi_nacl_param_##name##_show(struct config_item *item,	\
46962306a36Sopenharmony_ci		char *page)						\
47062306a36Sopenharmony_ci{									\
47162306a36Sopenharmony_ci	struct se_node_acl *se_nacl = param_to_nacl(item);		\
47262306a36Sopenharmony_ci	struct iscsit_session *sess;					\
47362306a36Sopenharmony_ci	struct se_session *se_sess;					\
47462306a36Sopenharmony_ci	ssize_t rb;							\
47562306a36Sopenharmony_ci									\
47662306a36Sopenharmony_ci	spin_lock_bh(&se_nacl->nacl_sess_lock);				\
47762306a36Sopenharmony_ci	se_sess = se_nacl->nacl_sess;					\
47862306a36Sopenharmony_ci	if (!se_sess) {							\
47962306a36Sopenharmony_ci		rb = snprintf(page, PAGE_SIZE,				\
48062306a36Sopenharmony_ci			"No Active iSCSI Session\n");			\
48162306a36Sopenharmony_ci	} else {							\
48262306a36Sopenharmony_ci		sess = se_sess->fabric_sess_ptr;			\
48362306a36Sopenharmony_ci		rb = snprintf(page, PAGE_SIZE, "%u\n",			\
48462306a36Sopenharmony_ci			(u32)sess->sess_ops->name);			\
48562306a36Sopenharmony_ci	}								\
48662306a36Sopenharmony_ci	spin_unlock_bh(&se_nacl->nacl_sess_lock);			\
48762306a36Sopenharmony_ci									\
48862306a36Sopenharmony_ci	return rb;							\
48962306a36Sopenharmony_ci}									\
49062306a36Sopenharmony_ci									\
49162306a36Sopenharmony_ciCONFIGFS_ATTR_RO(iscsi_nacl_param_, name)
49262306a36Sopenharmony_ci
49362306a36Sopenharmony_ciISCSI_NACL_PARAM(MaxConnections);
49462306a36Sopenharmony_ciISCSI_NACL_PARAM(InitialR2T);
49562306a36Sopenharmony_ciISCSI_NACL_PARAM(ImmediateData);
49662306a36Sopenharmony_ciISCSI_NACL_PARAM(MaxBurstLength);
49762306a36Sopenharmony_ciISCSI_NACL_PARAM(FirstBurstLength);
49862306a36Sopenharmony_ciISCSI_NACL_PARAM(DefaultTime2Wait);
49962306a36Sopenharmony_ciISCSI_NACL_PARAM(DefaultTime2Retain);
50062306a36Sopenharmony_ciISCSI_NACL_PARAM(MaxOutstandingR2T);
50162306a36Sopenharmony_ciISCSI_NACL_PARAM(DataPDUInOrder);
50262306a36Sopenharmony_ciISCSI_NACL_PARAM(DataSequenceInOrder);
50362306a36Sopenharmony_ciISCSI_NACL_PARAM(ErrorRecoveryLevel);
50462306a36Sopenharmony_ci
50562306a36Sopenharmony_cistatic struct configfs_attribute *lio_target_nacl_param_attrs[] = {
50662306a36Sopenharmony_ci	&iscsi_nacl_param_attr_MaxConnections,
50762306a36Sopenharmony_ci	&iscsi_nacl_param_attr_InitialR2T,
50862306a36Sopenharmony_ci	&iscsi_nacl_param_attr_ImmediateData,
50962306a36Sopenharmony_ci	&iscsi_nacl_param_attr_MaxBurstLength,
51062306a36Sopenharmony_ci	&iscsi_nacl_param_attr_FirstBurstLength,
51162306a36Sopenharmony_ci	&iscsi_nacl_param_attr_DefaultTime2Wait,
51262306a36Sopenharmony_ci	&iscsi_nacl_param_attr_DefaultTime2Retain,
51362306a36Sopenharmony_ci	&iscsi_nacl_param_attr_MaxOutstandingR2T,
51462306a36Sopenharmony_ci	&iscsi_nacl_param_attr_DataPDUInOrder,
51562306a36Sopenharmony_ci	&iscsi_nacl_param_attr_DataSequenceInOrder,
51662306a36Sopenharmony_ci	&iscsi_nacl_param_attr_ErrorRecoveryLevel,
51762306a36Sopenharmony_ci	NULL,
51862306a36Sopenharmony_ci};
51962306a36Sopenharmony_ci
52062306a36Sopenharmony_ci/* End items for lio_target_nacl_param_cit */
52162306a36Sopenharmony_ci
52262306a36Sopenharmony_ci/* Start items for lio_target_acl_cit */
52362306a36Sopenharmony_ci
52462306a36Sopenharmony_cistatic ssize_t lio_target_nacl_info_show(struct config_item *item, char *page)
52562306a36Sopenharmony_ci{
52662306a36Sopenharmony_ci	struct se_node_acl *se_nacl = acl_to_nacl(item);
52762306a36Sopenharmony_ci	struct iscsit_session *sess;
52862306a36Sopenharmony_ci	struct iscsit_conn *conn;
52962306a36Sopenharmony_ci	struct se_session *se_sess;
53062306a36Sopenharmony_ci	ssize_t rb = 0;
53162306a36Sopenharmony_ci	u32 max_cmd_sn;
53262306a36Sopenharmony_ci
53362306a36Sopenharmony_ci	spin_lock_bh(&se_nacl->nacl_sess_lock);
53462306a36Sopenharmony_ci	se_sess = se_nacl->nacl_sess;
53562306a36Sopenharmony_ci	if (!se_sess) {
53662306a36Sopenharmony_ci		rb += sysfs_emit_at(page, rb, "No active iSCSI Session for Initiator"
53762306a36Sopenharmony_ci			" Endpoint: %s\n", se_nacl->initiatorname);
53862306a36Sopenharmony_ci	} else {
53962306a36Sopenharmony_ci		sess = se_sess->fabric_sess_ptr;
54062306a36Sopenharmony_ci
54162306a36Sopenharmony_ci		rb += sysfs_emit_at(page, rb, "InitiatorName: %s\n",
54262306a36Sopenharmony_ci			sess->sess_ops->InitiatorName);
54362306a36Sopenharmony_ci		rb += sysfs_emit_at(page, rb, "InitiatorAlias: %s\n",
54462306a36Sopenharmony_ci			sess->sess_ops->InitiatorAlias);
54562306a36Sopenharmony_ci
54662306a36Sopenharmony_ci		rb += sysfs_emit_at(page, rb,
54762306a36Sopenharmony_ci			      "LIO Session ID: %u   ISID: 0x%6ph  TSIH: %hu  ",
54862306a36Sopenharmony_ci			      sess->sid, sess->isid, sess->tsih);
54962306a36Sopenharmony_ci		rb += sysfs_emit_at(page, rb, "SessionType: %s\n",
55062306a36Sopenharmony_ci				(sess->sess_ops->SessionType) ?
55162306a36Sopenharmony_ci				"Discovery" : "Normal");
55262306a36Sopenharmony_ci		rb += sysfs_emit_at(page, rb, "Session State: ");
55362306a36Sopenharmony_ci		switch (sess->session_state) {
55462306a36Sopenharmony_ci		case TARG_SESS_STATE_FREE:
55562306a36Sopenharmony_ci			rb += sysfs_emit_at(page, rb, "TARG_SESS_FREE\n");
55662306a36Sopenharmony_ci			break;
55762306a36Sopenharmony_ci		case TARG_SESS_STATE_ACTIVE:
55862306a36Sopenharmony_ci			rb += sysfs_emit_at(page, rb, "TARG_SESS_STATE_ACTIVE\n");
55962306a36Sopenharmony_ci			break;
56062306a36Sopenharmony_ci		case TARG_SESS_STATE_LOGGED_IN:
56162306a36Sopenharmony_ci			rb += sysfs_emit_at(page, rb, "TARG_SESS_STATE_LOGGED_IN\n");
56262306a36Sopenharmony_ci			break;
56362306a36Sopenharmony_ci		case TARG_SESS_STATE_FAILED:
56462306a36Sopenharmony_ci			rb += sysfs_emit_at(page, rb, "TARG_SESS_STATE_FAILED\n");
56562306a36Sopenharmony_ci			break;
56662306a36Sopenharmony_ci		case TARG_SESS_STATE_IN_CONTINUE:
56762306a36Sopenharmony_ci			rb += sysfs_emit_at(page, rb, "TARG_SESS_STATE_IN_CONTINUE\n");
56862306a36Sopenharmony_ci			break;
56962306a36Sopenharmony_ci		default:
57062306a36Sopenharmony_ci			rb += sysfs_emit_at(page, rb, "ERROR: Unknown Session"
57162306a36Sopenharmony_ci					" State!\n");
57262306a36Sopenharmony_ci			break;
57362306a36Sopenharmony_ci		}
57462306a36Sopenharmony_ci
57562306a36Sopenharmony_ci		rb += sysfs_emit_at(page, rb, "---------------------[iSCSI Session"
57662306a36Sopenharmony_ci				" Values]-----------------------\n");
57762306a36Sopenharmony_ci		rb += sysfs_emit_at(page, rb, "  CmdSN/WR  :  CmdSN/WC  :  ExpCmdSN"
57862306a36Sopenharmony_ci				"  :  MaxCmdSN  :     ITT    :     TTT\n");
57962306a36Sopenharmony_ci		max_cmd_sn = (u32) atomic_read(&sess->max_cmd_sn);
58062306a36Sopenharmony_ci		rb += sysfs_emit_at(page, rb, " 0x%08x   0x%08x   0x%08x   0x%08x"
58162306a36Sopenharmony_ci				"   0x%08x   0x%08x\n",
58262306a36Sopenharmony_ci			sess->cmdsn_window,
58362306a36Sopenharmony_ci			(max_cmd_sn - sess->exp_cmd_sn) + 1,
58462306a36Sopenharmony_ci			sess->exp_cmd_sn, max_cmd_sn,
58562306a36Sopenharmony_ci			sess->init_task_tag, sess->targ_xfer_tag);
58662306a36Sopenharmony_ci		rb += sysfs_emit_at(page, rb, "----------------------[iSCSI"
58762306a36Sopenharmony_ci				" Connections]-------------------------\n");
58862306a36Sopenharmony_ci
58962306a36Sopenharmony_ci		spin_lock(&sess->conn_lock);
59062306a36Sopenharmony_ci		list_for_each_entry(conn, &sess->sess_conn_list, conn_list) {
59162306a36Sopenharmony_ci			rb += sysfs_emit_at(page, rb, "CID: %hu  Connection"
59262306a36Sopenharmony_ci					" State: ", conn->cid);
59362306a36Sopenharmony_ci			switch (conn->conn_state) {
59462306a36Sopenharmony_ci			case TARG_CONN_STATE_FREE:
59562306a36Sopenharmony_ci				rb += sysfs_emit_at(page, rb,
59662306a36Sopenharmony_ci					"TARG_CONN_STATE_FREE\n");
59762306a36Sopenharmony_ci				break;
59862306a36Sopenharmony_ci			case TARG_CONN_STATE_XPT_UP:
59962306a36Sopenharmony_ci				rb += sysfs_emit_at(page, rb,
60062306a36Sopenharmony_ci					"TARG_CONN_STATE_XPT_UP\n");
60162306a36Sopenharmony_ci				break;
60262306a36Sopenharmony_ci			case TARG_CONN_STATE_IN_LOGIN:
60362306a36Sopenharmony_ci				rb += sysfs_emit_at(page, rb,
60462306a36Sopenharmony_ci					"TARG_CONN_STATE_IN_LOGIN\n");
60562306a36Sopenharmony_ci				break;
60662306a36Sopenharmony_ci			case TARG_CONN_STATE_LOGGED_IN:
60762306a36Sopenharmony_ci				rb += sysfs_emit_at(page, rb,
60862306a36Sopenharmony_ci					"TARG_CONN_STATE_LOGGED_IN\n");
60962306a36Sopenharmony_ci				break;
61062306a36Sopenharmony_ci			case TARG_CONN_STATE_IN_LOGOUT:
61162306a36Sopenharmony_ci				rb += sysfs_emit_at(page, rb,
61262306a36Sopenharmony_ci					"TARG_CONN_STATE_IN_LOGOUT\n");
61362306a36Sopenharmony_ci				break;
61462306a36Sopenharmony_ci			case TARG_CONN_STATE_LOGOUT_REQUESTED:
61562306a36Sopenharmony_ci				rb += sysfs_emit_at(page, rb,
61662306a36Sopenharmony_ci					"TARG_CONN_STATE_LOGOUT_REQUESTED\n");
61762306a36Sopenharmony_ci				break;
61862306a36Sopenharmony_ci			case TARG_CONN_STATE_CLEANUP_WAIT:
61962306a36Sopenharmony_ci				rb += sysfs_emit_at(page, rb,
62062306a36Sopenharmony_ci					"TARG_CONN_STATE_CLEANUP_WAIT\n");
62162306a36Sopenharmony_ci				break;
62262306a36Sopenharmony_ci			default:
62362306a36Sopenharmony_ci				rb += sysfs_emit_at(page, rb,
62462306a36Sopenharmony_ci					"ERROR: Unknown Connection State!\n");
62562306a36Sopenharmony_ci				break;
62662306a36Sopenharmony_ci			}
62762306a36Sopenharmony_ci
62862306a36Sopenharmony_ci			rb += sysfs_emit_at(page, rb, "   Address %pISc %s", &conn->login_sockaddr,
62962306a36Sopenharmony_ci				(conn->network_transport == ISCSI_TCP) ?
63062306a36Sopenharmony_ci				"TCP" : "SCTP");
63162306a36Sopenharmony_ci			rb += sysfs_emit_at(page, rb, "  StatSN: 0x%08x\n",
63262306a36Sopenharmony_ci				conn->stat_sn);
63362306a36Sopenharmony_ci		}
63462306a36Sopenharmony_ci		spin_unlock(&sess->conn_lock);
63562306a36Sopenharmony_ci	}
63662306a36Sopenharmony_ci	spin_unlock_bh(&se_nacl->nacl_sess_lock);
63762306a36Sopenharmony_ci
63862306a36Sopenharmony_ci	return rb;
63962306a36Sopenharmony_ci}
64062306a36Sopenharmony_ci
64162306a36Sopenharmony_cistatic ssize_t lio_target_nacl_cmdsn_depth_show(struct config_item *item,
64262306a36Sopenharmony_ci		char *page)
64362306a36Sopenharmony_ci{
64462306a36Sopenharmony_ci	return sysfs_emit(page, "%u\n", acl_to_nacl(item)->queue_depth);
64562306a36Sopenharmony_ci}
64662306a36Sopenharmony_ci
64762306a36Sopenharmony_cistatic ssize_t lio_target_nacl_cmdsn_depth_store(struct config_item *item,
64862306a36Sopenharmony_ci		const char *page, size_t count)
64962306a36Sopenharmony_ci{
65062306a36Sopenharmony_ci	struct se_node_acl *se_nacl = acl_to_nacl(item);
65162306a36Sopenharmony_ci	struct se_portal_group *se_tpg = se_nacl->se_tpg;
65262306a36Sopenharmony_ci	struct iscsi_portal_group *tpg = to_iscsi_tpg(se_tpg);
65362306a36Sopenharmony_ci	struct config_item *acl_ci, *tpg_ci, *wwn_ci;
65462306a36Sopenharmony_ci	u32 cmdsn_depth = 0;
65562306a36Sopenharmony_ci	int ret;
65662306a36Sopenharmony_ci
65762306a36Sopenharmony_ci	ret = kstrtou32(page, 0, &cmdsn_depth);
65862306a36Sopenharmony_ci	if (ret)
65962306a36Sopenharmony_ci		return ret;
66062306a36Sopenharmony_ci	if (cmdsn_depth > TA_DEFAULT_CMDSN_DEPTH_MAX) {
66162306a36Sopenharmony_ci		pr_err("Passed cmdsn_depth: %u exceeds"
66262306a36Sopenharmony_ci			" TA_DEFAULT_CMDSN_DEPTH_MAX: %u\n", cmdsn_depth,
66362306a36Sopenharmony_ci			TA_DEFAULT_CMDSN_DEPTH_MAX);
66462306a36Sopenharmony_ci		return -EINVAL;
66562306a36Sopenharmony_ci	}
66662306a36Sopenharmony_ci	acl_ci = &se_nacl->acl_group.cg_item;
66762306a36Sopenharmony_ci	if (!acl_ci) {
66862306a36Sopenharmony_ci		pr_err("Unable to locatel acl_ci\n");
66962306a36Sopenharmony_ci		return -EINVAL;
67062306a36Sopenharmony_ci	}
67162306a36Sopenharmony_ci	tpg_ci = &acl_ci->ci_parent->ci_group->cg_item;
67262306a36Sopenharmony_ci	if (!tpg_ci) {
67362306a36Sopenharmony_ci		pr_err("Unable to locate tpg_ci\n");
67462306a36Sopenharmony_ci		return -EINVAL;
67562306a36Sopenharmony_ci	}
67662306a36Sopenharmony_ci	wwn_ci = &tpg_ci->ci_group->cg_item;
67762306a36Sopenharmony_ci	if (!wwn_ci) {
67862306a36Sopenharmony_ci		pr_err("Unable to locate config_item wwn_ci\n");
67962306a36Sopenharmony_ci		return -EINVAL;
68062306a36Sopenharmony_ci	}
68162306a36Sopenharmony_ci
68262306a36Sopenharmony_ci	if (iscsit_get_tpg(tpg) < 0)
68362306a36Sopenharmony_ci		return -EINVAL;
68462306a36Sopenharmony_ci
68562306a36Sopenharmony_ci	ret = core_tpg_set_initiator_node_queue_depth(se_nacl, cmdsn_depth);
68662306a36Sopenharmony_ci
68762306a36Sopenharmony_ci	pr_debug("LIO_Target_ConfigFS: %s/%s Set CmdSN Window: %u for"
68862306a36Sopenharmony_ci		"InitiatorName: %s\n", config_item_name(wwn_ci),
68962306a36Sopenharmony_ci		config_item_name(tpg_ci), cmdsn_depth,
69062306a36Sopenharmony_ci		config_item_name(acl_ci));
69162306a36Sopenharmony_ci
69262306a36Sopenharmony_ci	iscsit_put_tpg(tpg);
69362306a36Sopenharmony_ci	return (!ret) ? count : (ssize_t)ret;
69462306a36Sopenharmony_ci}
69562306a36Sopenharmony_ci
69662306a36Sopenharmony_cistatic ssize_t lio_target_nacl_tag_show(struct config_item *item, char *page)
69762306a36Sopenharmony_ci{
69862306a36Sopenharmony_ci	return snprintf(page, PAGE_SIZE, "%s", acl_to_nacl(item)->acl_tag);
69962306a36Sopenharmony_ci}
70062306a36Sopenharmony_ci
70162306a36Sopenharmony_cistatic ssize_t lio_target_nacl_tag_store(struct config_item *item,
70262306a36Sopenharmony_ci		const char *page, size_t count)
70362306a36Sopenharmony_ci{
70462306a36Sopenharmony_ci	struct se_node_acl *se_nacl = acl_to_nacl(item);
70562306a36Sopenharmony_ci	int ret;
70662306a36Sopenharmony_ci
70762306a36Sopenharmony_ci	ret = core_tpg_set_initiator_node_tag(se_nacl->se_tpg, se_nacl, page);
70862306a36Sopenharmony_ci
70962306a36Sopenharmony_ci	if (ret < 0)
71062306a36Sopenharmony_ci		return ret;
71162306a36Sopenharmony_ci	return count;
71262306a36Sopenharmony_ci}
71362306a36Sopenharmony_ci
71462306a36Sopenharmony_ciCONFIGFS_ATTR_RO(lio_target_nacl_, info);
71562306a36Sopenharmony_ciCONFIGFS_ATTR(lio_target_nacl_, cmdsn_depth);
71662306a36Sopenharmony_ciCONFIGFS_ATTR(lio_target_nacl_, tag);
71762306a36Sopenharmony_ci
71862306a36Sopenharmony_cistatic struct configfs_attribute *lio_target_initiator_attrs[] = {
71962306a36Sopenharmony_ci	&lio_target_nacl_attr_info,
72062306a36Sopenharmony_ci	&lio_target_nacl_attr_cmdsn_depth,
72162306a36Sopenharmony_ci	&lio_target_nacl_attr_tag,
72262306a36Sopenharmony_ci	NULL,
72362306a36Sopenharmony_ci};
72462306a36Sopenharmony_ci
72562306a36Sopenharmony_cistatic int lio_target_init_nodeacl(struct se_node_acl *se_nacl,
72662306a36Sopenharmony_ci		const char *name)
72762306a36Sopenharmony_ci{
72862306a36Sopenharmony_ci	struct iscsi_node_acl *acl = to_iscsi_nacl(se_nacl);
72962306a36Sopenharmony_ci
73062306a36Sopenharmony_ci	config_group_init_type_name(&acl->node_stat_grps.iscsi_sess_stats_group,
73162306a36Sopenharmony_ci			"iscsi_sess_stats", &iscsi_stat_sess_cit);
73262306a36Sopenharmony_ci	configfs_add_default_group(&acl->node_stat_grps.iscsi_sess_stats_group,
73362306a36Sopenharmony_ci			&se_nacl->acl_fabric_stat_group);
73462306a36Sopenharmony_ci	return 0;
73562306a36Sopenharmony_ci}
73662306a36Sopenharmony_ci
73762306a36Sopenharmony_ci/* End items for lio_target_acl_cit */
73862306a36Sopenharmony_ci
73962306a36Sopenharmony_ci/* Start items for lio_target_tpg_attrib_cit */
74062306a36Sopenharmony_ci
74162306a36Sopenharmony_ci#define DEF_TPG_ATTRIB(name)						\
74262306a36Sopenharmony_ci									\
74362306a36Sopenharmony_cistatic ssize_t iscsi_tpg_attrib_##name##_show(struct config_item *item,	\
74462306a36Sopenharmony_ci		char *page)						\
74562306a36Sopenharmony_ci{									\
74662306a36Sopenharmony_ci	struct se_portal_group *se_tpg = attrib_to_tpg(item);		\
74762306a36Sopenharmony_ci	struct iscsi_portal_group *tpg = to_iscsi_tpg(se_tpg);		\
74862306a36Sopenharmony_ci	ssize_t rb;							\
74962306a36Sopenharmony_ci									\
75062306a36Sopenharmony_ci	if (iscsit_get_tpg(tpg) < 0)					\
75162306a36Sopenharmony_ci		return -EINVAL;						\
75262306a36Sopenharmony_ci									\
75362306a36Sopenharmony_ci	rb = sysfs_emit(page, "%u\n", tpg->tpg_attrib.name);		\
75462306a36Sopenharmony_ci	iscsit_put_tpg(tpg);						\
75562306a36Sopenharmony_ci	return rb;							\
75662306a36Sopenharmony_ci}									\
75762306a36Sopenharmony_ci									\
75862306a36Sopenharmony_cistatic ssize_t iscsi_tpg_attrib_##name##_store(struct config_item *item,\
75962306a36Sopenharmony_ci		const char *page, size_t count)				\
76062306a36Sopenharmony_ci{									\
76162306a36Sopenharmony_ci	struct se_portal_group *se_tpg = attrib_to_tpg(item);		\
76262306a36Sopenharmony_ci	struct iscsi_portal_group *tpg = to_iscsi_tpg(se_tpg);		\
76362306a36Sopenharmony_ci	u32 val;							\
76462306a36Sopenharmony_ci	int ret;							\
76562306a36Sopenharmony_ci									\
76662306a36Sopenharmony_ci	if (iscsit_get_tpg(tpg) < 0)					\
76762306a36Sopenharmony_ci		return -EINVAL;						\
76862306a36Sopenharmony_ci									\
76962306a36Sopenharmony_ci	ret = kstrtou32(page, 0, &val);					\
77062306a36Sopenharmony_ci	if (ret)							\
77162306a36Sopenharmony_ci		goto out;						\
77262306a36Sopenharmony_ci	ret = iscsit_ta_##name(tpg, val);				\
77362306a36Sopenharmony_ci	if (ret < 0)							\
77462306a36Sopenharmony_ci		goto out;						\
77562306a36Sopenharmony_ci									\
77662306a36Sopenharmony_ci	iscsit_put_tpg(tpg);						\
77762306a36Sopenharmony_ci	return count;							\
77862306a36Sopenharmony_ciout:									\
77962306a36Sopenharmony_ci	iscsit_put_tpg(tpg);						\
78062306a36Sopenharmony_ci	return ret;							\
78162306a36Sopenharmony_ci}									\
78262306a36Sopenharmony_ciCONFIGFS_ATTR(iscsi_tpg_attrib_, name)
78362306a36Sopenharmony_ci
78462306a36Sopenharmony_ciDEF_TPG_ATTRIB(authentication);
78562306a36Sopenharmony_ciDEF_TPG_ATTRIB(login_timeout);
78662306a36Sopenharmony_ciDEF_TPG_ATTRIB(generate_node_acls);
78762306a36Sopenharmony_ciDEF_TPG_ATTRIB(default_cmdsn_depth);
78862306a36Sopenharmony_ciDEF_TPG_ATTRIB(cache_dynamic_acls);
78962306a36Sopenharmony_ciDEF_TPG_ATTRIB(demo_mode_write_protect);
79062306a36Sopenharmony_ciDEF_TPG_ATTRIB(prod_mode_write_protect);
79162306a36Sopenharmony_ciDEF_TPG_ATTRIB(demo_mode_discovery);
79262306a36Sopenharmony_ciDEF_TPG_ATTRIB(default_erl);
79362306a36Sopenharmony_ciDEF_TPG_ATTRIB(t10_pi);
79462306a36Sopenharmony_ciDEF_TPG_ATTRIB(fabric_prot_type);
79562306a36Sopenharmony_ciDEF_TPG_ATTRIB(tpg_enabled_sendtargets);
79662306a36Sopenharmony_ciDEF_TPG_ATTRIB(login_keys_workaround);
79762306a36Sopenharmony_ci
79862306a36Sopenharmony_cistatic struct configfs_attribute *lio_target_tpg_attrib_attrs[] = {
79962306a36Sopenharmony_ci	&iscsi_tpg_attrib_attr_authentication,
80062306a36Sopenharmony_ci	&iscsi_tpg_attrib_attr_login_timeout,
80162306a36Sopenharmony_ci	&iscsi_tpg_attrib_attr_generate_node_acls,
80262306a36Sopenharmony_ci	&iscsi_tpg_attrib_attr_default_cmdsn_depth,
80362306a36Sopenharmony_ci	&iscsi_tpg_attrib_attr_cache_dynamic_acls,
80462306a36Sopenharmony_ci	&iscsi_tpg_attrib_attr_demo_mode_write_protect,
80562306a36Sopenharmony_ci	&iscsi_tpg_attrib_attr_prod_mode_write_protect,
80662306a36Sopenharmony_ci	&iscsi_tpg_attrib_attr_demo_mode_discovery,
80762306a36Sopenharmony_ci	&iscsi_tpg_attrib_attr_default_erl,
80862306a36Sopenharmony_ci	&iscsi_tpg_attrib_attr_t10_pi,
80962306a36Sopenharmony_ci	&iscsi_tpg_attrib_attr_fabric_prot_type,
81062306a36Sopenharmony_ci	&iscsi_tpg_attrib_attr_tpg_enabled_sendtargets,
81162306a36Sopenharmony_ci	&iscsi_tpg_attrib_attr_login_keys_workaround,
81262306a36Sopenharmony_ci	NULL,
81362306a36Sopenharmony_ci};
81462306a36Sopenharmony_ci
81562306a36Sopenharmony_ci/* End items for lio_target_tpg_attrib_cit */
81662306a36Sopenharmony_ci
81762306a36Sopenharmony_ci/* Start items for lio_target_tpg_auth_cit */
81862306a36Sopenharmony_ci
81962306a36Sopenharmony_ci#define __DEF_TPG_AUTH_STR(prefix, name, flags)					\
82062306a36Sopenharmony_cistatic ssize_t __iscsi_##prefix##_##name##_show(struct se_portal_group *se_tpg,	\
82162306a36Sopenharmony_ci		char *page)							\
82262306a36Sopenharmony_ci{										\
82362306a36Sopenharmony_ci	struct iscsi_portal_group *tpg = to_iscsi_tpg(se_tpg);			\
82462306a36Sopenharmony_ci	struct iscsi_node_auth *auth = &tpg->tpg_demo_auth;			\
82562306a36Sopenharmony_ci										\
82662306a36Sopenharmony_ci	if (!capable(CAP_SYS_ADMIN))						\
82762306a36Sopenharmony_ci		return -EPERM;							\
82862306a36Sopenharmony_ci										\
82962306a36Sopenharmony_ci	return snprintf(page, PAGE_SIZE, "%s\n", auth->name);			\
83062306a36Sopenharmony_ci}										\
83162306a36Sopenharmony_ci										\
83262306a36Sopenharmony_cistatic ssize_t __iscsi_##prefix##_##name##_store(struct se_portal_group *se_tpg,\
83362306a36Sopenharmony_ci		const char *page, size_t count)					\
83462306a36Sopenharmony_ci{										\
83562306a36Sopenharmony_ci	struct iscsi_portal_group *tpg = to_iscsi_tpg(se_tpg);			\
83662306a36Sopenharmony_ci	struct iscsi_node_auth *auth = &tpg->tpg_demo_auth;			\
83762306a36Sopenharmony_ci										\
83862306a36Sopenharmony_ci	if (!capable(CAP_SYS_ADMIN))						\
83962306a36Sopenharmony_ci		return -EPERM;							\
84062306a36Sopenharmony_ci										\
84162306a36Sopenharmony_ci	snprintf(auth->name, sizeof(auth->name), "%s", page);			\
84262306a36Sopenharmony_ci	if (!(strncmp("NULL", auth->name, 4)))					\
84362306a36Sopenharmony_ci		auth->naf_flags &= ~flags;					\
84462306a36Sopenharmony_ci	else									\
84562306a36Sopenharmony_ci		auth->naf_flags |= flags;					\
84662306a36Sopenharmony_ci										\
84762306a36Sopenharmony_ci	if ((auth->naf_flags & NAF_USERID_IN_SET) &&				\
84862306a36Sopenharmony_ci	    (auth->naf_flags & NAF_PASSWORD_IN_SET))				\
84962306a36Sopenharmony_ci		auth->authenticate_target = 1;					\
85062306a36Sopenharmony_ci	else									\
85162306a36Sopenharmony_ci		auth->authenticate_target = 0;					\
85262306a36Sopenharmony_ci										\
85362306a36Sopenharmony_ci	return count;								\
85462306a36Sopenharmony_ci}
85562306a36Sopenharmony_ci
85662306a36Sopenharmony_ci#define DEF_TPG_AUTH_STR(name, flags)						\
85762306a36Sopenharmony_ci	__DEF_TPG_AUTH_STR(tpg_auth, name, flags)				\
85862306a36Sopenharmony_cistatic ssize_t iscsi_tpg_auth_##name##_show(struct config_item *item,		\
85962306a36Sopenharmony_ci		char *page)							\
86062306a36Sopenharmony_ci{										\
86162306a36Sopenharmony_ci	return __iscsi_tpg_auth_##name##_show(auth_to_tpg(item), page);		\
86262306a36Sopenharmony_ci}										\
86362306a36Sopenharmony_ci										\
86462306a36Sopenharmony_cistatic ssize_t iscsi_tpg_auth_##name##_store(struct config_item *item,		\
86562306a36Sopenharmony_ci		const char *page, size_t count)					\
86662306a36Sopenharmony_ci{										\
86762306a36Sopenharmony_ci	return __iscsi_tpg_auth_##name##_store(auth_to_tpg(item), page, count);	\
86862306a36Sopenharmony_ci}										\
86962306a36Sopenharmony_ci										\
87062306a36Sopenharmony_ciCONFIGFS_ATTR(iscsi_tpg_auth_, name);
87162306a36Sopenharmony_ci
87262306a36Sopenharmony_ci
87362306a36Sopenharmony_ciDEF_TPG_AUTH_STR(userid, NAF_USERID_SET);
87462306a36Sopenharmony_ciDEF_TPG_AUTH_STR(password, NAF_PASSWORD_SET);
87562306a36Sopenharmony_ciDEF_TPG_AUTH_STR(userid_mutual, NAF_USERID_IN_SET);
87662306a36Sopenharmony_ciDEF_TPG_AUTH_STR(password_mutual, NAF_PASSWORD_IN_SET);
87762306a36Sopenharmony_ci
87862306a36Sopenharmony_ci#define __DEF_TPG_AUTH_INT(prefix, name)					\
87962306a36Sopenharmony_cistatic ssize_t __iscsi_##prefix##_##name##_show(struct se_portal_group *se_tpg,	\
88062306a36Sopenharmony_ci		char *page)								\
88162306a36Sopenharmony_ci{										\
88262306a36Sopenharmony_ci	struct iscsi_portal_group *tpg = to_iscsi_tpg(se_tpg);			\
88362306a36Sopenharmony_ci	struct iscsi_node_auth *auth = &tpg->tpg_demo_auth;			\
88462306a36Sopenharmony_ci										\
88562306a36Sopenharmony_ci	if (!capable(CAP_SYS_ADMIN))						\
88662306a36Sopenharmony_ci		return -EPERM;							\
88762306a36Sopenharmony_ci										\
88862306a36Sopenharmony_ci	return snprintf(page, PAGE_SIZE, "%d\n", auth->name);			\
88962306a36Sopenharmony_ci}
89062306a36Sopenharmony_ci
89162306a36Sopenharmony_ci#define DEF_TPG_AUTH_INT(name)							\
89262306a36Sopenharmony_ci	__DEF_TPG_AUTH_INT(tpg_auth, name)					\
89362306a36Sopenharmony_cistatic ssize_t iscsi_tpg_auth_##name##_show(struct config_item *item,		\
89462306a36Sopenharmony_ci		char *page) \
89562306a36Sopenharmony_ci{										\
89662306a36Sopenharmony_ci	return __iscsi_tpg_auth_##name##_show(auth_to_tpg(item), page);		\
89762306a36Sopenharmony_ci}										\
89862306a36Sopenharmony_ciCONFIGFS_ATTR_RO(iscsi_tpg_auth_, name);
89962306a36Sopenharmony_ci
90062306a36Sopenharmony_ciDEF_TPG_AUTH_INT(authenticate_target);
90162306a36Sopenharmony_ci
90262306a36Sopenharmony_cistatic struct configfs_attribute *lio_target_tpg_auth_attrs[] = {
90362306a36Sopenharmony_ci	&iscsi_tpg_auth_attr_userid,
90462306a36Sopenharmony_ci	&iscsi_tpg_auth_attr_password,
90562306a36Sopenharmony_ci	&iscsi_tpg_auth_attr_authenticate_target,
90662306a36Sopenharmony_ci	&iscsi_tpg_auth_attr_userid_mutual,
90762306a36Sopenharmony_ci	&iscsi_tpg_auth_attr_password_mutual,
90862306a36Sopenharmony_ci	NULL,
90962306a36Sopenharmony_ci};
91062306a36Sopenharmony_ci
91162306a36Sopenharmony_ci/* End items for lio_target_tpg_auth_cit */
91262306a36Sopenharmony_ci
91362306a36Sopenharmony_ci/* Start items for lio_target_tpg_param_cit */
91462306a36Sopenharmony_ci
91562306a36Sopenharmony_ci#define DEF_TPG_PARAM(name)						\
91662306a36Sopenharmony_cistatic ssize_t iscsi_tpg_param_##name##_show(struct config_item *item,	\
91762306a36Sopenharmony_ci		char *page)						\
91862306a36Sopenharmony_ci{									\
91962306a36Sopenharmony_ci	struct se_portal_group *se_tpg = param_to_tpg(item);		\
92062306a36Sopenharmony_ci	struct iscsi_portal_group *tpg = to_iscsi_tpg(se_tpg);		\
92162306a36Sopenharmony_ci	struct iscsi_param *param;					\
92262306a36Sopenharmony_ci	ssize_t rb;							\
92362306a36Sopenharmony_ci									\
92462306a36Sopenharmony_ci	if (iscsit_get_tpg(tpg) < 0)					\
92562306a36Sopenharmony_ci		return -EINVAL;						\
92662306a36Sopenharmony_ci									\
92762306a36Sopenharmony_ci	param = iscsi_find_param_from_key(__stringify(name),		\
92862306a36Sopenharmony_ci				tpg->param_list);			\
92962306a36Sopenharmony_ci	if (!param) {							\
93062306a36Sopenharmony_ci		iscsit_put_tpg(tpg);					\
93162306a36Sopenharmony_ci		return -EINVAL;						\
93262306a36Sopenharmony_ci	}								\
93362306a36Sopenharmony_ci	rb = snprintf(page, PAGE_SIZE, "%s\n", param->value);		\
93462306a36Sopenharmony_ci									\
93562306a36Sopenharmony_ci	iscsit_put_tpg(tpg);						\
93662306a36Sopenharmony_ci	return rb;							\
93762306a36Sopenharmony_ci}									\
93862306a36Sopenharmony_cistatic ssize_t iscsi_tpg_param_##name##_store(struct config_item *item, \
93962306a36Sopenharmony_ci		const char *page, size_t count)				\
94062306a36Sopenharmony_ci{									\
94162306a36Sopenharmony_ci	struct se_portal_group *se_tpg = param_to_tpg(item);		\
94262306a36Sopenharmony_ci	struct iscsi_portal_group *tpg = to_iscsi_tpg(se_tpg);		\
94362306a36Sopenharmony_ci	char *buf;							\
94462306a36Sopenharmony_ci	int ret, len;							\
94562306a36Sopenharmony_ci									\
94662306a36Sopenharmony_ci	buf = kzalloc(PAGE_SIZE, GFP_KERNEL);				\
94762306a36Sopenharmony_ci	if (!buf)							\
94862306a36Sopenharmony_ci		return -ENOMEM;						\
94962306a36Sopenharmony_ci	len = snprintf(buf, PAGE_SIZE, "%s=%s", __stringify(name), page);	\
95062306a36Sopenharmony_ci	if (isspace(buf[len-1]))					\
95162306a36Sopenharmony_ci		buf[len-1] = '\0'; /* Kill newline */			\
95262306a36Sopenharmony_ci									\
95362306a36Sopenharmony_ci	if (iscsit_get_tpg(tpg) < 0) {					\
95462306a36Sopenharmony_ci		kfree(buf);						\
95562306a36Sopenharmony_ci		return -EINVAL;						\
95662306a36Sopenharmony_ci	}								\
95762306a36Sopenharmony_ci									\
95862306a36Sopenharmony_ci	ret = iscsi_change_param_value(buf, tpg->param_list, 1);	\
95962306a36Sopenharmony_ci	if (ret < 0)							\
96062306a36Sopenharmony_ci		goto out;						\
96162306a36Sopenharmony_ci									\
96262306a36Sopenharmony_ci	kfree(buf);							\
96362306a36Sopenharmony_ci	iscsit_put_tpg(tpg);						\
96462306a36Sopenharmony_ci	return count;							\
96562306a36Sopenharmony_ciout:									\
96662306a36Sopenharmony_ci	kfree(buf);							\
96762306a36Sopenharmony_ci	iscsit_put_tpg(tpg);						\
96862306a36Sopenharmony_ci	return -EINVAL;							\
96962306a36Sopenharmony_ci}									\
97062306a36Sopenharmony_ciCONFIGFS_ATTR(iscsi_tpg_param_, name)
97162306a36Sopenharmony_ci
97262306a36Sopenharmony_ciDEF_TPG_PARAM(AuthMethod);
97362306a36Sopenharmony_ciDEF_TPG_PARAM(HeaderDigest);
97462306a36Sopenharmony_ciDEF_TPG_PARAM(DataDigest);
97562306a36Sopenharmony_ciDEF_TPG_PARAM(MaxConnections);
97662306a36Sopenharmony_ciDEF_TPG_PARAM(TargetAlias);
97762306a36Sopenharmony_ciDEF_TPG_PARAM(InitialR2T);
97862306a36Sopenharmony_ciDEF_TPG_PARAM(ImmediateData);
97962306a36Sopenharmony_ciDEF_TPG_PARAM(MaxRecvDataSegmentLength);
98062306a36Sopenharmony_ciDEF_TPG_PARAM(MaxXmitDataSegmentLength);
98162306a36Sopenharmony_ciDEF_TPG_PARAM(MaxBurstLength);
98262306a36Sopenharmony_ciDEF_TPG_PARAM(FirstBurstLength);
98362306a36Sopenharmony_ciDEF_TPG_PARAM(DefaultTime2Wait);
98462306a36Sopenharmony_ciDEF_TPG_PARAM(DefaultTime2Retain);
98562306a36Sopenharmony_ciDEF_TPG_PARAM(MaxOutstandingR2T);
98662306a36Sopenharmony_ciDEF_TPG_PARAM(DataPDUInOrder);
98762306a36Sopenharmony_ciDEF_TPG_PARAM(DataSequenceInOrder);
98862306a36Sopenharmony_ciDEF_TPG_PARAM(ErrorRecoveryLevel);
98962306a36Sopenharmony_ciDEF_TPG_PARAM(IFMarker);
99062306a36Sopenharmony_ciDEF_TPG_PARAM(OFMarker);
99162306a36Sopenharmony_ciDEF_TPG_PARAM(IFMarkInt);
99262306a36Sopenharmony_ciDEF_TPG_PARAM(OFMarkInt);
99362306a36Sopenharmony_ci
99462306a36Sopenharmony_cistatic struct configfs_attribute *lio_target_tpg_param_attrs[] = {
99562306a36Sopenharmony_ci	&iscsi_tpg_param_attr_AuthMethod,
99662306a36Sopenharmony_ci	&iscsi_tpg_param_attr_HeaderDigest,
99762306a36Sopenharmony_ci	&iscsi_tpg_param_attr_DataDigest,
99862306a36Sopenharmony_ci	&iscsi_tpg_param_attr_MaxConnections,
99962306a36Sopenharmony_ci	&iscsi_tpg_param_attr_TargetAlias,
100062306a36Sopenharmony_ci	&iscsi_tpg_param_attr_InitialR2T,
100162306a36Sopenharmony_ci	&iscsi_tpg_param_attr_ImmediateData,
100262306a36Sopenharmony_ci	&iscsi_tpg_param_attr_MaxRecvDataSegmentLength,
100362306a36Sopenharmony_ci	&iscsi_tpg_param_attr_MaxXmitDataSegmentLength,
100462306a36Sopenharmony_ci	&iscsi_tpg_param_attr_MaxBurstLength,
100562306a36Sopenharmony_ci	&iscsi_tpg_param_attr_FirstBurstLength,
100662306a36Sopenharmony_ci	&iscsi_tpg_param_attr_DefaultTime2Wait,
100762306a36Sopenharmony_ci	&iscsi_tpg_param_attr_DefaultTime2Retain,
100862306a36Sopenharmony_ci	&iscsi_tpg_param_attr_MaxOutstandingR2T,
100962306a36Sopenharmony_ci	&iscsi_tpg_param_attr_DataPDUInOrder,
101062306a36Sopenharmony_ci	&iscsi_tpg_param_attr_DataSequenceInOrder,
101162306a36Sopenharmony_ci	&iscsi_tpg_param_attr_ErrorRecoveryLevel,
101262306a36Sopenharmony_ci	&iscsi_tpg_param_attr_IFMarker,
101362306a36Sopenharmony_ci	&iscsi_tpg_param_attr_OFMarker,
101462306a36Sopenharmony_ci	&iscsi_tpg_param_attr_IFMarkInt,
101562306a36Sopenharmony_ci	&iscsi_tpg_param_attr_OFMarkInt,
101662306a36Sopenharmony_ci	NULL,
101762306a36Sopenharmony_ci};
101862306a36Sopenharmony_ci
101962306a36Sopenharmony_ci/* End items for lio_target_tpg_param_cit */
102062306a36Sopenharmony_ci
102162306a36Sopenharmony_ci/* Start items for lio_target_tpg_cit */
102262306a36Sopenharmony_ci
102362306a36Sopenharmony_cistatic ssize_t lio_target_tpg_dynamic_sessions_show(struct config_item *item,
102462306a36Sopenharmony_ci		char *page)
102562306a36Sopenharmony_ci{
102662306a36Sopenharmony_ci	return target_show_dynamic_sessions(to_tpg(item), page);
102762306a36Sopenharmony_ci}
102862306a36Sopenharmony_ci
102962306a36Sopenharmony_ciCONFIGFS_ATTR_RO(lio_target_tpg_, dynamic_sessions);
103062306a36Sopenharmony_ci
103162306a36Sopenharmony_cistatic struct configfs_attribute *lio_target_tpg_attrs[] = {
103262306a36Sopenharmony_ci	&lio_target_tpg_attr_dynamic_sessions,
103362306a36Sopenharmony_ci	NULL,
103462306a36Sopenharmony_ci};
103562306a36Sopenharmony_ci
103662306a36Sopenharmony_ci/* End items for lio_target_tpg_cit */
103762306a36Sopenharmony_ci
103862306a36Sopenharmony_ci/* Start items for lio_target_tiqn_cit */
103962306a36Sopenharmony_ci
104062306a36Sopenharmony_cistatic struct se_portal_group *lio_target_tiqn_addtpg(struct se_wwn *wwn,
104162306a36Sopenharmony_ci						      const char *name)
104262306a36Sopenharmony_ci{
104362306a36Sopenharmony_ci	struct iscsi_portal_group *tpg;
104462306a36Sopenharmony_ci	struct iscsi_tiqn *tiqn;
104562306a36Sopenharmony_ci	char *tpgt_str;
104662306a36Sopenharmony_ci	int ret;
104762306a36Sopenharmony_ci	u16 tpgt;
104862306a36Sopenharmony_ci
104962306a36Sopenharmony_ci	tiqn = container_of(wwn, struct iscsi_tiqn, tiqn_wwn);
105062306a36Sopenharmony_ci	/*
105162306a36Sopenharmony_ci	 * Only tpgt_# directory groups can be created below
105262306a36Sopenharmony_ci	 * target/iscsi/iqn.superturodiskarry/
105362306a36Sopenharmony_ci	 */
105462306a36Sopenharmony_ci	tpgt_str = strstr(name, "tpgt_");
105562306a36Sopenharmony_ci	if (!tpgt_str) {
105662306a36Sopenharmony_ci		pr_err("Unable to locate \"tpgt_#\" directory"
105762306a36Sopenharmony_ci				" group\n");
105862306a36Sopenharmony_ci		return NULL;
105962306a36Sopenharmony_ci	}
106062306a36Sopenharmony_ci	tpgt_str += 5; /* Skip ahead of "tpgt_" */
106162306a36Sopenharmony_ci	ret = kstrtou16(tpgt_str, 0, &tpgt);
106262306a36Sopenharmony_ci	if (ret)
106362306a36Sopenharmony_ci		return NULL;
106462306a36Sopenharmony_ci
106562306a36Sopenharmony_ci	tpg = iscsit_alloc_portal_group(tiqn, tpgt);
106662306a36Sopenharmony_ci	if (!tpg)
106762306a36Sopenharmony_ci		return NULL;
106862306a36Sopenharmony_ci
106962306a36Sopenharmony_ci	ret = core_tpg_register(wwn, &tpg->tpg_se_tpg, SCSI_PROTOCOL_ISCSI);
107062306a36Sopenharmony_ci	if (ret < 0)
107162306a36Sopenharmony_ci		goto free_out;
107262306a36Sopenharmony_ci
107362306a36Sopenharmony_ci	ret = iscsit_tpg_add_portal_group(tiqn, tpg);
107462306a36Sopenharmony_ci	if (ret != 0)
107562306a36Sopenharmony_ci		goto out;
107662306a36Sopenharmony_ci
107762306a36Sopenharmony_ci	pr_debug("LIO_Target_ConfigFS: REGISTER -> %s\n", tiqn->tiqn);
107862306a36Sopenharmony_ci	pr_debug("LIO_Target_ConfigFS: REGISTER -> Allocated TPG: %s\n",
107962306a36Sopenharmony_ci			name);
108062306a36Sopenharmony_ci	return &tpg->tpg_se_tpg;
108162306a36Sopenharmony_ciout:
108262306a36Sopenharmony_ci	core_tpg_deregister(&tpg->tpg_se_tpg);
108362306a36Sopenharmony_cifree_out:
108462306a36Sopenharmony_ci	kfree(tpg);
108562306a36Sopenharmony_ci	return NULL;
108662306a36Sopenharmony_ci}
108762306a36Sopenharmony_ci
108862306a36Sopenharmony_cistatic int lio_target_tiqn_enabletpg(struct se_portal_group *se_tpg,
108962306a36Sopenharmony_ci				     bool enable)
109062306a36Sopenharmony_ci{
109162306a36Sopenharmony_ci	struct iscsi_portal_group *tpg = to_iscsi_tpg(se_tpg);
109262306a36Sopenharmony_ci	int ret;
109362306a36Sopenharmony_ci
109462306a36Sopenharmony_ci	ret = iscsit_get_tpg(tpg);
109562306a36Sopenharmony_ci	if (ret < 0)
109662306a36Sopenharmony_ci		return -EINVAL;
109762306a36Sopenharmony_ci
109862306a36Sopenharmony_ci	if (enable) {
109962306a36Sopenharmony_ci		ret = iscsit_tpg_enable_portal_group(tpg);
110062306a36Sopenharmony_ci		if (ret < 0)
110162306a36Sopenharmony_ci			goto out;
110262306a36Sopenharmony_ci	} else {
110362306a36Sopenharmony_ci		/*
110462306a36Sopenharmony_ci		 * iscsit_tpg_disable_portal_group() assumes force=1
110562306a36Sopenharmony_ci		 */
110662306a36Sopenharmony_ci		ret = iscsit_tpg_disable_portal_group(tpg, 1);
110762306a36Sopenharmony_ci		if (ret < 0)
110862306a36Sopenharmony_ci			goto out;
110962306a36Sopenharmony_ci	}
111062306a36Sopenharmony_ci
111162306a36Sopenharmony_ci	iscsit_put_tpg(tpg);
111262306a36Sopenharmony_ci	return 0;
111362306a36Sopenharmony_ciout:
111462306a36Sopenharmony_ci	iscsit_put_tpg(tpg);
111562306a36Sopenharmony_ci	return -EINVAL;
111662306a36Sopenharmony_ci}
111762306a36Sopenharmony_ci
111862306a36Sopenharmony_cistatic void lio_target_tiqn_deltpg(struct se_portal_group *se_tpg)
111962306a36Sopenharmony_ci{
112062306a36Sopenharmony_ci	struct iscsi_portal_group *tpg;
112162306a36Sopenharmony_ci	struct iscsi_tiqn *tiqn;
112262306a36Sopenharmony_ci
112362306a36Sopenharmony_ci	tpg = to_iscsi_tpg(se_tpg);
112462306a36Sopenharmony_ci	tiqn = tpg->tpg_tiqn;
112562306a36Sopenharmony_ci	/*
112662306a36Sopenharmony_ci	 * iscsit_tpg_del_portal_group() assumes force=1
112762306a36Sopenharmony_ci	 */
112862306a36Sopenharmony_ci	pr_debug("LIO_Target_ConfigFS: DEREGISTER -> Releasing TPG\n");
112962306a36Sopenharmony_ci	iscsit_tpg_del_portal_group(tiqn, tpg, 1);
113062306a36Sopenharmony_ci}
113162306a36Sopenharmony_ci
113262306a36Sopenharmony_ci/* End items for lio_target_tiqn_cit */
113362306a36Sopenharmony_ci
113462306a36Sopenharmony_ci/* Start LIO-Target TIQN struct contig_item lio_target_cit */
113562306a36Sopenharmony_ci
113662306a36Sopenharmony_cistatic ssize_t lio_target_wwn_lio_version_show(struct config_item *item,
113762306a36Sopenharmony_ci		char *page)
113862306a36Sopenharmony_ci{
113962306a36Sopenharmony_ci	return sysfs_emit(page, "Datera Inc. iSCSI Target %s\n", ISCSIT_VERSION);
114062306a36Sopenharmony_ci}
114162306a36Sopenharmony_ci
114262306a36Sopenharmony_ciCONFIGFS_ATTR_RO(lio_target_wwn_, lio_version);
114362306a36Sopenharmony_ci
114462306a36Sopenharmony_cistatic ssize_t lio_target_wwn_cpus_allowed_list_show(
114562306a36Sopenharmony_ci		struct config_item *item, char *page)
114662306a36Sopenharmony_ci{
114762306a36Sopenharmony_ci	return sysfs_emit(page, "%*pbl\n",
114862306a36Sopenharmony_ci		       cpumask_pr_args(iscsit_global->allowed_cpumask));
114962306a36Sopenharmony_ci}
115062306a36Sopenharmony_ci
115162306a36Sopenharmony_cistatic ssize_t lio_target_wwn_cpus_allowed_list_store(
115262306a36Sopenharmony_ci		struct config_item *item, const char *page, size_t count)
115362306a36Sopenharmony_ci{
115462306a36Sopenharmony_ci	int ret = -ENOMEM;
115562306a36Sopenharmony_ci	char *orig;
115662306a36Sopenharmony_ci	cpumask_var_t new_allowed_cpumask;
115762306a36Sopenharmony_ci
115862306a36Sopenharmony_ci	if (!zalloc_cpumask_var(&new_allowed_cpumask, GFP_KERNEL))
115962306a36Sopenharmony_ci		goto out;
116062306a36Sopenharmony_ci
116162306a36Sopenharmony_ci	orig = kstrdup(page, GFP_KERNEL);
116262306a36Sopenharmony_ci	if (!orig)
116362306a36Sopenharmony_ci		goto out_free_cpumask;
116462306a36Sopenharmony_ci
116562306a36Sopenharmony_ci	ret = cpulist_parse(orig, new_allowed_cpumask);
116662306a36Sopenharmony_ci	if (!ret)
116762306a36Sopenharmony_ci		cpumask_copy(iscsit_global->allowed_cpumask,
116862306a36Sopenharmony_ci			     new_allowed_cpumask);
116962306a36Sopenharmony_ci
117062306a36Sopenharmony_ci	kfree(orig);
117162306a36Sopenharmony_ciout_free_cpumask:
117262306a36Sopenharmony_ci	free_cpumask_var(new_allowed_cpumask);
117362306a36Sopenharmony_ciout:
117462306a36Sopenharmony_ci	return ret ? ret : count;
117562306a36Sopenharmony_ci}
117662306a36Sopenharmony_ci
117762306a36Sopenharmony_ciCONFIGFS_ATTR(lio_target_wwn_, cpus_allowed_list);
117862306a36Sopenharmony_ci
117962306a36Sopenharmony_cistatic struct configfs_attribute *lio_target_wwn_attrs[] = {
118062306a36Sopenharmony_ci	&lio_target_wwn_attr_lio_version,
118162306a36Sopenharmony_ci	&lio_target_wwn_attr_cpus_allowed_list,
118262306a36Sopenharmony_ci	NULL,
118362306a36Sopenharmony_ci};
118462306a36Sopenharmony_ci
118562306a36Sopenharmony_cistatic struct se_wwn *lio_target_call_coreaddtiqn(
118662306a36Sopenharmony_ci	struct target_fabric_configfs *tf,
118762306a36Sopenharmony_ci	struct config_group *group,
118862306a36Sopenharmony_ci	const char *name)
118962306a36Sopenharmony_ci{
119062306a36Sopenharmony_ci	struct iscsi_tiqn *tiqn;
119162306a36Sopenharmony_ci
119262306a36Sopenharmony_ci	tiqn = iscsit_add_tiqn((unsigned char *)name);
119362306a36Sopenharmony_ci	if (IS_ERR(tiqn))
119462306a36Sopenharmony_ci		return ERR_CAST(tiqn);
119562306a36Sopenharmony_ci
119662306a36Sopenharmony_ci	pr_debug("LIO_Target_ConfigFS: REGISTER -> %s\n", tiqn->tiqn);
119762306a36Sopenharmony_ci	pr_debug("LIO_Target_ConfigFS: REGISTER -> Allocated Node:"
119862306a36Sopenharmony_ci			" %s\n", name);
119962306a36Sopenharmony_ci	return &tiqn->tiqn_wwn;
120062306a36Sopenharmony_ci}
120162306a36Sopenharmony_ci
120262306a36Sopenharmony_cistatic void lio_target_add_wwn_groups(struct se_wwn *wwn)
120362306a36Sopenharmony_ci{
120462306a36Sopenharmony_ci	struct iscsi_tiqn *tiqn = container_of(wwn, struct iscsi_tiqn, tiqn_wwn);
120562306a36Sopenharmony_ci
120662306a36Sopenharmony_ci	config_group_init_type_name(&tiqn->tiqn_stat_grps.iscsi_instance_group,
120762306a36Sopenharmony_ci			"iscsi_instance", &iscsi_stat_instance_cit);
120862306a36Sopenharmony_ci	configfs_add_default_group(&tiqn->tiqn_stat_grps.iscsi_instance_group,
120962306a36Sopenharmony_ci			&tiqn->tiqn_wwn.fabric_stat_group);
121062306a36Sopenharmony_ci
121162306a36Sopenharmony_ci	config_group_init_type_name(&tiqn->tiqn_stat_grps.iscsi_sess_err_group,
121262306a36Sopenharmony_ci			"iscsi_sess_err", &iscsi_stat_sess_err_cit);
121362306a36Sopenharmony_ci	configfs_add_default_group(&tiqn->tiqn_stat_grps.iscsi_sess_err_group,
121462306a36Sopenharmony_ci			&tiqn->tiqn_wwn.fabric_stat_group);
121562306a36Sopenharmony_ci
121662306a36Sopenharmony_ci	config_group_init_type_name(&tiqn->tiqn_stat_grps.iscsi_tgt_attr_group,
121762306a36Sopenharmony_ci			"iscsi_tgt_attr", &iscsi_stat_tgt_attr_cit);
121862306a36Sopenharmony_ci	configfs_add_default_group(&tiqn->tiqn_stat_grps.iscsi_tgt_attr_group,
121962306a36Sopenharmony_ci			&tiqn->tiqn_wwn.fabric_stat_group);
122062306a36Sopenharmony_ci
122162306a36Sopenharmony_ci	config_group_init_type_name(&tiqn->tiqn_stat_grps.iscsi_login_stats_group,
122262306a36Sopenharmony_ci			"iscsi_login_stats", &iscsi_stat_login_cit);
122362306a36Sopenharmony_ci	configfs_add_default_group(&tiqn->tiqn_stat_grps.iscsi_login_stats_group,
122462306a36Sopenharmony_ci			&tiqn->tiqn_wwn.fabric_stat_group);
122562306a36Sopenharmony_ci
122662306a36Sopenharmony_ci	config_group_init_type_name(&tiqn->tiqn_stat_grps.iscsi_logout_stats_group,
122762306a36Sopenharmony_ci			"iscsi_logout_stats", &iscsi_stat_logout_cit);
122862306a36Sopenharmony_ci	configfs_add_default_group(&tiqn->tiqn_stat_grps.iscsi_logout_stats_group,
122962306a36Sopenharmony_ci			&tiqn->tiqn_wwn.fabric_stat_group);
123062306a36Sopenharmony_ci}
123162306a36Sopenharmony_ci
123262306a36Sopenharmony_cistatic void lio_target_call_coredeltiqn(
123362306a36Sopenharmony_ci	struct se_wwn *wwn)
123462306a36Sopenharmony_ci{
123562306a36Sopenharmony_ci	struct iscsi_tiqn *tiqn = container_of(wwn, struct iscsi_tiqn, tiqn_wwn);
123662306a36Sopenharmony_ci
123762306a36Sopenharmony_ci	pr_debug("LIO_Target_ConfigFS: DEREGISTER -> %s\n",
123862306a36Sopenharmony_ci			tiqn->tiqn);
123962306a36Sopenharmony_ci	iscsit_del_tiqn(tiqn);
124062306a36Sopenharmony_ci}
124162306a36Sopenharmony_ci
124262306a36Sopenharmony_ci/* End LIO-Target TIQN struct contig_lio_target_cit */
124362306a36Sopenharmony_ci
124462306a36Sopenharmony_ci/* Start lio_target_discovery_auth_cit */
124562306a36Sopenharmony_ci
124662306a36Sopenharmony_ci#define DEF_DISC_AUTH_STR(name, flags)					\
124762306a36Sopenharmony_ci	__DEF_NACL_AUTH_STR(disc, name, flags)				\
124862306a36Sopenharmony_cistatic ssize_t iscsi_disc_##name##_show(struct config_item *item, char *page) \
124962306a36Sopenharmony_ci{									\
125062306a36Sopenharmony_ci	return __iscsi_disc_##name##_show(&iscsit_global->discovery_acl,\
125162306a36Sopenharmony_ci		page);							\
125262306a36Sopenharmony_ci}									\
125362306a36Sopenharmony_cistatic ssize_t iscsi_disc_##name##_store(struct config_item *item,	\
125462306a36Sopenharmony_ci		const char *page, size_t count)				\
125562306a36Sopenharmony_ci{									\
125662306a36Sopenharmony_ci	return __iscsi_disc_##name##_store(&iscsit_global->discovery_acl,	\
125762306a36Sopenharmony_ci		page, count);						\
125862306a36Sopenharmony_ci									\
125962306a36Sopenharmony_ci}									\
126062306a36Sopenharmony_ciCONFIGFS_ATTR(iscsi_disc_, name)
126162306a36Sopenharmony_ci
126262306a36Sopenharmony_ciDEF_DISC_AUTH_STR(userid, NAF_USERID_SET);
126362306a36Sopenharmony_ciDEF_DISC_AUTH_STR(password, NAF_PASSWORD_SET);
126462306a36Sopenharmony_ciDEF_DISC_AUTH_STR(userid_mutual, NAF_USERID_IN_SET);
126562306a36Sopenharmony_ciDEF_DISC_AUTH_STR(password_mutual, NAF_PASSWORD_IN_SET);
126662306a36Sopenharmony_ci
126762306a36Sopenharmony_ci#define DEF_DISC_AUTH_INT(name)						\
126862306a36Sopenharmony_ci	__DEF_NACL_AUTH_INT(disc, name)					\
126962306a36Sopenharmony_cistatic ssize_t iscsi_disc_##name##_show(struct config_item *item, char *page) \
127062306a36Sopenharmony_ci{									\
127162306a36Sopenharmony_ci	return __iscsi_disc_##name##_show(&iscsit_global->discovery_acl, \
127262306a36Sopenharmony_ci			page);						\
127362306a36Sopenharmony_ci}									\
127462306a36Sopenharmony_ciCONFIGFS_ATTR_RO(iscsi_disc_, name)
127562306a36Sopenharmony_ci
127662306a36Sopenharmony_ciDEF_DISC_AUTH_INT(authenticate_target);
127762306a36Sopenharmony_ci
127862306a36Sopenharmony_ci
127962306a36Sopenharmony_cistatic ssize_t iscsi_disc_enforce_discovery_auth_show(struct config_item *item,
128062306a36Sopenharmony_ci		char *page)
128162306a36Sopenharmony_ci{
128262306a36Sopenharmony_ci	struct iscsi_node_auth *discovery_auth = &iscsit_global->discovery_acl.node_auth;
128362306a36Sopenharmony_ci
128462306a36Sopenharmony_ci	return sysfs_emit(page, "%d\n", discovery_auth->enforce_discovery_auth);
128562306a36Sopenharmony_ci}
128662306a36Sopenharmony_ci
128762306a36Sopenharmony_cistatic ssize_t iscsi_disc_enforce_discovery_auth_store(struct config_item *item,
128862306a36Sopenharmony_ci		const char *page, size_t count)
128962306a36Sopenharmony_ci{
129062306a36Sopenharmony_ci	struct iscsi_param *param;
129162306a36Sopenharmony_ci	struct iscsi_portal_group *discovery_tpg = iscsit_global->discovery_tpg;
129262306a36Sopenharmony_ci	u32 op;
129362306a36Sopenharmony_ci	int err;
129462306a36Sopenharmony_ci
129562306a36Sopenharmony_ci	err = kstrtou32(page, 0, &op);
129662306a36Sopenharmony_ci	if (err)
129762306a36Sopenharmony_ci		return -EINVAL;
129862306a36Sopenharmony_ci	if ((op != 1) && (op != 0)) {
129962306a36Sopenharmony_ci		pr_err("Illegal value for enforce_discovery_auth:"
130062306a36Sopenharmony_ci				" %u\n", op);
130162306a36Sopenharmony_ci		return -EINVAL;
130262306a36Sopenharmony_ci	}
130362306a36Sopenharmony_ci
130462306a36Sopenharmony_ci	if (!discovery_tpg) {
130562306a36Sopenharmony_ci		pr_err("iscsit_global->discovery_tpg is NULL\n");
130662306a36Sopenharmony_ci		return -EINVAL;
130762306a36Sopenharmony_ci	}
130862306a36Sopenharmony_ci
130962306a36Sopenharmony_ci	param = iscsi_find_param_from_key(AUTHMETHOD,
131062306a36Sopenharmony_ci				discovery_tpg->param_list);
131162306a36Sopenharmony_ci	if (!param)
131262306a36Sopenharmony_ci		return -EINVAL;
131362306a36Sopenharmony_ci
131462306a36Sopenharmony_ci	if (op) {
131562306a36Sopenharmony_ci		/*
131662306a36Sopenharmony_ci		 * Reset the AuthMethod key to CHAP.
131762306a36Sopenharmony_ci		 */
131862306a36Sopenharmony_ci		if (iscsi_update_param_value(param, CHAP) < 0)
131962306a36Sopenharmony_ci			return -EINVAL;
132062306a36Sopenharmony_ci
132162306a36Sopenharmony_ci		discovery_tpg->tpg_attrib.authentication = 1;
132262306a36Sopenharmony_ci		iscsit_global->discovery_acl.node_auth.enforce_discovery_auth = 1;
132362306a36Sopenharmony_ci		pr_debug("LIO-CORE[0] Successfully enabled"
132462306a36Sopenharmony_ci			" authentication enforcement for iSCSI"
132562306a36Sopenharmony_ci			" Discovery TPG\n");
132662306a36Sopenharmony_ci	} else {
132762306a36Sopenharmony_ci		/*
132862306a36Sopenharmony_ci		 * Reset the AuthMethod key to CHAP,None
132962306a36Sopenharmony_ci		 */
133062306a36Sopenharmony_ci		if (iscsi_update_param_value(param, "CHAP,None") < 0)
133162306a36Sopenharmony_ci			return -EINVAL;
133262306a36Sopenharmony_ci
133362306a36Sopenharmony_ci		discovery_tpg->tpg_attrib.authentication = 0;
133462306a36Sopenharmony_ci		iscsit_global->discovery_acl.node_auth.enforce_discovery_auth = 0;
133562306a36Sopenharmony_ci		pr_debug("LIO-CORE[0] Successfully disabled"
133662306a36Sopenharmony_ci			" authentication enforcement for iSCSI"
133762306a36Sopenharmony_ci			" Discovery TPG\n");
133862306a36Sopenharmony_ci	}
133962306a36Sopenharmony_ci
134062306a36Sopenharmony_ci	return count;
134162306a36Sopenharmony_ci}
134262306a36Sopenharmony_ci
134362306a36Sopenharmony_ciCONFIGFS_ATTR(iscsi_disc_, enforce_discovery_auth);
134462306a36Sopenharmony_ci
134562306a36Sopenharmony_cistatic struct configfs_attribute *lio_target_discovery_auth_attrs[] = {
134662306a36Sopenharmony_ci	&iscsi_disc_attr_userid,
134762306a36Sopenharmony_ci	&iscsi_disc_attr_password,
134862306a36Sopenharmony_ci	&iscsi_disc_attr_authenticate_target,
134962306a36Sopenharmony_ci	&iscsi_disc_attr_userid_mutual,
135062306a36Sopenharmony_ci	&iscsi_disc_attr_password_mutual,
135162306a36Sopenharmony_ci	&iscsi_disc_attr_enforce_discovery_auth,
135262306a36Sopenharmony_ci	NULL,
135362306a36Sopenharmony_ci};
135462306a36Sopenharmony_ci
135562306a36Sopenharmony_ci/* End lio_target_discovery_auth_cit */
135662306a36Sopenharmony_ci
135762306a36Sopenharmony_ci/* Start functions for target_core_fabric_ops */
135862306a36Sopenharmony_ci
135962306a36Sopenharmony_cistatic int iscsi_get_cmd_state(struct se_cmd *se_cmd)
136062306a36Sopenharmony_ci{
136162306a36Sopenharmony_ci	struct iscsit_cmd *cmd = container_of(se_cmd, struct iscsit_cmd, se_cmd);
136262306a36Sopenharmony_ci
136362306a36Sopenharmony_ci	return cmd->i_state;
136462306a36Sopenharmony_ci}
136562306a36Sopenharmony_ci
136662306a36Sopenharmony_cistatic u32 lio_sess_get_index(struct se_session *se_sess)
136762306a36Sopenharmony_ci{
136862306a36Sopenharmony_ci	struct iscsit_session *sess = se_sess->fabric_sess_ptr;
136962306a36Sopenharmony_ci
137062306a36Sopenharmony_ci	return sess->session_index;
137162306a36Sopenharmony_ci}
137262306a36Sopenharmony_ci
137362306a36Sopenharmony_cistatic u32 lio_sess_get_initiator_sid(
137462306a36Sopenharmony_ci	struct se_session *se_sess,
137562306a36Sopenharmony_ci	unsigned char *buf,
137662306a36Sopenharmony_ci	u32 size)
137762306a36Sopenharmony_ci{
137862306a36Sopenharmony_ci	struct iscsit_session *sess = se_sess->fabric_sess_ptr;
137962306a36Sopenharmony_ci	/*
138062306a36Sopenharmony_ci	 * iSCSI Initiator Session Identifier from RFC-3720.
138162306a36Sopenharmony_ci	 */
138262306a36Sopenharmony_ci	return snprintf(buf, size, "%6phN", sess->isid);
138362306a36Sopenharmony_ci}
138462306a36Sopenharmony_ci
138562306a36Sopenharmony_cistatic int lio_queue_data_in(struct se_cmd *se_cmd)
138662306a36Sopenharmony_ci{
138762306a36Sopenharmony_ci	struct iscsit_cmd *cmd = container_of(se_cmd, struct iscsit_cmd, se_cmd);
138862306a36Sopenharmony_ci	struct iscsit_conn *conn = cmd->conn;
138962306a36Sopenharmony_ci
139062306a36Sopenharmony_ci	cmd->i_state = ISTATE_SEND_DATAIN;
139162306a36Sopenharmony_ci	return conn->conn_transport->iscsit_queue_data_in(conn, cmd);
139262306a36Sopenharmony_ci}
139362306a36Sopenharmony_ci
139462306a36Sopenharmony_cistatic int lio_write_pending(struct se_cmd *se_cmd)
139562306a36Sopenharmony_ci{
139662306a36Sopenharmony_ci	struct iscsit_cmd *cmd = container_of(se_cmd, struct iscsit_cmd, se_cmd);
139762306a36Sopenharmony_ci	struct iscsit_conn *conn = cmd->conn;
139862306a36Sopenharmony_ci
139962306a36Sopenharmony_ci	if (!cmd->immediate_data && !cmd->unsolicited_data)
140062306a36Sopenharmony_ci		return conn->conn_transport->iscsit_get_dataout(conn, cmd, false);
140162306a36Sopenharmony_ci
140262306a36Sopenharmony_ci	return 0;
140362306a36Sopenharmony_ci}
140462306a36Sopenharmony_ci
140562306a36Sopenharmony_cistatic int lio_queue_status(struct se_cmd *se_cmd)
140662306a36Sopenharmony_ci{
140762306a36Sopenharmony_ci	struct iscsit_cmd *cmd = container_of(se_cmd, struct iscsit_cmd, se_cmd);
140862306a36Sopenharmony_ci	struct iscsit_conn *conn = cmd->conn;
140962306a36Sopenharmony_ci
141062306a36Sopenharmony_ci	cmd->i_state = ISTATE_SEND_STATUS;
141162306a36Sopenharmony_ci
141262306a36Sopenharmony_ci	if (cmd->se_cmd.scsi_status || cmd->sense_reason) {
141362306a36Sopenharmony_ci		return iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
141462306a36Sopenharmony_ci	}
141562306a36Sopenharmony_ci	return conn->conn_transport->iscsit_queue_status(conn, cmd);
141662306a36Sopenharmony_ci}
141762306a36Sopenharmony_ci
141862306a36Sopenharmony_cistatic void lio_queue_tm_rsp(struct se_cmd *se_cmd)
141962306a36Sopenharmony_ci{
142062306a36Sopenharmony_ci	struct iscsit_cmd *cmd = container_of(se_cmd, struct iscsit_cmd, se_cmd);
142162306a36Sopenharmony_ci
142262306a36Sopenharmony_ci	cmd->i_state = ISTATE_SEND_TASKMGTRSP;
142362306a36Sopenharmony_ci	iscsit_add_cmd_to_response_queue(cmd, cmd->conn, cmd->i_state);
142462306a36Sopenharmony_ci}
142562306a36Sopenharmony_ci
142662306a36Sopenharmony_cistatic void lio_aborted_task(struct se_cmd *se_cmd)
142762306a36Sopenharmony_ci{
142862306a36Sopenharmony_ci	struct iscsit_cmd *cmd = container_of(se_cmd, struct iscsit_cmd, se_cmd);
142962306a36Sopenharmony_ci
143062306a36Sopenharmony_ci	cmd->conn->conn_transport->iscsit_aborted_task(cmd->conn, cmd);
143162306a36Sopenharmony_ci}
143262306a36Sopenharmony_ci
143362306a36Sopenharmony_cistatic char *lio_tpg_get_endpoint_wwn(struct se_portal_group *se_tpg)
143462306a36Sopenharmony_ci{
143562306a36Sopenharmony_ci	return to_iscsi_tpg(se_tpg)->tpg_tiqn->tiqn;
143662306a36Sopenharmony_ci}
143762306a36Sopenharmony_ci
143862306a36Sopenharmony_cistatic u16 lio_tpg_get_tag(struct se_portal_group *se_tpg)
143962306a36Sopenharmony_ci{
144062306a36Sopenharmony_ci	return to_iscsi_tpg(se_tpg)->tpgt;
144162306a36Sopenharmony_ci}
144262306a36Sopenharmony_ci
144362306a36Sopenharmony_cistatic u32 lio_tpg_get_default_depth(struct se_portal_group *se_tpg)
144462306a36Sopenharmony_ci{
144562306a36Sopenharmony_ci	return to_iscsi_tpg(se_tpg)->tpg_attrib.default_cmdsn_depth;
144662306a36Sopenharmony_ci}
144762306a36Sopenharmony_ci
144862306a36Sopenharmony_cistatic int lio_tpg_check_demo_mode(struct se_portal_group *se_tpg)
144962306a36Sopenharmony_ci{
145062306a36Sopenharmony_ci	return to_iscsi_tpg(se_tpg)->tpg_attrib.generate_node_acls;
145162306a36Sopenharmony_ci}
145262306a36Sopenharmony_ci
145362306a36Sopenharmony_cistatic int lio_tpg_check_demo_mode_cache(struct se_portal_group *se_tpg)
145462306a36Sopenharmony_ci{
145562306a36Sopenharmony_ci	return to_iscsi_tpg(se_tpg)->tpg_attrib.cache_dynamic_acls;
145662306a36Sopenharmony_ci}
145762306a36Sopenharmony_ci
145862306a36Sopenharmony_cistatic int lio_tpg_check_demo_mode_write_protect(
145962306a36Sopenharmony_ci	struct se_portal_group *se_tpg)
146062306a36Sopenharmony_ci{
146162306a36Sopenharmony_ci	return to_iscsi_tpg(se_tpg)->tpg_attrib.demo_mode_write_protect;
146262306a36Sopenharmony_ci}
146362306a36Sopenharmony_ci
146462306a36Sopenharmony_cistatic int lio_tpg_check_prod_mode_write_protect(
146562306a36Sopenharmony_ci	struct se_portal_group *se_tpg)
146662306a36Sopenharmony_ci{
146762306a36Sopenharmony_ci	return to_iscsi_tpg(se_tpg)->tpg_attrib.prod_mode_write_protect;
146862306a36Sopenharmony_ci}
146962306a36Sopenharmony_ci
147062306a36Sopenharmony_cistatic int lio_tpg_check_prot_fabric_only(
147162306a36Sopenharmony_ci	struct se_portal_group *se_tpg)
147262306a36Sopenharmony_ci{
147362306a36Sopenharmony_ci	/*
147462306a36Sopenharmony_ci	 * Only report fabric_prot_type if t10_pi has also been enabled
147562306a36Sopenharmony_ci	 * for incoming ib_isert sessions.
147662306a36Sopenharmony_ci	 */
147762306a36Sopenharmony_ci	if (!to_iscsi_tpg(se_tpg)->tpg_attrib.t10_pi)
147862306a36Sopenharmony_ci		return 0;
147962306a36Sopenharmony_ci	return to_iscsi_tpg(se_tpg)->tpg_attrib.fabric_prot_type;
148062306a36Sopenharmony_ci}
148162306a36Sopenharmony_ci
148262306a36Sopenharmony_ci/*
148362306a36Sopenharmony_ci * This function calls iscsit_inc_session_usage_count() on the
148462306a36Sopenharmony_ci * struct iscsit_session in question.
148562306a36Sopenharmony_ci */
148662306a36Sopenharmony_cistatic void lio_tpg_close_session(struct se_session *se_sess)
148762306a36Sopenharmony_ci{
148862306a36Sopenharmony_ci	struct iscsit_session *sess = se_sess->fabric_sess_ptr;
148962306a36Sopenharmony_ci	struct se_portal_group *se_tpg = &sess->tpg->tpg_se_tpg;
149062306a36Sopenharmony_ci
149162306a36Sopenharmony_ci	spin_lock_bh(&se_tpg->session_lock);
149262306a36Sopenharmony_ci	spin_lock(&sess->conn_lock);
149362306a36Sopenharmony_ci	if (atomic_read(&sess->session_fall_back_to_erl0) ||
149462306a36Sopenharmony_ci	    atomic_read(&sess->session_logout) ||
149562306a36Sopenharmony_ci	    atomic_read(&sess->session_close) ||
149662306a36Sopenharmony_ci	    (sess->time2retain_timer_flags & ISCSI_TF_EXPIRED)) {
149762306a36Sopenharmony_ci		spin_unlock(&sess->conn_lock);
149862306a36Sopenharmony_ci		spin_unlock_bh(&se_tpg->session_lock);
149962306a36Sopenharmony_ci		return;
150062306a36Sopenharmony_ci	}
150162306a36Sopenharmony_ci	iscsit_inc_session_usage_count(sess);
150262306a36Sopenharmony_ci	atomic_set(&sess->session_reinstatement, 1);
150362306a36Sopenharmony_ci	atomic_set(&sess->session_fall_back_to_erl0, 1);
150462306a36Sopenharmony_ci	atomic_set(&sess->session_close, 1);
150562306a36Sopenharmony_ci	spin_unlock(&sess->conn_lock);
150662306a36Sopenharmony_ci
150762306a36Sopenharmony_ci	iscsit_stop_time2retain_timer(sess);
150862306a36Sopenharmony_ci	spin_unlock_bh(&se_tpg->session_lock);
150962306a36Sopenharmony_ci
151062306a36Sopenharmony_ci	iscsit_stop_session(sess, 1, 1);
151162306a36Sopenharmony_ci	iscsit_dec_session_usage_count(sess);
151262306a36Sopenharmony_ci}
151362306a36Sopenharmony_ci
151462306a36Sopenharmony_cistatic u32 lio_tpg_get_inst_index(struct se_portal_group *se_tpg)
151562306a36Sopenharmony_ci{
151662306a36Sopenharmony_ci	return to_iscsi_tpg(se_tpg)->tpg_tiqn->tiqn_index;
151762306a36Sopenharmony_ci}
151862306a36Sopenharmony_ci
151962306a36Sopenharmony_cistatic void lio_set_default_node_attributes(struct se_node_acl *se_acl)
152062306a36Sopenharmony_ci{
152162306a36Sopenharmony_ci	struct iscsi_node_acl *acl = to_iscsi_nacl(se_acl);
152262306a36Sopenharmony_ci	struct se_portal_group *se_tpg = se_acl->se_tpg;
152362306a36Sopenharmony_ci	struct iscsi_portal_group *tpg = to_iscsi_tpg(se_tpg);
152462306a36Sopenharmony_ci
152562306a36Sopenharmony_ci	acl->node_attrib.nacl = acl;
152662306a36Sopenharmony_ci	iscsit_set_default_node_attribues(acl, tpg);
152762306a36Sopenharmony_ci}
152862306a36Sopenharmony_ci
152962306a36Sopenharmony_cistatic int lio_check_stop_free(struct se_cmd *se_cmd)
153062306a36Sopenharmony_ci{
153162306a36Sopenharmony_ci	return target_put_sess_cmd(se_cmd);
153262306a36Sopenharmony_ci}
153362306a36Sopenharmony_ci
153462306a36Sopenharmony_cistatic void lio_release_cmd(struct se_cmd *se_cmd)
153562306a36Sopenharmony_ci{
153662306a36Sopenharmony_ci	struct iscsit_cmd *cmd = container_of(se_cmd, struct iscsit_cmd, se_cmd);
153762306a36Sopenharmony_ci
153862306a36Sopenharmony_ci	pr_debug("Entering lio_release_cmd for se_cmd: %p\n", se_cmd);
153962306a36Sopenharmony_ci	iscsit_release_cmd(cmd);
154062306a36Sopenharmony_ci}
154162306a36Sopenharmony_ci
154262306a36Sopenharmony_ciconst struct target_core_fabric_ops iscsi_ops = {
154362306a36Sopenharmony_ci	.module				= THIS_MODULE,
154462306a36Sopenharmony_ci	.fabric_alias			= "iscsi",
154562306a36Sopenharmony_ci	.fabric_name			= "iSCSI",
154662306a36Sopenharmony_ci	.node_acl_size			= sizeof(struct iscsi_node_acl),
154762306a36Sopenharmony_ci	.tpg_get_wwn			= lio_tpg_get_endpoint_wwn,
154862306a36Sopenharmony_ci	.tpg_get_tag			= lio_tpg_get_tag,
154962306a36Sopenharmony_ci	.tpg_get_default_depth		= lio_tpg_get_default_depth,
155062306a36Sopenharmony_ci	.tpg_check_demo_mode		= lio_tpg_check_demo_mode,
155162306a36Sopenharmony_ci	.tpg_check_demo_mode_cache	= lio_tpg_check_demo_mode_cache,
155262306a36Sopenharmony_ci	.tpg_check_demo_mode_write_protect =
155362306a36Sopenharmony_ci			lio_tpg_check_demo_mode_write_protect,
155462306a36Sopenharmony_ci	.tpg_check_prod_mode_write_protect =
155562306a36Sopenharmony_ci			lio_tpg_check_prod_mode_write_protect,
155662306a36Sopenharmony_ci	.tpg_check_prot_fabric_only	= &lio_tpg_check_prot_fabric_only,
155762306a36Sopenharmony_ci	.tpg_get_inst_index		= lio_tpg_get_inst_index,
155862306a36Sopenharmony_ci	.check_stop_free		= lio_check_stop_free,
155962306a36Sopenharmony_ci	.release_cmd			= lio_release_cmd,
156062306a36Sopenharmony_ci	.close_session			= lio_tpg_close_session,
156162306a36Sopenharmony_ci	.sess_get_index			= lio_sess_get_index,
156262306a36Sopenharmony_ci	.sess_get_initiator_sid		= lio_sess_get_initiator_sid,
156362306a36Sopenharmony_ci	.write_pending			= lio_write_pending,
156462306a36Sopenharmony_ci	.set_default_node_attributes	= lio_set_default_node_attributes,
156562306a36Sopenharmony_ci	.get_cmd_state			= iscsi_get_cmd_state,
156662306a36Sopenharmony_ci	.queue_data_in			= lio_queue_data_in,
156762306a36Sopenharmony_ci	.queue_status			= lio_queue_status,
156862306a36Sopenharmony_ci	.queue_tm_rsp			= lio_queue_tm_rsp,
156962306a36Sopenharmony_ci	.aborted_task			= lio_aborted_task,
157062306a36Sopenharmony_ci	.fabric_make_wwn		= lio_target_call_coreaddtiqn,
157162306a36Sopenharmony_ci	.fabric_drop_wwn		= lio_target_call_coredeltiqn,
157262306a36Sopenharmony_ci	.add_wwn_groups			= lio_target_add_wwn_groups,
157362306a36Sopenharmony_ci	.fabric_make_tpg		= lio_target_tiqn_addtpg,
157462306a36Sopenharmony_ci	.fabric_enable_tpg		= lio_target_tiqn_enabletpg,
157562306a36Sopenharmony_ci	.fabric_drop_tpg		= lio_target_tiqn_deltpg,
157662306a36Sopenharmony_ci	.fabric_make_np			= lio_target_call_addnptotpg,
157762306a36Sopenharmony_ci	.fabric_drop_np			= lio_target_call_delnpfromtpg,
157862306a36Sopenharmony_ci	.fabric_init_nodeacl		= lio_target_init_nodeacl,
157962306a36Sopenharmony_ci
158062306a36Sopenharmony_ci	.tfc_discovery_attrs		= lio_target_discovery_auth_attrs,
158162306a36Sopenharmony_ci	.tfc_wwn_attrs			= lio_target_wwn_attrs,
158262306a36Sopenharmony_ci	.tfc_tpg_base_attrs		= lio_target_tpg_attrs,
158362306a36Sopenharmony_ci	.tfc_tpg_attrib_attrs		= lio_target_tpg_attrib_attrs,
158462306a36Sopenharmony_ci	.tfc_tpg_auth_attrs		= lio_target_tpg_auth_attrs,
158562306a36Sopenharmony_ci	.tfc_tpg_param_attrs		= lio_target_tpg_param_attrs,
158662306a36Sopenharmony_ci	.tfc_tpg_np_base_attrs		= lio_target_portal_attrs,
158762306a36Sopenharmony_ci	.tfc_tpg_nacl_base_attrs	= lio_target_initiator_attrs,
158862306a36Sopenharmony_ci	.tfc_tpg_nacl_attrib_attrs	= lio_target_nacl_attrib_attrs,
158962306a36Sopenharmony_ci	.tfc_tpg_nacl_auth_attrs	= lio_target_nacl_auth_attrs,
159062306a36Sopenharmony_ci	.tfc_tpg_nacl_param_attrs	= lio_target_nacl_param_attrs,
159162306a36Sopenharmony_ci
159262306a36Sopenharmony_ci	.write_pending_must_be_called	= true,
159362306a36Sopenharmony_ci};
1594