git: 9f0f30bc1f5f - main - libnvmf: Add nvmf_nqn_valid_strict() function
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 28 Jul 2025 18:33:39 UTC
The branch main has been updated by jhb:
URL: https://cgit.FreeBSD.org/src/commit/?id=9f0f30bc1f5f08d25243952bad3fdc6e13a75c2a
commit 9f0f30bc1f5f08d25243952bad3fdc6e13a75c2a
Author: John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2025-07-28 18:33:03 +0000
Commit: John Baldwin <jhb@FreeBSD.org>
CommitDate: 2025-07-28 18:33:03 +0000
libnvmf: Add nvmf_nqn_valid_strict() function
This moves the checks previously under #ifdef STRICT in
nvmf_nqn_valid() into a separate helper for userland. This
requires that the NQN starts with "nqn.YYYY-MM." followed by at
least one additional character.
Reviewed by: asomers
Differential Revision: https://reviews.freebsd.org/D48767
---
lib/libnvmf/libnvmf.h | 7 ++++-
lib/libnvmf/nvmf_controller.c | 50 ++++++++++++++++++++++++++++++++++++
sys/dev/nvmf/controller/nvmft_subr.c | 40 -----------------------------
3 files changed, 56 insertions(+), 41 deletions(-)
diff --git a/lib/libnvmf/libnvmf.h b/lib/libnvmf/libnvmf.h
index 7cdd7e433455..6b38fd286596 100644
--- a/lib/libnvmf/libnvmf.h
+++ b/lib/libnvmf/libnvmf.h
@@ -111,8 +111,13 @@ const void *nvmf_capsule_cqe(const struct nvmf_capsule *nc);
/* Return a string name for a transport type. */
const char *nvmf_transport_type(uint8_t trtype);
-/* Validate a NVMe Qualified Name. */
+/*
+ * Validate a NVMe Qualified Name. The second version enforces
+ * stricter checks inline with the specification. The first version
+ * enforces more minimal checks.
+ */
bool nvmf_nqn_valid(const char *nqn);
+bool nvmf_nqn_valid_strict(const char *nqn);
/* Controller-specific APIs. */
diff --git a/lib/libnvmf/nvmf_controller.c b/lib/libnvmf/nvmf_controller.c
index 971dccbe039e..f26f11633e03 100644
--- a/lib/libnvmf/nvmf_controller.c
+++ b/lib/libnvmf/nvmf_controller.c
@@ -7,6 +7,7 @@
#include <sys/utsname.h>
#include <assert.h>
+#include <ctype.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
@@ -15,6 +16,55 @@
#include "internal.h"
#include "nvmft_subr.h"
+bool
+nvmf_nqn_valid_strict(const char *nqn)
+{
+ size_t len;
+
+ if (!nvmf_nqn_valid(nqn))
+ return (false);
+
+ /*
+ * Stricter checks from the spec. Linux does not seem to
+ * require these.
+ */
+ len = strlen(nqn);
+
+ /*
+ * NVMF_NQN_MIN_LEN does not include '.' and require at least
+ * one character of a domain name.
+ */
+ if (len < NVMF_NQN_MIN_LEN + 2)
+ return (false);
+ if (memcmp("nqn.", nqn, strlen("nqn.")) != 0)
+ return (false);
+ nqn += strlen("nqn.");
+
+ /* Next 4 digits must be a year. */
+ for (u_int i = 0; i < 4; i++) {
+ if (!isdigit(nqn[i]))
+ return (false);
+ }
+ nqn += 4;
+
+ /* '-' between year and month. */
+ if (nqn[0] != '-')
+ return (false);
+ nqn++;
+
+ /* 2 digit month. */
+ for (u_int i = 0; i < 2; i++) {
+ if (!isdigit(nqn[i]))
+ return (false);
+ }
+ nqn += 2;
+
+ /* '.' between month and reverse domain name. */
+ if (nqn[0] != '.')
+ return (false);
+ return (true);
+}
+
void
nvmf_init_cqe(void *cqe, const struct nvmf_capsule *nc, uint16_t status)
{
diff --git a/sys/dev/nvmf/controller/nvmft_subr.c b/sys/dev/nvmf/controller/nvmft_subr.c
index bb2bc0988e81..245971813854 100644
--- a/sys/dev/nvmf/controller/nvmft_subr.c
+++ b/sys/dev/nvmf/controller/nvmft_subr.c
@@ -26,46 +26,6 @@ nvmf_nqn_valid(const char *nqn)
len = strnlen(nqn, NVME_NQN_FIELD_SIZE);
if (len == 0 || len > NVMF_NQN_MAX_LEN)
return (false);
-
-#ifdef STRICT_CHECKS
- /*
- * Stricter checks from the spec. Linux does not seem to
- * require these.
- */
-
- /*
- * NVMF_NQN_MIN_LEN does not include '.', and require at least
- * one character of a domain name.
- */
- if (len < NVMF_NQN_MIN_LEN + 2)
- return (false);
- if (memcmp("nqn.", nqn, strlen("nqn.")) != 0)
- return (false);
- nqn += strlen("nqn.");
-
- /* Next 4 digits must be a year. */
- for (u_int i = 0; i < 4; i++) {
- if (!isdigit(nqn[i]))
- return (false);
- }
- nqn += 4;
-
- /* '-' between year and month. */
- if (nqn[0] != '-')
- return (false);
- nqn++;
-
- /* 2 digit month. */
- for (u_int i = 0; i < 2; i++) {
- if (!isdigit(nqn[i]))
- return (false);
- }
- nqn += 2;
-
- /* '.' between month and reverse domain name. */
- if (nqn[0] != '.')
- return (false);
-#endif
return (true);
}