1e48354ceSNicholas Bellinger /*******************************************************************************
2e48354ceSNicholas Bellinger  * This file contains iSCSI Target Portal Group related functions.
3e48354ceSNicholas Bellinger  *
44c76251eSNicholas Bellinger  * (c) Copyright 2007-2013 Datera, Inc.
5e48354ceSNicholas Bellinger  *
6e48354ceSNicholas Bellinger  * Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
7e48354ceSNicholas Bellinger  *
8e48354ceSNicholas Bellinger  * This program is free software; you can redistribute it and/or modify
9e48354ceSNicholas Bellinger  * it under the terms of the GNU General Public License as published by
10e48354ceSNicholas Bellinger  * the Free Software Foundation; either version 2 of the License, or
11e48354ceSNicholas Bellinger  * (at your option) any later version.
12e48354ceSNicholas Bellinger  *
13e48354ceSNicholas Bellinger  * This program is distributed in the hope that it will be useful,
14e48354ceSNicholas Bellinger  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15e48354ceSNicholas Bellinger  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16e48354ceSNicholas Bellinger  * GNU General Public License for more details.
17e48354ceSNicholas Bellinger  ******************************************************************************/
18e48354ceSNicholas Bellinger 
19e48354ceSNicholas Bellinger #include <target/target_core_base.h>
20c4795fb2SChristoph Hellwig #include <target/target_core_fabric.h>
21e48354ceSNicholas Bellinger #include <target/target_core_configfs.h>
22e48354ceSNicholas Bellinger 
23e48354ceSNicholas Bellinger #include "iscsi_target_core.h"
24e48354ceSNicholas Bellinger #include "iscsi_target_erl0.h"
25e48354ceSNicholas Bellinger #include "iscsi_target_login.h"
26e48354ceSNicholas Bellinger #include "iscsi_target_nodeattrib.h"
27e48354ceSNicholas Bellinger #include "iscsi_target_tpg.h"
28e48354ceSNicholas Bellinger #include "iscsi_target_util.h"
29e48354ceSNicholas Bellinger #include "iscsi_target.h"
30e48354ceSNicholas Bellinger #include "iscsi_target_parameters.h"
31e48354ceSNicholas Bellinger 
32baa4d64bSNicholas Bellinger #include <target/iscsi/iscsi_transport.h>
33baa4d64bSNicholas Bellinger 
34e48354ceSNicholas Bellinger struct iscsi_portal_group *iscsit_alloc_portal_group(struct iscsi_tiqn *tiqn, u16 tpgt)
35e48354ceSNicholas Bellinger {
36e48354ceSNicholas Bellinger 	struct iscsi_portal_group *tpg;
37e48354ceSNicholas Bellinger 
38e48354ceSNicholas Bellinger 	tpg = kzalloc(sizeof(struct iscsi_portal_group), GFP_KERNEL);
39e48354ceSNicholas Bellinger 	if (!tpg) {
40e48354ceSNicholas Bellinger 		pr_err("Unable to allocate struct iscsi_portal_group\n");
41e48354ceSNicholas Bellinger 		return NULL;
42e48354ceSNicholas Bellinger 	}
43e48354ceSNicholas Bellinger 
44e48354ceSNicholas Bellinger 	tpg->tpgt = tpgt;
45e48354ceSNicholas Bellinger 	tpg->tpg_state = TPG_STATE_FREE;
46e48354ceSNicholas Bellinger 	tpg->tpg_tiqn = tiqn;
47e48354ceSNicholas Bellinger 	INIT_LIST_HEAD(&tpg->tpg_gnp_list);
48e48354ceSNicholas Bellinger 	INIT_LIST_HEAD(&tpg->tpg_list);
49e48354ceSNicholas Bellinger 	mutex_init(&tpg->tpg_access_lock);
50a91eb7d9SNicholas Bellinger 	sema_init(&tpg->np_login_sem, 1);
51e48354ceSNicholas Bellinger 	spin_lock_init(&tpg->tpg_state_lock);
52e48354ceSNicholas Bellinger 	spin_lock_init(&tpg->tpg_np_lock);
53e48354ceSNicholas Bellinger 
54e48354ceSNicholas Bellinger 	return tpg;
55e48354ceSNicholas Bellinger }
56e48354ceSNicholas Bellinger 
57e48354ceSNicholas Bellinger static void iscsit_set_default_tpg_attribs(struct iscsi_portal_group *);
58e48354ceSNicholas Bellinger 
59e48354ceSNicholas Bellinger int iscsit_load_discovery_tpg(void)
60e48354ceSNicholas Bellinger {
61e48354ceSNicholas Bellinger 	struct iscsi_param *param;
62e48354ceSNicholas Bellinger 	struct iscsi_portal_group *tpg;
63e48354ceSNicholas Bellinger 	int ret;
64e48354ceSNicholas Bellinger 
65e48354ceSNicholas Bellinger 	tpg = iscsit_alloc_portal_group(NULL, 1);
66e48354ceSNicholas Bellinger 	if (!tpg) {
67e48354ceSNicholas Bellinger 		pr_err("Unable to allocate struct iscsi_portal_group\n");
68e48354ceSNicholas Bellinger 		return -1;
69e48354ceSNicholas Bellinger 	}
70e48354ceSNicholas Bellinger 
71e48354ceSNicholas Bellinger 	ret = core_tpg_register(
72e48354ceSNicholas Bellinger 			&lio_target_fabric_configfs->tf_ops,
738359cf43SJörn Engel 			NULL, &tpg->tpg_se_tpg, tpg,
74e48354ceSNicholas Bellinger 			TRANSPORT_TPG_TYPE_DISCOVERY);
75e48354ceSNicholas Bellinger 	if (ret < 0) {
76e48354ceSNicholas Bellinger 		kfree(tpg);
77e48354ceSNicholas Bellinger 		return -1;
78e48354ceSNicholas Bellinger 	}
79e48354ceSNicholas Bellinger 
80e48354ceSNicholas Bellinger 	tpg->sid = 1; /* First Assigned LIO Session ID */
81e48354ceSNicholas Bellinger 	iscsit_set_default_tpg_attribs(tpg);
82e48354ceSNicholas Bellinger 
83e48354ceSNicholas Bellinger 	if (iscsi_create_default_params(&tpg->param_list) < 0)
84e48354ceSNicholas Bellinger 		goto out;
85e48354ceSNicholas Bellinger 	/*
86e48354ceSNicholas Bellinger 	 * By default we disable authentication for discovery sessions,
87e48354ceSNicholas Bellinger 	 * this can be changed with:
88e48354ceSNicholas Bellinger 	 *
89e48354ceSNicholas Bellinger 	 * /sys/kernel/config/target/iscsi/discovery_auth/enforce_discovery_auth
90e48354ceSNicholas Bellinger 	 */
91e48354ceSNicholas Bellinger 	param = iscsi_find_param_from_key(AUTHMETHOD, tpg->param_list);
92e48354ceSNicholas Bellinger 	if (!param)
93e48354ceSNicholas Bellinger 		goto out;
94e48354ceSNicholas Bellinger 
95e48354ceSNicholas Bellinger 	if (iscsi_update_param_value(param, "CHAP,None") < 0)
96e48354ceSNicholas Bellinger 		goto out;
97e48354ceSNicholas Bellinger 
98e48354ceSNicholas Bellinger 	tpg->tpg_attrib.authentication = 0;
99e48354ceSNicholas Bellinger 
100e48354ceSNicholas Bellinger 	spin_lock(&tpg->tpg_state_lock);
101e48354ceSNicholas Bellinger 	tpg->tpg_state  = TPG_STATE_ACTIVE;
102e48354ceSNicholas Bellinger 	spin_unlock(&tpg->tpg_state_lock);
103e48354ceSNicholas Bellinger 
104e48354ceSNicholas Bellinger 	iscsit_global->discovery_tpg = tpg;
105e48354ceSNicholas Bellinger 	pr_debug("CORE[0] - Allocated Discovery TPG\n");
106e48354ceSNicholas Bellinger 
107e48354ceSNicholas Bellinger 	return 0;
108e48354ceSNicholas Bellinger out:
109e48354ceSNicholas Bellinger 	if (tpg->sid == 1)
110e48354ceSNicholas Bellinger 		core_tpg_deregister(&tpg->tpg_se_tpg);
111e48354ceSNicholas Bellinger 	kfree(tpg);
112e48354ceSNicholas Bellinger 	return -1;
113e48354ceSNicholas Bellinger }
114e48354ceSNicholas Bellinger 
115e48354ceSNicholas Bellinger void iscsit_release_discovery_tpg(void)
116e48354ceSNicholas Bellinger {
117e48354ceSNicholas Bellinger 	struct iscsi_portal_group *tpg = iscsit_global->discovery_tpg;
118e48354ceSNicholas Bellinger 
119e48354ceSNicholas Bellinger 	if (!tpg)
120e48354ceSNicholas Bellinger 		return;
121e48354ceSNicholas Bellinger 
122e48354ceSNicholas Bellinger 	core_tpg_deregister(&tpg->tpg_se_tpg);
123e48354ceSNicholas Bellinger 
124e48354ceSNicholas Bellinger 	kfree(tpg);
125e48354ceSNicholas Bellinger 	iscsit_global->discovery_tpg = NULL;
126e48354ceSNicholas Bellinger }
127e48354ceSNicholas Bellinger 
128e48354ceSNicholas Bellinger struct iscsi_portal_group *iscsit_get_tpg_from_np(
129e48354ceSNicholas Bellinger 	struct iscsi_tiqn *tiqn,
130d381a801SNicholas Bellinger 	struct iscsi_np *np,
131d381a801SNicholas Bellinger 	struct iscsi_tpg_np **tpg_np_out)
132e48354ceSNicholas Bellinger {
133e48354ceSNicholas Bellinger 	struct iscsi_portal_group *tpg = NULL;
134e48354ceSNicholas Bellinger 	struct iscsi_tpg_np *tpg_np;
135e48354ceSNicholas Bellinger 
136e48354ceSNicholas Bellinger 	spin_lock(&tiqn->tiqn_tpg_lock);
137e48354ceSNicholas Bellinger 	list_for_each_entry(tpg, &tiqn->tiqn_tpg_list, tpg_list) {
138e48354ceSNicholas Bellinger 
139e48354ceSNicholas Bellinger 		spin_lock(&tpg->tpg_state_lock);
140a2a99ceaSNicholas Bellinger 		if (tpg->tpg_state != TPG_STATE_ACTIVE) {
141e48354ceSNicholas Bellinger 			spin_unlock(&tpg->tpg_state_lock);
142e48354ceSNicholas Bellinger 			continue;
143e48354ceSNicholas Bellinger 		}
144e48354ceSNicholas Bellinger 		spin_unlock(&tpg->tpg_state_lock);
145e48354ceSNicholas Bellinger 
146e48354ceSNicholas Bellinger 		spin_lock(&tpg->tpg_np_lock);
147e48354ceSNicholas Bellinger 		list_for_each_entry(tpg_np, &tpg->tpg_gnp_list, tpg_np_list) {
148e48354ceSNicholas Bellinger 			if (tpg_np->tpg_np == np) {
149d381a801SNicholas Bellinger 				*tpg_np_out = tpg_np;
150d381a801SNicholas Bellinger 				kref_get(&tpg_np->tpg_np_kref);
151e48354ceSNicholas Bellinger 				spin_unlock(&tpg->tpg_np_lock);
152e48354ceSNicholas Bellinger 				spin_unlock(&tiqn->tiqn_tpg_lock);
153e48354ceSNicholas Bellinger 				return tpg;
154e48354ceSNicholas Bellinger 			}
155e48354ceSNicholas Bellinger 		}
156e48354ceSNicholas Bellinger 		spin_unlock(&tpg->tpg_np_lock);
157e48354ceSNicholas Bellinger 	}
158e48354ceSNicholas Bellinger 	spin_unlock(&tiqn->tiqn_tpg_lock);
159e48354ceSNicholas Bellinger 
160e48354ceSNicholas Bellinger 	return NULL;
161e48354ceSNicholas Bellinger }
162e48354ceSNicholas Bellinger 
163e48354ceSNicholas Bellinger int iscsit_get_tpg(
164e48354ceSNicholas Bellinger 	struct iscsi_portal_group *tpg)
165e48354ceSNicholas Bellinger {
166e48354ceSNicholas Bellinger 	int ret;
167e48354ceSNicholas Bellinger 
168e48354ceSNicholas Bellinger 	ret = mutex_lock_interruptible(&tpg->tpg_access_lock);
169e48354ceSNicholas Bellinger 	return ((ret != 0) || signal_pending(current)) ? -1 : 0;
170e48354ceSNicholas Bellinger }
171e48354ceSNicholas Bellinger 
172e48354ceSNicholas Bellinger void iscsit_put_tpg(struct iscsi_portal_group *tpg)
173e48354ceSNicholas Bellinger {
174e48354ceSNicholas Bellinger 	mutex_unlock(&tpg->tpg_access_lock);
175e48354ceSNicholas Bellinger }
176e48354ceSNicholas Bellinger 
177e48354ceSNicholas Bellinger static void iscsit_clear_tpg_np_login_thread(
178e48354ceSNicholas Bellinger 	struct iscsi_tpg_np *tpg_np,
179a91eb7d9SNicholas Bellinger 	struct iscsi_portal_group *tpg,
180a91eb7d9SNicholas Bellinger 	bool shutdown)
181e48354ceSNicholas Bellinger {
182e48354ceSNicholas Bellinger 	if (!tpg_np->tpg_np) {
183e48354ceSNicholas Bellinger 		pr_err("struct iscsi_tpg_np->tpg_np is NULL!\n");
184e48354ceSNicholas Bellinger 		return;
185e48354ceSNicholas Bellinger 	}
186e48354ceSNicholas Bellinger 
187a91eb7d9SNicholas Bellinger 	iscsit_reset_np_thread(tpg_np->tpg_np, tpg_np, tpg, shutdown);
188e48354ceSNicholas Bellinger }
189e48354ceSNicholas Bellinger 
190e48354ceSNicholas Bellinger void iscsit_clear_tpg_np_login_threads(
191a91eb7d9SNicholas Bellinger 	struct iscsi_portal_group *tpg,
192a91eb7d9SNicholas Bellinger 	bool shutdown)
193e48354ceSNicholas Bellinger {
194e48354ceSNicholas Bellinger 	struct iscsi_tpg_np *tpg_np;
195e48354ceSNicholas Bellinger 
196e48354ceSNicholas Bellinger 	spin_lock(&tpg->tpg_np_lock);
197e48354ceSNicholas Bellinger 	list_for_each_entry(tpg_np, &tpg->tpg_gnp_list, tpg_np_list) {
198e48354ceSNicholas Bellinger 		if (!tpg_np->tpg_np) {
199e48354ceSNicholas Bellinger 			pr_err("struct iscsi_tpg_np->tpg_np is NULL!\n");
200e48354ceSNicholas Bellinger 			continue;
201e48354ceSNicholas Bellinger 		}
202e48354ceSNicholas Bellinger 		spin_unlock(&tpg->tpg_np_lock);
203a91eb7d9SNicholas Bellinger 		iscsit_clear_tpg_np_login_thread(tpg_np, tpg, shutdown);
204e48354ceSNicholas Bellinger 		spin_lock(&tpg->tpg_np_lock);
205e48354ceSNicholas Bellinger 	}
206e48354ceSNicholas Bellinger 	spin_unlock(&tpg->tpg_np_lock);
207e48354ceSNicholas Bellinger }
208e48354ceSNicholas Bellinger 
209e48354ceSNicholas Bellinger void iscsit_tpg_dump_params(struct iscsi_portal_group *tpg)
210e48354ceSNicholas Bellinger {
211e48354ceSNicholas Bellinger 	iscsi_print_params(tpg->param_list);
212e48354ceSNicholas Bellinger }
213e48354ceSNicholas Bellinger 
214e48354ceSNicholas Bellinger static void iscsit_set_default_tpg_attribs(struct iscsi_portal_group *tpg)
215e48354ceSNicholas Bellinger {
216e48354ceSNicholas Bellinger 	struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
217e48354ceSNicholas Bellinger 
218e48354ceSNicholas Bellinger 	a->authentication = TA_AUTHENTICATION;
219e48354ceSNicholas Bellinger 	a->login_timeout = TA_LOGIN_TIMEOUT;
220e48354ceSNicholas Bellinger 	a->netif_timeout = TA_NETIF_TIMEOUT;
221e48354ceSNicholas Bellinger 	a->default_cmdsn_depth = TA_DEFAULT_CMDSN_DEPTH;
222e48354ceSNicholas Bellinger 	a->generate_node_acls = TA_GENERATE_NODE_ACLS;
223e48354ceSNicholas Bellinger 	a->cache_dynamic_acls = TA_CACHE_DYNAMIC_ACLS;
224e48354ceSNicholas Bellinger 	a->demo_mode_write_protect = TA_DEMO_MODE_WRITE_PROTECT;
225e48354ceSNicholas Bellinger 	a->prod_mode_write_protect = TA_PROD_MODE_WRITE_PROTECT;
2264c54b6cfSThomas Glanzmann 	a->demo_mode_discovery = TA_DEMO_MODE_DISCOVERY;
227d1fa7a1dSNicholas Bellinger 	a->default_erl = TA_DEFAULT_ERL;
2285b168dcdSSagi Grimberg 	a->t10_pi = TA_DEFAULT_T10_PI;
229e48354ceSNicholas Bellinger }
230e48354ceSNicholas Bellinger 
231e48354ceSNicholas Bellinger int iscsit_tpg_add_portal_group(struct iscsi_tiqn *tiqn, struct iscsi_portal_group *tpg)
232e48354ceSNicholas Bellinger {
233e48354ceSNicholas Bellinger 	if (tpg->tpg_state != TPG_STATE_FREE) {
234e48354ceSNicholas Bellinger 		pr_err("Unable to add iSCSI Target Portal Group: %d"
235e48354ceSNicholas Bellinger 			" while not in TPG_STATE_FREE state.\n", tpg->tpgt);
236e48354ceSNicholas Bellinger 		return -EEXIST;
237e48354ceSNicholas Bellinger 	}
238e48354ceSNicholas Bellinger 	iscsit_set_default_tpg_attribs(tpg);
239e48354ceSNicholas Bellinger 
240e48354ceSNicholas Bellinger 	if (iscsi_create_default_params(&tpg->param_list) < 0)
241e48354ceSNicholas Bellinger 		goto err_out;
242e48354ceSNicholas Bellinger 
243b7eec2cdSAndy Grover 	tpg->tpg_attrib.tpg = tpg;
244e48354ceSNicholas Bellinger 
245e48354ceSNicholas Bellinger 	spin_lock(&tpg->tpg_state_lock);
246e48354ceSNicholas Bellinger 	tpg->tpg_state	= TPG_STATE_INACTIVE;
247e48354ceSNicholas Bellinger 	spin_unlock(&tpg->tpg_state_lock);
248e48354ceSNicholas Bellinger 
249e48354ceSNicholas Bellinger 	spin_lock(&tiqn->tiqn_tpg_lock);
250e48354ceSNicholas Bellinger 	list_add_tail(&tpg->tpg_list, &tiqn->tiqn_tpg_list);
251e48354ceSNicholas Bellinger 	tiqn->tiqn_ntpgs++;
252e48354ceSNicholas Bellinger 	pr_debug("CORE[%s]_TPG[%hu] - Added iSCSI Target Portal Group\n",
253e48354ceSNicholas Bellinger 			tiqn->tiqn, tpg->tpgt);
254e48354ceSNicholas Bellinger 	spin_unlock(&tiqn->tiqn_tpg_lock);
255e48354ceSNicholas Bellinger 
256e48354ceSNicholas Bellinger 	return 0;
257e48354ceSNicholas Bellinger err_out:
258e48354ceSNicholas Bellinger 	if (tpg->param_list) {
259e48354ceSNicholas Bellinger 		iscsi_release_param_list(tpg->param_list);
260e48354ceSNicholas Bellinger 		tpg->param_list = NULL;
261e48354ceSNicholas Bellinger 	}
262e48354ceSNicholas Bellinger 	kfree(tpg);
263e48354ceSNicholas Bellinger 	return -ENOMEM;
264e48354ceSNicholas Bellinger }
265e48354ceSNicholas Bellinger 
266e48354ceSNicholas Bellinger int iscsit_tpg_del_portal_group(
267e48354ceSNicholas Bellinger 	struct iscsi_tiqn *tiqn,
268e48354ceSNicholas Bellinger 	struct iscsi_portal_group *tpg,
269e48354ceSNicholas Bellinger 	int force)
270e48354ceSNicholas Bellinger {
271e48354ceSNicholas Bellinger 	u8 old_state = tpg->tpg_state;
272e48354ceSNicholas Bellinger 
273e48354ceSNicholas Bellinger 	spin_lock(&tpg->tpg_state_lock);
274e48354ceSNicholas Bellinger 	tpg->tpg_state = TPG_STATE_INACTIVE;
275e48354ceSNicholas Bellinger 	spin_unlock(&tpg->tpg_state_lock);
276e48354ceSNicholas Bellinger 
277a91eb7d9SNicholas Bellinger 	iscsit_clear_tpg_np_login_threads(tpg, true);
278a91eb7d9SNicholas Bellinger 
279e48354ceSNicholas Bellinger 	if (iscsit_release_sessions_for_tpg(tpg, force) < 0) {
280e48354ceSNicholas Bellinger 		pr_err("Unable to delete iSCSI Target Portal Group:"
281e48354ceSNicholas Bellinger 			" %hu while active sessions exist, and force=0\n",
282e48354ceSNicholas Bellinger 			tpg->tpgt);
283e48354ceSNicholas Bellinger 		tpg->tpg_state = old_state;
284e48354ceSNicholas Bellinger 		return -EPERM;
285e48354ceSNicholas Bellinger 	}
286e48354ceSNicholas Bellinger 
287e48354ceSNicholas Bellinger 	core_tpg_clear_object_luns(&tpg->tpg_se_tpg);
288e48354ceSNicholas Bellinger 
289e48354ceSNicholas Bellinger 	if (tpg->param_list) {
290e48354ceSNicholas Bellinger 		iscsi_release_param_list(tpg->param_list);
291e48354ceSNicholas Bellinger 		tpg->param_list = NULL;
292e48354ceSNicholas Bellinger 	}
293e48354ceSNicholas Bellinger 
294e48354ceSNicholas Bellinger 	core_tpg_deregister(&tpg->tpg_se_tpg);
295e48354ceSNicholas Bellinger 
296e48354ceSNicholas Bellinger 	spin_lock(&tpg->tpg_state_lock);
297e48354ceSNicholas Bellinger 	tpg->tpg_state = TPG_STATE_FREE;
298e48354ceSNicholas Bellinger 	spin_unlock(&tpg->tpg_state_lock);
299e48354ceSNicholas Bellinger 
300e48354ceSNicholas Bellinger 	spin_lock(&tiqn->tiqn_tpg_lock);
301e48354ceSNicholas Bellinger 	tiqn->tiqn_ntpgs--;
302e48354ceSNicholas Bellinger 	list_del(&tpg->tpg_list);
303e48354ceSNicholas Bellinger 	spin_unlock(&tiqn->tiqn_tpg_lock);
304e48354ceSNicholas Bellinger 
305e48354ceSNicholas Bellinger 	pr_debug("CORE[%s]_TPG[%hu] - Deleted iSCSI Target Portal Group\n",
306e48354ceSNicholas Bellinger 			tiqn->tiqn, tpg->tpgt);
307e48354ceSNicholas Bellinger 
308e48354ceSNicholas Bellinger 	kfree(tpg);
309e48354ceSNicholas Bellinger 	return 0;
310e48354ceSNicholas Bellinger }
311e48354ceSNicholas Bellinger 
312e48354ceSNicholas Bellinger int iscsit_tpg_enable_portal_group(struct iscsi_portal_group *tpg)
313e48354ceSNicholas Bellinger {
314e48354ceSNicholas Bellinger 	struct iscsi_param *param;
315e48354ceSNicholas Bellinger 	struct iscsi_tiqn *tiqn = tpg->tpg_tiqn;
316617a0c2eSAndy Grover 	int ret;
317e48354ceSNicholas Bellinger 
318e48354ceSNicholas Bellinger 	spin_lock(&tpg->tpg_state_lock);
319e48354ceSNicholas Bellinger 	if (tpg->tpg_state == TPG_STATE_ACTIVE) {
320e48354ceSNicholas Bellinger 		pr_err("iSCSI target portal group: %hu is already"
321e48354ceSNicholas Bellinger 			" active, ignoring request.\n", tpg->tpgt);
322e48354ceSNicholas Bellinger 		spin_unlock(&tpg->tpg_state_lock);
323e48354ceSNicholas Bellinger 		return -EINVAL;
324e48354ceSNicholas Bellinger 	}
325e48354ceSNicholas Bellinger 	/*
326e48354ceSNicholas Bellinger 	 * Make sure that AuthMethod does not contain None as an option
327e48354ceSNicholas Bellinger 	 * unless explictly disabled.  Set the default to CHAP if authentication
328e48354ceSNicholas Bellinger 	 * is enforced (as per default), and remove the NONE option.
329e48354ceSNicholas Bellinger 	 */
330e48354ceSNicholas Bellinger 	param = iscsi_find_param_from_key(AUTHMETHOD, tpg->param_list);
331e48354ceSNicholas Bellinger 	if (!param) {
332e48354ceSNicholas Bellinger 		spin_unlock(&tpg->tpg_state_lock);
333617a0c2eSAndy Grover 		return -EINVAL;
334e48354ceSNicholas Bellinger 	}
335e48354ceSNicholas Bellinger 
336b7eec2cdSAndy Grover 	if (tpg->tpg_attrib.authentication) {
337617a0c2eSAndy Grover 		if (!strcmp(param->value, NONE)) {
338617a0c2eSAndy Grover 			ret = iscsi_update_param_value(param, CHAP);
339617a0c2eSAndy Grover 			if (ret)
340617a0c2eSAndy Grover 				goto err;
341e48354ceSNicholas Bellinger 		}
342617a0c2eSAndy Grover 
343617a0c2eSAndy Grover 		ret = iscsit_ta_authentication(tpg, 1);
344617a0c2eSAndy Grover 		if (ret < 0)
345617a0c2eSAndy Grover 			goto err;
346e48354ceSNicholas Bellinger 	}
347e48354ceSNicholas Bellinger 
348e48354ceSNicholas Bellinger 	tpg->tpg_state = TPG_STATE_ACTIVE;
349e48354ceSNicholas Bellinger 	spin_unlock(&tpg->tpg_state_lock);
350e48354ceSNicholas Bellinger 
351e48354ceSNicholas Bellinger 	spin_lock(&tiqn->tiqn_tpg_lock);
352e48354ceSNicholas Bellinger 	tiqn->tiqn_active_tpgs++;
353e48354ceSNicholas Bellinger 	pr_debug("iSCSI_TPG[%hu] - Enabled iSCSI Target Portal Group\n",
354e48354ceSNicholas Bellinger 			tpg->tpgt);
355e48354ceSNicholas Bellinger 	spin_unlock(&tiqn->tiqn_tpg_lock);
356e48354ceSNicholas Bellinger 
357e48354ceSNicholas Bellinger 	return 0;
358617a0c2eSAndy Grover 
359617a0c2eSAndy Grover err:
360617a0c2eSAndy Grover 	spin_unlock(&tpg->tpg_state_lock);
361617a0c2eSAndy Grover 	return ret;
362e48354ceSNicholas Bellinger }
363e48354ceSNicholas Bellinger 
364e48354ceSNicholas Bellinger int iscsit_tpg_disable_portal_group(struct iscsi_portal_group *tpg, int force)
365e48354ceSNicholas Bellinger {
366e48354ceSNicholas Bellinger 	struct iscsi_tiqn *tiqn;
367e48354ceSNicholas Bellinger 	u8 old_state = tpg->tpg_state;
368e48354ceSNicholas Bellinger 
369e48354ceSNicholas Bellinger 	spin_lock(&tpg->tpg_state_lock);
370e48354ceSNicholas Bellinger 	if (tpg->tpg_state == TPG_STATE_INACTIVE) {
371e48354ceSNicholas Bellinger 		pr_err("iSCSI Target Portal Group: %hu is already"
372e48354ceSNicholas Bellinger 			" inactive, ignoring request.\n", tpg->tpgt);
373e48354ceSNicholas Bellinger 		spin_unlock(&tpg->tpg_state_lock);
374e48354ceSNicholas Bellinger 		return -EINVAL;
375e48354ceSNicholas Bellinger 	}
376e48354ceSNicholas Bellinger 	tpg->tpg_state = TPG_STATE_INACTIVE;
377e48354ceSNicholas Bellinger 	spin_unlock(&tpg->tpg_state_lock);
378e48354ceSNicholas Bellinger 
379a91eb7d9SNicholas Bellinger 	iscsit_clear_tpg_np_login_threads(tpg, false);
380e48354ceSNicholas Bellinger 
381e48354ceSNicholas Bellinger 	if (iscsit_release_sessions_for_tpg(tpg, force) < 0) {
382e48354ceSNicholas Bellinger 		spin_lock(&tpg->tpg_state_lock);
383e48354ceSNicholas Bellinger 		tpg->tpg_state = old_state;
384e48354ceSNicholas Bellinger 		spin_unlock(&tpg->tpg_state_lock);
385e48354ceSNicholas Bellinger 		pr_err("Unable to disable iSCSI Target Portal Group:"
386e48354ceSNicholas Bellinger 			" %hu while active sessions exist, and force=0\n",
387e48354ceSNicholas Bellinger 			tpg->tpgt);
388e48354ceSNicholas Bellinger 		return -EPERM;
389e48354ceSNicholas Bellinger 	}
390e48354ceSNicholas Bellinger 
391e48354ceSNicholas Bellinger 	tiqn = tpg->tpg_tiqn;
392e48354ceSNicholas Bellinger 	if (!tiqn || (tpg == iscsit_global->discovery_tpg))
393e48354ceSNicholas Bellinger 		return 0;
394e48354ceSNicholas Bellinger 
395e48354ceSNicholas Bellinger 	spin_lock(&tiqn->tiqn_tpg_lock);
396e48354ceSNicholas Bellinger 	tiqn->tiqn_active_tpgs--;
397e48354ceSNicholas Bellinger 	pr_debug("iSCSI_TPG[%hu] - Disabled iSCSI Target Portal Group\n",
398e48354ceSNicholas Bellinger 			tpg->tpgt);
399e48354ceSNicholas Bellinger 	spin_unlock(&tiqn->tiqn_tpg_lock);
400e48354ceSNicholas Bellinger 
401e48354ceSNicholas Bellinger 	return 0;
402e48354ceSNicholas Bellinger }
403e48354ceSNicholas Bellinger 
404e48354ceSNicholas Bellinger struct iscsi_node_attrib *iscsit_tpg_get_node_attrib(
405e48354ceSNicholas Bellinger 	struct iscsi_session *sess)
406e48354ceSNicholas Bellinger {
407e48354ceSNicholas Bellinger 	struct se_session *se_sess = sess->se_sess;
408e48354ceSNicholas Bellinger 	struct se_node_acl *se_nacl = se_sess->se_node_acl;
409e48354ceSNicholas Bellinger 	struct iscsi_node_acl *acl = container_of(se_nacl, struct iscsi_node_acl,
410e48354ceSNicholas Bellinger 					se_node_acl);
411e48354ceSNicholas Bellinger 
412e48354ceSNicholas Bellinger 	return &acl->node_attrib;
413e48354ceSNicholas Bellinger }
414e48354ceSNicholas Bellinger 
415e48354ceSNicholas Bellinger struct iscsi_tpg_np *iscsit_tpg_locate_child_np(
416e48354ceSNicholas Bellinger 	struct iscsi_tpg_np *tpg_np,
417e48354ceSNicholas Bellinger 	int network_transport)
418e48354ceSNicholas Bellinger {
419e48354ceSNicholas Bellinger 	struct iscsi_tpg_np *tpg_np_child, *tpg_np_child_tmp;
420e48354ceSNicholas Bellinger 
421e48354ceSNicholas Bellinger 	spin_lock(&tpg_np->tpg_np_parent_lock);
422e48354ceSNicholas Bellinger 	list_for_each_entry_safe(tpg_np_child, tpg_np_child_tmp,
423e48354ceSNicholas Bellinger 			&tpg_np->tpg_np_parent_list, tpg_np_child_list) {
424e48354ceSNicholas Bellinger 		if (tpg_np_child->tpg_np->np_network_transport ==
425e48354ceSNicholas Bellinger 				network_transport) {
426e48354ceSNicholas Bellinger 			spin_unlock(&tpg_np->tpg_np_parent_lock);
427e48354ceSNicholas Bellinger 			return tpg_np_child;
428e48354ceSNicholas Bellinger 		}
429e48354ceSNicholas Bellinger 	}
430e48354ceSNicholas Bellinger 	spin_unlock(&tpg_np->tpg_np_parent_lock);
431e48354ceSNicholas Bellinger 
432e48354ceSNicholas Bellinger 	return NULL;
433e48354ceSNicholas Bellinger }
434e48354ceSNicholas Bellinger 
4356e545935SNicholas Bellinger static bool iscsit_tpg_check_network_portal(
4366e545935SNicholas Bellinger 	struct iscsi_tiqn *tiqn,
4376e545935SNicholas Bellinger 	struct __kernel_sockaddr_storage *sockaddr,
4386e545935SNicholas Bellinger 	int network_transport)
4396e545935SNicholas Bellinger {
4406e545935SNicholas Bellinger 	struct iscsi_portal_group *tpg;
4416e545935SNicholas Bellinger 	struct iscsi_tpg_np *tpg_np;
4426e545935SNicholas Bellinger 	struct iscsi_np *np;
4436e545935SNicholas Bellinger 	bool match = false;
4446e545935SNicholas Bellinger 
4456e545935SNicholas Bellinger 	spin_lock(&tiqn->tiqn_tpg_lock);
4466e545935SNicholas Bellinger 	list_for_each_entry(tpg, &tiqn->tiqn_tpg_list, tpg_list) {
4476e545935SNicholas Bellinger 
4486e545935SNicholas Bellinger 		spin_lock(&tpg->tpg_np_lock);
4496e545935SNicholas Bellinger 		list_for_each_entry(tpg_np, &tpg->tpg_gnp_list, tpg_np_list) {
4506e545935SNicholas Bellinger 			np = tpg_np->tpg_np;
4516e545935SNicholas Bellinger 
4526e545935SNicholas Bellinger 			match = iscsit_check_np_match(sockaddr, np,
4536e545935SNicholas Bellinger 						network_transport);
4546e545935SNicholas Bellinger 			if (match == true)
4556e545935SNicholas Bellinger 				break;
4566e545935SNicholas Bellinger 		}
4576e545935SNicholas Bellinger 		spin_unlock(&tpg->tpg_np_lock);
4586e545935SNicholas Bellinger 	}
4596e545935SNicholas Bellinger 	spin_unlock(&tiqn->tiqn_tpg_lock);
4606e545935SNicholas Bellinger 
4616e545935SNicholas Bellinger 	return match;
4626e545935SNicholas Bellinger }
4636e545935SNicholas Bellinger 
464e48354ceSNicholas Bellinger struct iscsi_tpg_np *iscsit_tpg_add_network_portal(
465e48354ceSNicholas Bellinger 	struct iscsi_portal_group *tpg,
466e48354ceSNicholas Bellinger 	struct __kernel_sockaddr_storage *sockaddr,
467e48354ceSNicholas Bellinger 	char *ip_str,
468e48354ceSNicholas Bellinger 	struct iscsi_tpg_np *tpg_np_parent,
469e48354ceSNicholas Bellinger 	int network_transport)
470e48354ceSNicholas Bellinger {
471e48354ceSNicholas Bellinger 	struct iscsi_np *np;
472e48354ceSNicholas Bellinger 	struct iscsi_tpg_np *tpg_np;
473e48354ceSNicholas Bellinger 
4746e545935SNicholas Bellinger 	if (!tpg_np_parent) {
4756e545935SNicholas Bellinger 		if (iscsit_tpg_check_network_portal(tpg->tpg_tiqn, sockaddr,
4766e545935SNicholas Bellinger 				network_transport) == true) {
4776e545935SNicholas Bellinger 			pr_err("Network Portal: %s already exists on a"
4786e545935SNicholas Bellinger 				" different TPG on %s\n", ip_str,
4796e545935SNicholas Bellinger 				tpg->tpg_tiqn->tiqn);
4806e545935SNicholas Bellinger 			return ERR_PTR(-EEXIST);
4816e545935SNicholas Bellinger 		}
4826e545935SNicholas Bellinger 	}
4836e545935SNicholas Bellinger 
484e48354ceSNicholas Bellinger 	tpg_np = kzalloc(sizeof(struct iscsi_tpg_np), GFP_KERNEL);
485e48354ceSNicholas Bellinger 	if (!tpg_np) {
486e48354ceSNicholas Bellinger 		pr_err("Unable to allocate memory for"
487e48354ceSNicholas Bellinger 				" struct iscsi_tpg_np.\n");
488e48354ceSNicholas Bellinger 		return ERR_PTR(-ENOMEM);
489e48354ceSNicholas Bellinger 	}
490e48354ceSNicholas Bellinger 
491e48354ceSNicholas Bellinger 	np = iscsit_add_np(sockaddr, ip_str, network_transport);
492e48354ceSNicholas Bellinger 	if (IS_ERR(np)) {
493e48354ceSNicholas Bellinger 		kfree(tpg_np);
494e48354ceSNicholas Bellinger 		return ERR_CAST(np);
495e48354ceSNicholas Bellinger 	}
496e48354ceSNicholas Bellinger 
497e48354ceSNicholas Bellinger 	INIT_LIST_HEAD(&tpg_np->tpg_np_list);
498e48354ceSNicholas Bellinger 	INIT_LIST_HEAD(&tpg_np->tpg_np_child_list);
499e48354ceSNicholas Bellinger 	INIT_LIST_HEAD(&tpg_np->tpg_np_parent_list);
500e48354ceSNicholas Bellinger 	spin_lock_init(&tpg_np->tpg_np_parent_lock);
501d381a801SNicholas Bellinger 	init_completion(&tpg_np->tpg_np_comp);
502d381a801SNicholas Bellinger 	kref_init(&tpg_np->tpg_np_kref);
503e48354ceSNicholas Bellinger 	tpg_np->tpg_np		= np;
5045b168dcdSSagi Grimberg 	np->tpg_np		= tpg_np;
505e48354ceSNicholas Bellinger 	tpg_np->tpg		= tpg;
506e48354ceSNicholas Bellinger 
507e48354ceSNicholas Bellinger 	spin_lock(&tpg->tpg_np_lock);
508e48354ceSNicholas Bellinger 	list_add_tail(&tpg_np->tpg_np_list, &tpg->tpg_gnp_list);
509e48354ceSNicholas Bellinger 	tpg->num_tpg_nps++;
510e48354ceSNicholas Bellinger 	if (tpg->tpg_tiqn)
511e48354ceSNicholas Bellinger 		tpg->tpg_tiqn->tiqn_num_tpg_nps++;
512e48354ceSNicholas Bellinger 	spin_unlock(&tpg->tpg_np_lock);
513e48354ceSNicholas Bellinger 
514e48354ceSNicholas Bellinger 	if (tpg_np_parent) {
515e48354ceSNicholas Bellinger 		tpg_np->tpg_np_parent = tpg_np_parent;
516e48354ceSNicholas Bellinger 		spin_lock(&tpg_np_parent->tpg_np_parent_lock);
517e48354ceSNicholas Bellinger 		list_add_tail(&tpg_np->tpg_np_child_list,
518e48354ceSNicholas Bellinger 			&tpg_np_parent->tpg_np_parent_list);
519e48354ceSNicholas Bellinger 		spin_unlock(&tpg_np_parent->tpg_np_parent_lock);
520e48354ceSNicholas Bellinger 	}
521e48354ceSNicholas Bellinger 
522e48354ceSNicholas Bellinger 	pr_debug("CORE[%s] - Added Network Portal: %s:%hu,%hu on %s\n",
523e48354ceSNicholas Bellinger 		tpg->tpg_tiqn->tiqn, np->np_ip, np->np_port, tpg->tpgt,
524baa4d64bSNicholas Bellinger 		np->np_transport->name);
525e48354ceSNicholas Bellinger 
526e48354ceSNicholas Bellinger 	return tpg_np;
527e48354ceSNicholas Bellinger }
528e48354ceSNicholas Bellinger 
529e48354ceSNicholas Bellinger static int iscsit_tpg_release_np(
530e48354ceSNicholas Bellinger 	struct iscsi_tpg_np *tpg_np,
531e48354ceSNicholas Bellinger 	struct iscsi_portal_group *tpg,
532e48354ceSNicholas Bellinger 	struct iscsi_np *np)
533e48354ceSNicholas Bellinger {
534a91eb7d9SNicholas Bellinger 	iscsit_clear_tpg_np_login_thread(tpg_np, tpg, true);
535e48354ceSNicholas Bellinger 
536e48354ceSNicholas Bellinger 	pr_debug("CORE[%s] - Removed Network Portal: %s:%hu,%hu on %s\n",
537e48354ceSNicholas Bellinger 		tpg->tpg_tiqn->tiqn, np->np_ip, np->np_port, tpg->tpgt,
538baa4d64bSNicholas Bellinger 		np->np_transport->name);
539e48354ceSNicholas Bellinger 
540e48354ceSNicholas Bellinger 	tpg_np->tpg_np = NULL;
541e48354ceSNicholas Bellinger 	tpg_np->tpg = NULL;
542e48354ceSNicholas Bellinger 	kfree(tpg_np);
543e48354ceSNicholas Bellinger 	/*
544e48354ceSNicholas Bellinger 	 * iscsit_del_np() will shutdown struct iscsi_np when last TPG reference is released.
545e48354ceSNicholas Bellinger 	 */
546e48354ceSNicholas Bellinger 	return iscsit_del_np(np);
547e48354ceSNicholas Bellinger }
548e48354ceSNicholas Bellinger 
549e48354ceSNicholas Bellinger int iscsit_tpg_del_network_portal(
550e48354ceSNicholas Bellinger 	struct iscsi_portal_group *tpg,
551e48354ceSNicholas Bellinger 	struct iscsi_tpg_np *tpg_np)
552e48354ceSNicholas Bellinger {
553e48354ceSNicholas Bellinger 	struct iscsi_np *np;
554e48354ceSNicholas Bellinger 	struct iscsi_tpg_np *tpg_np_child, *tpg_np_child_tmp;
555e48354ceSNicholas Bellinger 	int ret = 0;
556e48354ceSNicholas Bellinger 
557e48354ceSNicholas Bellinger 	np = tpg_np->tpg_np;
558e48354ceSNicholas Bellinger 	if (!np) {
559e48354ceSNicholas Bellinger 		pr_err("Unable to locate struct iscsi_np from"
560e48354ceSNicholas Bellinger 				" struct iscsi_tpg_np\n");
561e48354ceSNicholas Bellinger 		return -EINVAL;
562e48354ceSNicholas Bellinger 	}
563e48354ceSNicholas Bellinger 
564e48354ceSNicholas Bellinger 	if (!tpg_np->tpg_np_parent) {
565e48354ceSNicholas Bellinger 		/*
566e48354ceSNicholas Bellinger 		 * We are the parent tpg network portal.  Release all of the
567e48354ceSNicholas Bellinger 		 * child tpg_np's (eg: the non ISCSI_TCP ones) on our parent
568e48354ceSNicholas Bellinger 		 * list first.
569e48354ceSNicholas Bellinger 		 */
570e48354ceSNicholas Bellinger 		list_for_each_entry_safe(tpg_np_child, tpg_np_child_tmp,
571e48354ceSNicholas Bellinger 				&tpg_np->tpg_np_parent_list,
572e48354ceSNicholas Bellinger 				tpg_np_child_list) {
573e48354ceSNicholas Bellinger 			ret = iscsit_tpg_del_network_portal(tpg, tpg_np_child);
574e48354ceSNicholas Bellinger 			if (ret < 0)
575e48354ceSNicholas Bellinger 				pr_err("iscsit_tpg_del_network_portal()"
576e48354ceSNicholas Bellinger 					" failed: %d\n", ret);
577e48354ceSNicholas Bellinger 		}
578e48354ceSNicholas Bellinger 	} else {
579e48354ceSNicholas Bellinger 		/*
580e48354ceSNicholas Bellinger 		 * We are not the parent ISCSI_TCP tpg network portal.  Release
581e48354ceSNicholas Bellinger 		 * our own network portals from the child list.
582e48354ceSNicholas Bellinger 		 */
583e48354ceSNicholas Bellinger 		spin_lock(&tpg_np->tpg_np_parent->tpg_np_parent_lock);
584e48354ceSNicholas Bellinger 		list_del(&tpg_np->tpg_np_child_list);
585e48354ceSNicholas Bellinger 		spin_unlock(&tpg_np->tpg_np_parent->tpg_np_parent_lock);
586e48354ceSNicholas Bellinger 	}
587e48354ceSNicholas Bellinger 
588e48354ceSNicholas Bellinger 	spin_lock(&tpg->tpg_np_lock);
589e48354ceSNicholas Bellinger 	list_del(&tpg_np->tpg_np_list);
590e48354ceSNicholas Bellinger 	tpg->num_tpg_nps--;
591e48354ceSNicholas Bellinger 	if (tpg->tpg_tiqn)
592e48354ceSNicholas Bellinger 		tpg->tpg_tiqn->tiqn_num_tpg_nps--;
593e48354ceSNicholas Bellinger 	spin_unlock(&tpg->tpg_np_lock);
594e48354ceSNicholas Bellinger 
595e48354ceSNicholas Bellinger 	return iscsit_tpg_release_np(tpg_np, tpg, np);
596e48354ceSNicholas Bellinger }
597e48354ceSNicholas Bellinger 
598e48354ceSNicholas Bellinger int iscsit_tpg_set_initiator_node_queue_depth(
599e48354ceSNicholas Bellinger 	struct iscsi_portal_group *tpg,
600e48354ceSNicholas Bellinger 	unsigned char *initiatorname,
601e48354ceSNicholas Bellinger 	u32 queue_depth,
602e48354ceSNicholas Bellinger 	int force)
603e48354ceSNicholas Bellinger {
604e48354ceSNicholas Bellinger 	return core_tpg_set_initiator_node_queue_depth(&tpg->tpg_se_tpg,
605e48354ceSNicholas Bellinger 		initiatorname, queue_depth, force);
606e48354ceSNicholas Bellinger }
607e48354ceSNicholas Bellinger 
608e48354ceSNicholas Bellinger int iscsit_ta_authentication(struct iscsi_portal_group *tpg, u32 authentication)
609e48354ceSNicholas Bellinger {
610e48354ceSNicholas Bellinger 	unsigned char buf1[256], buf2[256], *none = NULL;
611e48354ceSNicholas Bellinger 	int len;
612e48354ceSNicholas Bellinger 	struct iscsi_param *param;
613e48354ceSNicholas Bellinger 	struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
614e48354ceSNicholas Bellinger 
615e48354ceSNicholas Bellinger 	if ((authentication != 1) && (authentication != 0)) {
616e48354ceSNicholas Bellinger 		pr_err("Illegal value for authentication parameter:"
617e48354ceSNicholas Bellinger 			" %u, ignoring request.\n", authentication);
618617a0c2eSAndy Grover 		return -EINVAL;
619e48354ceSNicholas Bellinger 	}
620e48354ceSNicholas Bellinger 
621e48354ceSNicholas Bellinger 	memset(buf1, 0, sizeof(buf1));
622e48354ceSNicholas Bellinger 	memset(buf2, 0, sizeof(buf2));
623e48354ceSNicholas Bellinger 
624e48354ceSNicholas Bellinger 	param = iscsi_find_param_from_key(AUTHMETHOD, tpg->param_list);
625e48354ceSNicholas Bellinger 	if (!param)
626e48354ceSNicholas Bellinger 		return -EINVAL;
627e48354ceSNicholas Bellinger 
628e48354ceSNicholas Bellinger 	if (authentication) {
629e48354ceSNicholas Bellinger 		snprintf(buf1, sizeof(buf1), "%s", param->value);
630e48354ceSNicholas Bellinger 		none = strstr(buf1, NONE);
631e48354ceSNicholas Bellinger 		if (!none)
632e48354ceSNicholas Bellinger 			goto out;
633e48354ceSNicholas Bellinger 		if (!strncmp(none + 4, ",", 1)) {
634e48354ceSNicholas Bellinger 			if (!strcmp(buf1, none))
635e48354ceSNicholas Bellinger 				sprintf(buf2, "%s", none+5);
636e48354ceSNicholas Bellinger 			else {
637e48354ceSNicholas Bellinger 				none--;
638e48354ceSNicholas Bellinger 				*none = '\0';
639e48354ceSNicholas Bellinger 				len = sprintf(buf2, "%s", buf1);
640e48354ceSNicholas Bellinger 				none += 5;
641e48354ceSNicholas Bellinger 				sprintf(buf2 + len, "%s", none);
642e48354ceSNicholas Bellinger 			}
643e48354ceSNicholas Bellinger 		} else {
644e48354ceSNicholas Bellinger 			none--;
645e48354ceSNicholas Bellinger 			*none = '\0';
646e48354ceSNicholas Bellinger 			sprintf(buf2, "%s", buf1);
647e48354ceSNicholas Bellinger 		}
648e48354ceSNicholas Bellinger 		if (iscsi_update_param_value(param, buf2) < 0)
649e48354ceSNicholas Bellinger 			return -EINVAL;
650e48354ceSNicholas Bellinger 	} else {
651e48354ceSNicholas Bellinger 		snprintf(buf1, sizeof(buf1), "%s", param->value);
652e48354ceSNicholas Bellinger 		none = strstr(buf1, NONE);
653ee1b1b9cSAndy Grover 		if (none)
654e48354ceSNicholas Bellinger 			goto out;
655e48354ceSNicholas Bellinger 		strncat(buf1, ",", strlen(","));
656e48354ceSNicholas Bellinger 		strncat(buf1, NONE, strlen(NONE));
657e48354ceSNicholas Bellinger 		if (iscsi_update_param_value(param, buf1) < 0)
658e48354ceSNicholas Bellinger 			return -EINVAL;
659e48354ceSNicholas Bellinger 	}
660e48354ceSNicholas Bellinger 
661e48354ceSNicholas Bellinger out:
662e48354ceSNicholas Bellinger 	a->authentication = authentication;
663e48354ceSNicholas Bellinger 	pr_debug("%s iSCSI Authentication Methods for TPG: %hu.\n",
664e48354ceSNicholas Bellinger 		a->authentication ? "Enforcing" : "Disabling", tpg->tpgt);
665e48354ceSNicholas Bellinger 
666e48354ceSNicholas Bellinger 	return 0;
667e48354ceSNicholas Bellinger }
668e48354ceSNicholas Bellinger 
669e48354ceSNicholas Bellinger int iscsit_ta_login_timeout(
670e48354ceSNicholas Bellinger 	struct iscsi_portal_group *tpg,
671e48354ceSNicholas Bellinger 	u32 login_timeout)
672e48354ceSNicholas Bellinger {
673e48354ceSNicholas Bellinger 	struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
674e48354ceSNicholas Bellinger 
675e48354ceSNicholas Bellinger 	if (login_timeout > TA_LOGIN_TIMEOUT_MAX) {
676e48354ceSNicholas Bellinger 		pr_err("Requested Login Timeout %u larger than maximum"
677e48354ceSNicholas Bellinger 			" %u\n", login_timeout, TA_LOGIN_TIMEOUT_MAX);
678e48354ceSNicholas Bellinger 		return -EINVAL;
679e48354ceSNicholas Bellinger 	} else if (login_timeout < TA_LOGIN_TIMEOUT_MIN) {
680e48354ceSNicholas Bellinger 		pr_err("Requested Logout Timeout %u smaller than"
681e48354ceSNicholas Bellinger 			" minimum %u\n", login_timeout, TA_LOGIN_TIMEOUT_MIN);
682e48354ceSNicholas Bellinger 		return -EINVAL;
683e48354ceSNicholas Bellinger 	}
684e48354ceSNicholas Bellinger 
685e48354ceSNicholas Bellinger 	a->login_timeout = login_timeout;
686e48354ceSNicholas Bellinger 	pr_debug("Set Logout Timeout to %u for Target Portal Group"
687e48354ceSNicholas Bellinger 		" %hu\n", a->login_timeout, tpg->tpgt);
688e48354ceSNicholas Bellinger 
689e48354ceSNicholas Bellinger 	return 0;
690e48354ceSNicholas Bellinger }
691e48354ceSNicholas Bellinger 
692e48354ceSNicholas Bellinger int iscsit_ta_netif_timeout(
693e48354ceSNicholas Bellinger 	struct iscsi_portal_group *tpg,
694e48354ceSNicholas Bellinger 	u32 netif_timeout)
695e48354ceSNicholas Bellinger {
696e48354ceSNicholas Bellinger 	struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
697e48354ceSNicholas Bellinger 
698e48354ceSNicholas Bellinger 	if (netif_timeout > TA_NETIF_TIMEOUT_MAX) {
699e48354ceSNicholas Bellinger 		pr_err("Requested Network Interface Timeout %u larger"
700e48354ceSNicholas Bellinger 			" than maximum %u\n", netif_timeout,
701e48354ceSNicholas Bellinger 				TA_NETIF_TIMEOUT_MAX);
702e48354ceSNicholas Bellinger 		return -EINVAL;
703e48354ceSNicholas Bellinger 	} else if (netif_timeout < TA_NETIF_TIMEOUT_MIN) {
704e48354ceSNicholas Bellinger 		pr_err("Requested Network Interface Timeout %u smaller"
705e48354ceSNicholas Bellinger 			" than minimum %u\n", netif_timeout,
706e48354ceSNicholas Bellinger 				TA_NETIF_TIMEOUT_MIN);
707e48354ceSNicholas Bellinger 		return -EINVAL;
708e48354ceSNicholas Bellinger 	}
709e48354ceSNicholas Bellinger 
710e48354ceSNicholas Bellinger 	a->netif_timeout = netif_timeout;
711e48354ceSNicholas Bellinger 	pr_debug("Set Network Interface Timeout to %u for"
712e48354ceSNicholas Bellinger 		" Target Portal Group %hu\n", a->netif_timeout, tpg->tpgt);
713e48354ceSNicholas Bellinger 
714e48354ceSNicholas Bellinger 	return 0;
715e48354ceSNicholas Bellinger }
716e48354ceSNicholas Bellinger 
717e48354ceSNicholas Bellinger int iscsit_ta_generate_node_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 
728e48354ceSNicholas Bellinger 	a->generate_node_acls = flag;
729e48354ceSNicholas Bellinger 	pr_debug("iSCSI_TPG[%hu] - Generate Initiator Portal Group ACLs: %s\n",
730e48354ceSNicholas Bellinger 		tpg->tpgt, (a->generate_node_acls) ? "Enabled" : "Disabled");
731e48354ceSNicholas Bellinger 
73238b11baeSNicholas Bellinger 	if (flag == 1 && a->cache_dynamic_acls == 0) {
73338b11baeSNicholas Bellinger 		pr_debug("Explicitly setting cache_dynamic_acls=1 when "
73438b11baeSNicholas Bellinger 			"generate_node_acls=1\n");
73538b11baeSNicholas Bellinger 		a->cache_dynamic_acls = 1;
73638b11baeSNicholas Bellinger 	}
73738b11baeSNicholas Bellinger 
738e48354ceSNicholas Bellinger 	return 0;
739e48354ceSNicholas Bellinger }
740e48354ceSNicholas Bellinger 
741e48354ceSNicholas Bellinger int iscsit_ta_default_cmdsn_depth(
742e48354ceSNicholas Bellinger 	struct iscsi_portal_group *tpg,
743e48354ceSNicholas Bellinger 	u32 tcq_depth)
744e48354ceSNicholas Bellinger {
745e48354ceSNicholas Bellinger 	struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
746e48354ceSNicholas Bellinger 
747e48354ceSNicholas Bellinger 	if (tcq_depth > TA_DEFAULT_CMDSN_DEPTH_MAX) {
748e48354ceSNicholas Bellinger 		pr_err("Requested Default Queue Depth: %u larger"
749e48354ceSNicholas Bellinger 			" than maximum %u\n", tcq_depth,
750e48354ceSNicholas Bellinger 				TA_DEFAULT_CMDSN_DEPTH_MAX);
751e48354ceSNicholas Bellinger 		return -EINVAL;
752e48354ceSNicholas Bellinger 	} else if (tcq_depth < TA_DEFAULT_CMDSN_DEPTH_MIN) {
753e48354ceSNicholas Bellinger 		pr_err("Requested Default Queue Depth: %u smaller"
754e48354ceSNicholas Bellinger 			" than minimum %u\n", tcq_depth,
755e48354ceSNicholas Bellinger 				TA_DEFAULT_CMDSN_DEPTH_MIN);
756e48354ceSNicholas Bellinger 		return -EINVAL;
757e48354ceSNicholas Bellinger 	}
758e48354ceSNicholas Bellinger 
759e48354ceSNicholas Bellinger 	a->default_cmdsn_depth = tcq_depth;
760e48354ceSNicholas Bellinger 	pr_debug("iSCSI_TPG[%hu] - Set Default CmdSN TCQ Depth to %u\n",
761e48354ceSNicholas Bellinger 		tpg->tpgt, a->default_cmdsn_depth);
762e48354ceSNicholas Bellinger 
763e48354ceSNicholas Bellinger 	return 0;
764e48354ceSNicholas Bellinger }
765e48354ceSNicholas Bellinger 
766e48354ceSNicholas Bellinger int iscsit_ta_cache_dynamic_acls(
767e48354ceSNicholas Bellinger 	struct iscsi_portal_group *tpg,
768e48354ceSNicholas Bellinger 	u32 flag)
769e48354ceSNicholas Bellinger {
770e48354ceSNicholas Bellinger 	struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
771e48354ceSNicholas Bellinger 
772e48354ceSNicholas Bellinger 	if ((flag != 0) && (flag != 1)) {
773e48354ceSNicholas Bellinger 		pr_err("Illegal value %d\n", flag);
774e48354ceSNicholas Bellinger 		return -EINVAL;
775e48354ceSNicholas Bellinger 	}
776e48354ceSNicholas Bellinger 
77738b11baeSNicholas Bellinger 	if (a->generate_node_acls == 1 && flag == 0) {
77838b11baeSNicholas Bellinger 		pr_debug("Skipping cache_dynamic_acls=0 when"
77938b11baeSNicholas Bellinger 			" generate_node_acls=1\n");
78038b11baeSNicholas Bellinger 		return 0;
78138b11baeSNicholas Bellinger 	}
78238b11baeSNicholas Bellinger 
783e48354ceSNicholas Bellinger 	a->cache_dynamic_acls = flag;
784e48354ceSNicholas Bellinger 	pr_debug("iSCSI_TPG[%hu] - Cache Dynamic Initiator Portal Group"
785e48354ceSNicholas Bellinger 		" ACLs %s\n", tpg->tpgt, (a->cache_dynamic_acls) ?
786e48354ceSNicholas Bellinger 		"Enabled" : "Disabled");
787e48354ceSNicholas Bellinger 
788e48354ceSNicholas Bellinger 	return 0;
789e48354ceSNicholas Bellinger }
790e48354ceSNicholas Bellinger 
791e48354ceSNicholas Bellinger int iscsit_ta_demo_mode_write_protect(
792e48354ceSNicholas Bellinger 	struct iscsi_portal_group *tpg,
793e48354ceSNicholas Bellinger 	u32 flag)
794e48354ceSNicholas Bellinger {
795e48354ceSNicholas Bellinger 	struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
796e48354ceSNicholas Bellinger 
797e48354ceSNicholas Bellinger 	if ((flag != 0) && (flag != 1)) {
798e48354ceSNicholas Bellinger 		pr_err("Illegal value %d\n", flag);
799e48354ceSNicholas Bellinger 		return -EINVAL;
800e48354ceSNicholas Bellinger 	}
801e48354ceSNicholas Bellinger 
802e48354ceSNicholas Bellinger 	a->demo_mode_write_protect = flag;
803e48354ceSNicholas Bellinger 	pr_debug("iSCSI_TPG[%hu] - Demo Mode Write Protect bit: %s\n",
804e48354ceSNicholas Bellinger 		tpg->tpgt, (a->demo_mode_write_protect) ? "ON" : "OFF");
805e48354ceSNicholas Bellinger 
806e48354ceSNicholas Bellinger 	return 0;
807e48354ceSNicholas Bellinger }
808e48354ceSNicholas Bellinger 
809e48354ceSNicholas Bellinger int iscsit_ta_prod_mode_write_protect(
810e48354ceSNicholas Bellinger 	struct iscsi_portal_group *tpg,
811e48354ceSNicholas Bellinger 	u32 flag)
812e48354ceSNicholas Bellinger {
813e48354ceSNicholas Bellinger 	struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
814e48354ceSNicholas Bellinger 
815e48354ceSNicholas Bellinger 	if ((flag != 0) && (flag != 1)) {
816e48354ceSNicholas Bellinger 		pr_err("Illegal value %d\n", flag);
817e48354ceSNicholas Bellinger 		return -EINVAL;
818e48354ceSNicholas Bellinger 	}
819e48354ceSNicholas Bellinger 
820e48354ceSNicholas Bellinger 	a->prod_mode_write_protect = flag;
821e48354ceSNicholas Bellinger 	pr_debug("iSCSI_TPG[%hu] - Production Mode Write Protect bit:"
822e48354ceSNicholas Bellinger 		" %s\n", tpg->tpgt, (a->prod_mode_write_protect) ?
823e48354ceSNicholas Bellinger 		"ON" : "OFF");
824e48354ceSNicholas Bellinger 
825e48354ceSNicholas Bellinger 	return 0;
826e48354ceSNicholas Bellinger }
8274c54b6cfSThomas Glanzmann 
8284c54b6cfSThomas Glanzmann int iscsit_ta_demo_mode_discovery(
8294c54b6cfSThomas Glanzmann 	struct iscsi_portal_group *tpg,
8304c54b6cfSThomas Glanzmann 	u32 flag)
8314c54b6cfSThomas Glanzmann {
8324c54b6cfSThomas Glanzmann 	struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
8334c54b6cfSThomas Glanzmann 
8344c54b6cfSThomas Glanzmann 	if ((flag != 0) && (flag != 1)) {
8354c54b6cfSThomas Glanzmann 		pr_err("Illegal value %d\n", flag);
8364c54b6cfSThomas Glanzmann 		return -EINVAL;
8374c54b6cfSThomas Glanzmann 	}
8384c54b6cfSThomas Glanzmann 
8394c54b6cfSThomas Glanzmann 	a->demo_mode_discovery = flag;
8404c54b6cfSThomas Glanzmann 	pr_debug("iSCSI_TPG[%hu] - Demo Mode Discovery bit:"
8414c54b6cfSThomas Glanzmann 		" %s\n", tpg->tpgt, (a->demo_mode_discovery) ?
8424c54b6cfSThomas Glanzmann 		"ON" : "OFF");
8434c54b6cfSThomas Glanzmann 
8444c54b6cfSThomas Glanzmann 	return 0;
8454c54b6cfSThomas Glanzmann }
846d1fa7a1dSNicholas Bellinger 
847d1fa7a1dSNicholas Bellinger int iscsit_ta_default_erl(
848d1fa7a1dSNicholas Bellinger 	struct iscsi_portal_group *tpg,
849d1fa7a1dSNicholas Bellinger 	u32 default_erl)
850d1fa7a1dSNicholas Bellinger {
851d1fa7a1dSNicholas Bellinger 	struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
852d1fa7a1dSNicholas Bellinger 
853d1fa7a1dSNicholas Bellinger 	if ((default_erl != 0) && (default_erl != 1) && (default_erl != 2)) {
854d1fa7a1dSNicholas Bellinger 		pr_err("Illegal value for default_erl: %u\n", default_erl);
855d1fa7a1dSNicholas Bellinger 		return -EINVAL;
856d1fa7a1dSNicholas Bellinger 	}
857d1fa7a1dSNicholas Bellinger 
858d1fa7a1dSNicholas Bellinger 	a->default_erl = default_erl;
859d1fa7a1dSNicholas Bellinger 	pr_debug("iSCSI_TPG[%hu] - DefaultERL: %u\n", tpg->tpgt, a->default_erl);
860d1fa7a1dSNicholas Bellinger 
861d1fa7a1dSNicholas Bellinger 	return 0;
862d1fa7a1dSNicholas Bellinger }
8638085176fSSagi Grimberg 
8648085176fSSagi Grimberg int iscsit_ta_t10_pi(
8658085176fSSagi Grimberg 	struct iscsi_portal_group *tpg,
8668085176fSSagi Grimberg 	u32 flag)
8678085176fSSagi Grimberg {
8688085176fSSagi Grimberg 	struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
8698085176fSSagi Grimberg 
8708085176fSSagi Grimberg 	if ((flag != 0) && (flag != 1)) {
8718085176fSSagi Grimberg 		pr_err("Illegal value %d\n", flag);
8728085176fSSagi Grimberg 		return -EINVAL;
8738085176fSSagi Grimberg 	}
8748085176fSSagi Grimberg 
8758085176fSSagi Grimberg 	a->t10_pi = flag;
8768085176fSSagi Grimberg 	pr_debug("iSCSI_TPG[%hu] - T10 Protection information bit:"
8778085176fSSagi Grimberg 		" %s\n", tpg->tpgt, (a->t10_pi) ?
8788085176fSSagi Grimberg 		"ON" : "OFF");
8798085176fSSagi Grimberg 
8808085176fSSagi Grimberg 	return 0;
8818085176fSSagi Grimberg }
882