git: 6378393308bc - main - Add an internal libiscsiutil library.
Date: Wed, 22 Dec 2021 18:43:35 UTC
The branch main has been updated by jhb:
URL: https://cgit.FreeBSD.org/src/commit/?id=6378393308bc6bd81fb871dacf6b03cf1a390d8b
commit 6378393308bc6bd81fb871dacf6b03cf1a390d8b
Author: John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2021-12-22 18:35:46 +0000
Commit: John Baldwin <jhb@FreeBSD.org>
CommitDate: 2021-12-22 18:43:11 +0000
Add an internal libiscsiutil library.
Move some of the code duplicated between ctld(8) and iscsid(8) into a
libiscsiutil library.
Sharing the low-level PDU code did require having a
'struct connection' base class with a method table to permit separate
initiator vs target behavior (e.g. in handling proxy PDUs).
Reviewed by: mav, emaste
Sponsored by: Chelsio Communications
Differential Revision: https://reviews.freebsd.org/D33544
---
lib/Makefile | 1 +
lib/libiscsiutil/Makefile | 10 +
{usr.sbin/ctld => lib/libiscsiutil}/chap.c | 6 +-
lib/libiscsiutil/connection.c | 53 ++++
{usr.sbin/ctld => lib/libiscsiutil}/keys.c | 6 +-
lib/libiscsiutil/libiscsiutil.h | 148 ++++++++++
{usr.sbin/ctld => lib/libiscsiutil}/log.c | 6 +-
{usr.sbin/ctld => lib/libiscsiutil}/pdu.c | 96 ++-----
lib/libiscsiutil/utils.c | 44 +++
rescue/rescue/Makefile | 3 +
share/mk/bsd.libnames.mk | 1 +
share/mk/src.libnames.mk | 4 +
usr.sbin/ctld/Makefile | 7 +-
usr.sbin/ctld/ctld.c | 86 ++++--
usr.sbin/ctld/ctld.h | 102 +------
usr.sbin/ctld/discovery.c | 8 +-
usr.sbin/ctld/kernel.c | 27 +-
usr.sbin/ctld/login.c | 51 ++--
usr.sbin/iscsid/Makefile | 5 +-
usr.sbin/iscsid/chap.c | 423 -----------------------------
usr.sbin/iscsid/discovery.c | 14 +-
usr.sbin/iscsid/iscsid.c | 173 ++++++++----
usr.sbin/iscsid/iscsid.h | 97 +------
usr.sbin/iscsid/keys.c | 199 --------------
usr.sbin/iscsid/log.c | 202 --------------
usr.sbin/iscsid/login.c | 74 ++---
usr.sbin/iscsid/pdu.c | 309 ---------------------
27 files changed, 583 insertions(+), 1572 deletions(-)
diff --git a/lib/Makefile b/lib/Makefile
index bd28b974c673..43c345daf356 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -63,6 +63,7 @@ SUBDIR= ${SUBDIR_BOOTSTRAP} \
libgeom \
libifconfig \
libipsec \
+ libiscsiutil \
libjail \
libkiconv \
libkvm \
diff --git a/lib/libiscsiutil/Makefile b/lib/libiscsiutil/Makefile
new file mode 100644
index 000000000000..9ec625970eae
--- /dev/null
+++ b/lib/libiscsiutil/Makefile
@@ -0,0 +1,10 @@
+LIB= iscsiutil
+INTERNALLIB=
+PACKAGE= iscsi
+
+INCS= libiscsiutil.h
+
+SRCS= chap.c connection.c keys.c log.c pdu.c utils.c
+CFLAGS+= -I${SRCTOP}/sys/dev/iscsi
+
+.include <bsd.lib.mk>
diff --git a/usr.sbin/ctld/chap.c b/lib/libiscsiutil/chap.c
similarity index 99%
rename from usr.sbin/ctld/chap.c
rename to lib/libiscsiutil/chap.c
index 7b57b7080c97..b33fef220106 100644
--- a/usr.sbin/ctld/chap.c
+++ b/lib/libiscsiutil/chap.c
@@ -26,12 +26,8 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <assert.h>
#include <stdlib.h>
#include <string.h>
@@ -39,7 +35,7 @@ __FBSDID("$FreeBSD$");
#include <resolv.h>
#include <md5.h>
-#include "ctld.h"
+#include "libiscsiutil.h"
static void
chap_compute_md5(const char id, const char *secret,
diff --git a/lib/libiscsiutil/connection.c b/lib/libiscsiutil/connection.c
new file mode 100644
index 000000000000..7dc50574644c
--- /dev/null
+++ b/lib/libiscsiutil/connection.c
@@ -0,0 +1,53 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2012 The FreeBSD Foundation
+ *
+ * This software was developed by Edward Tomasz Napierala under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <string.h>
+
+#include "libiscsiutil.h"
+
+void
+connection_init(struct connection *conn, const struct connection_ops *ops,
+ bool use_proxy)
+{
+ memset(conn, 0, sizeof(*conn));
+ conn->conn_ops = ops;
+ conn->conn_use_proxy = use_proxy;
+
+ /*
+ * Default values, from RFC 3720, section 12.
+ */
+ conn->conn_header_digest = CONN_DIGEST_NONE;
+ conn->conn_data_digest = CONN_DIGEST_NONE;
+ conn->conn_immediate_data = true;
+ 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;
+}
diff --git a/usr.sbin/ctld/keys.c b/lib/libiscsiutil/keys.c
similarity index 98%
rename from usr.sbin/ctld/keys.c
rename to lib/libiscsiutil/keys.c
index f28e333bcd81..8011b0a25329 100644
--- a/usr.sbin/ctld/keys.c
+++ b/lib/libiscsiutil/keys.c
@@ -26,18 +26,14 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include "ctld.h"
+#include "libiscsiutil.h"
struct keys *
keys_new(void)
diff --git a/lib/libiscsiutil/libiscsiutil.h b/lib/libiscsiutil/libiscsiutil.h
new file mode 100644
index 000000000000..79c79872b2e6
--- /dev/null
+++ b/lib/libiscsiutil/libiscsiutil.h
@@ -0,0 +1,148 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2012 The FreeBSD Foundation
+ *
+ * This software was developed by Edward Tomasz Napierala under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef __LIBISCSIUTIL_H__
+#define __LIBISCSIUTIL_H__
+
+#include <sys/types.h>
+#include <stdbool.h>
+
+struct connection_ops;
+
+#define CONN_DIGEST_NONE 0
+#define CONN_DIGEST_CRC32C 1
+
+struct connection {
+ const struct connection_ops *conn_ops;
+ int conn_socket;
+ uint8_t conn_isid[6];
+ uint16_t conn_tsih;
+ uint32_t conn_cmdsn;
+ uint32_t conn_statsn;
+ int conn_header_digest;
+ int conn_data_digest;
+ bool conn_immediate_data;
+ bool conn_use_proxy;
+ int conn_max_recv_data_segment_length;
+ int conn_max_send_data_segment_length;
+ int conn_max_burst_length;
+ int conn_first_burst_length;
+};
+
+struct pdu {
+ struct connection *pdu_connection;
+ struct iscsi_bhs *pdu_bhs;
+ char *pdu_data;
+ size_t pdu_data_len;
+};
+
+struct connection_ops {
+ bool (*timed_out)(void);
+ void (*pdu_receive_proxy)(struct pdu *);
+ void (*pdu_send_proxy)(struct pdu *);
+ void (*fail)(const struct connection *, const char *);
+};
+
+#define KEYS_MAX 1024
+
+struct keys {
+ char *keys_names[KEYS_MAX];
+ char *keys_values[KEYS_MAX];
+ char *keys_data;
+ size_t keys_data_len;
+};
+
+#define CHAP_CHALLENGE_LEN 1024
+#define CHAP_DIGEST_LEN 16 /* Equal to MD5 digest size. */
+
+struct chap {
+ unsigned char chap_id;
+ char chap_challenge[CHAP_CHALLENGE_LEN];
+ char chap_response[CHAP_DIGEST_LEN];
+};
+
+struct rchap {
+ char *rchap_secret;
+ unsigned char rchap_id;
+ void *rchap_challenge;
+ size_t rchap_challenge_len;
+};
+
+struct chap *chap_new(void);
+char *chap_get_id(const struct chap *chap);
+char *chap_get_challenge(const struct chap *chap);
+int chap_receive(struct chap *chap, const char *response);
+int chap_authenticate(struct chap *chap,
+ const char *secret);
+void chap_delete(struct chap *chap);
+
+struct rchap *rchap_new(const char *secret);
+int rchap_receive(struct rchap *rchap,
+ const char *id, const char *challenge);
+char *rchap_get_response(struct rchap *rchap);
+void rchap_delete(struct rchap *rchap);
+
+struct keys *keys_new(void);
+void keys_delete(struct keys *key);
+void keys_load(struct keys *keys, const struct pdu *pdu);
+void keys_save(struct keys *keys, struct pdu *pdu);
+const char *keys_find(struct keys *keys, const char *name);
+void keys_add(struct keys *keys,
+ const char *name, const char *value);
+void keys_add_int(struct keys *keys,
+ const char *name, int value);
+
+struct pdu *pdu_new(struct connection *ic);
+struct pdu *pdu_new_response(struct pdu *request);
+int pdu_ahs_length(const struct pdu *pdu);
+int pdu_data_segment_length(const struct pdu *pdu);
+void pdu_set_data_segment_length(struct pdu *pdu,
+ uint32_t len);
+void pdu_receive(struct pdu *request);
+void pdu_send(struct pdu *response);
+void pdu_delete(struct pdu *ip);
+
+void connection_init(struct connection *conn,
+ const struct connection_ops *ops, bool use_proxy);
+
+void log_init(int level);
+void log_set_peer_name(const char *name);
+void log_set_peer_addr(const char *addr);
+void log_err(int, const char *, ...)
+ __dead2 __printflike(2, 3);
+void log_errx(int, const char *, ...)
+ __dead2 __printflike(2, 3);
+void log_warn(const char *, ...) __printflike(1, 2);
+void log_warnx(const char *, ...) __printflike(1, 2);
+void log_debugx(const char *, ...) __printflike(1, 2);
+
+char *checked_strdup(const char *);
+
+#endif /* !__LIBISCSIUTIL_H__ */
diff --git a/usr.sbin/ctld/log.c b/lib/libiscsiutil/log.c
similarity index 98%
rename from usr.sbin/ctld/log.c
rename to lib/libiscsiutil/log.c
index 94e014293a61..7d7a13bb11f2 100644
--- a/usr.sbin/ctld/log.c
+++ b/lib/libiscsiutil/log.c
@@ -26,12 +26,8 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
@@ -40,7 +36,7 @@ __FBSDID("$FreeBSD$");
#include <syslog.h>
#include <vis.h>
-#include "ctld.h"
+#include "libiscsiutil.h"
static int log_level = 0;
static char *peer_name = NULL;
diff --git a/usr.sbin/ctld/pdu.c b/lib/libiscsiutil/pdu.c
similarity index 77%
rename from usr.sbin/ctld/pdu.c
rename to lib/libiscsiutil/pdu.c
index 04691556b997..ed5ee5b71766 100644
--- a/usr.sbin/ctld/pdu.c
+++ b/lib/libiscsiutil/pdu.c
@@ -35,26 +35,22 @@ __FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/uio.h>
#include <assert.h>
+#include <errno.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
-#include "ctld.h"
-#include "iscsi_proto.h"
+#include <iscsi_proto.h>
+#include "libiscsiutil.h"
-#ifdef ICL_KERNEL_PROXY
-#include <sys/ioctl.h>
-#endif
-
-extern bool proxy_mode;
-
-static int
+int
pdu_ahs_length(const struct pdu *pdu)
{
return (pdu->pdu_bhs->bhs_total_ahs_len * 4);
}
-static int
+int
pdu_data_segment_length(const struct pdu *pdu)
{
uint32_t len = 0;
@@ -68,7 +64,7 @@ pdu_data_segment_length(const struct pdu *pdu)
return (len);
}
-static void
+void
pdu_set_data_segment_length(struct pdu *pdu, uint32_t len)
{
@@ -102,40 +98,6 @@ pdu_new_response(struct pdu *request)
return (pdu_new(request->pdu_connection));
}
-#ifdef ICL_KERNEL_PROXY
-
-static void
-pdu_receive_proxy(struct pdu *pdu)
-{
- struct connection *conn;
- size_t len;
-
- assert(proxy_mode);
- conn = pdu->pdu_connection;
-
- kernel_receive(pdu);
-
- len = pdu_ahs_length(pdu);
- if (len > 0)
- log_errx(1, "protocol error: non-empty AHS");
-
- len = pdu_data_segment_length(pdu);
- assert(len <= (size_t)conn->conn_max_recv_data_segment_length);
- pdu->pdu_data_len = len;
-}
-
-static void
-pdu_send_proxy(struct pdu *pdu)
-{
-
- assert(proxy_mode);
-
- pdu_set_data_segment_length(pdu, pdu->pdu_data_len);
- kernel_send(pdu);
-}
-
-#endif /* ICL_KERNEL_PROXY */
-
static size_t
pdu_padding(const struct pdu *pdu)
{
@@ -147,18 +109,24 @@ pdu_padding(const struct pdu *pdu)
}
static void
-pdu_read(int fd, char *data, size_t len)
+pdu_read(const struct connection *conn, char *data, size_t len)
{
ssize_t ret;
while (len > 0) {
- ret = read(fd, data, len);
+ ret = read(conn->conn_socket, data, len);
if (ret < 0) {
- if (timed_out())
+ if (conn->conn_ops->timed_out()) {
+ conn->conn_ops->fail(conn,
+ "Login Phase timeout");
log_errx(1, "exiting due to timeout");
+ }
+ conn->conn_ops->fail(conn, strerror(errno));
log_err(1, "read");
- } else if (ret == 0)
+ } else if (ret == 0) {
+ conn->conn_ops->fail(conn, "connection lost");
log_errx(1, "read: connection lost");
+ }
len -= ret;
data += ret;
}
@@ -171,16 +139,11 @@ pdu_receive(struct pdu *pdu)
size_t len, padding;
char dummy[4];
-#ifdef ICL_KERNEL_PROXY
- if (proxy_mode)
- return (pdu_receive_proxy(pdu));
-#endif
-
- assert(proxy_mode == false);
conn = pdu->pdu_connection;
+ if (conn->conn_use_proxy)
+ return (conn->conn_ops->pdu_receive_proxy(pdu));
- pdu_read(conn->conn_socket, (char *)pdu->pdu_bhs,
- sizeof(*pdu->pdu_bhs));
+ pdu_read(conn, (char *)pdu->pdu_bhs, sizeof(*pdu->pdu_bhs));
len = pdu_ahs_length(pdu);
if (len > 0)
@@ -199,13 +162,12 @@ pdu_receive(struct pdu *pdu)
if (pdu->pdu_data == NULL)
log_err(1, "malloc");
- pdu_read(conn->conn_socket, (char *)pdu->pdu_data,
- pdu->pdu_data_len);
+ pdu_read(conn, (char *)pdu->pdu_data, pdu->pdu_data_len);
padding = pdu_padding(pdu);
if (padding != 0) {
assert(padding < sizeof(dummy));
- pdu_read(conn->conn_socket, (char *)dummy, padding);
+ pdu_read(conn, (char *)dummy, padding);
}
}
}
@@ -213,18 +175,16 @@ pdu_receive(struct pdu *pdu)
void
pdu_send(struct pdu *pdu)
{
+ struct connection *conn;
ssize_t ret, total_len;
size_t padding;
uint32_t zero = 0;
struct iovec iov[3];
int iovcnt;
-#ifdef ICL_KERNEL_PROXY
- if (proxy_mode)
- return (pdu_send_proxy(pdu));
-#endif
-
- assert(proxy_mode == false);
+ conn = pdu->pdu_connection;
+ if (conn->conn_use_proxy)
+ return (conn->conn_ops->pdu_send_proxy(pdu));
pdu_set_data_segment_length(pdu, pdu->pdu_data_len);
iov[0].iov_base = pdu->pdu_bhs;
@@ -248,9 +208,9 @@ pdu_send(struct pdu *pdu)
}
}
- ret = writev(pdu->pdu_connection->conn_socket, iov, iovcnt);
+ ret = writev(conn->conn_socket, iov, iovcnt);
if (ret < 0) {
- if (timed_out())
+ if (conn->conn_ops->timed_out())
log_errx(1, "exiting due to timeout");
log_err(1, "writev");
}
diff --git a/lib/libiscsiutil/utils.c b/lib/libiscsiutil/utils.c
new file mode 100644
index 000000000000..1e04490c477c
--- /dev/null
+++ b/lib/libiscsiutil/utils.c
@@ -0,0 +1,44 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2012 The FreeBSD Foundation
+ *
+ * This software was developed by Edward Tomasz Napierala under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <string.h>
+
+#include "libiscsiutil.h"
+
+char *
+checked_strdup(const char *s)
+{
+ char *c;
+
+ c = strdup(s);
+ if (c == NULL)
+ log_err(1, "strdup");
+ return (c);
+}
diff --git a/rescue/rescue/Makefile b/rescue/rescue/Makefile
index 90aaea3cb709..783b5bbd7721 100644
--- a/rescue/rescue/Makefile
+++ b/rescue/rescue/Makefile
@@ -236,6 +236,9 @@ CRUNCH_LIBS+= -lm
.if ${MK_ISCSI} != "no"
CRUNCH_PROGS_usr.bin+= iscsictl
CRUNCH_PROGS_usr.sbin+= iscsid
+
+CRUNCH_LIBS+= ${OBJTOP}/lib/libiscsiutil/libiscsiutil.a
+CRUNCH_BUILDOPTS+= CRUNCH_CFLAGS+=-I${OBJTOP}/lib/libiscsiutil
.endif
.include <bsd.crunchgen.mk>
diff --git a/share/mk/bsd.libnames.mk b/share/mk/bsd.libnames.mk
index f71664bf5858..45710b203ddc 100644
--- a/share/mk/bsd.libnames.mk
+++ b/share/mk/bsd.libnames.mk
@@ -83,6 +83,7 @@ LIBIBVERBS?= ${LIBDESTDIR}${LIBDIR_BASE}/libibverbs.a
LIBICP?= ${LIBDESTDIR}${LIBDIR_BASE}/libicp.a
LIBIPSEC?= ${LIBDESTDIR}${LIBDIR_BASE}/libipsec.a
LIBIPT?= ${LIBDESTDIR}${LIBDIR_BASE}/libipt.a
+LIBISCSIUTIL?= ${LIBDESTDIR}${LIBDIR_BASE}/libiscsiutil.a
LIBJAIL?= ${LIBDESTDIR}${LIBDIR_BASE}/libjail.a
LIBKADM5CLNT?= ${LIBDESTDIR}${LIBDIR_BASE}/libkadm5clnt.a
LIBKADM5SRV?= ${LIBDESTDIR}${LIBDIR_BASE}/libkadm5srv.a
diff --git a/share/mk/src.libnames.mk b/share/mk/src.libnames.mk
index 385e8616a82d..cf6c41887791 100644
--- a/share/mk/src.libnames.mk
+++ b/share/mk/src.libnames.mk
@@ -44,6 +44,7 @@ _INTERNALLIBS= \
fifolog \
ifconfig \
ipf \
+ iscsiutil \
lpr \
lua \
lutok \
@@ -556,6 +557,9 @@ LIBIFCONFIG?= ${LIBIFCONFIGDIR}/libifconfig${PIE_SUFFIX}.a
LIBIPFDIR= ${_LIB_OBJTOP}/sbin/ipf/libipf
LIBIPF?= ${LIBIPFDIR}/libipf${PIE_SUFFIX}.a
+LIBISCSIUTILDIR= ${_LIB_OBJTOP}/lib/libiscsiutil
+LIBISCSIUTIL?= ${LIBISCSIUTILDIR}/libiscsiutil${PIE_SUFFIX}.a
+
LIBTELNETDIR= ${_LIB_OBJTOP}/lib/libtelnet
LIBTELNET?= ${LIBTELNETDIR}/libtelnet${PIE_SUFFIX}.a
diff --git a/usr.sbin/ctld/Makefile b/usr.sbin/ctld/Makefile
index ec207f024ab1..5f80ba026204 100644
--- a/usr.sbin/ctld/Makefile
+++ b/usr.sbin/ctld/Makefile
@@ -7,16 +7,17 @@ CFLAGS+=-I${SRCTOP}/contrib/libucl/include
PACKAGE= iscsi
PROG= ctld
-SRCS= chap.c ctld.c discovery.c isns.c kernel.c keys.c log.c
-SRCS+= login.c parse.y pdu.c token.l y.tab.h uclparse.c
+SRCS= ctld.c discovery.c isns.c kernel.c
+SRCS+= login.c parse.y token.l y.tab.h uclparse.c
CFLAGS+= -I${.CURDIR}
CFLAGS+= -I${SRCTOP}/sys
CFLAGS+= -I${SRCTOP}/sys/cam/ctl
CFLAGS+= -I${SRCTOP}/sys/dev/iscsi
+CFLAGS+= -I${SRCTOP}/lib/libiscsiutil
#CFLAGS+= -DICL_KERNEL_PROXY
MAN= ctld.8 ctl.conf.5
-LIBADD= bsdxml md sbuf util ucl m nv
+LIBADD= bsdxml iscsiutil md sbuf util ucl m nv
YFLAGS+= -v
CLEANFILES= y.tab.c y.tab.h y.output
diff --git a/usr.sbin/ctld/ctld.c b/usr.sbin/ctld/ctld.c
index c37181ff00d0..3f4bca632512 100644
--- a/usr.sbin/ctld/ctld.c
+++ b/usr.sbin/ctld/ctld.c
@@ -54,6 +54,13 @@ __FBSDID("$FreeBSD$");
#include "ctld.h"
#include "isns.h"
+static bool timed_out(void);
+#ifdef ICL_KERNEL_PROXY
+static void pdu_receive_proxy(struct pdu *pdu);
+static void pdu_send_proxy(struct pdu *pdu);
+#endif /* ICL_KERNEL_PROXY */
+static void pdu_fail(const struct connection *conn, const char *reason);
+
bool proxy_mode = false;
static volatile bool sighup_received = false;
@@ -63,6 +70,15 @@ static volatile bool sigalrm_received = false;
static int nchildren = 0;
static uint16_t last_portal_group_tag = 0xff;
+static struct connection_ops conn_ops = {
+ .timed_out = timed_out,
+#ifdef ICL_KERNEL_PROXY
+ .pdu_receive_proxy = pdu_receive_proxy,
+ .pdu_send_proxy = pdu_send_proxy,
+#endif
+ .fail = pdu_fail,
+};
+
static void
usage(void)
{
@@ -72,17 +88,6 @@ usage(void)
exit(1);
}
-char *
-checked_strdup(const char *s)
-{
- char *c;
-
- c = strdup(s);
- if (c == NULL)
- log_err(1, "strdup");
- return (c);
-}
-
struct conf *
conf_new(void)
{
@@ -1632,29 +1637,60 @@ option_set(struct option *o, const char *value)
o->o_value = checked_strdup(value);
}
-static struct connection *
+#ifdef ICL_KERNEL_PROXY
+
+static void
+pdu_receive_proxy(struct pdu *pdu)
+{
+ struct connection *conn;
+ size_t len;
+
+ assert(proxy_mode);
+ conn = pdu->pdu_connection;
+
+ kernel_receive(pdu);
+
+ len = pdu_ahs_length(pdu);
+ if (len > 0)
+ log_errx(1, "protocol error: non-empty AHS");
+
+ len = pdu_data_segment_length(pdu);
+ assert(len <= (size_t)conn->conn_max_recv_data_segment_length);
+ pdu->pdu_data_len = len;
+}
+
+static void
+pdu_send_proxy(struct pdu *pdu)
+{
+
+ assert(proxy_mode);
+
+ pdu_set_data_segment_length(pdu, pdu->pdu_data_len);
+ kernel_send(pdu);
+}
+
+#endif /* ICL_KERNEL_PROXY */
+
+static void
+pdu_fail(const struct connection *conn __unused, const char *reason __unused)
+{
+}
+
+static struct ctld_connection *
connection_new(struct portal *portal, int fd, const char *host,
const struct sockaddr *client_sa)
{
- struct connection *conn;
+ struct ctld_connection *conn;
conn = calloc(1, sizeof(*conn));
if (conn == NULL)
log_err(1, "calloc");
+ connection_init(&conn->conn, &conn_ops, proxy_mode);
+ conn->conn.conn_socket = fd;
conn->conn_portal = portal;
- conn->conn_socket = fd;
conn->conn_initiator_addr = checked_strdup(host);
memcpy(&conn->conn_initiator_sa, client_sa, client_sa->sa_len);
- /*
- * 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;
-
return (conn);
}
@@ -2296,7 +2332,7 @@ conf_apply(struct conf *oldconf, struct conf *newconf)
return (cumulated_error);
}
-bool
+static bool
timed_out(void)
{
@@ -2407,7 +2443,7 @@ static void
handle_connection(struct portal *portal, int fd,
const struct sockaddr *client_sa, bool dont_fork)
{
- struct connection *conn;
+ struct ctld_connection *conn;
int error;
pid_t pid;
char host[NI_MAXHOST + 1];
diff --git a/usr.sbin/ctld/ctld.h b/usr.sbin/ctld/ctld.h
index 4ff8f0e638ac..293f5378592f 100644
--- a/usr.sbin/ctld/ctld.h
+++ b/usr.sbin/ctld/ctld.h
@@ -39,6 +39,7 @@
#endif
#include <sys/socket.h>
#include <stdbool.h>
+#include <libiscsiutil.h>
#include <libutil.h>
#define DEFAULT_CONFIG_PATH "/etc/ctl.conf"
@@ -229,83 +230,25 @@ struct conf {
#define CONN_SESSION_TYPE_DISCOVERY 1
#define CONN_SESSION_TYPE_NORMAL 2
-#define CONN_DIGEST_NONE 0
-#define CONN_DIGEST_CRC32C 1
-
-struct connection {
+struct ctld_connection {
+ struct connection conn;
struct portal *conn_portal;
struct port *conn_port;
struct target *conn_target;
- int conn_socket;
int conn_session_type;
char *conn_initiator_name;
char *conn_initiator_addr;
char *conn_initiator_alias;
uint8_t conn_initiator_isid[6];
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;
- int conn_first_burst_length;
- int conn_immediate_data;
- int conn_header_digest;
- int conn_data_digest;
const char *conn_user;
struct chap *conn_chap;
};
-struct pdu {
- struct connection *pdu_connection;
- struct iscsi_bhs *pdu_bhs;
- char *pdu_data;
- size_t pdu_data_len;
-};
-
-#define KEYS_MAX 1024
-
-struct keys {
- char *keys_names[KEYS_MAX];
- char *keys_values[KEYS_MAX];
- char *keys_data;
- size_t keys_data_len;
-};
-
-#define CHAP_CHALLENGE_LEN 1024
-#define CHAP_DIGEST_LEN 16 /* Equal to MD5 digest size. */
-
-struct chap {
- unsigned char chap_id;
- char chap_challenge[CHAP_CHALLENGE_LEN];
- char chap_response[CHAP_DIGEST_LEN];
-};
-
-struct rchap {
- char *rchap_secret;
- unsigned char rchap_id;
- void *rchap_challenge;
- size_t rchap_challenge_len;
-};
-
-struct chap *chap_new(void);
-char *chap_get_id(const struct chap *chap);
-char *chap_get_challenge(const struct chap *chap);
-int chap_receive(struct chap *chap, const char *response);
-int chap_authenticate(struct chap *chap,
- const char *secret);
-void chap_delete(struct chap *chap);
-
-struct rchap *rchap_new(const char *secret);
-int rchap_receive(struct rchap *rchap,
- const char *id, const char *challenge);
-char *rchap_get_response(struct rchap *rchap);
-void rchap_delete(struct rchap *rchap);
-
int parse_conf(struct conf *conf, const char *path);
int uclparse_conf(struct conf *conf, const char *path);
@@ -412,7 +355,7 @@ void kernel_init(void);
int kernel_lun_add(struct lun *lun);
int kernel_lun_modify(struct lun *lun);
int kernel_lun_remove(struct lun *lun);
-void kernel_handoff(struct connection *conn);
+void kernel_handoff(struct ctld_connection *conn);
void kernel_limits(const char *offload,
int *max_recv_data_segment_length,
int *max_send_data_segment_length,
@@ -433,40 +376,11 @@ void kernel_send(struct pdu *pdu);
void kernel_receive(struct pdu *pdu);
#endif
-struct keys *keys_new(void);
-void keys_delete(struct keys *keys);
-void keys_load(struct keys *keys, const struct pdu *pdu);
-void keys_save(struct keys *keys, struct pdu *pdu);
-const char *keys_find(struct keys *keys, const char *name);
-void keys_add(struct keys *keys,
- const char *name, const char *value);
-void keys_add_int(struct keys *keys,
- const char *name, int value);
-
-struct pdu *pdu_new(struct connection *conn);
-struct pdu *pdu_new_response(struct pdu *request);
-void pdu_delete(struct pdu *pdu);
-void pdu_receive(struct pdu *request);
-void pdu_send(struct pdu *response);
-
-void login(struct connection *conn);
-
-void discovery(struct connection *conn);
-
-void log_init(int level);
-void log_set_peer_name(const char *name);
-void log_set_peer_addr(const char *addr);
-void log_err(int, const char *, ...)
- __dead2 __printflike(2, 3);
-void log_errx(int, const char *, ...)
- __dead2 __printflike(2, 3);
-void log_warn(const char *, ...) __printflike(1, 2);
-void log_warnx(const char *, ...) __printflike(1, 2);
-void log_debugx(const char *, ...) __printflike(1, 2);
-
-char *checked_strdup(const char *);
+void login(struct ctld_connection *conn);
+
+void discovery(struct ctld_connection *conn);
+
bool valid_iscsi_name(const char *name);
void set_timeout(int timeout, int fatal);
-bool timed_out(void);
#endif /* !CTLD_H */
diff --git a/usr.sbin/ctld/discovery.c b/usr.sbin/ctld/discovery.c
*** 2321 LINES SKIPPED ***