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 */