I have a nasty feeling it's time to sell all my guitars:

Add some very crude hacks which allow the iscsi-target to work with IPv6:

Mar  5 23:43:45 sys3 iscsi-target: > Discovery login from iqn.1994-04.org.NetBSD.iscsi-initiator:agc on 7f00:1::1002:cbc
Mar  5 23:43:45 sys3 iscsi-target: < Discovery logout from iqn.1994-04.org.NetBSD.iscsi-initiator:agc on 7f00:1::1002:cbc
Mar  5 23:43:45 sys3 iscsi-target: > Normal login from iqn.1994-04.org.NetBSD.iscsi-initiator:agc on 7f00:1::1002:cbc
Mar  5 23:43:48 sys3 iscsi-target: < Normal logout from iqn.1994-04.org.NetBSD.iscsi-initiator:agc on 7f00:1::1002:cbc

These have still to be cleaned up, but this will happen over the next
few days.

Update the TODO list to reflect the current state.
This commit is contained in:
agc 2006-03-05 23:50:46 +00:00
parent 8c2379fd97
commit 32306cea7e
5 changed files with 76 additions and 22 deletions

View File

@ -50,7 +50,10 @@
enum {
MAX_TGT_NAME_SIZE = 512,
MAX_INITIATOR_ADDRESS_SIZE = 256
MAX_INITIATOR_ADDRESS_SIZE = 256,
ISCSI_IPv4 = 4,
ISCSI_IPv6 = 6
};
/* global variables, moved from target.c */
@ -63,6 +66,7 @@ typedef struct globals_t {
volatile int listener_listening; /* whether a listener is listening */
char targetaddress[MAX_TGT_NAME_SIZE]; /* iSCSI TargetAddress set after iscsi_sock_accept() */
targv_t *tv; /* array of target devices */
int address_family; /* IP address family */
} globals_t;
typedef struct target_session_t {
@ -85,6 +89,7 @@ typedef struct target_session_t {
iscsi_parameter_t *params;
iscsi_sess_param_t sess_params;
char initiator[MAX_INITIATOR_ADDRESS_SIZE];
int address_family;
} target_session_t;
typedef struct target_cmd_t {

3
dist/iscsi/src/TODO vendored
View File

@ -1,6 +1,6 @@
To do
=====
IPv6 awareness
add socklen_t awareness
cmdline fs or fsmmap
add ability to add a target in, take one out (if !busy)
@ -30,3 +30,4 @@ mmap & munmap
get port from cmd line
raid0
add discovery masking
clean up IPv6

View File

@ -1,4 +1,4 @@
.\" $NetBSD: iscsi-target.8,v 1.3 2006/03/04 21:56:11 agc Exp $
.\" $NetBSD: iscsi-target.8,v 1.4 2006/03/05 23:50:46 agc Exp $
.\"
.\" Copyright © 2006 Alistair Crooks. All rights reserved.
.\"
@ -36,6 +36,8 @@
.Nm
.Op Fl D
.Op Fl V
.Op Fl 4
.Op Fl 6
.Op Fl b Ar block length
.Op Fl f Ar configuration file
.Op Fl p Ar port number
@ -67,6 +69,15 @@ This can be useful for debugging purposes.
.Nm
will print the utility name and version number,
and the address for bug reports, and then exit.
.It Fl 4
.Nm
will listen for IPv4 connections,
and respond back using IPv4.
This is the default address family.
.It Fl 6
.Nm
will listen for IPv6 connections,
and respond back using IPv6.
.It Fl f Ar configfile
Use the named file as the configuration file.
The default file can be found in

View File

@ -1,4 +1,4 @@
/* $NetBSD: iscsi-target.c,v 1.5 2006/03/04 21:56:11 agc Exp $ */
/* $NetBSD: iscsi-target.c,v 1.6 2006/03/05 23:50:46 agc Exp $ */
/*
* Copyright © 2006 Alistair Crooks. All rights reserved.
@ -81,10 +81,11 @@ main(int argc, char **argv)
(void) strlcpy(TargetName, DEFAULT_TARGET_NAME, sizeof(TargetName));
detach_me_harder = 1;
g.port = ISCSI_PORT;
g.address_family = ISCSI_IPv4;
cf = _PATH_ISCSI_TARGETS;
while ((i = getopt(argc, argv, "DVb:f:p:t:v:")) != -1) {
while ((i = getopt(argc, argv, "DV46b:f:p:t:v:")) != -1) {
switch (i) {
case 'D':
detach_me_harder = 0;
@ -93,6 +94,12 @@ main(int argc, char **argv)
(void) printf("\"%s\" %s\nPlease send all bug reports to %s\n", PACKAGE_NAME, PACKAGE_VERSION, PACKAGE_BUGREPORT);
exit(EXIT_SUCCESS);
/* NOTREACHED */
case '4':
g.address_family = ISCSI_IPv4;
break;
case '6':
g.address_family = ISCSI_IPv6;
break;
case 'b':
device_set_var("blocklen", optarg);
break;

View File

@ -625,7 +625,8 @@ text_command_t(target_session_t * sess, uint8_t *header)
PARAM_TEXT_ADD(sess->params, "SendTargets", "Reject", text_out, &len_out, 2048, 0, TC_ERROR);
} else {
for (i = 0 ; i < sess->globals->tv->c ; i++) {
if (allow_netmask(sess->globals->tv->v[i].mask, sess->initiator)) {
if (sess->address_family == ISCSI_IPv6 ||
(sess->address_family == ISCSI_IPv4 && allow_netmask(sess->globals->tv->v[i].mask, sess->initiator))) {
(void) snprintf(buf, sizeof(buf), "%s:%s", sess->globals->targetname, sess->globals->tv->v[i].target);
PARAM_TEXT_ADD(sess->params, "TargetName", buf, text_out, &len_out, 2048, 0, TC_ERROR);
PARAM_TEXT_ADD(sess->params, "TargetAddress", sess->globals->targetaddress, text_out, &len_out, 2048, 0, TC_ERROR);
@ -1453,7 +1454,11 @@ target_init(globals_t *gp, targv_t *tv, char *TargetName)
gp->listener_pid = -1;
gp->state = TARGET_INITIALIZED;
PRINT("TARGET: TargetName is %s\n", gp->targetname);
PRINT("TARGET: TargetName is %s, via Address Family %s on port %d\n",
gp->targetname,
(gp->address_family == ISCSI_IPv4) ? "IPv4" :
(gp->address_family == ISCSI_IPv6) ? "IPv6" : "unknown",
gp->port);
return 0;
}
@ -1524,10 +1529,11 @@ target_listen(globals_t *gp)
target_session_t *sess;
int one = 1;
int localAddrLen;
struct sockaddr_in localAddr;
struct sockaddr_in localAddrStorage;
int remoteAddrLen;
struct sockaddr_in remoteAddr;
struct sockaddr_in remoteAddrStorage;
char local[1024];
char remote[1024];
ISCSI_THREAD_START("listen_thread");
gp->listener_pid = ISCSI_GETPID;
@ -1571,36 +1577,60 @@ target_listen(globals_t *gp)
sess->globals = gp;
sess->address_family = gp->address_family;
/* Accept connection, spawn session thread, and */
/* clean up old threads */
TRACE(TRACE_NET_DEBUG, "waiting for connection on port %i\n", gp->port);
TRACE(TRACE_NET_DEBUG, "waiting for IPv4 connection on port %d\n", gp->port);
if (iscsi_sock_accept(gp->sock, &sess->sock) < 0) {
TRACE(TRACE_ISCSI_DEBUG, "iscsi_sock_accept() failed\n");
goto done;
}
localAddrLen = sizeof(localAddr);
(void) memset(&localAddr, 0x0, sizeof(localAddr));
if (iscsi_sock_getsockname(sess->sock, (struct sockaddr *) (void *)& localAddr, &localAddrLen) < 0) {
localAddrLen = sizeof(localAddrStorage);
(void) memset(&localAddrStorage, 0x0, sizeof(localAddrStorage));
if (iscsi_sock_getsockname(sess->sock, (struct sockaddr *) (void *) &localAddrStorage, &localAddrLen) < 0) {
TRACE_ERROR("iscsi_sock_getsockname() failed\n");
goto done;
}
remoteAddrLen = sizeof(remoteAddr);
(void) memset(&remoteAddr, 0x0, sizeof(remoteAddr));
if (iscsi_sock_getpeername(sess->sock, (struct sockaddr *) (void *)& remoteAddr, &remoteAddrLen) < 0) {
remoteAddrLen = sizeof(remoteAddrStorage);
(void) memset(&remoteAddrStorage, 0x0, sizeof(remoteAddrStorage));
if (iscsi_sock_getpeername(sess->sock, (struct sockaddr *) (void *) &remoteAddrStorage, &remoteAddrLen) < 0) {
TRACE_ERROR("iscsi_sock_getsockname() failed\n");
goto done;
}
(void) strlcpy(local, inet_ntoa(localAddr.sin_addr), sizeof(local));
(void) strlcpy(sess->initiator, inet_ntoa(remoteAddr.sin_addr), sizeof(sess->initiator));
(void) snprintf(gp->targetaddress, sizeof(gp->targetaddress), "%s:%u,1", local, gp->port);
TRACE(TRACE_ISCSI_DEBUG, "connection accepted on port %i (local IP %s, remote IP %s)\n",
gp->port, local, sess->initiator);
TRACE(TRACE_ISCSI_DEBUG, "TargetAddress = \"%s\"\n", gp->targetaddress);
switch (sess->address_family = (remoteAddrStorage.sin_family = PF_INET6) ? ISCSI_IPv6 : ISCSI_IPv4) {
case ISCSI_IPv4:
(void) strlcpy(local, inet_ntoa(localAddrStorage.sin_addr), sizeof(local));
(void) strlcpy(sess->initiator, inet_ntoa(remoteAddrStorage.sin_addr), sizeof(sess->initiator));
(void) snprintf(gp->targetaddress, sizeof(gp->targetaddress), "%s:%u,1", local, gp->port);
TRACE(TRACE_ISCSI_DEBUG, "IPv4 connection accepted on port %d (local IP %s, remote IP %s)\n",
gp->port, local, sess->initiator);
TRACE(TRACE_ISCSI_DEBUG, "TargetAddress = \"%s\"\n", gp->targetaddress);
if (iscsi_thread_create(&sess->worker.thread, (void *) worker_proc_t, sess) != 0) {
TRACE_ERROR("iscsi_thread_create() failed\n");
goto done;
}
break;
case ISCSI_IPv6:
if (inet_ntop(localAddrStorage.sin_family, (void *)&localAddrStorage.sin_addr, local, sizeof(local)) == NULL) {
TRACE_ERROR("inet_ntop local failed\n");
}
if (inet_ntop(remoteAddrStorage.sin_family, (void *)&remoteAddrStorage.sin_addr, remote, sizeof(remote)) == NULL) {
TRACE_ERROR("inet_ntop remotefailed\n");
}
(void) strlcpy(sess->initiator, remote, sizeof(sess->initiator));
(void) snprintf(gp->targetaddress, sizeof(gp->targetaddress), "%s:%u,1", local, gp->port);
TRACE(TRACE_ISCSI_DEBUG, "IPv6 connection accepted on port %d (local IP %s, remote IP %s)\n",
gp->port, local, sess->initiator);
TRACE(TRACE_ISCSI_DEBUG, "TargetAddress = \"%s\"\n", gp->targetaddress);
break;
}
if (iscsi_thread_create(&sess->worker.thread, (void *) worker_proc_t, sess) != 0) {
TRACE_ERROR("iscsi_thread_create() failed\n");
goto done;