Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 15 Feb 2023 16:19:13 GMT
From:      "Alexander V. Chernikov" <melifaro@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: f334eece0677 - releng/13.2 - netlink: allow to override sb_max for netlink sockets.
Message-ID:  <202302151619.31FGJDHm059515@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch releng/13.2 has been updated by melifaro:

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

commit f334eece06771b8f81a9ca04318925c4faf9cdcd
Author:     Alexander V. Chernikov <melifaro@FreeBSD.org>
AuthorDate: 2023-02-10 16:07:17 +0000
Commit:     Alexander V. Chernikov <melifaro@FreeBSD.org>
CommitDate: 2023-02-15 16:18:39 +0000

    netlink: allow to override sb_max for netlink sockets.
    
    Netlink sockets sometimes require larger buffers than other sockets.
    For example, full-view IPv4 dump sent via netlink may consume 50+ megabytes.
    The desired buffer may be bigger than the system maximum `sb_max`.
    FreeBSD HEAD has a mechanism for overriding protocol `setsockopt()` handler,
     which netlink  uses to permit buffer reservations beyond `sb_max`.
     This behaviour is handy as it doesn't require system administrator to lift
     the limits for other sockets.
    Stable/13 lack such muchanism, so a different approach has to be used.
    This diff is a direct commit to stable/13 and it simply copies the logic from
     Netlink in -HEAD for checking if the larger buffer size should be permitted.
    
    Differential Revision: https://reviews.freebsd.org/D38472
    Approved by:    re(cperciva)
    
    (cherry picked from commit c3d3f3594fdf653392936594b75ec330af12d7fa)
---
 sys/kern/uipc_sockbuf.c |  3 ++-
 sys/kern/uipc_socket.c  | 10 ++++++++++
 sys/sys/sockopt.h       |  1 +
 3 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/sys/kern/uipc_sockbuf.c b/sys/kern/uipc_sockbuf.c
index cbfcc0e5fe95..277965412779 100644
--- a/sys/kern/uipc_sockbuf.c
+++ b/sys/kern/uipc_sockbuf.c
@@ -693,7 +693,8 @@ sbsetopt(struct socket *so, int cmd, u_long cc)
 			if (*lowat > *hiwat)
 				*lowat = *hiwat;
 		} else {
-			if (!sbreserve_locked(sb, cc, so, curthread))
+                        u_long limit = sogetmaxbuf(so);
+			if (!sbreserve_locked_limit(sb, cc, so, limit, curthread))
 				error = ENOBUFS;
 		}
 		if (error == 0)
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index f8931b653a4d..fdf718de2483 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -128,6 +128,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/event.h>
 #include <sys/eventhandler.h>
 #include <sys/poll.h>
+#include <sys/priv.h>
 #include <sys/proc.h>
 #include <sys/protosw.h>
 #include <sys/sbuf.h>
@@ -2975,6 +2976,15 @@ sooptcopyin(struct sockopt *sopt, void *buf, size_t len, size_t minlen)
 	return (0);
 }
 
+u_long
+sogetmaxbuf(struct socket *so)
+{
+	if (so->so_proto->pr_domain->dom_family != PF_NETLINK)
+		return (sb_max);
+	u_long nl_maxsockbuf = 512 * 1024 * 1024; /* 512M, XXX: init based on physmem */
+	return ((priv_check(curthread, PRIV_NET_ROUTE) == 0) ? nl_maxsockbuf : sb_max);
+}
+
 /*
  * Kernel version of setsockopt(2).
  *
diff --git a/sys/sys/sockopt.h b/sys/sys/sockopt.h
index cb7fc3ffca27..d01d62f21680 100644
--- a/sys/sys/sockopt.h
+++ b/sys/sys/sockopt.h
@@ -68,5 +68,6 @@ int	accept_filt_getopt(struct socket *, struct sockopt *);
 int	accept_filt_setopt(struct socket *, struct sockopt *);
 int	so_setsockopt(struct socket *so, int level, int optname,
 	    void *optval, size_t optlen);
+u_long	sogetmaxbuf(struct socket *so);
 
 #endif /* _SYS_SOCKOPT_H_ */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202302151619.31FGJDHm059515>