Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 16 additions & 12 deletions libnvme/libnvme3/nvme.i
Original file line number Diff line number Diff line change
Expand Up @@ -339,8 +339,12 @@ static PyObject *ssns_to_dict(struct libnbft_subsystem_ns *ss)
if (ss->dhcp_root_path_string)
PyDict_SetItemStringDecRef(output, "dhcp_root_path_string", PyUnicode_FromString(ss->dhcp_root_path_string));

PyDict_SetItemStringDecRef(output, "pdu_header_digest_required", PyBool_FromLong(ss->pdu_header_digest_required));
PyDict_SetItemStringDecRef(output, "data_digest_required", PyBool_FromLong(ss->data_digest_required));
PyDict_SetItemStringDecRef(output, "trflags", PyLong_FromLong(ss->trflags));
PyDict_SetItemStringDecRef(output, "naed", PyLong_FromLong(ss->naed));
PyDict_SetItemStringDecRef(output, "cipeec", PyLong_FromLong(ss->cipeec));
PyDict_SetItemStringDecRef(output, "cto", PyLong_FromLong(ss->cto));
PyDict_SetItemStringDecRef(output, "nceec", PyLong_FromLong(ss->nceec));
PyDict_SetItemStringDecRef(output, "flags", PyLong_FromLong(ss->flags));

return output;
}
Expand Down Expand Up @@ -381,8 +385,15 @@ static PyObject *hfi_to_dict(struct libnbft_hfi *hfi)
if (hfi->tcp_info.host_name)
PyDict_SetItemStringDecRef(output, "host_name", PyUnicode_FromString(hfi->tcp_info.host_name));

PyDict_SetItemStringDecRef(output, "this_hfi_is_default_route", PyBool_FromLong(hfi->tcp_info.this_hfi_is_default_route));
PyDict_SetItemStringDecRef(output, "dhcp_override", PyBool_FromLong(hfi->tcp_info.dhcp_override));
PyDict_SetItemStringDecRef(output, "flags", PyLong_FromLong(hfi->tcp_info.flags));
PyDict_SetItemStringDecRef(output, "pcie_seg_num", PyLong_FromLong(hfi->tcp_info.pcie_seg_num));
PyDict_SetItemStringDecRef(output, "dhcp_iaid", PyLong_FromLong(hfi->tcp_info.dhcp_iaid));
{
PyObject *duid = PyBytes_FromStringAndSize((const char *)hfi->tcp_info.dhcp_duid,
hfi->tcp_info.dhcp_duid_len);
PyDict_SetItemStringDecRef(output, "dhcp_duid", duid);
}
PyDict_SetItemStringDecRef(output, "dhcp_duid_len", PyLong_FromLong(hfi->tcp_info.dhcp_duid_len));
}

return output;
Expand All @@ -406,7 +417,6 @@ static PyObject *discovery_to_dict(struct libnbft_discovery *disc)

static PyObject *nbft_to_pydict(struct libnbft_info *nbft)
{
PyObject *val;
PyObject *output = PyDict_New();

{
Expand All @@ -420,13 +430,7 @@ static PyObject *nbft_to_pydict(struct libnbft_info *nbft)
PyDict_SetItemStringDecRef(host, "id", PyUnicode_FromString(uuid_str));
}

PyDict_SetItemStringDecRef(host, "host_id_configured", PyBool_FromLong(nbft->host.host_id_configured));
PyDict_SetItemStringDecRef(host, "host_nqn_configured", PyBool_FromLong(nbft->host.host_nqn_configured));

val = PyUnicode_FromString(nbft->host.primary == LIBNBFT_PRIMARY_ADMIN_HOST_FLAG_NOT_INDICATED ? "not indicated" :
nbft->host.primary == LIBNBFT_PRIMARY_ADMIN_HOST_FLAG_UNSELECTED ? "unselected" :
nbft->host.primary == LIBNBFT_PRIMARY_ADMIN_HOST_FLAG_SELECTED ? "selected" : "reserved");
PyDict_SetItemStringDecRef(host, "primary_admin_host_flag", val);
PyDict_SetItemStringDecRef(host, "flags", PyLong_FromLong(nbft->host.flags));

PyDict_SetItemStringDecRef(output, "host", host);
}
Expand Down
27 changes: 18 additions & 9 deletions libnvme/libnvme3/tests/test-nbft.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,57 +18,66 @@ def setUp(self):
],
"hfi": [
{
"dhcp_override": True,
"dhcp_iaid": 0,
"dhcp_duid": b"",
"dhcp_duid_len": 0,
"dhcp_server_ipaddr": "100.71.245.254",
"flags": 0x07,
"gateway_ipaddr": "100.71.245.254",
"ip_origin": 82,
"ipaddr": "100.71.245.232",
"mac_addr": "b0:26:28:e8:7c:0e",
"pcidev": "0:40:0.0",
"pcie_seg_num": 0,
"primary_dns_ipaddr": "100.64.0.5",
"route_metric": 500,
"secondary_dns_ipaddr": "100.64.0.6",
"subnet_mask_prefix": 24,
"this_hfi_is_default_route": 1,
"trtype": "tcp",
"vlan": 0,
}
],
"host": {
"host_id_configured": True,
"host_nqn_configured": True,
"flags": 0x07,
"id": "44454c4c-3400-1036-8038-b2c04f313233",
"nqn": "nqn.1988-11.com.dell:PowerEdge.R760.1234567",
"primary_admin_host_flag": "not indicated",
},
"subsystem": [
{
"asqsz": 0,
"cipeec": 0,
"controller_id": 5,
"data_digest_required": False,
"cto": 0,
"flags": 0x0051,
"hfi_indexes": [0],
"naed": 0,
"nceec": 0,
"nid": "c82404ed9c15f53b8ccf0968002e0fca",
"nid_type": "nguid",
"nsid": 148,
"pdu_header_digest_required": False,
"subsys_nqn": "nqn.1988-11.com.dell:powerstore:00:2a64abf1c5b81F6C4549",
"subsys_port_id": 0,
"traddr": "100.71.103.48",
"trflags": 0x0000,
"trsvcid": "4420",
"trtype": "tcp",
},
{
"asqsz": 0,
"cipeec": 0,
"controller_id": 4166,
"data_digest_required": False,
"cto": 0,
"flags": 0x0051,
"hfi_indexes": [0],
"naed": 0,
"nceec": 0,
"nid": "c82404ed9c15f53b8ccf0968002e0fca",
"nid_type": "nguid",
"nsid": 148,
"pdu_header_digest_required": False,
"subsys_nqn": "nqn.1988-11.com.dell:powerstore:00:2a64abf1c5b81F6C4549",
"subsys_port_id": 0,
"traddr": "100.71.103.49",
"trflags": 0x0000,
"trsvcid": "4420",
"trtype": "tcp",
},
Expand Down
6 changes: 3 additions & 3 deletions libnvme/src/nvme/fabrics.c
Original file line number Diff line number Diff line change
Expand Up @@ -3088,7 +3088,7 @@ static int nbft_connect(struct libnvme_global_ctx *ctx,
return ret;

/* Pause logging for unavailable SSNSs */
if (ss && ss->unavailable && saved_log_level < 1)
if (ss && (ss->flags & NBFT_SSNS_UNAVAIL_NAMESPACE_UNAVAIL) && saved_log_level < 1)
libnvme_set_logging_level(ctx, -1, false, false);

/* Update tls or concat */
Expand All @@ -3097,7 +3097,7 @@ static int nbft_connect(struct libnvme_global_ctx *ctx,
ret = libnvmf_add_ctrl(h, c);

/* Resume logging */
if (ss && ss->unavailable && saved_log_level < 1)
if (ss && (ss->flags & NBFT_SSNS_UNAVAIL_NAMESPACE_UNAVAIL) && saved_log_level < 1)
libnvme_set_logging_level(ctx,
saved_log_level,
saved_log_pid,
Expand All @@ -3109,7 +3109,7 @@ static int nbft_connect(struct libnvme_global_ctx *ctx,
* In case this SSNS was marked as 'unavailable' and
* our connection attempt has failed, ignore it.
*/
if (ss && ss->unavailable) {
if (ss && (ss->flags & NBFT_SSNS_UNAVAIL_NAMESPACE_UNAVAIL)) {
libnvme_msg(ctx, LIBNVME_LOG_INFO,
"SSNS %d reported as unavailable, skipping\n",
ss->index);
Expand Down
83 changes: 59 additions & 24 deletions libnvme/src/nvme/nbft.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,10 +161,13 @@ static struct libnbft_security *security_from_index(struct libnbft_info *nbft,

static int read_ssns_exended_info(struct libnvme_global_ctx *ctx,
struct libnbft_info *nbft, struct libnbft_subsystem_ns *ssns,
struct nbft_ssns_ext_info *raw_ssns_ei)
struct nbft_ssns_ext_info *raw_ssns_ei, __u16 descriptor_len)
{
struct nbft_header *header = (struct nbft_header *)nbft->raw_nbft;

/* Verify minimum size of the NBFT rev. 1.0 ssns_ext_info structure */
verify(ctx, descriptor_len >= offsetof(struct nbft_ssns_ext_info, naed),
"SSNS extended info descriptor too short");
verify(ctx, raw_ssns_ei->structure_id == NBFT_DESC_SSNS_EXT_INFO,
"invalid ID in SSNS extended info descriptor");
verify(ctx, raw_ssns_ei->version == 1,
Expand All @@ -181,6 +184,14 @@ static int read_ssns_exended_info(struct libnvme_global_ctx *ctx,
get_heap_obj(ctx, raw_ssns_ei, dhcp_root_path_str_obj, 1,
&ssns->dhcp_root_path_string);

/* NBFT rev. 1.1 structure fields */
if (descriptor_len >= sizeof(struct nbft_ssns_ext_info)) {
ssns->naed = raw_ssns_ei->naed;
ssns->cipeec = raw_ssns_ei->cipeec;
ssns->cto = le16_to_cpu(raw_ssns_ei->cto);
ssns->nceec = raw_ssns_ei->nceec;
}

return 0;
}

Expand Down Expand Up @@ -213,14 +224,7 @@ static int read_ssns(struct libnvme_global_ctx *ctx,
sizeof(ssns->transport));

/* transport specific flags */
if (raw_ssns->trtype == NBFT_TRTYPE_TCP) {
if (le16_to_cpu(raw_ssns->trflags) &
NBFT_SSNS_PDU_HEADER_DIGEST)
ssns->pdu_header_digest_required = true;
if (le16_to_cpu(raw_ssns->trflags) &
NBFT_SSNS_DATA_DIGEST)
ssns->data_digest_required = true;
}
ssns->trflags = le16_to_cpu(raw_ssns->trflags);

/* primary discovery controller */
if (raw_ssns->primary_discovery_ctrl_index) {
Expand Down Expand Up @@ -254,10 +258,7 @@ static int read_ssns(struct libnvme_global_ctx *ctx,
ssns->nid = raw_ssns->nid;

/* flags */
ssns->unavailable = !!(le16_to_cpu(raw_ssns->flags) &
NBFT_SSNS_UNAVAIL_NAMESPACE_UNAVAIL);
ssns->discovered = !!(le16_to_cpu(raw_ssns->flags) &
NBFT_SSNS_DISCOVERED_NAMESPACE);
ssns->flags = le16_to_cpu(raw_ssns->flags);

/* security profile */
if (raw_ssns->security_desc_index) {
Expand Down Expand Up @@ -337,7 +338,8 @@ static int read_ssns(struct libnvme_global_ctx *ctx,
if (!get_heap_obj(ctx, raw_ssns, ssns_extended_info_desc_obj,
0, (char **)&ssns_extended_info)) {
read_ssns_exended_info(ctx, nbft, ssns,
ssns_extended_info);
ssns_extended_info,
le16_to_cpu(raw_ssns->ssns_extended_info_desc_obj.length));
}
}

Expand All @@ -349,6 +351,35 @@ static int read_ssns(struct libnvme_global_ctx *ctx,
return ret;
}

static void read_hfi_info_dhcp(struct libnvme_global_ctx *ctx,
struct libnbft_info *nbft,
struct nbft_hfi_info_ext *hfi_ext_info,
struct libnbft_hfi *hfi)
{
struct nbft_header *header = (struct nbft_header *)nbft->raw_nbft;
char *iaid_raw = NULL;
char *duid_raw = NULL;
__u16 duid_len;

if (hfi_ext_info->structure_id != NBFT_DESC_HFI_EXT_INFO ||
hfi_ext_info->version != 1)
return;
if (!(le32_to_cpu(hfi_ext_info->flags) & NBFT_HFI_INFO_EXT_VALID))
return;
if (!(le32_to_cpu(hfi_ext_info->flags) & NBFT_HFI_INFO_EXT_DCI))
return;

if (!get_heap_obj(ctx, hfi_ext_info, dhcp_iaid_obj, 0, &iaid_raw))
hfi->tcp_info.dhcp_iaid = le32_to_cpu(*(__le32 *)iaid_raw);
if (!get_heap_obj(ctx, hfi_ext_info, dhcp_duid_obj, 0, &duid_raw)) {
duid_len = le16_to_cpu(hfi_ext_info->dhcp_duid_obj.length);
if (duid_len > sizeof(hfi->tcp_info.dhcp_duid))
duid_len = sizeof(hfi->tcp_info.dhcp_duid);
memcpy(hfi->tcp_info.dhcp_duid, duid_raw, duid_len);
hfi->tcp_info.dhcp_duid_len = duid_len;
}
}

static int read_hfi_info_tcp(struct libnvme_global_ctx *ctx,
struct libnbft_info *nbft,
struct nbft_hfi_info_tcp *raw_hfi_info_tcp,
Expand Down Expand Up @@ -386,16 +417,23 @@ static int read_hfi_info_tcp(struct libnvme_global_ctx *ctx,
format_ip_addr(hfi->tcp_info.secondary_dns_ipaddr,
sizeof(hfi->tcp_info.secondary_dns_ipaddr),
raw_hfi_info_tcp->secondary_dns);
if (raw_hfi_info_tcp->flags & NBFT_HFI_INFO_TCP_DHCP_OVERRIDE) {
hfi->tcp_info.dhcp_override = true;
hfi->tcp_info.flags = raw_hfi_info_tcp->flags;
if (raw_hfi_info_tcp->flags & NBFT_HFI_INFO_TCP_DHCP_OVERRIDE)
format_ip_addr(hfi->tcp_info.dhcp_server_ipaddr,
sizeof(hfi->tcp_info.dhcp_server_ipaddr),
raw_hfi_info_tcp->dhcp_server);
}
get_heap_obj(ctx, raw_hfi_info_tcp, host_name_obj,
1, &hfi->tcp_info.host_name);
if (raw_hfi_info_tcp->flags & NBFT_HFI_INFO_TCP_GLOBAL_ROUTE)
hfi->tcp_info.this_hfi_is_default_route = true;

if (raw_hfi_info_tcp->trinfo_version >= 2) {
struct nbft_hfi_info_ext *hfi_ext_info;

hfi->tcp_info.pcie_seg_num = raw_hfi_info_tcp->pcie_seg_num;

if (!get_heap_obj(ctx, raw_hfi_info_tcp, hfi_ext_info_obj,
0, (char **)&hfi_ext_info))
read_hfi_info_dhcp(ctx, nbft, hfi_ext_info, hfi);
}

return 0;
}
Expand Down Expand Up @@ -603,7 +641,7 @@ static int parse_raw_nbft(struct libnvme_global_ctx *ctx, struct libnbft_info *n
"length in header exceeds table length");
verify(ctx, header->major_revision == 1,
"unsupported major revision");
verify(ctx, header->minor_revision == 0,
verify(ctx, header->minor_revision <= 1,
"unsupported minor revision");
verify(ctx, le32_to_cpu(header->heap_length) +
le32_to_cpu(header->heap_offset) <= le32_to_cpu(header->length),
Expand Down Expand Up @@ -637,10 +675,7 @@ static int parse_raw_nbft(struct libnvme_global_ctx *ctx, struct libnbft_info *n
nbft->host.id = (unsigned char *) &(host->host_id);
if (get_heap_obj(ctx, host, host_nqn_obj, 1, &nbft->host.nqn) != 0)
return -EINVAL;
nbft->host.host_id_configured =
host->flags & NBFT_HOST_HOSTID_CONFIGURED;
nbft->host.host_nqn_configured =
host->flags & NBFT_HOST_HOSTNQN_CONFIGURED;
nbft->host.flags = host->flags;

/*
* HFI
Expand Down
Loading
Loading