@@ -520,6 +520,7 @@ static void __pvcalls_back_accept(struct work_struct *work)
struct proto_accept_arg arg = {
.flags = O_NONBLOCK,
.kern = true,
+ .hold_net = false,
};
struct sock_mapping *map;
struct pvcalls_ioworker *iow;
@@ -1786,6 +1786,8 @@ static int o2net_accept_one(struct socket *sock, int *more)
struct o2net_sock_container *sc = NULL;
struct proto_accept_arg arg = {
.flags = O_NONBLOCK,
+ .kern = false,
+ .hold_net = true,
};
struct o2net_node *nn;
unsigned int nofs_flag;
@@ -502,7 +502,7 @@ struct sctp_pf {
int (*supported_addrs)(const struct sctp_sock *, __be16 *);
struct sock *(*create_accept_sk) (struct sock *sk,
struct sctp_association *asoc,
- bool kern);
+ struct proto_accept_arg *arg);
int (*addr_to_user)(struct sctp_sock *sk, union sctp_addr *addr);
void (*to_sk_saddr)(union sctp_addr *, struct sock *sk);
void (*to_sk_daddr)(union sctp_addr *, struct sock *sk);
@@ -1214,6 +1214,7 @@ struct proto_accept_arg {
int err;
int is_empty;
bool kern;
+ bool hold_net;
};
/* Networking protocol blocks we attach to sockets.
@@ -1559,6 +1559,8 @@ int io_accept(struct io_kiocb *req, unsigned int issue_flags)
bool fixed = !!accept->file_slot;
struct proto_accept_arg arg = {
.flags = force_nonblock ? O_NONBLOCK : 0,
+ .kern = false,
+ .hold_net = true,
};
struct file *file;
unsigned cflags;
@@ -336,7 +336,7 @@ static int svc_accept(struct socket *sock, struct socket *newsock,
lock_sock(sk);
- error = svc_create(sock_net(sk), newsock, 0, arg->kern, !arg->kern);
+ error = svc_create(sock_net(sk), newsock, 0, arg->kern, arg->hold_net);
if (error)
goto out;
@@ -108,6 +108,7 @@ int rds_tcp_accept_one(struct socket *sock)
struct proto_accept_arg arg = {
.flags = O_NONBLOCK,
.kern = true,
+ .hold_net = false,
};
#if !IS_ENABLED(CONFIG_IPV6)
struct in6_addr saddr, daddr;
@@ -777,13 +777,14 @@ static enum sctp_scope sctp_v6_scope(union sctp_addr *addr)
/* Create and initialize a new sk for the socket to be returned by accept(). */
static struct sock *sctp_v6_create_accept_sk(struct sock *sk,
struct sctp_association *asoc,
- bool kern)
+ struct proto_accept_arg *arg)
{
- struct sock *newsk;
struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
struct sctp6_sock *newsctp6sk;
+ struct sock *newsk;
- newsk = sk_alloc(sock_net(sk), PF_INET6, GFP_KERNEL, sk->sk_prot, kern);
+ newsk = sk_alloc(sock_net(sk), PF_INET6, GFP_KERNEL, sk->sk_prot,
+ arg->kern);
if (!newsk)
goto out;
@@ -581,12 +581,13 @@ static int sctp_v4_is_ce(const struct sk_buff *skb)
/* Create and initialize a new sk for the socket returned by accept(). */
static struct sock *sctp_v4_create_accept_sk(struct sock *sk,
struct sctp_association *asoc,
- bool kern)
+ struct proto_accept_arg *arg)
{
- struct sock *newsk = sk_alloc(sock_net(sk), PF_INET, GFP_KERNEL,
- sk->sk_prot, kern);
struct inet_sock *newinet;
+ struct sock *newsk;
+ newsk = sk_alloc(sock_net(sk), PF_INET, GFP_KERNEL, sk->sk_prot,
+ arg->kern);
if (!newsk)
goto out;
@@ -4887,7 +4887,7 @@ static struct sock *sctp_accept(struct sock *sk, struct proto_accept_arg *arg)
*/
asoc = list_entry(ep->asocs.next, struct sctp_association, asocs);
- newsk = sp->pf->create_accept_sk(sk, asoc, arg->kern);
+ newsk = sp->pf->create_accept_sk(sk, asoc, arg);
if (!newsk) {
error = -ENOMEM;
goto out;
@@ -1971,7 +1971,10 @@ struct file *do_accept(struct file *file, struct proto_accept_arg *arg,
static int __sys_accept4_file(struct file *file, struct sockaddr __user *upeer_sockaddr,
int __user *upeer_addrlen, int flags)
{
- struct proto_accept_arg arg = { };
+ struct proto_accept_arg arg = {
+ .kern = false,
+ .hold_net = true,
+ };
struct file *newfile;
int newfd;
@@ -3586,6 +3589,7 @@ int kernel_accept(struct socket *sock, struct socket **newsock, int flags)
struct proto_accept_arg arg = {
.flags = flags,
.kern = true,
+ .hold_net = false,
};
int err;
@@ -2737,7 +2737,7 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock,
buf = skb_peek(&sk->sk_receive_queue);
res = tipc_sk_create(sock_net(sock->sk), new_sock, 0,
- arg->kern, !arg->kern);
+ arg->kern, arg->hold_net);
if (res)
goto exit;
security_sk_clone(sock->sk, new_sock->sk);
We will introduce a new API to create a kernel socket with netns refcnt held. Then, sk_alloc() need the hold_net flag passed from the accept() paths. Let's add a new hold_net flag to struct proto_accept_arg and pass it down before sk_alloc(). Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com> --- drivers/xen/pvcalls-back.c | 1 + fs/ocfs2/cluster/tcp.c | 2 ++ include/net/sctp/structs.h | 2 +- include/net/sock.h | 1 + io_uring/net.c | 2 ++ net/atm/svc.c | 2 +- net/rds/tcp_listen.c | 1 + net/sctp/ipv6.c | 7 ++++--- net/sctp/protocol.c | 7 ++++--- net/sctp/socket.c | 2 +- net/socket.c | 6 +++++- net/tipc/socket.c | 2 +- 12 files changed, 24 insertions(+), 11 deletions(-)