]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blob - drivers/target/iscsi/iscsi_target_login.c
target: Avoid integer overflow in se_dev_align_max_sectors()
[mirror_ubuntu-bionic-kernel.git] / drivers / target / iscsi / iscsi_target_login.c
1 /*******************************************************************************
2 * This file contains the login functions used by the iSCSI Target driver.
3 *
4 * \u00a9 Copyright 2007-2011 RisingTide Systems LLC.
5 *
6 * Licensed to the Linux Foundation under the General Public License (GPL) version 2.
7 *
8 * Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 ******************************************************************************/
20
21 #include <linux/string.h>
22 #include <linux/kthread.h>
23 #include <linux/crypto.h>
24 #include <linux/idr.h>
25 #include <scsi/iscsi_proto.h>
26 #include <target/target_core_base.h>
27 #include <target/target_core_fabric.h>
28
29 #include "iscsi_target_core.h"
30 #include "iscsi_target_tq.h"
31 #include "iscsi_target_device.h"
32 #include "iscsi_target_nego.h"
33 #include "iscsi_target_erl0.h"
34 #include "iscsi_target_erl2.h"
35 #include "iscsi_target_login.h"
36 #include "iscsi_target_stat.h"
37 #include "iscsi_target_tpg.h"
38 #include "iscsi_target_util.h"
39 #include "iscsi_target.h"
40 #include "iscsi_target_parameters.h"
41
42 static int iscsi_login_init_conn(struct iscsi_conn *conn)
43 {
44 INIT_LIST_HEAD(&conn->conn_list);
45 INIT_LIST_HEAD(&conn->conn_cmd_list);
46 INIT_LIST_HEAD(&conn->immed_queue_list);
47 INIT_LIST_HEAD(&conn->response_queue_list);
48 init_completion(&conn->conn_post_wait_comp);
49 init_completion(&conn->conn_wait_comp);
50 init_completion(&conn->conn_wait_rcfr_comp);
51 init_completion(&conn->conn_waiting_on_uc_comp);
52 init_completion(&conn->conn_logout_comp);
53 init_completion(&conn->rx_half_close_comp);
54 init_completion(&conn->tx_half_close_comp);
55 spin_lock_init(&conn->cmd_lock);
56 spin_lock_init(&conn->conn_usage_lock);
57 spin_lock_init(&conn->immed_queue_lock);
58 spin_lock_init(&conn->nopin_timer_lock);
59 spin_lock_init(&conn->response_queue_lock);
60 spin_lock_init(&conn->state_lock);
61
62 if (!zalloc_cpumask_var(&conn->conn_cpumask, GFP_KERNEL)) {
63 pr_err("Unable to allocate conn->conn_cpumask\n");
64 return -ENOMEM;
65 }
66
67 return 0;
68 }
69
70 /*
71 * Used by iscsi_target_nego.c:iscsi_target_locate_portal() to setup
72 * per struct iscsi_conn libcrypto contexts for crc32c and crc32-intel
73 */
74 int iscsi_login_setup_crypto(struct iscsi_conn *conn)
75 {
76 /*
77 * Setup slicing by CRC32C algorithm for RX and TX libcrypto contexts
78 * which will default to crc32c_intel.ko for cpu_has_xmm4_2, or fallback
79 * to software 1x8 byte slicing from crc32c.ko
80 */
81 conn->conn_rx_hash.flags = 0;
82 conn->conn_rx_hash.tfm = crypto_alloc_hash("crc32c", 0,
83 CRYPTO_ALG_ASYNC);
84 if (IS_ERR(conn->conn_rx_hash.tfm)) {
85 pr_err("crypto_alloc_hash() failed for conn_rx_tfm\n");
86 return -ENOMEM;
87 }
88
89 conn->conn_tx_hash.flags = 0;
90 conn->conn_tx_hash.tfm = crypto_alloc_hash("crc32c", 0,
91 CRYPTO_ALG_ASYNC);
92 if (IS_ERR(conn->conn_tx_hash.tfm)) {
93 pr_err("crypto_alloc_hash() failed for conn_tx_tfm\n");
94 crypto_free_hash(conn->conn_rx_hash.tfm);
95 return -ENOMEM;
96 }
97
98 return 0;
99 }
100
101 static int iscsi_login_check_initiator_version(
102 struct iscsi_conn *conn,
103 u8 version_max,
104 u8 version_min)
105 {
106 if ((version_max != 0x00) || (version_min != 0x00)) {
107 pr_err("Unsupported iSCSI IETF Pre-RFC Revision,"
108 " version Min/Max 0x%02x/0x%02x, rejecting login.\n",
109 version_min, version_max);
110 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
111 ISCSI_LOGIN_STATUS_NO_VERSION);
112 return -1;
113 }
114
115 return 0;
116 }
117
118 int iscsi_check_for_session_reinstatement(struct iscsi_conn *conn)
119 {
120 int sessiontype;
121 struct iscsi_param *initiatorname_param = NULL, *sessiontype_param = NULL;
122 struct iscsi_portal_group *tpg = conn->tpg;
123 struct iscsi_session *sess = NULL, *sess_p = NULL;
124 struct se_portal_group *se_tpg = &tpg->tpg_se_tpg;
125 struct se_session *se_sess, *se_sess_tmp;
126
127 initiatorname_param = iscsi_find_param_from_key(
128 INITIATORNAME, conn->param_list);
129 if (!initiatorname_param)
130 return -1;
131
132 sessiontype_param = iscsi_find_param_from_key(
133 SESSIONTYPE, conn->param_list);
134 if (!sessiontype_param)
135 return -1;
136
137 sessiontype = (strncmp(sessiontype_param->value, NORMAL, 6)) ? 1 : 0;
138
139 spin_lock_bh(&se_tpg->session_lock);
140 list_for_each_entry_safe(se_sess, se_sess_tmp, &se_tpg->tpg_sess_list,
141 sess_list) {
142
143 sess_p = se_sess->fabric_sess_ptr;
144 spin_lock(&sess_p->conn_lock);
145 if (atomic_read(&sess_p->session_fall_back_to_erl0) ||
146 atomic_read(&sess_p->session_logout) ||
147 (sess_p->time2retain_timer_flags & ISCSI_TF_EXPIRED)) {
148 spin_unlock(&sess_p->conn_lock);
149 continue;
150 }
151 if (!memcmp(sess_p->isid, conn->sess->isid, 6) &&
152 (!strcmp(sess_p->sess_ops->InitiatorName,
153 initiatorname_param->value) &&
154 (sess_p->sess_ops->SessionType == sessiontype))) {
155 atomic_set(&sess_p->session_reinstatement, 1);
156 spin_unlock(&sess_p->conn_lock);
157 iscsit_inc_session_usage_count(sess_p);
158 iscsit_stop_time2retain_timer(sess_p);
159 sess = sess_p;
160 break;
161 }
162 spin_unlock(&sess_p->conn_lock);
163 }
164 spin_unlock_bh(&se_tpg->session_lock);
165 /*
166 * If the Time2Retain handler has expired, the session is already gone.
167 */
168 if (!sess)
169 return 0;
170
171 pr_debug("%s iSCSI Session SID %u is still active for %s,"
172 " preforming session reinstatement.\n", (sessiontype) ?
173 "Discovery" : "Normal", sess->sid,
174 sess->sess_ops->InitiatorName);
175
176 spin_lock_bh(&sess->conn_lock);
177 if (sess->session_state == TARG_SESS_STATE_FAILED) {
178 spin_unlock_bh(&sess->conn_lock);
179 iscsit_dec_session_usage_count(sess);
180 target_put_session(sess->se_sess);
181 return 0;
182 }
183 spin_unlock_bh(&sess->conn_lock);
184
185 iscsit_stop_session(sess, 1, 1);
186 iscsit_dec_session_usage_count(sess);
187
188 target_put_session(sess->se_sess);
189 return 0;
190 }
191
192 static void iscsi_login_set_conn_values(
193 struct iscsi_session *sess,
194 struct iscsi_conn *conn,
195 __be16 cid)
196 {
197 conn->sess = sess;
198 conn->cid = be16_to_cpu(cid);
199 /*
200 * Generate a random Status sequence number (statsn) for the new
201 * iSCSI connection.
202 */
203 get_random_bytes(&conn->stat_sn, sizeof(u32));
204
205 mutex_lock(&auth_id_lock);
206 conn->auth_id = iscsit_global->auth_id++;
207 mutex_unlock(&auth_id_lock);
208 }
209
210 /*
211 * This is the leading connection of a new session,
212 * or session reinstatement.
213 */
214 static int iscsi_login_zero_tsih_s1(
215 struct iscsi_conn *conn,
216 unsigned char *buf)
217 {
218 struct iscsi_session *sess = NULL;
219 struct iscsi_login_req *pdu = (struct iscsi_login_req *)buf;
220 int ret;
221
222 sess = kzalloc(sizeof(struct iscsi_session), GFP_KERNEL);
223 if (!sess) {
224 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
225 ISCSI_LOGIN_STATUS_NO_RESOURCES);
226 pr_err("Could not allocate memory for session\n");
227 return -ENOMEM;
228 }
229
230 iscsi_login_set_conn_values(sess, conn, pdu->cid);
231 sess->init_task_tag = pdu->itt;
232 memcpy(&sess->isid, pdu->isid, 6);
233 sess->exp_cmd_sn = be32_to_cpu(pdu->cmdsn);
234 INIT_LIST_HEAD(&sess->sess_conn_list);
235 INIT_LIST_HEAD(&sess->sess_ooo_cmdsn_list);
236 INIT_LIST_HEAD(&sess->cr_active_list);
237 INIT_LIST_HEAD(&sess->cr_inactive_list);
238 init_completion(&sess->async_msg_comp);
239 init_completion(&sess->reinstatement_comp);
240 init_completion(&sess->session_wait_comp);
241 init_completion(&sess->session_waiting_on_uc_comp);
242 mutex_init(&sess->cmdsn_mutex);
243 spin_lock_init(&sess->conn_lock);
244 spin_lock_init(&sess->cr_a_lock);
245 spin_lock_init(&sess->cr_i_lock);
246 spin_lock_init(&sess->session_usage_lock);
247 spin_lock_init(&sess->ttt_lock);
248
249 if (!idr_pre_get(&sess_idr, GFP_KERNEL)) {
250 pr_err("idr_pre_get() for sess_idr failed\n");
251 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
252 ISCSI_LOGIN_STATUS_NO_RESOURCES);
253 kfree(sess);
254 return -ENOMEM;
255 }
256 spin_lock(&sess_idr_lock);
257 ret = idr_get_new(&sess_idr, NULL, &sess->session_index);
258 spin_unlock(&sess_idr_lock);
259
260 if (ret < 0) {
261 pr_err("idr_get_new() for sess_idr failed\n");
262 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
263 ISCSI_LOGIN_STATUS_NO_RESOURCES);
264 kfree(sess);
265 return -ENOMEM;
266 }
267
268 sess->creation_time = get_jiffies_64();
269 spin_lock_init(&sess->session_stats_lock);
270 /*
271 * The FFP CmdSN window values will be allocated from the TPG's
272 * Initiator Node's ACL once the login has been successfully completed.
273 */
274 sess->max_cmd_sn = be32_to_cpu(pdu->cmdsn);
275
276 sess->sess_ops = kzalloc(sizeof(struct iscsi_sess_ops), GFP_KERNEL);
277 if (!sess->sess_ops) {
278 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
279 ISCSI_LOGIN_STATUS_NO_RESOURCES);
280 pr_err("Unable to allocate memory for"
281 " struct iscsi_sess_ops.\n");
282 kfree(sess);
283 return -ENOMEM;
284 }
285
286 sess->se_sess = transport_init_session();
287 if (IS_ERR(sess->se_sess)) {
288 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
289 ISCSI_LOGIN_STATUS_NO_RESOURCES);
290 kfree(sess);
291 return -ENOMEM;
292 }
293
294 return 0;
295 }
296
297 static int iscsi_login_zero_tsih_s2(
298 struct iscsi_conn *conn)
299 {
300 struct iscsi_node_attrib *na;
301 struct iscsi_session *sess = conn->sess;
302 unsigned char buf[32];
303
304 sess->tpg = conn->tpg;
305
306 /*
307 * Assign a new TPG Session Handle. Note this is protected with
308 * struct iscsi_portal_group->np_login_sem from iscsit_access_np().
309 */
310 sess->tsih = ++ISCSI_TPG_S(sess)->ntsih;
311 if (!sess->tsih)
312 sess->tsih = ++ISCSI_TPG_S(sess)->ntsih;
313
314 /*
315 * Create the default params from user defined values..
316 */
317 if (iscsi_copy_param_list(&conn->param_list,
318 ISCSI_TPG_C(conn)->param_list, 1) < 0) {
319 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
320 ISCSI_LOGIN_STATUS_NO_RESOURCES);
321 return -1;
322 }
323
324 iscsi_set_keys_to_negotiate(0, conn->param_list);
325
326 if (sess->sess_ops->SessionType)
327 return iscsi_set_keys_irrelevant_for_discovery(
328 conn->param_list);
329
330 na = iscsit_tpg_get_node_attrib(sess);
331
332 /*
333 * Need to send TargetPortalGroupTag back in first login response
334 * on any iSCSI connection where the Initiator provides TargetName.
335 * See 5.3.1. Login Phase Start
336 *
337 * In our case, we have already located the struct iscsi_tiqn at this point.
338 */
339 memset(buf, 0, 32);
340 sprintf(buf, "TargetPortalGroupTag=%hu", ISCSI_TPG_S(sess)->tpgt);
341 if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) {
342 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
343 ISCSI_LOGIN_STATUS_NO_RESOURCES);
344 return -1;
345 }
346
347 /*
348 * Workaround for Initiators that have broken connection recovery logic.
349 *
350 * "We would really like to get rid of this." Linux-iSCSI.org team
351 */
352 memset(buf, 0, 32);
353 sprintf(buf, "ErrorRecoveryLevel=%d", na->default_erl);
354 if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) {
355 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
356 ISCSI_LOGIN_STATUS_NO_RESOURCES);
357 return -1;
358 }
359
360 if (iscsi_login_disable_FIM_keys(conn->param_list, conn) < 0)
361 return -1;
362
363 return 0;
364 }
365
366 /*
367 * Remove PSTATE_NEGOTIATE for the four FIM related keys.
368 * The Initiator node will be able to enable FIM by proposing them itself.
369 */
370 int iscsi_login_disable_FIM_keys(
371 struct iscsi_param_list *param_list,
372 struct iscsi_conn *conn)
373 {
374 struct iscsi_param *param;
375
376 param = iscsi_find_param_from_key("OFMarker", param_list);
377 if (!param) {
378 pr_err("iscsi_find_param_from_key() for"
379 " OFMarker failed\n");
380 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
381 ISCSI_LOGIN_STATUS_NO_RESOURCES);
382 return -1;
383 }
384 param->state &= ~PSTATE_NEGOTIATE;
385
386 param = iscsi_find_param_from_key("OFMarkInt", param_list);
387 if (!param) {
388 pr_err("iscsi_find_param_from_key() for"
389 " IFMarker failed\n");
390 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
391 ISCSI_LOGIN_STATUS_NO_RESOURCES);
392 return -1;
393 }
394 param->state &= ~PSTATE_NEGOTIATE;
395
396 param = iscsi_find_param_from_key("IFMarker", param_list);
397 if (!param) {
398 pr_err("iscsi_find_param_from_key() for"
399 " IFMarker failed\n");
400 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
401 ISCSI_LOGIN_STATUS_NO_RESOURCES);
402 return -1;
403 }
404 param->state &= ~PSTATE_NEGOTIATE;
405
406 param = iscsi_find_param_from_key("IFMarkInt", param_list);
407 if (!param) {
408 pr_err("iscsi_find_param_from_key() for"
409 " IFMarker failed\n");
410 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
411 ISCSI_LOGIN_STATUS_NO_RESOURCES);
412 return -1;
413 }
414 param->state &= ~PSTATE_NEGOTIATE;
415
416 return 0;
417 }
418
419 static int iscsi_login_non_zero_tsih_s1(
420 struct iscsi_conn *conn,
421 unsigned char *buf)
422 {
423 struct iscsi_login_req *pdu = (struct iscsi_login_req *)buf;
424
425 iscsi_login_set_conn_values(NULL, conn, pdu->cid);
426 return 0;
427 }
428
429 /*
430 * Add a new connection to an existing session.
431 */
432 static int iscsi_login_non_zero_tsih_s2(
433 struct iscsi_conn *conn,
434 unsigned char *buf)
435 {
436 struct iscsi_portal_group *tpg = conn->tpg;
437 struct iscsi_session *sess = NULL, *sess_p = NULL;
438 struct se_portal_group *se_tpg = &tpg->tpg_se_tpg;
439 struct se_session *se_sess, *se_sess_tmp;
440 struct iscsi_login_req *pdu = (struct iscsi_login_req *)buf;
441
442 spin_lock_bh(&se_tpg->session_lock);
443 list_for_each_entry_safe(se_sess, se_sess_tmp, &se_tpg->tpg_sess_list,
444 sess_list) {
445
446 sess_p = (struct iscsi_session *)se_sess->fabric_sess_ptr;
447 if (atomic_read(&sess_p->session_fall_back_to_erl0) ||
448 atomic_read(&sess_p->session_logout) ||
449 (sess_p->time2retain_timer_flags & ISCSI_TF_EXPIRED))
450 continue;
451 if (!memcmp(sess_p->isid, pdu->isid, 6) &&
452 (sess_p->tsih == be16_to_cpu(pdu->tsih))) {
453 iscsit_inc_session_usage_count(sess_p);
454 iscsit_stop_time2retain_timer(sess_p);
455 sess = sess_p;
456 break;
457 }
458 }
459 spin_unlock_bh(&se_tpg->session_lock);
460
461 /*
462 * If the Time2Retain handler has expired, the session is already gone.
463 */
464 if (!sess) {
465 pr_err("Initiator attempting to add a connection to"
466 " a non-existent session, rejecting iSCSI Login.\n");
467 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
468 ISCSI_LOGIN_STATUS_NO_SESSION);
469 return -1;
470 }
471
472 /*
473 * Stop the Time2Retain timer if this is a failed session, we restart
474 * the timer if the login is not successful.
475 */
476 spin_lock_bh(&sess->conn_lock);
477 if (sess->session_state == TARG_SESS_STATE_FAILED)
478 atomic_set(&sess->session_continuation, 1);
479 spin_unlock_bh(&sess->conn_lock);
480
481 iscsi_login_set_conn_values(sess, conn, pdu->cid);
482
483 if (iscsi_copy_param_list(&conn->param_list,
484 ISCSI_TPG_C(conn)->param_list, 0) < 0) {
485 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
486 ISCSI_LOGIN_STATUS_NO_RESOURCES);
487 return -1;
488 }
489
490 iscsi_set_keys_to_negotiate(0, conn->param_list);
491 /*
492 * Need to send TargetPortalGroupTag back in first login response
493 * on any iSCSI connection where the Initiator provides TargetName.
494 * See 5.3.1. Login Phase Start
495 *
496 * In our case, we have already located the struct iscsi_tiqn at this point.
497 */
498 memset(buf, 0, 32);
499 sprintf(buf, "TargetPortalGroupTag=%hu", ISCSI_TPG_S(sess)->tpgt);
500 if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) {
501 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
502 ISCSI_LOGIN_STATUS_NO_RESOURCES);
503 return -1;
504 }
505
506 return iscsi_login_disable_FIM_keys(conn->param_list, conn);
507 }
508
509 int iscsi_login_post_auth_non_zero_tsih(
510 struct iscsi_conn *conn,
511 u16 cid,
512 u32 exp_statsn)
513 {
514 struct iscsi_conn *conn_ptr = NULL;
515 struct iscsi_conn_recovery *cr = NULL;
516 struct iscsi_session *sess = conn->sess;
517
518 /*
519 * By following item 5 in the login table, if we have found
520 * an existing ISID and a valid/existing TSIH and an existing
521 * CID we do connection reinstatement. Currently we dont not
522 * support it so we send back an non-zero status class to the
523 * initiator and release the new connection.
524 */
525 conn_ptr = iscsit_get_conn_from_cid_rcfr(sess, cid);
526 if (conn_ptr) {
527 pr_err("Connection exists with CID %hu for %s,"
528 " performing connection reinstatement.\n",
529 conn_ptr->cid, sess->sess_ops->InitiatorName);
530
531 iscsit_connection_reinstatement_rcfr(conn_ptr);
532 iscsit_dec_conn_usage_count(conn_ptr);
533 }
534
535 /*
536 * Check for any connection recovery entires containing CID.
537 * We use the original ExpStatSN sent in the first login request
538 * to acknowledge commands for the failed connection.
539 *
540 * Also note that an explict logout may have already been sent,
541 * but the response may not be sent due to additional connection
542 * loss.
543 */
544 if (sess->sess_ops->ErrorRecoveryLevel == 2) {
545 cr = iscsit_get_inactive_connection_recovery_entry(
546 sess, cid);
547 if (cr) {
548 pr_debug("Performing implicit logout"
549 " for connection recovery on CID: %hu\n",
550 conn->cid);
551 iscsit_discard_cr_cmds_by_expstatsn(cr, exp_statsn);
552 }
553 }
554
555 /*
556 * Else we follow item 4 from the login table in that we have
557 * found an existing ISID and a valid/existing TSIH and a new
558 * CID we go ahead and continue to add a new connection to the
559 * session.
560 */
561 pr_debug("Adding CID %hu to existing session for %s.\n",
562 cid, sess->sess_ops->InitiatorName);
563
564 if ((atomic_read(&sess->nconn) + 1) > sess->sess_ops->MaxConnections) {
565 pr_err("Adding additional connection to this session"
566 " would exceed MaxConnections %d, login failed.\n",
567 sess->sess_ops->MaxConnections);
568 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
569 ISCSI_LOGIN_STATUS_ISID_ERROR);
570 return -1;
571 }
572
573 return 0;
574 }
575
576 static void iscsi_post_login_start_timers(struct iscsi_conn *conn)
577 {
578 struct iscsi_session *sess = conn->sess;
579
580 if (!sess->sess_ops->SessionType)
581 iscsit_start_nopin_timer(conn);
582 }
583
584 static int iscsi_post_login_handler(
585 struct iscsi_np *np,
586 struct iscsi_conn *conn,
587 u8 zero_tsih)
588 {
589 int stop_timer = 0;
590 struct iscsi_session *sess = conn->sess;
591 struct se_session *se_sess = sess->se_sess;
592 struct iscsi_portal_group *tpg = ISCSI_TPG_S(sess);
593 struct se_portal_group *se_tpg = &tpg->tpg_se_tpg;
594 struct iscsi_thread_set *ts;
595
596 iscsit_inc_conn_usage_count(conn);
597
598 iscsit_collect_login_stats(conn, ISCSI_STATUS_CLS_SUCCESS,
599 ISCSI_LOGIN_STATUS_ACCEPT);
600
601 pr_debug("Moving to TARG_CONN_STATE_LOGGED_IN.\n");
602 conn->conn_state = TARG_CONN_STATE_LOGGED_IN;
603
604 iscsi_set_connection_parameters(conn->conn_ops, conn->param_list);
605 iscsit_set_sync_and_steering_values(conn);
606 /*
607 * SCSI Initiator -> SCSI Target Port Mapping
608 */
609 ts = iscsi_get_thread_set();
610 if (!zero_tsih) {
611 iscsi_set_session_parameters(sess->sess_ops,
612 conn->param_list, 0);
613 iscsi_release_param_list(conn->param_list);
614 conn->param_list = NULL;
615
616 spin_lock_bh(&sess->conn_lock);
617 atomic_set(&sess->session_continuation, 0);
618 if (sess->session_state == TARG_SESS_STATE_FAILED) {
619 pr_debug("Moving to"
620 " TARG_SESS_STATE_LOGGED_IN.\n");
621 sess->session_state = TARG_SESS_STATE_LOGGED_IN;
622 stop_timer = 1;
623 }
624
625 pr_debug("iSCSI Login successful on CID: %hu from %s to"
626 " %s:%hu,%hu\n", conn->cid, conn->login_ip,
627 conn->local_ip, conn->local_port, tpg->tpgt);
628
629 list_add_tail(&conn->conn_list, &sess->sess_conn_list);
630 atomic_inc(&sess->nconn);
631 pr_debug("Incremented iSCSI Connection count to %hu"
632 " from node: %s\n", atomic_read(&sess->nconn),
633 sess->sess_ops->InitiatorName);
634 spin_unlock_bh(&sess->conn_lock);
635
636 iscsi_post_login_start_timers(conn);
637 iscsi_activate_thread_set(conn, ts);
638 /*
639 * Determine CPU mask to ensure connection's RX and TX kthreads
640 * are scheduled on the same CPU.
641 */
642 iscsit_thread_get_cpumask(conn);
643 conn->conn_rx_reset_cpumask = 1;
644 conn->conn_tx_reset_cpumask = 1;
645
646 iscsit_dec_conn_usage_count(conn);
647 if (stop_timer) {
648 spin_lock_bh(&se_tpg->session_lock);
649 iscsit_stop_time2retain_timer(sess);
650 spin_unlock_bh(&se_tpg->session_lock);
651 }
652 iscsit_dec_session_usage_count(sess);
653 return 0;
654 }
655
656 iscsi_set_session_parameters(sess->sess_ops, conn->param_list, 1);
657 iscsi_release_param_list(conn->param_list);
658 conn->param_list = NULL;
659
660 iscsit_determine_maxcmdsn(sess);
661
662 spin_lock_bh(&se_tpg->session_lock);
663 __transport_register_session(&sess->tpg->tpg_se_tpg,
664 se_sess->se_node_acl, se_sess, sess);
665 pr_debug("Moving to TARG_SESS_STATE_LOGGED_IN.\n");
666 sess->session_state = TARG_SESS_STATE_LOGGED_IN;
667
668 pr_debug("iSCSI Login successful on CID: %hu from %s to %s:%hu,%hu\n",
669 conn->cid, conn->login_ip, conn->local_ip, conn->local_port,
670 tpg->tpgt);
671
672 spin_lock_bh(&sess->conn_lock);
673 list_add_tail(&conn->conn_list, &sess->sess_conn_list);
674 atomic_inc(&sess->nconn);
675 pr_debug("Incremented iSCSI Connection count to %hu from node:"
676 " %s\n", atomic_read(&sess->nconn),
677 sess->sess_ops->InitiatorName);
678 spin_unlock_bh(&sess->conn_lock);
679
680 sess->sid = tpg->sid++;
681 if (!sess->sid)
682 sess->sid = tpg->sid++;
683 pr_debug("Established iSCSI session from node: %s\n",
684 sess->sess_ops->InitiatorName);
685
686 tpg->nsessions++;
687 if (tpg->tpg_tiqn)
688 tpg->tpg_tiqn->tiqn_nsessions++;
689
690 pr_debug("Incremented number of active iSCSI sessions to %u on"
691 " iSCSI Target Portal Group: %hu\n", tpg->nsessions, tpg->tpgt);
692 spin_unlock_bh(&se_tpg->session_lock);
693
694 iscsi_post_login_start_timers(conn);
695 iscsi_activate_thread_set(conn, ts);
696 /*
697 * Determine CPU mask to ensure connection's RX and TX kthreads
698 * are scheduled on the same CPU.
699 */
700 iscsit_thread_get_cpumask(conn);
701 conn->conn_rx_reset_cpumask = 1;
702 conn->conn_tx_reset_cpumask = 1;
703
704 iscsit_dec_conn_usage_count(conn);
705
706 return 0;
707 }
708
709 static void iscsi_handle_login_thread_timeout(unsigned long data)
710 {
711 struct iscsi_np *np = (struct iscsi_np *) data;
712
713 spin_lock_bh(&np->np_thread_lock);
714 pr_err("iSCSI Login timeout on Network Portal %s:%hu\n",
715 np->np_ip, np->np_port);
716
717 if (np->np_login_timer_flags & ISCSI_TF_STOP) {
718 spin_unlock_bh(&np->np_thread_lock);
719 return;
720 }
721
722 if (np->np_thread)
723 send_sig(SIGINT, np->np_thread, 1);
724
725 np->np_login_timer_flags &= ~ISCSI_TF_RUNNING;
726 spin_unlock_bh(&np->np_thread_lock);
727 }
728
729 static void iscsi_start_login_thread_timer(struct iscsi_np *np)
730 {
731 /*
732 * This used the TA_LOGIN_TIMEOUT constant because at this
733 * point we do not have access to ISCSI_TPG_ATTRIB(tpg)->login_timeout
734 */
735 spin_lock_bh(&np->np_thread_lock);
736 init_timer(&np->np_login_timer);
737 np->np_login_timer.expires = (get_jiffies_64() + TA_LOGIN_TIMEOUT * HZ);
738 np->np_login_timer.data = (unsigned long)np;
739 np->np_login_timer.function = iscsi_handle_login_thread_timeout;
740 np->np_login_timer_flags &= ~ISCSI_TF_STOP;
741 np->np_login_timer_flags |= ISCSI_TF_RUNNING;
742 add_timer(&np->np_login_timer);
743
744 pr_debug("Added timeout timer to iSCSI login request for"
745 " %u seconds.\n", TA_LOGIN_TIMEOUT);
746 spin_unlock_bh(&np->np_thread_lock);
747 }
748
749 static void iscsi_stop_login_thread_timer(struct iscsi_np *np)
750 {
751 spin_lock_bh(&np->np_thread_lock);
752 if (!(np->np_login_timer_flags & ISCSI_TF_RUNNING)) {
753 spin_unlock_bh(&np->np_thread_lock);
754 return;
755 }
756 np->np_login_timer_flags |= ISCSI_TF_STOP;
757 spin_unlock_bh(&np->np_thread_lock);
758
759 del_timer_sync(&np->np_login_timer);
760
761 spin_lock_bh(&np->np_thread_lock);
762 np->np_login_timer_flags &= ~ISCSI_TF_RUNNING;
763 spin_unlock_bh(&np->np_thread_lock);
764 }
765
766 int iscsi_target_setup_login_socket(
767 struct iscsi_np *np,
768 struct __kernel_sockaddr_storage *sockaddr)
769 {
770 struct socket *sock;
771 int backlog = 5, ret, opt = 0, len;
772
773 switch (np->np_network_transport) {
774 case ISCSI_TCP:
775 np->np_ip_proto = IPPROTO_TCP;
776 np->np_sock_type = SOCK_STREAM;
777 break;
778 case ISCSI_SCTP_TCP:
779 np->np_ip_proto = IPPROTO_SCTP;
780 np->np_sock_type = SOCK_STREAM;
781 break;
782 case ISCSI_SCTP_UDP:
783 np->np_ip_proto = IPPROTO_SCTP;
784 np->np_sock_type = SOCK_SEQPACKET;
785 break;
786 case ISCSI_IWARP_TCP:
787 case ISCSI_IWARP_SCTP:
788 case ISCSI_INFINIBAND:
789 default:
790 pr_err("Unsupported network_transport: %d\n",
791 np->np_network_transport);
792 return -EINVAL;
793 }
794
795 ret = sock_create(sockaddr->ss_family, np->np_sock_type,
796 np->np_ip_proto, &sock);
797 if (ret < 0) {
798 pr_err("sock_create() failed.\n");
799 return ret;
800 }
801 np->np_socket = sock;
802 /*
803 * Setup the np->np_sockaddr from the passed sockaddr setup
804 * in iscsi_target_configfs.c code..
805 */
806 memcpy(&np->np_sockaddr, sockaddr,
807 sizeof(struct __kernel_sockaddr_storage));
808
809 if (sockaddr->ss_family == AF_INET6)
810 len = sizeof(struct sockaddr_in6);
811 else
812 len = sizeof(struct sockaddr_in);
813 /*
814 * Set SO_REUSEADDR, and disable Nagel Algorithm with TCP_NODELAY.
815 */
816 /* FIXME: Someone please explain why this is endian-safe */
817 opt = 1;
818 if (np->np_network_transport == ISCSI_TCP) {
819 ret = kernel_setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
820 (char *)&opt, sizeof(opt));
821 if (ret < 0) {
822 pr_err("kernel_setsockopt() for TCP_NODELAY"
823 " failed: %d\n", ret);
824 goto fail;
825 }
826 }
827
828 /* FIXME: Someone please explain why this is endian-safe */
829 ret = kernel_setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
830 (char *)&opt, sizeof(opt));
831 if (ret < 0) {
832 pr_err("kernel_setsockopt() for SO_REUSEADDR"
833 " failed\n");
834 goto fail;
835 }
836
837 ret = kernel_setsockopt(sock, IPPROTO_IP, IP_FREEBIND,
838 (char *)&opt, sizeof(opt));
839 if (ret < 0) {
840 pr_err("kernel_setsockopt() for IP_FREEBIND"
841 " failed\n");
842 goto fail;
843 }
844
845 ret = kernel_bind(sock, (struct sockaddr *)&np->np_sockaddr, len);
846 if (ret < 0) {
847 pr_err("kernel_bind() failed: %d\n", ret);
848 goto fail;
849 }
850
851 ret = kernel_listen(sock, backlog);
852 if (ret != 0) {
853 pr_err("kernel_listen() failed: %d\n", ret);
854 goto fail;
855 }
856
857 return 0;
858
859 fail:
860 np->np_socket = NULL;
861 if (sock)
862 sock_release(sock);
863 return ret;
864 }
865
866 static int __iscsi_target_login_thread(struct iscsi_np *np)
867 {
868 u8 buffer[ISCSI_HDR_LEN], iscsi_opcode, zero_tsih = 0;
869 int err, ret = 0, stop;
870 struct iscsi_conn *conn = NULL;
871 struct iscsi_login *login;
872 struct iscsi_portal_group *tpg = NULL;
873 struct socket *new_sock, *sock;
874 struct kvec iov;
875 struct iscsi_login_req *pdu;
876 struct sockaddr_in sock_in;
877 struct sockaddr_in6 sock_in6;
878
879 flush_signals(current);
880 sock = np->np_socket;
881
882 spin_lock_bh(&np->np_thread_lock);
883 if (np->np_thread_state == ISCSI_NP_THREAD_RESET) {
884 np->np_thread_state = ISCSI_NP_THREAD_ACTIVE;
885 complete(&np->np_restart_comp);
886 } else {
887 np->np_thread_state = ISCSI_NP_THREAD_ACTIVE;
888 }
889 spin_unlock_bh(&np->np_thread_lock);
890
891 if (kernel_accept(sock, &new_sock, 0) < 0) {
892 spin_lock_bh(&np->np_thread_lock);
893 if (np->np_thread_state == ISCSI_NP_THREAD_RESET) {
894 spin_unlock_bh(&np->np_thread_lock);
895 complete(&np->np_restart_comp);
896 /* Get another socket */
897 return 1;
898 }
899 spin_unlock_bh(&np->np_thread_lock);
900 goto out;
901 }
902 iscsi_start_login_thread_timer(np);
903
904 conn = kzalloc(sizeof(struct iscsi_conn), GFP_KERNEL);
905 if (!conn) {
906 pr_err("Could not allocate memory for"
907 " new connection\n");
908 sock_release(new_sock);
909 /* Get another socket */
910 return 1;
911 }
912
913 pr_debug("Moving to TARG_CONN_STATE_FREE.\n");
914 conn->conn_state = TARG_CONN_STATE_FREE;
915 conn->sock = new_sock;
916
917 pr_debug("Moving to TARG_CONN_STATE_XPT_UP.\n");
918 conn->conn_state = TARG_CONN_STATE_XPT_UP;
919
920 /*
921 * Allocate conn->conn_ops early as a failure calling
922 * iscsit_tx_login_rsp() below will call tx_data().
923 */
924 conn->conn_ops = kzalloc(sizeof(struct iscsi_conn_ops), GFP_KERNEL);
925 if (!conn->conn_ops) {
926 pr_err("Unable to allocate memory for"
927 " struct iscsi_conn_ops.\n");
928 goto new_sess_out;
929 }
930 /*
931 * Perform the remaining iSCSI connection initialization items..
932 */
933 if (iscsi_login_init_conn(conn) < 0)
934 goto new_sess_out;
935
936 memset(buffer, 0, ISCSI_HDR_LEN);
937 memset(&iov, 0, sizeof(struct kvec));
938 iov.iov_base = buffer;
939 iov.iov_len = ISCSI_HDR_LEN;
940
941 if (rx_data(conn, &iov, 1, ISCSI_HDR_LEN) <= 0) {
942 pr_err("rx_data() returned an error.\n");
943 goto new_sess_out;
944 }
945
946 iscsi_opcode = (buffer[0] & ISCSI_OPCODE_MASK);
947 if (!(iscsi_opcode & ISCSI_OP_LOGIN)) {
948 pr_err("First opcode is not login request,"
949 " failing login request.\n");
950 goto new_sess_out;
951 }
952
953 pdu = (struct iscsi_login_req *) buffer;
954
955 /*
956 * Used by iscsit_tx_login_rsp() for Login Resonses PDUs
957 * when Status-Class != 0.
958 */
959 conn->login_itt = pdu->itt;
960
961 spin_lock_bh(&np->np_thread_lock);
962 if (np->np_thread_state != ISCSI_NP_THREAD_ACTIVE) {
963 spin_unlock_bh(&np->np_thread_lock);
964 pr_err("iSCSI Network Portal on %s:%hu currently not"
965 " active.\n", np->np_ip, np->np_port);
966 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
967 ISCSI_LOGIN_STATUS_SVC_UNAVAILABLE);
968 goto new_sess_out;
969 }
970 spin_unlock_bh(&np->np_thread_lock);
971
972 if (np->np_sockaddr.ss_family == AF_INET6) {
973 memset(&sock_in6, 0, sizeof(struct sockaddr_in6));
974
975 if (conn->sock->ops->getname(conn->sock,
976 (struct sockaddr *)&sock_in6, &err, 1) < 0) {
977 pr_err("sock_ops->getname() failed.\n");
978 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
979 ISCSI_LOGIN_STATUS_TARGET_ERROR);
980 goto new_sess_out;
981 }
982 snprintf(conn->login_ip, sizeof(conn->login_ip), "%pI6c",
983 &sock_in6.sin6_addr.in6_u);
984 conn->login_port = ntohs(sock_in6.sin6_port);
985
986 if (conn->sock->ops->getname(conn->sock,
987 (struct sockaddr *)&sock_in6, &err, 0) < 0) {
988 pr_err("sock_ops->getname() failed.\n");
989 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
990 ISCSI_LOGIN_STATUS_TARGET_ERROR);
991 goto new_sess_out;
992 }
993 snprintf(conn->local_ip, sizeof(conn->local_ip), "%pI6c",
994 &sock_in6.sin6_addr.in6_u);
995 conn->local_port = ntohs(sock_in6.sin6_port);
996
997 } else {
998 memset(&sock_in, 0, sizeof(struct sockaddr_in));
999
1000 if (conn->sock->ops->getname(conn->sock,
1001 (struct sockaddr *)&sock_in, &err, 1) < 0) {
1002 pr_err("sock_ops->getname() failed.\n");
1003 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
1004 ISCSI_LOGIN_STATUS_TARGET_ERROR);
1005 goto new_sess_out;
1006 }
1007 sprintf(conn->login_ip, "%pI4", &sock_in.sin_addr.s_addr);
1008 conn->login_port = ntohs(sock_in.sin_port);
1009
1010 if (conn->sock->ops->getname(conn->sock,
1011 (struct sockaddr *)&sock_in, &err, 0) < 0) {
1012 pr_err("sock_ops->getname() failed.\n");
1013 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
1014 ISCSI_LOGIN_STATUS_TARGET_ERROR);
1015 goto new_sess_out;
1016 }
1017 sprintf(conn->local_ip, "%pI4", &sock_in.sin_addr.s_addr);
1018 conn->local_port = ntohs(sock_in.sin_port);
1019 }
1020
1021 conn->network_transport = np->np_network_transport;
1022
1023 pr_debug("Received iSCSI login request from %s on %s Network"
1024 " Portal %s:%hu\n", conn->login_ip,
1025 (conn->network_transport == ISCSI_TCP) ? "TCP" : "SCTP",
1026 conn->local_ip, conn->local_port);
1027
1028 pr_debug("Moving to TARG_CONN_STATE_IN_LOGIN.\n");
1029 conn->conn_state = TARG_CONN_STATE_IN_LOGIN;
1030
1031 if (iscsi_login_check_initiator_version(conn, pdu->max_version,
1032 pdu->min_version) < 0)
1033 goto new_sess_out;
1034
1035 zero_tsih = (pdu->tsih == 0x0000);
1036 if (zero_tsih) {
1037 /*
1038 * This is the leading connection of a new session.
1039 * We wait until after authentication to check for
1040 * session reinstatement.
1041 */
1042 if (iscsi_login_zero_tsih_s1(conn, buffer) < 0)
1043 goto new_sess_out;
1044 } else {
1045 /*
1046 * Add a new connection to an existing session.
1047 * We check for a non-existant session in
1048 * iscsi_login_non_zero_tsih_s2() below based
1049 * on ISID/TSIH, but wait until after authentication
1050 * to check for connection reinstatement, etc.
1051 */
1052 if (iscsi_login_non_zero_tsih_s1(conn, buffer) < 0)
1053 goto new_sess_out;
1054 }
1055
1056 /*
1057 * This will process the first login request, and call
1058 * iscsi_target_locate_portal(), and return a valid struct iscsi_login.
1059 */
1060 login = iscsi_target_init_negotiation(np, conn, buffer);
1061 if (!login) {
1062 tpg = conn->tpg;
1063 goto new_sess_out;
1064 }
1065
1066 tpg = conn->tpg;
1067 if (!tpg) {
1068 pr_err("Unable to locate struct iscsi_conn->tpg\n");
1069 goto new_sess_out;
1070 }
1071
1072 if (zero_tsih) {
1073 if (iscsi_login_zero_tsih_s2(conn) < 0) {
1074 iscsi_target_nego_release(login, conn);
1075 goto new_sess_out;
1076 }
1077 } else {
1078 if (iscsi_login_non_zero_tsih_s2(conn, buffer) < 0) {
1079 iscsi_target_nego_release(login, conn);
1080 goto old_sess_out;
1081 }
1082 }
1083
1084 if (iscsi_target_start_negotiation(login, conn) < 0)
1085 goto new_sess_out;
1086
1087 if (!conn->sess) {
1088 pr_err("struct iscsi_conn session pointer is NULL!\n");
1089 goto new_sess_out;
1090 }
1091
1092 iscsi_stop_login_thread_timer(np);
1093
1094 if (signal_pending(current))
1095 goto new_sess_out;
1096
1097 ret = iscsi_post_login_handler(np, conn, zero_tsih);
1098
1099 if (ret < 0)
1100 goto new_sess_out;
1101
1102 iscsit_deaccess_np(np, tpg);
1103 tpg = NULL;
1104 /* Get another socket */
1105 return 1;
1106
1107 new_sess_out:
1108 pr_err("iSCSI Login negotiation failed.\n");
1109 iscsit_collect_login_stats(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
1110 ISCSI_LOGIN_STATUS_INIT_ERR);
1111 if (!zero_tsih || !conn->sess)
1112 goto old_sess_out;
1113 if (conn->sess->se_sess)
1114 transport_free_session(conn->sess->se_sess);
1115 if (conn->sess->session_index != 0) {
1116 spin_lock_bh(&sess_idr_lock);
1117 idr_remove(&sess_idr, conn->sess->session_index);
1118 spin_unlock_bh(&sess_idr_lock);
1119 }
1120 if (conn->sess->sess_ops)
1121 kfree(conn->sess->sess_ops);
1122 if (conn->sess)
1123 kfree(conn->sess);
1124 old_sess_out:
1125 iscsi_stop_login_thread_timer(np);
1126 /*
1127 * If login negotiation fails check if the Time2Retain timer
1128 * needs to be restarted.
1129 */
1130 if (!zero_tsih && conn->sess) {
1131 spin_lock_bh(&conn->sess->conn_lock);
1132 if (conn->sess->session_state == TARG_SESS_STATE_FAILED) {
1133 struct se_portal_group *se_tpg =
1134 &ISCSI_TPG_C(conn)->tpg_se_tpg;
1135
1136 atomic_set(&conn->sess->session_continuation, 0);
1137 spin_unlock_bh(&conn->sess->conn_lock);
1138 spin_lock_bh(&se_tpg->session_lock);
1139 iscsit_start_time2retain_handler(conn->sess);
1140 spin_unlock_bh(&se_tpg->session_lock);
1141 } else
1142 spin_unlock_bh(&conn->sess->conn_lock);
1143 iscsit_dec_session_usage_count(conn->sess);
1144 }
1145
1146 if (!IS_ERR(conn->conn_rx_hash.tfm))
1147 crypto_free_hash(conn->conn_rx_hash.tfm);
1148 if (!IS_ERR(conn->conn_tx_hash.tfm))
1149 crypto_free_hash(conn->conn_tx_hash.tfm);
1150
1151 if (conn->conn_cpumask)
1152 free_cpumask_var(conn->conn_cpumask);
1153
1154 kfree(conn->conn_ops);
1155
1156 if (conn->param_list) {
1157 iscsi_release_param_list(conn->param_list);
1158 conn->param_list = NULL;
1159 }
1160 if (conn->sock)
1161 sock_release(conn->sock);
1162 kfree(conn);
1163
1164 if (tpg) {
1165 iscsit_deaccess_np(np, tpg);
1166 tpg = NULL;
1167 }
1168
1169 out:
1170 stop = kthread_should_stop();
1171 if (!stop && signal_pending(current)) {
1172 spin_lock_bh(&np->np_thread_lock);
1173 stop = (np->np_thread_state == ISCSI_NP_THREAD_SHUTDOWN);
1174 spin_unlock_bh(&np->np_thread_lock);
1175 }
1176 /* Wait for another socket.. */
1177 if (!stop)
1178 return 1;
1179
1180 iscsi_stop_login_thread_timer(np);
1181 spin_lock_bh(&np->np_thread_lock);
1182 np->np_thread_state = ISCSI_NP_THREAD_EXIT;
1183 spin_unlock_bh(&np->np_thread_lock);
1184 return 0;
1185 }
1186
1187 int iscsi_target_login_thread(void *arg)
1188 {
1189 struct iscsi_np *np = arg;
1190 int ret;
1191
1192 allow_signal(SIGINT);
1193
1194 while (!kthread_should_stop()) {
1195 ret = __iscsi_target_login_thread(np);
1196 /*
1197 * We break and exit here unless another sock_accept() call
1198 * is expected.
1199 */
1200 if (ret != 1)
1201 break;
1202 }
1203
1204 return 0;
1205 }