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