From 296a4cb5c5b18f82da7a365d9f209cb9fc09003b Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Tue, 16 Jan 2024 12:00:36 -0800 Subject: [PATCH] sockets: provide correct pr_shutdown for keysock and SDP My failure to run all kinds of kernel builds lead to missing the keysock and incorrectly assuming SDP as not having a shutdown method. Fixes: 5bba2728079ed4da33f727dbc2b6ae1de02ba897 --- sys/netipsec/keysock.c | 19 ++++++- .../drivers/infiniband/ulp/sdp/sdp_main.c | 52 ++++++++++++++----- 2 files changed, 56 insertions(+), 15 deletions(-) diff --git a/sys/netipsec/keysock.c b/sys/netipsec/keysock.c index 18bbdae316f0..d9297d44c18a 100644 --- a/sys/netipsec/keysock.c +++ b/sys/netipsec/keysock.c @@ -310,9 +310,24 @@ key_detach(struct socket *so) } static int -key_shutdown(struct socket *so) +key_shutdown(struct socket *so, enum shutdown_how how) { - socantsendmore(so); + /* + * Note: key socket marks itself as connected through its lifetime. + */ + switch (how) { + case SHUT_RD: + socantrcvmore(so); + sbrelease(so, SO_RCV); + break; + case SHUT_RDWR: + socantrcvmore(so); + sbrelease(so, SO_RCV); + /* FALLTHROUGH */ + case SHUT_WR: + socantsendmore(so); + } + return (0); } diff --git a/sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c b/sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c index 95048a1dc186..cfc2390db02e 100644 --- a/sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c +++ b/sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c @@ -787,24 +787,50 @@ sdp_accept(struct socket *so, struct sockaddr *sa) * Mark the connection as being incapable of further output. */ static int -sdp_shutdown(struct socket *so) +sdp_shutdown(struct socket *so, enum shutdown_how how) { + struct sdp_sock *ssk = sdp_sk(so); int error = 0; - struct sdp_sock *ssk; - ssk = sdp_sk(so); - SDP_WLOCK(ssk); - if (ssk->flags & (SDP_TIMEWAIT | SDP_DROPPED)) { - error = ECONNRESET; - goto out; + SOCK_LOCK(so); + if ((so->so_state & + (SS_ISCONNECTED | SS_ISCONNECTING | SS_ISDISCONNECTING)) == 0) { + SOCK_UNLOCK(so); + return (ENOTCONN); } - socantsendmore(so); - sdp_usrclosed(ssk); - if (!(ssk->flags & SDP_DROPPED)) - sdp_output_disconnect(ssk); + if (SOLISTENING(so)) { + if (how != SHUT_WR) { + so->so_error = ECONNABORTED; + solisten_wakeup(so); /* unlocks so */ + } else + SOCK_UNLOCK(so); + return (0); + } + SOCK_UNLOCK(so); -out: - SDP_WUNLOCK(ssk); + switch (how) { + case SHUT_RD: + socantrcvmore(so); + sbrelease(so, SO_RCV); + break; + case SHUT_RDWR: + socantrcvmore(so); + sbrelease(so, SO_RCV); + /* FALLTHROUGH */ + case SHUT_WR: + SDP_WLOCK(ssk); + if (ssk->flags & (SDP_TIMEWAIT | SDP_DROPPED)) { + SDP_WUNLOCK(ssk); + error = ECONNRESET; + break; + } + socantsendmore(so); + sdp_usrclosed(ssk); + if (!(ssk->flags & SDP_DROPPED)) + sdp_output_disconnect(ssk); + SDP_WUNLOCK(ssk); + } + wakeup(&so->so_timeo); return (error); }