The branch main has been updated by glebius:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=296a4cb5c5b18f82da7a365d9f209cb9fc09003b

commit 296a4cb5c5b18f82da7a365d9f209cb9fc09003b
Author:     Gleb Smirnoff <gleb...@freebsd.org>
AuthorDate: 2024-01-16 20:00:36 +0000
Commit:     Gleb Smirnoff <gleb...@freebsd.org>
CommitDate: 2024-01-16 20:02:59 +0000

    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 +++++++++-
 sys/ofed/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);
 }

Reply via email to