Message ID | 20210622202623.1311901-1-m@lambda.lt |
---|---|
State | New |
Headers | show |
Series | [net-next,1/2] net: retrieve netns cookie via getsocketopt | expand |
On Tue, 22 Jun 2021 at 21:24, Martynas Pumputis <m@lambda.lt> wrote: > > It's getting more common to run nested container environments for > testing cloud software. One of such examples is Kind [1] which runs a > Kubernetes cluster in Docker containers on a single host. Each container > acts as a Kubernetes node, and thus can run any Pod (aka container) > inside the former. This approach simplifies testing a lot, as it > eliminates complicated VM setups. > > Unfortunately, such a setup breaks some functionality when cgroupv2 BPF > programs are used for load-balancing. The load-balancer BPF program > needs to detect whether a request originates from the host netns or a > container netns in order to allow some access, e.g. to a service via a > loopback IP address. Typically, the programs detect this by comparing > netns cookies with the one of the init ns via a call to > bpf_get_netns_cookie(NULL). However, in nested environments the latter > cannot be used given the Kubernetes node's netns is outside the init ns. > To fix this, we need to pass the Kubernetes node netns cookie to the > program in a different way: by extending getsockopt() with a > SO_NETNS_COOKIE option, the orchestrator which runs in the Kubernetes > node netns can retrieve the cookie and pass it to the program instead. > > Thus, this is following up on Eric's commit 3d368ab87cf6 ("net: > initialize net->net_cookie at netns setup") to allow retrieval via > SO_NETNS_COOKIE. This is also in line in how we retrieve socket cookie > via SO_COOKIE. > > [1] https://kind.sigs.k8s.io/ > > Signed-off-by: Lorenz Bauer <lmb@cloudflare.com> > Signed-off-by: Martynas Pumputis <m@lambda.lt> > Cc: Eric Dumazet <edumazet@google.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 | 9 +++++++++ > 6 files changed, 19 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..92675dc380fa 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 0x0050 > + > #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 ddfa88082a2b..462fe1fb2056 100644 > --- a/net/core/sock.c > +++ b/net/core/sock.c > @@ -1635,6 +1635,15 @@ int sock_getsockopt(struct socket *sock, int level, int optname, > v.val = sk->sk_bound_dev_if; > break; > > +#ifdef CONFIG_NET_NS Nit: sock_net already takes care of CONFIG_NET_NS and returns the root ns if !NET_NS, so this define is not necessary. I think this behaviour is nicer: uapi stays consistent even if kernel config changes. > + case SO_NETNS_COOKIE: > + lv = sizeof(u64); > + if (len != lv) > + return -EINVAL; > + v.val64 = sock_net(sk)->net_cookie; > + break; > +#endif > + > default: > /* We implement the SO_SNDLOWAT etc to not be settable > * (1003.1g 7). > -- > 2.32.0 >
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..92675dc380fa 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 0x0050 + #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 ddfa88082a2b..462fe1fb2056 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1635,6 +1635,15 @@ int sock_getsockopt(struct socket *sock, int level, int optname, v.val = sk->sk_bound_dev_if; break; +#ifdef CONFIG_NET_NS + case SO_NETNS_COOKIE: + lv = sizeof(u64); + if (len != lv) + return -EINVAL; + v.val64 = sock_net(sk)->net_cookie; + break; +#endif + default: /* We implement the SO_SNDLOWAT etc to not be settable * (1003.1g 7).