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