aboutsummaryrefslogtreecommitdiff
path: root/sys/ofed/drivers/infiniband
diff options
context:
space:
mode:
authorGleb Smirnoff <glebius@FreeBSD.org>2024-01-16 20:00:36 +0000
committerGleb Smirnoff <glebius@FreeBSD.org>2024-01-16 20:02:59 +0000
commit296a4cb5c5b18f82da7a365d9f209cb9fc09003b (patch)
tree284a591b45b8438c5dc505e60e15bbcdd8d2790e /sys/ofed/drivers/infiniband
parent61a0eaca0dd7de0c08b46c986aee345922c804f0 (diff)
Diffstat (limited to 'sys/ofed/drivers/infiniband')
-rw-r--r--sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c52
1 files changed, 39 insertions, 13 deletions
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);
}