linux-parisc.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH bpf 0/4] Expose network namespace cookies to user space
@ 2021-02-10 12:04 Lorenz Bauer
  2021-02-10 12:04 ` [PATCH bpf 1/4] net: add SO_NETNS_COOKIE socket option Lorenz Bauer
  0 siblings, 1 reply; 3+ messages in thread
From: Lorenz Bauer @ 2021-02-10 12:04 UTC (permalink / raw)
  To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko
  Cc: kernel-team, Lorenz Bauer, bpf, linux-alpha, linux-api,
	linux-arch, linux-fsdevel, linux-kernel, linux-kselftest,
	linux-mips, linux-parisc, netdev, sparclinux

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.

Roughly, applications can give a socket to our user space component
to participate in custom bind semantics. This creates an edge case
where  an application can provide us with a socket that lives in
a different network namespace than our BPF sk_lookup program.
We'd like to return an error in this case.

Additionally, we have some user space state that is tied to the
network namespace. We currently use the inode of the nsfs entry
in a directory name, but this is suffers from inode reuse.

I'm proposing to fix both of these issues by adding a new
SO_NETNS_COOKIE socket option as well as a NS_GET_COOKIE ioctl.
Using these we get a stable, unique identifier for a network
namespace and check whether a socket belongs to the "correct"
namespace.

NS_GET_COOKIE could be renamed to NS_GET_NET_COOKIE. I kept the
name generic because it seems like other namespace types could
benefit from a cookie as well.

I'm trying to land this via the bpf tree since this is where the
netns cookie originated, please let me know if this isn't
appropriate.

1: https://www.kernel.org/doc/html/latest/bpf/prog_sk_lookup.html

Cc: bpf@vger.kernel.org
Cc: linux-alpha@vger.kernel.org
Cc: linux-api@vger.kernel.org
Cc: linux-arch@vger.kernel.org
Cc: linux-fsdevel@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-kselftest@vger.kernel.org
Cc: linux-mips@vger.kernel.org
Cc: linux-parisc@vger.kernel.org
Cc: netdev@vger.kernel.org
Cc: sparclinux@vger.kernel.org

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                                     |  9 +++
 include/linux/sock_diag.h                     | 20 ++++++
 include/net/net_namespace.h                   | 11 ++++
 include/uapi/asm-generic/socket.h             |  2 +
 include/uapi/linux/nsfs.h                     |  2 +
 net/core/filter.c                             |  9 ++-
 net/core/sock.c                               |  7 +++
 tools/testing/selftests/net/.gitignore        |  1 +
 tools/testing/selftests/net/Makefile          |  2 +-
 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/netns.c          | 57 +++++++++++++++++
 17 files changed, 185 insertions(+), 7 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] 3+ messages in thread

* [PATCH bpf 1/4] net: add SO_NETNS_COOKIE socket option
  2021-02-10 12:04 [PATCH bpf 0/4] Expose network namespace cookies to user space Lorenz Bauer
@ 2021-02-10 12:04 ` Lorenz Bauer
  2021-02-10 14:51   ` Eric Dumazet
  0 siblings, 1 reply; 3+ messages in thread
From: Lorenz Bauer @ 2021-02-10 12:04 UTC (permalink / raw)
  To: Richard Henderson, Ivan Kokshaysky, Matt Turner,
	Thomas Bogendoerfer, James E.J. Bottomley, Helge Deller,
	David S. Miller, Arnd Bergmann, Alexei Starovoitov,
	Daniel Borkmann, Andrii Nakryiko, Jakub Kicinski
  Cc: kernel-team, Lorenz Bauer, linux-api, linux-alpha, linux-kernel,
	linux-mips, linux-parisc, sparclinux, linux-arch, netdev, bpf

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.

The BPF helpers change slightly: instead of returning 0 when network
namespaces are disabled we return the init_net cookie as for the
socket option.

Cc: linux-api@vger.kernel.org
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/linux/sock_diag.h             | 20 ++++++++++++++++++++
 include/uapi/asm-generic/socket.h     |  2 ++
 net/core/filter.c                     |  9 ++++-----
 net/core/sock.c                       |  7 +++++++
 8 files changed, 41 insertions(+), 5 deletions(-)

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/linux/sock_diag.h b/include/linux/sock_diag.h
index 0b9ecd8cf979..6e88436097b1 100644
--- a/include/linux/sock_diag.h
+++ b/include/linux/sock_diag.h
@@ -38,6 +38,26 @@ static inline u64 sock_gen_cookie(struct sock *sk)
 	return cookie;
 }
 
+static inline u64 __sock_gen_netns_cookie(struct sock *sk)
+{
+#ifdef CONFIG_NET_NS
+	return __net_gen_cookie(sk->sk_net.net);
+#else
+	return __net_gen_cookie(&init_net);
+#endif
+}
+
+static inline u64 sock_gen_netns_cookie(struct sock *sk)
+{
+	u64 cookie;
+
+	preempt_disable();
+	cookie = __sock_gen_netns_cookie(sk);
+	preempt_enable();
+
+	return cookie;
+}
+
 int sock_diag_check_cookie(struct sock *sk, const __u32 *cookie);
 void sock_diag_save_cookie(struct sock *sk, __u32 *cookie);
 
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/filter.c b/net/core/filter.c
index e15d4741719a..51f47b6913f1 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -4645,11 +4645,10 @@ static const struct bpf_func_proto bpf_get_socket_cookie_sock_ops_proto = {
 
 static u64 __bpf_get_netns_cookie(struct sock *sk)
 {
-#ifdef CONFIG_NET_NS
-	return __net_gen_cookie(sk ? sk->sk_net.net : &init_net);
-#else
-	return 0;
-#endif
+	if (sk)
+		return __sock_gen_netns_cookie(sk);
+
+	return __net_gen_cookie(&init_net);
 }
 
 BPF_CALL_1(bpf_get_netns_cookie_sock, struct sock *, ctx)
diff --git a/net/core/sock.c b/net/core/sock.c
index bbcd4b97eddd..2db201c210ca 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1606,6 +1606,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_gen_netns_cookie(sk);
+		break;
+
 	default:
 		/* We implement the SO_SNDLOWAT etc to not be settable
 		 * (1003.1g 7).
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH bpf 1/4] net: add SO_NETNS_COOKIE socket option
  2021-02-10 12:04 ` [PATCH bpf 1/4] net: add SO_NETNS_COOKIE socket option Lorenz Bauer
@ 2021-02-10 14:51   ` Eric Dumazet
  0 siblings, 0 replies; 3+ messages in thread
From: Eric Dumazet @ 2021-02-10 14:51 UTC (permalink / raw)
  To: Lorenz Bauer, Richard Henderson, Ivan Kokshaysky, Matt Turner,
	Thomas Bogendoerfer, James E.J. Bottomley, Helge Deller,
	David S. Miller, Arnd Bergmann, Alexei Starovoitov,
	Daniel Borkmann, Andrii Nakryiko, Jakub Kicinski
  Cc: kernel-team, linux-api, linux-alpha, linux-kernel, linux-mips,
	linux-parisc, sparclinux, linux-arch, netdev, bpf



On 2/10/21 1:04 PM, Lorenz Bauer wrote:
> 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.
> 
> The BPF helpers change slightly: instead of returning 0 when network
> namespaces are disabled we return the init_net cookie as for the
> socket option.
> 
> Cc: linux-api@vger.kernel.org
> Signed-off-by: Lorenz Bauer <lmb@cloudflare.com>
> ---

...

>  
> +static inline u64 __sock_gen_netns_cookie(struct sock *sk)
> +{
> +#ifdef CONFIG_NET_NS
> +	return __net_gen_cookie(sk->sk_net.net);
> +#else
> +	return __net_gen_cookie(&init_net);
> +#endif
> +}
> +
> +static inline u64 sock_gen_netns_cookie(struct sock *sk)
> +{
> +	u64 cookie;
> +
> +	preempt_disable();
> +	cookie = __sock_gen_netns_cookie(sk);
> +	preempt_enable();
> +
> +	return cookie;
> +}
> +
> 

I suggest we make net->net_cookie a mere u64 initialized in setup_net(),
instead of having to preempt_disable() around reading it.

(Here and in your patch 2/4)

Your patches would be much simpler.

Cleanup patch :

https://patchwork.kernel.org/project/netdevbpf/patch/20210210144144.24284-1-eric.dumazet@gmail.com/



^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2021-02-10 14:52 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-10 12:04 [PATCH bpf 0/4] Expose network namespace cookies to user space Lorenz Bauer
2021-02-10 12:04 ` [PATCH bpf 1/4] net: add SO_NETNS_COOKIE socket option Lorenz Bauer
2021-02-10 14:51   ` Eric Dumazet

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).