|
Packit |
eace71 |
/*
|
|
Packit |
eace71 |
* Common code for setting up discovery and normal sessions.
|
|
Packit |
eace71 |
*
|
|
Packit |
eace71 |
* Copyright (C) 2004 Dmitry Yusupov, Alex Aizman
|
|
Packit |
eace71 |
* Copyright (C) 2006 - 2009 Mike Christie
|
|
Packit |
eace71 |
* Copyright (C) 2006 - 2009 Red Hat, Inc. All rights reserved.
|
|
Packit |
eace71 |
* maintained by open-iscsi@googlegroups.com
|
|
Packit |
eace71 |
*
|
|
Packit |
eace71 |
* This program is free software; you can redistribute it and/or modify
|
|
Packit |
eace71 |
* it under the terms of the GNU General Public License as published
|
|
Packit |
eace71 |
* by the Free Software Foundation; either version 2 of the License, or
|
|
Packit |
eace71 |
* (at your option) any later version.
|
|
Packit |
eace71 |
*
|
|
Packit |
eace71 |
* This program is distributed in the hope that it will be useful, but
|
|
Packit |
eace71 |
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
eace71 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
eace71 |
* General Public License for more details.
|
|
Packit |
eace71 |
*
|
|
Packit |
eace71 |
* See the file COPYING included with this distribution for more details.
|
|
Packit |
eace71 |
*/
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
#include <string.h>
|
|
Packit |
eace71 |
#include <stdio.h>
|
|
Packit |
eace71 |
#include <stdlib.h>
|
|
Packit |
eace71 |
#include <errno.h>
|
|
Packit |
eace71 |
#include <dirent.h>
|
|
Packit |
eace71 |
#include <libmount/libmount.h>
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
#include "initiator.h"
|
|
Packit |
eace71 |
#include "transport.h"
|
|
Packit |
eace71 |
#include "iscsid.h"
|
|
Packit |
eace71 |
#include "iscsi_ipc.h"
|
|
Packit |
eace71 |
#include "log.h"
|
|
Packit |
eace71 |
#include "iscsi_sysfs.h"
|
|
Packit |
eace71 |
#include "iscsi_settings.h"
|
|
Packit |
eace71 |
#include "iface.h"
|
|
Packit |
eace71 |
#include "host.h"
|
|
Packit |
eace71 |
#include "sysdeps.h"
|
|
Packit |
eace71 |
#include "iscsi_err.h"
|
|
Packit |
eace71 |
#include "iscsi_net_util.h"
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
struct iscsi_session *session_find_by_sid(uint32_t sid)
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
struct iscsi_transport *t;
|
|
Packit |
eace71 |
struct iscsi_session *session;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
list_for_each_entry(t, &transports, list) {
|
|
Packit |
eace71 |
list_for_each_entry(session, &t->sessions, list) {
|
|
Packit |
eace71 |
if (session->id == sid)
|
|
Packit |
eace71 |
return session;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
return NULL;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
const static unsigned int align_32_down(unsigned int param)
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
return param & ~0x3;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
int iscsi_setup_authentication(struct iscsi_session *session,
|
|
Packit |
eace71 |
struct iscsi_auth_config *auth_cfg)
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
/* if we have any incoming credentials, we insist on authenticating
|
|
Packit |
eace71 |
* the target or not logging in at all
|
|
Packit |
eace71 |
*/
|
|
Packit |
eace71 |
if (auth_cfg->username_in[0] || auth_cfg->password_in_length) {
|
|
Packit |
eace71 |
/* sanity check the config */
|
|
Packit |
eace71 |
if (auth_cfg->password_length == 0) {
|
|
Packit |
eace71 |
log_warning("CHAP configuration has incoming "
|
|
Packit |
eace71 |
"authentication credentials but has no "
|
|
Packit |
eace71 |
"outgoing credentials configured.");
|
|
Packit |
eace71 |
return EINVAL;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
session->bidirectional_auth = 1;
|
|
Packit |
eace71 |
} else {
|
|
Packit |
eace71 |
/* no or 1-way authentication */
|
|
Packit |
eace71 |
session->bidirectional_auth = 0;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
/* copy in whatever credentials we have */
|
|
Packit |
eace71 |
strlcpy(session->username, auth_cfg->username,
|
|
Packit |
eace71 |
sizeof (session->username));
|
|
Packit |
eace71 |
session->username[sizeof (session->username) - 1] = '\0';
|
|
Packit |
eace71 |
if ((session->password_length = auth_cfg->password_length))
|
|
Packit |
eace71 |
memcpy(session->password, auth_cfg->password,
|
|
Packit |
eace71 |
session->password_length);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
strlcpy(session->username_in, auth_cfg->username_in,
|
|
Packit |
eace71 |
sizeof (session->username_in));
|
|
Packit |
eace71 |
session->username_in[sizeof (session->username_in) - 1] = '\0';
|
|
Packit |
eace71 |
if ((session->password_in_length =
|
|
Packit |
eace71 |
auth_cfg->password_in_length))
|
|
Packit |
eace71 |
memcpy(session->password_in, auth_cfg->password_in,
|
|
Packit |
eace71 |
session->password_in_length);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (session->password_length || session->password_in_length) {
|
|
Packit |
eace71 |
/* setup the auth buffers */
|
|
Packit |
eace71 |
session->auth_buffers[0].address = &session->auth_client_block;
|
|
Packit |
eace71 |
session->auth_buffers[0].length =
|
|
Packit |
eace71 |
sizeof (session->auth_client_block);
|
|
Packit |
eace71 |
session->auth_buffers[1].address =
|
|
Packit |
eace71 |
&session->auth_recv_string_block;
|
|
Packit |
eace71 |
session->auth_buffers[1].length =
|
|
Packit |
eace71 |
sizeof (session->auth_recv_string_block);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
session->auth_buffers[2].address =
|
|
Packit |
eace71 |
&session->auth_send_string_block;
|
|
Packit |
eace71 |
session->auth_buffers[2].length =
|
|
Packit |
eace71 |
sizeof (session->auth_send_string_block);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
session->auth_buffers[3].address =
|
|
Packit |
eace71 |
&session->auth_recv_binary_block;
|
|
Packit |
eace71 |
session->auth_buffers[3].length =
|
|
Packit |
eace71 |
sizeof (session->auth_recv_binary_block);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
session->auth_buffers[4].address =
|
|
Packit |
eace71 |
&session->auth_send_binary_block;
|
|
Packit |
eace71 |
session->auth_buffers[4].length =
|
|
Packit |
eace71 |
sizeof (session->auth_send_binary_block);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
session->num_auth_buffers = 5;
|
|
Packit |
eace71 |
log_debug(6, "authentication setup complete...");
|
|
Packit |
eace71 |
} else {
|
|
Packit |
eace71 |
session->num_auth_buffers = 0;
|
|
Packit |
eace71 |
log_debug(6, "no authentication configured...");
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
return 0;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
void
|
|
Packit |
eace71 |
iscsi_copy_operational_params(struct iscsi_conn *conn,
|
|
Packit |
eace71 |
struct iscsi_session_operational_config *session_conf,
|
|
Packit |
eace71 |
struct iscsi_conn_operational_config *conn_conf)
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
struct iscsi_session *session = conn->session;
|
|
Packit |
eace71 |
struct iscsi_transport *t = session->t;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
conn->hdrdgst_en = conn_conf->HeaderDigest;
|
|
Packit |
eace71 |
conn->datadgst_en = conn_conf->DataDigest;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
conn->max_recv_dlength =
|
|
Packit |
eace71 |
align_32_down(conn_conf->MaxRecvDataSegmentLength);
|
|
Packit |
eace71 |
if (conn->max_recv_dlength < ISCSI_MIN_MAX_RECV_SEG_LEN ||
|
|
Packit |
eace71 |
conn->max_recv_dlength > ISCSI_MAX_MAX_RECV_SEG_LEN) {
|
|
Packit |
eace71 |
log_error("Invalid iscsi.MaxRecvDataSegmentLength. Must be "
|
|
Packit |
eace71 |
"within %u and %u. Setting to %u",
|
|
Packit |
eace71 |
ISCSI_MIN_MAX_RECV_SEG_LEN,
|
|
Packit |
eace71 |
ISCSI_MAX_MAX_RECV_SEG_LEN,
|
|
Packit |
eace71 |
DEF_INI_MAX_RECV_SEG_LEN);
|
|
Packit |
eace71 |
conn_conf->MaxRecvDataSegmentLength =
|
|
Packit |
eace71 |
DEF_INI_MAX_RECV_SEG_LEN;
|
|
Packit |
eace71 |
conn->max_recv_dlength = DEF_INI_MAX_RECV_SEG_LEN;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
/* zero indicates to use the target's value */
|
|
Packit |
eace71 |
conn->max_xmit_dlength =
|
|
Packit |
eace71 |
align_32_down(conn_conf->MaxXmitDataSegmentLength);
|
|
Packit |
eace71 |
if (conn->max_xmit_dlength == 0)
|
|
Packit |
eace71 |
conn->max_xmit_dlength = ISCSI_DEF_MAX_RECV_SEG_LEN;
|
|
Packit |
eace71 |
if (conn->max_xmit_dlength < ISCSI_MIN_MAX_RECV_SEG_LEN ||
|
|
Packit |
eace71 |
conn->max_xmit_dlength > ISCSI_MAX_MAX_RECV_SEG_LEN) {
|
|
Packit |
eace71 |
log_error("Invalid iscsi.MaxXmitDataSegmentLength. Must be "
|
|
Packit |
eace71 |
"within %u and %u. Setting to %u",
|
|
Packit |
eace71 |
ISCSI_MIN_MAX_RECV_SEG_LEN,
|
|
Packit |
eace71 |
ISCSI_MAX_MAX_RECV_SEG_LEN,
|
|
Packit |
eace71 |
DEF_INI_MAX_RECV_SEG_LEN);
|
|
Packit |
eace71 |
conn_conf->MaxXmitDataSegmentLength =
|
|
Packit |
eace71 |
DEF_INI_MAX_RECV_SEG_LEN;
|
|
Packit |
eace71 |
conn->max_xmit_dlength = DEF_INI_MAX_RECV_SEG_LEN;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
/* session's operational parameters */
|
|
Packit |
eace71 |
session->initial_r2t_en = session_conf->InitialR2T;
|
|
Packit |
eace71 |
session->max_r2t = session_conf->MaxOutstandingR2T;
|
|
Packit |
eace71 |
session->imm_data_en = session_conf->ImmediateData;
|
|
Packit |
eace71 |
session->first_burst = align_32_down(session_conf->FirstBurstLength);
|
|
Packit |
eace71 |
/*
|
|
Packit |
eace71 |
* some targets like netapp fail the login if sent bad first_burst
|
|
Packit |
eace71 |
* and max_burst lens, even when immediate data=no and
|
|
Packit |
eace71 |
* initial r2t = Yes, so we always check the user values.
|
|
Packit |
eace71 |
*/
|
|
Packit |
eace71 |
if (session->first_burst < ISCSI_MIN_FIRST_BURST_LEN ||
|
|
Packit |
eace71 |
session->first_burst > ISCSI_MAX_FIRST_BURST_LEN) {
|
|
Packit |
eace71 |
log_error("Invalid iscsi.FirstBurstLength of %u. Must be "
|
|
Packit |
eace71 |
"within %u and %u. Setting to %u",
|
|
Packit |
eace71 |
session->first_burst,
|
|
Packit |
eace71 |
ISCSI_MIN_FIRST_BURST_LEN,
|
|
Packit |
eace71 |
ISCSI_MAX_FIRST_BURST_LEN,
|
|
Packit |
eace71 |
DEF_INI_FIRST_BURST_LEN);
|
|
Packit |
eace71 |
session_conf->FirstBurstLength = DEF_INI_FIRST_BURST_LEN;
|
|
Packit |
eace71 |
session->first_burst = DEF_INI_FIRST_BURST_LEN;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
session->max_burst = align_32_down(session_conf->MaxBurstLength);
|
|
Packit |
eace71 |
if (session->max_burst < ISCSI_MIN_MAX_BURST_LEN ||
|
|
Packit |
eace71 |
session->max_burst > ISCSI_MAX_MAX_BURST_LEN) {
|
|
Packit |
eace71 |
log_error("Invalid iscsi.MaxBurstLength of %u. Must be "
|
|
Packit |
eace71 |
"within %u and %u. Setting to %u",
|
|
Packit |
eace71 |
session->max_burst, ISCSI_MIN_MAX_BURST_LEN,
|
|
Packit |
eace71 |
ISCSI_MAX_MAX_BURST_LEN, DEF_INI_MAX_BURST_LEN);
|
|
Packit |
eace71 |
session_conf->MaxBurstLength = DEF_INI_MAX_BURST_LEN;
|
|
Packit |
eace71 |
session->max_burst = DEF_INI_MAX_BURST_LEN;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (session->first_burst > session->max_burst) {
|
|
Packit |
eace71 |
log_error("Invalid iscsi.FirstBurstLength of %u. Must be "
|
|
Packit |
eace71 |
"less than iscsi.MaxBurstLength. Setting to %u",
|
|
Packit |
eace71 |
session->first_burst, session->max_burst);
|
|
Packit |
eace71 |
session_conf->FirstBurstLength = session->max_burst;
|
|
Packit |
eace71 |
session->first_burst = session->max_burst;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
session->def_time2wait = session_conf->DefaultTime2Wait;
|
|
Packit |
eace71 |
session->def_time2retain = session_conf->DefaultTime2Retain;
|
|
Packit |
eace71 |
session->erl = session_conf->ERL;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (session->type == ISCSI_SESSION_TYPE_DISCOVERY) {
|
|
Packit |
eace71 |
/*
|
|
Packit |
eace71 |
* Right now, we only support 8K max for kernel based
|
|
Packit |
eace71 |
* sendtargets discovery, because the recv pdu buffers are
|
|
Packit |
eace71 |
* limited to this size.
|
|
Packit |
eace71 |
*/
|
|
Packit |
eace71 |
if ((t->caps & CAP_TEXT_NEGO) &&
|
|
Packit |
eace71 |
conn->max_recv_dlength > ISCSI_DEF_MAX_RECV_SEG_LEN)
|
|
Packit |
eace71 |
conn->max_recv_dlength = ISCSI_DEF_MAX_RECV_SEG_LEN;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
/* We do not support discovery sessions with digests */
|
|
Packit |
eace71 |
conn->hdrdgst_en = ISCSI_DIGEST_NONE;
|
|
Packit |
eace71 |
conn->datadgst_en = ISCSI_DIGEST_NONE;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (t->template->create_conn)
|
|
Packit |
eace71 |
t->template->create_conn(conn);
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
int iscsi_setup_portal(struct iscsi_conn *conn, char *address, int port)
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
char serv[NI_MAXSERV];
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
sprintf(serv, "%d", port);
|
|
Packit |
eace71 |
if (resolve_address(address, serv, &conn->saddr)) {
|
|
Packit |
eace71 |
log_error("cannot resolve host name %s", address);
|
|
Packit |
eace71 |
return ISCSI_ERR_TRANS;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
conn->failback_saddr = conn->saddr;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
getnameinfo((struct sockaddr *)&conn->saddr, sizeof(conn->saddr),
|
|
Packit |
eace71 |
conn->host, sizeof(conn->host), NULL, 0, NI_NUMERICHOST);
|
|
Packit |
eace71 |
log_debug(4, "resolved %s to %s", address, conn->host);
|
|
Packit |
eace71 |
return 0;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
static int host_set_param(struct iscsi_transport *t,
|
|
Packit |
eace71 |
uint32_t host_no, int param, char *value,
|
|
Packit |
eace71 |
int type)
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
int rc;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
rc = ipc->set_host_param(t->handle, host_no, param, value, type);
|
|
Packit |
eace71 |
/* 2.6.20 and below returns EINVAL */
|
|
Packit |
eace71 |
if (rc && rc != -ENOSYS && rc != -EINVAL) {
|
|
Packit |
eace71 |
log_error("can't set operational parameter %d for "
|
|
Packit |
eace71 |
"host %d, retcode %d (%d)", param, host_no,
|
|
Packit |
eace71 |
rc, errno);
|
|
Packit |
eace71 |
return ISCSI_ERR_INVAL;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
return 0;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
static void print_param_value(enum iscsi_param param, void *value, int type)
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
log_debug(3, "set operational parameter %d to:", param);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (type == ISCSI_STRING)
|
|
Packit |
eace71 |
log_debug(3, "%s", value ? (char *)value : "NULL");
|
|
Packit |
eace71 |
else
|
|
Packit |
eace71 |
log_debug(3, "%u", *(uint32_t *)value);
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
#define MAX_HOST_PARAMS 2
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
int iscsi_host_set_params(struct iscsi_session *session)
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
struct iscsi_transport *t = session->t;
|
|
Packit |
eace71 |
int i;
|
|
Packit |
eace71 |
struct hostparam {
|
|
Packit |
eace71 |
int param;
|
|
Packit |
eace71 |
int type;
|
|
Packit |
eace71 |
void *value;
|
|
Packit |
eace71 |
} hosttbl[MAX_HOST_PARAMS] = {
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
.param = ISCSI_HOST_PARAM_NETDEV_NAME,
|
|
Packit |
eace71 |
.value = session->nrec.iface.netdev,
|
|
Packit |
eace71 |
.type = ISCSI_STRING,
|
|
Packit |
eace71 |
}, {
|
|
Packit |
eace71 |
.param = ISCSI_HOST_PARAM_HWADDRESS,
|
|
Packit |
eace71 |
.value = session->nrec.iface.hwaddress,
|
|
Packit |
eace71 |
.type = ISCSI_STRING,
|
|
Packit |
eace71 |
},
|
|
Packit |
eace71 |
};
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
for (i = 0; i < MAX_HOST_PARAMS; i++) {
|
|
Packit |
eace71 |
if (host_set_param(t, session->hostno,
|
|
Packit |
eace71 |
hosttbl[i].param, hosttbl[i].value,
|
|
Packit |
eace71 |
hosttbl[i].type)) {
|
|
Packit |
eace71 |
return EPERM;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
print_param_value(hosttbl[i].param, hosttbl[i].value,
|
|
Packit |
eace71 |
hosttbl[i].type);
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
return 0;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
static inline void iscsi_session_clear_param(struct iscsi_session *session,
|
|
Packit |
eace71 |
int param)
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
session->param_mask &= ~(1ULL << param);
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
void iscsi_session_init_params(struct iscsi_session *session)
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
session->param_mask = ~0ULL;
|
|
Packit |
eace71 |
if (!(session->t->caps & CAP_MULTI_R2T))
|
|
Packit |
eace71 |
iscsi_session_clear_param(session, ISCSI_PARAM_MAX_R2T);
|
|
Packit |
eace71 |
if (!(session->t->caps & CAP_HDRDGST))
|
|
Packit |
eace71 |
iscsi_session_clear_param(session, ISCSI_PARAM_HDRDGST_EN);
|
|
Packit |
eace71 |
if (!(session->t->caps & CAP_DATADGST))
|
|
Packit |
eace71 |
iscsi_session_clear_param(session, ISCSI_PARAM_DATADGST_EN);
|
|
Packit |
eace71 |
if (!(session->t->caps & CAP_MARKERS)) {
|
|
Packit |
eace71 |
iscsi_session_clear_param(session, ISCSI_PARAM_IFMARKER_EN);
|
|
Packit |
eace71 |
iscsi_session_clear_param(session, ISCSI_PARAM_OFMARKER_EN);
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
#define MAX_SESSION_NEG_PARAMS 16
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
int iscsi_session_set_neg_params(struct iscsi_conn *conn)
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
struct iscsi_session *session = conn->session;
|
|
Packit |
eace71 |
int i, rc;
|
|
Packit |
eace71 |
uint32_t zero = 0;
|
|
Packit |
eace71 |
struct connparam {
|
|
Packit |
eace71 |
int param;
|
|
Packit |
eace71 |
int type;
|
|
Packit |
eace71 |
void *value;
|
|
Packit |
eace71 |
int conn_only;
|
|
Packit |
eace71 |
} conntbl[MAX_SESSION_NEG_PARAMS] = {
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
.param = ISCSI_PARAM_MAX_RECV_DLENGTH,
|
|
Packit |
eace71 |
.value = &conn->max_recv_dlength,
|
|
Packit |
eace71 |
.type = ISCSI_INT,
|
|
Packit |
eace71 |
.conn_only = 0,
|
|
Packit |
eace71 |
}, {
|
|
Packit |
eace71 |
.param = ISCSI_PARAM_MAX_XMIT_DLENGTH,
|
|
Packit |
eace71 |
.value = &conn->max_xmit_dlength,
|
|
Packit |
eace71 |
.type = ISCSI_INT,
|
|
Packit |
eace71 |
.conn_only = 0,
|
|
Packit |
eace71 |
}, {
|
|
Packit |
eace71 |
.param = ISCSI_PARAM_HDRDGST_EN,
|
|
Packit |
eace71 |
.value = &conn->hdrdgst_en,
|
|
Packit |
eace71 |
.type = ISCSI_INT,
|
|
Packit |
eace71 |
.conn_only = 0,
|
|
Packit |
eace71 |
}, {
|
|
Packit |
eace71 |
.param = ISCSI_PARAM_DATADGST_EN,
|
|
Packit |
eace71 |
.value = &conn->datadgst_en,
|
|
Packit |
eace71 |
.type = ISCSI_INT,
|
|
Packit |
eace71 |
.conn_only = 1,
|
|
Packit |
eace71 |
}, {
|
|
Packit |
eace71 |
.param = ISCSI_PARAM_INITIAL_R2T_EN,
|
|
Packit |
eace71 |
.value = &session->initial_r2t_en,
|
|
Packit |
eace71 |
.type = ISCSI_INT,
|
|
Packit |
eace71 |
.conn_only = 0,
|
|
Packit |
eace71 |
}, {
|
|
Packit |
eace71 |
.param = ISCSI_PARAM_MAX_R2T,
|
|
Packit |
eace71 |
.value = &session->max_r2t,
|
|
Packit |
eace71 |
.type = ISCSI_INT,
|
|
Packit |
eace71 |
.conn_only = 0,
|
|
Packit |
eace71 |
}, {
|
|
Packit |
eace71 |
.param = ISCSI_PARAM_IMM_DATA_EN,
|
|
Packit |
eace71 |
.value = &session->imm_data_en,
|
|
Packit |
eace71 |
.type = ISCSI_INT,
|
|
Packit |
eace71 |
.conn_only = 0,
|
|
Packit |
eace71 |
}, {
|
|
Packit |
eace71 |
.param = ISCSI_PARAM_FIRST_BURST,
|
|
Packit |
eace71 |
.value = &session->first_burst,
|
|
Packit |
eace71 |
.type = ISCSI_INT,
|
|
Packit |
eace71 |
.conn_only = 0,
|
|
Packit |
eace71 |
}, {
|
|
Packit |
eace71 |
.param = ISCSI_PARAM_MAX_BURST,
|
|
Packit |
eace71 |
.value = &session->max_burst,
|
|
Packit |
eace71 |
.type = ISCSI_INT,
|
|
Packit |
eace71 |
.conn_only = 0,
|
|
Packit |
eace71 |
}, {
|
|
Packit |
eace71 |
.param = ISCSI_PARAM_PDU_INORDER_EN,
|
|
Packit |
eace71 |
.value = &session->pdu_inorder_en,
|
|
Packit |
eace71 |
.type = ISCSI_INT,
|
|
Packit |
eace71 |
.conn_only = 0,
|
|
Packit |
eace71 |
}, {
|
|
Packit |
eace71 |
.param =ISCSI_PARAM_DATASEQ_INORDER_EN,
|
|
Packit |
eace71 |
.value = &session->dataseq_inorder_en,
|
|
Packit |
eace71 |
.type = ISCSI_INT,
|
|
Packit |
eace71 |
.conn_only = 0,
|
|
Packit |
eace71 |
}, {
|
|
Packit |
eace71 |
.param = ISCSI_PARAM_ERL,
|
|
Packit |
eace71 |
.value = &zero, /* FIXME: session->erl */
|
|
Packit |
eace71 |
.type = ISCSI_INT,
|
|
Packit |
eace71 |
.conn_only = 0,
|
|
Packit |
eace71 |
}, {
|
|
Packit |
eace71 |
.param = ISCSI_PARAM_IFMARKER_EN,
|
|
Packit |
eace71 |
.value = &zero,/* FIXME: session->ifmarker_en */
|
|
Packit |
eace71 |
.type = ISCSI_INT,
|
|
Packit |
eace71 |
.conn_only = 0,
|
|
Packit |
eace71 |
}, {
|
|
Packit |
eace71 |
.param = ISCSI_PARAM_OFMARKER_EN,
|
|
Packit |
eace71 |
.value = &zero,/* FIXME: session->ofmarker_en */
|
|
Packit |
eace71 |
.type = ISCSI_INT,
|
|
Packit |
eace71 |
.conn_only = 0,
|
|
Packit |
eace71 |
}, {
|
|
Packit |
eace71 |
.param = ISCSI_PARAM_EXP_STATSN,
|
|
Packit |
eace71 |
.value = &conn->exp_statsn,
|
|
Packit |
eace71 |
.type = ISCSI_UINT,
|
|
Packit |
eace71 |
.conn_only = 1,
|
|
Packit |
eace71 |
}, {
|
|
Packit |
eace71 |
.param = ISCSI_PARAM_TPGT,
|
|
Packit |
eace71 |
.value = &session->portal_group_tag,
|
|
Packit |
eace71 |
.type = ISCSI_INT,
|
|
Packit |
eace71 |
.conn_only = 0,
|
|
Packit |
eace71 |
},
|
|
Packit |
eace71 |
};
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
iscsi_session_init_params(session);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
/* Entered full-feature phase! */
|
|
Packit |
eace71 |
for (i = 0; i < MAX_SESSION_NEG_PARAMS; i++) {
|
|
Packit |
eace71 |
if (conn->id != 0 && !conntbl[i].conn_only)
|
|
Packit |
eace71 |
continue;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (!(session->param_mask & (1ULL << conntbl[i].param)))
|
|
Packit |
eace71 |
continue;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
rc = ipc->set_param(session->t->handle, session->id,
|
|
Packit |
eace71 |
conn->id, conntbl[i].param, conntbl[i].value,
|
|
Packit |
eace71 |
conntbl[i].type);
|
|
Packit |
eace71 |
if (rc && rc != -ENOSYS) {
|
|
Packit |
eace71 |
log_error("can't set operational parameter %d for "
|
|
Packit |
eace71 |
"connection %d:%d, retcode %d (%d)",
|
|
Packit |
eace71 |
conntbl[i].param, session->id, conn->id,
|
|
Packit |
eace71 |
rc, errno);
|
|
Packit |
eace71 |
return EPERM;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
print_param_value(conntbl[i].param, conntbl[i].value,
|
|
Packit |
eace71 |
conntbl[i].type);
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
return 0;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
#define MAX_SESSION_PARAMS 20
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
int iscsi_session_set_params(struct iscsi_conn *conn)
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
struct iscsi_session *session = conn->session;
|
|
Packit |
eace71 |
int i, rc;
|
|
Packit |
eace71 |
struct connparam {
|
|
Packit |
eace71 |
int param;
|
|
Packit |
eace71 |
int type;
|
|
Packit |
eace71 |
void *value;
|
|
Packit |
eace71 |
int conn_only;
|
|
Packit |
eace71 |
} conntbl[MAX_SESSION_PARAMS] = {
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
.param = ISCSI_PARAM_TARGET_NAME,
|
|
Packit |
eace71 |
.conn_only = 0,
|
|
Packit |
eace71 |
.type = ISCSI_STRING,
|
|
Packit |
eace71 |
.value = session->target_name,
|
|
Packit |
eace71 |
}, {
|
|
Packit |
eace71 |
.param = ISCSI_PARAM_PERSISTENT_ADDRESS,
|
|
Packit |
eace71 |
.value = session->nrec.conn[conn->id].address,
|
|
Packit |
eace71 |
.type = ISCSI_STRING,
|
|
Packit |
eace71 |
.conn_only = 1,
|
|
Packit |
eace71 |
}, {
|
|
Packit |
eace71 |
.param = ISCSI_PARAM_PERSISTENT_PORT,
|
|
Packit |
eace71 |
.value = &session->nrec.conn[conn->id].port,
|
|
Packit |
eace71 |
.type = ISCSI_INT,
|
|
Packit |
eace71 |
.conn_only = 1,
|
|
Packit |
eace71 |
}, {
|
|
Packit |
eace71 |
.param = ISCSI_PARAM_SESS_RECOVERY_TMO,
|
|
Packit |
eace71 |
.value = &session->replacement_timeout,
|
|
Packit |
eace71 |
.type = ISCSI_INT,
|
|
Packit |
eace71 |
.conn_only = 0,
|
|
Packit |
eace71 |
}, {
|
|
Packit |
eace71 |
.param = ISCSI_PARAM_USERNAME,
|
|
Packit |
eace71 |
.value = session->username,
|
|
Packit |
eace71 |
.type = ISCSI_STRING,
|
|
Packit |
eace71 |
.conn_only = 0,
|
|
Packit |
eace71 |
}, {
|
|
Packit |
eace71 |
.param = ISCSI_PARAM_USERNAME_IN,
|
|
Packit |
eace71 |
.value = session->username_in,
|
|
Packit |
eace71 |
.type = ISCSI_STRING,
|
|
Packit |
eace71 |
.conn_only = 0,
|
|
Packit |
eace71 |
}, {
|
|
Packit |
eace71 |
.param = ISCSI_PARAM_PASSWORD,
|
|
Packit |
eace71 |
.value = session->password,
|
|
Packit |
eace71 |
.type = ISCSI_STRING,
|
|
Packit |
eace71 |
.conn_only = 0,
|
|
Packit |
eace71 |
}, {
|
|
Packit |
eace71 |
.param = ISCSI_PARAM_PASSWORD_IN,
|
|
Packit |
eace71 |
.value = session->password_in,
|
|
Packit |
eace71 |
.type = ISCSI_STRING,
|
|
Packit |
eace71 |
.conn_only = 0,
|
|
Packit |
eace71 |
}, {
|
|
Packit |
eace71 |
.param = ISCSI_PARAM_FAST_ABORT,
|
|
Packit |
eace71 |
.value = &session->fast_abort,
|
|
Packit |
eace71 |
.type = ISCSI_INT,
|
|
Packit |
eace71 |
.conn_only = 0,
|
|
Packit |
eace71 |
}, {
|
|
Packit |
eace71 |
.param = ISCSI_PARAM_ABORT_TMO,
|
|
Packit |
eace71 |
.value = &session->abort_timeout,
|
|
Packit |
eace71 |
.type = ISCSI_INT,
|
|
Packit |
eace71 |
.conn_only = 0,
|
|
Packit |
eace71 |
}, {
|
|
Packit |
eace71 |
.param = ISCSI_PARAM_LU_RESET_TMO,
|
|
Packit |
eace71 |
.value = &session->lu_reset_timeout,
|
|
Packit |
eace71 |
.type = ISCSI_INT,
|
|
Packit |
eace71 |
.conn_only = 0,
|
|
Packit |
eace71 |
}, {
|
|
Packit |
eace71 |
.param = ISCSI_PARAM_TGT_RESET_TMO,
|
|
Packit |
eace71 |
.value = &session->tgt_reset_timeout,
|
|
Packit |
eace71 |
.type = ISCSI_INT,
|
|
Packit |
eace71 |
.conn_only = 0,
|
|
Packit |
eace71 |
}, {
|
|
Packit |
eace71 |
.param = ISCSI_PARAM_PING_TMO,
|
|
Packit |
eace71 |
.value = &conn->noop_out_timeout,
|
|
Packit |
eace71 |
.type = ISCSI_INT,
|
|
Packit |
eace71 |
.conn_only = 1,
|
|
Packit |
eace71 |
}, {
|
|
Packit |
eace71 |
.param = ISCSI_PARAM_RECV_TMO,
|
|
Packit |
eace71 |
.value = &conn->noop_out_interval,
|
|
Packit |
eace71 |
.type = ISCSI_INT,
|
|
Packit |
eace71 |
.conn_only = 1,
|
|
Packit |
eace71 |
}, {
|
|
Packit |
eace71 |
.param = ISCSI_PARAM_IFACE_NAME,
|
|
Packit |
eace71 |
.value = session->nrec.iface.name,
|
|
Packit |
eace71 |
.type = ISCSI_STRING,
|
|
Packit |
eace71 |
.conn_only = 0,
|
|
Packit |
eace71 |
}, {
|
|
Packit |
eace71 |
.param = ISCSI_PARAM_INITIATOR_NAME,
|
|
Packit |
eace71 |
.value = session->initiator_name,
|
|
Packit |
eace71 |
.type = ISCSI_STRING,
|
|
Packit |
eace71 |
.conn_only = 0,
|
|
Packit |
eace71 |
}, {
|
|
Packit |
eace71 |
.param = ISCSI_PARAM_BOOT_ROOT,
|
|
Packit |
eace71 |
.value = session->nrec.session.boot_root,
|
|
Packit |
eace71 |
.type = ISCSI_STRING,
|
|
Packit |
eace71 |
.conn_only = 0,
|
|
Packit |
eace71 |
}, {
|
|
Packit |
eace71 |
.param = ISCSI_PARAM_BOOT_NIC,
|
|
Packit |
eace71 |
.value = session->nrec.session.boot_nic,
|
|
Packit |
eace71 |
.type = ISCSI_STRING,
|
|
Packit |
eace71 |
.conn_only = 0,
|
|
Packit |
eace71 |
}, {
|
|
Packit |
eace71 |
.param = ISCSI_PARAM_BOOT_TARGET,
|
|
Packit |
eace71 |
.value = session->nrec.session.boot_target,
|
|
Packit |
eace71 |
.type = ISCSI_STRING,
|
|
Packit |
eace71 |
.conn_only = 0,
|
|
Packit |
eace71 |
}, {
|
|
Packit |
eace71 |
.param = ISCSI_PARAM_DISCOVERY_SESS,
|
|
Packit |
eace71 |
.value = &session->type,
|
|
Packit |
eace71 |
.type = ISCSI_INT,
|
|
Packit |
eace71 |
.conn_only = 0,
|
|
Packit |
eace71 |
},
|
|
Packit |
eace71 |
};
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
iscsi_session_init_params(session);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
/* some llds will send nops internally */
|
|
Packit |
eace71 |
if (!iscsi_sysfs_session_supports_nop(session->id)) {
|
|
Packit |
eace71 |
iscsi_session_clear_param(session, ISCSI_PARAM_PING_TMO);
|
|
Packit |
eace71 |
iscsi_session_clear_param(session, ISCSI_PARAM_RECV_TMO);
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
/* Entered full-feature phase! */
|
|
Packit |
eace71 |
for (i = 0; i < MAX_SESSION_PARAMS; i++) {
|
|
Packit |
eace71 |
if (conn->id != 0 && !conntbl[i].conn_only)
|
|
Packit |
eace71 |
continue;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (!(session->param_mask & (1ULL << conntbl[i].param)))
|
|
Packit |
eace71 |
continue;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
rc = ipc->set_param(session->t->handle, session->id,
|
|
Packit |
eace71 |
conn->id, conntbl[i].param, conntbl[i].value,
|
|
Packit |
eace71 |
conntbl[i].type);
|
|
Packit |
eace71 |
if (rc && rc != -ENOSYS) {
|
|
Packit |
eace71 |
log_error("can't set operational parameter %d for "
|
|
Packit |
eace71 |
"connection %d:%d, retcode %d (%d)",
|
|
Packit |
eace71 |
conntbl[i].param, session->id, conn->id,
|
|
Packit |
eace71 |
rc, errno);
|
|
Packit |
eace71 |
return EPERM;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (rc == -ENOSYS) {
|
|
Packit |
eace71 |
switch (conntbl[i].param) {
|
|
Packit |
eace71 |
case ISCSI_PARAM_PING_TMO:
|
|
Packit |
eace71 |
/*
|
|
Packit |
eace71 |
* older kernels may not support nops
|
|
Packit |
eace71 |
* in kernel
|
|
Packit |
eace71 |
*/
|
|
Packit |
eace71 |
conn->userspace_nop = 1;
|
|
Packit |
eace71 |
break;
|
|
Packit |
eace71 |
#if 0
|
|
Packit |
eace71 |
TODO handle this
|
|
Packit |
eace71 |
case ISCSI_PARAM_INITIATOR_NAME:
|
|
Packit |
eace71 |
/* use host level one instead */
|
|
Packit |
eace71 |
hosttbl[ISCSI_HOST_PARAM_INITIATOR_NAME].set = 1;
|
|
Packit |
eace71 |
break;
|
|
Packit |
eace71 |
#endif
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
print_param_value(conntbl[i].param, conntbl[i].value,
|
|
Packit |
eace71 |
conntbl[i].type);
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
return 0;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
int iscsi_set_net_config(struct iscsi_transport *t, iscsi_session_t *session,
|
|
Packit |
eace71 |
struct iface_rec *iface)
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
if (t->template->set_net_config) {
|
|
Packit |
eace71 |
/* uip needs the netdev name */
|
|
Packit |
eace71 |
struct host_info hinfo;
|
|
Packit |
eace71 |
int hostno, rc;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
/* this assumes that the netdev or hw address is going to be
|
|
Packit |
eace71 |
set */
|
|
Packit |
eace71 |
hostno = iscsi_sysfs_get_host_no_from_hwinfo(iface, &rc);
|
|
Packit |
eace71 |
if (rc) {
|
|
Packit |
eace71 |
log_debug(4, "Couldn't get host no.");
|
|
Packit |
eace71 |
return rc;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
/* uip needs the netdev name */
|
|
Packit |
eace71 |
if (!strlen(iface->netdev)) {
|
|
Packit |
eace71 |
memset(&hinfo, 0, sizeof(hinfo));
|
|
Packit |
eace71 |
hinfo.host_no = hostno;
|
|
Packit |
eace71 |
iscsi_sysfs_get_hostinfo_by_host_no(&hinfo);
|
|
Packit |
eace71 |
strcpy(iface->netdev, hinfo.iface.netdev);
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
return t->template->set_net_config(t, iface, session);
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
return 0;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
int iscsi_host_set_net_params(struct iface_rec *iface,
|
|
Packit |
eace71 |
struct iscsi_session *session)
|
|
Packit |
eace71 |
{
|
|
Packit |
eace71 |
struct iscsi_transport *t = session->t;
|
|
Packit |
eace71 |
int rc = 0;
|
|
Packit |
eace71 |
char *netdev;
|
|
Packit |
eace71 |
struct host_info hinfo;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
log_debug(3, "setting iface %s, dev %s, set ip %s, hw %s, "
|
|
Packit |
eace71 |
"transport %s.",
|
|
Packit |
eace71 |
iface->name, iface->netdev, iface->ipaddress,
|
|
Packit |
eace71 |
iface->hwaddress, iface->transport_name);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (!t->template->set_host_ip)
|
|
Packit |
eace71 |
return 0;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
/* if we need to set the ip addr then set all the iface net settings */
|
|
Packit |
eace71 |
if (!iface_is_bound_by_ipaddr(iface)) {
|
|
Packit |
eace71 |
if (t->template->set_host_ip == SET_HOST_IP_REQ) {
|
|
Packit |
eace71 |
log_warning("Please set the iface.ipaddress for iface "
|
|
Packit |
eace71 |
"%s, then retry the login command.",
|
|
Packit |
eace71 |
iface->name);
|
|
Packit |
eace71 |
return ISCSI_ERR_INVAL;
|
|
Packit |
eace71 |
} else if (t->template->set_host_ip == SET_HOST_IP_OPT) {
|
|
Packit |
eace71 |
log_info("Optional iface.ipaddress for iface %s "
|
|
Packit |
eace71 |
"not set.", iface->name);
|
|
Packit |
eace71 |
return 0;
|
|
Packit |
eace71 |
} else {
|
|
Packit |
eace71 |
return ISCSI_ERR_INVAL;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
/* these type of drivers need the netdev upd */
|
|
Packit |
eace71 |
if (strlen(iface->netdev))
|
|
Packit |
eace71 |
netdev = iface->netdev;
|
|
Packit |
eace71 |
else {
|
|
Packit |
eace71 |
memset(&hinfo, 0, sizeof(hinfo));
|
|
Packit |
eace71 |
hinfo.host_no = session->hostno;
|
|
Packit |
eace71 |
iscsi_sysfs_get_hostinfo_by_host_no(&hinfo);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
netdev = hinfo.iface.netdev;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (!t->template->no_netdev && net_ifup_netdev(netdev))
|
|
Packit |
eace71 |
log_warning("Could not brining up netdev %s. Try running "
|
|
Packit |
eace71 |
"'ifup %s' first if login fails.", netdev, netdev);
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
rc = iscsi_set_net_config(t, session, iface);
|
|
Packit |
eace71 |
if (rc != 0)
|
|
Packit |
eace71 |
return rc;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
rc = host_set_param(t, session->hostno,
|
|
Packit |
eace71 |
ISCSI_HOST_PARAM_IPADDRESS,
|
|
Packit |
eace71 |
iface->ipaddress, ISCSI_STRING);
|
|
Packit |
eace71 |
if (rc)
|
|
Packit |
eace71 |
return rc;
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (iface_is_bound_by_netdev(iface)) {
|
|
Packit |
eace71 |
rc = host_set_param(t, session->hostno,
|
|
Packit |
eace71 |
ISCSI_HOST_PARAM_NETDEV_NAME,
|
|
Packit |
eace71 |
iface->netdev, ISCSI_STRING);
|
|
Packit |
eace71 |
if (rc)
|
|
Packit |
eace71 |
return rc;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
|
|
Packit |
eace71 |
if (iface_is_bound_by_hwaddr(iface)) {
|
|
Packit |
eace71 |
rc = host_set_param(t, session->hostno,
|
|
Packit |
eace71 |
ISCSI_HOST_PARAM_HWADDRESS,
|
|
Packit |
eace71 |
iface->hwaddress, ISCSI_STRING);
|
|
Packit |
eace71 |
if (rc)
|
|
Packit |
eace71 |
return rc;
|
|
Packit |
eace71 |
}
|
|
Packit |
eace71 |
return 0;
|
|
Packit |
eace71 |
}
|