From: Martin KaFai Lau <kafai@xxxxxx> Date: Fri, 14 May 2021 18:13:05 -0700 > On Mon, May 10, 2021 at 12:44:29PM +0900, Kuniyuki Iwashima wrote: > > diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c > > index e690d1cff36e..fe666dc5c621 100644 > > --- a/net/ipv4/inet_connection_sock.c > > +++ b/net/ipv4/inet_connection_sock.c > > @@ -1075,10 +1075,38 @@ struct sock *inet_csk_complete_hashdance(struct sock *sk, struct sock *child, > > if (own_req) { > > inet_csk_reqsk_queue_drop(sk, req); > > reqsk_queue_removed(&inet_csk(sk)->icsk_accept_queue, req); > In the migration case 'sk != req->rsk_listener', is sk the right > one to pass in the above two functions? Good catch, 'sk' should be 'req->rsk_listener' here. Thank you! > > > - if (inet_csk_reqsk_queue_add(sk, req, child)) > > + > > + if (sk != req->rsk_listener) { > > + /* another listening sk has been selected, > > + * migrate the req to it. > > + */ > > + struct request_sock *nreq; > > + > > + /* hold a refcnt for the nreq->rsk_listener > > + * which is assigned in reqsk_clone() > > + */ > > + sock_hold(sk); > > + nreq = reqsk_clone(req, sk); > > + if (!nreq) { > > + inet_child_forget(sk, req, child); > > + goto child_put; > > + } > > + > > + refcount_set(&nreq->rsk_refcnt, 1); > > + if (inet_csk_reqsk_queue_add(sk, nreq, child)) { > > + reqsk_migrate_reset(req); > > + reqsk_put(req); > > + return child; > > + } > > + > > + reqsk_migrate_reset(nreq); > > + __reqsk_free(nreq); > > + } else if (inet_csk_reqsk_queue_add(sk, req, child)) { > > return child; > > + } > > } > > /* Too bad, another child took ownership of the request, undo. */ > > +child_put: > > bh_unlock_sock(child); > > sock_put(child); > > return NULL;