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);