diff options
-rw-r--r-- | usr.sbin/ctld/ctld.c | 1 | ||||
-rw-r--r-- | usr.sbin/ctld/ctld.h | 6 | ||||
-rw-r--r-- | usr.sbin/ctld/login.c | 67 |
3 files changed, 48 insertions, 26 deletions
diff --git a/usr.sbin/ctld/ctld.c b/usr.sbin/ctld/ctld.c index d812bd271564..4f0521f718e9 100644 --- a/usr.sbin/ctld/ctld.c +++ b/usr.sbin/ctld/ctld.c @@ -1582,6 +1582,7 @@ connection_new(struct portal *portal, int fd, const char *host, * 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; diff --git a/usr.sbin/ctld/ctld.h b/usr.sbin/ctld/ctld.h index 85cbd324507e..8452a158e980 100644 --- a/usr.sbin/ctld/ctld.h +++ b/usr.sbin/ctld/ctld.h @@ -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; diff --git a/usr.sbin/ctld/login.c b/usr.sbin/ctld/login.c index 5c3586821b2f..3fb65024becb 100644 --- a/usr.sbin/ctld/login.c +++ b/usr.sbin/ctld/login.c @@ -557,13 +557,15 @@ login_negotiate_key(struct pdu *request, const char *name, * 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, const char *name, 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, const char *name, 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, struct pdu *request) * 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; } |