git: 296a4cb5c5b1 - main - sockets: provide correct pr_shutdown for keysock and SDP
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 16 Jan 2024 20:03:35 UTC
The branch main has been updated by glebius:
URL: https://cgit.FreeBSD.org/src/commit/?id=296a4cb5c5b18f82da7a365d9f209cb9fc09003b
commit 296a4cb5c5b18f82da7a365d9f209cb9fc09003b
Author: Gleb Smirnoff <glebius@FreeBSD.org>
AuthorDate: 2024-01-16 20:00:36 +0000
Commit: Gleb Smirnoff <glebius@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);
}