* [PATCH iproute2-next 1/3] uapi: import nsfs.h from last sync point
2026-09-23 16:17 [PATCH iproute2-next 0/3] ip: netns: report the network namespace cookie Ido Schimmel
@ 2026-09-23 16:17 ` Ido Schimmel
2026-09-23 16:17 ` [PATCH iproute2-next 2/3] ip: netns: report the network namespace cookie Ido Schimmel
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Ido Schimmel @ 2026-09-23 16:17 UTC (permalink / raw)
To: netdev; +Cc: dsahern, stephen, petrm, daniel, ferenc, Ido Schimmel
Import include/uapi/linux/nsfs.h from kernel commit 69963a0678a3 ("Merge
branch 'add-support-for-rtl8261c-d'"), the commit the headers were last
synced to. The header defines the NS_GET_ID ioctl which will be used by
a subsequent patch to retrieve the cookie of a network namespace.
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
include/uapi/linux/nsfs.h | 122 ++++++++++++++++++++++++++++++++++++++
1 file changed, 122 insertions(+)
create mode 100644 include/uapi/linux/nsfs.h
diff --git a/include/uapi/linux/nsfs.h b/include/uapi/linux/nsfs.h
new file mode 100644
index 000000000000..96bd591feb67
--- /dev/null
+++ b/include/uapi/linux/nsfs.h
@@ -0,0 +1,122 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef __LINUX_NSFS_H
+#define __LINUX_NSFS_H
+
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+#define NSIO 0xb7
+
+/* Returns a file descriptor that refers to an owning user namespace */
+#define NS_GET_USERNS _IO(NSIO, 0x1)
+/* Returns a file descriptor that refers to a parent namespace */
+#define NS_GET_PARENT _IO(NSIO, 0x2)
+/* Returns the type of namespace (CLONE_NEW* value) referred to by
+ file descriptor */
+#define NS_GET_NSTYPE _IO(NSIO, 0x3)
+/* Get owner UID (in the caller's user namespace) for a user namespace */
+#define NS_GET_OWNER_UID _IO(NSIO, 0x4)
+/* Translate pid from target pid namespace into the caller's pid namespace. */
+#define NS_GET_PID_FROM_PIDNS _IOR(NSIO, 0x6, int)
+/* Return thread-group leader id of pid in the callers pid namespace. */
+#define NS_GET_TGID_FROM_PIDNS _IOR(NSIO, 0x7, int)
+/* Translate pid from caller's pid namespace into a target pid namespace. */
+#define NS_GET_PID_IN_PIDNS _IOR(NSIO, 0x8, int)
+/* Return thread-group leader id of pid in the target pid namespace. */
+#define NS_GET_TGID_IN_PIDNS _IOR(NSIO, 0x9, int)
+
+struct mnt_ns_info {
+ __u32 size;
+ __u32 nr_mounts;
+ __u64 mnt_ns_id;
+};
+
+#define MNT_NS_INFO_SIZE_VER0 16 /* size of first published struct */
+
+/* Get information about namespace. */
+#define NS_MNT_GET_INFO _IOR(NSIO, 10, struct mnt_ns_info)
+/* Get next namespace. */
+#define NS_MNT_GET_NEXT _IOR(NSIO, 11, struct mnt_ns_info)
+/* Get previous namespace. */
+#define NS_MNT_GET_PREV _IOR(NSIO, 12, struct mnt_ns_info)
+
+/* Retrieve namespace identifiers. */
+#define NS_GET_MNTNS_ID _IOR(NSIO, 5, __u64)
+#define NS_GET_ID _IOR(NSIO, 13, __u64)
+
+enum init_ns_ino {
+ IPC_NS_INIT_INO = 0xEFFFFFFFU,
+ UTS_NS_INIT_INO = 0xEFFFFFFEU,
+ USER_NS_INIT_INO = 0xEFFFFFFDU,
+ PID_NS_INIT_INO = 0xEFFFFFFCU,
+ CGROUP_NS_INIT_INO = 0xEFFFFFFBU,
+ TIME_NS_INIT_INO = 0xEFFFFFFAU,
+ NET_NS_INIT_INO = 0xEFFFFFF9U,
+ MNT_NS_INIT_INO = 0xEFFFFFF8U,
+};
+
+struct nsfs_file_handle {
+ __u64 ns_id;
+ __u32 ns_type;
+ __u32 ns_inum;
+};
+
+#define NSFS_FILE_HANDLE_SIZE_VER0 16 /* sizeof first published struct */
+#define NSFS_FILE_HANDLE_SIZE_LATEST sizeof(struct nsfs_file_handle) /* sizeof latest published struct */
+
+enum init_ns_id {
+ IPC_NS_INIT_ID = 1ULL,
+ UTS_NS_INIT_ID = 2ULL,
+ USER_NS_INIT_ID = 3ULL,
+ PID_NS_INIT_ID = 4ULL,
+ CGROUP_NS_INIT_ID = 5ULL,
+ TIME_NS_INIT_ID = 6ULL,
+ NET_NS_INIT_ID = 7ULL,
+ MNT_NS_INIT_ID = 8ULL,
+};
+
+enum ns_type {
+ TIME_NS = (1ULL << 7), /* CLONE_NEWTIME */
+ MNT_NS = (1ULL << 17), /* CLONE_NEWNS */
+ CGROUP_NS = (1ULL << 25), /* CLONE_NEWCGROUP */
+ UTS_NS = (1ULL << 26), /* CLONE_NEWUTS */
+ IPC_NS = (1ULL << 27), /* CLONE_NEWIPC */
+ USER_NS = (1ULL << 28), /* CLONE_NEWUSER */
+ PID_NS = (1ULL << 29), /* CLONE_NEWPID */
+ NET_NS = (1ULL << 30), /* CLONE_NEWNET */
+};
+
+/**
+ * struct ns_id_req - namespace ID request structure
+ * @size: size of this structure
+ * @spare: reserved for future use
+ * @filter: filter mask
+ * @ns_id: last namespace id
+ * @user_ns_id: owning user namespace ID
+ *
+ * Structure for passing namespace ID and miscellaneous parameters to
+ * statns(2) and listns(2).
+ *
+ * For statns(2) @param represents the request mask.
+ * For listns(2) @param represents the last listed mount id (or zero).
+ */
+struct ns_id_req {
+ __u32 size;
+ __u32 spare;
+ __u64 ns_id;
+ struct /* listns */ {
+ __u32 ns_type;
+ __u32 spare2;
+ __u64 user_ns_id;
+ };
+};
+
+/*
+ * Special @user_ns_id value that can be passed to listns()
+ */
+#define LISTNS_CURRENT_USER 0xffffffffffffffff /* Caller's userns */
+
+/* List of all ns_id_req versions. */
+#define NS_ID_REQ_SIZE_VER0 32 /* sizeof first published struct */
+
+#endif /* __LINUX_NSFS_H */
--
2.55.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH iproute2-next 2/3] ip: netns: report the network namespace cookie
2026-09-23 16:17 [PATCH iproute2-next 0/3] ip: netns: report the network namespace cookie Ido Schimmel
2026-09-23 16:17 ` [PATCH iproute2-next 1/3] uapi: import nsfs.h from last sync point Ido Schimmel
@ 2026-09-23 16:17 ` Ido Schimmel
2026-09-23 16:17 ` [PATCH iproute2-next 3/3] ip: netns: add "ip netns cookie" command Ido Schimmel
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Ido Schimmel @ 2026-09-23 16:17 UTC (permalink / raw)
To: netdev; +Cc: dsahern, stephen, petrm, daniel, ferenc, Ido Schimmel
The kernel identifies a network namespace by a 64-bit cookie that is
assigned when the namespace is created and never changes. User space can
query the cookie using the SO_NETNS_COOKIE socket option and since Linux
6.18, the cookie is also the generic namespace ID and can be retrieved
via the NS_GET_ID ioctl on a network namespace file descriptor.
Report the cookie in "ip netns list". In JSON mode it is always
reported. In plain text mode it is only reported when details are
requested ("-d") to avoid breaking scripts that rely on the current
output format:
# ip netns add red
# ip netns add blue
# ip netns list
blue
red
# ip -d netns list
blue (cookie: 12)
red (cookie: 11)
# ip -j netns list
[{"name":"blue","cookie":12},{"name":"red","cookie":11}]
The cookie is not reported on kernels that do not support the NS_GET_ID
ioctl:
# uname -r
6.12.109-virtme-g39a867754a8a
# ip netns add red
# ip netns add blue
# ip -d netns list
blue
red
# ip -j netns list
[{"name":"blue"},{"name":"red"}]
The new functionality can be used to filter networking events that occur
in a specific network namespace:
# perf record -a -e net:net_dev_xmit --filter 'net_cookie == 12'
Assisted-by: LLM
Reviewed-by: Petr Machata <petrm@nvidia.com>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
ip/ipnetns.c | 25 +++++++++++++++++++++++++
man/man8/ip-netns.8.in | 14 +++++++++++++-
2 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/ip/ipnetns.c b/ip/ipnetns.c
index 587534ae016b..b62d2b0f57bf 100644
--- a/ip/ipnetns.c
+++ b/ip/ipnetns.c
@@ -16,8 +16,10 @@
#include <sys/stat.h>
#include <sys/inotify.h>
#include <sys/mount.h>
+#include <sys/ioctl.h>
#include <linux/net_namespace.h>
+#include <linux/nsfs.h>
#include "utils.h"
#include "list.h"
@@ -444,9 +446,26 @@ static int netns_list_id(int argc, char **argv)
return 0;
}
+static int netns_get_cookie(const char *name, __u64 *cookie)
+{
+ char net_path[PATH_MAX];
+ int fd, ret;
+
+ snprintf(net_path, sizeof(net_path), "%s/%s", NETNS_RUN_DIR, name);
+ fd = open(net_path, O_RDONLY);
+ if (fd < 0)
+ return -1;
+
+ ret = ioctl(fd, NS_GET_ID, cookie);
+ close(fd);
+
+ return ret;
+}
+
static int netns_list(int argc, char **argv)
{
struct dirent *entry;
+ __u64 cookie;
DIR *dir;
int id;
@@ -469,6 +488,12 @@ static int netns_list(int argc, char **argv)
if (id >= 0)
print_int(PRINT_ANY, "id", " (id: %d)", id);
}
+ if (netns_get_cookie(entry->d_name, &cookie) == 0) {
+ print_u64(PRINT_JSON, "cookie", NULL, cookie);
+ if (show_details)
+ print_u64(PRINT_FP, NULL, " (cookie: %llu)",
+ cookie);
+ }
print_string(PRINT_FP, NULL, "\n", NULL);
close_json_object();
}
diff --git a/man/man8/ip-netns.8.in b/man/man8/ip-netns.8.in
index 2e12e28bbb2f..597a2602b32c 100644
--- a/man/man8/ip-netns.8.in
+++ b/man/man8/ip-netns.8.in
@@ -89,7 +89,19 @@ their traditional location in /etc.
.TP
.B ip netns list - show all of the named network namespaces
.sp
-This command displays all of the network namespaces in @NETNS_RUN_DIR@
+This command displays all of the network namespaces in @NETNS_RUN_DIR@.
+If the
+.B -details
+option is specified, the cookie of each network namespace is also
+displayed. The cookie is a 64-bit identifier that the kernel assigns to
+a network namespace when it is created and that never changes. Unlike
+the nsid, it is not relative to a peer network namespace. It is the same
+value that is reported by the
+.B SO_NETNS_COOKIE
+socket option and by trace events that identify a network namespace.
+The cookie is only displayed on kernels that support the
+.B NS_GET_ID
+ioctl (Linux 6.18 and later).
.TP
.B ip netns add NAME - create a new named network namespace
--
2.55.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH iproute2-next 3/3] ip: netns: add "ip netns cookie" command
2026-09-23 16:17 [PATCH iproute2-next 0/3] ip: netns: report the network namespace cookie Ido Schimmel
2026-09-23 16:17 ` [PATCH iproute2-next 1/3] uapi: import nsfs.h from last sync point Ido Schimmel
2026-09-23 16:17 ` [PATCH iproute2-next 2/3] ip: netns: report the network namespace cookie Ido Schimmel
@ 2026-09-23 16:17 ` Ido Schimmel
2026-09-23 21:10 ` [PATCH iproute2-next 0/3] ip: netns: report the network namespace cookie patchwork-bot+netdevbpf
2026-09-24 5:30 ` GMail
4 siblings, 0 replies; 6+ messages in thread
From: Ido Schimmel @ 2026-09-23 16:17 UTC (permalink / raw)
To: netdev; +Cc: dsahern, stephen, petrm, daniel, ferenc, Ido Schimmel
"ip netns list" only reports named network namespaces, i.e., those that
are bind mounted under /var/run/netns. Network namespaces created by
container runtimes are usually not named, but there is still a need to
retrieve their cookie, for example, in order to correlate the records
in a trace to a container.
Add a command that reports the cookie of a single network namespace,
referenced either by name or by the PID of a process running in it. If
neither is specified, the cookie of the current network namespace is
reported:
# ip netns add red
# ip netns cookie red
11
# ip -j netns cookie red
[{"cookie":11}]
# ip netns exec red ip netns cookie
11
# ip netns cookie $$
7
# ip netns cookie
7
An error is returned when the kernel does not support the NS_GET_ID
ioctl:
# uname -r
6.12.109-virtme-g39a867754a8a
# ip netns add red
# ip netns cookie red
Cannot get cookie of network namespace "red": Inappropriate ioctl for device
Assisted-by: LLM
Reviewed-by: Petr Machata <petrm@nvidia.com>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
ip/ipnetns.c | 46 ++++++++++++++++++++++++++++++++++++++++++
man/man8/ip-netns.8.in | 16 +++++++++++++++
2 files changed, 62 insertions(+)
diff --git a/ip/ipnetns.c b/ip/ipnetns.c
index b62d2b0f57bf..165317b14c1c 100644
--- a/ip/ipnetns.c
+++ b/ip/ipnetns.c
@@ -36,6 +36,7 @@ static int usage(void)
" ip [-all] netns delete [NAME]\n"
" ip netns identify [PID]\n"
" ip netns pids NAME\n"
+ " ip netns cookie [NAME | PID]\n"
" ip [-all] netns exec [NAME] cmd ...\n"
" ip netns monitor\n"
" ip netns list-id [target-nsid POSITIVE-INT] [nsid POSITIVE-INT]\n"
@@ -710,6 +711,48 @@ static int netns_identify(int argc, char **argv)
return rc;
}
+static int netns_cookie(int argc, char **argv)
+{
+ const char *str;
+ __u64 cookie;
+ int fd;
+
+ if (argc > 1) {
+ fprintf(stderr, "extra arguments specified\n");
+ return -1;
+ }
+
+ if (argc == 1) {
+ str = argv[0];
+ fd = netns_get_fd(str);
+ } else {
+ str = "/proc/self/ns/net";
+ fd = open(str, O_RDONLY);
+ }
+ if (fd < 0) {
+ fprintf(stderr, "Cannot open network namespace \"%s\": %s\n",
+ str, strerror(errno));
+ return -1;
+ }
+
+ if (ioctl(fd, NS_GET_ID, &cookie) < 0) {
+ fprintf(stderr,
+ "Cannot get cookie of network namespace \"%s\": %s\n",
+ str, strerror(errno));
+ close(fd);
+ return -1;
+ }
+ close(fd);
+
+ new_json_obj(json);
+ open_json_object(NULL);
+ print_u64(PRINT_ANY, "cookie", "%llu\n", cookie);
+ close_json_object();
+ delete_json_obj();
+
+ return 0;
+}
+
static int on_netns_del(char *nsname, void *arg)
{
char netns_path[PATH_MAX];
@@ -1055,6 +1098,9 @@ int do_netns(int argc, char **argv)
if (matches(*argv, "pids") == 0)
return netns_pids(argc-1, argv+1);
+ if (strcmp(*argv, "cookie") == 0)
+ return netns_cookie(argc-1, argv+1);
+
if (matches(*argv, "exec") == 0)
return netns_exec(argc-1, argv+1);
diff --git a/man/man8/ip-netns.8.in b/man/man8/ip-netns.8.in
index 597a2602b32c..9b3ad14de677 100644
--- a/man/man8/ip-netns.8.in
+++ b/man/man8/ip-netns.8.in
@@ -42,6 +42,10 @@ ip-netns \- process network namespace management
.BR "ip netns pids"
.I NETNSNAME
+.ti -8
+.BR "ip netns cookie"
+.RI "[ " NETNSNAME " | " PID " ]"
+
.ti -8
.BR "ip [-all] netns exec "
.RI "[ " NETNSNAME " ] " command ...
@@ -182,6 +186,18 @@ not specified then the current process will be used.
This command walks through proc and finds all of the process who have
the named network namespace as their primary network namespace.
+.TP
+.B ip netns cookie [ NETNSNAME | PID ] - Report the cookie of a network namespace
+.sp
+This command displays the cookie of the named network namespace or of
+the network namespace of the process PID. If neither is specified, the
+cookie of the current network namespace is displayed. See
+.B ip netns list
+for a description of the cookie. Unlike
+.BR "ip netns list" ,
+this command can also be used with network namespaces that are not
+named, such as those created by container runtimes.
+
.TP
.B ip [-all] netns exec [ NAME ] cmd ... - Run cmd in the named network namespace
.sp
--
2.55.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [PATCH iproute2-next 0/3] ip: netns: report the network namespace cookie
2026-09-23 16:17 [PATCH iproute2-next 0/3] ip: netns: report the network namespace cookie Ido Schimmel
` (2 preceding siblings ...)
2026-09-23 16:17 ` [PATCH iproute2-next 3/3] ip: netns: add "ip netns cookie" command Ido Schimmel
@ 2026-09-23 21:10 ` patchwork-bot+netdevbpf
2026-09-24 5:30 ` GMail
4 siblings, 0 replies; 6+ messages in thread
From: patchwork-bot+netdevbpf @ 2026-09-23 21:10 UTC (permalink / raw)
To: Ido Schimmel; +Cc: netdev, dsahern, stephen, petrm, daniel, ferenc
Hello:
This series was applied to iproute2/iproute2-next.git (main)
by David Ahern <dsahern@kernel.org>:
On Wed, 23 Sep 2026 19:17:53 +0300 you wrote:
> The kernel identifies a network namespace by a 64-bit cookie that is
> assigned when the namespace is created and never changes.
>
> The cookie is reported by a growing number of trace events such as the
> TCP-MD5 and TCP-AO events and the net device events (e.g.,
> net:net_dev_xmit). This allows filtering events that occur in a specific
> network namespace, for example:
>
> [...]
Here is the summary with links:
- [iproute2-next,1/3] uapi: import nsfs.h from last sync point
(no matching commit)
- [iproute2-next,2/3] ip: netns: report the network namespace cookie
https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=f49fa3143008
- [iproute2-next,3/3] ip: netns: add "ip netns cookie" command
https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=07a6444c127e
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH iproute2-next 0/3] ip: netns: report the network namespace cookie
2026-09-23 16:17 [PATCH iproute2-next 0/3] ip: netns: report the network namespace cookie Ido Schimmel
` (3 preceding siblings ...)
2026-09-23 21:10 ` [PATCH iproute2-next 0/3] ip: netns: report the network namespace cookie patchwork-bot+netdevbpf
@ 2026-09-24 5:30 ` GMail
4 siblings, 0 replies; 6+ messages in thread
From: GMail @ 2026-09-24 5:30 UTC (permalink / raw)
To: Ido Schimmel, netdev; +Cc: dsahern, stephen, petrm, daniel, ferenc
On Wed, 2026-09-23 at 19:17 +0300, Ido Schimmel wrote:
> The kernel identifies a network namespace by a 64-bit cookie that is
> assigned when the namespace is created and never changes.
>
> The cookie is reported by a growing number of trace events such as
> the
> TCP-MD5 and TCP-AO events and the net device events (e.g.,
> net:net_dev_xmit). This allows filtering events that occur in a
> specific
> network namespace, for example:
>
> # perf record -a -e net:net_dev_xmit --filter 'net_cookie == 12'
>
> It is also available to tracing BPF programs that can access
> 'net_cookie' in 'struct net'.
>
> However, no utility currently reports the cookie of a given network
> namespace, so mapping a cookie in a trace to a namespace requires a
> custom program that calls getsockopt(SO_NETNS_COOKIE) from within the
> namespace.
>
> Since Linux 6.18, the cookie is also the generic namespace ID and can
> be
> retrieved via the NS_GET_ID ioctl on a network namespace file
> descriptor. Unlike SO_NETNS_COOKIE, this does not require entering
> the
> namespace, so the cookie of any namespace whose file can be opened
> can
> be retrieved without privileges. A kernel selftest [1] ensures that
> both
> interfaces report the same value for a given network namespace.
>
> This patchset extends ip-netns to display the network namespace
> cookie.
Super useful, thank you!
>
> Patch #1 imports the nsfs.h header that defines the NS_GET_ID ioctl.
>
> Patch #2 reports the cookie in "ip netns list". It is always reported
> in
> JSON mode and only reported with "-d" in plain text mode to avoid
> breaking scripts that rely on the current output format.
>
> Patch #3 adds "ip netns cookie [ NETNSNAME | PID ]" to report the
> cookie
> of a single network namespace, including namespaces that are not bind
> mounted under /var/run/netns, such as those created by container
> runtimes.
>
> [1] nsid_netns_basic in
> tools/testing/selftests/namespaces/nsid_test.c
>
> Ido Schimmel (3):
> uapi: import nsfs.h from last sync point
> ip: netns: report the network namespace cookie
> ip: netns: add "ip netns cookie" command
>
> include/uapi/linux/nsfs.h | 122
> ++++++++++++++++++++++++++++++++++++++
> ip/ipnetns.c | 71 ++++++++++++++++++++++
> man/man8/ip-netns.8.in | 30 +++++++++-
> 3 files changed, 222 insertions(+), 1 deletion(-)
> create mode 100644 include/uapi/linux/nsfs.h
Ferenc
^ permalink raw reply [flat|nested] 6+ messages in thread