The branch main has been updated by melifaro:

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

commit f66968564dd7e87a02f3a4d4bfa5e73c84e5e772
Author:     Alexander V. Chernikov <melif...@freebsd.org>
AuthorDate: 2022-09-27 13:39:34 +0000
Commit:     Alexander V. Chernikov <melif...@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);

Reply via email to