summaryrefslogtreecommitdiffstats
path: root/usr.sbin/ctld/login.c
diff options
context:
space:
mode:
authortrasz <trasz@FreeBSD.org>2015-02-06 21:03:25 +0000
committertrasz <trasz@FreeBSD.org>2015-02-06 21:03:25 +0000
commitba70dc0f4deacb9392d178bd7b48c20556486a5c (patch)
tree87c429dd203f72c20ec2b1a4649579aab5189db6 /usr.sbin/ctld/login.c
parent83fb4b4e9bdce5fa574089d1a3272a152b4a4a18 (diff)
downloadFreeBSD-src-ba70dc0f4deacb9392d178bd7b48c20556486a5c.zip
FreeBSD-src-ba70dc0f4deacb9392d178bd7b48c20556486a5c.tar.gz
Make it possible to set (via ctl.conf(5)) and query (via ctladm islist -v)
target iSCSI offload. Add mechanism to query maximum receive data segment size supported by chosen hardware offload module, and use it in ctld(8) to determine the value to advertise to the other side. MFC after: 1 month Sponsored by: The FreeBSD Foundation
Diffstat (limited to 'usr.sbin/ctld/login.c')
-rw-r--r--usr.sbin/ctld/login.c33
1 files changed, 23 insertions, 10 deletions
diff --git a/usr.sbin/ctld/login.c b/usr.sbin/ctld/login.c
index 865a19a..11d97cf 100644
--- a/usr.sbin/ctld/login.c
+++ b/usr.sbin/ctld/login.c
@@ -453,7 +453,8 @@ static void
login_negotiate_key(struct pdu *request, const char *name,
const char *value, bool skipped_security, struct keys *response_keys)
{
- int which, tmp;
+ int which;
+ size_t tmp;
struct connection *conn;
conn = request->pdu_connection;
@@ -552,13 +553,13 @@ login_negotiate_key(struct pdu *request, const char *name,
log_errx(1, "received invalid "
"MaxRecvDataSegmentLength");
}
- if (tmp > MAX_DATA_SEGMENT_LENGTH) {
+ if (tmp > conn->conn_data_segment_limit) {
log_debugx("capping MaxRecvDataSegmentLength "
- "from %d to %d", tmp, MAX_DATA_SEGMENT_LENGTH);
- tmp = MAX_DATA_SEGMENT_LENGTH;
+ "from %zd to %zd", tmp, conn->conn_data_segment_limit);
+ tmp = conn->conn_data_segment_limit;
}
conn->conn_max_data_segment_length = tmp;
- keys_add_int(response_keys, name, MAX_DATA_SEGMENT_LENGTH);
+ keys_add_int(response_keys, name, tmp);
} else if (strcmp(name, "MaxBurstLength") == 0) {
tmp = strtoul(value, NULL, 10);
if (tmp <= 0) {
@@ -566,7 +567,7 @@ login_negotiate_key(struct pdu *request, const char *name,
log_errx(1, "received invalid MaxBurstLength");
}
if (tmp > MAX_BURST_LENGTH) {
- log_debugx("capping MaxBurstLength from %d to %d",
+ log_debugx("capping MaxBurstLength from %zd to %d",
tmp, MAX_BURST_LENGTH);
tmp = MAX_BURST_LENGTH;
}
@@ -579,10 +580,10 @@ login_negotiate_key(struct pdu *request, const char *name,
log_errx(1, "received invalid "
"FirstBurstLength");
}
- if (tmp > MAX_DATA_SEGMENT_LENGTH) {
- log_debugx("capping FirstBurstLength from %d to %d",
- tmp, MAX_DATA_SEGMENT_LENGTH);
- tmp = MAX_DATA_SEGMENT_LENGTH;
+ if (tmp > conn->conn_data_segment_limit) {
+ log_debugx("capping FirstBurstLength from %zd to %zd",
+ tmp, conn->conn_data_segment_limit);
+ tmp = conn->conn_data_segment_limit;
}
/*
* We don't pass the value to the kernel; it only enforces
@@ -680,6 +681,18 @@ login_negotiate(struct connection *conn, struct pdu *request)
int i;
bool redirected, skipped_security;
+ if (conn->conn_session_type == CONN_SESSION_TYPE_NORMAL) {
+ /*
+ * Query the kernel for MaxDataSegmentLength it can handle.
+ * In case of offload, it depends on hardware capabilities.
+ */
+ assert(conn->conn_target != NULL);
+ kernel_limits(conn->conn_target->t_offload,
+ &conn->conn_data_segment_limit);
+ } else {
+ conn->conn_data_segment_limit = MAX_DATA_SEGMENT_LENGTH;
+ }
+
if (request == NULL) {
log_debugx("beginning operational parameter negotiation; "
"waiting for Login PDU");
OpenPOWER on IntegriCloud