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