1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23 * Use is subject to license terms.
24 */
25/*
26 * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
27 */
28
29#ifndef	_LIBISCSIT_H
30#define	_LIBISCSIT_H
31
32#ifndef _KERNEL
33#include <libnvpair.h>
34#include <sys/socket.h>
35#endif
36
37#include <sys/iscsit/iscsit_common.h>
38
39#ifdef	__cplusplus
40extern "C" {
41#endif
42
43#define	MAX_TARGETS	4095 /* maximum targets that may be created */
44#define	MAX_TPGT	256
45#define	CFG_TPGTLIST	"tpgt-list"
46
47#define	IS_IQN_NAME(s) (strncmp((s), "iqn.", 4) == 0)
48#define	IS_EUI_NAME(s) (strncmp((s), "eui.", 4) == 0)
49
50/*
51 * We change the default IQN here to org.illumos.
52 * Other distros using it need to change accordingly.
53 */
54
55#define	DEFAULT_IQN	"iqn.2010-08.org.illumos:"
56
57/*
58 * Object Hierarchy
59 *
60 *  _______________________
61 * |                       |
62 * |  iSCSI Target Config  |
63 * |      it_config_t      |
64 * |_______________________|
65 *    |     |
66 *    |     |
67 *    |     |      ________     ________              ________
68 *    |     |     |        |   |        |            |        |
69 *    |     |     | Target |-->| Target |--  - -  -->| Target |
70 *    |     |     |________|   |________|            |________|
71 *    |     |           |
72 *    |     |           |
73 *    |     |           |
74 *    |     |           |       ______              ______
75 *    |     |           |      |      |            |      |
76 *    |     |           +----->| TPGT |--  - -  -->| TPGT |
77 *    |     |                  |______|            |______|
78 *    |     |                       |                   |
79 *    |  +--+                       |                   |
80 *    |  |   _______     _______    |         ______    |
81 *    |  |  |       |   |       |<--+        |      |<--+
82 *    |  +->|  TPG  |-->|  TPG  |--  - -  -->| TPG  |
83 *    |     |_______|   |_______|            |______|
84 *    |
85 *    |      ___________     ___________              ___________
86 *    |     |           |   |           |            |           |
87 *    +---->| Initiator |-->| Initiator |--  - -  -->| Initiator |
88 *          |  Context  |   |  Context  |            |  Context  |
89 *          |___________|   |___________|            |___________|
90 *
91 *
92 * it_config_t includes a list of global properties
93 *
94 * Targets include a list of properties which override the global properties
95 * if set
96 *
97 * Initiators also include a list of properties but never inherit properties
98 * from the global config.
99 */
100
101/*
102 * Function:  it_config_load()
103 *
104 * Allocate and create an it_config_t structure representing the
105 * current iSCSI configuration.  This structure is compiled using
106 * the 'provider' data returned by stmfGetProviderData().  If there
107 * is no provider data associated with iscsit, the it_config_t
108 * structure will be set to a default configuration.
109 *
110 * Parameters:
111 *    cfg		A C representation of the current iSCSI configuration
112 *
113 * Return Values:
114 *    0			Success
115 *    ENOMEM		Could not allocate resources
116 *    EINVAL		Invalid parameter
117 */
118int
119it_config_load(it_config_t **cfg);
120
121/*
122 * Function:  it_config_commit()
123 *
124 * Informs the iscsit service that the configuration has changed and
125 * commits the new configuration to persistent store by calling
126 * stmfSetProviderData.  This function can be called multiple times
127 * during a configuration sequence if necessary.
128 *
129 * Parameters:
130 *    cfg		A C representation of the current iSCSI configuration
131 *
132 * Return Values:
133 *    0			Success
134 *    ENOMEM		Could not allocate resources
135 *    EINVAL		Invalid it_config_t structure
136 *    STMF_ERROR_SERVICE_DATA_VERSION	Configuration was updated by another
137 *			client.  See stmfSetProviderDataProt().
138 */
139int
140it_config_commit(it_config_t *cfg);
141
142/*
143 * Function:  it_config_setprop()
144 *
145 * Validate the provided property list and set the global properties
146 * for iSCSI Target.  If errlist is not NULL, returns detailed
147 * errors for each property that failed.  The format for errorlist
148 * is key = property, value = error string.
149 *
150 * Parameters:
151 *
152 *    cfg		The current iSCSI configuration obtained from
153 *			it_config_load()
154 *    proplist		nvlist_t containing properties for this target.
155 *    errlist		(optional)  nvlist_t of errors encountered when
156 *			validating the properties.
157 *
158 * Return Values:
159 *    0			Success
160 *    ENOMEM		Could not allocate resources
161 *    EINVAL		Invalid property
162 *
163 */
164int
165it_config_setprop(it_config_t *cfg, nvlist_t *proplist, nvlist_t **errlist);
166
167/*
168 * Function:  it_config_free()
169 *
170 * Free any resources associated with the it_config_t structure.
171 *
172 * Parameters:
173 *    cfg		A C representation of the current iSCSI configuration
174 */
175void
176it_config_free(it_config_t *cfg);
177
178/*
179 * Function:  it_tgt_create()
180 *
181 * Allocate and create an it_tgt_t structure representing a new iSCSI
182 * target node.  If tgt_name is NULL, then a unique target node name will
183 * be generated automatically.  Otherwise, the value of tgt_name will be
184 * used as the target node name.  The new it_tgt_t structure is added to
185 * the target list (cfg_tgt_list) in the configuration structure, and the
186 * new target will not be instantiated until the modified configuration
187 * is committed by calling it_config_commit().
188 *
189 * Parameters:
190 *    cfg		The current iSCSI configuration obtained from
191 *			it_config_load()
192 *    tgt		Pointer to an iSCSI target structure
193 *    tgt_name		The target node name for the target to be created.
194 *			The name must be in either IQN or EUI format.  If
195 *			this value is NULL, a node name will be generated
196 *			automatically in IQN format.
197 *
198 * Return Values:
199 *    0			Success
200 *    ENOMEM		Could not allocate resources
201 *    EINVAL		Invalid parameter or creating would create too many
202 *			targets.
203 *    EEXIST		The requested target node name is already configured
204 *    EFAULT		Invalid iSCSI target name
205 */
206int
207it_tgt_create(it_config_t *cfg, it_tgt_t **tgt, char *tgt_name);
208
209/*
210 * Function:  it_tgt_setprop()
211 *
212 * Validate the provided property list and set the properties for
213 * the specified target.  If errlist is not NULL, returns detailed
214 * errors for each property that failed.  The format for errorlist
215 * is key = property, value = error string.
216 *
217 * Parameters:
218 *
219 *    cfg		The current iSCSI configuration obtained from
220 *			it_config_load()
221 *    tgt		Pointer to an iSCSI target structure
222 *    proplist		nvlist_t containing properties for this target.
223 *    errlist		(optional)  nvlist_t of errors encountered when
224 *			validating the properties.
225 *
226 * Return Values:
227 *    0			Success
228 *    ENOMEM		Could not allocate resources
229 *    EINVAL		Invalid property
230 *
231 */
232int
233it_tgt_setprop(it_config_t *cfg, it_tgt_t *tgt, nvlist_t *proplist,
234    nvlist_t **errlist);
235
236
237/*
238 * Function:  it_tgt_delete()
239 *
240 * Delete target represented by 'tgt', where 'tgt' is an existing
241 * it_tgt_t structure within the configuration 'cfg'.  The target removal
242 * will not take effect until the modified configuration is committed
243 * by calling it_config_commit().
244 *
245 * Parameters:
246 *    cfg		The current iSCSI configuration obtained from
247 *			it_config_load()
248 *    tgt		Pointer to an iSCSI target structure
249 *    force		Set the target to offline before removing it from
250 *			the config.  If not specified, the operation will
251 *			fail if the target is determined to be online.
252 *
253 * Return Values:
254 *    0			Success
255 *    EBUSY		Target is online
256 */
257int
258it_tgt_delete(it_config_t *cfg, it_tgt_t *tgt, boolean_t force);
259
260/*
261 * Function:  it_tpgt_create()
262 *
263 * Allocate and create an it_tpgt_t structure representing a new iSCSI
264 * target portal group tag.  The new it_tpgt_t structure is added to the
265 * target tpgt list (tgt_tpgt_list) in the it_tgt_t structure.  The new
266 * target portal group tag will not be instantiated until the modified
267 * configuration is committed by calling it_config_commit().
268 *
269 * Parameters:
270 *    cfg		The current iSCSI configuration obtained from
271 *			it_config_load()
272 *    tgt		Pointer to the iSCSI target structure associated
273 *			with the target portal group tag
274 *    tpgt		Pointer to a target portal group tag structure
275 *    tpg_name		The name of the TPG to be associated with this TPGT
276 *    tpgt_tag		16-bit numerical identifier for this TPGT.  Valid
277 *			values are 2 through 65535.  If tpgt_tag is '0',
278 *			this function will assign an appropriate tag number.
279 *			If tpgt_tag is != 0, and the requested number is
280 *			unavailable, another value will be chosen.
281 *
282 * Return Values:
283 *    0			Success
284 *    ENOMEM		Could not allocate resources
285 *    EINVAL		Invalid parameter
286 *    EEXIST		Specified TPG is already associated with the target
287 *    E2BIG		All tag numbers already in use
288 */
289int
290it_tpgt_create(it_config_t *cfg, it_tgt_t *tgt, it_tpgt_t **tpgt,
291    char *tpg_name, uint16_t tpgt_tag);
292
293/*
294 * Function:  it_tpgt_delete()
295 *
296 * Delete the target portal group tag represented by 'tpgt', where
297 * 'tpgt' is an existing is_tpgt_t structure within the target 'tgt'.
298 * The target portal group tag removal will not take effect until the
299 * modified configuation is committed by calling it_config_commit().
300 *
301 * Parameters:
302 *    cfg		The current iSCSI configuration obtained from
303 *			it_config_load()
304 *    tgt		Pointer to the iSCSI target structure associated
305 *			with the target portal group tag
306 *    tpgt		Pointer to a target portal group tag structure
307 */
308void
309it_tpgt_delete(it_config_t *cfg, it_tgt_t *tgt, it_tpgt_t *tpgt);
310
311/*
312 * Function:  it_tpg_create()
313 *
314 * Allocate and create an it_tpg_t structure representing a new iSCSI
315 * target portal group.  The new it_tpg_t structure is added to the global
316 * tpg list (cfg_tgt_list) in the it_config_t structure.  The new target
317 * portal group will not be instantiated until the modified configuration
318 * is committed by calling it_config_commit().
319 *
320 * Parameters:
321 *    cfg		The current iSCSI configuration obtained from
322 *			it_config_load()
323 *    tpg		Pointer to the it_tpg_t structure representing
324 *			the target portal group
325 *    tpg_name		Identifier for the target portal group
326 *    portal_ip_port	A string containing an appropriatedly formatted
327 *			IP address:port.  Both IPv4 and IPv6 addresses are
328 *			permitted.  This value becomes the first portal in
329 *			the TPG -- applications can add additional values
330 *			using it_portal_create() before committing the TPG.
331 * Return Values:
332 *    0			Success
333 *    ENOMEM		Cannot allocate resources
334 *    EINVAL		Invalid parameter
335 *    EEXIST		Portal already configured for another portal group
336 *			associated with this target.
337 */
338int
339it_tpg_create(it_config_t *cfg, it_tpg_t **tpg, char *tpg_name,
340    char *portal_ip_port);
341
342/*
343 * Function:  it_tpg_delete()
344 *
345 * Delete target portal group represented by 'tpg', where 'tpg' is an
346 * existing it_tpg_t structure within the global configuration 'cfg'.
347 * The target portal group removal will not take effect until the
348 * modified configuration is committed by calling it_config_commit().
349 *
350 * Parameters:
351 *    cfg		The current iSCSI configuration obtained from
352 *			it_config_load()
353 *    tpg		Pointer to the it_tpg_t structure representing
354 *			the target portal group
355 *    force		Remove this target portal group even if it's
356 *			associated with one or more targets.
357 *
358 * Return Values:
359 *    0			Success
360 *    EINVAL		Invalid parameter
361 *    EBUSY		Portal group associated with one or more targets.
362 */
363int
364it_tpg_delete(it_config_t *cfg, it_tpg_t *tpg, boolean_t force);
365
366/*
367 * Function:  it_portal_create()
368 *
369 * Add an it_portal_t structure representing a new portal to the specified
370 * target portal group.  The change to the target portal group will not take
371 * effect until the modified configuration is committed by calling
372 * it_config_commit().
373 *
374 * Parameters:
375 *    cfg		The current iSCSI configration obtained from
376 *			it_config_load()
377 *    tpg		Pointer to the it_tpg_t structure representing the
378 *			target portal group or "none" to remove
379 *    portal		Pointer to the it_portal_t structure representing
380 *			the portal
381 *    portal_ip_port	A string containing an appropriately formatted
382 *			IP address or IP address:port in either IPv4 or
383 *			IPv6 format.
384 * Return Values:
385 *    0			Success
386 *    ENOMEM		Could not allocate resources
387 *    EINVAL		Invalid parameter
388 *    EEXIST		Portal already configured for another portal group
389 */
390int
391it_portal_create(it_config_t *cfg, it_tpg_t *tpg, it_portal_t **portal,
392    char *portal_ip_port);
393
394/*
395 * Function:  it_portal_delete()
396 *
397 * Remove the specified portal from the specified target portal group.
398 * The portal removal will not take effect until the modified configuration
399 * is committed by calling it_config_commit().
400 *
401 * Parameters:
402 *    cfg		The current iSCSI configration obtained from
403 *			it_config_load()
404 *    tpg		Pointer to the it_tpg_t structure representing the
405 *			target portal group
406 *    portal		Pointer to the it_portal_t structure representing
407 *			the portal
408 */
409void
410it_portal_delete(it_config_t *cfg, it_tpg_t *tpg, it_portal_t *portal);
411
412/*
413 * Function:  it_ini_create()
414 *
415 * Add an initiator context to the global configuration. The new
416 * initiator context will not be instantiated until the modified
417 * configuration is committed by calling it_config_commit().
418 *
419 * Parameters:
420 *    cfg		The current iSCSI configration obtained from
421 *			it_config_load()
422 *    ini		Pointer to the it_ini_t structure representing
423 *			the initiator context.
424 *    ini_node_name	The iSCSI node name of the remote initiator.
425 *
426 * Return Values:
427 *    0			Success
428 *    ENOMEM		Could not allocate resources
429 *    EINVAL		Invalid parameter.
430 *    EEXIST		Initiator already configured
431 *    EFAULT		Invalid initiator name
432 */
433int
434it_ini_create(it_config_t *cfg, it_ini_t **ini, char *ini_node_name);
435
436/*
437 * Function:  it_ini_setprop()
438 *
439 * Validate the provided property list and set the initiator properties.
440 * If errlist is not NULL, returns detailed errors for each property
441 * that failed.  The format for errorlist is
442 *		 key = property, value = error string.
443 *
444 * Parameters:
445 *
446 *    ini		The initiator being updated.
447 *    proplist		nvlist_t containing properties for this target.
448 *    errlist		(optional)  nvlist_t of errors encountered when
449 *			validating the properties.
450 *
451 * Return Values:
452 *    0			Success
453 *    ENOMEM		Could not allocate resources
454 *    EINVAL		Invalid property
455 *
456 */
457int
458it_ini_setprop(it_ini_t *ini, nvlist_t *proplist, nvlist_t **errlist);
459
460/*
461 * Function:  it_ini_delete()
462 *
463 * Remove the specified initiator context from the global configuration.
464 * The removal will not take effect until the modified configuration is
465 * committed by calling it_config_commit().
466 *
467 * Parameters:
468 *    cfg		The current iSCSI configration obtained from
469 *			it_config_load()
470 *    ini		Pointer to the it_ini_t structure representing
471 *			the initiator context.
472 */
473void
474it_ini_delete(it_config_t *cfg, it_ini_t *ini);
475
476/*
477 * Function:  it_config_free()
478 *
479 * Free any resources associated with the it_config_t structure.
480 *
481 * Parameters:
482 *    cfg       A C representation of the current iSCSI configuration
483 */
484void
485it_config_free(it_config_t *cfg);
486
487/*
488 * Function:  it_tgt_free()
489 *
490 * Frees an it_tgt_t structure.  If tgt_next is not NULL, frees
491 * all structures in the list.
492 */
493void
494it_tgt_free(it_tgt_t *tgt);
495
496/*
497 * Function:  it_tpgt_free()
498 *
499 * Deallocates resources of an it_tpgt_t structure.  If tpgt->next
500 * is not NULL, frees all members of the list.
501 */
502void
503it_tpgt_free(it_tpgt_t *tpgt);
504
505/*
506 * Function:  it_tpg_free()
507 *
508 * Deallocates resources associated with an it_tpg_t structure.
509 * If tpg->next is not NULL, frees all members of the list.
510 */
511void
512it_tpg_free(it_tpg_t *tpg);
513
514/*
515 * Function:  it_ini_free()
516 *
517 * Deallocates resources of an it_ini_t structure. If ini->next is
518 * not NULL, frees all members of the list.
519 */
520void
521it_ini_free(it_ini_t *ini);
522
523/*
524 * Function:  validate_iscsi_name()
525 *
526 * Ensures the passed-in string is a valid IQN or EUI iSCSI name
527 */
528boolean_t
529validate_iscsi_name(char *in_name);
530
531/*
532 * Function:  canonical_iscsi_name()
533 *
534 * Fold the iqn iscsi name to lower-case and the EUI-64 identifier of
535 * the eui iscsi name to upper-case.
536 * Ensures the passed-in string is a valid IQN or EUI iSCSI name
537 */
538void
539canonical_iscsi_name(char *tgt);
540
541#ifdef	__cplusplus
542}
543#endif
544
545#endif	/* _LIBISCSIT_H */
546