Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 11 Sep 2014 20:01:58 +0000 (UTC)
From:      Edward Tomasz Napierala <trasz@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r271437 - head/usr.sbin/iscsid
Message-ID:  <201409112001.s8BK1woN025786@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: trasz
Date: Thu Sep 11 20:01:57 2014
New Revision: 271437
URL: http://svnweb.freebsd.org/changeset/base/271437

Log:
  Don't blindly assume the target agreed to transition to Full Feature Phase;
  if we got a Login Response PDU without the "T" bit set, try again with
  an empty request.  This fixes interoperability with COMSTAR.
  
  Reviewed by:	mav@
  Tested by:	mav@
  MFC after:	1 week

Modified:
  head/usr.sbin/iscsid/login.c

Modified: head/usr.sbin/iscsid/login.c
==============================================================================
--- head/usr.sbin/iscsid/login.c	Thu Sep 11 19:54:30 2014	(r271436)
+++ head/usr.sbin/iscsid/login.c	Thu Sep 11 20:01:57 2014	(r271437)
@@ -575,7 +575,7 @@ login_negotiate(struct connection *conn)
 	struct pdu *request, *response;
 	struct keys *request_keys, *response_keys;
 	struct iscsi_bhs_login_response *bhslr;
-	int i;
+	int i, nrequests = 0;
 
 	log_debugx("beginning operational parameter negotiation");
 	request = login_new_request(conn, BHSLR_STAGE_OPERATIONAL_NEGOTIATION);
@@ -629,19 +629,41 @@ login_negotiate(struct connection *conn)
 		    response_keys->keys_names[i], response_keys->keys_values[i]);
 	}
 
-	bhslr = (struct iscsi_bhs_login_response *)response->pdu_bhs;
-	if ((bhslr->bhslr_flags & BHSLR_FLAGS_TRANSIT) == 0)
-		log_warnx("received final login response "
-		    "without the \"T\" flag");
-	else if (login_nsg(response) != BHSLR_STAGE_FULL_FEATURE_PHASE)
+	keys_delete(response_keys);
+	response_keys = NULL;
+
+	for (;;) {
+		bhslr = (struct iscsi_bhs_login_response *)response->pdu_bhs;
+		if ((bhslr->bhslr_flags & BHSLR_FLAGS_TRANSIT) != 0)
+			break;
+
+		nrequests++;
+		if (nrequests > 5) {
+			log_warnx("received login response "
+			    "without the \"T\" flag too many times; giving up");
+			break;
+		}
+
+		log_debugx("received login response "
+		    "without the \"T\" flag; sending another request");
+
+		pdu_delete(response);
+
+		request = login_new_request(conn,
+		    BHSLR_STAGE_OPERATIONAL_NEGOTIATION);
+		pdu_send(request);
+		pdu_delete(request);
+
+		response = login_receive(conn);
+	}
+
+	if (login_nsg(response) != BHSLR_STAGE_FULL_FEATURE_PHASE)
 		log_warnx("received final login response with wrong NSG 0x%x",
 		    login_nsg(response));
+	pdu_delete(response);
 
 	log_debugx("operational parameter negotiation done; "
 	    "transitioning to Full Feature phase");
-
-	keys_delete(response_keys);
-	pdu_delete(response);
 }
 
 static void



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201409112001.s8BK1woN025786>