Re: [PATCH v1 net-next 7/8] sctp: Use sctp_clone_sock() in sctp_do_peeloff().
Kuniyuki Iwashima <[email protected]>
| Newsgroups | org.kernel.vger.linux-sctp,org.kernel.vger.netdev |
|---|---|
| Message-ID | <CAAVpQUAxenM9_MRAo3z5ChFnr3-DN8yq+mR2xC4+ceuOaSL3=A@mail.gmail.com> |
On Tue, Oct 21, 2025 at 2:44 PM Kuniyuki Iwashima <[email protected]> wrote: > > sctp_do_peeloff() calls sock_create() to allocate and initialise > struct sock, inet_sock, and sctp_sock, but later sctp_copy_sock() > and sctp_sock_migrate() overwrite most fields. > > What sctp_do_peeloff() does is more like accept(). > > Let's use sock_create_lite() and sctp_clone_sock(). > > Signed-off-by: Kuniyuki Iwashima <[email protected]> > --- > net/sctp/socket.c | 36 +++++++++++++++--------------------- > 1 file changed, 15 insertions(+), 21 deletions(-) > > diff --git a/net/sctp/socket.c b/net/sctp/socket.c > index 826f17747f176..60d3e340dfeda 100644 > --- a/net/sctp/socket.c > +++ b/net/sctp/socket.c > @@ -5671,11 +5671,11 @@ static int sctp_getsockopt_autoclose(struct sock *sk, int len, char __user *optv > > /* Helper routine to branch off an association to a new socket. */ > static int sctp_do_peeloff(struct sock *sk, sctp_assoc_t id, > - struct socket **sockp) > + struct socket **sockp) > { > struct sctp_association *asoc = sctp_id2assoc(sk, id); > - struct sctp_sock *sp = sctp_sk(sk); > struct socket *sock; > + struct sock *newsk; > int err = 0; > > /* Do not peel off from one netns to another one. */ > @@ -5691,30 +5691,24 @@ static int sctp_do_peeloff(struct sock *sk, sctp_assoc_t id, > if (!sctp_style(sk, UDP)) > return -EINVAL; > > - /* Create a new socket. */ > - err = sock_create(sk->sk_family, SOCK_SEQPACKET, IPPROTO_SCTP, &sock); > - if (err < 0) > + err = sock_create_lite(sk->sk_family, SOCK_SEQPACKET, IPPROTO_SCTP, &sock); > + if (err) > return err; > > - sctp_copy_sock(sock->sk, sk, asoc); > - > - /* Make peeled-off sockets more like 1-1 accepted sockets. > - * Set the daddr and initialize id to something more random and also > - * copy over any ip options. > - */ > - sp->pf->to_sk_daddr(&asoc->peer.primary_addr, sock->sk); > - sp->pf->copy_ip_options(sk, sock->sk); > - > - /* Populate the fields of the newsk from the oldsk and migrate the > - * asoc to the newsk. > - */ > - err = sctp_sock_migrate(sk, sock->sk, asoc, > - SCTP_SOCKET_UDP_HIGH_BANDWIDTH); > - if (err) { > + newsk = sctp_clone_sock(sk, asoc, SCTP_SOCKET_UDP_HIGH_BANDWIDTH); > + if (IS_ERR(newsk)) { > sock_release(sock); > - sock = NULL; > + *sockp = NULL; > + return PTR_ERR(newsk); > } > > + lock_sock_nested(newsk, SINGLE_DEPTH_NESTING); > + __inet_accept(sk->sk_socket, sock, newsk); Oh I assumed __inet_accept() was exported to MPTCP, but it's built-in, and SCTP=m needs this. diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 77f6ae0fc231..ffd4d75d0a7a 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -788,6 +788,7 @@ void __inet_accept(struct socket *sock, struct socket *newsock, struct sock *new newsock->state = SS_CONNECTED; } +EXPORT_SYMBOL(__inet_accept); /* * Accept a pending connection. The TCP layer now gives BSD semantics. -- pw-bot: cr