1 /* $OpenBSD: iscsid.h,v 1.16 2016/09/02 16:22:31 benno Exp $ */ 2 3 /* 4 * Copyright (c) 2009 Claudio Jeker <claudio@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #define ISCSID_DEVICE "/dev/vscsi0" 20 #define ISCSID_CONTROL "/var/run/iscsid.sock" 21 #define ISCSID_CONFIG "/etc/iscsi.conf" 22 #define ISCSID_USER "_iscsid" 23 24 #define ISCSID_BASE_NAME "iqn.1995-11.org.openbsd.iscsid" 25 #define ISCSID_DEF_CONNS 8 26 #define ISCSID_HOLD_TIME_MAX 128 27 28 #define PDU_READ_SIZE (256 * 1024) 29 #define CONTROL_READ_SIZE 8192 30 #define PDU_MAXIOV 5 31 #define PDU_WRIOV (PDU_MAXIOV * 8) 32 33 #define PDU_HEADER 0 34 #define PDU_AHS 1 35 #define PDU_HDIGEST 2 36 #define PDU_DATA 3 37 #define PDU_DDIGEST 4 38 39 #define PDU_LEN(x) ((((x) + 3) / 4) * 4) 40 41 #ifndef nitems 42 #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) 43 #endif 44 45 /* 46 * Common control message header. 47 * A message can consist of up to 3 parts with specified length. 48 */ 49 struct ctrlmsghdr { 50 u_int16_t type; 51 u_int16_t len[3]; 52 }; 53 54 struct ctrldata { 55 void *buf; 56 size_t len; 57 }; 58 59 #define CTRLARGV(x...) ((struct ctrldata []){ x }) 60 61 /* Control message types */ 62 #define CTRL_SUCCESS 1 63 #define CTRL_FAILURE 2 64 #define CTRL_INPROGRESS 3 65 #define CTRL_INITIATOR_CONFIG 4 66 #define CTRL_SESSION_CONFIG 5 67 #define CTRL_LOG_VERBOSE 6 68 #define CTRL_VSCSI_STATS 7 69 #define CTRL_SHOW_SUM 8 70 71 72 TAILQ_HEAD(session_head, session); 73 TAILQ_HEAD(connection_head, connection); 74 TAILQ_HEAD(pduq, pdu); 75 TAILQ_HEAD(taskq, task); 76 77 /* as in tcp_seq.h */ 78 #define SEQ_LT(a,b) ((int)((a)-(b)) < 0) 79 #define SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0) 80 #define SEQ_GT(a,b) ((int)((a)-(b)) > 0) 81 #define SEQ_GEQ(a,b) ((int)((a)-(b)) >= 0) 82 83 #define SESS_INIT 0x0001 84 #define SESS_FREE 0x0002 85 #define SESS_LOGGED_IN 0x0004 86 #define SESS_FAILED 0x0008 87 #define SESS_ANYSTATE 0xffff 88 #define SESS_RUNNING (SESS_FREE | SESS_LOGGED_IN | SESS_FAILED) 89 90 #define CONN_FREE 0x0001 /* S1 = R3 */ 91 #define CONN_XPT_WAIT 0x0002 /* S2 */ 92 #define CONN_XPT_UP 0x0004 /* S3 */ 93 #define CONN_IN_LOGIN 0x0008 /* S4 */ 94 #define CONN_LOGGED_IN 0x0010 /* S5 */ 95 #define CONN_IN_LOGOUT 0x0020 /* S6 */ 96 #define CONN_LOGOUT_REQ 0x0040 /* S7 */ 97 #define CONN_CLEANUP_WAIT 0x0080 /* S8 = R1 */ 98 #define CONN_IN_CLEANUP 0x0100 /* R2 */ 99 #define CONN_ANYSTATE 0xffff 100 #define CONN_RUNNING (CONN_LOGGED_IN | CONN_LOGOUT_REQ) 101 #define CONN_FAILED (CONN_CLEANUP_WAIT | CONN_IN_CLEANUP) 102 #define CONN_NEVER_LOGGED_IN (CONN_FREE | CONN_XPT_WAIT | CONN_XPT_UP | \ 103 CONN_IN_LOGIN) 104 105 enum c_event { 106 CONN_EV_FAIL, 107 CONN_EV_FREE, 108 CONN_EV_CONNECT, 109 CONN_EV_CONNECTED, 110 CONN_EV_LOGGED_IN, 111 CONN_EV_REQ_LOGOUT, 112 CONN_EV_LOGOUT, 113 CONN_EV_LOGGED_OUT, 114 CONN_EV_CLOSED, 115 CONN_EV_CLEANING_UP 116 }; 117 118 enum s_event { 119 SESS_EV_START, 120 SESS_EV_STOP, 121 SESS_EV_CONN_LOGGED_IN, 122 SESS_EV_CONN_FAIL, 123 SESS_EV_CONN_CLOSED, 124 SESS_EV_REINSTATEMENT, 125 SESS_EV_TIMEOUT, 126 SESS_EV_CLOSED, 127 SESS_EV_FAIL, 128 SESS_EV_FREE 129 }; 130 131 #define SESS_ACT_UP 0 132 #define SESS_ACT_DOWN 1 133 134 struct pdu { 135 TAILQ_ENTRY(pdu) entry; 136 struct iovec iov[PDU_MAXIOV]; 137 size_t resid; 138 }; 139 140 struct pdu_readbuf { 141 char *buf; 142 size_t size; 143 size_t rpos; 144 size_t wpos; 145 struct pdu *wip; 146 }; 147 148 struct connection_config { 149 /* values inherited from session_config */ 150 struct sockaddr_storage TargetAddr; /* IP:port of target */ 151 struct sockaddr_storage LocalAddr; /* IP:port of target */ 152 }; 153 154 struct initiator_config { 155 u_int32_t isid_base; /* only 24 bits */ 156 u_int16_t isid_qual; 157 u_int16_t pad; 158 }; 159 160 struct session_config { 161 /* unique session ID */ 162 char SessionName[32]; 163 /* 164 * I = initialize only, L = leading only 165 * S = session wide, C = connection only 166 */ 167 struct connection_config connection; 168 169 char *TargetName; /* String: IS */ 170 171 char *InitiatorName; /* String: IS */ 172 173 u_int16_t MaxConnections; 174 /* 1, 1-65535 (min()): LS */ 175 u_int8_t HeaderDigest; 176 /* None , (None|CRC32): IC */ 177 u_int8_t DataDigest; 178 /* None , (None|CRC32): IC */ 179 u_int8_t SessionType; 180 /* Normal, (Discovery|Normal): LS */ 181 u_int8_t disabled; 182 }; 183 184 #define SESSION_TYPE_NORMAL 0 185 #define SESSION_TYPE_DISCOVERY 1 186 187 struct session_params { 188 u_int32_t MaxBurstLength; 189 /* 262144, 512-to-(2**24-1) (min()): LS */ 190 u_int32_t FirstBurstLength; 191 /* 65536, 512-to-(2**24-1) (min()): LS */ 192 u_int16_t DefaultTime2Wait; 193 /* 2, 0-to-3600 (max()): LS */ 194 u_int16_t DefaultTime2Retain; 195 /* 20, 0-to-3600 (min()): LS */ 196 u_int16_t MaxOutstandingR2T; 197 /* 1, 1-to-65535 (min()): LS */ 198 u_int16_t TargetPortalGroupTag; 199 /* 1- 65535: IS */ 200 u_int16_t MaxConnections; 201 /* 1, 1-65535 (min()): LS */ 202 u_int8_t InitialR2T; 203 /* yes, bool (||): LS */ 204 u_int8_t ImmediateData; 205 /* yes, bool (&&): LS */ 206 u_int8_t DataPDUInOrder; 207 /* yes, bool (||): LS */ 208 u_int8_t DataSequenceInOrder; 209 /* yes, bool (||): LS */ 210 u_int8_t ErrorRecoveryLevel; 211 /* 0, 0 - 2 (min()): LS */ 212 }; 213 214 struct connection_params { 215 u_int32_t MaxRecvDataSegmentLength; 216 /* 8192, 512-to-(2**24-1): C */ 217 /* inherited from session_config */ 218 u_int8_t HeaderDigest; 219 u_int8_t DataDigest; 220 }; 221 222 struct initiator { 223 struct session_head sessions; 224 struct initiator_config config; 225 u_int target; 226 }; 227 228 struct sessev { 229 struct session *sess; 230 struct connection *conn; 231 enum s_event event; 232 }; 233 234 struct session { 235 TAILQ_ENTRY(session) entry; 236 struct connection_head connections; 237 struct taskq tasks; 238 struct session_config config; 239 struct session_params mine; 240 struct session_params his; 241 struct session_params active; 242 struct initiator *initiator; 243 u_int32_t cmdseqnum; 244 u_int32_t itt; 245 u_int32_t isid_base; /* only 24 bits */ 246 u_int16_t isid_qual; /* inherited from initiator */ 247 u_int16_t tsih; /* target session id handle */ 248 u_int target; 249 int holdTimer; /* internal hold timer */ 250 int state; 251 int action; 252 }; 253 254 struct connection { 255 struct event ev; 256 struct event wev; 257 TAILQ_ENTRY(connection) entry; 258 struct connection_params mine; 259 struct connection_params his; 260 struct connection_params active; 261 struct connection_config config; 262 struct pdu_readbuf prbuf; 263 struct pduq pdu_w; 264 struct taskq tasks; 265 struct session *session; 266 u_int32_t expstatsn; 267 int state; 268 int fd; 269 u_int16_t cid; /* conection id */ 270 }; 271 272 struct task { 273 TAILQ_ENTRY(task) entry; 274 struct pduq sendq; 275 struct pduq recvq; 276 void *callarg; 277 void (*callback)(struct connection *, void *, struct pdu *); 278 void (*failback)(void *); 279 u_int32_t cmdseqnum; 280 u_int32_t itt; 281 u_int8_t pending; 282 }; 283 284 struct kvp { 285 char *key; 286 char *value; 287 long flags; 288 }; 289 #define KVP_KEY_ALLOCED 0x01 290 #define KVP_VALUE_ALLOCED 0x02 291 292 struct vscsi_stats { 293 u_int64_t bytes_rd; 294 u_int64_t bytes_wr; 295 u_int64_t cnt_read; 296 u_int64_t cnt_write; 297 u_int64_t cnt_i2t; 298 u_int64_t cnt_i2t_dir[3]; 299 u_int64_t cnt_t2i; 300 u_int64_t cnt_t2i_status[3]; 301 u_int32_t cnt_probe; 302 u_int32_t cnt_detach; 303 }; 304 305 extern const struct session_params iscsi_sess_defaults; 306 extern const struct connection_params iscsi_conn_defaults; 307 extern struct session_params initiator_sess_defaults; 308 extern struct connection_params initiator_conn_defaults; 309 310 void iscsid_ctrl_dispatch(void *, struct pdu *); 311 void iscsi_merge_sess_params(struct session_params *, 312 struct session_params *, struct session_params *); 313 void iscsi_merge_conn_params(struct connection_params *, 314 struct connection_params *, struct connection_params *); 315 316 struct initiator *initiator_init(void); 317 void initiator_cleanup(struct initiator *); 318 void initiator_shutdown(struct initiator *); 319 int initiator_isdown(struct initiator *); 320 struct session *initiator_t2s(u_int); 321 void initiator_login(struct connection *); 322 void initiator_discovery(struct session *); 323 void initiator_logout(struct session *, struct connection *, u_int8_t); 324 void initiator_nop_in_imm(struct connection *, struct pdu *); 325 char *default_initiator_name(void); 326 327 int control_init(char *); 328 void control_cleanup(char *); 329 void control_event_init(void); 330 void control_queue(void *, struct pdu *); 331 int control_compose(void *, u_int16_t, void *, size_t); 332 int control_build(void *, u_int16_t, int, struct ctrldata *); 333 334 struct session *session_find(struct initiator *, char *); 335 struct session *session_new(struct initiator *, u_int8_t); 336 void session_cleanup(struct session *); 337 int session_shutdown(struct session *); 338 void session_config(struct session *, struct session_config *); 339 void session_task_issue(struct session *, struct task *); 340 void session_logout_issue(struct session *, struct task *); 341 void session_schedule(struct session *); 342 void session_task_login(struct connection *); 343 void session_fsm(struct session *, enum s_event, struct connection *, 344 unsigned int); 345 346 void conn_new(struct session *, struct connection_config *); 347 void conn_free(struct connection *); 348 int conn_task_ready(struct connection *); 349 void conn_task_issue(struct connection *, struct task *); 350 void conn_task_schedule(struct connection *); 351 void conn_task_cleanup(struct connection *, struct task *); 352 int conn_parse_kvp(struct connection *, struct kvp *); 353 int conn_gen_kvp(struct connection *, struct kvp *, size_t *); 354 void conn_pdu_write(struct connection *, struct pdu *); 355 void conn_fail(struct connection *); 356 void conn_fsm(struct connection *, enum c_event); 357 358 void *pdu_gethdr(struct pdu *); 359 int text_to_pdu(struct kvp *, struct pdu *); 360 struct kvp *pdu_to_text(char *, size_t); 361 u_int64_t text_to_num(const char *, u_int64_t, u_int64_t, const char **); 362 int text_to_bool(const char *, const char **); 363 void pdu_free_queue(struct pduq *); 364 ssize_t pdu_read(struct connection *); 365 ssize_t pdu_write(struct connection *); 366 int pdu_pending(struct connection *); 367 void pdu_parse(struct connection *); 368 int pdu_readbuf_set(struct pdu_readbuf *, size_t); 369 void pdu_readbuf_free(struct pdu_readbuf *); 370 371 struct pdu *pdu_new(void); 372 void *pdu_alloc(size_t); 373 void *pdu_dup(void *, size_t); 374 int pdu_addbuf(struct pdu *, void *, size_t, unsigned int); 375 void *pdu_getbuf(struct pdu *, size_t *, unsigned int); 376 void pdu_free(struct pdu *); 377 int socket_setblockmode(int, int); 378 const char *log_sockaddr(void *); 379 380 void task_init(struct task *, struct session *, int, void *, 381 void (*)(struct connection *, void *, struct pdu *), 382 void (*)(void *)); 383 void taskq_cleanup(struct taskq *); 384 void task_pdu_add(struct task *, struct pdu *); 385 void task_pdu_cb(struct connection *, struct pdu *); 386 387 void vscsi_open(char *); 388 void vscsi_dispatch(int, short, void *); 389 void vscsi_data(unsigned long, int, void *, size_t); 390 void vscsi_status(int, int, void *, size_t); 391 void vscsi_event(unsigned long, u_int, u_int); 392 struct vscsi_stats *vscsi_stats(void); 393 394 /* logmsg.c */ 395 void log_hexdump(void *, size_t); 396 void log_pdu(struct pdu *, int); 397