1c942fddfSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2e48354ceSNicholas Bellinger /*******************************************************************************
3e48354ceSNicholas Bellinger  * This file contains iSCSI Target Portal Group related functions.
4e48354ceSNicholas Bellinger  *
54c76251eSNicholas Bellinger  * (c) Copyright 2007-2013 Datera, Inc.
6e48354ceSNicholas Bellinger  *
7e48354ceSNicholas Bellinger  * Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
8e48354ceSNicholas Bellinger  *
9e48354ceSNicholas Bellinger  ******************************************************************************/
10e48354ceSNicholas Bellinger 
118dcf07beSBart Van Assche #include <linux/slab.h>
12e48354ceSNicholas Bellinger #include <target/target_core_base.h>
13c4795fb2SChristoph Hellwig #include <target/target_core_fabric.h>
1467f091f2SSagi Grimberg #include <target/iscsi/iscsi_target_core.h>
15e48354ceSNicholas Bellinger #include "iscsi_target_erl0.h"
16e48354ceSNicholas Bellinger #include "iscsi_target_login.h"
17e48354ceSNicholas Bellinger #include "iscsi_target_nodeattrib.h"
18e48354ceSNicholas Bellinger #include "iscsi_target_tpg.h"
19e48354ceSNicholas Bellinger #include "iscsi_target_util.h"
20e48354ceSNicholas Bellinger #include "iscsi_target.h"
21e48354ceSNicholas Bellinger #include "iscsi_target_parameters.h"
22e48354ceSNicholas Bellinger 
23baa4d64bSNicholas Bellinger #include <target/iscsi/iscsi_transport.h>
24baa4d64bSNicholas Bellinger 
iscsit_alloc_portal_group(struct iscsi_tiqn * tiqn,u16 tpgt)25e48354ceSNicholas Bellinger struct iscsi_portal_group *iscsit_alloc_portal_group(struct iscsi_tiqn *tiqn, u16 tpgt)
26e48354ceSNicholas Bellinger {
27e48354ceSNicholas Bellinger 	struct iscsi_portal_group *tpg;
28e48354ceSNicholas Bellinger 
29e48354ceSNicholas Bellinger 	tpg = kzalloc(sizeof(struct iscsi_portal_group), GFP_KERNEL);
30e48354ceSNicholas Bellinger 	if (!tpg) {
31e48354ceSNicholas Bellinger 		pr_err("Unable to allocate struct iscsi_portal_group\n");
32e48354ceSNicholas Bellinger 		return NULL;
33e48354ceSNicholas Bellinger 	}
34e48354ceSNicholas Bellinger 
35e48354ceSNicholas Bellinger 	tpg->tpgt = tpgt;
36e48354ceSNicholas Bellinger 	tpg->tpg_state = TPG_STATE_FREE;
37e48354ceSNicholas Bellinger 	tpg->tpg_tiqn = tiqn;
38e48354ceSNicholas Bellinger 	INIT_LIST_HEAD(&tpg->tpg_gnp_list);
39e48354ceSNicholas Bellinger 	INIT_LIST_HEAD(&tpg->tpg_list);
40e48354ceSNicholas Bellinger 	mutex_init(&tpg->tpg_access_lock);
41a91eb7d9SNicholas Bellinger 	sema_init(&tpg->np_login_sem, 1);
42e48354ceSNicholas Bellinger 	spin_lock_init(&tpg->tpg_state_lock);
43e48354ceSNicholas Bellinger 	spin_lock_init(&tpg->tpg_np_lock);
44e48354ceSNicholas Bellinger 
45e48354ceSNicholas Bellinger 	return tpg;
46e48354ceSNicholas Bellinger }
47e48354ceSNicholas Bellinger 
48e48354ceSNicholas Bellinger static void iscsit_set_default_tpg_attribs(struct iscsi_portal_group *);
49e48354ceSNicholas Bellinger 
iscsit_load_discovery_tpg(void)50e48354ceSNicholas Bellinger int iscsit_load_discovery_tpg(void)
51e48354ceSNicholas Bellinger {
52e48354ceSNicholas Bellinger 	struct iscsi_param *param;
53e48354ceSNicholas Bellinger 	struct iscsi_portal_group *tpg;
54e48354ceSNicholas Bellinger 	int ret;
55e48354ceSNicholas Bellinger 
56e48354ceSNicholas Bellinger 	tpg = iscsit_alloc_portal_group(NULL, 1);
57e48354ceSNicholas Bellinger 	if (!tpg) {
58e48354ceSNicholas Bellinger 		pr_err("Unable to allocate struct iscsi_portal_group\n");
59e48354ceSNicholas Bellinger 		return -1;
60e48354ceSNicholas Bellinger 	}
61bc0c94b1SNicholas Bellinger 	/*
62bc0c94b1SNicholas Bellinger 	 * Save iscsi_ops pointer for special case discovery TPG that
63bc0c94b1SNicholas Bellinger 	 * doesn't exist as se_wwn->wwn_group within configfs.
64bc0c94b1SNicholas Bellinger 	 */
65bc0c94b1SNicholas Bellinger 	tpg->tpg_se_tpg.se_tpg_tfo = &iscsi_ops;
66bc0c94b1SNicholas Bellinger 	ret = core_tpg_register(NULL, &tpg->tpg_se_tpg, -1);
67e48354ceSNicholas Bellinger 	if (ret < 0) {
68e48354ceSNicholas Bellinger 		kfree(tpg);
69e48354ceSNicholas Bellinger 		return -1;
70e48354ceSNicholas Bellinger 	}
71e48354ceSNicholas Bellinger 
72e48354ceSNicholas Bellinger 	tpg->sid = 1; /* First Assigned LIO Session ID */
73e48354ceSNicholas Bellinger 	iscsit_set_default_tpg_attribs(tpg);
74e48354ceSNicholas Bellinger 
75e48354ceSNicholas Bellinger 	if (iscsi_create_default_params(&tpg->param_list) < 0)
76e48354ceSNicholas Bellinger 		goto out;
77e48354ceSNicholas Bellinger 	/*
78e48354ceSNicholas Bellinger 	 * By default we disable authentication for discovery sessions,
79e48354ceSNicholas Bellinger 	 * this can be changed with:
80e48354ceSNicholas Bellinger 	 *
81e48354ceSNicholas Bellinger 	 * /sys/kernel/config/target/iscsi/discovery_auth/enforce_discovery_auth
82e48354ceSNicholas Bellinger 	 */
83e48354ceSNicholas Bellinger 	param = iscsi_find_param_from_key(AUTHMETHOD, tpg->param_list);
84e48354ceSNicholas Bellinger 	if (!param)
85a0884d48Stangwenji 		goto free_pl_out;
86e48354ceSNicholas Bellinger 
87e48354ceSNicholas Bellinger 	if (iscsi_update_param_value(param, "CHAP,None") < 0)
88a0884d48Stangwenji 		goto free_pl_out;
89e48354ceSNicholas Bellinger 
90e48354ceSNicholas Bellinger 	tpg->tpg_attrib.authentication = 0;
91e48354ceSNicholas Bellinger 
92e48354ceSNicholas Bellinger 	spin_lock(&tpg->tpg_state_lock);
93e48354ceSNicholas Bellinger 	tpg->tpg_state  = TPG_STATE_ACTIVE;
94e48354ceSNicholas Bellinger 	spin_unlock(&tpg->tpg_state_lock);
95e48354ceSNicholas Bellinger 
96e48354ceSNicholas Bellinger 	iscsit_global->discovery_tpg = tpg;
97e48354ceSNicholas Bellinger 	pr_debug("CORE[0] - Allocated Discovery TPG\n");
98e48354ceSNicholas Bellinger 
99e48354ceSNicholas Bellinger 	return 0;
100a0884d48Stangwenji free_pl_out:
101a0884d48Stangwenji 	iscsi_release_param_list(tpg->param_list);
102e48354ceSNicholas Bellinger out:
103e48354ceSNicholas Bellinger 	if (tpg->sid == 1)
104e48354ceSNicholas Bellinger 		core_tpg_deregister(&tpg->tpg_se_tpg);
105e48354ceSNicholas Bellinger 	kfree(tpg);
106e48354ceSNicholas Bellinger 	return -1;
107e48354ceSNicholas Bellinger }
108e48354ceSNicholas Bellinger 
iscsit_release_discovery_tpg(void)109e48354ceSNicholas Bellinger void iscsit_release_discovery_tpg(void)
110e48354ceSNicholas Bellinger {
111e48354ceSNicholas Bellinger 	struct iscsi_portal_group *tpg = iscsit_global->discovery_tpg;
112e48354ceSNicholas Bellinger 
113e48354ceSNicholas Bellinger 	if (!tpg)
114e48354ceSNicholas Bellinger 		return;
115e48354ceSNicholas Bellinger 
116a0884d48Stangwenji 	iscsi_release_param_list(tpg->param_list);
117e48354ceSNicholas Bellinger 	core_tpg_deregister(&tpg->tpg_se_tpg);
118e48354ceSNicholas Bellinger 
119e48354ceSNicholas Bellinger 	kfree(tpg);
120e48354ceSNicholas Bellinger 	iscsit_global->discovery_tpg = NULL;
121e48354ceSNicholas Bellinger }
122e48354ceSNicholas Bellinger 
iscsit_get_tpg_from_np(struct iscsi_tiqn * tiqn,struct iscsi_np * np,struct iscsi_tpg_np ** tpg_np_out)123e48354ceSNicholas Bellinger struct iscsi_portal_group *iscsit_get_tpg_from_np(
124e48354ceSNicholas Bellinger 	struct iscsi_tiqn *tiqn,
125d381a801SNicholas Bellinger 	struct iscsi_np *np,
126d381a801SNicholas Bellinger 	struct iscsi_tpg_np **tpg_np_out)
127e48354ceSNicholas Bellinger {
128e48354ceSNicholas Bellinger 	struct iscsi_portal_group *tpg = NULL;
129e48354ceSNicholas Bellinger 	struct iscsi_tpg_np *tpg_np;
130e48354ceSNicholas Bellinger 
131e48354ceSNicholas Bellinger 	spin_lock(&tiqn->tiqn_tpg_lock);
132e48354ceSNicholas Bellinger 	list_for_each_entry(tpg, &tiqn->tiqn_tpg_list, tpg_list) {
133e48354ceSNicholas Bellinger 
134e48354ceSNicholas Bellinger 		spin_lock(&tpg->tpg_state_lock);
135a2a99ceaSNicholas Bellinger 		if (tpg->tpg_state != TPG_STATE_ACTIVE) {
136e48354ceSNicholas Bellinger 			spin_unlock(&tpg->tpg_state_lock);
137e48354ceSNicholas Bellinger 			continue;
138e48354ceSNicholas Bellinger 		}
139e48354ceSNicholas Bellinger 		spin_unlock(&tpg->tpg_state_lock);
140e48354ceSNicholas Bellinger 
141e48354ceSNicholas Bellinger 		spin_lock(&tpg->tpg_np_lock);
142e48354ceSNicholas Bellinger 		list_for_each_entry(tpg_np, &tpg->tpg_gnp_list, tpg_np_list) {
143e48354ceSNicholas Bellinger 			if (tpg_np->tpg_np == np) {
144d381a801SNicholas Bellinger 				*tpg_np_out = tpg_np;
145d381a801SNicholas Bellinger 				kref_get(&tpg_np->tpg_np_kref);
146e48354ceSNicholas Bellinger 				spin_unlock(&tpg->tpg_np_lock);
147e48354ceSNicholas Bellinger 				spin_unlock(&tiqn->tiqn_tpg_lock);
148e48354ceSNicholas Bellinger 				return tpg;
149e48354ceSNicholas Bellinger 			}
150e48354ceSNicholas Bellinger 		}
151e48354ceSNicholas Bellinger 		spin_unlock(&tpg->tpg_np_lock);
152e48354ceSNicholas Bellinger 	}
153e48354ceSNicholas Bellinger 	spin_unlock(&tiqn->tiqn_tpg_lock);
154e48354ceSNicholas Bellinger 
155e48354ceSNicholas Bellinger 	return NULL;
156e48354ceSNicholas Bellinger }
157e48354ceSNicholas Bellinger 
iscsit_get_tpg(struct iscsi_portal_group * tpg)158e48354ceSNicholas Bellinger int iscsit_get_tpg(
159e48354ceSNicholas Bellinger 	struct iscsi_portal_group *tpg)
160e48354ceSNicholas Bellinger {
161ee7619f2SNicholas Bellinger 	return mutex_lock_interruptible(&tpg->tpg_access_lock);
162e48354ceSNicholas Bellinger }
163e48354ceSNicholas Bellinger 
iscsit_put_tpg(struct iscsi_portal_group * tpg)164e48354ceSNicholas Bellinger void iscsit_put_tpg(struct iscsi_portal_group *tpg)
165e48354ceSNicholas Bellinger {
166e48354ceSNicholas Bellinger 	mutex_unlock(&tpg->tpg_access_lock);
167e48354ceSNicholas Bellinger }
168e48354ceSNicholas Bellinger 
iscsit_clear_tpg_np_login_thread(struct iscsi_tpg_np * tpg_np,struct iscsi_portal_group * tpg,bool shutdown)169e48354ceSNicholas Bellinger static void iscsit_clear_tpg_np_login_thread(
170e48354ceSNicholas Bellinger 	struct iscsi_tpg_np *tpg_np,
171a91eb7d9SNicholas Bellinger 	struct iscsi_portal_group *tpg,
172a91eb7d9SNicholas Bellinger 	bool shutdown)
173e48354ceSNicholas Bellinger {
174e48354ceSNicholas Bellinger 	if (!tpg_np->tpg_np) {
175e48354ceSNicholas Bellinger 		pr_err("struct iscsi_tpg_np->tpg_np is NULL!\n");
176e48354ceSNicholas Bellinger 		return;
177e48354ceSNicholas Bellinger 	}
178e48354ceSNicholas Bellinger 
1792363d196SNicholas Bellinger 	if (shutdown)
18014f4b54fSSagi Grimberg 		tpg_np->tpg_np->enabled = false;
181a91eb7d9SNicholas Bellinger 	iscsit_reset_np_thread(tpg_np->tpg_np, tpg_np, tpg, shutdown);
182e48354ceSNicholas Bellinger }
183e48354ceSNicholas Bellinger 
iscsit_clear_tpg_np_login_threads(struct iscsi_portal_group * tpg,bool shutdown)1845256ffdbSNicholas Bellinger static void iscsit_clear_tpg_np_login_threads(
185a91eb7d9SNicholas Bellinger 	struct iscsi_portal_group *tpg,
186a91eb7d9SNicholas Bellinger 	bool shutdown)
187e48354ceSNicholas Bellinger {
188e48354ceSNicholas Bellinger 	struct iscsi_tpg_np *tpg_np;
189e48354ceSNicholas Bellinger 
190e48354ceSNicholas Bellinger 	spin_lock(&tpg->tpg_np_lock);
191e48354ceSNicholas Bellinger 	list_for_each_entry(tpg_np, &tpg->tpg_gnp_list, tpg_np_list) {
192e48354ceSNicholas Bellinger 		if (!tpg_np->tpg_np) {
193e48354ceSNicholas Bellinger 			pr_err("struct iscsi_tpg_np->tpg_np is NULL!\n");
194e48354ceSNicholas Bellinger 			continue;
195e48354ceSNicholas Bellinger 		}
196e48354ceSNicholas Bellinger 		spin_unlock(&tpg->tpg_np_lock);
197a91eb7d9SNicholas Bellinger 		iscsit_clear_tpg_np_login_thread(tpg_np, tpg, shutdown);
198e48354ceSNicholas Bellinger 		spin_lock(&tpg->tpg_np_lock);
199e48354ceSNicholas Bellinger 	}
200e48354ceSNicholas Bellinger 	spin_unlock(&tpg->tpg_np_lock);
201e48354ceSNicholas Bellinger }
202e48354ceSNicholas Bellinger 
iscsit_tpg_dump_params(struct iscsi_portal_group * tpg)203e48354ceSNicholas Bellinger void iscsit_tpg_dump_params(struct iscsi_portal_group *tpg)
204e48354ceSNicholas Bellinger {
205e48354ceSNicholas Bellinger 	iscsi_print_params(tpg->param_list);
206e48354ceSNicholas Bellinger }
207e48354ceSNicholas Bellinger 
iscsit_set_default_tpg_attribs(struct iscsi_portal_group * tpg)208e48354ceSNicholas Bellinger static void iscsit_set_default_tpg_attribs(struct iscsi_portal_group *tpg)
209e48354ceSNicholas Bellinger {
210e48354ceSNicholas Bellinger 	struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
211e48354ceSNicholas Bellinger 
212e48354ceSNicholas Bellinger 	a->authentication = TA_AUTHENTICATION;
213e48354ceSNicholas Bellinger 	a->login_timeout = TA_LOGIN_TIMEOUT;
214e48354ceSNicholas Bellinger 	a->default_cmdsn_depth = TA_DEFAULT_CMDSN_DEPTH;
215e48354ceSNicholas Bellinger 	a->generate_node_acls = TA_GENERATE_NODE_ACLS;
216e48354ceSNicholas Bellinger 	a->cache_dynamic_acls = TA_CACHE_DYNAMIC_ACLS;
217e48354ceSNicholas Bellinger 	a->demo_mode_write_protect = TA_DEMO_MODE_WRITE_PROTECT;
218e48354ceSNicholas Bellinger 	a->prod_mode_write_protect = TA_PROD_MODE_WRITE_PROTECT;
2194c54b6cfSThomas Glanzmann 	a->demo_mode_discovery = TA_DEMO_MODE_DISCOVERY;
220d1fa7a1dSNicholas Bellinger 	a->default_erl = TA_DEFAULT_ERL;
2215b168dcdSSagi Grimberg 	a->t10_pi = TA_DEFAULT_T10_PI;
222901c04a3SNicholas Bellinger 	a->fabric_prot_type = TA_DEFAULT_FABRIC_PROT_TYPE;
223a6415cddSDavid Disseldorp 	a->tpg_enabled_sendtargets = TA_DEFAULT_TPG_ENABLED_SENDTARGETS;
224138d351eSNicholas Bellinger 	a->login_keys_workaround = TA_DEFAULT_LOGIN_KEYS_WORKAROUND;
225e48354ceSNicholas Bellinger }
226e48354ceSNicholas Bellinger 
iscsit_tpg_add_portal_group(struct iscsi_tiqn * tiqn,struct iscsi_portal_group * tpg)227e48354ceSNicholas Bellinger int iscsit_tpg_add_portal_group(struct iscsi_tiqn *tiqn, struct iscsi_portal_group *tpg)
228e48354ceSNicholas Bellinger {
229e48354ceSNicholas Bellinger 	if (tpg->tpg_state != TPG_STATE_FREE) {
230e48354ceSNicholas Bellinger 		pr_err("Unable to add iSCSI Target Portal Group: %d"
231e48354ceSNicholas Bellinger 			" while not in TPG_STATE_FREE state.\n", tpg->tpgt);
232e48354ceSNicholas Bellinger 		return -EEXIST;
233e48354ceSNicholas Bellinger 	}
234e48354ceSNicholas Bellinger 	iscsit_set_default_tpg_attribs(tpg);
235e48354ceSNicholas Bellinger 
236e48354ceSNicholas Bellinger 	if (iscsi_create_default_params(&tpg->param_list) < 0)
237e48354ceSNicholas Bellinger 		goto err_out;
238e48354ceSNicholas Bellinger 
239b7eec2cdSAndy Grover 	tpg->tpg_attrib.tpg = tpg;
240e48354ceSNicholas Bellinger 
241e48354ceSNicholas Bellinger 	spin_lock(&tpg->tpg_state_lock);
242e48354ceSNicholas Bellinger 	tpg->tpg_state	= TPG_STATE_INACTIVE;
243e48354ceSNicholas Bellinger 	spin_unlock(&tpg->tpg_state_lock);
244e48354ceSNicholas Bellinger 
245e48354ceSNicholas Bellinger 	spin_lock(&tiqn->tiqn_tpg_lock);
246e48354ceSNicholas Bellinger 	list_add_tail(&tpg->tpg_list, &tiqn->tiqn_tpg_list);
247e48354ceSNicholas Bellinger 	tiqn->tiqn_ntpgs++;
248e48354ceSNicholas Bellinger 	pr_debug("CORE[%s]_TPG[%hu] - Added iSCSI Target Portal Group\n",
249e48354ceSNicholas Bellinger 			tiqn->tiqn, tpg->tpgt);
250e48354ceSNicholas Bellinger 	spin_unlock(&tiqn->tiqn_tpg_lock);
251e48354ceSNicholas Bellinger 
252e48354ceSNicholas Bellinger 	return 0;
253e48354ceSNicholas Bellinger err_out:
254e48354ceSNicholas Bellinger 	if (tpg->param_list) {
255e48354ceSNicholas Bellinger 		iscsi_release_param_list(tpg->param_list);
256e48354ceSNicholas Bellinger 		tpg->param_list = NULL;
257e48354ceSNicholas Bellinger 	}
258e48354ceSNicholas Bellinger 	return -ENOMEM;
259e48354ceSNicholas Bellinger }
260e48354ceSNicholas Bellinger 
iscsit_tpg_del_portal_group(struct iscsi_tiqn * tiqn,struct iscsi_portal_group * tpg,int force)261e48354ceSNicholas Bellinger int iscsit_tpg_del_portal_group(
262e48354ceSNicholas Bellinger 	struct iscsi_tiqn *tiqn,
263e48354ceSNicholas Bellinger 	struct iscsi_portal_group *tpg,
264e48354ceSNicholas Bellinger 	int force)
265e48354ceSNicholas Bellinger {
266e48354ceSNicholas Bellinger 	u8 old_state = tpg->tpg_state;
267e48354ceSNicholas Bellinger 
268e48354ceSNicholas Bellinger 	spin_lock(&tpg->tpg_state_lock);
269e48354ceSNicholas Bellinger 	tpg->tpg_state = TPG_STATE_INACTIVE;
270e48354ceSNicholas Bellinger 	spin_unlock(&tpg->tpg_state_lock);
271e48354ceSNicholas Bellinger 
272e48354ceSNicholas Bellinger 	if (iscsit_release_sessions_for_tpg(tpg, force) < 0) {
273e48354ceSNicholas Bellinger 		pr_err("Unable to delete iSCSI Target Portal Group:"
274e48354ceSNicholas Bellinger 			" %hu while active sessions exist, and force=0\n",
275e48354ceSNicholas Bellinger 			tpg->tpgt);
276e48354ceSNicholas Bellinger 		tpg->tpg_state = old_state;
277e48354ceSNicholas Bellinger 		return -EPERM;
278e48354ceSNicholas Bellinger 	}
279e48354ceSNicholas Bellinger 
280e48354ceSNicholas Bellinger 	if (tpg->param_list) {
281e48354ceSNicholas Bellinger 		iscsi_release_param_list(tpg->param_list);
282e48354ceSNicholas Bellinger 		tpg->param_list = NULL;
283e48354ceSNicholas Bellinger 	}
284e48354ceSNicholas Bellinger 
285e48354ceSNicholas Bellinger 	core_tpg_deregister(&tpg->tpg_se_tpg);
286e48354ceSNicholas Bellinger 
287e48354ceSNicholas Bellinger 	spin_lock(&tpg->tpg_state_lock);
288e48354ceSNicholas Bellinger 	tpg->tpg_state = TPG_STATE_FREE;
289e48354ceSNicholas Bellinger 	spin_unlock(&tpg->tpg_state_lock);
290e48354ceSNicholas Bellinger 
291e48354ceSNicholas Bellinger 	spin_lock(&tiqn->tiqn_tpg_lock);
292e48354ceSNicholas Bellinger 	tiqn->tiqn_ntpgs--;
293e48354ceSNicholas Bellinger 	list_del(&tpg->tpg_list);
294e48354ceSNicholas Bellinger 	spin_unlock(&tiqn->tiqn_tpg_lock);
295e48354ceSNicholas Bellinger 
296e48354ceSNicholas Bellinger 	pr_debug("CORE[%s]_TPG[%hu] - Deleted iSCSI Target Portal Group\n",
297e48354ceSNicholas Bellinger 			tiqn->tiqn, tpg->tpgt);
298e48354ceSNicholas Bellinger 
299e48354ceSNicholas Bellinger 	kfree(tpg);
300e48354ceSNicholas Bellinger 	return 0;
301e48354ceSNicholas Bellinger }
302e48354ceSNicholas Bellinger 
iscsit_tpg_enable_portal_group(struct iscsi_portal_group * tpg)303e48354ceSNicholas Bellinger int iscsit_tpg_enable_portal_group(struct iscsi_portal_group *tpg)
304e48354ceSNicholas Bellinger {
305e48354ceSNicholas Bellinger 	struct iscsi_param *param;
306e48354ceSNicholas Bellinger 	struct iscsi_tiqn *tiqn = tpg->tpg_tiqn;
307617a0c2eSAndy Grover 	int ret;
308e48354ceSNicholas Bellinger 
309e48354ceSNicholas Bellinger 	if (tpg->tpg_state == TPG_STATE_ACTIVE) {
310e48354ceSNicholas Bellinger 		pr_err("iSCSI target portal group: %hu is already"
311e48354ceSNicholas Bellinger 			" active, ignoring request.\n", tpg->tpgt);
312e48354ceSNicholas Bellinger 		return -EINVAL;
313e48354ceSNicholas Bellinger 	}
314e48354ceSNicholas Bellinger 	/*
315e48354ceSNicholas Bellinger 	 * Make sure that AuthMethod does not contain None as an option
316e48354ceSNicholas Bellinger 	 * unless explictly disabled.  Set the default to CHAP if authentication
317e48354ceSNicholas Bellinger 	 * is enforced (as per default), and remove the NONE option.
318e48354ceSNicholas Bellinger 	 */
319e48354ceSNicholas Bellinger 	param = iscsi_find_param_from_key(AUTHMETHOD, tpg->param_list);
320eceb4459SNicholas Bellinger 	if (!param)
321617a0c2eSAndy Grover 		return -EINVAL;
322e48354ceSNicholas Bellinger 
323b7eec2cdSAndy Grover 	if (tpg->tpg_attrib.authentication) {
324617a0c2eSAndy Grover 		if (!strcmp(param->value, NONE)) {
325617a0c2eSAndy Grover 			ret = iscsi_update_param_value(param, CHAP);
326617a0c2eSAndy Grover 			if (ret)
327617a0c2eSAndy Grover 				goto err;
328e48354ceSNicholas Bellinger 		}
329617a0c2eSAndy Grover 
330617a0c2eSAndy Grover 		ret = iscsit_ta_authentication(tpg, 1);
331617a0c2eSAndy Grover 		if (ret < 0)
332617a0c2eSAndy Grover 			goto err;
333e48354ceSNicholas Bellinger 	}
334e48354ceSNicholas Bellinger 
335eceb4459SNicholas Bellinger 	spin_lock(&tpg->tpg_state_lock);
336e48354ceSNicholas Bellinger 	tpg->tpg_state = TPG_STATE_ACTIVE;
337e48354ceSNicholas Bellinger 	spin_unlock(&tpg->tpg_state_lock);
338e48354ceSNicholas Bellinger 
339e48354ceSNicholas Bellinger 	spin_lock(&tiqn->tiqn_tpg_lock);
340e48354ceSNicholas Bellinger 	tiqn->tiqn_active_tpgs++;
341e48354ceSNicholas Bellinger 	pr_debug("iSCSI_TPG[%hu] - Enabled iSCSI Target Portal Group\n",
342e48354ceSNicholas Bellinger 			tpg->tpgt);
343e48354ceSNicholas Bellinger 	spin_unlock(&tiqn->tiqn_tpg_lock);
344e48354ceSNicholas Bellinger 
345e48354ceSNicholas Bellinger 	return 0;
346617a0c2eSAndy Grover 
347617a0c2eSAndy Grover err:
348617a0c2eSAndy Grover 	return ret;
349e48354ceSNicholas Bellinger }
350e48354ceSNicholas Bellinger 
iscsit_tpg_disable_portal_group(struct iscsi_portal_group * tpg,int force)351e48354ceSNicholas Bellinger int iscsit_tpg_disable_portal_group(struct iscsi_portal_group *tpg, int force)
352e48354ceSNicholas Bellinger {
353e48354ceSNicholas Bellinger 	struct iscsi_tiqn *tiqn;
354e48354ceSNicholas Bellinger 	u8 old_state = tpg->tpg_state;
355e48354ceSNicholas Bellinger 
356e48354ceSNicholas Bellinger 	spin_lock(&tpg->tpg_state_lock);
357e48354ceSNicholas Bellinger 	if (tpg->tpg_state == TPG_STATE_INACTIVE) {
358e48354ceSNicholas Bellinger 		pr_err("iSCSI Target Portal Group: %hu is already"
359e48354ceSNicholas Bellinger 			" inactive, ignoring request.\n", tpg->tpgt);
360e48354ceSNicholas Bellinger 		spin_unlock(&tpg->tpg_state_lock);
361e48354ceSNicholas Bellinger 		return -EINVAL;
362e48354ceSNicholas Bellinger 	}
363e48354ceSNicholas Bellinger 	tpg->tpg_state = TPG_STATE_INACTIVE;
364e48354ceSNicholas Bellinger 	spin_unlock(&tpg->tpg_state_lock);
365e48354ceSNicholas Bellinger 
366a91eb7d9SNicholas Bellinger 	iscsit_clear_tpg_np_login_threads(tpg, false);
367e48354ceSNicholas Bellinger 
368e48354ceSNicholas Bellinger 	if (iscsit_release_sessions_for_tpg(tpg, force) < 0) {
369e48354ceSNicholas Bellinger 		spin_lock(&tpg->tpg_state_lock);
370e48354ceSNicholas Bellinger 		tpg->tpg_state = old_state;
371e48354ceSNicholas Bellinger 		spin_unlock(&tpg->tpg_state_lock);
372e48354ceSNicholas Bellinger 		pr_err("Unable to disable iSCSI Target Portal Group:"
373e48354ceSNicholas Bellinger 			" %hu while active sessions exist, and force=0\n",
374e48354ceSNicholas Bellinger 			tpg->tpgt);
375e48354ceSNicholas Bellinger 		return -EPERM;
376e48354ceSNicholas Bellinger 	}
377e48354ceSNicholas Bellinger 
378e48354ceSNicholas Bellinger 	tiqn = tpg->tpg_tiqn;
379e48354ceSNicholas Bellinger 	if (!tiqn || (tpg == iscsit_global->discovery_tpg))
380e48354ceSNicholas Bellinger 		return 0;
381e48354ceSNicholas Bellinger 
382e48354ceSNicholas Bellinger 	spin_lock(&tiqn->tiqn_tpg_lock);
383e48354ceSNicholas Bellinger 	tiqn->tiqn_active_tpgs--;
384e48354ceSNicholas Bellinger 	pr_debug("iSCSI_TPG[%hu] - Disabled iSCSI Target Portal Group\n",
385e48354ceSNicholas Bellinger 			tpg->tpgt);
386e48354ceSNicholas Bellinger 	spin_unlock(&tiqn->tiqn_tpg_lock);
387e48354ceSNicholas Bellinger 
388e48354ceSNicholas Bellinger 	return 0;
389e48354ceSNicholas Bellinger }
390e48354ceSNicholas Bellinger 
iscsit_tpg_get_node_attrib(struct iscsit_session * sess)391e48354ceSNicholas Bellinger struct iscsi_node_attrib *iscsit_tpg_get_node_attrib(
3920873fe44SMax Gurtovoy 	struct iscsit_session *sess)
393e48354ceSNicholas Bellinger {
394e48354ceSNicholas Bellinger 	struct se_session *se_sess = sess->se_sess;
395e48354ceSNicholas Bellinger 	struct se_node_acl *se_nacl = se_sess->se_node_acl;
396*a11b8069SDmitry Bogdanov 	struct iscsi_node_acl *acl = to_iscsi_nacl(se_nacl);
397e48354ceSNicholas Bellinger 
398e48354ceSNicholas Bellinger 	return &acl->node_attrib;
399e48354ceSNicholas Bellinger }
400e48354ceSNicholas Bellinger 
iscsit_tpg_locate_child_np(struct iscsi_tpg_np * tpg_np,int network_transport)401e48354ceSNicholas Bellinger struct iscsi_tpg_np *iscsit_tpg_locate_child_np(
402e48354ceSNicholas Bellinger 	struct iscsi_tpg_np *tpg_np,
403e48354ceSNicholas Bellinger 	int network_transport)
404e48354ceSNicholas Bellinger {
405e48354ceSNicholas Bellinger 	struct iscsi_tpg_np *tpg_np_child, *tpg_np_child_tmp;
406e48354ceSNicholas Bellinger 
407e48354ceSNicholas Bellinger 	spin_lock(&tpg_np->tpg_np_parent_lock);
408e48354ceSNicholas Bellinger 	list_for_each_entry_safe(tpg_np_child, tpg_np_child_tmp,
409e48354ceSNicholas Bellinger 			&tpg_np->tpg_np_parent_list, tpg_np_child_list) {
410e48354ceSNicholas Bellinger 		if (tpg_np_child->tpg_np->np_network_transport ==
411e48354ceSNicholas Bellinger 				network_transport) {
412e48354ceSNicholas Bellinger 			spin_unlock(&tpg_np->tpg_np_parent_lock);
413e48354ceSNicholas Bellinger 			return tpg_np_child;
414e48354ceSNicholas Bellinger 		}
415e48354ceSNicholas Bellinger 	}
416e48354ceSNicholas Bellinger 	spin_unlock(&tpg_np->tpg_np_parent_lock);
417e48354ceSNicholas Bellinger 
418e48354ceSNicholas Bellinger 	return NULL;
419e48354ceSNicholas Bellinger }
420e48354ceSNicholas Bellinger 
iscsit_tpg_check_network_portal(struct iscsi_tiqn * tiqn,struct sockaddr_storage * sockaddr,int network_transport)4216e545935SNicholas Bellinger static bool iscsit_tpg_check_network_portal(
4226e545935SNicholas Bellinger 	struct iscsi_tiqn *tiqn,
42313a3cf08SAndy Grover 	struct sockaddr_storage *sockaddr,
4246e545935SNicholas Bellinger 	int network_transport)
4256e545935SNicholas Bellinger {
4266e545935SNicholas Bellinger 	struct iscsi_portal_group *tpg;
4276e545935SNicholas Bellinger 	struct iscsi_tpg_np *tpg_np;
4286e545935SNicholas Bellinger 	struct iscsi_np *np;
4296e545935SNicholas Bellinger 	bool match = false;
4306e545935SNicholas Bellinger 
4316e545935SNicholas Bellinger 	spin_lock(&tiqn->tiqn_tpg_lock);
4326e545935SNicholas Bellinger 	list_for_each_entry(tpg, &tiqn->tiqn_tpg_list, tpg_list) {
4336e545935SNicholas Bellinger 
4346e545935SNicholas Bellinger 		spin_lock(&tpg->tpg_np_lock);
4356e545935SNicholas Bellinger 		list_for_each_entry(tpg_np, &tpg->tpg_gnp_list, tpg_np_list) {
4366e545935SNicholas Bellinger 			np = tpg_np->tpg_np;
4376e545935SNicholas Bellinger 
4386e545935SNicholas Bellinger 			match = iscsit_check_np_match(sockaddr, np,
4396e545935SNicholas Bellinger 						network_transport);
4400bcc297eSChristophe Vu-Brugier 			if (match)
4416e545935SNicholas Bellinger 				break;
4426e545935SNicholas Bellinger 		}
4436e545935SNicholas Bellinger 		spin_unlock(&tpg->tpg_np_lock);
444a861790aSZouMingzhe 
445a861790aSZouMingzhe 		if (match)
446a861790aSZouMingzhe 			break;
4476e545935SNicholas Bellinger 	}
4486e545935SNicholas Bellinger 	spin_unlock(&tiqn->tiqn_tpg_lock);
4496e545935SNicholas Bellinger 
4506e545935SNicholas Bellinger 	return match;
4516e545935SNicholas Bellinger }
4526e545935SNicholas Bellinger 
iscsit_tpg_add_network_portal(struct iscsi_portal_group * tpg,struct sockaddr_storage * sockaddr,struct iscsi_tpg_np * tpg_np_parent,int network_transport)453e48354ceSNicholas Bellinger struct iscsi_tpg_np *iscsit_tpg_add_network_portal(
454e48354ceSNicholas Bellinger 	struct iscsi_portal_group *tpg,
45513a3cf08SAndy Grover 	struct sockaddr_storage *sockaddr,
456e48354ceSNicholas Bellinger 	struct iscsi_tpg_np *tpg_np_parent,
457e48354ceSNicholas Bellinger 	int network_transport)
458e48354ceSNicholas Bellinger {
459e48354ceSNicholas Bellinger 	struct iscsi_np *np;
460e48354ceSNicholas Bellinger 	struct iscsi_tpg_np *tpg_np;
461e48354ceSNicholas Bellinger 
4626e545935SNicholas Bellinger 	if (!tpg_np_parent) {
4636e545935SNicholas Bellinger 		if (iscsit_tpg_check_network_portal(tpg->tpg_tiqn, sockaddr,
4640bcc297eSChristophe Vu-Brugier 				network_transport)) {
46576c28f1fSAndy Grover 			pr_err("Network Portal: %pISc already exists on a"
46676c28f1fSAndy Grover 				" different TPG on %s\n", sockaddr,
4676e545935SNicholas Bellinger 				tpg->tpg_tiqn->tiqn);
4686e545935SNicholas Bellinger 			return ERR_PTR(-EEXIST);
4696e545935SNicholas Bellinger 		}
4706e545935SNicholas Bellinger 	}
4716e545935SNicholas Bellinger 
472e48354ceSNicholas Bellinger 	tpg_np = kzalloc(sizeof(struct iscsi_tpg_np), GFP_KERNEL);
473e48354ceSNicholas Bellinger 	if (!tpg_np) {
474e48354ceSNicholas Bellinger 		pr_err("Unable to allocate memory for"
475e48354ceSNicholas Bellinger 				" struct iscsi_tpg_np.\n");
476e48354ceSNicholas Bellinger 		return ERR_PTR(-ENOMEM);
477e48354ceSNicholas Bellinger 	}
478e48354ceSNicholas Bellinger 
47976c28f1fSAndy Grover 	np = iscsit_add_np(sockaddr, network_transport);
480e48354ceSNicholas Bellinger 	if (IS_ERR(np)) {
481e48354ceSNicholas Bellinger 		kfree(tpg_np);
482e48354ceSNicholas Bellinger 		return ERR_CAST(np);
483e48354ceSNicholas Bellinger 	}
484e48354ceSNicholas Bellinger 
485e48354ceSNicholas Bellinger 	INIT_LIST_HEAD(&tpg_np->tpg_np_list);
486e48354ceSNicholas Bellinger 	INIT_LIST_HEAD(&tpg_np->tpg_np_child_list);
487e48354ceSNicholas Bellinger 	INIT_LIST_HEAD(&tpg_np->tpg_np_parent_list);
488e48354ceSNicholas Bellinger 	spin_lock_init(&tpg_np->tpg_np_parent_lock);
489d381a801SNicholas Bellinger 	init_completion(&tpg_np->tpg_np_comp);
490d381a801SNicholas Bellinger 	kref_init(&tpg_np->tpg_np_kref);
491e48354ceSNicholas Bellinger 	tpg_np->tpg_np		= np;
492e48354ceSNicholas Bellinger 	tpg_np->tpg		= tpg;
493e48354ceSNicholas Bellinger 
494e48354ceSNicholas Bellinger 	spin_lock(&tpg->tpg_np_lock);
495e48354ceSNicholas Bellinger 	list_add_tail(&tpg_np->tpg_np_list, &tpg->tpg_gnp_list);
496e48354ceSNicholas Bellinger 	tpg->num_tpg_nps++;
497e48354ceSNicholas Bellinger 	if (tpg->tpg_tiqn)
498e48354ceSNicholas Bellinger 		tpg->tpg_tiqn->tiqn_num_tpg_nps++;
499e48354ceSNicholas Bellinger 	spin_unlock(&tpg->tpg_np_lock);
500e48354ceSNicholas Bellinger 
501e48354ceSNicholas Bellinger 	if (tpg_np_parent) {
502e48354ceSNicholas Bellinger 		tpg_np->tpg_np_parent = tpg_np_parent;
503e48354ceSNicholas Bellinger 		spin_lock(&tpg_np_parent->tpg_np_parent_lock);
504e48354ceSNicholas Bellinger 		list_add_tail(&tpg_np->tpg_np_child_list,
505e48354ceSNicholas Bellinger 			&tpg_np_parent->tpg_np_parent_list);
506e48354ceSNicholas Bellinger 		spin_unlock(&tpg_np_parent->tpg_np_parent_lock);
507e48354ceSNicholas Bellinger 	}
508e48354ceSNicholas Bellinger 
50969d75574SAndy Grover 	pr_debug("CORE[%s] - Added Network Portal: %pISpc,%hu on %s\n",
51069d75574SAndy Grover 		tpg->tpg_tiqn->tiqn, &np->np_sockaddr, tpg->tpgt,
511baa4d64bSNicholas Bellinger 		np->np_transport->name);
512e48354ceSNicholas Bellinger 
513e48354ceSNicholas Bellinger 	return tpg_np;
514e48354ceSNicholas Bellinger }
515e48354ceSNicholas Bellinger 
iscsit_tpg_release_np(struct iscsi_tpg_np * tpg_np,struct iscsi_portal_group * tpg,struct iscsi_np * np)516e48354ceSNicholas Bellinger static int iscsit_tpg_release_np(
517e48354ceSNicholas Bellinger 	struct iscsi_tpg_np *tpg_np,
518e48354ceSNicholas Bellinger 	struct iscsi_portal_group *tpg,
519e48354ceSNicholas Bellinger 	struct iscsi_np *np)
520e48354ceSNicholas Bellinger {
521a91eb7d9SNicholas Bellinger 	iscsit_clear_tpg_np_login_thread(tpg_np, tpg, true);
522e48354ceSNicholas Bellinger 
52369d75574SAndy Grover 	pr_debug("CORE[%s] - Removed Network Portal: %pISpc,%hu on %s\n",
52469d75574SAndy Grover 		tpg->tpg_tiqn->tiqn, &np->np_sockaddr, tpg->tpgt,
525baa4d64bSNicholas Bellinger 		np->np_transport->name);
526e48354ceSNicholas Bellinger 
527e48354ceSNicholas Bellinger 	tpg_np->tpg_np = NULL;
528e48354ceSNicholas Bellinger 	tpg_np->tpg = NULL;
529e48354ceSNicholas Bellinger 	kfree(tpg_np);
530e48354ceSNicholas Bellinger 	/*
531e48354ceSNicholas Bellinger 	 * iscsit_del_np() will shutdown struct iscsi_np when last TPG reference is released.
532e48354ceSNicholas Bellinger 	 */
533e48354ceSNicholas Bellinger 	return iscsit_del_np(np);
534e48354ceSNicholas Bellinger }
535e48354ceSNicholas Bellinger 
iscsit_tpg_del_network_portal(struct iscsi_portal_group * tpg,struct iscsi_tpg_np * tpg_np)536e48354ceSNicholas Bellinger int iscsit_tpg_del_network_portal(
537e48354ceSNicholas Bellinger 	struct iscsi_portal_group *tpg,
538e48354ceSNicholas Bellinger 	struct iscsi_tpg_np *tpg_np)
539e48354ceSNicholas Bellinger {
540e48354ceSNicholas Bellinger 	struct iscsi_np *np;
541e48354ceSNicholas Bellinger 	struct iscsi_tpg_np *tpg_np_child, *tpg_np_child_tmp;
542e48354ceSNicholas Bellinger 	int ret = 0;
543e48354ceSNicholas Bellinger 
544e48354ceSNicholas Bellinger 	np = tpg_np->tpg_np;
545e48354ceSNicholas Bellinger 	if (!np) {
546e48354ceSNicholas Bellinger 		pr_err("Unable to locate struct iscsi_np from"
547e48354ceSNicholas Bellinger 				" struct iscsi_tpg_np\n");
548e48354ceSNicholas Bellinger 		return -EINVAL;
549e48354ceSNicholas Bellinger 	}
550e48354ceSNicholas Bellinger 
551e48354ceSNicholas Bellinger 	if (!tpg_np->tpg_np_parent) {
552e48354ceSNicholas Bellinger 		/*
553e48354ceSNicholas Bellinger 		 * We are the parent tpg network portal.  Release all of the
554e48354ceSNicholas Bellinger 		 * child tpg_np's (eg: the non ISCSI_TCP ones) on our parent
555e48354ceSNicholas Bellinger 		 * list first.
556e48354ceSNicholas Bellinger 		 */
557e48354ceSNicholas Bellinger 		list_for_each_entry_safe(tpg_np_child, tpg_np_child_tmp,
558e48354ceSNicholas Bellinger 				&tpg_np->tpg_np_parent_list,
559e48354ceSNicholas Bellinger 				tpg_np_child_list) {
560e48354ceSNicholas Bellinger 			ret = iscsit_tpg_del_network_portal(tpg, tpg_np_child);
561e48354ceSNicholas Bellinger 			if (ret < 0)
562e48354ceSNicholas Bellinger 				pr_err("iscsit_tpg_del_network_portal()"
563e48354ceSNicholas Bellinger 					" failed: %d\n", ret);
564e48354ceSNicholas Bellinger 		}
565e48354ceSNicholas Bellinger 	} else {
566e48354ceSNicholas Bellinger 		/*
567e48354ceSNicholas Bellinger 		 * We are not the parent ISCSI_TCP tpg network portal.  Release
568e48354ceSNicholas Bellinger 		 * our own network portals from the child list.
569e48354ceSNicholas Bellinger 		 */
570e48354ceSNicholas Bellinger 		spin_lock(&tpg_np->tpg_np_parent->tpg_np_parent_lock);
571e48354ceSNicholas Bellinger 		list_del(&tpg_np->tpg_np_child_list);
572e48354ceSNicholas Bellinger 		spin_unlock(&tpg_np->tpg_np_parent->tpg_np_parent_lock);
573e48354ceSNicholas Bellinger 	}
574e48354ceSNicholas Bellinger 
575e48354ceSNicholas Bellinger 	spin_lock(&tpg->tpg_np_lock);
576e48354ceSNicholas Bellinger 	list_del(&tpg_np->tpg_np_list);
577e48354ceSNicholas Bellinger 	tpg->num_tpg_nps--;
578e48354ceSNicholas Bellinger 	if (tpg->tpg_tiqn)
579e48354ceSNicholas Bellinger 		tpg->tpg_tiqn->tiqn_num_tpg_nps--;
580e48354ceSNicholas Bellinger 	spin_unlock(&tpg->tpg_np_lock);
581e48354ceSNicholas Bellinger 
582e48354ceSNicholas Bellinger 	return iscsit_tpg_release_np(tpg_np, tpg, np);
583e48354ceSNicholas Bellinger }
584e48354ceSNicholas Bellinger 
iscsit_ta_authentication(struct iscsi_portal_group * tpg,u32 authentication)585e48354ceSNicholas Bellinger int iscsit_ta_authentication(struct iscsi_portal_group *tpg, u32 authentication)
586e48354ceSNicholas Bellinger {
587e48354ceSNicholas Bellinger 	unsigned char buf1[256], buf2[256], *none = NULL;
588e48354ceSNicholas Bellinger 	int len;
589e48354ceSNicholas Bellinger 	struct iscsi_param *param;
590e48354ceSNicholas Bellinger 	struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
591e48354ceSNicholas Bellinger 
592e48354ceSNicholas Bellinger 	if ((authentication != 1) && (authentication != 0)) {
593e48354ceSNicholas Bellinger 		pr_err("Illegal value for authentication parameter:"
594e48354ceSNicholas Bellinger 			" %u, ignoring request.\n", authentication);
595617a0c2eSAndy Grover 		return -EINVAL;
596e48354ceSNicholas Bellinger 	}
597e48354ceSNicholas Bellinger 
598e48354ceSNicholas Bellinger 	memset(buf1, 0, sizeof(buf1));
599e48354ceSNicholas Bellinger 	memset(buf2, 0, sizeof(buf2));
600e48354ceSNicholas Bellinger 
601e48354ceSNicholas Bellinger 	param = iscsi_find_param_from_key(AUTHMETHOD, tpg->param_list);
602e48354ceSNicholas Bellinger 	if (!param)
603e48354ceSNicholas Bellinger 		return -EINVAL;
604e48354ceSNicholas Bellinger 
605e48354ceSNicholas Bellinger 	if (authentication) {
606e48354ceSNicholas Bellinger 		snprintf(buf1, sizeof(buf1), "%s", param->value);
607e48354ceSNicholas Bellinger 		none = strstr(buf1, NONE);
608e48354ceSNicholas Bellinger 		if (!none)
609e48354ceSNicholas Bellinger 			goto out;
610e48354ceSNicholas Bellinger 		if (!strncmp(none + 4, ",", 1)) {
611e48354ceSNicholas Bellinger 			if (!strcmp(buf1, none))
612e48354ceSNicholas Bellinger 				sprintf(buf2, "%s", none+5);
613e48354ceSNicholas Bellinger 			else {
614e48354ceSNicholas Bellinger 				none--;
615e48354ceSNicholas Bellinger 				*none = '\0';
616e48354ceSNicholas Bellinger 				len = sprintf(buf2, "%s", buf1);
617e48354ceSNicholas Bellinger 				none += 5;
618e48354ceSNicholas Bellinger 				sprintf(buf2 + len, "%s", none);
619e48354ceSNicholas Bellinger 			}
620e48354ceSNicholas Bellinger 		} else {
621e48354ceSNicholas Bellinger 			none--;
622e48354ceSNicholas Bellinger 			*none = '\0';
623e48354ceSNicholas Bellinger 			sprintf(buf2, "%s", buf1);
624e48354ceSNicholas Bellinger 		}
625e48354ceSNicholas Bellinger 		if (iscsi_update_param_value(param, buf2) < 0)
626e48354ceSNicholas Bellinger 			return -EINVAL;
627e48354ceSNicholas Bellinger 	} else {
628e48354ceSNicholas Bellinger 		snprintf(buf1, sizeof(buf1), "%s", param->value);
629e48354ceSNicholas Bellinger 		none = strstr(buf1, NONE);
630ee1b1b9cSAndy Grover 		if (none)
631e48354ceSNicholas Bellinger 			goto out;
63235bea5c8SBart Van Assche 		strlcat(buf1, "," NONE, sizeof(buf1));
633e48354ceSNicholas Bellinger 		if (iscsi_update_param_value(param, buf1) < 0)
634e48354ceSNicholas Bellinger 			return -EINVAL;
635e48354ceSNicholas Bellinger 	}
636e48354ceSNicholas Bellinger 
637e48354ceSNicholas Bellinger out:
638e48354ceSNicholas Bellinger 	a->authentication = authentication;
639e48354ceSNicholas Bellinger 	pr_debug("%s iSCSI Authentication Methods for TPG: %hu.\n",
640e48354ceSNicholas Bellinger 		a->authentication ? "Enforcing" : "Disabling", tpg->tpgt);
641e48354ceSNicholas Bellinger 
642e48354ceSNicholas Bellinger 	return 0;
643e48354ceSNicholas Bellinger }
644e48354ceSNicholas Bellinger 
iscsit_ta_login_timeout(struct iscsi_portal_group * tpg,u32 login_timeout)645e48354ceSNicholas Bellinger int iscsit_ta_login_timeout(
646e48354ceSNicholas Bellinger 	struct iscsi_portal_group *tpg,
647e48354ceSNicholas Bellinger 	u32 login_timeout)
648e48354ceSNicholas Bellinger {
649e48354ceSNicholas Bellinger 	struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
650e48354ceSNicholas Bellinger 
651e48354ceSNicholas Bellinger 	if (login_timeout > TA_LOGIN_TIMEOUT_MAX) {
652e48354ceSNicholas Bellinger 		pr_err("Requested Login Timeout %u larger than maximum"
653e48354ceSNicholas Bellinger 			" %u\n", login_timeout, TA_LOGIN_TIMEOUT_MAX);
654e48354ceSNicholas Bellinger 		return -EINVAL;
655e48354ceSNicholas Bellinger 	} else if (login_timeout < TA_LOGIN_TIMEOUT_MIN) {
656e48354ceSNicholas Bellinger 		pr_err("Requested Logout Timeout %u smaller than"
657e48354ceSNicholas Bellinger 			" minimum %u\n", login_timeout, TA_LOGIN_TIMEOUT_MIN);
658e48354ceSNicholas Bellinger 		return -EINVAL;
659e48354ceSNicholas Bellinger 	}
660e48354ceSNicholas Bellinger 
661e48354ceSNicholas Bellinger 	a->login_timeout = login_timeout;
662e48354ceSNicholas Bellinger 	pr_debug("Set Logout Timeout to %u for Target Portal Group"
663e48354ceSNicholas Bellinger 		" %hu\n", a->login_timeout, tpg->tpgt);
664e48354ceSNicholas Bellinger 
665e48354ceSNicholas Bellinger 	return 0;
666e48354ceSNicholas Bellinger }
667e48354ceSNicholas Bellinger 
iscsit_ta_generate_node_acls(struct iscsi_portal_group * tpg,u32 flag)668e48354ceSNicholas Bellinger int iscsit_ta_generate_node_acls(
669e48354ceSNicholas Bellinger 	struct iscsi_portal_group *tpg,
670e48354ceSNicholas Bellinger 	u32 flag)
671e48354ceSNicholas Bellinger {
672e48354ceSNicholas Bellinger 	struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
673e48354ceSNicholas Bellinger 
674e48354ceSNicholas Bellinger 	if ((flag != 0) && (flag != 1)) {
675e48354ceSNicholas Bellinger 		pr_err("Illegal value %d\n", flag);
676e48354ceSNicholas Bellinger 		return -EINVAL;
677e48354ceSNicholas Bellinger 	}
678e48354ceSNicholas Bellinger 
679e48354ceSNicholas Bellinger 	a->generate_node_acls = flag;
680e48354ceSNicholas Bellinger 	pr_debug("iSCSI_TPG[%hu] - Generate Initiator Portal Group ACLs: %s\n",
681e48354ceSNicholas Bellinger 		tpg->tpgt, (a->generate_node_acls) ? "Enabled" : "Disabled");
682e48354ceSNicholas Bellinger 
68338b11baeSNicholas Bellinger 	if (flag == 1 && a->cache_dynamic_acls == 0) {
68438b11baeSNicholas Bellinger 		pr_debug("Explicitly setting cache_dynamic_acls=1 when "
68538b11baeSNicholas Bellinger 			"generate_node_acls=1\n");
68638b11baeSNicholas Bellinger 		a->cache_dynamic_acls = 1;
68738b11baeSNicholas Bellinger 	}
68838b11baeSNicholas Bellinger 
689e48354ceSNicholas Bellinger 	return 0;
690e48354ceSNicholas Bellinger }
691e48354ceSNicholas Bellinger 
iscsit_ta_default_cmdsn_depth(struct iscsi_portal_group * tpg,u32 tcq_depth)692e48354ceSNicholas Bellinger int iscsit_ta_default_cmdsn_depth(
693e48354ceSNicholas Bellinger 	struct iscsi_portal_group *tpg,
694e48354ceSNicholas Bellinger 	u32 tcq_depth)
695e48354ceSNicholas Bellinger {
696e48354ceSNicholas Bellinger 	struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
697e48354ceSNicholas Bellinger 
698e48354ceSNicholas Bellinger 	if (tcq_depth > TA_DEFAULT_CMDSN_DEPTH_MAX) {
699e48354ceSNicholas Bellinger 		pr_err("Requested Default Queue Depth: %u larger"
700e48354ceSNicholas Bellinger 			" than maximum %u\n", tcq_depth,
701e48354ceSNicholas Bellinger 				TA_DEFAULT_CMDSN_DEPTH_MAX);
702e48354ceSNicholas Bellinger 		return -EINVAL;
703e48354ceSNicholas Bellinger 	} else if (tcq_depth < TA_DEFAULT_CMDSN_DEPTH_MIN) {
704e48354ceSNicholas Bellinger 		pr_err("Requested Default Queue Depth: %u smaller"
705e48354ceSNicholas Bellinger 			" than minimum %u\n", tcq_depth,
706e48354ceSNicholas Bellinger 				TA_DEFAULT_CMDSN_DEPTH_MIN);
707e48354ceSNicholas Bellinger 		return -EINVAL;
708e48354ceSNicholas Bellinger 	}
709e48354ceSNicholas Bellinger 
710e48354ceSNicholas Bellinger 	a->default_cmdsn_depth = tcq_depth;
711e48354ceSNicholas Bellinger 	pr_debug("iSCSI_TPG[%hu] - Set Default CmdSN TCQ Depth to %u\n",
712e48354ceSNicholas Bellinger 		tpg->tpgt, a->default_cmdsn_depth);
713e48354ceSNicholas Bellinger 
714e48354ceSNicholas Bellinger 	return 0;
715e48354ceSNicholas Bellinger }
716e48354ceSNicholas Bellinger 
iscsit_ta_cache_dynamic_acls(struct iscsi_portal_group * tpg,u32 flag)717e48354ceSNicholas Bellinger int iscsit_ta_cache_dynamic_acls(
718e48354ceSNicholas Bellinger 	struct iscsi_portal_group *tpg,
719e48354ceSNicholas Bellinger 	u32 flag)
720e48354ceSNicholas Bellinger {
721e48354ceSNicholas Bellinger 	struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
722e48354ceSNicholas Bellinger 
723e48354ceSNicholas Bellinger 	if ((flag != 0) && (flag != 1)) {
724e48354ceSNicholas Bellinger 		pr_err("Illegal value %d\n", flag);
725e48354ceSNicholas Bellinger 		return -EINVAL;
726e48354ceSNicholas Bellinger 	}
727e48354ceSNicholas Bellinger 
72838b11baeSNicholas Bellinger 	if (a->generate_node_acls == 1 && flag == 0) {
72938b11baeSNicholas Bellinger 		pr_debug("Skipping cache_dynamic_acls=0 when"
73038b11baeSNicholas Bellinger 			" generate_node_acls=1\n");
73138b11baeSNicholas Bellinger 		return 0;
73238b11baeSNicholas Bellinger 	}
73338b11baeSNicholas Bellinger 
734e48354ceSNicholas Bellinger 	a->cache_dynamic_acls = flag;
735e48354ceSNicholas Bellinger 	pr_debug("iSCSI_TPG[%hu] - Cache Dynamic Initiator Portal Group"
736e48354ceSNicholas Bellinger 		" ACLs %s\n", tpg->tpgt, (a->cache_dynamic_acls) ?
737e48354ceSNicholas Bellinger 		"Enabled" : "Disabled");
738e48354ceSNicholas Bellinger 
739e48354ceSNicholas Bellinger 	return 0;
740e48354ceSNicholas Bellinger }
741e48354ceSNicholas Bellinger 
iscsit_ta_demo_mode_write_protect(struct iscsi_portal_group * tpg,u32 flag)742e48354ceSNicholas Bellinger int iscsit_ta_demo_mode_write_protect(
743e48354ceSNicholas Bellinger 	struct iscsi_portal_group *tpg,
744e48354ceSNicholas Bellinger 	u32 flag)
745e48354ceSNicholas Bellinger {
746e48354ceSNicholas Bellinger 	struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
747e48354ceSNicholas Bellinger 
748e48354ceSNicholas Bellinger 	if ((flag != 0) && (flag != 1)) {
749e48354ceSNicholas Bellinger 		pr_err("Illegal value %d\n", flag);
750e48354ceSNicholas Bellinger 		return -EINVAL;
751e48354ceSNicholas Bellinger 	}
752e48354ceSNicholas Bellinger 
753e48354ceSNicholas Bellinger 	a->demo_mode_write_protect = flag;
754e48354ceSNicholas Bellinger 	pr_debug("iSCSI_TPG[%hu] - Demo Mode Write Protect bit: %s\n",
755e48354ceSNicholas Bellinger 		tpg->tpgt, (a->demo_mode_write_protect) ? "ON" : "OFF");
756e48354ceSNicholas Bellinger 
757e48354ceSNicholas Bellinger 	return 0;
758e48354ceSNicholas Bellinger }
759e48354ceSNicholas Bellinger 
iscsit_ta_prod_mode_write_protect(struct iscsi_portal_group * tpg,u32 flag)760e48354ceSNicholas Bellinger int iscsit_ta_prod_mode_write_protect(
761e48354ceSNicholas Bellinger 	struct iscsi_portal_group *tpg,
762e48354ceSNicholas Bellinger 	u32 flag)
763e48354ceSNicholas Bellinger {
764e48354ceSNicholas Bellinger 	struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
765e48354ceSNicholas Bellinger 
766e48354ceSNicholas Bellinger 	if ((flag != 0) && (flag != 1)) {
767e48354ceSNicholas Bellinger 		pr_err("Illegal value %d\n", flag);
768e48354ceSNicholas Bellinger 		return -EINVAL;
769e48354ceSNicholas Bellinger 	}
770e48354ceSNicholas Bellinger 
771e48354ceSNicholas Bellinger 	a->prod_mode_write_protect = flag;
772e48354ceSNicholas Bellinger 	pr_debug("iSCSI_TPG[%hu] - Production Mode Write Protect bit:"
773e48354ceSNicholas Bellinger 		" %s\n", tpg->tpgt, (a->prod_mode_write_protect) ?
774e48354ceSNicholas Bellinger 		"ON" : "OFF");
775e48354ceSNicholas Bellinger 
776e48354ceSNicholas Bellinger 	return 0;
777e48354ceSNicholas Bellinger }
7784c54b6cfSThomas Glanzmann 
iscsit_ta_demo_mode_discovery(struct iscsi_portal_group * tpg,u32 flag)7794c54b6cfSThomas Glanzmann int iscsit_ta_demo_mode_discovery(
7804c54b6cfSThomas Glanzmann 	struct iscsi_portal_group *tpg,
7814c54b6cfSThomas Glanzmann 	u32 flag)
7824c54b6cfSThomas Glanzmann {
7834c54b6cfSThomas Glanzmann 	struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
7844c54b6cfSThomas Glanzmann 
7854c54b6cfSThomas Glanzmann 	if ((flag != 0) && (flag != 1)) {
7864c54b6cfSThomas Glanzmann 		pr_err("Illegal value %d\n", flag);
7874c54b6cfSThomas Glanzmann 		return -EINVAL;
7884c54b6cfSThomas Glanzmann 	}
7894c54b6cfSThomas Glanzmann 
7904c54b6cfSThomas Glanzmann 	a->demo_mode_discovery = flag;
7914c54b6cfSThomas Glanzmann 	pr_debug("iSCSI_TPG[%hu] - Demo Mode Discovery bit:"
7924c54b6cfSThomas Glanzmann 		" %s\n", tpg->tpgt, (a->demo_mode_discovery) ?
7934c54b6cfSThomas Glanzmann 		"ON" : "OFF");
7944c54b6cfSThomas Glanzmann 
7954c54b6cfSThomas Glanzmann 	return 0;
7964c54b6cfSThomas Glanzmann }
797d1fa7a1dSNicholas Bellinger 
iscsit_ta_default_erl(struct iscsi_portal_group * tpg,u32 default_erl)798d1fa7a1dSNicholas Bellinger int iscsit_ta_default_erl(
799d1fa7a1dSNicholas Bellinger 	struct iscsi_portal_group *tpg,
800d1fa7a1dSNicholas Bellinger 	u32 default_erl)
801d1fa7a1dSNicholas Bellinger {
802d1fa7a1dSNicholas Bellinger 	struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
803d1fa7a1dSNicholas Bellinger 
804d1fa7a1dSNicholas Bellinger 	if ((default_erl != 0) && (default_erl != 1) && (default_erl != 2)) {
805d1fa7a1dSNicholas Bellinger 		pr_err("Illegal value for default_erl: %u\n", default_erl);
806d1fa7a1dSNicholas Bellinger 		return -EINVAL;
807d1fa7a1dSNicholas Bellinger 	}
808d1fa7a1dSNicholas Bellinger 
809d1fa7a1dSNicholas Bellinger 	a->default_erl = default_erl;
810d1fa7a1dSNicholas Bellinger 	pr_debug("iSCSI_TPG[%hu] - DefaultERL: %u\n", tpg->tpgt, a->default_erl);
811d1fa7a1dSNicholas Bellinger 
812d1fa7a1dSNicholas Bellinger 	return 0;
813d1fa7a1dSNicholas Bellinger }
8148085176fSSagi Grimberg 
iscsit_ta_t10_pi(struct iscsi_portal_group * tpg,u32 flag)8158085176fSSagi Grimberg int iscsit_ta_t10_pi(
8168085176fSSagi Grimberg 	struct iscsi_portal_group *tpg,
8178085176fSSagi Grimberg 	u32 flag)
8188085176fSSagi Grimberg {
8198085176fSSagi Grimberg 	struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
8208085176fSSagi Grimberg 
8218085176fSSagi Grimberg 	if ((flag != 0) && (flag != 1)) {
8228085176fSSagi Grimberg 		pr_err("Illegal value %d\n", flag);
8238085176fSSagi Grimberg 		return -EINVAL;
8248085176fSSagi Grimberg 	}
8258085176fSSagi Grimberg 
8268085176fSSagi Grimberg 	a->t10_pi = flag;
8278085176fSSagi Grimberg 	pr_debug("iSCSI_TPG[%hu] - T10 Protection information bit:"
8288085176fSSagi Grimberg 		" %s\n", tpg->tpgt, (a->t10_pi) ?
8298085176fSSagi Grimberg 		"ON" : "OFF");
8308085176fSSagi Grimberg 
8318085176fSSagi Grimberg 	return 0;
8328085176fSSagi Grimberg }
833901c04a3SNicholas Bellinger 
iscsit_ta_fabric_prot_type(struct iscsi_portal_group * tpg,u32 prot_type)834901c04a3SNicholas Bellinger int iscsit_ta_fabric_prot_type(
835901c04a3SNicholas Bellinger 	struct iscsi_portal_group *tpg,
836901c04a3SNicholas Bellinger 	u32 prot_type)
837901c04a3SNicholas Bellinger {
838901c04a3SNicholas Bellinger 	struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
839901c04a3SNicholas Bellinger 
840901c04a3SNicholas Bellinger 	if ((prot_type != 0) && (prot_type != 1) && (prot_type != 3)) {
841901c04a3SNicholas Bellinger 		pr_err("Illegal value for fabric_prot_type: %u\n", prot_type);
842901c04a3SNicholas Bellinger 		return -EINVAL;
843901c04a3SNicholas Bellinger 	}
844901c04a3SNicholas Bellinger 
845901c04a3SNicholas Bellinger 	a->fabric_prot_type = prot_type;
846901c04a3SNicholas Bellinger 	pr_debug("iSCSI_TPG[%hu] - T10 Fabric Protection Type: %u\n",
847901c04a3SNicholas Bellinger 		 tpg->tpgt, prot_type);
848901c04a3SNicholas Bellinger 
849901c04a3SNicholas Bellinger 	return 0;
850901c04a3SNicholas Bellinger }
851a6415cddSDavid Disseldorp 
iscsit_ta_tpg_enabled_sendtargets(struct iscsi_portal_group * tpg,u32 flag)852a6415cddSDavid Disseldorp int iscsit_ta_tpg_enabled_sendtargets(
853a6415cddSDavid Disseldorp 	struct iscsi_portal_group *tpg,
854a6415cddSDavid Disseldorp 	u32 flag)
855a6415cddSDavid Disseldorp {
856a6415cddSDavid Disseldorp 	struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
857a6415cddSDavid Disseldorp 
858a6415cddSDavid Disseldorp 	if ((flag != 0) && (flag != 1)) {
859a6415cddSDavid Disseldorp 		pr_err("Illegal value %d\n", flag);
860a6415cddSDavid Disseldorp 		return -EINVAL;
861a6415cddSDavid Disseldorp 	}
862a6415cddSDavid Disseldorp 
863a6415cddSDavid Disseldorp 	a->tpg_enabled_sendtargets = flag;
864a6415cddSDavid Disseldorp 	pr_debug("iSCSI_TPG[%hu] - TPG enabled bit required for SendTargets:"
865a6415cddSDavid Disseldorp 		" %s\n", tpg->tpgt, (a->tpg_enabled_sendtargets) ? "ON" : "OFF");
866a6415cddSDavid Disseldorp 
867a6415cddSDavid Disseldorp 	return 0;
868a6415cddSDavid Disseldorp }
869138d351eSNicholas Bellinger 
iscsit_ta_login_keys_workaround(struct iscsi_portal_group * tpg,u32 flag)870138d351eSNicholas Bellinger int iscsit_ta_login_keys_workaround(
871138d351eSNicholas Bellinger 	struct iscsi_portal_group *tpg,
872138d351eSNicholas Bellinger 	u32 flag)
873138d351eSNicholas Bellinger {
874138d351eSNicholas Bellinger 	struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
875138d351eSNicholas Bellinger 
876138d351eSNicholas Bellinger 	if ((flag != 0) && (flag != 1)) {
877138d351eSNicholas Bellinger 		pr_err("Illegal value %d\n", flag);
878138d351eSNicholas Bellinger 		return -EINVAL;
879138d351eSNicholas Bellinger 	}
880138d351eSNicholas Bellinger 
881138d351eSNicholas Bellinger 	a->login_keys_workaround = flag;
882138d351eSNicholas Bellinger 	pr_debug("iSCSI_TPG[%hu] - TPG enabled bit for login keys workaround: %s ",
883138d351eSNicholas Bellinger 		tpg->tpgt, (a->login_keys_workaround) ? "ON" : "OFF");
884138d351eSNicholas Bellinger 
885138d351eSNicholas Bellinger 	return 0;
886138d351eSNicholas Bellinger }
887