net: Refactor arguments of inet{,6}_bind

The intent is to add an additional bind parameter in the next commit.
Instead of adding another argument, let's convert all existing
flag arguments into an extendable bit field.

No functional changes.

Signed-off-by: Stanislav Fomichev <sdf@google.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Andrey Ignatov <rdna@fb.com>
Acked-by: Martin KaFai Lau <kafai@fb.com>
Link: https://lore.kernel.org/bpf/20200508174611.228805-4-sdf@google.com
This commit is contained in:
Stanislav Fomichev 2020-05-08 10:46:10 -07:00 committed by Daniel Borkmann
parent 488a23b89d
commit cb0721c7e2
5 changed files with 20 additions and 14 deletions

View File

@ -35,8 +35,12 @@ int inet_shutdown(struct socket *sock, int how);
int inet_listen(struct socket *sock, int backlog); int inet_listen(struct socket *sock, int backlog);
void inet_sock_destruct(struct sock *sk); void inet_sock_destruct(struct sock *sk);
int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len); int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len);
/* Don't allocate port at this moment, defer to connect. */
#define BIND_FORCE_ADDRESS_NO_PORT (1 << 0)
/* Grab and release socket lock. */
#define BIND_WITH_LOCK (1 << 1)
int __inet_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len, int __inet_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len,
bool force_bind_address_no_port, bool with_lock); u32 flags);
int inet_getname(struct socket *sock, struct sockaddr *uaddr, int inet_getname(struct socket *sock, struct sockaddr *uaddr,
int peer); int peer);
int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg); int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);

View File

@ -63,7 +63,7 @@ extern const struct ipv6_stub *ipv6_stub __read_mostly;
/* A stub used by bpf helpers. Similarly ugly as ipv6_stub */ /* A stub used by bpf helpers. Similarly ugly as ipv6_stub */
struct ipv6_bpf_stub { struct ipv6_bpf_stub {
int (*inet6_bind)(struct sock *sk, struct sockaddr *uaddr, int addr_len, int (*inet6_bind)(struct sock *sk, struct sockaddr *uaddr, int addr_len,
bool force_bind_address_no_port, bool with_lock); u32 flags);
struct sock *(*udp6_lib_lookup)(struct net *net, struct sock *(*udp6_lib_lookup)(struct net *net,
const struct in6_addr *saddr, __be16 sport, const struct in6_addr *saddr, __be16 sport,
const struct in6_addr *daddr, __be16 dport, const struct in6_addr *daddr, __be16 dport,

View File

@ -4538,7 +4538,8 @@ BPF_CALL_3(bpf_bind, struct bpf_sock_addr_kern *, ctx, struct sockaddr *, addr,
return err; return err;
if (((struct sockaddr_in *)addr)->sin_port != htons(0)) if (((struct sockaddr_in *)addr)->sin_port != htons(0))
return err; return err;
return __inet_bind(sk, addr, addr_len, true, false); return __inet_bind(sk, addr, addr_len,
BIND_FORCE_ADDRESS_NO_PORT);
#if IS_ENABLED(CONFIG_IPV6) #if IS_ENABLED(CONFIG_IPV6)
} else if (addr->sa_family == AF_INET6) { } else if (addr->sa_family == AF_INET6) {
if (addr_len < SIN6_LEN_RFC2133) if (addr_len < SIN6_LEN_RFC2133)
@ -4548,7 +4549,8 @@ BPF_CALL_3(bpf_bind, struct bpf_sock_addr_kern *, ctx, struct sockaddr *, addr,
/* ipv6_bpf_stub cannot be NULL, since it's called from /* ipv6_bpf_stub cannot be NULL, since it's called from
* bpf_cgroup_inet6_connect hook and ipv6 is already loaded * bpf_cgroup_inet6_connect hook and ipv6 is already loaded
*/ */
return ipv6_bpf_stub->inet6_bind(sk, addr, addr_len, true, false); return ipv6_bpf_stub->inet6_bind(sk, addr, addr_len,
BIND_FORCE_ADDRESS_NO_PORT);
#endif /* CONFIG_IPV6 */ #endif /* CONFIG_IPV6 */
} }
#endif /* CONFIG_INET */ #endif /* CONFIG_INET */

View File

@ -450,12 +450,12 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
if (err) if (err)
return err; return err;
return __inet_bind(sk, uaddr, addr_len, false, true); return __inet_bind(sk, uaddr, addr_len, BIND_WITH_LOCK);
} }
EXPORT_SYMBOL(inet_bind); EXPORT_SYMBOL(inet_bind);
int __inet_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len, int __inet_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len,
bool force_bind_address_no_port, bool with_lock) u32 flags)
{ {
struct sockaddr_in *addr = (struct sockaddr_in *)uaddr; struct sockaddr_in *addr = (struct sockaddr_in *)uaddr;
struct inet_sock *inet = inet_sk(sk); struct inet_sock *inet = inet_sk(sk);
@ -506,7 +506,7 @@ int __inet_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len,
* would be illegal to use them (multicast/broadcast) in * would be illegal to use them (multicast/broadcast) in
* which case the sending device address is used. * which case the sending device address is used.
*/ */
if (with_lock) if (flags & BIND_WITH_LOCK)
lock_sock(sk); lock_sock(sk);
/* Check these errors (active socket, double bind). */ /* Check these errors (active socket, double bind). */
@ -520,7 +520,7 @@ int __inet_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len,
/* Make sure we are allowed to bind here. */ /* Make sure we are allowed to bind here. */
if (snum || !(inet->bind_address_no_port || if (snum || !(inet->bind_address_no_port ||
force_bind_address_no_port)) { (flags & BIND_FORCE_ADDRESS_NO_PORT))) {
if (sk->sk_prot->get_port(sk, snum)) { if (sk->sk_prot->get_port(sk, snum)) {
inet->inet_saddr = inet->inet_rcv_saddr = 0; inet->inet_saddr = inet->inet_rcv_saddr = 0;
err = -EADDRINUSE; err = -EADDRINUSE;
@ -543,7 +543,7 @@ int __inet_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len,
sk_dst_reset(sk); sk_dst_reset(sk);
err = 0; err = 0;
out_release_sock: out_release_sock:
if (with_lock) if (flags & BIND_WITH_LOCK)
release_sock(sk); release_sock(sk);
out: out:
return err; return err;

View File

@ -273,7 +273,7 @@ static int inet6_create(struct net *net, struct socket *sock, int protocol,
} }
static int __inet6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len, static int __inet6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len,
bool force_bind_address_no_port, bool with_lock) u32 flags)
{ {
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)uaddr; struct sockaddr_in6 *addr = (struct sockaddr_in6 *)uaddr;
struct inet_sock *inet = inet_sk(sk); struct inet_sock *inet = inet_sk(sk);
@ -297,7 +297,7 @@ static int __inet6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len,
!ns_capable(net->user_ns, CAP_NET_BIND_SERVICE)) !ns_capable(net->user_ns, CAP_NET_BIND_SERVICE))
return -EACCES; return -EACCES;
if (with_lock) if (flags & BIND_WITH_LOCK)
lock_sock(sk); lock_sock(sk);
/* Check these errors (active socket, double bind). */ /* Check these errors (active socket, double bind). */
@ -400,7 +400,7 @@ static int __inet6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len,
/* Make sure we are allowed to bind here. */ /* Make sure we are allowed to bind here. */
if (snum || !(inet->bind_address_no_port || if (snum || !(inet->bind_address_no_port ||
force_bind_address_no_port)) { (flags & BIND_FORCE_ADDRESS_NO_PORT))) {
if (sk->sk_prot->get_port(sk, snum)) { if (sk->sk_prot->get_port(sk, snum)) {
sk->sk_ipv6only = saved_ipv6only; sk->sk_ipv6only = saved_ipv6only;
inet_reset_saddr(sk); inet_reset_saddr(sk);
@ -423,7 +423,7 @@ static int __inet6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len,
inet->inet_dport = 0; inet->inet_dport = 0;
inet->inet_daddr = 0; inet->inet_daddr = 0;
out: out:
if (with_lock) if (flags & BIND_WITH_LOCK)
release_sock(sk); release_sock(sk);
return err; return err;
out_unlock: out_unlock:
@ -451,7 +451,7 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
if (err) if (err)
return err; return err;
return __inet6_bind(sk, uaddr, addr_len, false, true); return __inet6_bind(sk, uaddr, addr_len, BIND_WITH_LOCK);
} }
EXPORT_SYMBOL(inet6_bind); EXPORT_SYMBOL(inet6_bind);