1/*	$NetBSD: iscsid_globals.h,v 1.4 2011/11/20 01:23:57 agc Exp $	*/
2
3/*-
4 * Copyright (c) 2005,2006,2011 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Wasabi Systems, Inc.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#ifndef _ISCSID_GLOBALS_H
33#define _ISCSID_GLOBALS_H
34
35#ifndef _THREAD_SAFE
36#define _THREAD_SAFE 1
37#endif
38
39#include <sys/queue.h>
40#include <sys/scsiio.h>
41#include <sys/param.h>
42
43#include <uvm/uvm_param.h>
44
45#include <stdio.h>
46#include <stdlib.h>
47#include <string.h>
48#include <unistd.h>
49#include <errno.h>
50
51#ifndef ISCSI_NOTHREAD
52#include <pthread.h>
53#endif
54
55#include <iscsi.h>
56#include <iscsi_ioctl.h>
57
58#include "iscsid.h"
59
60/* -------------------------  Global Constants  ----------------------------- */
61
62/* Version information */
63
64#define INTERFACE_VERSION	2
65#define VERSION_MAJOR		3
66#define VERSION_MINOR		1
67#define VERSION_STRING		"NetBSD iSCSI Software Initiator Daemon 20110407 "
68
69/* Sizes for the static request and response buffers. */
70/* 8k should be more than enough for both. */
71#define REQ_BUFFER_SIZE    8192
72#define RSP_BUFFER_SIZE    8192
73
74#define ISCSI_DEFAULT_PORT 3260
75#define ISCSI_DEFAULT_ISNS_PORT 3205
76
77/* ---------------------------  Global Types  ------------------------------- */
78
79#ifndef TRUE
80typedef int boolean_t;
81#define	TRUE	1
82#define	FALSE	0
83#endif
84
85
86/*
87 * The generic list entry.
88 * Almost all lists in the daemon use this structure as the base for
89 * list processing. It contains both a numeric ID and a symbolic name.
90 * Using the same structure for all lists greatly simplifies processing.
91 *
92 * All structures that will be linked into searchable lists have to define
93 * their first structure field as "generic_entry_t entry".
94*/
95
96struct generic_entry_s
97{
98	TAILQ_ENTRY(generic_entry_s) link;	/* the list link */
99	iscsid_sym_id_t sid;		/* the entry ID and name */
100};
101
102typedef struct generic_entry_s generic_entry_t;
103TAILQ_HEAD(generic_list_s, generic_entry_s);
104typedef struct generic_list_s generic_list_t;
105
106/*
107 * The iSNS list structure.
108 * This structure contains the list of iSNS servers that have been added
109 */
110
111struct isns_s
112{
113	generic_entry_t entry;		/* global list link */
114
115	uint8_t address[ISCSI_ADDRESS_LENGTH];	/* iSNS Server Address */
116	uint16_t port;				/* Port (0 = default) */
117
118	int sock;					/* socket if registered, else -1 */
119	/* following fields only valid if sock >= 0 */
120	uint8_t reg_iscsi_name[ISCSI_STRING_LENGTH];	/* Registered ISCSI Name */
121	uint8_t reg_entity_id[ISCSI_STRING_LENGTH];	/* Registered Entity Identifier */
122	uint8_t reg_ip_addr[16];	/* registered IP address */
123	uint32_t reg_ip_port;		/* registered IP port */
124};
125
126
127TAILQ_HEAD(isns_list_s, isns_s);
128typedef struct isns_s isns_t;
129typedef struct isns_list_s isns_list_t;
130
131
132/*
133 *  The initiator portal list structure.
134 */
135
136typedef struct initiator_s initiator_t;
137
138struct initiator_s
139{
140	generic_entry_t entry;		/* global list link */
141
142	uint8_t address[ISCSI_ADDRESS_LENGTH];	/* address */
143	uint32_t active_connections;	/* connection count */
144};
145
146TAILQ_HEAD(initiator_list_s, initiator_s);
147typedef struct initiator_list_s initiator_list_t;
148
149
150/*
151 * The portal structure.
152 * This structure is linked into two lists - a global portal list (this list
153 * is used for searches and to verify unique IDs) and a portal group list
154 * attached to the owning target.
155 */
156
157typedef enum
158{
159	PORTAL_TYPE_STATIC = 0,
160	PORTAL_TYPE_SENDTARGET = 1,
161	PORTAL_TYPE_ISNS = 2,
162	PORTAL_TYPE_REFRESHING = 99
163} iscsi_portal_types_t;
164/*
165   PORTAL_TYPE_STATIC
166      Indicates that target was statically added
167   PORTAL_TYPE_SENDTARGET
168      Indicates that target was added as result of SendTargets discovery
169   PORTAL_TYPE_ISNS
170      Indicates that target was added as result of iSNS discovery
171   PORTAL_TYPE_REFRESHING
172      Discovered portals are set to this when we are refreshing
173      (via REFRESH_TARGETS). As a portal is discovered, its type is reset to
174      SENDTARGET or ISNS, so any portals which remain set to REFRESHING were not
175      discovered and thus can be removed.
176*/
177
178typedef struct portal_s portal_t;
179typedef struct portal_group_s portal_group_t;
180typedef struct target_s target_t;
181typedef struct send_target_s send_target_t;
182
183struct portal_s
184{
185	generic_entry_t entry;		/* global list link */
186
187	  TAILQ_ENTRY(portal_s) group_list;	/* group list link */
188
189	iscsi_portal_address_t addr;	/* address */
190	iscsid_portal_options_t options; /* portal options (override target options) */
191	target_t *target;			/* back pointer to target */
192	portal_group_t *group;		/* back pointer to group head */
193	iscsi_portal_types_t portaltype;   /* Type of portal (how it was discovered) */
194	uint32_t discoveryid;		/* ID of sendtargets or isnsserver */
195	uint32_t active_connections; /* Number of connections active on this portal */
196};
197
198TAILQ_HEAD(portal_list_s, portal_s);
199typedef struct portal_list_s portal_list_t;
200
201
202/*
203 * The portal group structure.
204 * This structure is not searchable, and has no generic list entry field.
205 * It links all portals with the same group tag to the owning target.
206*/
207
208struct portal_group_s
209{
210	TAILQ_ENTRY(portal_group_s) groups;	/* link to next group */
211
212	portal_list_t portals;		/* the list of portals for this tag */
213
214	uint32_t tag;				/* the group tag */
215	u_short num_portals;		/* the number of portals in this list */
216};
217
218TAILQ_HEAD(portal_group_list_s, portal_group_s);
219typedef struct portal_group_list_s portal_group_list_t;
220
221
222/*
223 * The target structure.
224 * Contains target information including connection and authentication options.
225 *****************************************************************************
226 * WARNING: This structure is used interchangeably with a send_target structure
227 *          in many routines dealing with targets to avoid duplicating code.
228 *          The first fields in both structures up to and including
229 *          the authentication options MUST match for this to work.
230 *          If you change one, you MUST change the other accordingly.
231 *****************************************************************************
232*/
233
234struct target_s
235{
236	generic_entry_t entry;		/* global list link */
237
238	uint8_t TargetName[ISCSI_STRING_LENGTH];	/* TargetName */
239	uint8_t TargetAlias[ISCSI_STRING_LENGTH];	/* TargetAlias */
240
241	u_short num_portals;		/* the number of portals */
242	u_short num_groups;			/* the number of groups */
243
244	iscsid_get_set_target_options_t options;	/* connection options */
245	iscsid_set_target_authentication_req_t auth;	/* authentication options */
246
247	portal_group_list_t group_list;	/* the list of portal groups */
248};
249
250TAILQ_HEAD(target_list_s, target_s);
251typedef struct target_list_s target_list_t;
252
253
254/*
255 * The Send Target structure.
256 * Contains target information including connection and authentication options
257 * plus a single portal.
258 *****************************************************************************
259 * WARNING: This structure is used interchangeably with a target structure
260 *          in many routines dealing with targets to avoid duplicating code.
261 *          The first fields in both structures up to and including
262 *          the authentication options MUST match for this to work.
263 *          If you change one, you MUST change the other accordingly.
264 *****************************************************************************
265 */
266
267struct send_target_s
268{
269	generic_entry_t entry;		/* global list link */
270
271	uint8_t TargetName[ISCSI_STRING_LENGTH];	/* TargetName */
272	uint8_t TargetAlias[ISCSI_STRING_LENGTH];	/* TargetAlias */
273
274	u_short num_portals;		/* the number of portals */
275	u_short num_groups;			/* the number of groups */
276	/* */
277	iscsid_get_set_target_options_t options;	/* connection options */
278	iscsid_set_target_authentication_req_t auth;	/* authentication options */
279
280	iscsi_portal_address_t addr;	/* address */
281};
282
283TAILQ_HEAD(send_target_list_s, send_target_s);
284typedef struct send_target_list_s send_target_list_t;
285
286/*
287   Target and Portal information maintained in the connection structure.
288*/
289
290struct target_info_s
291{
292	iscsid_sym_id_t sid;		/* the entry ID and name */
293	uint8_t TargetName[ISCSI_STRING_LENGTH];	/* TargetName */
294	uint8_t TargetAlias[ISCSI_STRING_LENGTH];	/* TargetAlias */
295	iscsid_get_set_target_options_t options;	/* connection options */
296	iscsid_set_target_authentication_req_t auth;	/* authentication options */
297};
298typedef struct target_info_s target_info_t;
299
300
301struct portal_info_s
302{
303	iscsid_sym_id_t sid;		/* the entry ID and name */
304	iscsi_portal_address_t addr;	/* address */
305};
306typedef struct portal_info_s portal_info_t;
307
308/*
309   Per connection data: the connection structure.
310*/
311
312typedef struct connection_s connection_t;
313typedef struct session_s session_t;
314
315
316struct connection_s
317{
318	generic_entry_t entry;		/* connection list link */
319
320	session_t *session;			/* back pointer to the owning session */
321	target_info_t target;		/* connected target */
322	portal_info_t portal;		/* connected portal */
323	uint32_t initiator_id;		/* connected initiator portal */
324
325	iscsi_login_parameters_t loginp;	/* Login parameters for recovery */
326};
327
328
329/*
330   Per session data: the session structure
331*/
332
333struct session_s
334{
335	generic_entry_t entry;		/* global list link */
336
337	target_info_t target;		/* connected target */
338	iscsi_login_session_type_t login_type;	/* session type */
339
340	uint32_t max_connections;	/* maximum connections */
341	uint32_t num_connections;	/* currently active connections */
342	generic_list_t connections;	/* the list of connections */
343};
344
345/* the session list type */
346
347TAILQ_HEAD(session_list_s, session_s);
348typedef struct session_list_s session_list_t;
349
350
351/* list head with entry count */
352
353typedef struct
354{
355	generic_list_t list;
356	int num_entries;
357} list_head_t;
358
359/* -------------------------  Global Variables  ----------------------------- */
360
361/* In iscsid_main.c */
362
363int driver;						/* the driver's file desc */
364int client_sock;				/* the client communication socket */
365
366list_head_t list[NUM_DAEMON_LISTS];	/* the lists this daemon keeps */
367
368#ifndef ISCSI_NOTHREAD
369pthread_t event_thread;			/* event handler thread ID */
370pthread_mutex_t sesslist_lock;	/* session list lock */
371#endif
372
373/* in iscsid_discover.c */
374
375iscsid_set_node_name_req_t node_name;
376
377
378/* -------------------------  Global Functions  ----------------------------- */
379
380/* Debugging stuff */
381
382
383extern int debug_level;				/* How much info to display */
384
385#define DEBOUT(x) printf x
386#define DEB(lev,x) {if (debug_level >= lev) printf x ;}
387
388/* Session list protection shortcuts */
389
390#if 0
391#define LOCK_SESSIONS   verify_sessions()
392#define UNLOCK_SESSIONS
393#endif
394#define LOCK_SESSIONS   if (nothreads) event_handler(NULL); else pthread_mutex_lock(&sesslist_lock)
395#define UNLOCK_SESSIONS if (!nothreads) pthread_mutex_unlock(&sesslist_lock)
396
397/* Check whether ID is present */
398
399#define NO_ID(sid) (!(sid)->id && !(sid)->name[0])
400
401/* iscsid_main.c */
402
403iscsid_response_t *make_rsp(size_t, iscsid_response_t **, int *);
404void exit_daemon(void) __dead;
405
406/* iscsid_lists.c */
407
408generic_entry_t *find_id(generic_list_t *, uint32_t);
409generic_entry_t *find_name(generic_list_t *, uint8_t *);
410generic_entry_t *find_sym_id(generic_list_t *, iscsid_sym_id_t *);
411uint32_t get_id(generic_list_t *, iscsid_sym_id_t *);
412target_t *find_target(iscsid_list_kind_t, iscsid_sym_id_t *);
413target_t *find_TargetName(iscsid_list_kind_t, uint8_t *);
414portal_t *find_portal_by_addr(target_t *, iscsi_portal_address_t *);
415send_target_t *find_send_target_by_addr(iscsi_portal_address_t *);
416
417#define find_isns_id(id) \
418   (isns_t *)(void *)find_id(&list [ISNS_LIST].list, id)
419#define find_session_id(id) \
420   (session_t *)(void *)find_id(&list [SESSION_LIST].list, id)
421#define find_connection_id(session, id) \
422   (connection_t *)(void *)find_id(&session->connections, id)
423#define find_portal_id(id) \
424   (portal_t *)(void *)find_id(&list [PORTAL_LIST].list, id)
425#define find_target_id(lst, id) \
426   (target_t *)(void *)find_id(&list [lst].list, id)
427#define find_send_target_id(id) \
428   (send_target_t *)(void *)find_id(&list [SEND_TARGETS_LIST].list, id)
429#define find_initiator_id(id) \
430   (initiator_t *)(void *)find_id(&list [INITIATOR_LIST].list, id)
431#define find_isns_name(name) \
432   (isns_t *)(void *)find_name(&list [ISNS_LIST].list, name)
433#define find_session_name(name) \
434   (session_t *)(void *)find_name(&list [SESSION_LIST].list, name)
435#define find_connection_name(session, name) \
436   (connection_t *)(void *)find_name(&session->connections, name)
437#define find_portal_name(name) \
438   (portal_t *)(void *)find_name(&list [PORTAL_LIST].list, name)
439#define find_target_symname(lst, name) \
440   (target_t *)(void *)find_name(&list [lst].list, name)
441#define find_initiator_name(name) \
442   (initiator_t *)(void *)find_name(&list [INITIATOR_LIST].list, name)
443#define find_isns(sid) \
444   (isns_t *)(void *)find_sym_id(&list [ISNS_LIST].list, sid)
445#define find_session(sid) \
446   (session_t *)(void *)find_sym_id(&list [SESSION_LIST].list, sid)
447#define find_connection(session, sid) \
448   (connection_t *)(void *)find_sym_id(&session->connections, sid)
449#define find_portal(sid) \
450   (portal_t *)(void *)find_sym_id(&list [PORTAL_LIST].list, sid)
451#define find_initiator(sid) \
452   (initiator_t *)(void *)find_sym_id(&list [INITIATOR_LIST].list, sid)
453
454void get_list(iscsid_get_list_req_t *, iscsid_response_t **, int *);
455void search_list(iscsid_search_list_req_t *, iscsid_response_t **, int *);
456
457void get_session_list(iscsid_response_t **, int *);
458void get_connection_info(iscsid_get_connection_info_req_t *,
459						 iscsid_response_t **, int *);
460void get_connection_list(iscsid_sym_id_t *, iscsid_response_t **, int *);
461
462void add_initiator_portal(iscsid_add_initiator_req_t *, iscsid_response_t **,
463						  int *);
464uint32_t remove_initiator_portal(iscsid_sym_id_t *);
465void get_initiator_portal(iscsid_sym_id_t *, iscsid_response_t **, int *);
466initiator_t *select_initiator(void);
467
468void event_kill_session(uint32_t);
469void event_kill_connection(uint32_t, uint32_t);
470
471/* iscsid_targets.c */
472
473void add_target(iscsid_add_target_req_t *, iscsid_response_t **, int *);
474uint32_t set_target_options(iscsid_get_set_target_options_t *);
475uint32_t set_target_auth(iscsid_set_target_authentication_req_t *);
476void add_portal(iscsid_add_portal_req_t *, iscsid_response_t **, int *);
477void delete_portal(portal_t *, boolean_t);
478
479void get_target_info(iscsid_list_id_t *, iscsid_response_t **, int *);
480void get_portal_info(iscsid_list_id_t *, iscsid_response_t **, int *);
481uint32_t remove_target(iscsid_list_id_t *);
482uint32_t refresh_targets(iscsid_refresh_req_t *);
483target_t *add_discovered_target(uint8_t *, iscsi_portal_address_t *,
484								iscsi_portal_types_t, uint32_t);
485
486/* iscsid_driverif.c */
487
488boolean_t register_event_handler(void);
489void deregister_event_handler(void);
490void *event_handler(void *);
491
492uint32_t set_node_name(iscsid_set_node_name_req_t *);
493void login(iscsid_login_req_t *, iscsid_response_t *);
494void add_connection(iscsid_login_req_t *, iscsid_response_t *);
495uint32_t send_targets(uint32_t, uint8_t **, uint32_t *);
496uint32_t logout(iscsid_sym_id_t *);
497uint32_t remove_connection(iscsid_remove_connection_req_t *);
498void get_version(iscsid_response_t **, int *);
499
500/* iscsid_discover.c */
501
502#ifndef ISCSI_MINIMAL
503void add_isns_server(iscsid_add_isns_server_req_t *, iscsid_response_t **,
504					 int *);
505void get_isns_server(iscsid_sym_id_t *, iscsid_response_t **, int *);
506uint32_t refresh_isns_server(uint32_t);
507uint32_t remove_isns_server(iscsid_sym_id_t *);
508void dereg_all_isns_servers(void);
509#endif
510
511#endif /* !_ISCSID_GLOBALS_H */
512