nvmf/fc: Add listen address support in FC transport
Enables access control to allow subsystem access on one or more FC ports. If a subsystem definition does not have a single valid "Listen" directive, then the subsystem will allow dynamic listen address binding. For such subsystems, * When a FC port comes online, FC transport will add port's address to subsystem's listen list. * When a FC port goes offline, FC transport will remove port's address from subsystem's listen list. If subsystem definition has 1 or more valid "Listen" directives then FC ports coming online or going offline will not affect subsystem's listen address whitelist. Signed-off-by: Anil Veerabhadrappa <anil.veerabhadrappa@broadcom.com> Change-Id: Ic7fed76e4bf8d1df0aeeae1d4fa5e6d207afccf3 Signed-off-by: Anil Veerabhadrappa <anil.veerabhadrappa@broadcom.com> Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/471025 Community-CI: Broadcom SPDK FC-NVMe CI <spdk-ci.pdl@broadcom.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Alexey Marchuk <alexeymar@mellanox.com> Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
parent
c265fa18a8
commit
5e25bbdd49
@ -232,7 +232,7 @@
|
||||
# - NQN is required and must be unique.
|
||||
# - Between 1 and 255 Listen directives are allowed. This defines
|
||||
# the addresses on which new connections may be accepted. The format
|
||||
# is Listen <type> <address> where type can be RDMA or TCP.
|
||||
# is Listen <type> <address> where type can be RDMA, TCP or FC.
|
||||
# - Between 0 and 255 Host directives are allowed. This defines the
|
||||
# NQNs of allowed hosts. If no Host directive is specified, all hosts
|
||||
# are allowed to connect.
|
||||
@ -273,3 +273,16 @@
|
||||
Namespace Malloc1
|
||||
Namespace AIO0
|
||||
Namespace AIO1
|
||||
|
||||
# Subsystem with FC listen address directive
|
||||
# - Listen option allows subsystem access on specific FC ports identified
|
||||
# by WWNN-WWPN. Each subsystem allows 0 - 255 listen directives.
|
||||
# If no listen directive is provided, subsystem can be accessed on all
|
||||
# avialable FC links permitted by FC zoning rules.
|
||||
#
|
||||
# [Subsystem3]
|
||||
#NQN nqn.2016-06.io.spdk:cnode3
|
||||
#Listen FC "nn-0x20000090fac7ca5c:pn-0x10000090fac7ca5c"
|
||||
#AllowAnyHost Yes
|
||||
#SN SPDK00000000000003
|
||||
#Namespace Malloc4
|
||||
|
@ -616,6 +616,29 @@ struct spdk_nvmf_listener *spdk_nvmf_subsystem_get_next_listener(
|
||||
const struct spdk_nvme_transport_id *spdk_nvmf_listener_get_trid(
|
||||
struct spdk_nvmf_listener *listener);
|
||||
|
||||
/**
|
||||
* Set whether a subsystem should allow any listen address or only addresses in the allowed list.
|
||||
*
|
||||
* \param subsystem Subsystem to allow dynamic listener assignment.
|
||||
* \param allow_any_listener true to allow dynamic listener assignment for
|
||||
* this subsystem, or false to enforce the whitelist configured during
|
||||
* subsystem setup.
|
||||
*/
|
||||
void spdk_nvmf_subsystem_allow_any_listener(
|
||||
struct spdk_nvmf_subsystem *subsystem,
|
||||
bool allow_any_listener);
|
||||
|
||||
/**
|
||||
* Check whether a subsystem allows any listen address or only addresses in the allowed list.
|
||||
*
|
||||
* \param subsystem Subsystem to query.
|
||||
*
|
||||
* \return true if this subsystem allows dynamic management of listen address list,
|
||||
* or false if only allows addresses in the whitelist configured during subsystem setup.
|
||||
*/
|
||||
bool spdk_nvmf_subsytem_any_listener_allowed(
|
||||
struct spdk_nvmf_subsystem *subsystem);
|
||||
|
||||
/** NVMe-oF target namespace creation options */
|
||||
struct spdk_nvmf_ns_opts {
|
||||
/**
|
||||
|
@ -3003,16 +3003,23 @@ nvmf_fc_adm_add_rem_nport_listener(struct spdk_nvmf_fc_nport *nport, bool add)
|
||||
while (subsystem) {
|
||||
struct nvmf_fc_add_rem_listener_ctx *ctx;
|
||||
|
||||
ctx = calloc(1, sizeof(struct nvmf_fc_add_rem_listener_ctx));
|
||||
if (ctx) {
|
||||
ctx->add_listener = add;
|
||||
spdk_nvmf_fc_create_trid(&ctx->trid, nport->fc_nodename.u.wwn,
|
||||
nport->fc_portname.u.wwn);
|
||||
if (spdk_nvmf_subsystem_pause(subsystem, nvmf_fc_adm_subsystem_paused_cb, ctx)) {
|
||||
SPDK_ERRLOG("Failed to pause subsystem: %s\n", subsystem->subnqn);
|
||||
free(ctx);
|
||||
if (spdk_nvmf_subsytem_any_listener_allowed(subsystem) == true) {
|
||||
ctx = calloc(1, sizeof(struct nvmf_fc_add_rem_listener_ctx));
|
||||
if (ctx) {
|
||||
ctx->add_listener = add;
|
||||
spdk_nvmf_fc_create_trid(&ctx->trid,
|
||||
nport->fc_nodename.u.wwn,
|
||||
nport->fc_portname.u.wwn);
|
||||
if (spdk_nvmf_subsystem_pause(subsystem,
|
||||
nvmf_fc_adm_subsystem_paused_cb,
|
||||
ctx)) {
|
||||
SPDK_ERRLOG("Failed to pause subsystem: %s\n",
|
||||
subsystem->subnqn);
|
||||
free(ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
subsystem = spdk_nvmf_subsystem_get_next(subsystem);
|
||||
}
|
||||
|
||||
|
@ -350,6 +350,7 @@ struct spdk_nvmf_subsystem {
|
||||
enum spdk_nvmf_subtype subtype;
|
||||
uint16_t next_cntlid;
|
||||
bool allow_any_host;
|
||||
bool allow_any_listener ;
|
||||
|
||||
struct spdk_nvmf_tgt *tgt;
|
||||
|
||||
|
@ -842,6 +842,20 @@ spdk_nvmf_listener_get_trid(struct spdk_nvmf_listener *listener)
|
||||
return &listener->trid;
|
||||
}
|
||||
|
||||
void
|
||||
spdk_nvmf_subsystem_allow_any_listener(struct spdk_nvmf_subsystem *subsystem,
|
||||
bool allow_any_listener)
|
||||
{
|
||||
subsystem->allow_any_listener = allow_any_listener;
|
||||
}
|
||||
|
||||
bool
|
||||
spdk_nvmf_subsytem_any_listener_allowed(struct spdk_nvmf_subsystem *subsystem)
|
||||
{
|
||||
return subsystem->allow_any_listener;
|
||||
}
|
||||
|
||||
|
||||
struct subsystem_update_ns_ctx {
|
||||
struct spdk_nvmf_subsystem *subsystem;
|
||||
|
||||
|
@ -266,6 +266,25 @@ spdk_nvmf_tgt_parse_listen_ip_addr(char *address,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
spdk_nvmf_tgt_parse_listen_fc_addr(const char *address,
|
||||
struct spdk_nvme_transport_id *trid)
|
||||
{
|
||||
/* transport address format and requirements,
|
||||
* "nn-0xWWNN:pn-0xWWPN" - size equals 43 bytes and is required to
|
||||
* contain 'nn' and 'pn'.
|
||||
*/
|
||||
if (strlen(address) != 43 || strncmp(address, "nn-0x", 5) ||
|
||||
strncmp(&address[21], ":pn-0x", 6)) {
|
||||
SPDK_ERRLOG("Unable to parse fc address '%s'\n", address);
|
||||
return -1;
|
||||
}
|
||||
|
||||
snprintf(trid->traddr, sizeof(trid->traddr), "%s", address);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
spdk_nvmf_parse_subsystem(struct spdk_conf_section *sp)
|
||||
{
|
||||
@ -273,6 +292,7 @@ spdk_nvmf_parse_subsystem(struct spdk_conf_section *sp)
|
||||
size_t i;
|
||||
int lcore;
|
||||
bool allow_any_host;
|
||||
bool allow_any_listener = true;
|
||||
const char *sn;
|
||||
const char *mn;
|
||||
struct spdk_nvmf_subsystem *subsystem;
|
||||
@ -443,6 +463,11 @@ spdk_nvmf_parse_subsystem(struct spdk_conf_section *sp)
|
||||
free(address_dup);
|
||||
continue;
|
||||
}
|
||||
} else if (trid.trtype == SPDK_NVME_TRANSPORT_FC) {
|
||||
if (spdk_nvmf_tgt_parse_listen_fc_addr(address_dup, &trid)) {
|
||||
free(address_dup);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
free(address_dup);
|
||||
@ -450,8 +475,11 @@ spdk_nvmf_parse_subsystem(struct spdk_conf_section *sp)
|
||||
spdk_nvmf_tgt_listen(g_spdk_nvmf_tgt, &trid, spdk_nvmf_tgt_listen_done, NULL);
|
||||
|
||||
spdk_nvmf_subsystem_add_listener(subsystem, &trid);
|
||||
allow_any_listener = false;
|
||||
}
|
||||
|
||||
spdk_nvmf_subsystem_allow_any_listener(subsystem, allow_any_listener);
|
||||
|
||||
/* Parse Host sections */
|
||||
for (i = 0; ; i++) {
|
||||
const char *host = spdk_conf_section_get_nval(sp, "Host", i);
|
||||
|
Loading…
Reference in New Issue
Block a user