nvmf: add AllowAnyHost option to subsystems

The previous behavior with an empty host NQN whitelist was to allow any
host to connect.

Change-Id: I5401e52d96642cf20afe0d50c692613e67262edf
Signed-off-by: Daniel Verkamp <daniel.verkamp@intel.com>
Reviewed-on: https://review.gerrithub.io/376432
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
Daniel Verkamp 2017-08-30 13:21:12 -07:00
parent 6847a679ea
commit a2db49a121
22 changed files with 76 additions and 19 deletions

View File

@ -32,12 +32,19 @@ The HotplugEnable option in `[Nvme]` sections of the configuration file is now
The NVMe library now includes a function spdk_nvme_ns_get_ctrlr which returns the
NVMe Controller associated with a given namespace.
### NVMe-oF Target (nvmf)
### NVMe-oF Target (nvmf_tgt)
The NVMe-oF target no longer requires any in capsule data buffers to run, and
the feature is now entirely optional. Previously, at least 4KiB in capsule
data buffers were required.
NVMe-oF subsytems have a new configuration option, AllowAnyHost, to control
whether the host NQN whitelist is enforced when accepting new connections.
If no Host options have been specified and AllowAnyHost is disabled, the
connection will be denied; this is a behavior change from previous releases,
which allowed any host NQN to connect if the Host list was empty.
AllowAnyHost is disabled by default.
### Environment Abstraction Layer
A new default value, SPDK_MEMPOOL_DEFAULT_CACHE_SIZE, was added to provide

View File

@ -124,6 +124,7 @@ spdk_add_nvmf_discovery_subsystem(void)
return -1;
}
spdk_nvmf_subsystem_set_allow_any_host(app_subsys->subsystem, true);
nvmf_tgt_start_subsystem(app_subsys);
return 0;
@ -230,6 +231,7 @@ spdk_nvmf_parse_subsystem(struct spdk_conf_section *sp)
char *listen_addrs_str[MAX_LISTEN_ADDRESSES] = {};
int num_hosts;
char *hosts[MAX_HOSTS];
bool allow_any_host;
const char *sn;
int num_devs;
char *devs[MAX_NAMESPACES];
@ -290,6 +292,8 @@ spdk_nvmf_parse_subsystem(struct spdk_conf_section *sp)
}
num_hosts = i;
allow_any_host = spdk_conf_section_get_boolval(sp, "AllowAnyHost", false);
sn = spdk_conf_section_get_val(sp, "SN");
num_devs = 0;
@ -304,7 +308,7 @@ spdk_nvmf_parse_subsystem(struct spdk_conf_section *sp)
ret = spdk_nvmf_construct_subsystem(nqn, lcore,
num_listen_addrs, listen_addrs,
num_hosts, hosts,
num_hosts, hosts, allow_any_host,
sn,
num_devs, devs);
@ -357,7 +361,7 @@ spdk_nvmf_parse_conf(void)
int
spdk_nvmf_construct_subsystem(const char *name, int32_t lcore,
int num_listen_addresses, struct rpc_listen_address *addresses,
int num_hosts, char *hosts[],
int num_hosts, char *hosts[], bool allow_any_host,
const char *sn, int num_devs, char *dev_list[])
{
struct spdk_nvmf_subsystem *subsystem;
@ -444,6 +448,7 @@ spdk_nvmf_construct_subsystem(const char *name, int32_t lcore,
for (i = 0; i < num_hosts; i++) {
spdk_nvmf_subsystem_add_host(subsystem, hosts[i]);
}
spdk_nvmf_subsystem_set_allow_any_host(subsystem, allow_any_host);
if (sn == NULL) {
SPDK_ERRLOG("Subsystem %s: missing serial number\n", name);

View File

@ -89,6 +89,9 @@ dump_nvmf_subsystem(struct spdk_json_write_ctx *w, struct nvmf_tgt_subsystem *tg
}
spdk_json_write_array_end(w);
spdk_json_write_name(w, "allow_any_host");
spdk_json_write_bool(w, spdk_nvmf_subsystem_get_allow_any_host(subsystem));
spdk_json_write_name(w, "hosts");
spdk_json_write_array_begin(w);
@ -261,6 +264,7 @@ struct rpc_subsystem {
char *nqn;
struct rpc_listen_addresses listen_addresses;
struct rpc_hosts hosts;
bool allow_any_host;
char *pci_address;
char *serial_number;
struct rpc_dev_names namespaces;
@ -283,6 +287,7 @@ static const struct spdk_json_object_decoder rpc_subsystem_decoders[] = {
{"nqn", offsetof(struct rpc_subsystem, nqn), spdk_json_decode_string},
{"listen_addresses", offsetof(struct rpc_subsystem, listen_addresses), decode_rpc_listen_addresses},
{"hosts", offsetof(struct rpc_subsystem, hosts), decode_rpc_hosts, true},
{"allow_any_host", offsetof(struct rpc_subsystem, allow_any_host), spdk_json_decode_bool, true},
{"serial_number", offsetof(struct rpc_subsystem, serial_number), spdk_json_decode_string, true},
{"namespaces", offsetof(struct rpc_subsystem, namespaces), decode_rpc_dev_names, true},
};
@ -321,7 +326,7 @@ spdk_rpc_construct_nvmf_subsystem(struct spdk_jsonrpc_request *request,
ret = spdk_nvmf_construct_subsystem(req.nqn, req.core,
req.listen_addresses.num_listen_address,
req.listen_addresses.addresses,
req.hosts.num_hosts, req.hosts.hosts,
req.hosts.num_hosts, req.hosts.hosts, req.allow_any_host,
req.serial_number,
req.namespaces.num_names, req.namespaces.names);
if (ret) {

View File

@ -83,7 +83,7 @@ int
spdk_nvmf_construct_subsystem(const char *name,
int32_t lcore,
int num_listen_addresses, struct rpc_listen_address *addresses,
int num_hosts, char *hosts[],
int num_hosts, char *hosts[], bool allow_any_host,
const char *sn, int num_devs, char *dev_list[]);
int

View File

@ -160,6 +160,7 @@ TransportID "trtype:PCIe traddr:0000:82:00.0" Nvme1
NQN nqn.2016-06.io.spdk:cnode1
Core 25
Listen RDMA 192.168.100.8:4420
AllowAnyHost No
Host nqn.2016-06.io.spdk:init
SN SPDK00000000000001
Namespace Nvme0n1
@ -168,6 +169,7 @@ Namespace Nvme0n1
NQN nqn.2016-06.io.spdk:cnode2
Core 26
Listen RDMA 192.168.100.9:4420
AllowAnyHost Yes
SN SPDK00000000000002
Namespace Nvme1n1
~~~
@ -193,6 +195,7 @@ virtual controller with two namespaces backed by the malloc LUNs named Malloc0 a
NQN nqn.2016-06.io.spdk:cnode2
Core 0
Listen RDMA 192.168.2.21:4420
AllowAnyHost No
Host nqn.2016-06.io.spdk:init
SN SPDK00000000000001
Namespace Malloc0

View File

@ -139,6 +139,7 @@
NQN nqn.2016-06.io.spdk:cnode1
Core 0
Listen RDMA 15.15.15.2:4420
AllowAnyHost No
Host nqn.2016-06.io.spdk:init
SN SPDK00000000000001
Namespace Nvme0n1
@ -150,6 +151,7 @@
NQN nqn.2016-06.io.spdk:cnode2
Core 0
Listen RDMA 192.168.2.21:4420
AllowAnyHost No
Host nqn.2016-06.io.spdk:init
SN SPDK00000000000002
Namespace Malloc0

View File

@ -135,6 +135,25 @@ void spdk_nvmf_delete_subsystem(struct spdk_nvmf_subsystem *subsystem);
int spdk_nvmf_subsystem_add_host(struct spdk_nvmf_subsystem *subsystem,
const char *hostnqn);
/**
* Set whether a subsystem should allow any host or only hosts in the allowed list.
*
* \param subsystem Subsystem to modify.
* \param allow_any_host true to allow any host to connect to this subsystem, or false to enforce
* the whitelist configured with spdk_nvmf_subsystem_add_host().
*/
void spdk_nvmf_subsystem_set_allow_any_host(struct spdk_nvmf_subsystem *subsystem,
bool allow_any_host);
/**
* Check whether a subsystem should allow any host or only hosts in the allowed list.
*
* \param subsystem Subsystem to modify.
* \return true if any host is allowed to connect to this subsystem, or false if connecting hosts
* must be in the whitelist configured with spdk_nvmf_subsystem_add_host().
*/
bool spdk_nvmf_subsystem_get_allow_any_host(const struct spdk_nvmf_subsystem *subsystem);
/**
* Check if the given host is allowed to connect to the subsystem.
*

View File

@ -176,6 +176,7 @@ struct spdk_nvmf_subsystem {
char subnqn[SPDK_NVMF_NQN_MAX_LEN + 1];
enum spdk_nvmf_subtype subtype;
bool is_removed;
bool allow_any_host;
struct spdk_nvmf_tgt *tgt;

View File

@ -224,6 +224,18 @@ spdk_nvmf_subsystem_add_host(struct spdk_nvmf_subsystem *subsystem, const char *
return 0;
}
void
spdk_nvmf_subsystem_set_allow_any_host(struct spdk_nvmf_subsystem *subsystem, bool allow_any_host)
{
subsystem->allow_any_host = allow_any_host;
}
bool
spdk_nvmf_subsystem_get_allow_any_host(const struct spdk_nvmf_subsystem *subsystem)
{
return subsystem->allow_any_host;
}
bool
spdk_nvmf_subsystem_host_allowed(struct spdk_nvmf_subsystem *subsystem, const char *hostnqn)
{
@ -233,8 +245,7 @@ spdk_nvmf_subsystem_host_allowed(struct spdk_nvmf_subsystem *subsystem, const ch
return false;
}
if (TAILQ_EMPTY(&subsystem->hosts)) {
/* No hosts means any host can connect */
if (subsystem->allow_any_host) {
return true;
}

View File

@ -420,6 +420,9 @@ def construct_nvmf_subsystem(args):
hosts.append(u)
params['hosts'] = hosts
if args.allow_any_host:
params['allow_any_host'] = True
if args.namespaces:
namespaces = []
for u in args.namespaces.strip().split(" "):
@ -437,6 +440,7 @@ Example: 'trtype:RDMA traddr:192.168.100.8 trsvcid:4420,trtype:RDMA traddr:192.1
p.add_argument('hosts', help="""Whitespace-separated list of host nqn list.
Format: 'nqn1 nqn2' etc
Example: 'nqn.2016-06.io.spdk:init nqn.2016-07.io.spdk:init'""")
p.add_argument("-a", "--allow-any-host", action='store_true', help="Allow any host to connect (don't enforce host NQN whitelist)")
p.add_argument("-s", "--serial_number", help="""
Format: 'sn' etc
Example: 'SPDK00000000000001'""", default='0000:00:01.0')

View File

@ -31,7 +31,7 @@ trap "killprocess $nvmfpid; exit 1" SIGINT SIGTERM EXIT
waitforlisten $nvmfpid 5260
echo "NVMf target has started."
bdevs=$($rpc_py construct_malloc_bdev 64 512)
$rpc_py construct_nvmf_subsystem nqn.2016-06.io.spdk:cnode1 "trtype:RDMA traddr:$NVMF_FIRST_TARGET_IP trsvcid:4420" "" -s SPDK00000000000001 -n "$bdevs"
$rpc_py construct_nvmf_subsystem nqn.2016-06.io.spdk:cnode1 "trtype:RDMA traddr:$NVMF_FIRST_TARGET_IP trsvcid:4420" "" -a -s SPDK00000000000001 -n "$bdevs"
echo "NVMf subsystem created."
timing_enter start_iscsi_tgt

View File

@ -40,7 +40,7 @@ bdevs="$bdevs $($rpc_py construct_null_bdev Null1 $NULL_BDEV_SIZE $NULL_BLOCK_SI
modprobe -v nvme-rdma
$rpc_py construct_nvmf_subsystem nqn.2016-06.io.spdk:cnode1 "trtype:RDMA traddr:$NVMF_FIRST_TARGET_IP trsvcid:4420" "" -s SPDK00000000000001 -n "$bdevs"
$rpc_py construct_nvmf_subsystem nqn.2016-06.io.spdk:cnode1 "trtype:RDMA traddr:$NVMF_FIRST_TARGET_IP trsvcid:4420" "" -a -s SPDK00000000000001 -n "$bdevs"
nvme discover -t rdma -a $NVMF_FIRST_TARGET_IP -s $NVMF_PORT

View File

@ -35,7 +35,7 @@ bdevs="$bdevs $($rpc_py construct_malloc_bdev $MALLOC_BDEV_SIZE $MALLOC_BLOCK_SI
modprobe -v nvme-rdma
$rpc_py construct_nvmf_subsystem nqn.2016-06.io.spdk:cnode1 "trtype:RDMA traddr:$NVMF_FIRST_TARGET_IP trsvcid:4420" "" -s SPDK00000000000001 -n "$bdevs"
$rpc_py construct_nvmf_subsystem nqn.2016-06.io.spdk:cnode1 "trtype:RDMA traddr:$NVMF_FIRST_TARGET_IP trsvcid:4420" "" -a -s SPDK00000000000001 -n "$bdevs"
nvme connect -t rdma -n "nqn.2016-06.io.spdk:cnode1" -a "$NVMF_FIRST_TARGET_IP" -s "$NVMF_PORT"

View File

@ -35,7 +35,7 @@ bdevs="$bdevs $($rpc_py construct_malloc_bdev $MALLOC_BDEV_SIZE $MALLOC_BLOCK_SI
modprobe -v nvme-rdma
$rpc_py construct_nvmf_subsystem nqn.2016-06.io.spdk:cnode1 "trtype:RDMA traddr:$NVMF_FIRST_TARGET_IP trsvcid:4420" "" -s SPDK00000000000001 -n "$bdevs"
$rpc_py construct_nvmf_subsystem nqn.2016-06.io.spdk:cnode1 "trtype:RDMA traddr:$NVMF_FIRST_TARGET_IP trsvcid:4420" "" -a -s SPDK00000000000001 -n "$bdevs"
nvme connect -t rdma -n "nqn.2016-06.io.spdk:cnode1" -a "$NVMF_FIRST_TARGET_IP" -s "$NVMF_PORT"

View File

@ -28,7 +28,7 @@ waitforlisten $nvmfpid ${RPC_PORT}
timing_exit start_nvmf_tgt
bdevs="$bdevs $($rpc_py construct_malloc_bdev 64 512)"
$rpc_py construct_nvmf_subsystem nqn.2016-06.io.spdk:cnode1 "trtype:RDMA traddr:$NVMF_FIRST_TARGET_IP trsvcid:4420" '' -s SPDK00000000000001 -n "$bdevs"
$rpc_py construct_nvmf_subsystem nqn.2016-06.io.spdk:cnode1 "trtype:RDMA traddr:$NVMF_FIRST_TARGET_IP trsvcid:4420" '' -a -s SPDK00000000000001 -n "$bdevs"
$rootdir/test/lib/nvme/aer/aer -r "\
trtype:RDMA \

View File

@ -33,7 +33,7 @@ waitforlisten $nvmfpid ${RPC_PORT}
timing_exit start_nvmf_tgt
bdevs="$bdevs $($rpc_py construct_malloc_bdev 64 512)"
$rpc_py construct_nvmf_subsystem nqn.2016-06.io.spdk:cnode1 "trtype:RDMA traddr:$NVMF_FIRST_TARGET_IP trsvcid:4420" '' -s SPDK00000000000001 -n "$bdevs"
$rpc_py construct_nvmf_subsystem nqn.2016-06.io.spdk:cnode1 "trtype:RDMA traddr:$NVMF_FIRST_TARGET_IP trsvcid:4420" '' -a -s SPDK00000000000001 -n "$bdevs"
PLUGIN_DIR=$rootdir/examples/nvme/fio_plugin

View File

@ -31,7 +31,7 @@ timing_exit start_nvmf_tgt
bdevs="$bdevs $($rpc_py construct_malloc_bdev $MALLOC_BDEV_SIZE $MALLOC_BLOCK_SIZE)"
$rpc_py construct_nvmf_subsystem nqn.2016-06.io.spdk:cnode1 "trtype:RDMA traddr:$NVMF_FIRST_TARGET_IP trsvcid:4420" '' -s SPDK00000000000001 -n "$bdevs"
$rpc_py construct_nvmf_subsystem nqn.2016-06.io.spdk:cnode1 "trtype:RDMA traddr:$NVMF_FIRST_TARGET_IP trsvcid:4420" '' -a -s SPDK00000000000001 -n "$bdevs"
$rootdir/examples/nvme/identify/identify -r "\
trtype:RDMA \

View File

@ -32,7 +32,7 @@ timing_exit start_nvmf_tgt
bdevs="$bdevs $($rpc_py construct_malloc_bdev $MALLOC_BDEV_SIZE $MALLOC_BLOCK_SIZE)"
$rpc_py construct_nvmf_subsystem nqn.2016-06.io.spdk:cnode1 "trtype:RDMA traddr:$NVMF_FIRST_TARGET_IP trsvcid:4420" '' -s SPDK00000000000001 -n "$bdevs"
$rpc_py construct_nvmf_subsystem nqn.2016-06.io.spdk:cnode1 "trtype:RDMA traddr:$NVMF_FIRST_TARGET_IP trsvcid:4420" '' -a -s SPDK00000000000001 -n "$bdevs"
$rootdir/examples/nvme/perf/perf -q 128 -s 4096 -w randrw -M 50 -t 1 -r "trtype:RDMA adrfam:IPv4 traddr:$NVMF_FIRST_TARGET_IP trsvcid:4420"
sync

View File

@ -35,7 +35,7 @@ modprobe -v nvme-rdma
for i in `seq 1 11`
do
bdevs="$($rpc_py construct_malloc_bdev $MALLOC_BDEV_SIZE $MALLOC_BLOCK_SIZE)"
$rpc_py construct_nvmf_subsystem nqn.2016-06.io.spdk:cnode${i} "trtype:RDMA traddr:$NVMF_FIRST_TARGET_IP trsvcid:$NVMF_PORT" '' -s SPDK${i} -n "$bdevs"
$rpc_py construct_nvmf_subsystem nqn.2016-06.io.spdk:cnode${i} "trtype:RDMA traddr:$NVMF_FIRST_TARGET_IP trsvcid:$NVMF_PORT" '' -a -s SPDK${i} -n "$bdevs"
done
for i in `seq 1 11`; do

View File

@ -34,7 +34,7 @@ bdevs="$bdevs $($rpc_py construct_malloc_bdev $MALLOC_BDEV_SIZE $MALLOC_BLOCK_SI
modprobe -v nvme-rdma
$rpc_py construct_nvmf_subsystem nqn.2016-06.io.spdk:cnode1 "trtype:RDMA traddr:$NVMF_FIRST_TARGET_IP trsvcid:4420" '' -s SPDK00000000000001 -n "$bdevs"
$rpc_py construct_nvmf_subsystem nqn.2016-06.io.spdk:cnode1 "trtype:RDMA traddr:$NVMF_FIRST_TARGET_IP trsvcid:4420" '' -a -s SPDK00000000000001 -n "$bdevs"
nvme connect -t rdma -n "nqn.2016-06.io.spdk:cnode1" -a "$NVMF_FIRST_TARGET_IP" -s "$NVMF_PORT"

View File

@ -45,7 +45,7 @@ do
j=0
for bdf in $bdfs; do
let j=j+1
$rpc_py construct_nvmf_subsystem nqn.2016-06.io.spdk:cnode$j "trtype:RDMA traddr:$NVMF_FIRST_TARGET_IP trsvcid:4420" '' -s SPDK00000000000001 -n "$bdevs"
$rpc_py construct_nvmf_subsystem nqn.2016-06.io.spdk:cnode$j "trtype:RDMA traddr:$NVMF_FIRST_TARGET_IP trsvcid:4420" '' -a -s SPDK00000000000001 -n "$bdevs"
done
n=$j

View File

@ -34,7 +34,7 @@ timing_exit start_nvmf_tgt
for i in `seq 1 10`
do
bdevs="$($rpc_py construct_malloc_bdev $MALLOC_BDEV_SIZE $MALLOC_BLOCK_SIZE)"
$rpc_py construct_nvmf_subsystem nqn.2016-06.io.spdk:cnode${i} "trtype:RDMA traddr:$NVMF_FIRST_TARGET_IP trsvcid:$NVMF_PORT" '' -s SPDK${i} -n "$bdevs"
$rpc_py construct_nvmf_subsystem nqn.2016-06.io.spdk:cnode${i} "trtype:RDMA traddr:$NVMF_FIRST_TARGET_IP trsvcid:$NVMF_PORT" '' -a -s SPDK${i} -n "$bdevs"
done
# Kill nvmf tgt without removing any subsystem to check whether it can shutdown correctly