Message ID | 20210219095149.50346-2-lmb@cloudflare.com (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | BPF |
Headers | show |
Series | Expose network namespace cookies to user space | expand |
On 2/19/21 10:51 AM, 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. > > Signed-off-by: Lorenz Bauer <lmb@cloudflare.com> > --- > diff --git a/net/core/sock.c b/net/core/sock.c > index 0ed98f20448a..de4644aeb58d 100644 > --- a/net/core/sock.c > +++ b/net/core/sock.c > @@ -1614,6 +1614,17 @@ 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; if (len != lv) return -EINVAL; (There is no reason to support bigger value before at least hundred years) > +#ifdef CONFIG_NET_NS > + v.val64 = sock_net(sk)->net_cookie; > +#else > + v.val64 = init_net.net_cookie; > +#endif > + break; > + Why using this ugly #ifdef ? The following should work just fine, even if CONFIG_NET_NS is not set. v.val64 = sock_net(sk)->net_cookie; > default: > /* We implement the SO_SNDLOWAT etc to not be settable > * (1003.1g 7). >
On Fri, 19 Feb 2021 at 11:49, Eric Dumazet <eric.dumazet@gmail.com> wrote: > > > + case SO_NETNS_COOKIE: > > + lv = sizeof(u64); > > + if (len < lv) > > + return -EINVAL; > > if (len != lv) > return -EINVAL; > > (There is no reason to support bigger value before at least hundred years) Sorry that was copy pasta from SO_COOKIE which uses the same check. I'll change it to your suggestion. Want me to fix SO_COOKIE as well? > > > +#ifdef CONFIG_NET_NS > > + v.val64 = sock_net(sk)->net_cookie; > > +#else > > + v.val64 = init_net.net_cookie; > > +#endif > > + break; > > + > > Why using this ugly #ifdef ? > > The following should work just fine, even if CONFIG_NET_NS is not set. > > v.val64 = sock_net(sk)->net_cookie; I looked at sock_net and didn't understand how it avoids a compile error so I didn't use it, thanks for pointing this out.
On 2/19/21 1:23 PM, Lorenz Bauer wrote: > On Fri, 19 Feb 2021 at 11:49, Eric Dumazet <eric.dumazet@gmail.com> wrote: >> >>> + case SO_NETNS_COOKIE: >>> + lv = sizeof(u64); >>> + if (len < lv) >>> + return -EINVAL; >> >> if (len != lv) >> return -EINVAL; >> >> (There is no reason to support bigger value before at least hundred years) > > Sorry that was copy pasta from SO_COOKIE which uses the same check. I'll > change it to your suggestion. Want me to fix SO_COOKIE as well? Unfortunately it is too late for SO_COOKIE Some applications might use len = 256, and just look at what the kernel gives back. Better be strict at the time a feature is added, instead of having to maintain legacy stuff.
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..de4644aeb58d 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1614,6 +1614,17 @@ 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; +#ifdef CONFIG_NET_NS + v.val64 = sock_net(sk)->net_cookie; +#else + v.val64 = init_net.net_cookie; +#endif + break; + default: /* We implement the SO_SNDLOWAT etc to not be settable * (1003.1g 7).
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 | 11 +++++++++++ 6 files changed, 21 insertions(+)