Author: mav
Date: Sat Jan 14 18:04:12 2017
New Revision: 312190
URL: https://svnweb.freebsd.org/changeset/base/312190

Log:
  Decouple iSCSI connection limits from defaults.
  
  If initiator does not negotiate some parameter, it expects one to get
  default value, not some unknown remote hardware limit.  On the side side,
  if some parameter is negotiated, its default value from RFC should not
  be used for anything.

Modified:
  head/usr.sbin/ctld/ctld.c
  head/usr.sbin/ctld/ctld.h
  head/usr.sbin/ctld/login.c

Modified: head/usr.sbin/ctld/ctld.c
==============================================================================
--- head/usr.sbin/ctld/ctld.c   Sat Jan 14 16:58:49 2017        (r312189)
+++ head/usr.sbin/ctld/ctld.c   Sat Jan 14 18:04:12 2017        (r312190)
@@ -1582,6 +1582,7 @@ connection_new(struct portal *portal, in
         * Default values, from RFC 3720, section 12.
         */
        conn->conn_max_recv_data_segment_length = 8192;
+       conn->conn_max_send_data_segment_length = 8192;
        conn->conn_max_burst_length = 262144;
        conn->conn_first_burst_length = 65536;
        conn->conn_immediate_data = true;

Modified: head/usr.sbin/ctld/ctld.h
==============================================================================
--- head/usr.sbin/ctld/ctld.h   Sat Jan 14 16:58:49 2017        (r312189)
+++ head/usr.sbin/ctld/ctld.h   Sat Jan 14 18:04:12 2017        (r312190)
@@ -48,8 +48,6 @@
 #define        MAX_LUNS                        1024
 #define        MAX_NAME_LEN                    223
 #define        MAX_DATA_SEGMENT_LENGTH         (128 * 1024)
-#define        MAX_BURST_LENGTH                16776192
-#define        FIRST_BURST_LENGTH              (128 * 1024)
 #define        SOCKBUF_SIZE                    1048576
 
 struct auth {
@@ -242,6 +240,10 @@ struct connection {
        struct sockaddr_storage conn_initiator_sa;
        uint32_t                conn_cmdsn;
        uint32_t                conn_statsn;
+       int                     conn_max_recv_data_segment_limit;
+       int                     conn_max_send_data_segment_limit;
+       int                     conn_max_burst_limit;
+       int                     conn_first_burst_limit;
        int                     conn_max_recv_data_segment_length;
        int                     conn_max_send_data_segment_length;
        int                     conn_max_burst_length;

Modified: head/usr.sbin/ctld/login.c
==============================================================================
--- head/usr.sbin/ctld/login.c  Sat Jan 14 16:58:49 2017        (r312189)
+++ head/usr.sbin/ctld/login.c  Sat Jan 14 18:04:12 2017        (r312190)
@@ -557,13 +557,15 @@ login_negotiate_key(struct pdu *request,
                 * our MaxRecvDataSegmentLength is not influenced by the
                 * initiator in any way.
                 */
-               if ((int)tmp > conn->conn_max_send_data_segment_length) {
-                       log_debugx("capping max_send_data_segment_length "
+               if ((int)tmp > conn->conn_max_send_data_segment_limit) {
+                       log_debugx("capping MaxRecvDataSegmentLength "
                            "from %zd to %d", tmp,
-                           conn->conn_max_send_data_segment_length);
-                       tmp = conn->conn_max_send_data_segment_length;
+                           conn->conn_max_send_data_segment_limit);
+                       tmp = conn->conn_max_send_data_segment_limit;
                }
                conn->conn_max_send_data_segment_length = tmp;
+               conn->conn_max_recv_data_segment_length =
+                   conn->conn_max_recv_data_segment_limit;
                keys_add_int(response_keys, name,
                    conn->conn_max_recv_data_segment_length);
        } else if (strcmp(name, "MaxBurstLength") == 0) {
@@ -572,10 +574,10 @@ login_negotiate_key(struct pdu *request,
                        login_send_error(request, 0x02, 0x00);
                        log_errx(1, "received invalid MaxBurstLength");
                }
-               if ((int)tmp > conn->conn_max_burst_length) {
+               if ((int)tmp > conn->conn_max_burst_limit) {
                        log_debugx("capping MaxBurstLength from %zd to %d",
-                           tmp, conn->conn_max_burst_length);
-                       tmp = conn->conn_max_burst_length;
+                           tmp, conn->conn_max_burst_limit);
+                       tmp = conn->conn_max_burst_limit;
                }
                conn->conn_max_burst_length = tmp;
                keys_add_int(response_keys, name, tmp);
@@ -585,10 +587,10 @@ login_negotiate_key(struct pdu *request,
                        login_send_error(request, 0x02, 0x00);
                        log_errx(1, "received invalid FirstBurstLength");
                }
-               if ((int)tmp > conn->conn_first_burst_length) {
+               if ((int)tmp > conn->conn_first_burst_limit) {
                        log_debugx("capping FirstBurstLength from %zd to %d",
-                           tmp, conn->conn_first_burst_length);
-                       tmp = conn->conn_first_burst_length;
+                           tmp, conn->conn_first_burst_limit);
+                       tmp = conn->conn_first_burst_limit;
                }
                conn->conn_first_burst_length = tmp;
                keys_add_int(response_keys, name, tmp);
@@ -694,25 +696,42 @@ login_negotiate(struct connection *conn,
                 * offload, it depends on hardware capabilities.
                 */
                assert(conn->conn_target != NULL);
+               conn->conn_max_recv_data_segment_limit = (1 << 24) - 1;
+               conn->conn_max_send_data_segment_limit = (1 << 24) - 1;
+               conn->conn_max_burst_limit = (1 << 24) - 1;
+               conn->conn_first_burst_limit = (1 << 24) - 1;
                kernel_limits(conn->conn_portal->p_portal_group->pg_offload,
-                   &conn->conn_max_recv_data_segment_length,
-                   &conn->conn_max_send_data_segment_length,
-                   &conn->conn_max_burst_length,
-                   &conn->conn_first_burst_length);
+                   &conn->conn_max_recv_data_segment_limit,
+                   &conn->conn_max_send_data_segment_limit,
+                   &conn->conn_max_burst_limit,
+                   &conn->conn_first_burst_limit);
 
                /* We expect legal, usable values at this point. */
-               assert(conn->conn_max_recv_data_segment_length >= 512);
-               assert(conn->conn_max_recv_data_segment_length < (1 << 24));
-               assert(conn->conn_max_burst_length >= 512);
-               assert(conn->conn_max_burst_length < (1 << 24));
-               assert(conn->conn_first_burst_length >= 512);
-               assert(conn->conn_first_burst_length < (1 << 24));
-               assert(conn->conn_first_burst_length <=
-                   conn->conn_max_burst_length);
+               assert(conn->conn_max_recv_data_segment_limit >= 512);
+               assert(conn->conn_max_recv_data_segment_limit < (1 << 24));
+               assert(conn->conn_max_send_data_segment_limit >= 512);
+               assert(conn->conn_max_send_data_segment_limit < (1 << 24));
+               assert(conn->conn_max_burst_limit >= 512);
+               assert(conn->conn_max_burst_limit < (1 << 24));
+               assert(conn->conn_first_burst_limit >= 512);
+               assert(conn->conn_first_burst_limit < (1 << 24));
+               assert(conn->conn_first_burst_limit <=
+                   conn->conn_max_burst_limit);
+
+               /*
+                * Limit default send length in case it won't be negotiated.
+                * We can't do it for other limits, since they may affect both
+                * sender and receiver operation, and we must obey defaults.
+                */
+               if (conn->conn_max_send_data_segment_limit <
+                   conn->conn_max_send_data_segment_length) {
+                       conn->conn_max_send_data_segment_limit =
+                           conn->conn_max_send_data_segment_length;
+               }
        } else {
-               conn->conn_max_recv_data_segment_length =
+               conn->conn_max_recv_data_segment_limit =
                    MAX_DATA_SEGMENT_LENGTH;
-               conn->conn_max_send_data_segment_length =
+               conn->conn_max_send_data_segment_limit =
                    MAX_DATA_SEGMENT_LENGTH;
        }
 
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to