xref: /openbsd-src/usr.sbin/iscsid/iscsid.h (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
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