* [PATCH bpf-next v3 1/4] net: add SO_NETNS_COOKIE socket option
2021-02-19 15:43 [PATCH bpf-next v3 0/4] Expose network namespace cookies to user space Lorenz Bauer
@ 2021-02-19 15:43 ` Lorenz Bauer
2021-02-19 15:43 ` [PATCH bpf-next v3 2/4] nsfs: add an ioctl to discover the network namespace cookie Lorenz Bauer
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Lorenz Bauer @ 2021-02-19 15:43 UTC (permalink / raw)
To: eric.dumazet, daniel, ast, andrii; +Cc: bpf, netdev, kernel-team, Lorenz Bauer
We need to distinguish which network namespace a socket belongs to.
BPF has the useful bpf_get_netns_cookie helper for this, but accessing
it from user space isn't possible. Add a read-only socket option that
returns the netns cookie, similar to SO_COOKIE. If network namespaces
are disabled, SO_NETNS_COOKIE returns the cookie of init_net.
Signed-off-by: Lorenz Bauer <lmb@cloudflare.com>
---
arch/alpha/include/uapi/asm/socket.h | 2 ++
arch/mips/include/uapi/asm/socket.h | 2 ++
arch/parisc/include/uapi/asm/socket.h | 2 ++
arch/sparc/include/uapi/asm/socket.h | 2 ++
include/uapi/asm-generic/socket.h | 2 ++
net/core/sock.c | 7 +++++++
6 files changed, 17 insertions(+)
diff --git a/arch/alpha/include/uapi/asm/socket.h b/arch/alpha/include/uapi/asm/socket.h
index 57420356ce4c..6b3daba60987 100644
--- a/arch/alpha/include/uapi/asm/socket.h
+++ b/arch/alpha/include/uapi/asm/socket.h
@@ -127,6 +127,8 @@
#define SO_PREFER_BUSY_POLL 69
#define SO_BUSY_POLL_BUDGET 70
+#define SO_NETNS_COOKIE 71
+
#if !defined(__KERNEL__)
#if __BITS_PER_LONG == 64
diff --git a/arch/mips/include/uapi/asm/socket.h b/arch/mips/include/uapi/asm/socket.h
index 2d949969313b..cdf404a831b2 100644
--- a/arch/mips/include/uapi/asm/socket.h
+++ b/arch/mips/include/uapi/asm/socket.h
@@ -138,6 +138,8 @@
#define SO_PREFER_BUSY_POLL 69
#define SO_BUSY_POLL_BUDGET 70
+#define SO_NETNS_COOKIE 71
+
#if !defined(__KERNEL__)
#if __BITS_PER_LONG == 64
diff --git a/arch/parisc/include/uapi/asm/socket.h b/arch/parisc/include/uapi/asm/socket.h
index f60904329bbc..5b5351cdcb33 100644
--- a/arch/parisc/include/uapi/asm/socket.h
+++ b/arch/parisc/include/uapi/asm/socket.h
@@ -119,6 +119,8 @@
#define SO_PREFER_BUSY_POLL 0x4043
#define SO_BUSY_POLL_BUDGET 0x4044
+#define SO_NETNS_COOKIE 0x4045
+
#if !defined(__KERNEL__)
#if __BITS_PER_LONG == 64
diff --git a/arch/sparc/include/uapi/asm/socket.h b/arch/sparc/include/uapi/asm/socket.h
index 848a22fbac20..ff79db753dce 100644
--- a/arch/sparc/include/uapi/asm/socket.h
+++ b/arch/sparc/include/uapi/asm/socket.h
@@ -120,6 +120,8 @@
#define SO_PREFER_BUSY_POLL 0x0048
#define SO_BUSY_POLL_BUDGET 0x0049
+#define SO_NETNS_COOKIE 0x004a
+
#if !defined(__KERNEL__)
diff --git a/include/uapi/asm-generic/socket.h b/include/uapi/asm-generic/socket.h
index 4dcd13d097a9..d588c244ec2f 100644
--- a/include/uapi/asm-generic/socket.h
+++ b/include/uapi/asm-generic/socket.h
@@ -122,6 +122,8 @@
#define SO_PREFER_BUSY_POLL 69
#define SO_BUSY_POLL_BUDGET 70
+#define SO_NETNS_COOKIE 71
+
#if !defined(__KERNEL__)
#if __BITS_PER_LONG == 64 || (defined(__x86_64__) && defined(__ILP32__))
diff --git a/net/core/sock.c b/net/core/sock.c
index 0ed98f20448a..84db011a192f 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1614,6 +1614,13 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
v.val = sk->sk_bound_dev_if;
break;
+ case SO_NETNS_COOKIE:
+ lv = sizeof(u64);
+ if (len != lv)
+ return -EINVAL;
+ v.val64 = sock_net(sk)->net_cookie;
+ break;
+
default:
/* We implement the SO_SNDLOWAT etc to not be settable
* (1003.1g 7).
--
2.27.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH bpf-next v3 2/4] nsfs: add an ioctl to discover the network namespace cookie
2021-02-19 15:43 [PATCH bpf-next v3 0/4] Expose network namespace cookies to user space Lorenz Bauer
2021-02-19 15:43 ` [PATCH bpf-next v3 1/4] net: add SO_NETNS_COOKIE socket option Lorenz Bauer
@ 2021-02-19 15:43 ` Lorenz Bauer
2021-02-19 15:43 ` [PATCH bpf-next v3 3/4] tools/testing: add test for NS_GET_COOKIE Lorenz Bauer
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Lorenz Bauer @ 2021-02-19 15:43 UTC (permalink / raw)
To: eric.dumazet, daniel, ast, andrii; +Cc: bpf, netdev, kernel-team, Lorenz Bauer
Network namespaces have a globally unique non-zero identifier aka a
cookie, in line with socket cookies. Add an ioctl to retrieve the
cookie from user space without going via BPF.
Signed-off-by: Lorenz Bauer <lmb@cloudflare.com>
---
fs/nsfs.c | 7 +++++++
include/uapi/linux/nsfs.h | 2 ++
2 files changed, 9 insertions(+)
diff --git a/fs/nsfs.c b/fs/nsfs.c
index 800c1d0eb0d0..48198a1b1685 100644
--- a/fs/nsfs.c
+++ b/fs/nsfs.c
@@ -11,6 +11,7 @@
#include <linux/user_namespace.h>
#include <linux/nsfs.h>
#include <linux/uaccess.h>
+#include <net/net_namespace.h>
#include "internal.h"
@@ -191,6 +192,7 @@ static long ns_ioctl(struct file *filp, unsigned int ioctl,
struct user_namespace *user_ns;
struct ns_common *ns = get_proc_ns(file_inode(filp));
uid_t __user *argp;
+ struct net *net_ns;
uid_t uid;
switch (ioctl) {
@@ -209,6 +211,11 @@ static long ns_ioctl(struct file *filp, unsigned int ioctl,
argp = (uid_t __user *) arg;
uid = from_kuid_munged(current_user_ns(), user_ns->owner);
return put_user(uid, argp);
+ case NS_GET_COOKIE:
+ if (ns->ops->type != CLONE_NEWNET)
+ return -EINVAL;
+ net_ns = container_of(ns, struct net, ns);
+ return put_user(net_ns->net_cookie, (u64 __user *)arg);
default:
return -ENOTTY;
}
diff --git a/include/uapi/linux/nsfs.h b/include/uapi/linux/nsfs.h
index a0c8552b64ee..86611c2cf908 100644
--- a/include/uapi/linux/nsfs.h
+++ b/include/uapi/linux/nsfs.h
@@ -15,5 +15,7 @@
#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)
+/* Returns a unique non-zero identifier for a network namespace */
+#define NS_GET_COOKIE _IO(NSIO, 0x5)
#endif /* __LINUX_NSFS_H */
--
2.27.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH bpf-next v3 3/4] tools/testing: add test for NS_GET_COOKIE
2021-02-19 15:43 [PATCH bpf-next v3 0/4] Expose network namespace cookies to user space Lorenz Bauer
2021-02-19 15:43 ` [PATCH bpf-next v3 1/4] net: add SO_NETNS_COOKIE socket option Lorenz Bauer
2021-02-19 15:43 ` [PATCH bpf-next v3 2/4] nsfs: add an ioctl to discover the network namespace cookie Lorenz Bauer
@ 2021-02-19 15:43 ` Lorenz Bauer
2021-02-19 15:43 ` [PATCH bpf-next v3 4/4] tools/testing: add a selftest for SO_NETNS_COOKIE Lorenz Bauer
2021-03-12 9:57 ` [PATCH bpf-next v3 0/4] Expose network namespace cookies to user space Tony Lu
4 siblings, 0 replies; 6+ messages in thread
From: Lorenz Bauer @ 2021-02-19 15:43 UTC (permalink / raw)
To: eric.dumazet, daniel, ast, andrii; +Cc: bpf, netdev, kernel-team, Lorenz Bauer
Check that NS_GET_COOKIE returns a non-zero value, and that distinct
network namespaces have different cookies.
Signed-off-by: Lorenz Bauer <lmb@cloudflare.com>
---
tools/testing/selftests/nsfs/.gitignore | 1 +
tools/testing/selftests/nsfs/Makefile | 2 +-
tools/testing/selftests/nsfs/config | 1 +
tools/testing/selftests/nsfs/netns.c | 57 +++++++++++++++++++++++++
4 files changed, 60 insertions(+), 1 deletion(-)
create mode 100644 tools/testing/selftests/nsfs/netns.c
diff --git a/tools/testing/selftests/nsfs/.gitignore b/tools/testing/selftests/nsfs/.gitignore
index ed79ebdf286e..ca31b216215b 100644
--- a/tools/testing/selftests/nsfs/.gitignore
+++ b/tools/testing/selftests/nsfs/.gitignore
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-only
owner
pidns
+netns
diff --git a/tools/testing/selftests/nsfs/Makefile b/tools/testing/selftests/nsfs/Makefile
index dd9bd50b7b93..93793cdb5a7c 100644
--- a/tools/testing/selftests/nsfs/Makefile
+++ b/tools/testing/selftests/nsfs/Makefile
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-only
-TEST_GEN_PROGS := owner pidns
+TEST_GEN_PROGS := owner pidns netns
CFLAGS := -Wall -Werror
diff --git a/tools/testing/selftests/nsfs/config b/tools/testing/selftests/nsfs/config
index 598d0a225fc9..ea654f6a4cd9 100644
--- a/tools/testing/selftests/nsfs/config
+++ b/tools/testing/selftests/nsfs/config
@@ -1,3 +1,4 @@
CONFIG_USER_NS=y
CONFIG_UTS_NS=y
CONFIG_PID_NS=y
+CONFIG_NET_NS=y
diff --git a/tools/testing/selftests/nsfs/netns.c b/tools/testing/selftests/nsfs/netns.c
new file mode 100644
index 000000000000..8ab862667b45
--- /dev/null
+++ b/tools/testing/selftests/nsfs/netns.c
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: GPL-2.0
+#define _GNU_SOURCE
+#include <sched.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+
+#define NSIO 0xb7
+#define NS_GET_COOKIE _IO(NSIO, 0x5)
+
+#define pr_err(fmt, ...) \
+ ({ \
+ fprintf(stderr, "%s:%d:" fmt ": %m\n", \
+ __func__, __LINE__, ##__VA_ARGS__); \
+ 1; \
+ })
+
+int main(int argc, char *argvp[])
+{
+ uint64_t cookie1, cookie2;
+ char path[128];
+ int ns;
+
+ snprintf(path, sizeof(path), "/proc/%d/ns/net", getpid());
+ ns = open(path, O_RDONLY);
+ if (ns < 0)
+ return pr_err("Unable to open %s", path);
+
+ if (ioctl(ns, NS_GET_COOKIE, &cookie1))
+ return pr_err("Unable to get first namespace cookie");
+
+ if (!cookie1)
+ return pr_err("NS_GET_COOKIE returned zero first cookie");
+
+ close(ns);
+ if (unshare(CLONE_NEWNET))
+ return pr_err("unshare");
+
+ ns = open(path, O_RDONLY);
+ if (ns < 0)
+ return pr_err("Unable to open %s", path);
+
+ if (ioctl(ns, NS_GET_COOKIE, &cookie2))
+ return pr_err("Unable to get second namespace cookie");
+
+ if (!cookie2)
+ return pr_err("NS_GET_COOKIE returned zero second cookie");
+
+ if (cookie1 == cookie2)
+ return pr_err("NS_GET_COOKIE returned identical cookies for distinct ns");
+
+ close(ns);
+ return 0;
+}
--
2.27.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH bpf-next v3 4/4] tools/testing: add a selftest for SO_NETNS_COOKIE
2021-02-19 15:43 [PATCH bpf-next v3 0/4] Expose network namespace cookies to user space Lorenz Bauer
` (2 preceding siblings ...)
2021-02-19 15:43 ` [PATCH bpf-next v3 3/4] tools/testing: add test for NS_GET_COOKIE Lorenz Bauer
@ 2021-02-19 15:43 ` Lorenz Bauer
2021-03-12 9:57 ` [PATCH bpf-next v3 0/4] Expose network namespace cookies to user space Tony Lu
4 siblings, 0 replies; 6+ messages in thread
From: Lorenz Bauer @ 2021-02-19 15:43 UTC (permalink / raw)
To: eric.dumazet, daniel, ast, andrii; +Cc: bpf, netdev, kernel-team, Lorenz Bauer
Make sure that SO_NETNS_COOKIE returns a non-zero value, and
that sockets from different namespaces have a distinct cookie
value.
Signed-off-by: Lorenz Bauer <lmb@cloudflare.com>
---
tools/testing/selftests/net/.gitignore | 1 +
tools/testing/selftests/net/Makefile | 2 +-
tools/testing/selftests/net/config | 1 +
tools/testing/selftests/net/so_netns_cookie.c | 61 +++++++++++++++++++
4 files changed, 64 insertions(+), 1 deletion(-)
create mode 100644 tools/testing/selftests/net/so_netns_cookie.c
diff --git a/tools/testing/selftests/net/.gitignore b/tools/testing/selftests/net/.gitignore
index 61ae899cfc17..19deb9cdf72f 100644
--- a/tools/testing/selftests/net/.gitignore
+++ b/tools/testing/selftests/net/.gitignore
@@ -30,3 +30,4 @@ hwtstamp_config
rxtimestamp
timestamping
txtimestamp
+so_netns_cookie
diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile
index 25f198bec0b2..91bb372f5ba5 100644
--- a/tools/testing/selftests/net/Makefile
+++ b/tools/testing/selftests/net/Makefile
@@ -28,7 +28,7 @@ TEST_GEN_FILES = socket nettest
TEST_GEN_FILES += psock_fanout psock_tpacket msg_zerocopy reuseport_addr_any
TEST_GEN_FILES += tcp_mmap tcp_inq psock_snd txring_overwrite
TEST_GEN_FILES += udpgso udpgso_bench_tx udpgso_bench_rx ip_defrag
-TEST_GEN_FILES += so_txtime ipv6_flowlabel ipv6_flowlabel_mgr
+TEST_GEN_FILES += so_txtime ipv6_flowlabel ipv6_flowlabel_mgr so_netns_cookie
TEST_GEN_FILES += tcp_fastopen_backup_key
TEST_GEN_FILES += fin_ack_lat
TEST_GEN_FILES += reuseaddr_ports_exhausted
diff --git a/tools/testing/selftests/net/config b/tools/testing/selftests/net/config
index 614d5477365a..6f905b53904f 100644
--- a/tools/testing/selftests/net/config
+++ b/tools/testing/selftests/net/config
@@ -1,4 +1,5 @@
CONFIG_USER_NS=y
+CONFIG_NET_NS=y
CONFIG_BPF_SYSCALL=y
CONFIG_TEST_BPF=m
CONFIG_NUMA=y
diff --git a/tools/testing/selftests/net/so_netns_cookie.c b/tools/testing/selftests/net/so_netns_cookie.c
new file mode 100644
index 000000000000..b39e87e967cd
--- /dev/null
+++ b/tools/testing/selftests/net/so_netns_cookie.c
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0
+#define _GNU_SOURCE
+#include <sched.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#ifndef SO_NETNS_COOKIE
+#define SO_NETNS_COOKIE 71
+#endif
+
+#define pr_err(fmt, ...) \
+ ({ \
+ fprintf(stderr, "%s:%d:" fmt ": %m\n", \
+ __func__, __LINE__, ##__VA_ARGS__); \
+ 1; \
+ })
+
+int main(int argc, char *argvp[])
+{
+ uint64_t cookie1, cookie2;
+ socklen_t vallen;
+ int sock1, sock2;
+
+ sock1 = socket(AF_INET, SOCK_STREAM, 0);
+ if (sock1 < 0)
+ return pr_err("Unable to create TCP socket");
+
+ vallen = sizeof(cookie1);
+ if (getsockopt(sock1, SOL_SOCKET, SO_NETNS_COOKIE, &cookie1, &vallen) != 0)
+ return pr_err("getsockopt(SOL_SOCKET, SO_NETNS_COOKIE)");
+
+ if (!cookie1)
+ return pr_err("SO_NETNS_COOKIE returned zero cookie");
+
+ if (unshare(CLONE_NEWNET))
+ return pr_err("unshare");
+
+ sock2 = socket(AF_INET, SOCK_STREAM, 0);
+ if (sock2 < 0)
+ return pr_err("Unable to create TCP socket");
+
+ vallen = sizeof(cookie2);
+ if (getsockopt(sock2, SOL_SOCKET, SO_NETNS_COOKIE, &cookie2, &vallen) != 0)
+ return pr_err("getsockopt(SOL_SOCKET, SO_NETNS_COOKIE)");
+
+ if (!cookie2)
+ return pr_err("SO_NETNS_COOKIE returned zero cookie");
+
+ if (cookie1 == cookie2)
+ return pr_err("SO_NETNS_COOKIE returned identical cookies for distinct ns");
+
+ close(sock1);
+ close(sock2);
+ return 0;
+}
--
2.27.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH bpf-next v3 0/4] Expose network namespace cookies to user space
2021-02-19 15:43 [PATCH bpf-next v3 0/4] Expose network namespace cookies to user space Lorenz Bauer
` (3 preceding siblings ...)
2021-02-19 15:43 ` [PATCH bpf-next v3 4/4] tools/testing: add a selftest for SO_NETNS_COOKIE Lorenz Bauer
@ 2021-03-12 9:57 ` Tony Lu
4 siblings, 0 replies; 6+ messages in thread
From: Tony Lu @ 2021-03-12 9:57 UTC (permalink / raw)
To: Lorenz Bauer; +Cc: eric.dumazet, daniel, ast, andrii, bpf, netdev, kernel-team
On Fri, Feb 19, 2021 at 03:43:26PM +0000, Lorenz Bauer wrote:
> We're working on a user space control plane for the BPF sk_lookup
> hook [1]. The hook attaches to a network namespace and allows
> control over which socket receives a new connection / packet.
We are developing a net stack latency tracing tool, which need
net_cookie to distinguish different net namespace. Besides that, our
container management system need to read net_cookie from userspace.
In [0], you said you would give up this patch set. Could you reconsider
continuing with these patches? Because we also need them.
net_cookie could be an unified net namespace ID to replace netns inode,
but there are lots of work to do.
[0]: https://lkml.org/lkml/2021/3/10/254
Cheers,
Tony Lu
>
> I'm proposing to add a new getsockopt and a netns ioctl to retrieve
> netns cookies, which allows identifying which netns a socket belongs
> to.
>
> 1: https://www.kernel.org/doc/html/latest/bpf/prog_sk_lookup.html
>
> Changes in v3:
> - Use sock_net unconditionally
> - Fix unused variable in nsfs ioctl
> - Be strict about getsockopt value size
>
> Changes in v2:
> - Rebase on top of Eric Dumazet's netns cookie simplification
>
> Lorenz Bauer (4):
> net: add SO_NETNS_COOKIE socket option
> nsfs: add an ioctl to discover the network namespace cookie
> tools/testing: add test for NS_GET_COOKIE
> tools/testing: add a selftest for SO_NETNS_COOKIE
>
> arch/alpha/include/uapi/asm/socket.h | 2 +
> arch/mips/include/uapi/asm/socket.h | 2 +
> arch/parisc/include/uapi/asm/socket.h | 2 +
> arch/sparc/include/uapi/asm/socket.h | 2 +
> fs/nsfs.c | 7 +++
> include/uapi/asm-generic/socket.h | 2 +
> include/uapi/linux/nsfs.h | 2 +
> net/core/sock.c | 7 +++
> tools/testing/selftests/net/.gitignore | 1 +
> tools/testing/selftests/net/Makefile | 2 +-
> tools/testing/selftests/net/config | 1 +
> tools/testing/selftests/net/so_netns_cookie.c | 61 +++++++++++++++++++
> tools/testing/selftests/nsfs/.gitignore | 1 +
> tools/testing/selftests/nsfs/Makefile | 2 +-
> tools/testing/selftests/nsfs/config | 1 +
> tools/testing/selftests/nsfs/netns.c | 57 +++++++++++++++++
> 16 files changed, 150 insertions(+), 2 deletions(-)
> create mode 100644 tools/testing/selftests/net/so_netns_cookie.c
> create mode 100644 tools/testing/selftests/nsfs/netns.c
>
> --
> 2.27.0
^ permalink raw reply [flat|nested] 6+ messages in thread