xref: /illumos-gate/usr/src/uts/common/sys/iscsit/iscsit_common.h (revision 581cede61ac9c14d8d4ea452562a567189eead78)
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 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #ifndef _ISCSIT_COMMON_H_
27 #define	_ISCSIT_COMMON_H_
28 
29 #ifdef	_KERNEL
30 #include <sys/nvpair.h>
31 #else
32 #include <libnvpair.h>
33 #endif
34 
35 #ifdef __cplusplus
36 extern "C" {
37 #endif
38 
39 #define	ISCSIT_API_VERS0		0
40 
41 #define	ISCSIT_MODNAME		"iscsit"
42 #define	ISCSIT_NODE		"/devices/pseudo/iscsit@0:iscsit"
43 
44 typedef enum {
45 	ITCFG_SUCCESS = 0,
46 	ITCFG_INVALID,
47 	ITCFG_TGT_CREATE_ERR,
48 	ITCFG_MISC_ERR
49 } it_cfg_status_t;
50 
51 /*
52  * This structure is passed back to the driver during ISCSIT_IOC_ENABLE_SVC
53  * in order to provide the fully qualified hostname for use as the EID
54  * by iSNS.
55  */
56 
57 #define	ISCSIT_MAX_HOSTNAME_LEN	256
58 
59 typedef struct iscsit_hostinfo_s {
60 	uint32_t	length;
61 	char		fqhn[ISCSIT_MAX_HOSTNAME_LEN];
62 } iscsit_hostinfo_t;
63 
64 #define	ISCSIT_IOC_SET_CONFIG		1
65 #define	ISCSIT_IOC_GET_STATE		2
66 #define	ISCSIT_IOC_ENABLE_SVC		101
67 #define	ISCSIT_IOC_DISABLE_SVC		102
68 
69 /* XXX Rationalize these with other error values (used in it_smf.c */
70 #define	ITADM_SUCCESS		0
71 #define	ITADM_FATAL_ERROR	0x1
72 #define	ITADM_NO_MEM		0x2
73 #define	ITADM_INVALID		0x4
74 #define	ITADM_NODATA		0x8
75 #define	ITADM_PERM		0x10
76 
77 
78 #define	PROP_AUTH		"auth"
79 #define	PROP_ALIAS		"alias"
80 #define	PROP_CHAP_USER		"chapuser"
81 #define	PROP_CHAP_SECRET	"chapsecret"
82 #define	PROP_TARGET_CHAP_USER	"targetchapuser"
83 #define	PROP_TARGET_CHAP_SECRET	"targetchapsecret"
84 #define	PROP_RADIUS_SERVER	"radiusserver"
85 #define	PROP_RADIUS_SECRET	"radiussecret"
86 #define	PROP_ISNS_ENABLED	"isns"
87 #define	PROP_ISNS_SERVER	"isnsserver"
88 #define	PROP_OLD_TARGET_NAME	"oldtargetname"
89 
90 #define	PA_AUTH_RADIUS		"radius"
91 #define	PA_AUTH_CHAP		"chap"
92 #define	PA_AUTH_NONE		"none"
93 
94 typedef struct {
95 	int		set_cfg_vers;
96 	int		set_cfg_pnvlist_len;
97 	caddr_t		set_cfg_pnvlist;
98 } iscsit_ioc_set_config_t;
99 
100 typedef struct {
101 	int		getst_vers;
102 	int		getst_pnvlist_len;
103 	char		*getst_pnvlist;
104 } iscsit_ioc_getstate_t;
105 
106 #ifdef _SYSCALL32
107 typedef struct {
108 	int		set_cfg_vers;
109 	int		set_cfg_pnvlist_len;
110 	caddr32_t	set_cfg_pnvlist;
111 } iscsit_ioc_set_config32_t;
112 
113 typedef struct {
114 	int		getst_vers;
115 	int		getst_pnvlist_len;
116 	caddr32_t	getst_pnvlist;
117 } iscsit_ioc_getstate32_t;
118 #endif /* _SYSCALL32 */
119 
120 /* Shared user/kernel structures */
121 /*  Maximum size of a Target Portal Group name */
122 #define	MAX_TPG_NAMELEN		256		/* XXX */
123 
124 /* Maximum size of an iSCSI Target Node name */
125 #define	MAX_ISCSI_NODENAMELEN	256		/* XXX */
126 
127 /*
128  * A target portal group tag is a binding between a target and a target
129  * portal group along with a numerical value associated with that binding.
130  * The numerical identifier is used as the 'target portal group tag' defined
131  * in RFC3720.
132  *
133  *  tpgt_tpg_name	The name of the target portal group associated with
134  *			this target portal group tag.
135  *  tpgt_generation	Generation number which is incremented each time the
136  *			structure changes.
137  *  tpgt_next		Next target portal group tag in th list of target portal
138  *			group tags.  If tpgt_next is NUL, then this is the last
139  *			target portal group in the list.
140  *  tpgt_tag		A numerical identifier that uniquely identifies a
141  *			target portal group within the associated target node.
142  */
143 typedef struct it_tpgt_s {
144 	char			tpgt_tpg_name[MAX_TPG_NAMELEN];
145 	uint64_t		tpgt_generation;
146 	struct it_tpgt_s	*tpgt_next;
147 	uint16_t		tpgt_tag;
148 } it_tpgt_t;
149 
150 /*
151  * An iSCSI target node is represented by an it_tgt_structure.  Each
152  * target node includes a list of associated target portal group tags
153  * and a list of properties.
154  *
155  *  tgt_name		The iSCSI target node name in either IQN or EUI
156  *			format (see RFC3720).
157  *  tgt_generation	Generation number which is incremented each time
158  *			the structure changes.
159  *  tgt_next		Next target in the list of targets.  If tgt_next
160  *			is NULL, then this is the last target in the list.
161  *  tgt_tpgt_list	A linked list representing the current target
162  *			portal group tags associated with this target.
163  *  tgt_tpgt_count	The number of currently defined target portal
164  *			group tags.
165  *  tgt_properties	An nvlist representation of the properties
166  *			associated with this target.  This list can be
167  *			manipulated using libnvpair(3lib), and should be
168  *			validated and stored using it_tgt_setprop().
169  *
170  * Target nvlist Properties:
171  *
172  *  nvlist Key		Type		Valid Values
173  *  --------------------------------------------------------------------
174  *  targetchapuser	string		any string or "none" to remove
175  *  targetchapsecret	string		string of at least 12 characters
176  *					but not more than 255 characters.
177  *					secret will be base64 encoded when
178  *					stored.
179  *  alias		string		any string or "none" to remove
180  *  auth		string		"radius", "chap", or "none"
181  *
182  */
183 typedef struct it_tgt_s {
184 	char			tgt_name[MAX_ISCSI_NODENAMELEN];
185 	uint64_t		tgt_generation;
186 	struct it_tgt_s		*tgt_next;
187 	it_tpgt_t		*tgt_tpgt_list;
188 	uint32_t		tgt_tpgt_count;
189 	nvlist_t		*tgt_properties;
190 } it_tgt_t;
191 
192 /*
193  * A target portal is represented by an IP address and a listening
194  * TCP port.
195  *
196  *  portal_addr		sockaddr_storage structure representing the
197  *			IPv4 or IPv6 address and TCP port associated
198  *			with the portal.
199  *  portal_next		Next portal in the list of portals.  If
200  *			portal_next is NULL, this is the last portal
201  *			in the list.
202  */
203 typedef struct it_portal_s {
204 	struct sockaddr_storage portal_addr;
205 	struct it_portal_s	*next;
206 } it_portal_t;
207 
208 /*
209  * A portal is an IP address and TCP port and a portal group is a set
210  * of portals.  Each defined portal belongs to exactly one portal group.
211  * Applications can associate a target portal group with a particular
212  * target using a target portal group name.  Initiators can only connect
213  * to targets through the portals associated with the target's target
214  * portal group tags.
215  *
216  *  tpg_name		Identifier for the target portal group.
217  *  tpg_generation	Generation number which is incremented each
218  *			time this structure changes.
219  *  tpg_next		Next target portal group in the list of target
220  *			portal groups.  If tpg_next is NULL, this is the
221  *			last target portal group in the list.
222  *  tpg_portal_count	Number of it_portal_t structures in the list.
223  *  tpg_portal_list	Linked list of it_portal_t structures.
224  */
225 typedef struct it_tpg_s {
226 	char			tpg_name[MAX_TPG_NAMELEN];
227 	uint64_t		tpg_generation;
228 	struct it_tpg_s		*tpg_next;
229 	uint32_t		tpg_portal_count;
230 	it_portal_t		*tpg_portal_list;
231 } it_tpg_t;
232 
233 /*
234  * A context representing a remote iSCSI initiator node.  The purpose
235  * of this structure is to maintain information specific to a remote
236  * initiator such as the CHAP username and CHAP secret.
237  *
238  *  ini_name		the iSCSI node name of the remote initiator.
239  *  ini_generation	Generation number which is incremented each
240  *			time this structure changes.
241  *  ini_next		Next initiator in the list of initiators.
242  *			If ini_next is NULL, this is the last initiator
243  *			in the list.
244  *  ini_properties	Name/Value list containing the properties
245  *			associated with the initiator context.  This list
246  *			can be manipulated using libnvpair(3lib), and should
247  *			be validated and stored using it_ini_setprop().
248  *
249  * Initiator nvlist Properties:
250  *
251  *  nvlist Key		Type		Valid Values
252  *  --------------------------------------------------------------------
253  *  chapuser		string		any string
254  *  chapsecret		string		string of at least 12 characters
255  *					but not more than 255 characters.
256  *					secret will be base64 encoded when
257  *					stored.
258  */
259 typedef struct it_ini_s {
260 	char		ini_name[MAX_ISCSI_NODENAMELEN];
261 	uint64_t	ini_generation;
262 	struct it_ini_s	*ini_next;
263 	nvlist_t	*ini_properties;
264 } it_ini_t;
265 
266 
267 /*
268  * This structure represents a complete configuration for the iscsit
269  * port provider.  In addition to the global configuration, it_config_t
270  * includes lists of child objects including targets, target portal
271  * groups and initiator contexts.  Each object includes a "generation"
272  * value which is used by the iscsit kernel driver to identify changes
273  * from one configuration update to the next.
274  *
275  *  stmf_token		A uint64_t that contains the value returned from a
276  *			successful call to stmfGetProviderDataProt(3STMF).
277  *			This token is used to verify that the configuration
278  *			data persistently stored in COMSTAR has not been
279  *			modified since this version was loaded.
280  *  config_version	Version number for this configuration structure
281  *  config_tgt_list	Linked list of target contexts representing the
282  *			currently defined targets.  Applications can add
283  *			targets to or remove targets from this list using
284  *			the it_tgt_create and it_tgt_delete functions.
285  *  config_tgt_count	The number of currently defined targets.
286  *  config_tpg_list	Linked list of target portal group contexts.
287  *			Applications can add or remove target portal groups
288  *			to/from this list using the it_tpg_create and
289  *			it_tpg_delete functions.
290  *  config_tpg_count	The number of currently defined target portal groups
291  *  config_ini_list	Linked list of initiator contexts.  Applications
292  *			can add initiator contexts or remove initiator
293  *			contexts from this list using the it_ini_create
294  *			and it_ini_delete functions.
295  *  config_ini_count	The number of currently defined initiator contexts.
296  *  config_global_properties
297  *			Name/Value list representing the current global
298  *			property settings.  This list can be manipulated
299  *			using libnvpair(3lib), and should be validated
300  *			and stored using it_config_setprop().
301  *  config_isns_svr_list
302  *			Linked list of currently defined iSNS servers.
303  *			Applications can add or remove iSNS servers by
304  *			using the it_config_setprop() function and changing
305  *			the array of iSNS servers stored in the "isnsserver"
306  *			property.
307  *  config_isns_svr_count
308  *			The number of currently defined iSNS servers.
309  *
310  * Global nvlist Properties:
311  *
312  *  nvlist Key		Type		Valid Values
313  *  --------------------------------------------------------------------
314  *  alias		string		any string
315  *  auth		string		"radius", "chap", or "none"
316  *  isns		boolean		B_TRUE, B_FALSE
317  *  isnsserver		string array	Array of portal specifications of
318  *					the form IPaddress:port.  Port
319  *					is optional; if not specified, the
320  *					default iSNS port number of 3205 will
321  *					be used.  IPv6 addresses should
322  *					be enclosed in square brackets '[' ']'.
323  *					If "none" is specified, all defined
324  *					iSNS servers will be removed from the
325  *					configuration.
326  *  radiusserver	string		IPaddress:port specification as
327  *					described for 'isnsserver'.
328  *  radiussecret	string		string of at least 12 characters
329  *					but not more than 255 characters.
330  *					secret will be base64 encoded when
331  *					stored.
332  */
333 typedef struct it_config_s {
334 	uint64_t		stmf_token;
335 	uint32_t		config_version;
336 	it_tgt_t		*config_tgt_list;
337 	uint32_t		config_tgt_count;
338 	it_tpg_t		*config_tpg_list;
339 	uint32_t		config_tpg_count;
340 	it_ini_t		*config_ini_list;
341 	uint32_t		config_ini_count;
342 	it_portal_t		*config_isns_svr_list;
343 	uint32_t		config_isns_svr_count;
344 	nvlist_t		*config_global_properties;
345 } it_config_t;
346 
347 
348 /*  Functions to convert iSCSI target structures to/from nvlists. */
349 int
350 it_config_to_nv(it_config_t *cfg, nvlist_t **nvl);
351 
352 /*
353  * nvlist version of config is 3 list-of-list, + 1 proplist.  arrays
354  * are interesting, but lists-of-lists are more useful when doing
355  * individual lookups when we later add support for it.  Also, no
356  * need to store name in individual struct representation.
357  */
358 int
359 it_nv_to_config(nvlist_t *nvl, it_config_t **cfg);
360 
361 int
362 it_nv_to_tgtlist(nvlist_t *nvl, uint32_t *count, it_tgt_t **tgtlist);
363 
364 int
365 it_tgtlist_to_nv(it_tgt_t *tgtlist, nvlist_t **nvl);
366 
367 int
368 it_tgt_to_nv(it_tgt_t *tgt, nvlist_t **nvl);
369 
370 int
371 it_nv_to_tgt(nvlist_t *nvl, char *name, it_tgt_t **tgt);
372 
373 int
374 it_tpgt_to_nv(it_tpgt_t *tpgt, nvlist_t **nvl);
375 
376 int
377 it_nv_to_tpgt(nvlist_t *nvl, char *name, it_tpgt_t **tpgt);
378 
379 int
380 it_tpgtlist_to_nv(it_tpgt_t *tpgtlist, nvlist_t **nvl);
381 
382 int
383 it_nv_to_tpgtlist(nvlist_t *nvl, uint32_t *count, it_tpgt_t **tpgtlist);
384 
385 int
386 it_tpg_to_nv(it_tpg_t *tpg, nvlist_t **nvl);
387 
388 int
389 it_nv_to_tpg(nvlist_t *nvl, char *name, it_tpg_t **tpg);
390 
391 int
392 it_tpglist_to_nv(it_tpg_t *tpglist, nvlist_t **nvl);
393 
394 int
395 it_nv_to_tpglist(nvlist_t *nvl, uint32_t *count, it_tpg_t **tpglist);
396 
397 int
398 it_ini_to_nv(it_ini_t *ini, nvlist_t **nvl);
399 
400 int
401 it_nv_to_ini(nvlist_t *nvl, char *name, it_ini_t **ini);
402 
403 int
404 it_inilist_to_nv(it_ini_t *inilist, nvlist_t **nvl);
405 
406 int
407 it_nv_to_inilist(nvlist_t *nvl, uint32_t *count, it_ini_t **inilist);
408 
409 it_tgt_t *
410 it_tgt_lookup(it_config_t *cfg, char *tgt_name);
411 
412 it_tpg_t *
413 it_tpg_lookup(it_config_t *cfg, char *tpg_name);
414 
415 it_portal_t *
416 it_sns_svr_lookup(it_config_t *cfg, struct sockaddr_storage *sa);
417 
418 it_portal_t *
419 it_portal_lookup(it_tpg_t *cfg_tpg, struct sockaddr_storage *sa);
420 
421 int
422 it_sa_compare(struct sockaddr_storage *sa1, struct sockaddr_storage *sa2);
423 
424 /*
425  * Convert a sockaddr to the string representation, suitable for
426  * storing in an nvlist or printing out in a list.
427  */
428 int
429 sockaddr_to_str(struct sockaddr_storage *sa, char **addr);
430 
431 /*
432  * Convert a char string to a sockaddr structure
433  *
434  * default_port should be the port to be used, if not specified
435  * as part of the supplied string 'arg'.
436  */
437 struct sockaddr_storage *
438 it_common_convert_sa(char *arg, struct sockaddr_storage *buf,
439     uint32_t default_port);
440 
441 /*
442  * Convert an string array of IP-addr:port to a portal list
443  */
444 int
445 it_array_to_portallist(char **arr, uint32_t count, uint32_t default_port,
446     it_portal_t **portallist, uint32_t *list_count);
447 
448 /*
449  * Function:  it_config_free_cmn()
450  *
451  * Free any resources associated with the it_config_t structure.
452  *
453  * Parameters:
454  *    cfg       A C representation of the current iSCSI configuration
455  */
456 void
457 it_config_free_cmn(it_config_t *cfg);
458 
459 /*
460  * Function:  it_tgt_free_cmn()
461  *
462  * Frees an it_tgt_t structure.  If tgt_next is not NULL, frees
463  * all structures in the list.
464  */
465 void
466 it_tgt_free_cmn(it_tgt_t *tgt);
467 
468 /*
469  * Function:  it_tpgt_free_cmn()
470  *
471  * Deallocates resources of an it_tpgt_t structure.  If tpgt->next
472  * is not NULL, frees all members of the list.
473  */
474 void
475 it_tpgt_free_cmn(it_tpgt_t *tpgt);
476 
477 /*
478  * Function:  it_tpg_free_cmn()
479  *
480  * Deallocates resources associated with an it_tpg_t structure.
481  * If tpg->next is not NULL, frees all members of the list.
482  */
483 void
484 it_tpg_free_cmn(it_tpg_t *tpg);
485 
486 /*
487  * Function:  it_ini_free_cmn()
488  *
489  * Deallocates resources of an it_ini_t structure. If ini->next is
490  * not NULL, frees all members of the list.
491  */
492 void
493 it_ini_free_cmn(it_ini_t *ini);
494 
495 /*
496  * Function:  iscsi_binary_to_base64_str()
497  *
498  * Encodes a byte array into a base64 string.
499  */
500 int
501 iscsi_binary_to_base64_str(uint8_t *in_buf, int in_buf_len,
502     char *base64_str_buf, int base64_buf_len);
503 
504 /*
505  * Function:  iscsi_base64_str_to_binary()
506  *
507  * Decodes a base64 string into a byte array
508  */
509 int
510 iscsi_base64_str_to_binary(char *hstr, int hstr_len,
511     uint8_t *binary, int binary_buf_len, int *out_len);
512 
513 #ifdef __cplusplus
514 }
515 #endif
516 
517 #endif /* _ISCSIT_COMMON_H_ */
518