summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/ctld/ctld.c1
-rw-r--r--usr.sbin/ctld/ctld.h6
-rw-r--r--usr.sbin/ctld/login.c67
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;
}