summaryrefslogtreecommitdiff
path: root/usr.sbin/iscsid
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2011-01-04 13:19:56 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2011-01-04 13:19:56 +0000
commit9b81c3ce326e0a7660ca76b5323696b65544d58c (patch)
treef9186d411c098ddabbcd1c795ea9a82f58daf8c3 /usr.sbin/iscsid
parent10d5b27eee32af0bcfe9a70c767f9e71229d1c3b (diff)
Implememnt NOP-IN -> NOP-OUT handling. If the NOP-In was issued by the
target (itt = 0xffffffff) send back an immediate NOP-Out reusing the NOP-In PDU. This makes my iscsi target happy. Also plug a mem leak on error path which was found by Igor Zinovik.
Diffstat (limited to 'usr.sbin/iscsid')
-rw-r--r--usr.sbin/iscsid/initiator.c27
-rw-r--r--usr.sbin/iscsid/iscsid.h9
-rw-r--r--usr.sbin/iscsid/task.c10
3 files changed, 40 insertions, 6 deletions
diff --git a/usr.sbin/iscsid/initiator.c b/usr.sbin/iscsid/initiator.c
index c41a149eb84..5e706cc82a7 100644
--- a/usr.sbin/iscsid/initiator.c
+++ b/usr.sbin/iscsid/initiator.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: initiator.c,v 1.3 2010/09/25 16:20:06 sobrado Exp $ */
+/* $OpenBSD: initiator.c,v 1.4 2011/01/04 13:19:55 claudio Exp $ */
/*
* Copyright (c) 2009 Claudio Jeker <claudio@openbsd.org>
@@ -326,6 +326,7 @@ initiator_discovery(struct session *s)
if (!(p = initiator_text_build(t, s, kvp))) {
log_warnx("initiator_text_build failed");
+ free(t);
return;
}
@@ -394,6 +395,30 @@ fail:
pdu_free(p);
}
+void
+initiator_nop_in_imm(struct connection *c, struct pdu *p)
+{
+ struct iscsi_pdu_nop_in *nopin;
+ struct task *t;
+
+ /* fixup NOP-IN to make it a NOP-OUT */
+ nopin = pdu_getbuf(p, NULL, PDU_HEADER);
+ nopin->maxcmdsn = 0;
+ nopin->opcode = ISCSI_OP_I_NOP | ISCSI_OP_F_IMMEDIATE;
+
+ /* and schedule an immediate task */
+ if (!(t = calloc(1, sizeof(*t)))) {
+ log_warn("initiator_nop_in_imm");
+ pdu_free(p);
+ return;
+ }
+
+ task_init(t, c->session, 1, NULL, NULL);
+ t->itt = 0xffffffff; /* change ITT because it is just a ping reply */
+ task_pdu_add(t, p);
+ conn_task_issue(c, t);
+}
+
char *
default_initiator_name(void)
{
diff --git a/usr.sbin/iscsid/iscsid.h b/usr.sbin/iscsid/iscsid.h
index e6bc592164b..c5c19f4f00a 100644
--- a/usr.sbin/iscsid/iscsid.h
+++ b/usr.sbin/iscsid/iscsid.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: iscsid.h,v 1.3 2011/01/04 09:50:18 claudio Exp $ */
+/* $OpenBSD: iscsid.h,v 1.4 2011/01/04 13:19:55 claudio Exp $ */
/*
* Copyright (c) 2009 Claudio Jeker <claudio@openbsd.org>
@@ -238,8 +238,11 @@ struct kvp {
void iscsid_ctrl_dispatch(void *, struct pdu *);
struct initiator *initiator_init(void);
-void initiator_cleanup(struct initiator *);
+void initiator_cleanup(struct initiator *);
struct session *initiator_t2s(u_int);
+void initiator_login(struct connection *);
+void initiator_discovery(struct session *);
+void initiator_nop_in_imm(struct connection *, struct pdu *);
int control_init(char *);
void control_cleanup(char *);
@@ -254,8 +257,6 @@ void session_config(struct session *, struct session_config *);
void session_task_issue(struct session *, struct task *);
void session_schedule(struct session *);
void session_task_login(struct connection *);
-void initiator_login(struct connection *);
-void initiator_discovery(struct session *);
void conn_new(struct session *, struct connection_config *);
void conn_free(struct connection *);
diff --git a/usr.sbin/iscsid/task.c b/usr.sbin/iscsid/task.c
index 87926931c98..6150625fa74 100644
--- a/usr.sbin/iscsid/task.c
+++ b/usr.sbin/iscsid/task.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: task.c,v 1.4 2011/01/04 09:53:17 claudio Exp $ */
+/* $OpenBSD: task.c,v 1.5 2011/01/04 13:19:55 claudio Exp $ */
/*
* Copyright (c) 2009 Claudio Jeker <claudio@openbsd.org>
@@ -93,6 +93,14 @@ task_pdu_cb(struct connection *c, struct pdu *p)
ipdu = pdu_getbuf(p, NULL, PDU_HEADER);
switch (ISCSI_PDU_OPCODE(ipdu->opcode)) {
case ISCSI_OP_T_NOP:
+ itt = ntohl(ipdu->itt);
+ if (itt == 0xffffffff) {
+ /* target issued a ping, must answer back immediately */
+ c->expstatsn = ntohl(ipdu->cmdsn) + 1;
+ initiator_nop_in_imm(c, p);
+ break;
+ }
+ /* FALLTHROUGH */
case ISCSI_OP_LOGIN_RESPONSE:
case ISCSI_OP_TEXT_RESPONSE:
case ISCSI_OP_LOGOUT_RESPONSE: