git: f66968564dd7 - main - protocols: make socket buffers ioctl handler changeable
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 28 Sep 2022 10:20:20 UTC
The branch main has been updated by melifaro:
URL: https://cgit.FreeBSD.org/src/commit/?id=f66968564dd7e87a02f3a4d4bfa5e73c84e5e772
commit f66968564dd7e87a02f3a4d4bfa5e73c84e5e772
Author: Alexander V. Chernikov <melifaro@FreeBSD.org>
AuthorDate: 2022-09-27 13:39:34 +0000
Commit: Alexander V. Chernikov <melifaro@FreeBSD.org>
CommitDate: 2022-09-28 10:20:09 +0000
protocols: make socket buffers ioctl handler changeable
Allow to set custom per-protocol handlers for the socket buffers
ioctls by introducing pr_setsbopt callback with the default value
set to the currently-used sbsetopt().
Reviewed by: glebius
Differential Revision: https://reviews.freebsd.org/D36746
---
sys/kern/uipc_domain.c | 1 +
sys/kern/uipc_sockbuf.c | 24 ++++++++++++++++++------
sys/kern/uipc_socket.c | 14 +-------------
sys/sys/protosw.h | 2 ++
sys/sys/sockbuf.h | 3 ++-
5 files changed, 24 insertions(+), 20 deletions(-)
diff --git a/sys/kern/uipc_domain.c b/sys/kern/uipc_domain.c
index f1b2c616c662..0c92ff699171 100644
--- a/sys/kern/uipc_domain.c
+++ b/sys/kern/uipc_domain.c
@@ -201,6 +201,7 @@ pr_init(struct domain *dom, struct protosw *pr)
DEFAULT(pr_sosend, sosend_generic);
DEFAULT(pr_soreceive, soreceive_generic);
DEFAULT(pr_sopoll, sopoll_generic);
+ DEFAULT(pr_setsbopt, sbsetopt);
#define NOTSUPP(foo) if (pr->foo == NULL) pr->foo = foo ## _notsupp
NOTSUPP(pr_accept);
diff --git a/sys/kern/uipc_sockbuf.c b/sys/kern/uipc_sockbuf.c
index da02de3e3301..a2d3fc28bbec 100644
--- a/sys/kern/uipc_sockbuf.c
+++ b/sys/kern/uipc_sockbuf.c
@@ -651,18 +651,30 @@ sbreserve_locked(struct socket *so, sb_which which, u_long cc,
}
int
-sbsetopt(struct socket *so, int cmd, u_long cc)
+sbsetopt(struct socket *so, struct sockopt *sopt)
{
struct sockbuf *sb;
sb_which wh;
short *flags;
- u_int *hiwat, *lowat;
- int error;
+ u_int cc, *hiwat, *lowat;
+ int error, optval;
+
+ error = sooptcopyin(sopt, &optval, sizeof optval, sizeof optval);
+ if (error != 0)
+ return (error);
+
+ /*
+ * Values < 1 make no sense for any of these options,
+ * so disallow them.
+ */
+ if (optval < 1)
+ return (EINVAL);
+ cc = optval;
sb = NULL;
SOCK_LOCK(so);
if (SOLISTENING(so)) {
- switch (cmd) {
+ switch (sopt->sopt_name) {
case SO_SNDLOWAT:
case SO_SNDBUF:
lowat = &so->sol_sbsnd_lowat;
@@ -677,7 +689,7 @@ sbsetopt(struct socket *so, int cmd, u_long cc)
break;
}
} else {
- switch (cmd) {
+ switch (sopt->sopt_name) {
case SO_SNDLOWAT:
case SO_SNDBUF:
sb = &so->so_snd;
@@ -696,7 +708,7 @@ sbsetopt(struct socket *so, int cmd, u_long cc)
}
error = 0;
- switch (cmd) {
+ switch (sopt->sopt_name) {
case SO_SNDBUF:
case SO_RCVBUF:
if (SOLISTENING(so)) {
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index 7f5e70d14e91..7e1d2c910dbd 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -3109,21 +3109,9 @@ sosetopt(struct socket *so, struct sockopt *sopt)
case SO_RCVBUF:
case SO_SNDLOWAT:
case SO_RCVLOWAT:
- error = sooptcopyin(sopt, &optval, sizeof optval,
- sizeof optval);
+ error = so->so_proto->pr_setsbopt(so, sopt);
if (error)
goto bad;
-
- /*
- * Values < 1 make no sense for any of these options,
- * so disallow them.
- */
- if (optval < 1) {
- error = EINVAL;
- goto bad;
- }
-
- error = sbsetopt(so, sopt->sopt_name, optval);
break;
case SO_SNDTIMEO:
diff --git a/sys/sys/protosw.h b/sys/sys/protosw.h
index 3b89c6f78caf..c0d1ae3761d8 100644
--- a/sys/sys/protosw.h
+++ b/sys/sys/protosw.h
@@ -62,6 +62,7 @@ struct uio;
/* USE THESE FOR YOUR PROTOTYPES ! */
typedef int pr_ctloutput_t(struct socket *, struct sockopt *);
+typedef int pr_setsbopt_t(struct socket *, struct sockopt *);
typedef void pr_abort_t(struct socket *);
typedef int pr_accept_t(struct socket *, struct sockaddr **);
typedef int pr_attach_t(struct socket *, int, struct thread *);
@@ -143,6 +144,7 @@ struct protosw {
pr_sense_t *pr_sense; /* stat(2) */
pr_flush_t *pr_flush; /* XXXGL: merge with pr_shutdown_t! */
pr_sosetlabel_t *pr_sosetlabel; /* MAC, XXXGL: remove */
+ pr_setsbopt_t *pr_setsbopt; /* Socket buffer ioctls */
};
/*#endif*/
diff --git a/sys/sys/sockbuf.h b/sys/sys/sockbuf.h
index 7075cab650da..a0c6fd10116a 100644
--- a/sys/sys/sockbuf.h
+++ b/sys/sys/sockbuf.h
@@ -71,6 +71,7 @@ struct ktls_session;
struct mbuf;
struct sockaddr;
struct socket;
+struct sockopt;
struct thread;
struct selinfo;
@@ -227,7 +228,7 @@ void sbflush(struct sockbuf *sb);
void sbflush_locked(struct sockbuf *sb);
void sbrelease(struct socket *, sb_which);
void sbrelease_locked(struct socket *, sb_which);
-int sbsetopt(struct socket *so, int cmd, u_long cc);
+int sbsetopt(struct socket *so, struct sockopt *);
bool sbreserve_locked(struct socket *so, sb_which which, u_long cc,
struct thread *td);
void sbsndptr_adv(struct sockbuf *sb, struct mbuf *mb, u_int len);