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
40 extern "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  */
118 int
119 it_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  */
139 int
140 it_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  */
164 int
165 it_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  */
175 void
176 it_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  */
206 int
207 it_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  */
232 int
233 it_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  */
257 int
258 it_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  */
289 int
290 it_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  */
308 void
309 it_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  */
338 int
339 it_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  */
363 int
364 it_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  */
390 int
391 it_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  */
409 void
410 it_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  */
433 int
434 it_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  */
457 int
458 it_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  */
473 void
474 it_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  */
484 void
485 it_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  */
493 void
494 it_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  */
502 void
503 it_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  */
511 void
512 it_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  */
520 void
521 it_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  */
528 boolean_t
529 validate_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  */
538 void
539 canonical_iscsi_name(char *tgt);
540 
541 #ifdef	__cplusplus
542 }
543 #endif
544 
545 #endif	/* _LIBISCSIT_H */
546