Signed-off-by: Alexander Nezhinsky <alexandern@xxxxxxxxxxxx> --- usr/Makefile | 2 +- usr/iscsi/iscsi_tcp.c | 4 ++ usr/iscsi/iscsid.c | 86 ++++++++++++++++++++----------------- usr/iscsi/iscsid.h | 74 ++++++++++++++++++------------- usr/iscsi/isns.c | 24 ++-------- usr/iscsi/session.c | 5 +-- usr/iscsi/target.c | 114 ++----------------------------------------------- usr/list.h | 3 + 8 files changed, 108 insertions(+), 204 deletions(-) diff --git a/usr/Makefile b/usr/Makefile index 262300d..e2a6e0b 100644 --- a/usr/Makefile +++ b/usr/Makefile @@ -19,7 +19,7 @@ TGTD_OBJS += bs_rdwr.o bs_aio.o ifneq ($(ISCSI_RDMA),) CFLAGS += -DISCSI_RDMA -TGTD_OBJS += iscsi/iscsi_rdma.o +TGTD_OBJS += iscsi/iser_ib.o iscsi/iser_text.o LIBS += -libverbs -lrdmacm endif endif diff --git a/usr/iscsi/iscsi_tcp.c b/usr/iscsi/iscsi_tcp.c index 8fc145f..e41e019 100644 --- a/usr/iscsi/iscsi_tcp.c +++ b/usr/iscsi/iscsi_tcp.c @@ -134,6 +134,10 @@ static void accept_connection(int afd, int events, void *data) tcp_conn->fd = fd; conn->tp = &iscsi_tcp; + conn->op.conn_show = iscsi_tcp.ep_show; + conn->op.conn_getsockname = iscsi_tcp.ep_getsockname; + conn->op.conn_getpeername = iscsi_tcp.ep_getpeername; + conn_read_pdu(conn); set_non_blocking(fd); diff --git a/usr/iscsi/iscsid.c b/usr/iscsi/iscsid.c index 3ca98ab..bb103e6 100644 --- a/usr/iscsi/iscsid.c +++ b/usr/iscsi/iscsid.c @@ -38,7 +38,6 @@ #include "util.h" #include "driver.h" #include "scsi.h" -#include "tgtadm.h" #include "crc32c.h" #define MAX_QUEUE_CMD 128 @@ -97,14 +96,17 @@ static struct iscsi_key login_keys[] = { {NULL, 0, 0, 0, NULL}, }; -char *text_key_find(struct iscsi_connection *conn, char *searchKey) +extern char *text_key_find(struct iscsi_connection *conn, char *searchKey) { - char *data, *key, *value; - int keylen, datasize; + return text_key_find_in_buf(conn->req.data, conn->req.datasize, searchKey); +} + +char *text_key_find_in_buf(char *data, unsigned int datasize, char *searchKey) +{ + char *key, *value; + int keylen; keylen = strlen(searchKey); - data = conn->req.data; - datasize = conn->req.datasize; while (1) { for (key = data; datasize > 0 && *data != '='; data++, datasize--) @@ -159,7 +161,6 @@ void text_key_add(struct iscsi_connection *conn, char *key, char *value) int keylen = strlen(key); int valuelen = strlen(value); int len = keylen + valuelen + 2; - char *buffer; int max_len; if (conn->state == STATE_FULL) @@ -170,13 +171,12 @@ void text_key_add(struct iscsi_connection *conn, char *key, char *value) if (!conn->rsp.datasize) conn->rsp.data = conn->rsp_buffer; - buffer = conn->rsp_buffer; - if (conn->rsp.datasize + len > max_len && (conn->req.bhs.opcode & ISCSI_OPCODE_MASK) != ISCSI_OP_TEXT) goto drop; if (conn->rsp.datasize + len > conn->rsp_buffer_size) { + char *buffer = conn->rsp_buffer; buffer = realloc(buffer, conn->rsp.datasize + len); if (buffer) { conn->rsp_buffer = buffer; @@ -186,17 +186,27 @@ void text_key_add(struct iscsi_connection *conn, char *key, char *value) goto drop; } - buffer += conn->rsp.datasize; - conn->rsp.datasize += len; + text_key_add_to_buf(conn->rsp_buffer, &conn->rsp.datasize, key, value); + return; + +drop: + log_warning("Dropping key (%s=%s)", key, value); + return; +} + +void text_key_add_to_buf(char *data, unsigned int *datalen, char *key, char *value) +{ + int keylen = strlen(key); + int valuelen = strlen(value); + int len = keylen + valuelen + 2; + char *buffer = data + *datalen; strcpy(buffer, key); buffer += keylen; *buffer++ = '='; strcpy(buffer, value); - return; -drop: - log_warning("Dropping key (%s=%s)", key, value); - return; + + *datalen += len; } static void text_key_add_reject(struct iscsi_connection *conn, char *key) @@ -468,9 +478,6 @@ static void login_start(struct iscsi_connection *conn) } } - if (conn->session_type == SESSION_DISCOVERY) - conn->tid = GLOBAL_TID; - if (conn->session_type == SESSION_NORMAL) { if (!target_name) { rsp->status_class = ISCSI_STATUS_CLS_INITIATOR_ERR; @@ -486,19 +493,15 @@ static void login_start(struct iscsi_connection *conn) conn->state = STATE_EXIT; return; } - - conn->tid = target->tid; - - if (target_redirected(target, conn)) { - char buf[NI_MAXHOST + NI_MAXSERV + 4]; - snprintf(buf, sizeof(buf), "%s:%s", target->redirect_info.addr, - target->redirect_info.port); - text_key_add(conn, "TargetAddress", buf); - rsp->status_class = ISCSI_STATUS_CLS_REDIRECT; - rsp->status_detail = target->redirect_info.reason; + if (target->rdma) { + eprintf("Target %s is RDMA, but conn cid:%d from %s is TCP\n", + target_name, conn->cid, conn->initiator); + rsp->status_class = ISCSI_STATUS_CLS_INITIATOR_ERR; + rsp->status_detail = ISCSI_LOGIN_STATUS_TGT_NOT_FOUND; conn->state = STATE_EXIT; return; } + conn->tid = target->tid; if (tgt_get_target_state(target->tid) != SCSI_TARGET_READY) { rsp->status_class = ISCSI_STATUS_CLS_TARGET_ERR; @@ -599,7 +602,9 @@ static int cmnd_exec_auth(struct iscsi_connection *conn) switch (conn->auth_method) { case AUTH_CHAP: - res = cmnd_exec_auth_chap(conn); + res = cmnd_exec_auth_chap(conn); + eprintf("CHAP currently unsupported\n"); + res = -3; break; case AUTH_NONE: res = 0; @@ -808,6 +813,7 @@ static void text_scan_text(struct iscsi_connection *conn) data = conn->req.data; datasize = conn->req.datasize; + dprintf("entry\n"); while ((key = next_key(&data, &datasize, &value))) { if (!strcmp(key, "SendTargets")) { struct sockaddr_storage ss; @@ -822,7 +828,8 @@ static void text_scan_text(struct iscsi_connection *conn) blen = sizeof(buf); slen = sizeof(ss); - ret = conn->tp->ep_getsockname(conn, + + ret = conn->op.conn_getsockname(conn, (struct sockaddr *)&ss, &slen); if (ret) { @@ -853,6 +860,7 @@ static void text_scan_text(struct iscsi_connection *conn) } else text_key_add(conn, key, "NotUnderstood"); } + dprintf("exit\n"); } static void cmnd_exec_text(struct iscsi_connection *conn) @@ -865,6 +873,8 @@ static void cmnd_exec_text(struct iscsi_connection *conn) rsp->opcode = ISCSI_OP_TEXT_RSP; rsp->itt = req->itt; + /* rsp->ttt = rsp->ttt; */ + rsp->ttt = 0xffffffff; conn->exp_cmd_sn = be32_to_cpu(req->cmdsn); if (!(req->opcode & ISCSI_OP_IMMEDIATE)) conn->exp_cmd_sn++; @@ -872,6 +882,7 @@ static void cmnd_exec_text(struct iscsi_connection *conn) if (be32_to_cpu(req->ttt) == ISCSI_RESERVED_TAG) { conn->text_datasize = 0; + dprintf("Text request: %d\n", conn->state); text_scan_text(conn); conn->text_rsp_buffer = conn->rsp_buffer; @@ -2259,7 +2270,7 @@ out: return ret; } -static int iscsi_transportid(int tid, uint64_t itn_id, char *buf, int size) +int iscsi_transportid(int tid, uint64_t itn_id, char *buf, int size) { struct iscsi_session *session; char *p; @@ -2333,14 +2344,11 @@ static int iscsi_param_parser(char *p) else len = strlen(addr); - if (iscsi_portal_addr) { - free(iscsi_portal_addr); - iscsi_portal_addr = NULL; - } - if (len) { - iscsi_portal_addr = zalloc(len + 1); - memcpy(iscsi_portal_addr, addr, len); - } + iscsi_portal_addr = zalloc(len + 1); + memcpy(iscsi_portal_addr, addr, len); + + eprintf("Listen port:%d Portal addr:%s\n", + iscsi_listen_port, iscsi_portal_addr); } p += strcspn(p, ","); diff --git a/usr/iscsi/iscsid.h b/usr/iscsi/iscsid.h index 35bb068..9a386e4 100644 --- a/usr/iscsi/iscsid.h +++ b/usr/iscsi/iscsid.h @@ -21,7 +21,6 @@ #include <stdint.h> #include <inttypes.h> -#include <netdb.h> #include "transport.h" #include "list.h" @@ -132,16 +131,31 @@ struct iscsi_task { unsigned long extdata[0]; }; +struct iscsi_conn_ops { + + int (*conn_show)(struct iscsi_connection *conn, char *buf, int rest); + int (*conn_getsockname)(struct iscsi_connection *conn, + struct sockaddr *sa, socklen_t *len); + int (*conn_getpeername)(struct iscsi_connection *conn, + struct sockaddr *sa, socklen_t *len); +}; + struct iscsi_connection { int state; - /* should be a new state */ int closed; - int rx_iostate; - int tx_iostate; int refcount; + struct iscsi_conn_ops op; + + uint32_t stat_sn; + uint32_t exp_stat_sn; + + uint32_t cmd_sn; + uint32_t exp_cmd_sn; + uint32_t max_cmd_sn; + struct list_head clist; struct iscsi_session *session; @@ -155,12 +169,19 @@ struct iscsi_connection { int session_type; int auth_method; - uint32_t stat_sn; - uint32_t exp_stat_sn; + int auth_state; + union { + struct { + int digest_alg; + int id; + int challenge_size; + unsigned char *challenge; + } chap; + } auth; - uint32_t cmd_sn; - uint32_t exp_cmd_sn; - uint32_t max_cmd_sn; + /* From here iscsi_tcp specific */ + int rx_iostate; + int tx_iostate; struct iscsi_pdu req; void *req_buffer; @@ -186,16 +207,6 @@ struct iscsi_connection { unsigned char rx_digest[4]; unsigned char tx_digest[4]; - int auth_state; - union { - struct { - int digest_alg; - int id; - int challenge_size; - unsigned char *challenge; - } chap; - } auth; - struct iscsi_transport *tp; }; @@ -212,6 +223,9 @@ struct iscsi_connection { #define STATE_CLOSE 10 #define STATE_EXIT 11 #define STATE_SCSI 12 +#define STATE_INIT 13 +#define STATE_START 14 +#define STATE_READY 15 #define AUTH_STATE_START 0 #define AUTH_STATE_CHALLENGE 1 @@ -244,13 +258,9 @@ struct iscsi_target { int max_nr_sessions; int nr_sessions; - struct redirect_info { - char addr[NI_MAXHOST + 1]; - char port[NI_MAXSERV + 1]; - uint8_t reason; - } redirect_info; - struct list_head isns_list; + + int rdma; }; enum task_flags { @@ -273,7 +283,7 @@ extern int lld_index; extern struct list_head iscsi_targets_list; /* chap.c */ -extern int cmnd_exec_auth_chap(struct iscsi_connection *conn); +extern int cmnd_exec_auth_chap(struct iscsi_connection *conn_h); /* conn.c */ extern int conn_init(struct iscsi_connection *conn); @@ -287,6 +297,8 @@ extern void conn_add_to_session(struct iscsi_connection *conn, struct iscsi_sess extern int conn_close_force(uint32_t tid, uint64_t sid, uint32_t cid); /* iscsid.c */ +extern char *text_key_find_in_buf(char *data,unsigned int datasize, char *searchKey); +extern void text_key_add_to_buf(char *data, unsigned int *datalen, char *key, char *value); extern char *text_key_find(struct iscsi_connection *conn, char *searchKey); extern void text_key_add(struct iscsi_connection *conn, char *key, char *value); extern void conn_read_pdu(struct iscsi_connection *conn); @@ -306,17 +318,17 @@ extern void session_get(struct iscsi_session *session); extern void session_put(struct iscsi_session *session); /* target.c */ -struct iscsi_target * target_find_by_name(const char *name); -struct iscsi_target * target_find_by_id(int tid); +extern struct iscsi_target * target_find_by_name(const char *name); +extern struct iscsi_target * target_find_by_id(int tid); extern void target_list_build(struct iscsi_connection *, char *, char *); extern int ip_acl(int tid, struct iscsi_connection *conn); extern int iscsi_target_create(struct target *); extern void iscsi_target_destroy(int); extern int iscsi_target_show(int mode, int tid, uint64_t sid, uint32_t cid, uint64_t lun, char *buf, int rest); -int iscsi_target_update(int mode, int op, int tid, uint64_t sid, uint64_t lun, - uint32_t cid, char *name); -int target_redirected(struct iscsi_target *target, struct iscsi_connection *conn); +extern int iscsi_target_update(int mode, int op, int tid, uint64_t sid, uint64_t lun, + uint32_t cid, char *name); +extern int iscsi_transportid(int tid, uint64_t itn_id, char *buf, int size); /* param.c */ int param_index_by_name(char *name, struct iscsi_key *keys); diff --git a/usr/iscsi/isns.c b/usr/iscsi/isns.c index cdc2ece..3bfc1fc 100644 --- a/usr/iscsi/isns.c +++ b/usr/iscsi/isns.c @@ -316,7 +316,7 @@ static int isns_attr_query(char *name) tlv = (struct isns_tlv *) hdr->pdu; if (name) - snprintf(mgmt->name, sizeof(mgmt->name), "%s", name); + snprintf(mgmt->name, sizeof(mgmt->name), name); else { mgmt->name[0] = '\0'; target = list_first_entry(&iscsi_targets_list, @@ -460,7 +460,6 @@ static void free_all_acl(struct iscsi_target *target) while (!list_empty(&target->isns_list)) { ini = list_first_entry(&target->isns_list, typeof(*ini), ilist); list_del(&ini->ilist); - free(ini); } } @@ -605,23 +604,17 @@ static char *print_scn_pdu(struct isns_hdr *hdr) struct isns_tlv *tlv = (struct isns_tlv *) hdr->pdu; uint16_t function, length, flags, transaction, sequence; char *name = NULL; - static char iscsi_name[224]; get_hdr_param(hdr, function, length, flags, transaction, sequence); while (length) { uint32_t vlen = ntohl(tlv->length); - if (vlen + sizeof(*tlv) > length) - vlen = length - sizeof(*tlv); - switch (ntohl(tlv->tag)) { case ISNS_ATTR_ISCSI_NAME: eprintf("scn name: %u, %s\n", vlen, (char *) tlv->value); - if (!name) { - snprintf(iscsi_name, sizeof(iscsi_name), (char *)tlv->value); - name = iscsi_name; - } + if (!name) + name = (char *) tlv->value; break; case ISNS_ATTR_TIMESTAMP: /* log_error("%u : %u : %" PRIx64, ntohl(tlv->tag), vlen, */ @@ -682,17 +675,11 @@ found: /* skip status */ tlv = (struct isns_tlv *) ((char *) hdr->pdu + 4); - - if (length < 4) - goto free_qry_mgmt; length -= 4; while (length) { uint32_t vlen = ntohl(tlv->length); - if (vlen + sizeof(*tlv) > length) - vlen = length - sizeof(*tlv); - switch (ntohl(tlv->tag)) { case ISNS_ATTR_ISCSI_NAME: name = (char *) tlv->value; @@ -703,7 +690,7 @@ found: ini = malloc(sizeof(*ini)); if (!ini) goto free_qry_mgmt; - snprintf(ini->name, sizeof(ini->name), "%s", name); + snprintf(ini->name, sizeof(ini->name), name); list_add(&ini->ilist, &target->isns_list); } else name = NULL; @@ -925,7 +912,7 @@ int isns_init(void) eprintf("getaddrinfo error %s\n", isns_addr); return -1; } - memcpy(&ss, res->ai_addr, sizeof(*res->ai_addr)); + memcpy(&ss, res->ai_addr, sizeof(ss)); freeaddrinfo(res); rxbuf = calloc(2, BUFSIZE); @@ -1040,7 +1027,6 @@ int isns_update(char *params) case Opt_port: if (match_int(&args[0], &isns_port)) ret = TGTADM_INVALID_REQUEST; - break; case Opt_ac: match_strncpy(tmp, &args[0], sizeof(tmp)); use_isns_ac = !strcmp(tmp, "On"); diff --git a/usr/iscsi/session.c b/usr/iscsi/session.c index 46864c7..e377c6e 100644 --- a/usr/iscsi/session.c +++ b/usr/iscsi/session.c @@ -70,7 +70,6 @@ int session_create(struct iscsi_connection *conn) struct iscsi_target *target; char addr[128]; - target = target_find_by_id(conn->tid); if (!target) return -EINVAL; @@ -103,7 +102,7 @@ int session_create(struct iscsi_connection *conn) } memset(addr, 0, sizeof(addr)); - conn->tp->ep_show(conn, addr, sizeof(addr)); + conn->op.conn_show(conn, addr, sizeof(addr)); snprintf(session->info, 1024, _TAB3 "Initiator: %s\n" _TAB3 "Connection: %u\n" @@ -128,8 +127,6 @@ int session_create(struct iscsi_connection *conn) memcpy(session->isid, conn->isid, sizeof(session->isid)); session->tsih = last_tsih = tsih; - session->rdma = conn->tp->rdma; - conn_add_to_session(conn, session); dprintf("session_create: %#" PRIx64 "\n", sid64(conn->isid, session->tsih)); diff --git a/usr/iscsi/target.c b/usr/iscsi/target.c index f3b1edd..841c912 100644 --- a/usr/iscsi/target.c +++ b/usr/iscsi/target.c @@ -123,7 +123,7 @@ static int ip_match(struct iscsi_connection *conn, char *address) int err; len = sizeof(from); - err = conn->tp->ep_getpeername(conn, (struct sockaddr *) &from, &len); + err = conn->op.conn_getpeername(conn, (struct sockaddr *) &from, &len); if (err < 0) return -EPERM; @@ -189,57 +189,6 @@ int ip_acl(int tid, struct iscsi_connection *conn) return -EPERM; } -int target_redirected(struct iscsi_target *target, struct iscsi_connection *conn) -{ - struct sockaddr_storage from; - struct addrinfo hints, *res; - socklen_t len; - int ret; - char *p, *q, *str; - - if (!strlen(target->redirect_info.addr)) - return 0; - - if (target->redirect_info.reason != ISCSI_LOGIN_STATUS_TGT_MOVED_TEMP && - target->redirect_info.reason != ISCSI_LOGIN_STATUS_TGT_MOVED_PERM) - return 0; - - len = sizeof(from); - ret = conn->tp->ep_getpeername(conn, (struct sockaddr *)&from, &len); - if (ret < 0) - return 0; - - p = strdup(target->redirect_info.addr); - if (!p) - return 0; - str = p; - - if (*p == '[') { - p++; - if (!(q = strchr(p, ']'))) { - free(str); - return 0; - } - *(q++) = '\0'; - } - - memset(&hints, 0, sizeof(hints)); - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = AI_NUMERICHOST; - - ret = getaddrinfo(p, NULL, &hints, &res); - if (ret < 0) { - free(str); - return 0; - } - - ret = address_match(res->ai_addr, (struct sockaddr *)&from); - freeaddrinfo(res); - free(str); - - return !ret; -} - void target_list_build(struct iscsi_connection *conn, char *addr, char *name) { struct iscsi_target *target; @@ -256,6 +205,8 @@ void target_list_build(struct iscsi_connection *conn, char *addr, char *name) text_key_add(conn, "TargetName", tgt_targetname(target->tid)); text_key_add(conn, "TargetAddress", addr); + dprintf("added TargetName:%s TargetAddress:%s rdma:%d\n", + tgt_targetname(target->tid), addr, target->rdma); } } @@ -398,29 +349,6 @@ int iscsi_target_update(int mode, int op, int tid, uint64_t sid, uint64_t lun, dprintf("%s:%s\n", name, str); - if (!strncmp(name, "RedirectAddress", 15)) { - snprintf(target->redirect_info.addr, - sizeof(target->redirect_info.addr), "%s", str); - err = TGTADM_SUCCESS; - break; - } else if (!strncmp(name, "RedirectPort", 12)) { - snprintf(target->redirect_info.port, - sizeof(target->redirect_info.port), "%s", str); - err = TGTADM_SUCCESS; - break; - } else if (!strncmp(name, "RedirectReason", 14)) { - if (!strncmp(str, "Temporary", 9)) { - target->redirect_info.reason = - ISCSI_LOGIN_STATUS_TGT_MOVED_TEMP; - err = TGTADM_SUCCESS; - } else if (!strncmp(str, "Permanent", 9)) { - target->redirect_info.reason = - ISCSI_LOGIN_STATUS_TGT_MOVED_PERM; - err = TGTADM_SUCCESS; - } else - break; - } - idx = param_index_by_name(name, session_keys); if (idx >= 0) { err = iscsi_session_param_update(target, idx, str); @@ -468,37 +396,6 @@ static int iscsi_target_show_session(struct iscsi_target* target, uint64_t sid, return total; } -#define __buffer_check(buf, total, len, rest) \ -({ \ - buf += len; \ - total += len; \ - rest -= len; \ - if (!rest) \ - return total; \ -}) - -static int show_redirect_info(struct iscsi_target* target, char *buf, int rest) -{ - int len, total = 0; - - len = snprintf(buf, rest, "RedirectAddress=%s\n", target->redirect_info.addr); - __buffer_check(buf, total, len, rest); - len = snprintf(buf, rest, "RedirectPort=%s\n", target->redirect_info.port); - __buffer_check(buf, total, len, rest); - if (target->redirect_info.reason == ISCSI_LOGIN_STATUS_TGT_MOVED_TEMP) { - len = snprintf(buf, rest, "RedirectReason=Temporary\n"); - __buffer_check(buf, total, len, rest); - } else if (target->redirect_info.reason == ISCSI_LOGIN_STATUS_TGT_MOVED_PERM) { - len = snprintf(buf, rest, "RedirectReason=Permanent\n"); - __buffer_check(buf, total, len, rest); - } else { - len = snprintf(buf, rest, "RedirectReason=Unknown\n"); - __buffer_check(buf, total, len, rest); - } - - return total; -} - int iscsi_target_show(int mode, int tid, uint64_t sid, uint32_t cid, uint64_t lun, char *buf, int rest) { @@ -516,10 +413,7 @@ int iscsi_target_show(int mode, int tid, uint64_t sid, uint32_t cid, uint64_t lu total = isns_show(buf, rest); break; case MODE_TARGET: - if (strlen(target->redirect_info.addr)) - len = show_redirect_info(target, buf, rest); - else - len = show_iscsi_param(buf, target->session_param, rest); + len = show_iscsi_param(buf, target->session_param, rest); total += len; break; case MODE_SESSION: diff --git a/usr/list.h b/usr/list.h index f66ff36..2f80a56 100644 --- a/usr/list.h +++ b/usr/list.h @@ -43,6 +43,9 @@ static inline int list_empty(const struct list_head *head) #define list_for_each(pos, head) \ for (pos = (head)->next; pos != (head); pos = pos->next) +#define list_for_each_prev(pos, head) \ + for (pos = (head)->prev; pos != (head); pos = pos->prev) + #define list_for_each_entry(pos, head, member) \ for (pos = list_entry((head)->next, typeof(*pos), member); \ &pos->member != (head); \ -- 1.6.5 -- To unsubscribe from this list: send the line "unsubscribe stgt" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html