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