Author: mav
Date: Sun Jul  6 17:37:49 2014
New Revision: 268326
URL: http://svnweb.freebsd.org/changeset/base/268326

Log:
  Make iSCSI initiator keep Initiator Session ID (ISID) across reconnects.
  
  Previously ISID was changed every time, that made impossible correct
  persistent reservation, because reconnected session was identified as
  completely new one.
  
  Reviewed by:  trasz
  MFC after:    1 week

Modified:
  head/sys/dev/iscsi/iscsi.c
  head/sys/dev/iscsi/iscsi.h
  head/sys/dev/iscsi/iscsi_ioctl.h
  head/usr.sbin/iscsid/iscsid.c
  head/usr.sbin/iscsid/iscsid.h
  head/usr.sbin/iscsid/login.c

Modified: head/sys/dev/iscsi/iscsi.c
==============================================================================
--- head/sys/dev/iscsi/iscsi.c  Sun Jul  6 17:29:19 2014        (r268325)
+++ head/sys/dev/iscsi/iscsi.c  Sun Jul  6 17:37:49 2014        (r268326)
@@ -1221,6 +1221,9 @@ iscsi_ioctl_daemon_wait(struct iscsi_sof
                ISCSI_SESSION_UNLOCK(is);
 
                request->idr_session_id = is->is_id;
+               memcpy(&request->idr_isid, &is->is_isid,
+                   sizeof(request->idr_isid));
+               request->idr_tsih = 0;  /* New or reinstated session. */
                memcpy(&request->idr_conf, &is->is_conf,
                    sizeof(request->idr_conf));
 
@@ -1270,7 +1273,7 @@ iscsi_ioctl_daemon_handoff(struct iscsi_
 
        strlcpy(is->is_target_alias, handoff->idh_target_alias,
            sizeof(is->is_target_alias));
-       memcpy(is->is_isid, handoff->idh_isid, sizeof(is->is_isid));
+       is->is_tsih = handoff->idh_tsih;
        is->is_statsn = handoff->idh_statsn;
        is->is_initial_r2t = handoff->idh_initial_r2t;
        is->is_immediate_data = handoff->idh_immediate_data;
@@ -1663,6 +1666,9 @@ iscsi_ioctl_session_add(struct iscsi_sof
        is->is_softc = sc;
        sc->sc_last_session_id++;
        is->is_id = sc->sc_last_session_id;
+       is->is_isid[0] = 0x80; /* RFC 3720, 10.12.5: 10b, "Random" ISID. */
+       arc4rand(&is->is_isid[1], 5, 0);
+       is->is_tsih = 0;
        callout_init(&is->is_callout, 1);
        callout_reset(&is->is_callout, 1 * hz, iscsi_callout, is);
        TAILQ_INSERT_TAIL(&sc->sc_sessions, is, is_next);

Modified: head/sys/dev/iscsi/iscsi.h
==============================================================================
--- head/sys/dev/iscsi/iscsi.h  Sun Jul  6 17:29:19 2014        (r268325)
+++ head/sys/dev/iscsi/iscsi.h  Sun Jul  6 17:37:49 2014        (r268326)
@@ -64,6 +64,7 @@ struct iscsi_session {
        size_t                          is_max_burst_length;
        size_t                          is_first_burst_length;
        uint8_t                         is_isid[6];
+       uint16_t                        is_tsih;
        bool                            is_immediate_data;
        size_t                          is_max_data_segment_length;
        char                            is_target_alias[ISCSI_ALIAS_LEN];

Modified: head/sys/dev/iscsi/iscsi_ioctl.h
==============================================================================
--- head/sys/dev/iscsi/iscsi_ioctl.h    Sun Jul  6 17:29:19 2014        
(r268325)
+++ head/sys/dev/iscsi/iscsi_ioctl.h    Sun Jul  6 17:37:49 2014        
(r268326)
@@ -91,8 +91,8 @@ struct iscsi_session_state {
 struct iscsi_daemon_request {
        unsigned int                    idr_session_id;
        struct iscsi_session_conf       idr_conf;
-       uint8_t                         idr_spare_isid[6];
-       uint16_t                        idr_spare_tsih;
+       uint8_t                         idr_isid[6];
+       uint16_t                        idr_tsih;
        uint16_t                        idr_spare_cid;
        int                             idr_spare[4];
 };
@@ -101,9 +101,9 @@ struct iscsi_daemon_handoff {
        unsigned int                    idh_session_id;
        int                             idh_socket;
        char                            idh_target_alias[ISCSI_ALIAS_LEN];
-       uint8_t                         idh_isid[6];
-       uint16_t                        idr_spare_tsih;
-       uint16_t                        idr_spare_cid;
+       uint8_t                         idh_spare_isid[6];
+       uint16_t                        idh_tsih;
+       uint16_t                        idh_spare_cid;
        uint32_t                        idh_statsn;
        int                             idh_header_digest;
        int                             idh_data_digest;

Modified: head/usr.sbin/iscsid/iscsid.c
==============================================================================
--- head/usr.sbin/iscsid/iscsid.c       Sun Jul  6 17:29:19 2014        
(r268325)
+++ head/usr.sbin/iscsid/iscsid.c       Sun Jul  6 17:37:49 2014        
(r268326)
@@ -149,8 +149,8 @@ resolve_addr(const struct connection *co
 }
 
 static struct connection *
-connection_new(unsigned int session_id, const struct iscsi_session_conf *conf,
-    int iscsi_fd)
+connection_new(unsigned int session_id, const uint8_t isid[8], uint16_t tsih,
+    const struct iscsi_session_conf *conf, int iscsi_fd)
 {
        struct connection *conn;
        struct addrinfo *from_ai, *to_ai;
@@ -176,6 +176,8 @@ connection_new(unsigned int session_id, 
        conn->conn_first_burst_length = 65536;
 
        conn->conn_session_id = session_id;
+       memcpy(&conn->conn_isid, isid, sizeof(conn->conn_isid));
+       conn->conn_tsih = tsih;
        conn->conn_iscsi_fd = iscsi_fd;
 
        /*
@@ -264,7 +266,7 @@ handoff(struct connection *conn)
        idh.idh_socket = conn->conn_socket;
        strlcpy(idh.idh_target_alias, conn->conn_target_alias,
            sizeof(idh.idh_target_alias));
-       memcpy(idh.idh_isid, conn->conn_isid, sizeof(idh.idh_isid));
+       idh.idh_tsih = conn->conn_tsih;
        idh.idh_statsn = conn->conn_statsn;
        idh.idh_header_digest = conn->conn_header_digest;
        idh.idh_data_digest = conn->conn_data_digest;
@@ -430,7 +432,8 @@ handle_request(int iscsi_fd, const struc
                setproctitle("%s", request->idr_conf.isc_target_addr);
        }
 
-       conn = connection_new(request->idr_session_id, &request->idr_conf, 
iscsi_fd);
+       conn = connection_new(request->idr_session_id, request->idr_isid,
+           request->idr_tsih, &request->idr_conf, iscsi_fd);
        set_timeout(timeout);
        capsicate(conn);
        login(conn);

Modified: head/usr.sbin/iscsid/iscsid.h
==============================================================================
--- head/usr.sbin/iscsid/iscsid.h       Sun Jul  6 17:29:19 2014        
(r268325)
+++ head/usr.sbin/iscsid/iscsid.h       Sun Jul  6 17:37:49 2014        
(r268326)
@@ -51,6 +51,7 @@ struct connection {
        struct iscsi_session_conf       conn_conf;
        char                    conn_target_alias[ISCSI_ADDR_LEN];
        uint8_t                 conn_isid[6];
+       uint16_t                conn_tsih;
        uint32_t                conn_statsn;
        int                     conn_header_digest;
        int                     conn_data_digest;

Modified: head/usr.sbin/iscsid/login.c
==============================================================================
--- head/usr.sbin/iscsid/login.c        Sun Jul  6 17:29:19 2014        
(r268325)
+++ head/usr.sbin/iscsid/login.c        Sun Jul  6 17:37:49 2014        
(r268326)
@@ -260,6 +260,7 @@ login_receive(struct connection *conn)
                    "is %d, should be %d", ntohl(bhslr->bhslr_statsn),
                    conn->conn_statsn + 1);
        }
+       conn->conn_tsih = ntohs(bhslr->bhslr_tsih);
        conn->conn_statsn = ntohl(bhslr->bhslr_statsn);
 
        initial = false;
@@ -295,6 +296,7 @@ login_new_request(struct connection *con
        login_set_nsg(request, nsg);
 
        memcpy(bhslr->bhslr_isid, &conn->conn_isid, sizeof(bhslr->bhslr_isid));
+       bhslr->bhslr_tsih = htons(conn->conn_tsih);
        bhslr->bhslr_initiator_task_tag = 0;
        bhslr->bhslr_cmdsn = 0;
        bhslr->bhslr_expstatsn = htonl(conn->conn_statsn + 1);
@@ -824,24 +826,6 @@ login_chap(struct connection *conn)
        log_debugx("CHAP authentication done");
 }
 
-static void
-login_create_isid(struct connection *conn)
-{
-       int rv;
-
-       /*
-        * RFC 3720, 10.12.5: 10b, "Random" ISID.
-        *
-        */
-       conn->conn_isid[0] = 0x80; 
-
-       rv = RAND_bytes(&conn->conn_isid[1], 3);
-       if (rv != 1) {
-               log_errx(1, "RAND_bytes failed: %s",
-                   ERR_error_string(ERR_get_error(), NULL));
-       }
-}
-
 void
 login(struct connection *conn)
 {
@@ -851,8 +835,6 @@ login(struct connection *conn)
        const char *auth_method;
        int i;
 
-       login_create_isid(conn);
-
        log_debugx("beginning Login phase; sending Login PDU");
        request = login_new_request(conn, BHSLR_STAGE_SECURITY_NEGOTIATION);
        request_keys = keys_new();
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to