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