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 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Copyright 2017 Nexenta Systems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 28 #ifndef _IDM_H 29 #define _IDM_H 30 31 #ifdef __cplusplus 32 extern "C" { 33 #endif 34 35 #include <sys/stmf_defines.h> 36 37 typedef enum { 38 IDM_STATUS_SUCCESS = 0, 39 IDM_STATUS_FAIL, 40 IDM_STATUS_NORESOURCES, 41 IDM_STATUS_REJECT, 42 IDM_STATUS_IO, 43 IDM_STATUS_ABORTED, 44 IDM_STATUS_SUSPENDED, 45 IDM_STATUS_HEADER_DIGEST, 46 IDM_STATUS_DATA_DIGEST, 47 IDM_STATUS_PROTOCOL_ERROR, 48 IDM_STATUS_LOGIN_FAIL 49 } idm_status_t; 50 51 #define IDM_CLIENT_NOTIFY_LIST() \ 52 item(CN_UNDEFINED) \ 53 item(CN_CONNECT_ACCEPT) /* Target only */ \ 54 item(CN_LOGIN_FAIL) \ 55 item(CN_READY_FOR_LOGIN) /* Initiator only */ \ 56 item(CN_FFP_ENABLED) \ 57 item(CN_FFP_DISABLED) \ 58 item(CN_CONNECT_LOST) \ 59 item(CN_CONNECT_DESTROY) \ 60 item(CN_CONNECT_FAIL) \ 61 item(CN_MAX) 62 63 typedef enum { 64 #define item(a) a, 65 IDM_CLIENT_NOTIFY_LIST() 66 #undef item 67 } idm_client_notify_t; 68 69 #ifdef IDM_CN_NOTIFY_STRINGS 70 static const char *idm_cn_strings[CN_MAX + 1] = { 71 #define item(a) #a, 72 IDM_CLIENT_NOTIFY_LIST() 73 #undef item 74 }; 75 #endif 76 77 typedef enum { 78 FD_CONN_FAIL, 79 FD_CONN_LOGOUT, 80 FD_SESS_LOGOUT 81 } idm_ffp_disable_t; 82 83 typedef enum { 84 AT_INTERNAL_SUSPEND, 85 AT_INTERNAL_ABORT, 86 AT_TASK_MGMT_ABORT 87 } idm_abort_type_t; 88 89 #define IDM_TASK_STATE_LIST() \ 90 item(TASK_IDLE) \ 91 item(TASK_ACTIVE) \ 92 item(TASK_SUSPENDING) \ 93 item(TASK_SUSPENDED) \ 94 item(TASK_ABORTING) \ 95 item(TASK_ABORTED) \ 96 item(TASK_COMPLETE) \ 97 item(TASK_MAX_STATE) 98 99 typedef enum { 100 #define item(a) a, 101 IDM_TASK_STATE_LIST() 102 #undef item 103 } idm_task_state_t; 104 105 #ifdef IDM_TASK_SM_STRINGS 106 static const char *idm_ts_name[TASK_MAX_STATE+1] = { 107 #define item(a) #a, 108 IDM_TASK_STATE_LIST() 109 #undef item 110 }; 111 #endif 112 113 typedef enum { 114 KV_HANDLED = 0, 115 KV_HANDLED_NO_TRANSIT, 116 KV_UNHANDLED, 117 KV_TARGET_ONLY, 118 KV_NO_RESOURCES, 119 KV_INTERNAL_ERROR, 120 KV_VALUE_ERROR, 121 KV_MISSING_FIELDS, 122 KV_AUTH_FAILED 123 } kv_status_t; 124 125 /* 126 * Request structures 127 */ 128 129 /* Defined in idm_impl.h */ 130 struct idm_conn_s; 131 struct idm_svc_s; 132 struct idm_buf_s; 133 struct idm_pdu_s; 134 struct idm_task_s; 135 136 typedef idm_status_t (idm_client_notify_cb_t)( 137 struct idm_conn_s *ic, idm_client_notify_t cn, uintptr_t data); 138 139 typedef void (idm_rx_pdu_cb_t)(struct idm_conn_s *ic, struct idm_pdu_s *pdu); 140 141 typedef void (idm_rx_pdu_error_cb_t)(struct idm_conn_s *ic, 142 struct idm_pdu_s *pdu, idm_status_t status); 143 144 typedef void (idm_buf_cb_t)(struct idm_buf_s *idb, idm_status_t status); 145 146 typedef void (idm_pdu_cb_t)(struct idm_pdu_s *pdu, idm_status_t status); 147 148 typedef void (idm_task_cb_t)(struct idm_task_s *task, idm_status_t status); 149 150 typedef void (idm_build_hdr_cb_t)( 151 struct idm_task_s *task, struct idm_pdu_s *pdu, uint8_t opcode); 152 153 typedef void (idm_update_statsn_cb_t)( 154 struct idm_task_s *task, struct idm_pdu_s *pdu); 155 156 typedef void (idm_keepalive_cb_t)(struct idm_conn_s *ic); 157 158 typedef union idm_sockaddr { 159 struct sockaddr sin; 160 struct sockaddr_in sin4; 161 struct sockaddr_in6 sin6; 162 } idm_sockaddr_t; 163 164 #define SIZEOF_SOCKADDR(so) \ 165 ((so)->sa_family == AF_INET ? \ 166 sizeof (struct sockaddr_in) : sizeof (struct sockaddr_in6)) 167 168 typedef struct { 169 idm_rx_pdu_cb_t *icb_rx_scsi_cmd; 170 idm_rx_pdu_cb_t *icb_rx_scsi_rsp; 171 idm_rx_pdu_cb_t *icb_rx_misc; 172 idm_rx_pdu_error_cb_t *icb_rx_error; 173 idm_task_cb_t *icb_task_aborted; 174 idm_client_notify_cb_t *icb_client_notify; 175 idm_build_hdr_cb_t *icb_build_hdr; 176 idm_update_statsn_cb_t *icb_update_statsn; /* advance statsn */ 177 idm_keepalive_cb_t *icb_keepalive; 178 } idm_conn_ops_t; 179 180 typedef struct { 181 int cr_domain; 182 int cr_type; 183 int cr_protocol; 184 boolean_t cr_bound; 185 idm_sockaddr_t cr_bound_addr; 186 idm_sockaddr_t cr_ini_dst_addr; 187 ldi_ident_t cr_li; 188 idm_conn_ops_t icr_conn_ops; 189 boolean_t cr_boot_conn; 190 } idm_conn_req_t; 191 192 typedef struct { 193 uint16_t sr_port; 194 ldi_ident_t sr_li; 195 idm_conn_ops_t sr_conn_ops; 196 } idm_svc_req_t; 197 198 199 /* This is not how other networking code handles this */ 200 typedef struct { 201 union { 202 struct in_addr in4; 203 struct in6_addr in6; 204 } i_addr; 205 /* i_insize determines which is valid in the union above */ 206 int i_insize; 207 } idm_ipaddr_t; 208 209 typedef struct { 210 idm_ipaddr_t a_addr; 211 uint32_t a_port, 212 a_oid; 213 } idm_addr_t; 214 215 typedef struct { 216 uint32_t al_vers, /* In */ 217 al_oid; /* In */ 218 uint32_t al_in_cnt; /* In */ 219 uint32_t al_out_cnt; /* Out */ 220 uint32_t al_tpgt; /* Out */ 221 idm_addr_t al_addrs[1]; /* Out */ 222 } idm_addr_list_t; 223 224 /* 225 * State machine auditing 226 */ 227 228 #define SM_AUDIT_BUF_MAX_REC 32 229 230 typedef enum { 231 SAR_UNDEFINED = 0, 232 SAR_STATE_EVENT, 233 SAR_STATE_CHANGE 234 } sm_audit_record_type_t; 235 236 typedef enum { 237 SAS_UNDEFINED = 0, 238 SAS_IDM_CONN, 239 SAS_IDM_TASK, 240 SAS_ISCSIT_TGT, 241 SAS_ISCSIT_SESS, 242 SAS_ISCSIT_LOGIN, 243 SAS_ISCSI_CMD, 244 SAS_ISCSI_SESS, 245 SAS_ISCSI_CONN, 246 SAS_ISCSI_LOGIN 247 } sm_audit_sm_type_t; 248 249 typedef struct { 250 timespec_t sar_timestamp; 251 sm_audit_sm_type_t sar_sm_type; 252 sm_audit_record_type_t sar_type; 253 int sar_state; 254 int sar_new_state; /* Only for SAR_STATE_CHANGE */ 255 int sar_event; /* Only for SAR_STATE_EVENT */ 256 uintptr_t sar_event_info; /* Only for SAR_STATE_EVENT */ 257 } sm_audit_record_t; 258 259 typedef struct { 260 int sab_index; 261 int sab_max_index; 262 sm_audit_record_t sab_records[SM_AUDIT_BUF_MAX_REC]; 263 } sm_audit_buf_t; 264 265 extern boolean_t idm_sm_logging; 266 extern boolean_t idm_conn_logging; 267 extern boolean_t idm_svc_logging; 268 269 #define IDM_SM_LOG if (idm_sm_logging) cmn_err 270 #define IDM_CONN_LOG if (idm_conn_logging) cmn_err 271 #define IDM_SVC_LOG if (idm_svc_logging) cmn_err 272 273 void idm_sm_audit_init(sm_audit_buf_t *audit_buf); 274 275 void idm_sm_audit_event(sm_audit_buf_t *audit_buf, 276 sm_audit_sm_type_t sm_type, 277 int state, int event, uintptr_t event_info); 278 279 void idm_sm_audit_state_change(sm_audit_buf_t *audit_buf, 280 sm_audit_sm_type_t sm_type, int state, int new_state); 281 282 283 #include <sys/iscsi_protocol.h> 284 #include <sys/idm/idm_conn_sm.h> 285 #include <sys/idm/idm_transport.h> 286 #include <sys/idm/idm_impl.h> 287 #include <sys/idm/idm_text.h> 288 #include <sys/idm/idm_so.h> 289 290 /* 291 * iSCSI Initiator Services 292 */ 293 294 idm_status_t 295 idm_ini_conn_create(idm_conn_req_t *cr, idm_conn_t **new_con); 296 297 idm_status_t 298 idm_ini_conn_connect(idm_conn_t *ic); 299 300 void 301 idm_ini_conn_disconnect(idm_conn_t *ic); 302 303 void 304 idm_ini_conn_disconnect_sync(idm_conn_t *ic); 305 306 void 307 idm_ini_conn_destroy(idm_conn_t *ic); 308 309 /* 310 * iSCSI Target Services 311 */ 312 313 idm_status_t 314 idm_tgt_svc_create(idm_svc_req_t *sr, idm_svc_t **new_svc); 315 316 idm_status_t 317 idm_tgt_svc_online(idm_svc_t *is); 318 319 void 320 idm_tgt_svc_offline(idm_svc_t *is); 321 322 void 323 idm_tgt_svc_destroy(idm_svc_t *is); 324 325 void 326 idm_tgt_svc_destroy_if_unref(idm_svc_t *is); 327 328 idm_svc_t * 329 idm_tgt_svc_lookup(uint16_t port); 330 331 void 332 idm_tgt_svc_hold(idm_svc_t *is); 333 334 void 335 idm_tgt_svc_rele_and_destroy(idm_svc_t *is); 336 337 idm_status_t 338 idm_tgt_conn_accept(idm_conn_t *ic); 339 340 void 341 idm_tgt_conn_reject(idm_conn_t *ic); 342 343 void 344 idm_conn_hold(idm_conn_t *ic); 345 346 void 347 idm_conn_rele(idm_conn_t *ic); 348 349 void 350 idm_conn_set_target_name(idm_conn_t *ic, char *target_name); 351 352 void 353 idm_conn_set_initiator_name(idm_conn_t *ic, char *initiator_name); 354 355 void 356 idm_conn_set_isid(idm_conn_t *ic, uint8_t isid[ISCSI_ISID_LEN]); 357 358 /* 359 * Target data transfer services 360 */ 361 idm_status_t 362 idm_buf_tx_to_ini(idm_task_t *idt, idm_buf_t *idb, 363 uint32_t offset, uint32_t xfer_length, 364 idm_buf_cb_t idb_buf_cb, void *cb_arg); 365 366 idm_status_t 367 idm_buf_rx_from_ini(idm_task_t *idt, idm_buf_t *idb, 368 uint32_t offset, uint32_t xfer_length, 369 idm_buf_cb_t idb_buf_cb, void *cb_arg); 370 371 void 372 idm_buf_tx_to_ini_done(idm_task_t *idt, idm_buf_t *idb, idm_status_t status); 373 374 void 375 idm_buf_rx_from_ini_done(idm_task_t *idt, idm_buf_t *idb, idm_status_t status); 376 377 #define XFER_BUF_TX_TO_INI 0 378 #define XFER_BUF_RX_FROM_INI 1 379 /* 380 * Shared Initiator/Target Services 381 */ 382 kv_status_t 383 idm_negotiate_key_values(idm_conn_t *ic, nvlist_t *request_nvl, 384 nvlist_t *response_nvl, nvlist_t *negotiated_nvl); 385 386 void 387 idm_notice_key_values(idm_conn_t *ic, nvlist_t *negotiated_nvl); 388 389 kv_status_t 390 idm_declare_key_values(idm_conn_t *ic, nvlist_t *config_nvl, 391 nvlist_t *outgoing_nvl); 392 393 /* 394 * Buffer services 395 */ 396 397 idm_buf_t * 398 idm_buf_alloc(idm_conn_t *ic, void *bufptr, uint64_t buflen); 399 400 void 401 idm_buf_free(idm_buf_t *idb); 402 403 void 404 idm_buf_bind_in(idm_task_t *idt, idm_buf_t *buf); 405 406 void 407 idm_buf_bind_out(idm_task_t *idt, idm_buf_t *buf); 408 409 void 410 idm_buf_unbind_in(idm_task_t *idt, idm_buf_t *buf); 411 412 void 413 idm_buf_unbind_out(idm_task_t *idt, idm_buf_t *buf); 414 415 idm_buf_t * 416 idm_buf_find(void *lbuf, size_t data_offset); 417 418 void 419 idm_bufpat_set(idm_buf_t *idb); 420 421 boolean_t 422 idm_bufpat_check(idm_buf_t *idb, int check_len, idm_bufpat_check_type_t type); 423 424 extern boolean_t idm_pattern_checking; 425 426 #define IDM_BUFPAT_SET(CHK_BUF) \ 427 if (idm_pattern_checking && (CHK_BUF)->idb_bufalloc) { \ 428 idm_bufpat_set(CHK_BUF); \ 429 } 430 431 #define IDM_BUFPAT_CHECK(CHK_BUF, CHK_LEN, CHK_TYPE) \ 432 if (idm_pattern_checking) { \ 433 (void) idm_bufpat_check(CHK_BUF, CHK_LEN, CHK_TYPE); \ 434 } 435 436 /* 437 * Task services 438 */ 439 idm_task_t * 440 idm_task_alloc(idm_conn_t *ic); 441 442 void 443 idm_task_start(idm_task_t *idt, uintptr_t handle); 444 445 stmf_status_t 446 idm_task_abort(idm_conn_t *ic, idm_task_t *idt, idm_abort_type_t abort_type); 447 448 void 449 idm_task_cleanup(idm_task_t *idt); 450 451 void 452 idm_task_done(idm_task_t *idt); 453 454 void 455 idm_task_free(idm_task_t *idt); 456 457 idm_task_t * 458 idm_task_find(idm_conn_t *ic, uint32_t itt, uint32_t ttt); 459 460 idm_task_t * 461 idm_task_find_and_complete(idm_conn_t *ic, uint32_t itt, uint32_t ttt); 462 463 void * 464 idm_task_find_by_handle(idm_conn_t *ic, uintptr_t handle); 465 466 void 467 idm_task_hold(idm_task_t *idt); 468 469 void 470 idm_task_rele(idm_task_t *idt); 471 472 /* 473 * PDU Services 474 */ 475 476 idm_pdu_t * 477 idm_pdu_alloc(uint_t hdrlen, uint_t datalen); 478 479 idm_pdu_t * 480 idm_pdu_alloc_nosleep(uint_t hdrlen, uint_t datalen); 481 482 void 483 idm_pdu_free(idm_pdu_t *pdu); 484 485 void 486 idm_pdu_init(idm_pdu_t *pdu, idm_conn_t *ic, void *private, idm_pdu_cb_t *cb); 487 488 void 489 idm_pdu_init_hdr(idm_pdu_t *pdu, uint8_t *hdr, uint_t hdrlen); 490 491 void 492 idm_pdu_init_data(idm_pdu_t *pdu, uint8_t *data, uint_t datalen); 493 494 void 495 idm_pdu_complete(idm_pdu_t *pdu, idm_status_t status); 496 497 void 498 idm_pdu_tx(idm_pdu_t *pdu); 499 500 /* 501 * Object reference tracking 502 */ 503 504 void 505 idm_refcnt_init(idm_refcnt_t *refcnt, void *referenced_obj); 506 507 void 508 idm_refcnt_destroy(idm_refcnt_t *refcnt); 509 510 void 511 idm_refcnt_reset(idm_refcnt_t *refcnt); 512 513 void 514 idm_refcnt_hold(idm_refcnt_t *refcnt); 515 516 void 517 idm_refcnt_rele(idm_refcnt_t *refcnt); 518 519 void 520 idm_refcnt_rele_and_destroy(idm_refcnt_t *refcnt, idm_refcnt_cb_t *cb_func); 521 522 void 523 idm_refcnt_wait_ref(idm_refcnt_t *refcnt); 524 525 void 526 idm_refcnt_async_wait_ref(idm_refcnt_t *refcnt, idm_refcnt_cb_t *cb_func); 527 528 int 529 idm_refcnt_is_held(idm_refcnt_t *refcnt); 530 531 #ifdef __cplusplus 532 } 533 #endif 534 535 #endif /* _IDM_H */ 536