diff options
66 files changed, 1143 insertions, 760 deletions
@@ -27,16 +27,21 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 15.x IS SLOW: world, or to merely disable the most expensive debugging functionality at runtime, run "ln -s 'abort:false,junk:false' /etc/malloc.conf".) +20250730: + The usbhid(4) USB HID driver is now enabled by default, and will be + used in preference to other USB HID drivers like ukbd(4), ums(4), and + uhid(4). Work on a FIDO/U2F driver and moused(8) is in progress. + The default is being switched now so that we can find and fix any + additional issues prior to FreeBSD 15.0. + + To revert to the previous USB HID driver behavior, set the loader + tunable hw.usb.usbhid_enable=0. + 20250727: bmake (i.e., /usr/bin/make and /usr/share/mk) has moved to a new package, FreeBSD-bmake. If you use pkgbase and you need make, you should install this package. -20250727: - LLVM's debugging assertions are now disabled in main by default. - The WITH_LLVM_ASSERTIONS src.conf(5) knob should be used to - enable it when working on LLVM or requesting help with it. - 20250726: amd64 kernel configurations must contain "options SMP". diff --git a/lib/libc/db/hash/hash.c b/lib/libc/db/hash/hash.c index cc96fb5ce326..b1655fe63d55 100644 --- a/lib/libc/db/hash/hash.c +++ b/lib/libc/db/hash/hash.c @@ -99,11 +99,6 @@ __hash_open(const char *file, int flags, int mode, DB *dbp; int bpages, hdrsize, new_table, nsegs, save_errno; - if ((flags & O_ACCMODE) == O_WRONLY) { - errno = EINVAL; - return (NULL); - } - if (!(hashp = (HTAB *)calloc(1, sizeof(HTAB)))) return (NULL); hashp->fp = -1; @@ -115,6 +110,10 @@ __hash_open(const char *file, int flags, int mode, * we can check accesses. */ hashp->flags = flags; + if ((flags & O_ACCMODE) == O_WRONLY) { + flags &= ~O_WRONLY; + flags |= O_RDWR; + } if (file) { if ((hashp->fp = _open(file, flags | O_CLOEXEC, mode)) == -1) @@ -180,7 +179,7 @@ __hash_open(const char *file, int flags, int mode, __buf_init(hashp, DEF_BUFSIZE); hashp->new_file = new_table; - hashp->save_file = file && (hashp->flags & O_RDWR); + hashp->save_file = file && (flags & O_RDWR); hashp->cbucket = -1; if (!(dbp = (DB *)malloc(sizeof(DB)))) { save_errno = errno; @@ -524,6 +523,10 @@ hash_get(const DB *dbp, const DBT *key, DBT *data, u_int32_t flag) hashp->error = errno = EINVAL; return (ERROR); } + if ((hashp->flags & O_ACCMODE) == O_WRONLY) { + hashp->error = errno = EPERM; + return (ERROR); + } return (hash_access(hashp, HASH_GET, (DBT *)key, data)); } @@ -701,17 +704,19 @@ hash_seq(const DB *dbp, DBT *key, DBT *data, u_int32_t flag) u_int16_t *bp, ndx; hashp = (HTAB *)dbp->internal; - if (flag && flag != R_FIRST && flag != R_NEXT) { + if (flag != R_FIRST || flag != R_NEXT) { hashp->error = errno = EINVAL; return (ERROR); } #ifdef HASH_STATISTICS hash_accesses++; #endif - if ((hashp->cbucket < 0) || (flag == R_FIRST)) { + if (flag == R_FIRST) { hashp->cbucket = 0; hashp->cndx = 1; hashp->cpage = NULL; + } else if (hashp->cbucket < 0) { /* R_NEXT */ + return (ABNORMAL); } next_bucket: for (bp = NULL; !bp || !bp[0]; ) { diff --git a/lib/libc/db/man/dbm.3 b/lib/libc/db/man/dbm.3 index c5a83c7acef4..30787600ad2d 100644 --- a/lib/libc/db/man/dbm.3 +++ b/lib/libc/db/man/dbm.3 @@ -13,7 +13,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd April 2, 2022 +.Dd July 25, 2025 .Dt DBM 3 .Os .Sh NAME @@ -99,9 +99,6 @@ is a typical value for .Li 0660 is a typical value for .Fa mode . -.Dv O_WRONLY -is not allowed in -.Fa flags . The pointer returned by .Fn dbm_open identifies the database and is the diff --git a/lib/libc/db/man/dbopen.3 b/lib/libc/db/man/dbopen.3 index 64cef88506d8..7fe515f17849 100644 --- a/lib/libc/db/man/dbopen.3 +++ b/lib/libc/db/man/dbopen.3 @@ -76,13 +76,10 @@ are as specified to the .Xr open 2 routine, however, only the .Dv O_CREAT , O_EXCL , O_EXLOCK , O_NOFOLLOW , O_NONBLOCK , -.Dv O_RDONLY , O_RDWR , O_SHLOCK , O_SYNC +.Dv O_RDONLY , O_RDWR , O_SHLOCK , O_SYNC, O_WRONLY, and .Dv O_TRUNC flags are meaningful. -(Note, opening a database file -.Dv O_WRONLY -is not possible.) .\"Three additional options may be specified by .\".Em or Ns 'ing .\"them into the diff --git a/lib/libc/tests/db/Makefile b/lib/libc/tests/db/Makefile index 54b38b94a581..771569183584 100644 --- a/lib/libc/tests/db/Makefile +++ b/lib/libc/tests/db/Makefile @@ -8,6 +8,8 @@ PROGS+= h_lfsr ${PACKAGE}FILES+= README ATF_TESTS_C+= dbm_open_test +ATF_TESTS_C+= dbm_perm_test +ATF_TESTS_C+= dbm_nextkey_test NETBSD_ATF_TESTS_C+= db_hash_seq_test NETBSD_ATF_TESTS_SH+= db_test diff --git a/lib/libc/tests/db/dbm_nextkey_test.c b/lib/libc/tests/db/dbm_nextkey_test.c new file mode 100644 index 000000000000..67b745efb196 --- /dev/null +++ b/lib/libc/tests/db/dbm_nextkey_test.c @@ -0,0 +1,53 @@ +/*- + * Copyright (c) 2025 Klara, Inc. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <fcntl.h> +#include <ndbm.h> +#include <stdio.h> + +#include <atf-c.h> + +static const char *path = "tmp"; +static const char *dbname = "tmp.db"; + +ATF_TC(dbm_nextkey_test); +ATF_TC_HEAD(dbm_nextkey_test, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Check that dbm_nextkey always returns NULL after reaching the end of the database"); +} + +ATF_TC_BODY(dbm_nextkey_test, tc) +{ + DBM *db; + datum key, data; + + data.dptr = "bar"; + data.dsize = strlen("bar"); + key.dptr = "foo"; + key.dsize = strlen("foo"); + + db = dbm_open(path, O_RDWR | O_CREAT, 0755); + ATF_CHECK(db != NULL); + ATF_REQUIRE(atf_utils_file_exists(dbname)); + ATF_REQUIRE(dbm_store(db, key, data, DBM_INSERT) != -1); + + key = dbm_firstkey(db); + ATF_REQUIRE(key.dptr != NULL); + key = dbm_nextkey(db); + ATF_REQUIRE(key.dptr == NULL); + key = dbm_nextkey(db); + ATF_REQUIRE(key.dptr == NULL); + + dbm_close(db); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, dbm_nextkey_test); + + return (atf_no_error()); +} diff --git a/lib/libc/tests/db/dbm_open_test.c b/lib/libc/tests/db/dbm_open_test.c index 18d398e16b2a..8a3e888bf72c 100644 --- a/lib/libc/tests/db/dbm_open_test.c +++ b/lib/libc/tests/db/dbm_open_test.c @@ -4,14 +4,15 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include <sys/mman.h> - #include <fcntl.h> #include <ndbm.h> #include <stdio.h> #include <atf-c.h> +static const char *path = "tmp"; +static const char *dbname = "tmp.db"; + ATF_TC(dbm_open_missing_test); ATF_TC_HEAD(dbm_open_missing_test, tc) { @@ -21,23 +22,31 @@ ATF_TC_HEAD(dbm_open_missing_test, tc) ATF_TC_BODY(dbm_open_missing_test, tc) { - const char *path = "tmp"; - const char *dbname = "tmp.db"; /* * POSIX.1 specifies that a missing database file should * always get created if O_CREAT is present, except when * O_EXCL is specified as well. */ - ATF_CHECK(dbm_open(path, O_RDONLY, _PROT_ALL) == NULL); + ATF_CHECK(dbm_open(path, O_RDONLY, 0755) == NULL); + ATF_REQUIRE(!atf_utils_file_exists(dbname)); + ATF_CHECK(dbm_open(path, O_RDONLY | O_CREAT, 0755) != NULL); + ATF_REQUIRE(atf_utils_file_exists(dbname)); + ATF_CHECK(dbm_open(path, O_RDONLY | O_CREAT | O_EXCL, 0755) == NULL); +} + +ATF_TC_WITHOUT_HEAD(dbm_open_wronly_test); +ATF_TC_BODY(dbm_open_wronly_test, tc) +{ + ATF_CHECK(dbm_open(path, O_WRONLY, 0755) == NULL); ATF_REQUIRE(!atf_utils_file_exists(dbname)); - ATF_CHECK(dbm_open(path, O_RDONLY | O_CREAT, _PROT_ALL) != NULL); + ATF_CHECK(dbm_open(path, O_WRONLY | O_CREAT, 0755) != NULL); ATF_REQUIRE(atf_utils_file_exists(dbname)); - ATF_CHECK(dbm_open(path, O_RDONLY | O_CREAT | O_EXCL, _PROT_ALL) == NULL); } ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, dbm_open_missing_test); + ATF_TP_ADD_TC(tp, dbm_open_wronly_test); return (atf_no_error()); } diff --git a/lib/libc/tests/db/dbm_perm_test.c b/lib/libc/tests/db/dbm_perm_test.c new file mode 100644 index 000000000000..c07210292014 --- /dev/null +++ b/lib/libc/tests/db/dbm_perm_test.c @@ -0,0 +1,98 @@ +/*- + * Copyright (c) 2025 Klara, Inc. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <errno.h> +#include <fcntl.h> +#include <ndbm.h> +#include <stdio.h> + +#include <atf-c.h> + +static const char *path = "tmp"; +static const char *dbname = "tmp.db"; + +static void +create_db(void) +{ + DB *db; + datum data, key; + + data.dptr = "bar"; + data.dsize = strlen("bar"); + key.dptr = "foo"; + key.dsize = strlen("foo"); + + db = dbm_open(path, O_RDWR | O_CREAT, 0755); + ATF_CHECK(db != NULL); + ATF_REQUIRE(atf_utils_file_exists(dbname)); + ATF_REQUIRE(dbm_store(db, key, data, DBM_INSERT) != -1); + dbm_close(db); +} + +ATF_TC_WITHOUT_HEAD(dbm_rdonly_test); +ATF_TC_BODY(dbm_rdonly_test, tc) +{ + DB *db; + datum data, key; + + bzero(&data, sizeof(data)); + key.dptr = "foo"; + key.dsize = strlen("foo"); + create_db(); + + db = dbm_open(path, O_RDONLY, 0755); + data = dbm_fetch(db, key); + ATF_REQUIRE(data.dptr != NULL); + ATF_REQUIRE(strncmp((const char*)data.dptr, "bar", data.dsize) == 0); + ATF_REQUIRE(dbm_store(db, key, data, DBM_REPLACE) == -1); + ATF_REQUIRE(errno == EPERM); +} + +ATF_TC_WITHOUT_HEAD(dbm_wronly_test); +ATF_TC_BODY(dbm_wronly_test, tc) +{ + DB *db; + datum data, key; + + key.dptr = "foo"; + key.dsize = strlen("foo"); + data.dptr = "baz"; + data.dsize = strlen("baz"); + create_db(); + + db = dbm_open(path, O_WRONLY, 0755); + data = dbm_fetch(db, key); + ATF_REQUIRE(data.dptr == NULL); + ATF_REQUIRE(errno == EPERM); + ATF_REQUIRE(dbm_store(db, key, data, DBM_REPLACE) != -1); +} + +ATF_TC_WITHOUT_HEAD(dbm_rdwr_test); +ATF_TC_BODY(dbm_rdwr_test, tc) +{ + DB *db; + datum data, key; + + key.dptr = "foo"; + key.dsize = strlen("foo"); + create_db(); + + db = dbm_open(path, O_RDWR, 0755); + data = dbm_fetch(db, key); + ATF_REQUIRE(data.dptr != NULL); + data.dptr = "baz"; + data.dsize = strlen("baz"); + ATF_REQUIRE(dbm_store(db, key, data, DBM_REPLACE) != -1); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, dbm_rdonly_test); + ATF_TP_ADD_TC(tp, dbm_wronly_test); + ATF_TP_ADD_TC(tp, dbm_rdwr_test); + + return (atf_no_error()); +} diff --git a/lib/libthr/thread/thr_getthreadid_np.c b/lib/libthr/thread/thr_getthreadid_np.c index ade332519dfb..ffecd0bc7ea9 100644 --- a/lib/libthr/thread/thr_getthreadid_np.c +++ b/lib/libthr/thread/thr_getthreadid_np.c @@ -36,7 +36,7 @@ __weak_reference(_thr_getthreadid_np, _pthread_getthreadid_np); __weak_reference(_thr_getthreadid_np, pthread_getthreadid_np); /* - * Provide the equivelant to AIX pthread_getthreadid_np() function. + * Provide the equivalent to AIX pthread_getthreadid_np() function. */ int _thr_getthreadid_np(void) diff --git a/release/scripts/pkgbase-stage.lua b/release/scripts/pkgbase-stage.lua index 01eec8c44e49..1b48b4faede3 100755 --- a/release/scripts/pkgbase-stage.lua +++ b/release/scripts/pkgbase-stage.lua @@ -46,7 +46,9 @@ local function select_packages(pkg, media, all_libcompats) table.insert(components["src"], package) elseif package == "FreeBSD-tests" or package:match("^FreeBSD%-tests%-.*") then table.insert(components["tests"], package) - elseif package:match("^FreeBSD%-kernel%-.*") then + elseif package:match("^FreeBSD%-kernel%-.*") and + package ~= "FreeBSD-kernel-man" + then -- Kernels other than FreeBSD-kernel-generic are ignored if package == "FreeBSD-kernel-generic" then table.insert(components["kernel"], package) diff --git a/release/tools/vmimage.subr b/release/tools/vmimage.subr index eb816018e9d3..156987e33457 100644 --- a/release/tools/vmimage.subr +++ b/release/tools/vmimage.subr @@ -118,7 +118,6 @@ vm_emulation_setup() { mkdir -p ${DESTDIR}/dev mount -t devfs devfs ${DESTDIR}/dev - chroot ${DESTDIR} ${EMULATOR} /usr/bin/newaliases chroot ${DESTDIR} ${EMULATOR} /bin/sh /etc/rc.d/ldconfig forcestart cp /etc/resolv.conf ${DESTDIR}/etc/resolv.conf diff --git a/sbin/ping/Makefile b/sbin/ping/Makefile index b4e3f115b245..30c68cbaba52 100644 --- a/sbin/ping/Makefile +++ b/sbin/ping/Makefile @@ -32,8 +32,6 @@ CFLAGS+=-DWITH_CASPER CFLAGS+=-DIPSEC LIBADD+= ipsec -CFLAGS+= -Wno-error=unused-but-set-variable - HAS_TESTS= SUBDIR.${MK_TESTS}+= tests diff --git a/sbin/recoverdisk/recoverdisk.c b/sbin/recoverdisk/recoverdisk.c index e1b283e54a93..f13a1f211863 100644 --- a/sbin/recoverdisk/recoverdisk.c +++ b/sbin/recoverdisk/recoverdisk.c @@ -715,7 +715,7 @@ main(int argc, char * const argv[]) int64_t sz; int error; time_t t_now, t_report, t_save; - unsigned snapshot = 60, unsaved; + time_t snapshot = 60, unsaved; setbuf(stdout, NULL); setbuf(stderr, NULL); diff --git a/sbin/swapon/tests/swapon_test.sh b/sbin/swapon/tests/swapon_test.sh index b6d31ecaeed0..a04bb36cc49e 100755 --- a/sbin/swapon/tests/swapon_test.sh +++ b/sbin/swapon/tests/swapon_test.sh @@ -31,7 +31,10 @@ attach_mdX_head() attach_mdX_body() { # if the swapfile is too small (like 1k) then mdconfig hangs looking up the md - atf_check -s exit:0 -x "truncate -s 10k swapfile" + # but need a swapfile bigger than one page kernel page size + pagesize=$(sysctl -n hw.pagesize) + minsize=$(( pagesize * 2 )) + atf_check -s exit:0 -x "truncate -s $minsize swapfile" atf_check -s exit:0 -o save:fstab.out -x "echo 'md31 none swap sw,file=swapfile 0 0'" atf_check -s exit:0 -o match:"swapon: adding /dev/md31 as swap device" -x "swapon -F fstab.out -a" } @@ -49,7 +52,10 @@ attach_dev_mdX_head() attach_dev_mdX_body() { # if the swapfile is too small (like 1k) then mdconfig hangs looking up the md - atf_check -s exit:0 -x "truncate -s 10k swapfile" + # but need a swapfile bigger than one page kernel page size + pagesize=$(sysctl -n hw.pagesize) + minsize=$(( pagesize * 2 )) + atf_check -s exit:0 -x "truncate -s $minsize swapfile" atf_check -s exit:0 -o save:fstab.out -x "echo '/dev/md32 none swap sw,file=swapfile 0 0'" atf_check -s exit:0 -o match:"swapon: adding /dev/md32 as swap device" -x "swapon -F fstab.out -a" } @@ -67,7 +73,10 @@ attach_md_head() attach_md_body() { # if the swapfile is too small (like 1k) then mdconfig hangs looking up the md - atf_check -s exit:0 -x "truncate -s 10k swapfile" + # but need a swapfile bigger than one page kernel page size + pagesize=$(sysctl -n hw.pagesize) + minsize=$(( pagesize * 2 )) + atf_check -s exit:0 -x "truncate -s $minsize swapfile" atf_check -s exit:0 -o save:fstab.out -x "echo 'md none swap sw,file=swapfile 0 0'" atf_check -s exit:0 -o match:"swapon: adding /dev/md[0-9][0-9]* as swap device" -x "swapon -F fstab.out -a" } @@ -85,7 +94,10 @@ attach_dev_md_head() attach_dev_md_body() { # if the swapfile is too small (like 1k) then mdconfig hangs looking up the md - atf_check -s exit:0 -x "truncate -s 10k swapfile" + # but need a swapfile bigger than one page kernel page size + pagesize=$(sysctl -n hw.pagesize) + minsize=$(( pagesize * 2 )) + atf_check -s exit:0 -x "truncate -s $minsize swapfile" atf_check -s exit:0 -o save:fstab.out -x "echo '/dev/md none swap sw,file=swapfile 0 0'" atf_check -s exit:0 -o match:"swapon: adding /dev/md[0-9][0-9]* as swap device" -x "swapon -F fstab.out -a" } @@ -103,7 +115,10 @@ attach_mdX_eli_head() attach_mdX_eli_body() { # if the swapfile is too small (like 1k) then mdconfig hangs looking up the md - atf_check -s exit:0 -x "truncate -s 10k swapfile" + # but need a swapfile bigger than one page kernel page size + pagesize=$(sysctl -n hw.pagesize) + minsize=$(( pagesize * 2 )) + atf_check -s exit:0 -x "truncate -s $minsize swapfile" atf_check -s exit:0 -o save:fstab.out -x "echo 'md33.eli none swap sw,file=swapfile 0 0'" atf_check -s exit:0 -o match:"swapon: adding /dev/md33.eli as swap device" -x "swapon -F fstab.out -a" } @@ -121,7 +136,10 @@ attach_dev_mdX_eli_head() attach_dev_mdX_eli_body() { # if the swapfile is too small (like 1k) then mdconfig hangs looking up the md - atf_check -s exit:0 -x "truncate -s 10k swapfile" + # but need a swapfile bigger than one page kernel page size + pagesize=$(sysctl -n hw.pagesize) + minsize=$(( pagesize * 2 )) + atf_check -s exit:0 -x "truncate -s $minsize swapfile" atf_check -s exit:0 -o save:fstab.out -x "echo '/dev/md34.eli none swap sw,file=swapfile 0 0'" atf_check -s exit:0 -o match:"swapon: adding /dev/md34.eli as swap device" -x "swapon -F fstab.out -a" } @@ -139,7 +157,10 @@ attach_md_eli_head() attach_md_eli_body() { # if the swapfile is too small (like 1k) then mdconfig hangs looking up the md - atf_check -s exit:0 -x "truncate -s 10k swapfile" + # but need a swapfile bigger than one page kernel page size + pagesize=$(sysctl -n hw.pagesize) + minsize=$(( pagesize * 2 )) + atf_check -s exit:0 -x "truncate -s $minsize swapfile" atf_check -s exit:0 -o save:fstab.out -x "echo 'md.eli none swap sw,file=swapfile 0 0'" atf_check -s exit:0 -o match:"swapon: adding /dev/md[0-9][0-9]*.eli as swap device" -x "swapon -F fstab.out -a" } @@ -157,7 +178,10 @@ attach_dev_md_eli_head() attach_dev_md_eli_body() { # if the swapfile is too small (like 1k) then mdconfig hangs looking up the md - atf_check -s exit:0 -x "truncate -s 10k swapfile" + # but need a swapfile bigger than one page kernel page size + pagesize=$(sysctl -n hw.pagesize) + minsize=$(( pagesize * 2 )) + atf_check -s exit:0 -x "truncate -s $minsize swapfile" atf_check -s exit:0 -o save:fstab.out -x "echo '/dev/md.eli none swap sw,file=swapfile 0 0'" atf_check -s exit:0 -o match:"swapon: adding /dev/md[0-9][0-9]*.eli as swap device" -x "swapon -F fstab.out -a" } @@ -167,6 +191,24 @@ attach_dev_md_eli_cleanup() } ### + +atf_test_case attach_too_small +attach_too_small_head() +{ + atf_set "descr" "should refuse to attach if smaller than one kernel page size" +} +attach_too_small_body() +{ + # Need to use smaller than kernel page size + pagesize=$(sysctl -n hw.pagesize) + minsize=$(( pagesize / 2 )) + atf_check -s exit:0 -x "truncate -s $minsize swapfile" + atf_check -s exit:0 -o save:fstab.out -x "echo 'md35 none swap sw,file=swapfile 0 0'" + atf_check -s exit:1 -e match:"swapon: /dev/md35: NSWAPDEV limit reached" -x "swapon -F fstab.out -a" + atf_check -s exit:0 -x "mdconfig -d -u 35" +} + +### atf_init_test_cases() { atf_add_test_case attach_mdX @@ -178,4 +220,6 @@ atf_init_test_cases() atf_add_test_case attach_dev_mdX_eli atf_add_test_case attach_md_eli atf_add_test_case attach_dev_md_eli + + atf_add_test_case attach_too_small } diff --git a/share/man/man4/usbhid.4 b/share/man/man4/usbhid.4 index 5109bbe72de6..e5ba370cd025 100644 --- a/share/man/man4/usbhid.4 +++ b/share/man/man4/usbhid.4 @@ -21,7 +21,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd January 12, 2021 +.Dd July 30, 2025 .Dt USBHID 4 .Os .Sh NAME @@ -60,7 +60,7 @@ and make its priority greater than other USB HID drivers, such as .Xr ums 4 , and .Xr uhid 4 . -Default is 0. +Default is 1. .El .Bl -tag -width indent .It Va hw.usb.usbhid.debug diff --git a/share/man/man5/src.conf.5 b/share/man/man5/src.conf.5 index f93d3f9fc69f..a3db00aed42f 100644 --- a/share/man/man5/src.conf.5 +++ b/share/man/man5/src.conf.5 @@ -1,5 +1,5 @@ .\" DO NOT EDIT-- this file is @generated by tools/build/options/makeman. -.Dd July 27, 2025 +.Dd July 14, 2025 .Dt SRC.CONF 5 .Os .Sh NAME @@ -940,9 +940,8 @@ amd64/amd64, arm64/aarch64, i386/i386, powerpc/powerpc64 and powerpc/powerpc64le Do not build the LLD linker during the bootstrap phase of the build. To be able to build the system an alternate linker must be provided via XLD. -.It Va WITH_LLVM_ASSERTIONS -Enable debugging assertions in LLVM. -Use when working on or requesting help with LLVM components. +.It Va WITHOUT_LLVM_ASSERTIONS +Disable debugging assertions in LLVM. .It Va WITHOUT_LLVM_BINUTILS Install ELF Tool Chain's binary utilities instead of LLVM's. This includes diff --git a/share/man/man9/style.9 b/share/man/man9/style.9 index e9f17392ae0c..26c7a3b2aa64 100644 --- a/share/man/man9/style.9 +++ b/share/man/man9/style.9 @@ -934,9 +934,9 @@ and Header files should always use a suffix, unlike headers from the C++ standard library. .Pp -Return values should not be enclosed in parantheses. +Return values should not be enclosed in parentheses. When converting existing C code to C++, -existing return values may remain in parantheses. +existing return values may remain in parentheses. .Pp The opening curly brace for namespace declarations should be on the first line similar to structure and class definitions. diff --git a/share/man/man9/ucred.9 b/share/man/man9/ucred.9 index e9fe2e1d02fc..38759bddb5b0 100644 --- a/share/man/man9/ucred.9 +++ b/share/man/man9/ucred.9 @@ -24,7 +24,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH .\" DAMAGE. .\" -.Dd January 23, 2019 +.Dd July 29, 2025 .Dt UCRED 9 .Os .Sh NAME @@ -54,6 +54,9 @@ .Ft void .Fn crsetgroups "struct ucred *cr" "int ngrp" "gid_t *groups" .Ft void +.Fn crsetgroups_and_egid "struct ucred *cr" "int ngrp" "gid_t *groups" \ + "gid_t default_egid" +.Ft void .Fn cru2x "struct ucred *cr" "struct xucred *xcr" .Sh DESCRIPTION The @@ -110,17 +113,28 @@ The actual copying is performed by .Pp The .Fn crsetgroups -function sets the +and +.Fn crsetgroups_and_egid +functions set the .Va cr_groups and .Va cr_ngroups variables and allocates space as needed. -It also truncates the group list to the current maximum number of +They also truncate the group list to the current maximum number of groups. No other mechanism should be used to modify the .Va cr_groups -array except for updating the primary group via assignment to -.Va cr_groups[0] . +array. +Note that +.Fn crsetgroups_and_egid +will interpret the first element of +.Va groups +as the new effective GID and the rest of the array as the supplementary groups, +and +.Va default_egid +will be used as the new effective GID only if +.Va groups +is empty. .Pp The .Fn cru2x diff --git a/share/misc/organization.dot b/share/misc/organization.dot index 1a88bc71b14e..73e879578dd7 100644 --- a/share/misc/organization.dot +++ b/share/misc/organization.dot @@ -30,7 +30,7 @@ doccommitters [label="Doc/www Committers\ndoc-committers@FreeBSD.org"] doceng [label="Documentation Engineering Team\ndoceng@FreeBSD.org\nbcr, gabor, gjb, hrs,\nblackend, ryusuke, wblock"] pkgmgr [label="Package Management Team\npkgmgr@FreeBSD.org\nantoine, bdrewery"] portscommitters [label="Ports Committers\nports-committers@FreeBSD.org"] -portmgr [label="Port Management Team\nportmgr@FreeBSD.org\nbapt, bofh, mat,\npizzamig, rene, tcberner"] +portmgr [label="Port Management Team\nportmgr@FreeBSD.org\nbapt, dvl, mat,\npizzamig, rene, tcberner"] portmgrsecretary [label="Port Management Team Secretary\nportmgr-secretary@FreeBSD.org\nrene"] re [label="Primary Release Engineering Team\nre@FreeBSD.org\ngjb, kib,\nblackend, delphij, cperciva"] secteam [label="Security Team\nsecteam@FreeBSD.org\ndelphij,\ndes, markj,\nemaste,\ngjb, gordon,\noshogbo, philip"] diff --git a/share/mk/src.opts.mk b/share/mk/src.opts.mk index 77923ae7b6d1..ef43d3c939b2 100644 --- a/share/mk/src.opts.mk +++ b/share/mk/src.opts.mk @@ -123,6 +123,7 @@ __DEFAULT_YES_OPTIONS = \ LEGACY_CONSOLE \ LLD \ LLD_BOOTSTRAP \ + LLVM_ASSERTIONS \ LLVM_BINUTILS \ LLVM_COV \ LLVM_CXXFILT \ @@ -209,7 +210,6 @@ __DEFAULT_NO_OPTIONS = \ HESIOD \ LOADER_VERBOSE \ LOADER_VERIEXEC_PASS_MANIFEST \ - LLVM_ASSERTIONS \ LLVM_FULL_DEBUGINFO \ MALLOC_PRODUCTION \ OFED_EXTRA \ diff --git a/share/vt/fonts/INDEX.fonts b/share/vt/fonts/INDEX.fonts index 8a36ccfbf211..dee9e855c42e 100644 --- a/share/vt/fonts/INDEX.fonts +++ b/share/vt/fonts/INDEX.fonts @@ -25,14 +25,6 @@ MENU:da:Vælg skrifttypen til din terminal MENU:de:Wählen Sie Ihre Schrift MENU:fr:Choisissez votre fonte écran -# -# The font definition for "en" is the fall-back font for -# all languages. -# Add language specific font definitions only where required! -# -FONT:en:vgarom-8x14.fnt -# - gallant.fnt:en:Gallant Character set, 12x22 gallant.fnt:da:Gallant-tegnsæt, 12x22 gallant.fnt:de:Gallant Zeichensatz, 12x22 diff --git a/share/vt/keymaps/INDEX.keymaps b/share/vt/keymaps/INDEX.keymaps index 2b1db8528e85..fd00d0e71c87 100644 --- a/share/vt/keymaps/INDEX.keymaps +++ b/share/vt/keymaps/INDEX.keymaps @@ -33,14 +33,6 @@ MENU:el:Επιλέξτε το πληκτρολόγιο της κονσόλας MENU:hy:Ընտրեք ստեղնաշարի դասավորությունը MENU:tr:Klavye düzeninizi seçiniz -# -# The font definition for "en" is the fall-back font for -# all languages. -# Add language specific font definitions only where required! -# -FONT:en:vgarom-8x16.hex - -# am.kbd:en:Armenian phonetic layout am.kbd:da:Armensk fonetisk layout am.kbd:de:Armenische phonetische Tastenbelegung diff --git a/stand/defaults/loader.conf b/stand/defaults/loader.conf index f0843f3e930b..036479d22285 100644 --- a/stand/defaults/loader.conf +++ b/stand/defaults/loader.conf @@ -114,6 +114,7 @@ kernels_autodetect="YES" # Auto-detect kernel directories in /boot #currdev="disk1s1a" # Set the current device module_path="/boot/modules;/boot/firmware;/boot/dtb;/boot/dtb/overlays" # Set the module search path module_blacklist="drm drm2 radeonkms i915kms amdgpu if_iwlwifi if_rtw88 if_rtw89" # Loader module blacklist +module_blacklist="${module_blacklist} nvidia nvidia-drm nvidia-modeset" #prompt="\\${interpret}" # Set the command prompt #root_disk_unit="0" # Force the root disk unit number #rootdev="disk1s1a" # Set the root filesystem diff --git a/stand/libsa/ip.c b/stand/libsa/ip.c index 2c2acf2eda16..6c7b0844b14d 100644 --- a/stand/libsa/ip.c +++ b/stand/libsa/ip.c @@ -181,6 +181,7 @@ readipv4(struct iodesc *d, void **pkt, void **payload, time_t tleft, ssize_t n; size_t hlen; struct ether_header *eh; + void *buf; struct ip *ip; struct udphdr *uh; uint16_t etype; /* host order */ @@ -195,7 +196,7 @@ readipv4(struct iodesc *d, void **pkt, void **payload, time_t tleft, ip = NULL; ptr = NULL; - n = readether(d, (void **)&ptr, (void **)&ip, tleft, &etype); + n = readether(d, (void **)&ptr, (void **)&buf, tleft, &etype); if (n == -1 || n < sizeof(*ip) + sizeof(*uh)) { free(ptr); return (-1); @@ -205,7 +206,7 @@ readipv4(struct iodesc *d, void **pkt, void **payload, time_t tleft, /* Need to respond to ARP requests. */ if (etype == ETHERTYPE_ARP) { - struct arphdr *ah = (void *)ip; + struct arphdr *ah = buf; if (ah->ar_op == htons(ARPOP_REQUEST)) { /* Send ARP reply */ arp_reply(d, ah); @@ -224,6 +225,7 @@ readipv4(struct iodesc *d, void **pkt, void **payload, time_t tleft, return (-1); } + ip = buf; /* Check ip header */ if (ip->ip_v != IPVERSION || /* half char */ ip->ip_p != proto) { diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c index b88f1451f1a2..5e32353c6b8e 100644 --- a/sys/compat/linux/linux_misc.c +++ b/sys/compat/linux/linux_misc.c @@ -1030,47 +1030,33 @@ linux_setgroups(struct thread *td, struct linux_setgroups_args *args) { struct ucred *newcred, *oldcred; l_gid_t *linux_gidset; - gid_t *bsd_gidset; int ngrp, error; struct proc *p; ngrp = args->gidsetsize; - if (ngrp < 0 || ngrp >= ngroups_max + 1) + if (ngrp < 0 || ngrp >= ngroups_max) return (EINVAL); linux_gidset = malloc(ngrp * sizeof(*linux_gidset), M_LINUX, M_WAITOK); error = copyin(args->grouplist, linux_gidset, ngrp * sizeof(l_gid_t)); if (error) goto out; newcred = crget(); - crextend(newcred, ngrp + 1); + crextend(newcred, ngrp); p = td->td_proc; PROC_LOCK(p); oldcred = p->p_ucred; crcopy(newcred, oldcred); - /* - * cr_groups[0] holds egid. Setting the whole set from - * the supplied set will cause egid to be changed too. - * Keep cr_groups[0] unchanged to prevent that. - */ - if ((error = priv_check_cred(oldcred, PRIV_CRED_SETGROUPS)) != 0) { PROC_UNLOCK(p); crfree(newcred); goto out; } - if (ngrp > 0) { - newcred->cr_ngroups = ngrp + 1; - - bsd_gidset = newcred->cr_groups; - ngrp--; - while (ngrp >= 0) { - bsd_gidset[ngrp + 1] = linux_gidset[ngrp]; - ngrp--; - } - } else - newcred->cr_ngroups = 1; + newcred->cr_ngroups = ngrp; + for (int i = 0; i < ngrp; i++) + newcred->cr_groups[i] = linux_gidset[i]; + newcred->cr_flags |= CRED_FLAG_GROUPSET; setsugid(p); proc_set_cred(p, newcred); @@ -1092,13 +1078,7 @@ linux_getgroups(struct thread *td, struct linux_getgroups_args *args) cred = td->td_ucred; bsd_gidset = cred->cr_groups; - bsd_gidsetsz = cred->cr_ngroups - 1; - - /* - * cr_groups[0] holds egid. Returning the whole set - * here will cause a duplicate. Exclude cr_groups[0] - * to prevent that. - */ + bsd_gidsetsz = cred->cr_ngroups; if ((ngrp = args->gidsetsize) == 0) { td->td_retval[0] = bsd_gidsetsz; @@ -1112,7 +1092,7 @@ linux_getgroups(struct thread *td, struct linux_getgroups_args *args) linux_gidset = malloc(bsd_gidsetsz * sizeof(*linux_gidset), M_LINUX, M_WAITOK); while (ngrp < bsd_gidsetsz) { - linux_gidset[ngrp] = bsd_gidset[ngrp + 1]; + linux_gidset[ngrp] = bsd_gidset[ngrp]; ngrp++; } diff --git a/sys/compat/linux/linux_uid16.c b/sys/compat/linux/linux_uid16.c index a0c9f1c39198..1d9a19916412 100644 --- a/sys/compat/linux/linux_uid16.c +++ b/sys/compat/linux/linux_uid16.c @@ -87,12 +87,11 @@ linux_setgroups16(struct thread *td, struct linux_setgroups16_args *args) { struct ucred *newcred, *oldcred; l_gid16_t *linux_gidset; - gid_t *bsd_gidset; int ngrp, error; struct proc *p; ngrp = args->gidsetsize; - if (ngrp < 0 || ngrp >= ngroups_max + 1) + if (ngrp < 0 || ngrp >= ngroups_max) return (EINVAL); linux_gidset = malloc(ngrp * sizeof(*linux_gidset), M_LINUX, M_WAITOK); error = copyin(args->gidset, linux_gidset, ngrp * sizeof(l_gid16_t)); @@ -106,12 +105,6 @@ linux_setgroups16(struct thread *td, struct linux_setgroups16_args *args) PROC_LOCK(p); oldcred = crcopysafe(p, newcred); - /* - * cr_groups[0] holds egid. Setting the whole set from - * the supplied set will cause egid to be changed too. - * Keep cr_groups[0] unchanged to prevent that. - */ - if ((error = priv_check_cred(oldcred, PRIV_CRED_SETGROUPS)) != 0) { PROC_UNLOCK(p); crfree(newcred); @@ -121,18 +114,10 @@ linux_setgroups16(struct thread *td, struct linux_setgroups16_args *args) goto out; } - if (ngrp > 0) { - newcred->cr_ngroups = ngrp + 1; - - bsd_gidset = newcred->cr_groups; - ngrp--; - while (ngrp >= 0) { - bsd_gidset[ngrp + 1] = linux_gidset[ngrp]; - ngrp--; - } - } - else - newcred->cr_ngroups = 1; + newcred->cr_ngroups = ngrp; + for (int i = 0; i < ngrp; i++) + newcred->cr_groups[i] = linux_gidset[i]; + newcred->cr_flags |= CRED_FLAG_GROUPSET; setsugid(td->td_proc); proc_set_cred(p, newcred); @@ -155,13 +140,7 @@ linux_getgroups16(struct thread *td, struct linux_getgroups16_args *args) cred = td->td_ucred; bsd_gidset = cred->cr_groups; - bsd_gidsetsz = cred->cr_ngroups - 1; - - /* - * cr_groups[0] holds egid. Returning the whole set - * here will cause a duplicate. Exclude cr_groups[0] - * to prevent that. - */ + bsd_gidsetsz = cred->cr_ngroups; if ((ngrp = args->gidsetsize) == 0) { td->td_retval[0] = bsd_gidsetsz; @@ -175,7 +154,7 @@ linux_getgroups16(struct thread *td, struct linux_getgroups16_args *args) linux_gidset = malloc(bsd_gidsetsz * sizeof(*linux_gidset), M_LINUX, M_WAITOK); while (ngrp < bsd_gidsetsz) { - linux_gidset[ngrp] = bsd_gidset[ngrp + 1]; + linux_gidset[ngrp] = bsd_gidset[ngrp]; ngrp++; } diff --git a/sys/compat/linuxkpi/common/include/acpi/acpi_bus.h b/sys/compat/linuxkpi/common/include/acpi/acpi_bus.h index 47195e7d66a6..da50d25a63bb 100644 --- a/sys/compat/linuxkpi/common/include/acpi/acpi_bus.h +++ b/sys/compat/linuxkpi/common/include/acpi/acpi_bus.h @@ -45,9 +45,9 @@ struct acpi_bus_event { lkpi_acpi_dev_get_first_match_dev(__VA_ARGS__) ACPI_HANDLE bsd_acpi_get_handle(device_t bsddev); -bool acpi_check_dsm(ACPI_HANDLE handle, const char *uuid, int rev, +bool acpi_check_dsm(ACPI_HANDLE handle, const guid_t *uuid, int rev, uint64_t funcs); -ACPI_OBJECT * acpi_evaluate_dsm_typed(ACPI_HANDLE handle, const char *uuid, +ACPI_OBJECT * acpi_evaluate_dsm_typed(ACPI_HANDLE handle, const guid_t *uuid, int rev, int func, ACPI_OBJECT *argv4, ACPI_OBJECT_TYPE type); int register_acpi_notifier(struct notifier_block *nb); diff --git a/sys/compat/linuxkpi/common/include/linux/pci.h b/sys/compat/linuxkpi/common/include/linux/pci.h index af19829f1cbb..ba1c0d2ac99e 100644 --- a/sys/compat/linuxkpi/common/include/linux/pci.h +++ b/sys/compat/linuxkpi/common/include/linux/pci.h @@ -4,7 +4,7 @@ * Copyright (c) 2010 Panasas, Inc. * Copyright (c) 2013-2016 Mellanox Technologies, Ltd. * All rights reserved. - * Copyright (c) 2020-2022 The FreeBSD Foundation + * Copyright (c) 2020-2025 The FreeBSD Foundation * * Portions of this software were developed by Björn Zeeb * under sponsorship from the FreeBSD Foundation. @@ -362,9 +362,9 @@ bool pci_device_is_present(struct pci_dev *pdev); int linuxkpi_pcim_enable_device(struct pci_dev *pdev); void __iomem **linuxkpi_pcim_iomap_table(struct pci_dev *pdev); -void *linuxkpi_pci_iomap_range(struct pci_dev *pdev, int mmio_bar, - unsigned long mmio_off, unsigned long mmio_size); -void *linuxkpi_pci_iomap(struct pci_dev *pdev, int mmio_bar, int mmio_size); +void *linuxkpi_pci_iomap_range(struct pci_dev *, int, + unsigned long, unsigned long); +void *linuxkpi_pci_iomap(struct pci_dev *, int, unsigned long); void linuxkpi_pci_iounmap(struct pci_dev *pdev, void *res); int linuxkpi_pcim_iomap_regions(struct pci_dev *pdev, uint32_t mask, const char *name); @@ -377,7 +377,7 @@ int linuxkpi_pci_enable_msix(struct pci_dev *pdev, struct msix_entry *entries, /* Internal helper function(s). */ struct pci_dev *lkpinew_pci_dev(device_t); void lkpi_pci_devres_release(struct device *, void *); -struct pci_dev *lkpi_pci_get_device(uint16_t, uint16_t, struct pci_dev *); +struct pci_dev *lkpi_pci_get_device(uint32_t, uint32_t, struct pci_dev *); struct msi_desc *lkpi_pci_msi_desc_alloc(int); struct device *lkpi_pci_find_irq_dev(unsigned int irq); int _lkpi_pci_enable_msi_range(struct pci_dev *pdev, int minvec, int maxvec); @@ -561,10 +561,12 @@ done: return (pdev->bus->self); } -#define pci_release_region(pdev, bar) linuxkpi_pci_release_region(pdev, bar) -#define pci_release_regions(pdev) linuxkpi_pci_release_regions(pdev) -#define pci_request_regions(pdev, res_name) \ - linuxkpi_pci_request_regions(pdev, res_name) +#define pci_release_region(pdev, bar) \ + linuxkpi_pci_release_region(pdev, bar) +#define pci_release_regions(pdev) \ + linuxkpi_pci_release_regions(pdev) +#define pci_request_regions(pdev, res_name) \ + linuxkpi_pci_request_regions(pdev, res_name) static inline void lkpi_pci_disable_msix(struct pci_dev *pdev) @@ -730,8 +732,10 @@ int linux_pci_register_drm_driver(struct pci_driver *pdrv); void linux_pci_unregister_driver(struct pci_driver *pdrv); void linux_pci_unregister_drm_driver(struct pci_driver *pdrv); -#define pci_register_driver(pdrv) linux_pci_register_driver(pdrv) -#define pci_unregister_driver(pdrv) linux_pci_unregister_driver(pdrv) +#define pci_register_driver(pdrv) \ + linux_pci_register_driver(pdrv) +#define pci_unregister_driver(pdrv) \ + linux_pci_unregister_driver(pdrv) /* * Enable msix, positive errors indicate actual number of available @@ -740,10 +744,11 @@ void linux_pci_unregister_drm_driver(struct pci_driver *pdrv); * NB: define added to prevent this definition of pci_enable_msix from * clashing with the native FreeBSD version. */ -#define pci_enable_msix(...) linuxkpi_pci_enable_msix(__VA_ARGS__) +#define pci_enable_msix(...) \ + linuxkpi_pci_enable_msix(__VA_ARGS__) -#define pci_enable_msix_range(...) \ - linux_pci_enable_msix_range(__VA_ARGS__) +#define pci_enable_msix_range(...) \ + linux_pci_enable_msix_range(__VA_ARGS__) static inline int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, @@ -768,8 +773,8 @@ pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, return (nvec); } -#define pci_enable_msi(pdev) \ - linux_pci_enable_msi(pdev) +#define pci_enable_msi(pdev) \ + linux_pci_enable_msi(pdev) static inline int pci_enable_msi(struct pci_dev *pdev) @@ -794,11 +799,12 @@ static inline void pci_disable_sriov(struct pci_dev *dev) { } -#define pci_iomap_range(pdev, mmio_bar, mmio_off, mmio_size) \ - linuxkpi_pci_iomap_range(pdev, mmio_bar, mmio_off, mmio_size) -#define pci_iomap(pdev, mmio_bar, mmio_size) \ - linuxkpi_pci_iomap(pdev, mmio_bar, mmio_size) -#define pci_iounmap(pdev, res) linuxkpi_pci_iounmap(pdev, res) +#define pci_iomap_range(pdev, mmio_bar, mmio_off, mmio_size) \ + linuxkpi_pci_iomap_range(pdev, mmio_bar, mmio_off, mmio_size) +#define pci_iomap(pdev, mmio_bar, mmio_size) \ + linuxkpi_pci_iomap(pdev, mmio_bar, mmio_size) +#define pci_iounmap(pdev, res) \ + linuxkpi_pci_iounmap(pdev, res) static inline void lkpi_pci_save_state(struct pci_dev *pdev) @@ -1387,10 +1393,12 @@ struct pci_dev *lkpi_pci_get_base_class(unsigned int class, /* -------------------------------------------------------------------------- */ -#define pcim_enable_device(pdev) linuxkpi_pcim_enable_device(pdev) -#define pcim_iomap_table(pdev) linuxkpi_pcim_iomap_table(pdev) -#define pcim_iomap_regions(pdev, mask, name) \ - linuxkpi_pcim_iomap_regions(pdev, mask, name) +#define pcim_enable_device(pdev) \ + linuxkpi_pcim_enable_device(pdev) +#define pcim_iomap_table(pdev) \ + linuxkpi_pcim_iomap_table(pdev) +#define pcim_iomap_regions(pdev, mask, name) \ + linuxkpi_pcim_iomap_regions(pdev, mask, name) static inline int pcim_iomap_regions_request_all(struct pci_dev *pdev, uint32_t mask, char *name) @@ -1431,7 +1439,7 @@ err: * using pci_get_device() need to be changed to call linuxkpi_pci_get_device(). */ static inline struct pci_dev * -linuxkpi_pci_get_device(uint16_t vendor, uint16_t device, struct pci_dev *odev) +linuxkpi_pci_get_device(uint32_t vendor, uint32_t device, struct pci_dev *odev) { return (lkpi_pci_get_device(vendor, device, odev)); diff --git a/sys/compat/linuxkpi/common/src/linux_acpi.c b/sys/compat/linuxkpi/common/src/linux_acpi.c index d18c69d9210d..43783bb8727b 100644 --- a/sys/compat/linuxkpi/common/src/linux_acpi.c +++ b/sys/compat/linuxkpi/common/src/linux_acpi.c @@ -72,8 +72,9 @@ bsd_acpi_get_handle(device_t bsddev) } bool -acpi_check_dsm(ACPI_HANDLE handle, const char *uuid, int rev, uint64_t funcs) +acpi_check_dsm(ACPI_HANDLE handle, const guid_t *uuid, int rev, uint64_t funcs) { + UINT64 ret; if (funcs == 0) return (false); @@ -87,17 +88,20 @@ acpi_check_dsm(ACPI_HANDLE handle, const char *uuid, int rev, uint64_t funcs) */ funcs |= 1 << 0; - return ((acpi_DSMQuery(handle, uuid, rev) & funcs) == funcs); + ret = acpi_DSMQuery(handle, (const uint8_t *)uuid, rev); + return ((ret & funcs) == funcs); } ACPI_OBJECT * -acpi_evaluate_dsm_typed(ACPI_HANDLE handle, const char *uuid, int rev, +acpi_evaluate_dsm_typed(ACPI_HANDLE handle, const guid_t *uuid, int rev, int func, ACPI_OBJECT *argv4, ACPI_OBJECT_TYPE type) { ACPI_BUFFER buf; + ACPI_STATUS status; - return (ACPI_SUCCESS(acpi_EvaluateDSMTyped(handle, uuid, rev, func, - argv4, &buf, type)) ? (ACPI_OBJECT *)buf.Pointer : NULL); + status = acpi_EvaluateDSMTyped(handle, (const uint8_t *)uuid, rev, func, + argv4, &buf, type); + return (ACPI_SUCCESS(status) ? (ACPI_OBJECT *)buf.Pointer : NULL); } union linuxkpi_acpi_object * @@ -105,9 +109,11 @@ acpi_evaluate_dsm(ACPI_HANDLE ObjHandle, const guid_t *guid, UINT64 rev, UINT64 func, union linuxkpi_acpi_object *pkg) { ACPI_BUFFER buf; + ACPI_STATUS status; - return (ACPI_SUCCESS(acpi_EvaluateDSM(ObjHandle, (const uint8_t *)guid, - rev, func, (ACPI_OBJECT *)pkg, &buf)) ? + status = acpi_EvaluateDSM(ObjHandle, (const uint8_t *)guid, rev, func, + (ACPI_OBJECT *)pkg, &buf); + return (ACPI_SUCCESS(status) ? (union linuxkpi_acpi_object *)buf.Pointer : NULL); } @@ -323,13 +329,13 @@ bsd_acpi_get_handle(device_t bsddev) } bool -acpi_check_dsm(ACPI_HANDLE handle, const char *uuid, int rev, uint64_t funcs) +acpi_check_dsm(ACPI_HANDLE handle, const guid_t *uuid, int rev, uint64_t funcs) { return (false); } ACPI_OBJECT * -acpi_evaluate_dsm_typed(ACPI_HANDLE handle, const char *uuid, int rev, +acpi_evaluate_dsm_typed(ACPI_HANDLE handle, const guid_t *uuid, int rev, int func, ACPI_OBJECT *argv4, ACPI_OBJECT_TYPE type) { return (NULL); diff --git a/sys/compat/linuxkpi/common/src/linux_pci.c b/sys/compat/linuxkpi/common/src/linux_pci.c index 55202da00440..d5bbbea1eb2c 100644 --- a/sys/compat/linuxkpi/common/src/linux_pci.c +++ b/sys/compat/linuxkpi/common/src/linux_pci.c @@ -1,7 +1,7 @@ /*- * Copyright (c) 2015-2016 Mellanox Technologies, Ltd. * All rights reserved. - * Copyright (c) 2020-2022 The FreeBSD Foundation + * Copyright (c) 2020-2025 The FreeBSD Foundation * * Portions of this software were developed by Björn Zeeb * under sponsorship from the FreeBSD Foundation. @@ -285,7 +285,7 @@ linux_pci_find(device_t dev, const struct pci_device_id **idp) } struct pci_dev * -lkpi_pci_get_device(uint16_t vendor, uint16_t device, struct pci_dev *odev) +lkpi_pci_get_device(uint32_t vendor, uint32_t device, struct pci_dev *odev) { struct pci_dev *pdev, *found; @@ -752,7 +752,7 @@ linuxkpi_pcim_iomap_table(struct pci_dev *pdev) } static struct resource * -_lkpi_pci_iomap(struct pci_dev *pdev, int bar, int mmio_size __unused) +_lkpi_pci_iomap(struct pci_dev *pdev, int bar, unsigned long maxlen __unused) { struct pci_mmio_region *mmio, *p; int type; @@ -792,25 +792,25 @@ _lkpi_pci_iomap(struct pci_dev *pdev, int bar, int mmio_size __unused) } void * -linuxkpi_pci_iomap_range(struct pci_dev *pdev, int mmio_bar, - unsigned long mmio_off, unsigned long mmio_size) +linuxkpi_pci_iomap_range(struct pci_dev *pdev, int bar, + unsigned long off, unsigned long maxlen) { struct resource *res; - res = _lkpi_pci_iomap(pdev, mmio_bar, mmio_size); + res = _lkpi_pci_iomap(pdev, bar, maxlen); if (res == NULL) return (NULL); /* This is a FreeBSD extension so we can use bus_*(). */ if (pdev->want_iomap_res) return (res); - MPASS(mmio_off < rman_get_size(res)); - return ((void *)(rman_get_bushandle(res) + mmio_off)); + MPASS(off < rman_get_size(res)); + return ((void *)(rman_get_bushandle(res) + off)); } void * -linuxkpi_pci_iomap(struct pci_dev *pdev, int mmio_bar, int mmio_size) +linuxkpi_pci_iomap(struct pci_dev *pdev, int bar, unsigned long maxlen) { - return (linuxkpi_pci_iomap_range(pdev, mmio_bar, 0, mmio_size)); + return (linuxkpi_pci_iomap_range(pdev, bar, 0, maxlen)); } void diff --git a/sys/dev/mmc/host/dwmmc.c b/sys/dev/mmc/host/dwmmc.c index 57992571982c..a422d86d6034 100644 --- a/sys/dev/mmc/host/dwmmc.c +++ b/sys/dev/mmc/host/dwmmc.c @@ -315,20 +315,11 @@ static void dwmmc_cmd_done(struct dwmmc_softc *sc) { struct mmc_command *cmd; -#ifdef MMCCAM - union ccb *ccb; -#endif -#ifdef MMCCAM - ccb = sc->ccb; - if (ccb == NULL) - return; - cmd = &ccb->mmcio.cmd; -#else + DWMMC_ASSERT_LOCKED(sc); + cmd = sc->curcmd; -#endif - if (cmd == NULL) - return; + KASSERT(cmd != NULL, ("%s: sc %p curcmd %p == NULL", __func__, sc, cmd)); if (cmd->flags & MMC_RSP_PRESENT) { if (cmd->flags & MMC_RSP_136) { @@ -350,15 +341,17 @@ dwmmc_tasklet(struct dwmmc_softc *sc) { struct mmc_command *cmd; + DWMMC_ASSERT_LOCKED(sc); + cmd = sc->curcmd; - if (cmd == NULL) - return; + KASSERT(cmd != NULL, ("%s: sc %p curcmd %p == NULL", __func__, sc, cmd)); if (!sc->cmd_done) return; if (cmd->error != MMC_ERR_NONE || !cmd->data) { dwmmc_next_operation(sc); + } else if (cmd->data && sc->dto_rcvd) { if ((cmd->opcode == MMC_WRITE_MULTIPLE_BLOCK || cmd->opcode == MMC_READ_MULTIPLE_BLOCK) && @@ -383,6 +376,7 @@ dwmmc_intr(void *arg) DWMMC_LOCK(sc); cmd = sc->curcmd; + KASSERT(cmd != NULL, ("%s: sc %p curcmd %p == NULL", __func__, sc, cmd)); /* First handle SDMMC controller interrupts */ reg = READ4(sc, SDMMC_MINTSTS); @@ -1093,6 +1087,9 @@ dwmmc_start_cmd(struct dwmmc_softc *sc, struct mmc_command *cmd) uint32_t cmdr; dprintf("%s\n", __func__); + + DWMMC_ASSERT_LOCKED(sc); + sc->curcmd = cmd; data = cmd->data; @@ -1177,18 +1174,22 @@ dwmmc_start_cmd(struct dwmmc_softc *sc, struct mmc_command *cmd) static void dwmmc_next_operation(struct dwmmc_softc *sc) { - struct mmc_command *cmd; - dprintf("%s\n", __func__); #ifdef MMCCAM union ccb *ccb; +#else + struct mmc_request *req; +#endif + struct mmc_command *cmd; + dprintf("%s\n", __func__); + DWMMC_ASSERT_LOCKED(sc); + +#ifdef MMCCAM ccb = sc->ccb; if (ccb == NULL) return; cmd = &ccb->mmcio.cmd; #else - struct mmc_request *req; - req = sc->req; if (req == NULL) return; @@ -1205,7 +1206,7 @@ dwmmc_next_operation(struct dwmmc_softc *sc) * mostly caused by multi-block write command * followed by single-read. */ - while(READ4(sc, SDMMC_STATUS) & (SDMMC_STATUS_DATA_BUSY)) + while (READ4(sc, SDMMC_STATUS) & (SDMMC_STATUS_DATA_BUSY)) continue; if (sc->flags & PENDING_CMD) { @@ -1219,50 +1220,44 @@ dwmmc_next_operation(struct dwmmc_softc *sc) return; } -#ifdef MMCCAM - sc->ccb = NULL; sc->curcmd = NULL; +#ifdef MMCCAM ccb->ccb_h.status = (ccb->mmcio.cmd.error == 0 ? CAM_REQ_CMP : CAM_REQ_CMP_ERR); xpt_done(ccb); + sc->ccb = NULL; #else - sc->req = NULL; - sc->curcmd = NULL; req->done(req); + sc->req = NULL; #endif } +#ifndef MMCCAM static int dwmmc_request(device_t brdev, device_t reqdev, struct mmc_request *req) { struct dwmmc_softc *sc; - sc = device_get_softc(brdev); - dprintf("%s\n", __func__); - DWMMC_LOCK(sc); + sc = device_get_softc(brdev); -#ifdef MMCCAM - sc->flags |= PENDING_CMD; -#else + DWMMC_LOCK(sc); if (sc->req != NULL) { DWMMC_UNLOCK(sc); return (EBUSY); } - sc->req = req; sc->flags |= PENDING_CMD; if (sc->req->stop) sc->flags |= PENDING_STOP; -#endif - dwmmc_next_operation(sc); + dwmmc_next_operation(sc); DWMMC_UNLOCK(sc); + return (0); } -#ifndef MMCCAM static int dwmmc_get_ro(device_t brdev, device_t reqdev) { @@ -1505,10 +1500,15 @@ dwmmc_cam_request(device_t dev, union ccb *ccb) struct ccb_mmcio *mmcio; sc = device_get_softc(dev); - mmcio = &ccb->mmcio; - DWMMC_LOCK(sc); + KASSERT(ccb->ccb_h.pinfo.index == CAM_ACTIVE_INDEX, + ("%s: ccb %p index %d != CAM_ACTIVE_INDEX: func=%#x %s status %#x\n", + __func__, ccb, ccb->ccb_h.pinfo.index, ccb->ccb_h.func_code, + xpt_action_name(ccb->ccb_h.func_code), ccb->ccb_h.status)); + + mmcio = &ccb->mmcio; + #ifdef DEBUG if (__predict_false(bootverbose)) { device_printf(sc->dev, "CMD%u arg %#x flags %#x dlen %u dflags %#x\n", @@ -1519,16 +1519,21 @@ dwmmc_cam_request(device_t dev, union ccb *ccb) #endif if (mmcio->cmd.data != NULL) { if (mmcio->cmd.data->len == 0 || mmcio->cmd.data->flags == 0) - panic("data->len = %d, data->flags = %d -- something is b0rked", - (int)mmcio->cmd.data->len, mmcio->cmd.data->flags); + panic("%s: data %p data->len = %d, data->flags = %d -- something is b0rked", + __func__, mmcio->cmd.data, (int)mmcio->cmd.data->len, mmcio->cmd.data->flags); } + if (sc->ccb != NULL) { - device_printf(sc->dev, "Controller still has an active command\n"); + device_printf(sc->dev, "%s: Controller still has an active command: " + "sc->ccb %p new ccb %p\n", __func__, sc->ccb, ccb); + DWMMC_UNLOCK(sc); return (EBUSY); } sc->ccb = ccb; + sc->flags |= PENDING_CMD; + + dwmmc_next_operation(sc); DWMMC_UNLOCK(sc); - dwmmc_request(sc->dev, NULL, NULL); return (0); } diff --git a/sys/dev/usb/input/usbhid.c b/sys/dev/usb/input/usbhid.c index 3bb7d5e594e3..df810012b3f8 100644 --- a/sys/dev/usb/input/usbhid.c +++ b/sys/dev/usb/input/usbhid.c @@ -76,7 +76,7 @@ #include "hid_if.h" static SYSCTL_NODE(_hw_usb, OID_AUTO, usbhid, CTLFLAG_RW, 0, "USB usbhid"); -static int usbhid_enable = 0; +static int usbhid_enable = 1; SYSCTL_INT(_hw_usb_usbhid, OID_AUTO, enable, CTLFLAG_RWTUN, &usbhid_enable, 0, "Enable usbhid and prefer it to other USB HID drivers"); #ifdef USB_DEBUG diff --git a/sys/fs/nfs/nfs_commonport.c b/sys/fs/nfs/nfs_commonport.c index 222cfc03e4b3..e5fdb395c9f7 100644 --- a/sys/fs/nfs/nfs_commonport.c +++ b/sys/fs/nfs/nfs_commonport.c @@ -258,7 +258,7 @@ newnfs_copycred(struct nfscred *nfscr, struct ucred *cr) KASSERT(nfscr->nfsc_ngroups >= 0, ("newnfs_copycred: negative nfsc_ngroups")); cr->cr_uid = nfscr->nfsc_uid; - crsetgroups_fallback(cr, nfscr->nfsc_ngroups, nfscr->nfsc_groups, + crsetgroups_and_egid(cr, nfscr->nfsc_ngroups, nfscr->nfsc_groups, GID_NOGROUP); } @@ -380,8 +380,7 @@ newnfs_setroot(struct ucred *cred) cred->cr_uid = 0; cred->cr_gid = 0; - /* XXXKE Fix this if cr_gid gets separated out. */ - cred->cr_ngroups = 1; + cred->cr_ngroups = 0; } /* diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c index a957315aaa12..4ffc4ce5c29f 100644 --- a/sys/fs/nfs/nfs_commonsubs.c +++ b/sys/fs/nfs/nfs_commonsubs.c @@ -4143,7 +4143,7 @@ nfssvc_idname(struct nfsd_idargs *nidp) */ cr = crget(); cr->cr_uid = cr->cr_ruid = cr->cr_svuid = nidp->nid_uid; - crsetgroups_fallback(cr, nidp->nid_ngroup, grps, + crsetgroups_and_egid(cr, nidp->nid_ngroup, grps, GID_NOGROUP); cr->cr_rgid = cr->cr_svgid = cr->cr_gid; cr->cr_prison = curthread->td_ucred->cr_prison; diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c index 36b534be531e..920fcf7b8c61 100644 --- a/sys/fs/nfsclient/nfs_clrpcops.c +++ b/sys/fs/nfsclient/nfs_clrpcops.c @@ -6934,8 +6934,7 @@ nfscl_dofflayoutio(vnode_t vp, struct uio *uiop, int *iomode, int *must_commit, tcred = NFSNEWCRED(cred); tcred->cr_uid = flp->nfsfl_ffm[mirror].user; tcred->cr_gid = flp->nfsfl_ffm[mirror].group; - /* XXXKE Fix this if cr_gid gets separated out. */ - tcred->cr_ngroups = 1; + tcred->cr_ngroups = 0; } else tcred = cred; if (rwflag == NFSV4OPEN_ACCESSREAD) diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c index 4f0d5946d6b9..8c427c66c156 100644 --- a/sys/fs/nfsserver/nfs_nfsdport.c +++ b/sys/fs/nfsserver/nfs_nfsdport.c @@ -3463,9 +3463,10 @@ nfsd_excred(struct nfsrv_descript *nd, struct nfsexstuff *exp, NFSVNO_EXPORTANON(exp) || (nd->nd_flag & ND_AUTHNONE) != 0) { nd->nd_cred->cr_uid = credanon->cr_uid; + nd->nd_cred->cr_gid = credanon->cr_gid; /* * 'credanon' is already a 'struct ucred' that was built - * internally with calls to crsetgroups_fallback(), so + * internally with calls to crsetgroups_and_egid(), so * we don't need a fallback here. */ crsetgroups(nd->nd_cred, credanon->cr_ngroups, diff --git a/sys/fs/nfsserver/nfs_nfsdsocket.c b/sys/fs/nfsserver/nfs_nfsdsocket.c index d1b6198ba0e1..d6832b4f74be 100644 --- a/sys/fs/nfsserver/nfs_nfsdsocket.c +++ b/sys/fs/nfsserver/nfs_nfsdsocket.c @@ -1425,7 +1425,7 @@ nfsrv_createrootcred(void) cr = crget(); cr->cr_uid = cr->cr_ruid = cr->cr_svuid = UID_ROOT; - crsetgroups_fallback(cr, 0, NULL, GID_WHEEL); + crsetgroups_and_egid(cr, 0, NULL, GID_WHEEL); cr->cr_rgid = cr->cr_svgid = cr->cr_gid; cr->cr_prison = curthread->td_ucred->cr_prison; prison_hold(cr->cr_prison); diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c index 0f0bc056cafd..6bdef84a34c1 100644 --- a/sys/kern/kern_prot.c +++ b/sys/kern/kern_prot.c @@ -99,12 +99,11 @@ static inline void groups_check_positive_len(int ngrp) { MPASS2(ngrp >= 0, "negative number of groups"); - MPASS2(ngrp != 0, "at least one group expected (effective GID)"); } static inline void groups_check_max_len(int ngrp) { - MPASS2(ngrp <= ngroups_max + 1, "too many groups"); + MPASS2(ngrp <= ngroups_max, "too many supplementary groups"); } static void groups_normalize(int *ngrp, gid_t *groups); @@ -321,10 +320,17 @@ int sys_getgroups(struct thread *td, struct getgroups_args *uap) { struct ucred *cred; + gid_t *ugidset; int ngrp, error; cred = td->td_ucred; - ngrp = cred->cr_ngroups; + + /* + * cr_gid has been moved out of cr_groups, but we'll continue exporting + * the egid as groups[0] for the time being until we audit userland for + * any surprises. + */ + ngrp = cred->cr_ngroups + 1; if (uap->gidsetsize == 0) { error = 0; @@ -333,7 +339,14 @@ sys_getgroups(struct thread *td, struct getgroups_args *uap) if (uap->gidsetsize < ngrp) return (EINVAL); - error = copyout(cred->cr_groups, uap->gidset, ngrp * sizeof(gid_t)); + ugidset = uap->gidset; + error = copyout(&cred->cr_gid, ugidset, sizeof(*ugidset)); + if (error != 0) + goto out; + + if (ngrp > 1) + error = copyout(cred->cr_groups, ugidset + 1, + (ngrp - 1) * sizeof(*ugidset)); out: td->td_retval[0] = ngrp; return (error); @@ -499,8 +512,8 @@ gidp_cmp(const void *p1, const void *p2) } /* - * Final storage for groups (including the effective GID) will be returned via - * 'groups'. '*groups' must be NULL on input, and if not equal to 'smallgroups' + * Final storage for supplementary groups will be returned via 'groups'. + * '*groups' must be NULL on input, and if not equal to 'smallgroups' * on output, must be freed (M_TEMP) *even if* an error is returned. */ static int @@ -525,15 +538,15 @@ kern_setcred_copyin_supp_groups(struct setcred *const wcred, * now, to avoid having to allocate and copy again the * supplementary groups. */ - *groups = wcred->sc_supp_groups_nb < CRED_SMALLGROUPS_NB ? - smallgroups : malloc((wcred->sc_supp_groups_nb + 1) * + *groups = wcred->sc_supp_groups_nb <= CRED_SMALLGROUPS_NB ? + smallgroups : malloc(wcred->sc_supp_groups_nb * sizeof(*groups), M_TEMP, M_WAITOK); - error = copyin(wcred->sc_supp_groups, *groups + 1, + error = copyin(wcred->sc_supp_groups, *groups, wcred->sc_supp_groups_nb * sizeof(*groups)); if (error != 0) return (error); - wcred->sc_supp_groups = *groups + 1; + wcred->sc_supp_groups = *groups; } else { wcred->sc_supp_groups_nb = 0; wcred->sc_supp_groups = NULL; @@ -652,9 +665,8 @@ sys_setcred(struct thread *td, struct setcred_args *uap) * CAUTION: This function normalizes groups in 'wcred'. * * If 'preallocated_groups' is non-NULL, it must be an already allocated array - * of size 'wcred->sc_supp_groups_nb + 1', with the supplementary groups - * starting at index 1, and 'wcred->sc_supp_groups' then must point to the first - * supplementary group. + * of size 'wcred->sc_supp_groups_nb' containing the supplementary groups, and + * 'wcred->sc_supp_groups' then must point to it. */ int kern_setcred(struct thread *const td, const u_int flags, @@ -685,13 +697,14 @@ kern_setcred(struct thread *const td, const u_int flags, return (EINVAL); if (preallocated_groups != NULL) { groups = preallocated_groups; - MPASS(preallocated_groups + 1 == wcred->sc_supp_groups); + MPASS(preallocated_groups == wcred->sc_supp_groups); } else { - groups = wcred->sc_supp_groups_nb < CRED_SMALLGROUPS_NB ? - smallgroups : - malloc((wcred->sc_supp_groups_nb + 1) * - sizeof(*groups), M_TEMP, M_WAITOK); - memcpy(groups + 1, wcred->sc_supp_groups, + if (wcred->sc_supp_groups_nb <= CRED_SMALLGROUPS_NB) + groups = smallgroups; + else + groups = malloc(wcred->sc_supp_groups_nb * + sizeof(*groups), M_TEMP, M_WAITOK); + memcpy(groups, wcred->sc_supp_groups, wcred->sc_supp_groups_nb * sizeof(*groups)); } } @@ -726,16 +739,12 @@ kern_setcred(struct thread *const td, const u_int flags, if (flags & SETCREDF_SVGID) AUDIT_ARG_SGID(wcred->sc_svgid); if (flags & SETCREDF_SUPP_GROUPS) { - int ngrp = wcred->sc_supp_groups_nb; - /* * Output the raw supplementary groups array for better * traceability. */ - AUDIT_ARG_GROUPSET(groups + 1, ngrp); - ++ngrp; - groups_normalize(&ngrp, groups); - wcred->sc_supp_groups_nb = ngrp - 1; + AUDIT_ARG_GROUPSET(groups, wcred->sc_supp_groups_nb); + groups_normalize(&wcred->sc_supp_groups_nb, groups); } /* @@ -746,7 +755,7 @@ kern_setcred(struct thread *const td, const u_int flags, new_cred = crget(); to_free_cred = new_cred; if (flags & SETCREDF_SUPP_GROUPS) - crextend(new_cred, wcred->sc_supp_groups_nb + 1); + crextend(new_cred, wcred->sc_supp_groups_nb); #ifdef MAC mac_cred_setcred_enter(); @@ -773,16 +782,11 @@ kern_setcred(struct thread *const td, const u_int flags, /* * Change groups. - * - * crsetgroups_internal() changes both the effective and supplementary - * ones. */ - if (flags & SETCREDF_SUPP_GROUPS) { - groups[0] = flags & SETCREDF_GID ? wcred->sc_gid : - new_cred->cr_gid; - crsetgroups_internal(new_cred, wcred->sc_supp_groups_nb + 1, + if (flags & SETCREDF_SUPP_GROUPS) + crsetgroups_internal(new_cred, wcred->sc_supp_groups_nb, groups); - } else if (flags & SETCREDF_GID) + if (flags & SETCREDF_GID) change_egid(new_cred, wcred->sc_gid); if (flags & SETCREDF_RGID) change_rgid(new_cred, wcred->sc_rgid); @@ -1206,6 +1210,7 @@ sys_setgroups(struct thread *td, struct setgroups_args *uap) * setgroups() differ. */ gidsetsize = uap->gidsetsize; + /* XXXKE Limit to ngroups_max when we change the userland interface. */ if (gidsetsize > ngroups_max + 1 || gidsetsize < 0) return (EINVAL); @@ -1233,29 +1238,49 @@ kern_setgroups(struct thread *td, int *ngrpp, gid_t *groups) struct proc *p = td->td_proc; struct ucred *newcred, *oldcred; int ngrp, error; + gid_t egid; ngrp = *ngrpp; /* Sanity check size. */ + /* XXXKE Limit to ngroups_max when we change the userland interface. */ if (ngrp < 0 || ngrp > ngroups_max + 1) return (EINVAL); AUDIT_ARG_GROUPSET(groups, ngrp); + /* + * setgroups(0, NULL) is a legitimate way of clearing the groups vector + * on non-BSD systems (which generally do not have the egid in the + * groups[0]). We risk security holes when running non-BSD software if + * we do not do the same. So we allow and treat 0 for 'ngrp' specially + * below (twice). + */ if (ngrp != 0) { - /* We allow and treat 0 specially below. */ - groups_normalize(ngrpp, groups); - ngrp = *ngrpp; + /* + * To maintain userland compat for now, we use the first group + * as our egid and we'll use the rest as our supplemental + * groups. + */ + egid = groups[0]; + ngrp--; + groups++; + + groups_normalize(&ngrp, groups); + *ngrpp = ngrp; } newcred = crget(); - if (ngrp != 0) - crextend(newcred, ngrp); + crextend(newcred, ngrp); PROC_LOCK(p); oldcred = crcopysafe(p, newcred); #ifdef MAC - error = ngrp == 0 ? - /* If 'ngrp' is 0, we'll keep just the current effective GID. */ - mac_cred_check_setgroups(oldcred, 1, oldcred->cr_groups) : - mac_cred_check_setgroups(oldcred, ngrp, groups); + /* + * We pass NULL here explicitly if we don't have any supplementary + * groups mostly for the sake of normalization, but also to avoid/detect + * a situation where a MAC module has some assumption about the layout + * of `groups` matching historical behavior. + */ + error = mac_cred_check_setgroups(oldcred, ngrp, + ngrp == 0 ? NULL : groups); if (error) goto fail; #endif @@ -1264,16 +1289,14 @@ kern_setgroups(struct thread *td, int *ngrpp, gid_t *groups) if (error) goto fail; - if (ngrp == 0) { - /* - * setgroups(0, NULL) is a legitimate way of clearing the - * groups vector on non-BSD systems (which generally do not - * have the egid in the groups[0]). We risk security holes - * when running non-BSD software if we do not do the same. - */ - newcred->cr_ngroups = 1; - } else - crsetgroups_internal(newcred, ngrp, groups); + /* + * If some groups were passed, the first one is currently the desired + * egid. This code is to be removed (along with some commented block + * above) when setgroups() is changed to take only supplementary groups. + */ + if (ngrp != 0) + newcred->cr_gid = egid; + crsetgroups_internal(newcred, ngrp, groups); setsugid(p); proc_set_cred(p, newcred); @@ -1693,11 +1716,11 @@ groups_check_normalized(int ngrp, const gid_t *groups) groups_check_positive_len(ngrp); groups_check_max_len(ngrp); - if (ngrp == 1) + if (ngrp <= 1) return; - prev_g = groups[1]; - for (int i = 2; i < ngrp; ++i) { + prev_g = groups[0]; + for (int i = 1; i < ngrp; ++i) { const gid_t g = groups[i]; if (prev_g >= g) @@ -1723,7 +1746,7 @@ group_is_supplementary(const gid_t gid, const struct ucred *const cred) * Perform a binary search of the supplementary groups. This is * possible because we sort the groups in crsetgroups(). */ - return (bsearch(&gid, cred->cr_groups + 1, cred->cr_ngroups - 1, + return (bsearch(&gid, cred->cr_groups, cred->cr_ngroups, sizeof(gid), gidp_cmp) != NULL); } @@ -2588,11 +2611,6 @@ void crcopy(struct ucred *dest, struct ucred *src) { - /* - * Ideally, 'cr_ngroups' should be moved out of 'struct ucred''s bcopied - * area, but this would break the ABI, so is deferred until there is - * a compelling need to change it. - */ bcopy(&src->cr_startcopy, &dest->cr_startcopy, (unsigned)((caddr_t)&src->cr_endcopy - (caddr_t)&src->cr_startcopy)); @@ -2634,11 +2652,17 @@ cru2x(struct ucred *cr, struct xucred *xcr) bzero(xcr, sizeof(*xcr)); xcr->cr_version = XUCRED_VERSION; xcr->cr_uid = cr->cr_uid; + xcr->cr_gid = cr->cr_gid; - ngroups = MIN(cr->cr_ngroups, XU_NGROUPS); + /* + * We use a union to alias cr_gid to cr_groups[0] in the xucred, so + * this is kind of ugly; cr_ngroups still includes the egid for our + * purposes to avoid bumping the xucred version. + */ + ngroups = MIN(cr->cr_ngroups + 1, nitems(xcr->cr_groups)); xcr->cr_ngroups = ngroups; - bcopy(cr->cr_groups, xcr->cr_groups, - ngroups * sizeof(*cr->cr_groups)); + bcopy(cr->cr_groups, xcr->cr_sgroups, + (ngroups - 1) * sizeof(*cr->cr_groups)); } void @@ -2772,7 +2796,8 @@ crextend(struct ucred *cr, int n) size_t nbytes; MPASS2(cr->cr_ref == 1, "'cr_ref' must be 1 (referenced, unshared)"); - MPASS2(cr->cr_ngroups == 0, "groups on 'cr' already set!"); + MPASS2((cr->cr_flags & CRED_FLAG_GROUPSET) == 0, + "groups on 'cr' already set!"); groups_check_positive_len(n); groups_check_max_len(n); @@ -2809,12 +2834,8 @@ crextend(struct ucred *cr, int n) /* * Normalizes a set of groups to be applied to a 'struct ucred'. * - * The set of groups is an array that must comprise the effective GID as its - * first element (so its length cannot be 0). - * - * Normalization ensures that elements after the first, which stand for the - * supplementary groups, are sorted in ascending order and do not contain - * duplicates. + * Normalization ensures that the supplementary groups are sorted in ascending + * order and do not contain duplicates. */ static void groups_normalize(int *ngrp, gid_t *groups) @@ -2825,15 +2846,15 @@ groups_normalize(int *ngrp, gid_t *groups) groups_check_positive_len(*ngrp); groups_check_max_len(*ngrp); - if (*ngrp == 1) + if (*ngrp <= 1) return; - qsort(groups + 1, *ngrp - 1, sizeof(*groups), gidp_cmp); + qsort(groups, *ngrp, sizeof(*groups), gidp_cmp); /* Remove duplicates. */ - prev_g = groups[1]; - ins_idx = 2; - for (int i = 2; i < *ngrp; ++i) { + prev_g = groups[0]; + ins_idx = 1; + for (int i = ins_idx; i < *ngrp; ++i) { const gid_t g = groups[i]; if (g != prev_g) { @@ -2870,13 +2891,14 @@ crsetgroups_internal(struct ucred *cr, int ngrp, const gid_t *groups) bcopy(groups, cr->cr_groups, ngrp * sizeof(gid_t)); cr->cr_ngroups = ngrp; + cr->cr_flags |= CRED_FLAG_GROUPSET; } /* * Copy groups in to a credential after expanding it if required. * * May sleep in order to allocate memory (except if, e.g., crextend() was called - * before with 'ngrp' or greater). Truncates the list to (ngroups_max + 1) if + * before with 'ngrp' or greater). Truncates the list to ngroups_max if * it is too large. Array 'groups' doesn't need to be sorted. 'ngrp' must be * strictly positive. */ @@ -2884,36 +2906,48 @@ void crsetgroups(struct ucred *cr, int ngrp, const gid_t *groups) { - if (ngrp > ngroups_max + 1) - ngrp = ngroups_max + 1; + if (ngrp > ngroups_max) + ngrp = ngroups_max; + cr->cr_ngroups = 0; + if (ngrp == 0) { + cr->cr_flags |= CRED_FLAG_GROUPSET; + return; + } + /* * crextend() asserts that groups are not set, as it may allocate a new * backing storage without copying the content of the old one. Since we * are going to install a completely new set anyway, signal that we * consider the old ones thrown away. */ - cr->cr_ngroups = 0; + cr->cr_flags &= ~CRED_FLAG_GROUPSET; + crextend(cr, ngrp); crsetgroups_internal(cr, ngrp, groups); groups_normalize(&cr->cr_ngroups, cr->cr_groups); } /* - * Same as crsetgroups() but accepts an empty groups array. + * Same as crsetgroups() but sets the effective GID as well. * * This function ensures that an effective GID is always present in credentials. - * An empty array is treated as a one-size one holding the passed effective GID - * fallback. + * An empty array will only set the effective GID to the default_egid, while a + * non-empty array will peel off groups[0] to set as the effective GID and use + * the remainder, if any, as supplementary groups. */ void -crsetgroups_fallback(struct ucred *cr, int ngrp, const gid_t *groups, - const gid_t fallback) +crsetgroups_and_egid(struct ucred *cr, int ngrp, const gid_t *groups, + const gid_t default_egid) { - if (ngrp == 0) - /* Shortcut. */ - crsetgroups_internal(cr, 1, &fallback); - else - crsetgroups(cr, ngrp, groups); + if (ngrp == 0) { + cr->cr_gid = default_egid; + cr->cr_ngroups = 0; + cr->cr_flags |= CRED_FLAG_GROUPSET; + return; + } + + crsetgroups(cr, ngrp - 1, groups + 1); + cr->cr_gid = groups[0]; } /* diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c index 02973146068d..e63fa4c01434 100644 --- a/sys/kern/vfs_aio.c +++ b/sys/kern/vfs_aio.c @@ -222,6 +222,7 @@ typedef struct oaiocb { #define KAIOCB_CHECKSYNC 0x08 #define KAIOCB_CLEARED 0x10 #define KAIOCB_FINISHED 0x20 +#define KAIOCB_MARKER 0x40 /* ioflags */ #define KAIOCB_IO_FOFFSET 0x01 @@ -584,6 +585,12 @@ aio_cancel_job(struct proc *p, struct kaioinfo *ki, struct kaiocb *job) int cancelled; AIO_LOCK_ASSERT(ki, MA_OWNED); + + /* + * If we're running down the queue, the process must be single-threaded, + * and so no markers should be present. + */ + MPASS((job->jobflags & KAIOCB_MARKER) == 0); if (job->jobflags & (KAIOCB_CANCELLED | KAIOCB_FINISHED)) return (0); MPASS((job->jobflags & KAIOCB_CANCELLING) == 0); @@ -658,7 +665,7 @@ restart: } /* Wait for all running I/O to be finished */ - if (TAILQ_FIRST(&ki->kaio_jobqueue) || ki->kaio_active_count != 0) { + if (!TAILQ_EMPTY(&ki->kaio_jobqueue) || ki->kaio_active_count != 0) { ki->kaio_flags |= KAIO_WAKEUP; msleep(&p->p_aioinfo, AIO_MTX(ki), PRIBIO, "aioprn", hz); goto restart; @@ -1804,6 +1811,8 @@ aio_queue_file(struct file *fp, struct kaiocb *job) } else if (job->uaiocb.aio_lio_opcode & LIO_SYNC) { AIO_LOCK(ki); TAILQ_FOREACH(job2, &ki->kaio_jobqueue, plist) { + if ((job2->jobflags & KAIOCB_MARKER) != 0) + continue; if (job2->fd_file == job->fd_file && ((job2->uaiocb.aio_lio_opcode & LIO_SYNC) == 0) && job2->seqno < job->seqno) { @@ -2033,7 +2042,7 @@ sys_aio_cancel(struct thread *td, struct aio_cancel_args *uap) { struct proc *p = td->td_proc; struct kaioinfo *ki; - struct kaiocb *job, *jobn; + struct kaiocb *job, *jobn, marker; struct file *fp; int error; int cancelled = 0; @@ -2058,16 +2067,30 @@ sys_aio_cancel(struct thread *td, struct aio_cancel_args *uap) } } + /* + * We may have to drop the list mutex in order to cancel a job. After + * that point it is unsafe to rely on the stability of the list. We + * could restart the search from the beginning after canceling a job, + * but this may inefficient. Instead, use a marker job to keep our + * place in the list. + */ + memset(&marker, 0, sizeof(marker)); + marker.jobflags = KAIOCB_MARKER; + AIO_LOCK(ki); TAILQ_FOREACH_SAFE(job, &ki->kaio_jobqueue, plist, jobn) { - if ((uap->fd == job->uaiocb.aio_fildes) && - ((uap->aiocbp == NULL) || - (uap->aiocbp == job->ujob))) { + if (uap->fd == job->uaiocb.aio_fildes && + (uap->aiocbp == NULL || uap->aiocbp == job->ujob) && + (job->jobflags & KAIOCB_MARKER) == 0) { + TAILQ_INSERT_AFTER(&ki->kaio_jobqueue, job, &marker, + plist); if (aio_cancel_job(p, ki, job)) { cancelled++; } else { notcancelled++; } + jobn = TAILQ_NEXT(&marker, plist); + TAILQ_REMOVE(&ki->kaio_jobqueue, &marker, plist); if (uap->aiocbp != NULL) break; } diff --git a/sys/kern/vfs_export.c b/sys/kern/vfs_export.c index a314bda164de..bd7caa01e153 100644 --- a/sys/kern/vfs_export.c +++ b/sys/kern/vfs_export.c @@ -134,7 +134,7 @@ vfs_hang_addrlist(struct mount *mp, struct netexport *nep, np->netc_exflags = argp->ex_flags; np->netc_anon = crget(); np->netc_anon->cr_uid = argp->ex_uid; - crsetgroups_fallback(np->netc_anon, argp->ex_ngroups, + crsetgroups_and_egid(np->netc_anon, argp->ex_ngroups, argp->ex_groups, GID_NOGROUP); np->netc_anon->cr_prison = &prison0; prison_hold(np->netc_anon->cr_prison); @@ -213,7 +213,7 @@ vfs_hang_addrlist(struct mount *mp, struct netexport *nep, np->netc_exflags = argp->ex_flags; np->netc_anon = crget(); np->netc_anon->cr_uid = argp->ex_uid; - crsetgroups_fallback(np->netc_anon, argp->ex_ngroups, argp->ex_groups, + crsetgroups_and_egid(np->netc_anon, argp->ex_ngroups, argp->ex_groups, GID_NOGROUP); np->netc_anon->cr_prison = &prison0; prison_hold(np->netc_anon->cr_prison); diff --git a/sys/netinet/tcp_hpts.c b/sys/netinet/tcp_hpts.c index b60cdf45af52..22fc99496d34 100644 --- a/sys/netinet/tcp_hpts.c +++ b/sys/netinet/tcp_hpts.c @@ -170,6 +170,50 @@ #define NUM_OF_HPTSI_SLOTS 102400 +/* The number of connections after which the dynamic sleep logic kicks in. */ +#define DEFAULT_CONNECTION_THRESHOLD 100 + +/* + * When using the hpts, a TCP stack must make sure + * that once a INP_DROPPED flag is applied to a INP + * that it does not expect tcp_output() to ever be + * called by the hpts. The hpts will *not* call + * any output (or input) functions on a TCB that + * is in the DROPPED state. + * + * This implies final ACK's and RST's that might + * be sent when a TCB is still around must be + * sent from a routine like tcp_respond(). + */ +#define LOWEST_SLEEP_ALLOWED 50 +#define DEFAULT_MIN_SLEEP 250 /* How many usec's is default for hpts sleep + * this determines min granularity of the + * hpts. If 1, granularity is 10useconds at + * the cost of more CPU (context switching). + * Note do not set this to 0. + */ +#define DYNAMIC_MIN_SLEEP DEFAULT_MIN_SLEEP +#define DYNAMIC_MAX_SLEEP 5000 /* 5ms */ + +/* Thresholds for raising/lowering sleep */ +#define SLOTS_INDICATE_MORE_SLEEP 100 /* This would be 1ms */ +#define SLOTS_INDICATE_LESS_SLEEP 1000 /* This would indicate 10ms */ +/** + * + * Dynamic adjustment of sleeping times is done in "new" mode + * where we are depending on syscall returns and lro returns + * to push hpts forward mainly and the timer is only a backstop. + * + * When we are in the "new" mode i.e. conn_cnt > conn_cnt_thresh + * then we do a dynamic adjustment on the time we sleep. + * Our threshold is if the lateness of the first client served (in ticks) is + * greater than or equal too slots_indicate_more_sleep (10ms + * or 10000 ticks). If we were that late, the actual sleep time + * is adjusted down by 50%. If the ticks_ran is less than + * slots_indicate_more_sleep (100 ticks or 1000usecs). + * + */ + /* Each hpts has its own p_mtx which is used for locking */ #define HPTS_MTX_ASSERT(hpts) mtx_assert(&(hpts)->p_mtx, MA_OWNED) #define HPTS_LOCK(hpts) mtx_lock(&(hpts)->p_mtx) @@ -244,11 +288,10 @@ static int32_t tcp_hptsi(struct tcp_hpts_entry *hpts, bool from_callout); static void tcp_hpts_thread(void *ctx); int32_t tcp_min_hptsi_time = DEFAULT_MIN_SLEEP; -static int conn_cnt_thresh = DEFAULT_CONNECTION_THESHOLD; +static int conn_cnt_thresh = DEFAULT_CONNECTION_THRESHOLD; static int32_t dynamic_min_sleep = DYNAMIC_MIN_SLEEP; static int32_t dynamic_max_sleep = DYNAMIC_MAX_SLEEP; - SYSCTL_NODE(_net_inet_tcp, OID_AUTO, hpts, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, "TCP Hpts controls"); SYSCTL_NODE(_net_inet_tcp_hpts, OID_AUTO, stats, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, @@ -366,7 +409,7 @@ sysctl_net_inet_tcp_hpts_max_sleep(SYSCTL_HANDLER_ARGS) new = hpts_sleep_max; error = sysctl_handle_int(oidp, &new, 0, req); if (error == 0 && req->newptr) { - if ((new < (dynamic_min_sleep/HPTS_TICKS_PER_SLOT)) || + if ((new < (dynamic_min_sleep/HPTS_USECS_PER_SLOT)) || (new > HPTS_MAX_SLEEP_ALLOWED)) error = EINVAL; else @@ -404,15 +447,15 @@ SYSCTL_PROC(_net_inet_tcp_hpts, OID_AUTO, minsleep, &sysctl_net_inet_tcp_hpts_min_sleep, "IU", "The minimum time the hpts must sleep before processing more slots"); -static int ticks_indicate_more_sleep = TICKS_INDICATE_MORE_SLEEP; -static int ticks_indicate_less_sleep = TICKS_INDICATE_LESS_SLEEP; +static int slots_indicate_more_sleep = SLOTS_INDICATE_MORE_SLEEP; +static int slots_indicate_less_sleep = SLOTS_INDICATE_LESS_SLEEP; static int tcp_hpts_no_wake_over_thresh = 1; SYSCTL_INT(_net_inet_tcp_hpts, OID_AUTO, more_sleep, CTLFLAG_RW, - &ticks_indicate_more_sleep, 0, + &slots_indicate_more_sleep, 0, "If we only process this many or less on a timeout, we need longer sleep on the next callout"); SYSCTL_INT(_net_inet_tcp_hpts, OID_AUTO, less_sleep, CTLFLAG_RW, - &ticks_indicate_less_sleep, 0, + &slots_indicate_less_sleep, 0, "If we process this many or more on a timeout, we need less sleep on the next callout"); SYSCTL_INT(_net_inet_tcp_hpts, OID_AUTO, nowake_over_thresh, CTLFLAG_RW, &tcp_hpts_no_wake_over_thresh, 0, @@ -453,7 +496,7 @@ tcp_hpts_log(struct tcp_hpts_entry *hpts, struct tcpcb *tp, struct timeval *tv, log.u_bbr.inflight = slots_to_run; log.u_bbr.applimited = hpts->overidden_sleep; log.u_bbr.delivered = hpts->saved_curtick; - log.u_bbr.timeStamp = tcp_tv_to_usectick(tv); + log.u_bbr.timeStamp = tcp_tv_to_usec(tv); log.u_bbr.epoch = hpts->saved_curslot; log.u_bbr.lt_epoch = hpts->saved_prev_slot; log.u_bbr.pkts_out = hpts->p_delayed_by; @@ -877,7 +920,7 @@ tcp_hpts_insert_diag(struct tcpcb *tp, uint32_t slot, int32_t line, struct hpts_ return (slot_on); } /* Get the current time relative to the wheel */ - wheel_cts = tcp_tv_to_hptstick(&tv); + wheel_cts = tcp_tv_to_hpts_slot(&tv); /* Map it onto the wheel */ wheel_slot = tick_to_wheel(wheel_cts); /* Now what's the max we can place it at? */ @@ -949,7 +992,7 @@ tcp_hpts_insert_diag(struct tcpcb *tp, uint32_t slot, int32_t line, struct hpts_ * We need to reschedule the hpts's time-out. */ hpts->p_hpts_sleep_time = slot; - need_new_to = slot * HPTS_TICKS_PER_SLOT; + need_new_to = slot * HPTS_USECS_PER_SLOT; } } /* @@ -1104,7 +1147,7 @@ tcp_hptsi(struct tcp_hpts_entry *hpts, bool from_callout) hpts->p_lasttick = hpts->p_curtick; hpts->p_curtick = tcp_gethptstick(&tv); - tcp_pace.cts_last_ran[hpts->p_num] = tcp_tv_to_usectick(&tv); + tcp_pace.cts_last_ran[hpts->p_num] = tcp_tv_to_usec(&tv); orig_exit_slot = hpts->p_cur_slot = tick_to_wheel(hpts->p_curtick); if ((hpts->p_on_queue_cnt == 0) || (hpts->p_lasttick == hpts->p_curtick)) { @@ -1121,7 +1164,7 @@ again: HPTS_MTX_ASSERT(hpts); slots_to_run = hpts_slots_diff(hpts->p_prev_slot, hpts->p_cur_slot); if (((hpts->p_curtick - hpts->p_lasttick) > - ((NUM_OF_HPTSI_SLOTS-1) * HPTS_TICKS_PER_SLOT)) && + ((NUM_OF_HPTSI_SLOTS-1) * HPTS_USECS_PER_SLOT)) && (hpts->p_on_queue_cnt != 0)) { /* * Wheel wrap is occuring, basically we @@ -1202,7 +1245,7 @@ again: * was not any (i.e. if slots_to_run == 1, no delay). */ hpts->p_delayed_by = (slots_to_run - (i + 1)) * - HPTS_TICKS_PER_SLOT; + HPTS_USECS_PER_SLOT; runningslot = hpts->p_runningslot; hptsh = &hpts->p_hptss[runningslot]; @@ -1446,7 +1489,7 @@ no_one: goto again; } no_run: - tcp_pace.cts_last_ran[hpts->p_num] = tcp_tv_to_usectick(&tv); + tcp_pace.cts_last_ran[hpts->p_num] = tcp_tv_to_usec(&tv); /* * Set flag to tell that we are done for * any slot input that happens during @@ -1569,7 +1612,7 @@ __tcp_run_hpts(void) ticks_ran = tcp_hptsi(hpts, false); /* We may want to adjust the sleep values here */ if (hpts->p_on_queue_cnt >= conn_cnt_thresh) { - if (ticks_ran > ticks_indicate_less_sleep) { + if (ticks_ran > slots_indicate_less_sleep) { struct timeval tv; sbintime_t sb; @@ -1579,7 +1622,7 @@ __tcp_run_hpts(void) /* Reschedule with new to value */ tcp_hpts_set_max_sleep(hpts, 0); tv.tv_sec = 0; - tv.tv_usec = hpts->p_hpts_sleep_time * HPTS_TICKS_PER_SLOT; + tv.tv_usec = hpts->p_hpts_sleep_time * HPTS_USECS_PER_SLOT; /* Validate its in the right ranges */ if (tv.tv_usec < hpts->p_mysleep.tv_usec) { hpts->overidden_sleep = tv.tv_usec; @@ -1601,7 +1644,7 @@ __tcp_run_hpts(void) callout_reset_sbt_on(&hpts->co, sb, 0, hpts_timeout_swi, hpts, hpts->p_cpu, (C_DIRECT_EXEC | C_PREL(tcp_hpts_precision))); - } else if (ticks_ran < ticks_indicate_more_sleep) { + } else if (ticks_ran < slots_indicate_more_sleep) { /* For the further sleep, don't reschedule hpts */ hpts->p_mysleep.tv_usec *= 2; if (hpts->p_mysleep.tv_usec > dynamic_max_sleep) @@ -1683,7 +1726,7 @@ tcp_hpts_thread(void *ctx) hpts->p_hpts_active = 1; ticks_ran = tcp_hptsi(hpts, true); tv.tv_sec = 0; - tv.tv_usec = hpts->p_hpts_sleep_time * HPTS_TICKS_PER_SLOT; + tv.tv_usec = hpts->p_hpts_sleep_time * HPTS_USECS_PER_SLOT; if ((hpts->p_on_queue_cnt > conn_cnt_thresh) && (hpts->hit_callout_thresh == 0)) { hpts->hit_callout_thresh = 1; atomic_add_int(&hpts_that_need_softclock, 1); @@ -1697,11 +1740,11 @@ tcp_hpts_thread(void *ctx) * Only adjust sleep time if we were * called from the callout i.e. direct_wake == 0. */ - if (ticks_ran < ticks_indicate_more_sleep) { + if (ticks_ran < slots_indicate_more_sleep) { hpts->p_mysleep.tv_usec *= 2; if (hpts->p_mysleep.tv_usec > dynamic_max_sleep) hpts->p_mysleep.tv_usec = dynamic_max_sleep; - } else if (ticks_ran > ticks_indicate_less_sleep) { + } else if (ticks_ran > slots_indicate_less_sleep) { hpts->p_mysleep.tv_usec /= 2; if (hpts->p_mysleep.tv_usec < dynamic_min_sleep) hpts->p_mysleep.tv_usec = dynamic_min_sleep; @@ -1948,7 +1991,7 @@ tcp_hpts_mod_load(void) hpts->p_hpts_sleep_time = hpts_sleep_max; hpts->p_num = i; hpts->p_curtick = tcp_gethptstick(&tv); - tcp_pace.cts_last_ran[i] = tcp_tv_to_usectick(&tv); + tcp_pace.cts_last_ran[i] = tcp_tv_to_usec(&tv); hpts->p_prev_slot = hpts->p_cur_slot = tick_to_wheel(hpts->p_curtick); hpts->p_cpu = 0xffff; hpts->p_nxt_slot = hpts_slot(hpts->p_cur_slot, 1); @@ -1995,7 +2038,7 @@ tcp_hpts_mod_load(void) } } tv.tv_sec = 0; - tv.tv_usec = hpts->p_hpts_sleep_time * HPTS_TICKS_PER_SLOT; + tv.tv_usec = hpts->p_hpts_sleep_time * HPTS_USECS_PER_SLOT; hpts->sleeping = tv.tv_usec; sb = tvtosbt(tv); callout_reset_sbt_on(&hpts->co, sb, 0, diff --git a/sys/netinet/tcp_hpts.h b/sys/netinet/tcp_hpts.h index f5856ed8e688..6172baf2a062 100644 --- a/sys/netinet/tcp_hpts.h +++ b/sys/netinet/tcp_hpts.h @@ -26,14 +26,38 @@ #ifndef __tcp_hpts_h__ #define __tcp_hpts_h__ -/* Number of useconds in a hpts tick */ -#define HPTS_TICKS_PER_SLOT 10 +/* Number of useconds represented by an hpts slot */ +#define HPTS_USECS_PER_SLOT 10 #define HPTS_MS_TO_SLOTS(x) ((x * 100) + 1) #define HPTS_USEC_TO_SLOTS(x) ((x+9) /10) #define HPTS_USEC_IN_SEC 1000000 #define HPTS_MSEC_IN_SEC 1000 #define HPTS_USEC_IN_MSEC 1000 +static inline uint32_t +tcp_tv_to_hpts_slot(const struct timeval *sv) +{ + return ((sv->tv_sec * 100000) + (sv->tv_usec / HPTS_USECS_PER_SLOT)); +} + +static inline uint32_t +tcp_tv_to_usec(const struct timeval *sv) +{ + return ((uint32_t) ((sv->tv_sec * HPTS_USEC_IN_SEC) + sv->tv_usec)); +} + +static inline uint32_t +tcp_tv_to_msec(const struct timeval *sv) +{ + return ((uint32_t) ((sv->tv_sec * HPTS_MSEC_IN_SEC) + (sv->tv_usec/HPTS_USEC_IN_MSEC))); +} + +static inline uint64_t +tcp_tv_to_lusec(const struct timeval *sv) +{ + return ((uint64_t)((sv->tv_sec * HPTS_USEC_IN_SEC) + sv->tv_usec)); +} + struct hpts_diag { uint32_t p_hpts_active; /* bbr->flex7 x */ uint32_t p_nxt_slot; /* bbr->flex1 x */ @@ -66,52 +90,16 @@ struct hpts_diag { #define PACE_PKT_OUTPUT 0x40 /* Output Packets being paced */ #define PACE_TMR_MASK (PACE_TMR_KEEP|PACE_TMR_PERSIT|PACE_TMR_RXT|PACE_TMR_TLP|PACE_TMR_RACK|PACE_TMR_DELACK) -#define DEFAULT_CONNECTION_THESHOLD 100 +#ifdef _KERNEL /* - * When using the hpts, a TCP stack must make sure - * that once a INP_DROPPED flag is applied to a INP - * that it does not expect tcp_output() to ever be - * called by the hpts. The hpts will *not* call - * any output (or input) functions on a TCB that - * is in the DROPPED state. - * - * This implies final ACK's and RST's that might - * be sent when a TCB is still around must be - * sent from a routine like tcp_respond(). - */ -#define LOWEST_SLEEP_ALLOWED 50 -#define DEFAULT_MIN_SLEEP 250 /* How many usec's is default for hpts sleep - * this determines min granularity of the - * hpts. If 1, granularity is 10useconds at - * the cost of more CPU (context switching). - * Note do not set this to 0. - */ -#define DYNAMIC_MIN_SLEEP DEFAULT_MIN_SLEEP -#define DYNAMIC_MAX_SLEEP 5000 /* 5ms */ - -/* Thresholds for raising/lowering sleep */ -#define TICKS_INDICATE_MORE_SLEEP 100 /* This would be 1ms */ -#define TICKS_INDICATE_LESS_SLEEP 1000 /* This would indicate 10ms */ -/** - * - * Dynamic adjustment of sleeping times is done in "new" mode - * where we are depending on syscall returns and lro returns - * to push hpts forward mainly and the timer is only a backstop. - * - * When we are in the "new" mode i.e. conn_cnt > conn_cnt_thresh - * then we do a dynamic adjustment on the time we sleep. - * Our threshold is if the lateness of the first client served (in ticks) is - * greater than or equal too ticks_indicate_more_sleep (10ms - * or 10000 ticks). If we were that late, the actual sleep time - * is adjusted down by 50%. If the ticks_ran is less than - * ticks_indicate_more_sleep (100 ticks or 1000usecs). - * - */ + * The following are the definitions for the kernel HPTS interface for managing + * the HPTS ring and the TCBs on it. +*/ -#ifdef _KERNEL void tcp_hpts_init(struct tcpcb *); void tcp_hpts_remove(struct tcpcb *); + static inline bool tcp_in_hpts(struct tcpcb *tp) { @@ -151,51 +139,12 @@ uint32_t tcp_hpts_insert_diag(struct tcpcb *tp, uint32_t slot, int32_t line, void tcp_set_hpts(struct tcpcb *tp); -void tcp_set_inp_to_drop(struct inpcb *inp, uint16_t reason); - -void tcp_lro_hpts_init(void); -void tcp_lro_hpts_uninit(void); - -extern int32_t tcp_min_hptsi_time; - -#endif /* _KERNEL */ - -/* - * The following functions should also be available - * to userspace as well. - */ -static inline uint32_t -tcp_tv_to_hptstick(const struct timeval *sv) -{ - return ((sv->tv_sec * 100000) + (sv->tv_usec / HPTS_TICKS_PER_SLOT)); -} - -static inline uint32_t -tcp_tv_to_usectick(const struct timeval *sv) -{ - return ((uint32_t) ((sv->tv_sec * HPTS_USEC_IN_SEC) + sv->tv_usec)); -} - -static inline uint32_t -tcp_tv_to_mssectick(const struct timeval *sv) -{ - return ((uint32_t) ((sv->tv_sec * HPTS_MSEC_IN_SEC) + (sv->tv_usec/HPTS_USEC_IN_MSEC))); -} - -static inline uint64_t -tcp_tv_to_lusectick(const struct timeval *sv) -{ - return ((uint64_t)((sv->tv_sec * HPTS_USEC_IN_SEC) + sv->tv_usec)); -} - -#ifdef _KERNEL - extern int32_t tcp_min_hptsi_time; static inline int32_t get_hpts_min_sleep_time(void) { - return (tcp_min_hptsi_time + HPTS_TICKS_PER_SLOT); + return (tcp_min_hptsi_time + HPTS_USECS_PER_SLOT); } static inline uint32_t @@ -206,7 +155,7 @@ tcp_gethptstick(struct timeval *sv) if (sv == NULL) sv = &tv; microuptime(sv); - return (tcp_tv_to_hptstick(sv)); + return (tcp_tv_to_hpts_slot(sv)); } static inline uint64_t @@ -217,7 +166,7 @@ tcp_get_u64_usecs(struct timeval *tv) if (tv == NULL) tv = &tvd; microuptime(tv); - return (tcp_tv_to_lusectick(tv)); + return (tcp_tv_to_lusec(tv)); } static inline uint32_t @@ -228,8 +177,15 @@ tcp_get_usecs(struct timeval *tv) if (tv == NULL) tv = &tvd; microuptime(tv); - return (tcp_tv_to_usectick(tv)); + return (tcp_tv_to_usec(tv)); } +/* + * LRO HPTS initialization and uninitialization, only for internal use by the + * HPTS code. + */ +void tcp_lro_hpts_init(void); +void tcp_lro_hpts_uninit(void); + #endif /* _KERNEL */ #endif /* __tcp_hpts_h__ */ diff --git a/sys/netinet/tcp_lro_hpts.c b/sys/netinet/tcp_lro_hpts.c index 7e756285da45..43587285fe26 100644 --- a/sys/netinet/tcp_lro_hpts.c +++ b/sys/netinet/tcp_lro_hpts.c @@ -188,7 +188,7 @@ tcp_lro_log(struct tcpcb *tp, const struct lro_ctrl *lc, log.u_bbr.cur_del_rate = (uintptr_t)m; log.u_bbr.bw_inuse = (uintptr_t)le->m_head; bintime2timeval(&lc->lro_last_queue_time, &btv); - log.u_bbr.flex6 = tcp_tv_to_usectick(&btv); + log.u_bbr.flex6 = tcp_tv_to_usec(&btv); log.u_bbr.flex7 = le->compressed; log.u_bbr.pacing_gain = le->uncompressed; if (in_epoch(net_epoch_preempt)) diff --git a/sys/netinet/tcp_stacks/bbr.c b/sys/netinet/tcp_stacks/bbr.c index b232d3f08fe6..ce4e9f30020c 100644 --- a/sys/netinet/tcp_stacks/bbr.c +++ b/sys/netinet/tcp_stacks/bbr.c @@ -2173,7 +2173,7 @@ bbr_log_rtt_sample(struct tcp_bbr *bbr, uint32_t rtt, uint32_t tsin) log.u_bbr.flex3 = bbr->r_ctl.rc_ack_hdwr_delay; log.u_bbr.flex4 = bbr->rc_tp->ts_offset; log.u_bbr.flex5 = bbr->r_ctl.rc_target_at_state; - log.u_bbr.pkts_out = tcp_tv_to_mssectick(&bbr->rc_tv); + log.u_bbr.pkts_out = tcp_tv_to_msec(&bbr->rc_tv); log.u_bbr.flex6 = tsin; log.u_bbr.flex7 = 0; log.u_bbr.flex8 = bbr->rc_ack_was_delayed; @@ -2241,13 +2241,13 @@ bbr_log_ack_event(struct tcp_bbr *bbr, struct tcphdr *th, struct tcpopt *to, uin mbuf_tstmp2timespec(m, &ts); tv.tv_sec = ts.tv_sec; tv.tv_usec = ts.tv_nsec / 1000; - log.u_bbr.lt_epoch = tcp_tv_to_usectick(&tv); + log.u_bbr.lt_epoch = tcp_tv_to_usec(&tv); } else { log.u_bbr.lt_epoch = 0; } if (m->m_flags & M_TSTMP_LRO) { mbuf_tstmp2timeval(m, &tv); - log.u_bbr.flex5 = tcp_tv_to_usectick(&tv); + log.u_bbr.flex5 = tcp_tv_to_usec(&tv); } else { /* No arrival timestamp */ log.u_bbr.flex5 = 0; @@ -6792,7 +6792,7 @@ bbr_update_rtt(struct tcpcb *tp, struct tcp_bbr *bbr, (ack_type == BBR_CUM_ACKED) && (to->to_flags & TOF_TS) && (to->to_tsecr != 0)) { - t = tcp_tv_to_mssectick(&bbr->rc_tv) - to->to_tsecr; + t = tcp_tv_to_msec(&bbr->rc_tv) - to->to_tsecr; if (t < 1) t = 1; t *= MS_IN_USEC; @@ -7330,7 +7330,7 @@ bbr_log_ack(struct tcpcb *tp, struct tcpopt *to, struct tcphdr *th, uint32_t ts, now, rtt; ts = bbr_ts_convert(to->to_tsecr); - now = bbr_ts_convert(tcp_tv_to_mssectick(&bbr->rc_tv)); + now = bbr_ts_convert(tcp_tv_to_msec(&bbr->rc_tv)); rtt = now - ts; if (rtt < 1) rtt = 1; @@ -8461,7 +8461,7 @@ bbr_do_fastnewdata(struct mbuf *m, struct tcphdr *th, struct socket *so, } if ((to->to_flags & TOF_TS) != 0 && SEQ_LEQ(th->th_seq, tp->last_ack_sent)) { - tp->ts_recent_age = tcp_tv_to_mssectick(&bbr->rc_tv); + tp->ts_recent_age = tcp_tv_to_msec(&bbr->rc_tv); tp->ts_recent = to->to_tsval; } /* @@ -8893,7 +8893,7 @@ bbr_do_syn_sent(struct mbuf *m, struct tcphdr *th, struct socket *so, if ((to->to_flags & TOF_TS) != 0) { uint32_t t, rtt; - t = tcp_tv_to_mssectick(&bbr->rc_tv); + t = tcp_tv_to_msec(&bbr->rc_tv); if (TSTMP_GEQ(t, to->to_tsecr)) { rtt = t - to->to_tsecr; if (rtt == 0) { @@ -9034,7 +9034,7 @@ bbr_do_syn_recv(struct mbuf *m, struct tcphdr *th, struct socket *so, SEQ_LEQ(th->th_seq, tp->last_ack_sent) && SEQ_LEQ(tp->last_ack_sent, th->th_seq + tlen + ((thflags & (TH_SYN | TH_FIN)) != 0))) { - tp->ts_recent_age = tcp_tv_to_mssectick(&bbr->rc_tv); + tp->ts_recent_age = tcp_tv_to_msec(&bbr->rc_tv); tp->ts_recent = to->to_tsval; } tp->snd_wnd = tiwin; @@ -9067,7 +9067,7 @@ bbr_do_syn_recv(struct mbuf *m, struct tcphdr *th, struct socket *so, if ((to->to_flags & TOF_TS) != 0) { uint32_t t, rtt; - t = tcp_tv_to_mssectick(&bbr->rc_tv); + t = tcp_tv_to_msec(&bbr->rc_tv); if (TSTMP_GEQ(t, to->to_tsecr)) { rtt = t - to->to_tsecr; if (rtt == 0) { @@ -9258,7 +9258,7 @@ bbr_do_established(struct mbuf *m, struct tcphdr *th, struct socket *so, SEQ_LEQ(th->th_seq, tp->last_ack_sent) && SEQ_LEQ(tp->last_ack_sent, th->th_seq + tlen + ((thflags & (TH_SYN | TH_FIN)) != 0))) { - tp->ts_recent_age = tcp_tv_to_mssectick(&bbr->rc_tv); + tp->ts_recent_age = tcp_tv_to_msec(&bbr->rc_tv); tp->ts_recent = to->to_tsval; } /* @@ -9355,7 +9355,7 @@ bbr_do_close_wait(struct mbuf *m, struct tcphdr *th, struct socket *so, SEQ_LEQ(th->th_seq, tp->last_ack_sent) && SEQ_LEQ(tp->last_ack_sent, th->th_seq + tlen + ((thflags & (TH_SYN | TH_FIN)) != 0))) { - tp->ts_recent_age = tcp_tv_to_mssectick(&bbr->rc_tv); + tp->ts_recent_age = tcp_tv_to_msec(&bbr->rc_tv); tp->ts_recent = to->to_tsval; } /* @@ -9486,7 +9486,7 @@ bbr_do_fin_wait_1(struct mbuf *m, struct tcphdr *th, struct socket *so, SEQ_LEQ(th->th_seq, tp->last_ack_sent) && SEQ_LEQ(tp->last_ack_sent, th->th_seq + tlen + ((thflags & (TH_SYN | TH_FIN)) != 0))) { - tp->ts_recent_age = tcp_tv_to_mssectick(&bbr->rc_tv); + tp->ts_recent_age = tcp_tv_to_msec(&bbr->rc_tv); tp->ts_recent = to->to_tsval; } /* @@ -9602,7 +9602,7 @@ bbr_do_closing(struct mbuf *m, struct tcphdr *th, struct socket *so, SEQ_LEQ(th->th_seq, tp->last_ack_sent) && SEQ_LEQ(tp->last_ack_sent, th->th_seq + tlen + ((thflags & (TH_SYN | TH_FIN)) != 0))) { - tp->ts_recent_age = tcp_tv_to_mssectick(&bbr->rc_tv); + tp->ts_recent_age = tcp_tv_to_msec(&bbr->rc_tv); tp->ts_recent = to->to_tsval; } /* @@ -9704,7 +9704,7 @@ bbr_do_lastack(struct mbuf *m, struct tcphdr *th, struct socket *so, SEQ_LEQ(th->th_seq, tp->last_ack_sent) && SEQ_LEQ(tp->last_ack_sent, th->th_seq + tlen + ((thflags & (TH_SYN | TH_FIN)) != 0))) { - tp->ts_recent_age = tcp_tv_to_mssectick(&bbr->rc_tv); + tp->ts_recent_age = tcp_tv_to_msec(&bbr->rc_tv); tp->ts_recent = to->to_tsval; } /* @@ -9818,7 +9818,7 @@ bbr_do_fin_wait_2(struct mbuf *m, struct tcphdr *th, struct socket *so, SEQ_LEQ(th->th_seq, tp->last_ack_sent) && SEQ_LEQ(tp->last_ack_sent, th->th_seq + tlen + ((thflags & (TH_SYN | TH_FIN)) != 0))) { - tp->ts_recent_age = tcp_tv_to_mssectick(&bbr->rc_tv); + tp->ts_recent_age = tcp_tv_to_msec(&bbr->rc_tv); tp->ts_recent = to->to_tsval; } /* @@ -11327,7 +11327,7 @@ bbr_do_segment_nounlock(struct tcpcb *tp, struct mbuf *m, struct tcphdr *th, mbuf_tstmp2timespec(m, &ts); bbr->rc_tv.tv_sec = ts.tv_sec; bbr->rc_tv.tv_usec = ts.tv_nsec / 1000; - bbr->r_ctl.rc_rcvtime = cts = tcp_tv_to_usectick(&bbr->rc_tv); + bbr->r_ctl.rc_rcvtime = cts = tcp_tv_to_usec(&bbr->rc_tv); } else if (m->m_flags & M_TSTMP_LRO) { /* Next the arrival timestamp */ struct timespec ts; @@ -11335,7 +11335,7 @@ bbr_do_segment_nounlock(struct tcpcb *tp, struct mbuf *m, struct tcphdr *th, mbuf_tstmp2timespec(m, &ts); bbr->rc_tv.tv_sec = ts.tv_sec; bbr->rc_tv.tv_usec = ts.tv_nsec / 1000; - bbr->r_ctl.rc_rcvtime = cts = tcp_tv_to_usectick(&bbr->rc_tv); + bbr->r_ctl.rc_rcvtime = cts = tcp_tv_to_usec(&bbr->rc_tv); } else { /* * Ok just get the current time. @@ -11376,7 +11376,7 @@ bbr_do_segment_nounlock(struct tcpcb *tp, struct mbuf *m, struct tcphdr *th, */ if ((to.to_flags & TOF_TS) && (to.to_tsecr != 0)) { to.to_tsecr -= tp->ts_offset; - if (TSTMP_GT(to.to_tsecr, tcp_tv_to_mssectick(&bbr->rc_tv))) + if (TSTMP_GT(to.to_tsecr, tcp_tv_to_msec(&bbr->rc_tv))) to.to_tsecr = 0; } /* @@ -11414,7 +11414,7 @@ bbr_do_segment_nounlock(struct tcpcb *tp, struct mbuf *m, struct tcphdr *th, (tp->t_flags & TF_REQ_TSTMP)) { tp->t_flags |= TF_RCVD_TSTMP; tp->ts_recent = to.to_tsval; - tp->ts_recent_age = tcp_tv_to_mssectick(&bbr->rc_tv); + tp->ts_recent_age = tcp_tv_to_msec(&bbr->rc_tv); } else tp->t_flags &= ~TF_REQ_TSTMP; if (to.to_flags & TOF_MSS) @@ -11870,7 +11870,7 @@ bbr_output_wtime(struct tcpcb *tp, const struct timeval *tv) bbr = (struct tcp_bbr *)tp->t_fb_ptr; /* We take a cache hit here */ memcpy(&bbr->rc_tv, tv, sizeof(struct timeval)); - cts = tcp_tv_to_usectick(&bbr->rc_tv); + cts = tcp_tv_to_usec(&bbr->rc_tv); inp = bbr->rc_inp; hpts_calling = !!(tp->t_flags2 & TF2_HPTS_CALLS); tp->t_flags2 &= ~TF2_HPTS_CALLS; @@ -12885,7 +12885,7 @@ send: /* Timestamps. */ if ((tp->t_flags & TF_RCVD_TSTMP) || ((flags & TH_SYN) && (tp->t_flags & TF_REQ_TSTMP))) { - to.to_tsval = tcp_tv_to_mssectick(&bbr->rc_tv) + tp->ts_offset; + to.to_tsval = tcp_tv_to_msec(&bbr->rc_tv) + tp->ts_offset; to.to_tsecr = tp->ts_recent; to.to_flags |= TOF_TS; local_options += TCPOLEN_TIMESTAMP + 2; @@ -12893,7 +12893,7 @@ send: /* Set receive buffer autosizing timestamp. */ if (tp->rfbuf_ts == 0 && (so->so_rcv.sb_flags & SB_AUTOSIZE)) - tp->rfbuf_ts = tcp_tv_to_mssectick(&bbr->rc_tv); + tp->rfbuf_ts = tcp_tv_to_msec(&bbr->rc_tv); /* Selective ACK's. */ if (flags & TH_SYN) to.to_flags |= TOF_SACKPERM; @@ -14123,17 +14123,17 @@ bbr_switch_failed(struct tcpcb *tp) toval = bbr->rc_pacer_started - cts; } else { /* one slot please */ - toval = HPTS_TICKS_PER_SLOT; + toval = HPTS_USECS_PER_SLOT; } } else if (bbr->r_ctl.rc_hpts_flags & PACE_TMR_MASK) { if (TSTMP_GT(bbr->r_ctl.rc_timer_exp, cts)) { toval = bbr->r_ctl.rc_timer_exp - cts; } else { /* one slot please */ - toval = HPTS_TICKS_PER_SLOT; + toval = HPTS_USECS_PER_SLOT; } } else - toval = HPTS_TICKS_PER_SLOT; + toval = HPTS_USECS_PER_SLOT; (void)tcp_hpts_insert_diag(tp, HPTS_USEC_TO_SLOTS(toval), __LINE__, &diag); bbr_log_hpts_diag(bbr, cts, &diag); diff --git a/sys/netinet/tcp_stacks/rack.c b/sys/netinet/tcp_stacks/rack.c index 940a4024bb73..d6bbfeb886d9 100644 --- a/sys/netinet/tcp_stacks/rack.c +++ b/sys/netinet/tcp_stacks/rack.c @@ -604,7 +604,7 @@ rack_get_lt_bw(struct tcp_rack *rack) /* Include all the current bytes too */ microuptime(&tv); bytes += (rack->rc_tp->snd_una - rack->r_ctl.lt_seq); - tim += (tcp_tv_to_lusectick(&tv) - rack->r_ctl.lt_timemark); + tim += (tcp_tv_to_lusec(&tv) - rack->r_ctl.lt_timemark); } if ((bytes != 0) && (tim != 0)) return ((bytes * (uint64_t)1000000) / tim); @@ -2245,7 +2245,7 @@ rack_rate_cap_bw(struct tcp_rack *rack, uint64_t *bw, int *capped) ent = rack->r_ctl.rc_last_sft; microuptime(&tv); - timenow = tcp_tv_to_lusectick(&tv); + timenow = tcp_tv_to_lusec(&tv); if (timenow >= ent->deadline) { /* No time left we do DGP only */ rack_log_hybrid_bw(rack, rack->rc_tp->snd_max, @@ -2888,7 +2888,7 @@ rack_log_rtt_upd(struct tcpcb *tp, struct tcp_rack *rack, uint32_t t, uint32_t l log.u_bbr.lt_epoch = rack->r_ctl.rc_time_probertt_entered; log.u_bbr.cur_del_rate = rack->r_ctl.rc_lower_rtt_us_cts; log.u_bbr.delRate = rack->r_ctl.rc_gp_srtt; - log.u_bbr.bw_inuse = tcp_tv_to_usectick(&rack->r_ctl.act_rcv_time); + log.u_bbr.bw_inuse = tcp_tv_to_usec(&rack->r_ctl.act_rcv_time); log.u_bbr.bw_inuse <<= 32; if (rsm) log.u_bbr.bw_inuse |= ((uint32_t)rsm->r_tim_lastsent[(rsm->r_rtr_cnt-1)]); @@ -3644,7 +3644,7 @@ rack_enough_for_measurement(struct tcpcb *tp, struct tcp_rack *rack, tcp_seq th_ } /* Now what about time? */ srtts = (rack->r_ctl.rc_gp_srtt * rack_min_srtts); - tim = tcp_tv_to_usectick(&rack->r_ctl.act_rcv_time) - tp->gput_ts; + tim = tcp_tv_to_usec(&rack->r_ctl.act_rcv_time) - tp->gput_ts; if ((tim >= srtts) && (IN_RECOVERY(rack->rc_tp->t_flags) == 0)) { /* * We do not allow a measurement if we are in recovery @@ -4891,7 +4891,7 @@ rack_do_goodput_measurement(struct tcpcb *tp, struct tcp_rack *rack, uint64_t resid_bw, subpart = 0, addpart = 0, srtt; int did_add = 0; - us_cts = tcp_tv_to_usectick(&rack->r_ctl.act_rcv_time); + us_cts = tcp_tv_to_usec(&rack->r_ctl.act_rcv_time); segsiz = min(ctf_fixed_maxseg(tp), rack->r_ctl.rc_pace_min_segs); if (TSTMP_GEQ(us_cts, tp->gput_ts)) tim = us_cts - tp->gput_ts; @@ -5355,7 +5355,7 @@ skip_measurement: rack->r_ctl.rc_gp_lowrtt = 0xffffffff; rack->r_ctl.rc_gp_high_rwnd = rack->rc_tp->snd_wnd; - tp->gput_ts = tcp_tv_to_usectick(&rack->r_ctl.act_rcv_time); + tp->gput_ts = tcp_tv_to_usec(&rack->r_ctl.act_rcv_time); rack->app_limited_needs_set = 0; tp->gput_seq = th_ack; if (rack->in_probe_rtt) @@ -5490,7 +5490,7 @@ rack_ack_received(struct tcpcb *tp, struct tcp_rack *rack, uint32_t th_ack, uint rack->r_ctl.lt_bw_bytes += (tp->snd_max - rack->r_ctl.lt_seq); rack->r_ctl.lt_seq = tp->snd_max; - tmark = tcp_tv_to_lusectick(&rack->r_ctl.act_rcv_time); + tmark = tcp_tv_to_lusec(&rack->r_ctl.act_rcv_time); if (tmark >= rack->r_ctl.lt_timemark) { rack->r_ctl.lt_bw_time += (tmark - rack->r_ctl.lt_timemark); } @@ -6390,7 +6390,7 @@ rack_enter_persist(struct tcpcb *tp, struct tcp_rack *rack, uint32_t cts, tcp_se rack->r_ctl.lt_bw_bytes += (snd_una - rack->r_ctl.lt_seq); rack->r_ctl.lt_seq = snd_una; - tmark = tcp_tv_to_lusectick(&rack->r_ctl.act_rcv_time); + tmark = tcp_tv_to_lusec(&rack->r_ctl.act_rcv_time); if (tmark >= rack->r_ctl.lt_timemark) { rack->r_ctl.lt_bw_time += (tmark - rack->r_ctl.lt_timemark); } @@ -6592,22 +6592,22 @@ rack_start_hpts_timer (struct tcp_rack *rack, struct tcpcb *tp, uint32_t cts, * on the clock. We always have a min * 10 slots (10 x 10 i.e. 100 usecs). */ - if (slot <= HPTS_TICKS_PER_SLOT) { + if (slot <= HPTS_USECS_PER_SLOT) { /* We gain delay */ - rack->r_ctl.rc_agg_delayed += (HPTS_TICKS_PER_SLOT - slot); - slot = HPTS_TICKS_PER_SLOT; + rack->r_ctl.rc_agg_delayed += (HPTS_USECS_PER_SLOT - slot); + slot = HPTS_USECS_PER_SLOT; } else { /* We take off some */ - rack->r_ctl.rc_agg_delayed -= (slot - HPTS_TICKS_PER_SLOT); - slot = HPTS_TICKS_PER_SLOT; + rack->r_ctl.rc_agg_delayed -= (slot - HPTS_USECS_PER_SLOT); + slot = HPTS_USECS_PER_SLOT; } } else { slot -= rack->r_ctl.rc_agg_delayed; rack->r_ctl.rc_agg_delayed = 0; /* Make sure we have 100 useconds at minimum */ - if (slot < HPTS_TICKS_PER_SLOT) { - rack->r_ctl.rc_agg_delayed = HPTS_TICKS_PER_SLOT - slot; - slot = HPTS_TICKS_PER_SLOT; + if (slot < HPTS_USECS_PER_SLOT) { + rack->r_ctl.rc_agg_delayed = HPTS_USECS_PER_SLOT - slot; + slot = HPTS_USECS_PER_SLOT; } if (rack->r_ctl.rc_agg_delayed == 0) rack->r_late = 0; @@ -8780,7 +8780,7 @@ tcp_rack_xmit_timer_commit(struct tcp_rack *rack, struct tcpcb *tp) } stats_voi_update_abs_u32(tp->t_stats, VOI_TCP_PATHRTT, imax(0, rack->r_ctl.rack_rs.rs_us_rtt)); #endif - rack->r_ctl.last_rcv_tstmp_for_rtt = tcp_tv_to_mssectick(&rack->r_ctl.act_rcv_time); + rack->r_ctl.last_rcv_tstmp_for_rtt = tcp_tv_to_msec(&rack->r_ctl.act_rcv_time); /* * the retransmit should happen at rtt + 4 * rttvar. Because of the * way we do the smoothing, srtt and rttvar will each average +1/2 @@ -8886,8 +8886,8 @@ rack_update_rtt(struct tcpcb *tp, struct tcp_rack *rack, rack->r_ctl.rc_rack_min_rtt = 1; } } - if (TSTMP_GT(tcp_tv_to_usectick(&rack->r_ctl.act_rcv_time), rsm->r_tim_lastsent[(rsm->r_rtr_cnt-1)])) - us_rtt = tcp_tv_to_usectick(&rack->r_ctl.act_rcv_time) - (uint32_t)rsm->r_tim_lastsent[(rsm->r_rtr_cnt-1)]; + if (TSTMP_GT(tcp_tv_to_usec(&rack->r_ctl.act_rcv_time), rsm->r_tim_lastsent[(rsm->r_rtr_cnt-1)])) + us_rtt = tcp_tv_to_usec(&rack->r_ctl.act_rcv_time) - (uint32_t)rsm->r_tim_lastsent[(rsm->r_rtr_cnt-1)]; else us_rtt = tcp_get_usecs(NULL) - (uint32_t)rsm->r_tim_lastsent[(rsm->r_rtr_cnt-1)]; if (us_rtt == 0) @@ -8896,7 +8896,7 @@ rack_update_rtt(struct tcpcb *tp, struct tcp_rack *rack, /* Kick the RTT to the CC */ CC_ALGO(tp)->rttsample(&tp->t_ccv, us_rtt, 1, rsm->r_fas); } - rack_apply_updated_usrtt(rack, us_rtt, tcp_tv_to_usectick(&rack->r_ctl.act_rcv_time)); + rack_apply_updated_usrtt(rack, us_rtt, tcp_tv_to_usec(&rack->r_ctl.act_rcv_time)); if (ack_type == SACKED) { rack_log_rtt_sample_calc(rack, t, (uint32_t)rsm->r_tim_lastsent[(rsm->r_rtr_cnt - 1)], cts, 1); tcp_rack_xmit_timer(rack, t + 1, len_acked, us_rtt, 2 , rsm, rsm->r_rtr_cnt); @@ -8991,8 +8991,8 @@ rack_update_rtt(struct tcpcb *tp, struct tcp_rack *rack, * we retransmitted. This is because * we match the timestamps. */ - if (TSTMP_GT(tcp_tv_to_usectick(&rack->r_ctl.act_rcv_time), rsm->r_tim_lastsent[i])) - us_rtt = tcp_tv_to_usectick(&rack->r_ctl.act_rcv_time) - (uint32_t)rsm->r_tim_lastsent[i]; + if (TSTMP_GT(tcp_tv_to_usec(&rack->r_ctl.act_rcv_time), rsm->r_tim_lastsent[i])) + us_rtt = tcp_tv_to_usec(&rack->r_ctl.act_rcv_time) - (uint32_t)rsm->r_tim_lastsent[i]; else us_rtt = tcp_get_usecs(NULL) - (uint32_t)rsm->r_tim_lastsent[i]; CC_ALGO(tp)->rttsample(&tp->t_ccv, us_rtt, 1, rsm->r_fas); @@ -9185,7 +9185,7 @@ rack_need_set_test(struct tcpcb *tp, seq = tp->gput_seq; ts = tp->gput_ts; rack->app_limited_needs_set = 0; - tp->gput_ts = tcp_tv_to_usectick(&rack->r_ctl.act_rcv_time); + tp->gput_ts = tcp_tv_to_usec(&rack->r_ctl.act_rcv_time); /* Do we start at a new end? */ if ((use_which == RACK_USE_BEG) && SEQ_GEQ(rsm->r_start, tp->gput_seq)) { @@ -10820,7 +10820,7 @@ rack_log_ack(struct tcpcb *tp, struct tcpopt *to, struct tcphdr *th, int entered changed = th_ack - rsm->r_start; if (changed) { rack_process_to_cumack(tp, rack, th_ack, cts, to, - tcp_tv_to_lusectick(&rack->r_ctl.act_rcv_time)); + tcp_tv_to_lusec(&rack->r_ctl.act_rcv_time)); } if ((to->to_flags & TOF_SACK) == 0) { /* We are done nothing left and no sack. */ @@ -11698,7 +11698,7 @@ rack_req_check_for_comp(struct tcp_rack *rack, tcp_seq th_ack) rack_log_hybrid_sends(rack, ent, __LINE__); /* calculate the time based on the ack arrival */ data = ent->end - ent->start; - laa = tcp_tv_to_lusectick(&rack->r_ctl.act_rcv_time); + laa = tcp_tv_to_lusec(&rack->r_ctl.act_rcv_time); if (ent->flags & TCP_TRK_TRACK_FLG_FSND) { if (ent->first_send > ent->localtime) ftim = ent->first_send; @@ -11844,7 +11844,7 @@ rack_process_ack(struct mbuf *m, struct tcphdr *th, struct socket *so, * less than and we have not closed our window. */ if (SEQ_LT(th->th_ack, tp->snd_una) && (sbspace(&so->so_rcv) > ctf_fixed_maxseg(tp))) { - rack->r_ctl.rc_reorder_ts = tcp_tv_to_usectick(&rack->r_ctl.act_rcv_time); + rack->r_ctl.rc_reorder_ts = tcp_tv_to_usec(&rack->r_ctl.act_rcv_time); if (rack->r_ctl.rc_reorder_ts == 0) rack->r_ctl.rc_reorder_ts = 1; } @@ -14368,17 +14368,17 @@ rack_switch_failed(struct tcpcb *tp) toval = rack->r_ctl.rc_last_output_to - cts; } else { /* one slot please */ - toval = HPTS_TICKS_PER_SLOT; + toval = HPTS_USECS_PER_SLOT; } } else if (rack->r_ctl.rc_hpts_flags & PACE_TMR_MASK) { if (TSTMP_GT(rack->r_ctl.rc_timer_exp, cts)) { toval = rack->r_ctl.rc_timer_exp - cts; } else { /* one slot please */ - toval = HPTS_TICKS_PER_SLOT; + toval = HPTS_USECS_PER_SLOT; } } else - toval = HPTS_TICKS_PER_SLOT; + toval = HPTS_USECS_PER_SLOT; (void)tcp_hpts_insert_diag(tp, HPTS_USEC_TO_SLOTS(toval), __LINE__, &diag); rack_log_hpts_diag(rack, cts, &diag, &tv); @@ -14743,12 +14743,12 @@ rack_init(struct tcpcb *tp, void **ptr) rack->r_ctl.rack_per_of_gp_ss = 250; } rack->r_ctl.rack_per_of_gp_probertt = rack_per_of_gp_probertt; - rack->r_ctl.rc_tlp_rxt_last_time = tcp_tv_to_mssectick(&rack->r_ctl.act_rcv_time); - rack->r_ctl.last_rcv_tstmp_for_rtt = tcp_tv_to_mssectick(&rack->r_ctl.act_rcv_time); + rack->r_ctl.rc_tlp_rxt_last_time = tcp_tv_to_msec(&rack->r_ctl.act_rcv_time); + rack->r_ctl.last_rcv_tstmp_for_rtt = tcp_tv_to_msec(&rack->r_ctl.act_rcv_time); setup_time_filter_small(&rack->r_ctl.rc_gp_min_rtt, FILTER_TYPE_MIN, rack_probertt_filter_life); - us_cts = tcp_tv_to_usectick(&rack->r_ctl.act_rcv_time); + us_cts = tcp_tv_to_usec(&rack->r_ctl.act_rcv_time); rack->r_ctl.rc_lower_rtt_us_cts = us_cts; rack->r_ctl.rc_time_of_last_probertt = us_cts; rack->r_ctl.rc_went_idle_time = us_cts; @@ -14957,7 +14957,7 @@ rack_init(struct tcpcb *tp, void **ptr) if (TSTMP_GT(qr.timer_pacing_to, us_cts)) tov = qr.timer_pacing_to - us_cts; else - tov = HPTS_TICKS_PER_SLOT; + tov = HPTS_USECS_PER_SLOT; } if (qr.timer_hpts_flags & PACE_TMR_MASK) { rack->r_ctl.rc_timer_exp = qr.timer_timer_exp; @@ -14965,7 +14965,7 @@ rack_init(struct tcpcb *tp, void **ptr) if (TSTMP_GT(qr.timer_timer_exp, us_cts)) tov = qr.timer_timer_exp - us_cts; else - tov = HPTS_TICKS_PER_SLOT; + tov = HPTS_USECS_PER_SLOT; } } rack_log_chg_info(tp, rack, 4, @@ -15385,7 +15385,7 @@ rack_log_input_packet(struct tcpcb *tp, struct tcp_rack *rack, struct tcp_ackent ts.tv_nsec = ae->timestamp % 1000000000; ltv.tv_sec = ts.tv_sec; ltv.tv_usec = ts.tv_nsec / 1000; - log.u_bbr.lt_epoch = tcp_tv_to_usectick(<v); + log.u_bbr.lt_epoch = tcp_tv_to_usec(<v); } else if (ae->flags & TSTMP_LRO) { /* Record the LRO the arrival timestamp */ log.u_bbr.flex3 = M_TSTMP_LRO; @@ -15393,7 +15393,7 @@ rack_log_input_packet(struct tcpcb *tp, struct tcp_rack *rack, struct tcp_ackent ts.tv_nsec = ae->timestamp % 1000000000; ltv.tv_sec = ts.tv_sec; ltv.tv_usec = ts.tv_nsec / 1000; - log.u_bbr.flex5 = tcp_tv_to_usectick(<v); + log.u_bbr.flex5 = tcp_tv_to_usec(<v); } log.u_bbr.timeStamp = tcp_get_usecs(<v); /* Log the rcv time */ @@ -15564,7 +15564,7 @@ rack_log_pcm(struct tcp_rack *rack, uint8_t mod, uint32_t flex1, uint32_t flex2, (void)tcp_get_usecs(&tv); memset(&log, 0, sizeof(log)); - log.u_bbr.timeStamp = tcp_tv_to_usectick(&tv); + log.u_bbr.timeStamp = tcp_tv_to_usec(&tv); log.u_bbr.inflight = ctf_flight_size(rack->rc_tp, rack->r_ctl.rc_sacked); log.u_bbr.flex8 = mod; log.u_bbr.flex1 = flex1; @@ -15747,8 +15747,8 @@ rack_do_compressed_ack_processing(struct tcpcb *tp, struct socket *so, struct mb the_win = tp->snd_wnd; win_seq = tp->snd_wl1; win_upd_ack = tp->snd_wl2; - cts = tcp_tv_to_usectick(tv); - ms_cts = tcp_tv_to_mssectick(tv); + cts = tcp_tv_to_usec(tv); + ms_cts = tcp_tv_to_msec(tv); rack->r_ctl.rc_rcvtime = cts; segsiz = ctf_fixed_maxseg(tp); if ((rack->rc_gp_dyn_mul) && @@ -15864,7 +15864,7 @@ rack_do_compressed_ack_processing(struct tcpcb *tp, struct socket *so, struct mb * or it could be a keep-alive or persists */ if (SEQ_LT(ae->ack, tp->snd_una) && (sbspace(&so->so_rcv) > segsiz)) { - rack->r_ctl.rc_reorder_ts = tcp_tv_to_usectick(&rack->r_ctl.act_rcv_time); + rack->r_ctl.rc_reorder_ts = tcp_tv_to_usec(&rack->r_ctl.act_rcv_time); if (rack->r_ctl.rc_reorder_ts == 0) rack->r_ctl.rc_reorder_ts = 1; } @@ -15883,7 +15883,7 @@ rack_do_compressed_ack_processing(struct tcpcb *tp, struct socket *so, struct mb } if (rack->forced_ack) { rack_handle_probe_response(rack, tiwin, - tcp_tv_to_usectick(&rack->r_ctl.act_rcv_time)); + tcp_tv_to_usec(&rack->r_ctl.act_rcv_time)); } #ifdef TCP_ACCOUNTING win_up_req = 1; @@ -15930,7 +15930,7 @@ rack_do_compressed_ack_processing(struct tcpcb *tp, struct socket *so, struct mb rack->r_ctl.act_rcv_time = *tv; } rack_process_to_cumack(tp, rack, ae->ack, cts, to, - tcp_tv_to_lusectick(&rack->r_ctl.act_rcv_time)); + tcp_tv_to_lusec(&rack->r_ctl.act_rcv_time)); #ifdef TCP_REQUEST_TRK rack_req_check_for_comp(rack, high_seq); #endif @@ -16398,7 +16398,7 @@ rack_do_segment_nounlock(struct tcpcb *tp, struct mbuf *m, struct tcphdr *th, * must process the ack coming in but need to defer sending * anything becase a pacing timer is running. */ - us_cts = tcp_tv_to_usectick(tv); + us_cts = tcp_tv_to_usec(tv); if (m->m_flags & M_ACKCMP) { /* * All compressed ack's are ack's by definition so @@ -16466,8 +16466,8 @@ rack_do_segment_nounlock(struct tcpcb *tp, struct mbuf *m, struct tcphdr *th, if (m->m_flags & M_ACKCMP) { panic("Impossible reach m has ackcmp? m:%p tp:%p", m, tp); } - cts = tcp_tv_to_usectick(tv); - ms_cts = tcp_tv_to_mssectick(tv); + cts = tcp_tv_to_usec(tv); + ms_cts = tcp_tv_to_msec(tv); nsegs = m->m_pkthdr.lro_nsegs; counter_u64_add(rack_proc_non_comp_ack, 1); #ifdef TCP_ACCOUNTING @@ -16595,13 +16595,13 @@ rack_do_segment_nounlock(struct tcpcb *tp, struct mbuf *m, struct tcphdr *th, mbuf_tstmp2timespec(m, &ts); ltv.tv_sec = ts.tv_sec; ltv.tv_usec = ts.tv_nsec / 1000; - log.u_bbr.lt_epoch = tcp_tv_to_usectick(<v); + log.u_bbr.lt_epoch = tcp_tv_to_usec(<v); } else if (m->m_flags & M_TSTMP_LRO) { /* Record the LRO the arrival timestamp */ mbuf_tstmp2timespec(m, &ts); ltv.tv_sec = ts.tv_sec; ltv.tv_usec = ts.tv_nsec / 1000; - log.u_bbr.flex5 = tcp_tv_to_usectick(<v); + log.u_bbr.flex5 = tcp_tv_to_usec(<v); } log.u_bbr.timeStamp = tcp_get_usecs(<v); /* Log the rcv time */ @@ -16819,7 +16819,7 @@ rack_do_segment_nounlock(struct tcpcb *tp, struct mbuf *m, struct tcphdr *th, } if (thflags & TH_FIN) tcp_log_end_status(tp, TCP_EI_STATUS_CLIENT_FIN); - us_cts = tcp_tv_to_usectick(&rack->r_ctl.act_rcv_time); + us_cts = tcp_tv_to_usec(&rack->r_ctl.act_rcv_time); if ((rack->rc_gp_dyn_mul) && (rack->use_fixed_rate == 0) && (rack->rc_always_pace)) { @@ -19442,7 +19442,7 @@ again: } if ((error == 0) && (rack->lt_bw_up == 0)) { /* Unlikely */ - rack->r_ctl.lt_timemark = tcp_tv_to_lusectick(tv); + rack->r_ctl.lt_timemark = tcp_tv_to_lusec(tv); rack->r_ctl.lt_seq = tp->snd_una; rack->lt_bw_up = 1; } else if ((error == 0) && @@ -19785,7 +19785,7 @@ rack_output(struct tcpcb *tp) #endif early = 0; cts = tcp_get_usecs(&tv); - ms_cts = tcp_tv_to_mssectick(&tv); + ms_cts = tcp_tv_to_msec(&tv); if (((rack->r_ctl.rc_hpts_flags & PACE_PKT_OUTPUT) == 0) && tcp_in_hpts(rack->rc_tp)) { /* @@ -20023,7 +20023,7 @@ rack_output(struct tcpcb *tp) again: sendalot = 0; cts = tcp_get_usecs(&tv); - ms_cts = tcp_tv_to_mssectick(&tv); + ms_cts = tcp_tv_to_msec(&tv); tso = 0; mtu = 0; if (TCPS_HAVEESTABLISHED(tp->t_state) && @@ -22090,7 +22090,7 @@ out: } if (rsm == NULL) { if (rack->lt_bw_up == 0) { - rack->r_ctl.lt_timemark = tcp_tv_to_lusectick(&tv); + rack->r_ctl.lt_timemark = tcp_tv_to_lusec(&tv); rack->r_ctl.lt_seq = tp->snd_una; rack->lt_bw_up = 1; } else if (((rack_seq + len) - rack->r_ctl.lt_seq) > 0x7fffffff) { @@ -22838,7 +22838,7 @@ process_hybrid_pacing(struct tcp_rack *rack, struct tcp_hybrid_req *hybrid) rack->r_ctl.rc_fixed_pacing_rate_ca = 0; rack->r_ctl.rc_fixed_pacing_rate_ss = 0; /* Now allocate or find our entry that will have these settings */ - sft = tcp_req_alloc_req_full(rack->rc_tp, &hybrid->req, tcp_tv_to_lusectick(&tv), 0); + sft = tcp_req_alloc_req_full(rack->rc_tp, &hybrid->req, tcp_tv_to_lusec(&tv), 0); if (sft == NULL) { rack->rc_tp->tcp_hybrid_error++; /* no space, where would it have gone? */ diff --git a/sys/netinet/tcp_stacks/rack_pcm.c b/sys/netinet/tcp_stacks/rack_pcm.c index 101e6826536c..759bfda98357 100644 --- a/sys/netinet/tcp_stacks/rack_pcm.c +++ b/sys/netinet/tcp_stacks/rack_pcm.c @@ -174,7 +174,7 @@ rack_update_pcm_ack(struct tcp_rack *rack, int was_cumack, uint32_t start, uint3 /* * Record ACK data. */ - ack_arrival = tcp_tv_to_lusectick(&rack->r_ctl.act_rcv_time); + ack_arrival = tcp_tv_to_lusec(&rack->r_ctl.act_rcv_time); if (SEQ_GT(end, rack->r_ctl.pcm_i.eseq)) { /* Trim the end to the end of our range if it is beyond */ end = rack->r_ctl.pcm_i.eseq; @@ -242,7 +242,7 @@ skip_ack_accounting: e = &rack->r_ctl.pcm_s[i]; memset(&log, 0, sizeof(log)); - log.u_bbr.timeStamp = tcp_tv_to_usectick(&tv); + log.u_bbr.timeStamp = tcp_tv_to_usec(&tv); log.u_bbr.inflight = ctf_flight_size(rack->rc_tp, rack->r_ctl.rc_sacked); log.u_bbr.flex8 = 1; log.u_bbr.flex1 = e->sseq; @@ -286,7 +286,7 @@ skip_ack_accounting: * Prev time holds the last ack arrival time. */ memset(&log.u_bbr, 0, sizeof(log.u_bbr)); - log.u_bbr.timeStamp = tcp_tv_to_usectick(&tv); + log.u_bbr.timeStamp = tcp_tv_to_usec(&tv); log.u_bbr.inflight = ctf_flight_size(rack->rc_tp, rack->r_ctl.rc_sacked); log.u_bbr.flex8 = 2; log.u_bbr.flex1 = rack->r_ctl.pcm_i.sseq; diff --git a/sys/netlink/netlink_io.c b/sys/netlink/netlink_io.c index ce323910af3f..e7908d6f3a44 100644 --- a/sys/netlink/netlink_io.c +++ b/sys/netlink/netlink_io.c @@ -308,6 +308,7 @@ static void npt_clear(struct nl_pstate *npt) { lb_clear(&npt->lb); + npt->cookie = NULL; npt->error = 0; npt->err_msg = NULL; npt->err_off = 0; diff --git a/sys/rpc/authunix_prot.c b/sys/rpc/authunix_prot.c index 7b531946488a..b107d5541c50 100644 --- a/sys/rpc/authunix_prot.c +++ b/sys/rpc/authunix_prot.c @@ -96,8 +96,12 @@ xdr_authunix_parms(XDR *xdrs, uint32_t *time, struct xucred *cred) if (!xdr_uint32_t(xdrs, &cred->cr_gid)) return (FALSE); - /* XXXKE Fix this is cr_gid gets separated out. */ if (xdrs->x_op == XDR_ENCODE) { + /* + * Note that this is a `struct xucred`, which maintains its + * historical layout of preserving the egid in cr_ngroups and + * cr_groups[0] == egid. + */ ngroups = cred->cr_ngroups - 1; if (ngroups > NGRPS) ngroups = NGRPS; diff --git a/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c b/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c index b1790dd167d5..51077c71822c 100644 --- a/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c +++ b/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c @@ -537,7 +537,7 @@ rpc_gss_svc_getcred(struct svc_req *req, struct ucred **crp, int *flavorp) cr = client->cl_cred = crget(); cr->cr_uid = cr->cr_ruid = cr->cr_svuid = uc->uid; cr->cr_rgid = cr->cr_svgid = uc->gid; - crsetgroups_fallback(cr, uc->gidlen, uc->gidlist, uc->gid); + crsetgroups_and_egid(cr, uc->gidlen, uc->gidlist, uc->gid); cr->cr_prison = curthread->td_ucred->cr_prison; prison_hold(cr->cr_prison); *crp = crhold(cr); diff --git a/sys/rpc/svc_auth.c b/sys/rpc/svc_auth.c index 92f1ee0f2844..acbb1112e270 100644 --- a/sys/rpc/svc_auth.c +++ b/sys/rpc/svc_auth.c @@ -39,6 +39,7 @@ */ #include <sys/param.h> +#include <sys/conf.h> #include <sys/lock.h> #include <sys/mutex.h> #include <sys/proc.h> @@ -191,7 +192,7 @@ svc_getcred(struct svc_req *rqst, struct ucred **crp, int *flavorp) return (FALSE); cr = crget(); cr->cr_uid = cr->cr_ruid = cr->cr_svuid = xprt->xp_uid; - crsetgroups(cr, xprt->xp_ngrps, xprt->xp_gidp); + crsetgroups_and_egid(cr, xprt->xp_ngrps, xprt->xp_gidp, GID_NOGROUP); cr->cr_rgid = cr->cr_svgid = cr->cr_gid; cr->cr_prison = curthread->td_ucred->cr_prison; prison_hold(cr->cr_prison); @@ -206,7 +207,7 @@ svc_getcred(struct svc_req *rqst, struct ucred **crp, int *flavorp) return (FALSE); cr = crget(); cr->cr_uid = cr->cr_ruid = cr->cr_svuid = xcr->cr_uid; - crsetgroups(cr, xcr->cr_ngroups, xcr->cr_groups); + crsetgroups_and_egid(cr, xcr->cr_ngroups, xcr->cr_groups, GID_NOGROUP); cr->cr_rgid = cr->cr_svgid = cr->cr_gid; cr->cr_prison = curthread->td_ucred->cr_prison; prison_hold(cr->cr_prison); diff --git a/sys/rpc/svc_auth_unix.c b/sys/rpc/svc_auth_unix.c index b10ef33be704..963f4f272964 100644 --- a/sys/rpc/svc_auth_unix.c +++ b/sys/rpc/svc_auth_unix.c @@ -89,8 +89,12 @@ _svcauth_unix(struct svc_req *rqst, struct rpc_msg *msg) stat = AUTH_BADCRED; goto done; } - /* XXXKE Fix this if cr_gid gets separated out. */ for (i = 0; i < gid_len; i++) { + /* + * Note that this is a `struct xucred`, which maintains + * its historical layout of preserving the egid in + * cr_ngroups and cr_groups[0] == egid. + */ if (i + 1 < XU_NGROUPS) xcr->cr_groups[i + 1] = IXDR_GET_INT32(buf); else diff --git a/sys/sys/param.h b/sys/sys/param.h index 33d61e8a1619..f7abc740ddc3 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -74,7 +74,7 @@ * cannot include sys/param.h and should only be updated here. */ #undef __FreeBSD_version -#define __FreeBSD_version 1500055 +#define __FreeBSD_version 1500056 /* * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD, diff --git a/sys/sys/ucred.h b/sys/sys/ucred.h index ddd8f3ddb63d..9c1d8545af34 100644 --- a/sys/sys/ucred.h +++ b/sys/sys/ucred.h @@ -44,6 +44,7 @@ * Flags for cr_flags. */ #define CRED_FLAG_CAPMODE 0x00000001 /* In capability mode. */ +#define CRED_FLAG_GROUPSET 0x00000002 /* Groups have been set. */ /* * Number of groups inlined in 'struct ucred'. It must stay reasonably low as @@ -76,15 +77,12 @@ struct ucred { u_int cr_users; /* (c) proc + thread using this cred */ u_int cr_flags; /* credential flags */ struct auditinfo_addr cr_audit; /* Audit properties. */ + int cr_ngroups; /* number of supplementary groups */ #define cr_startcopy cr_uid uid_t cr_uid; /* effective user id */ uid_t cr_ruid; /* real user id */ uid_t cr_svuid; /* saved user id */ - /* - * XXXOC: On the next ABI change, please move 'cr_ngroups' out of the - * copied area (crcopy() already copes with this change). - */ - int cr_ngroups; /* number of groups */ + gid_t cr_gid; /* effective group id */ gid_t cr_rgid; /* real group id */ gid_t cr_svgid; /* saved group id */ struct uidinfo *cr_uidinfo; /* per euid resource consumption */ @@ -111,8 +109,20 @@ struct ucred { struct xucred { u_int cr_version; /* structure layout version */ uid_t cr_uid; /* effective user id */ - short cr_ngroups; /* number of groups */ - gid_t cr_groups[XU_NGROUPS]; /* groups */ + short cr_ngroups; /* number of groups (incl. cr_gid). */ + union { + /* + * Special little hack to avoid needing a cr_gid macro, which + * would cause problems if one were to use it with struct ucred + * which also has a cr_groups member. + */ + struct { + gid_t cr_gid; /* effective group id */ + gid_t cr_sgroups[XU_NGROUPS - 1]; + }; + + gid_t cr_groups[XU_NGROUPS]; /* groups */ + }; union { void *_cr_unused1; /* compatibility with old ucred */ pid_t cr_pid; @@ -120,9 +130,6 @@ struct xucred { }; #define XUCRED_VERSION 0 -/* This can be used for both ucred and xucred structures. */ -#define cr_gid cr_groups[0] - struct mac; /* * Structure to pass as an argument to the setcred() system call. @@ -235,8 +242,8 @@ void crcowfree(struct thread *td); void cru2x(struct ucred *cr, struct xucred *xcr); void cru2xt(struct thread *td, struct xucred *xcr); void crsetgroups(struct ucred *cr, int ngrp, const gid_t *groups); -void crsetgroups_fallback(struct ucred *cr, int ngrp, const gid_t *groups, - const gid_t fallback); +void crsetgroups_and_egid(struct ucred *cr, int ngrp, const gid_t *groups, + const gid_t default_egid); bool cr_xids_subset(struct ucred *active_cred, struct ucred *obj_cred); /* diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c index 3f4aec02ba49..67cd6fb4b738 100644 --- a/sys/ufs/ffs/ffs_softdep.c +++ b/sys/ufs/ffs/ffs_softdep.c @@ -274,7 +274,7 @@ void softdep_setup_remove(struct buf *bp, struct inode *dp, struct inode *ip, - int isrmdir) + bool isrmdir) { panic("softdep_setup_remove called"); @@ -285,7 +285,7 @@ softdep_setup_directory_change(struct buf *bp, struct inode *dp, struct inode *ip, ino_t newinum, - int isrmdir) + u_int newparent) { panic("softdep_setup_directory_change called"); @@ -765,7 +765,7 @@ static void initiate_write_inodeblock_ufs2(struct inodedep *, struct buf *); static void handle_workitem_freefile(struct freefile *); static int handle_workitem_remove(struct dirrem *, int); static struct dirrem *newdirrem(struct buf *, struct inode *, - struct inode *, int, struct dirrem **); + struct inode *, bool, struct dirrem **); static struct indirdep *indirdep_lookup(struct mount *, struct inode *, struct buf *); static void cancel_indirdep(struct indirdep *, struct buf *, @@ -9169,7 +9169,7 @@ softdep_setup_remove( struct buf *bp, /* buffer containing directory block */ struct inode *dp, /* inode for the directory being modified */ struct inode *ip, /* inode for directory entry being removed */ - int isrmdir) /* indicates if doing RMDIR */ + bool isrmdir) /* indicates if doing RMDIR */ { struct dirrem *dirrem, *prevdirrem; struct inodedep *inodedep; @@ -9361,7 +9361,7 @@ newdirrem( struct buf *bp, /* buffer containing directory block */ struct inode *dp, /* inode for the directory being modified */ struct inode *ip, /* inode for directory entry being removed */ - int isrmdir, /* indicates if doing RMDIR */ + bool isrmdir, /* indicates if doing RMDIR */ struct dirrem **prevdirremp) /* previously referenced inode, if any */ { int offset; @@ -9490,7 +9490,7 @@ newdirrem( dirrem->dm_state |= COMPLETE; cancel_diradd(dap, dirrem, jremref, dotremref, dotdotremref); #ifdef INVARIANTS - if (isrmdir == 0) { + if (!isrmdir) { struct worklist *wk; LIST_FOREACH(wk, &dirrem->dm_jwork, wk_list) @@ -9525,7 +9525,7 @@ softdep_setup_directory_change( struct inode *dp, /* inode for the directory being modified */ struct inode *ip, /* inode for directory entry being removed */ ino_t newinum, /* new inode number for changed entry */ - int isrmdir) /* indicates if doing RMDIR */ + u_int newparent) /* indicates if doing RMDIR */ { int offset; struct diradd *dap = NULL; @@ -9558,10 +9558,10 @@ softdep_setup_directory_change( /* * Allocate a new dirrem and ACQUIRE_LOCK. */ - dirrem = newdirrem(bp, dp, ip, isrmdir, &prevdirrem); + dirrem = newdirrem(bp, dp, ip, newparent != 0, &prevdirrem); pagedep = dirrem->dm_pagedep; /* - * The possible values for isrmdir: + * The possible values for newparent: * 0 - non-directory file rename * 1 - directory rename within same directory * inum - directory rename to new directory of given inode number @@ -9572,7 +9572,7 @@ softdep_setup_directory_change( * the DIRCHG flag to tell handle_workitem_remove to skip the * followup dirrem. */ - if (isrmdir > 1) + if (newparent > 1) dirrem->dm_state |= DIRCHG; /* diff --git a/sys/ufs/ufs/ufs_extern.h b/sys/ufs/ufs/ufs_extern.h index ccd9046a5fa8..111fb1cb40b3 100644 --- a/sys/ufs/ufs/ufs_extern.h +++ b/sys/ufs/ufs/ufs_extern.h @@ -66,8 +66,8 @@ void ufs_makedirentry(struct inode *, struct componentname *, struct direct *); int ufs_direnter(struct vnode *, struct vnode *, struct direct *, struct componentname *, struct buf *); -int ufs_dirremove(struct vnode *, struct inode *, int, int); -int ufs_dirrewrite(struct inode *, struct inode *, ino_t, int, int); +int ufs_dirremove(struct vnode *, struct inode *, int, bool); +int ufs_dirrewrite(struct inode *, struct inode *, ino_t, int, u_int); int ufs_lookup_ino(struct vnode *, struct vnode **, struct componentname *, ino_t *); int ufs_getlbns(struct vnode *, ufs2_daddr_t, struct indir *, int *); @@ -93,9 +93,9 @@ int softdep_setup_directory_add(struct buf *, struct inode *, off_t, ino_t, struct buf *, int); void softdep_change_directoryentry_offset(struct buf *, struct inode *, caddr_t, caddr_t, caddr_t, int); -void softdep_setup_remove(struct buf *,struct inode *, struct inode *, int); +void softdep_setup_remove(struct buf *,struct inode *, struct inode *, bool); void softdep_setup_directory_change(struct buf *, struct inode *, - struct inode *, ino_t, int); + struct inode *, ino_t, u_int); void softdep_change_linkcnt(struct inode *); int softdep_slowdown(struct vnode *); void softdep_setup_create(struct inode *, struct inode *); diff --git a/sys/ufs/ufs/ufs_lookup.c b/sys/ufs/ufs/ufs_lookup.c index 3f9c95e934fc..fd0539c40c0d 100644 --- a/sys/ufs/ufs/ufs_lookup.c +++ b/sys/ufs/ufs/ufs_lookup.c @@ -1101,7 +1101,7 @@ ufs_direnter(struct vnode *dvp, struct vnode *tvp, struct direct *dirp, * to the size of the previous entry. */ int -ufs_dirremove(struct vnode *dvp, struct inode *ip, int flags, int isrmdir) +ufs_dirremove(struct vnode *dvp, struct inode *ip, int flags, bool isrmdir) { struct inode *dp; struct direct *ep, *rep; @@ -1224,7 +1224,7 @@ out: */ int ufs_dirrewrite(struct inode *dp, struct inode *oip, ino_t newinum, int newtype, - int isrmdir) + u_int newparent) { struct buf *bp; struct direct *ep; @@ -1267,7 +1267,8 @@ ufs_dirrewrite(struct inode *dp, struct inode *oip, ino_t newinum, int newtype, if (!OFSFMT(vdp)) ep->d_type = newtype; if (DOINGSOFTDEP(vdp)) { - softdep_setup_directory_change(bp, dp, oip, newinum, isrmdir); + softdep_setup_directory_change(bp, dp, oip, newinum, + newparent); bdwrite(bp); } else { if (DOINGASYNC(vdp)) { diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c index b7453db9013c..ffc993aef9fc 100644 --- a/sys/ufs/ufs/ufs_vnops.c +++ b/sys/ufs/ufs/ufs_vnops.c @@ -1051,7 +1051,7 @@ ufs_remove( #ifdef UFS_GJOURNAL ufs_gjournal_orphan(vp); #endif - error = ufs_dirremove(dvp, ip, ap->a_cnp->cn_flags, 0); + error = ufs_dirremove(dvp, ip, ap->a_cnp->cn_flags, false); if (ip->i_nlink <= 0) vp->v_vflag |= VV_NOSYNC; if (IS_SNAPSHOT(ip)) { @@ -1209,7 +1209,7 @@ ufs_whiteout( #endif cnp->cn_flags &= ~DOWHITEOUT; - error = ufs_dirremove(dvp, NULL, cnp->cn_flags, 0); + error = ufs_dirremove(dvp, NULL, cnp->cn_flags, false); break; default: panic("ufs_whiteout: unknown op"); @@ -1728,7 +1728,7 @@ relock: "rename: missing .. entry"); cache_purge(fdvp); } - error = ufs_dirremove(fdvp, fip, fcnp->cn_flags, 0); + error = ufs_dirremove(fdvp, fip, fcnp->cn_flags, false); /* * The kern_renameat() looks up the fvp using the DELETE flag, which * causes the removal of the name cache entry for fvp. @@ -2038,7 +2038,6 @@ ufs_mkdir( { #ifdef QUOTA struct ucred ucred, *ucp; - gid_t ucred_group; ucp = cnp->cn_cred; #endif /* @@ -2065,13 +2064,8 @@ ufs_mkdir( */ ucred.cr_ref = 1; ucred.cr_uid = ip->i_uid; - - /* - * XXXKE Fix this is cr_gid gets separated out - */ - ucred.cr_ngroups = 1; - ucred.cr_groups = &ucred_group; - ucred.cr_gid = ucred_group = dp->i_gid; + ucred.cr_gid = dp->i_gid; + ucred.cr_ngroups = 0; ucp = &ucred; } #endif @@ -2309,7 +2303,7 @@ ufs_rmdir( ip->i_effnlink--; if (DOINGSOFTDEP(vp)) softdep_setup_rmdir(dp, ip); - error = ufs_dirremove(dvp, ip, cnp->cn_flags, 1); + error = ufs_dirremove(dvp, ip, cnp->cn_flags, true); if (error) { dp->i_effnlink++; ip->i_effnlink++; @@ -2802,7 +2796,6 @@ ufs_makeinode(int mode, struct vnode *dvp, struct vnode **vpp, { #ifdef QUOTA struct ucred ucred, *ucp; - gid_t ucred_group; ucp = cnp->cn_cred; #endif /* @@ -2828,13 +2821,8 @@ ufs_makeinode(int mode, struct vnode *dvp, struct vnode **vpp, */ ucred.cr_ref = 1; ucred.cr_uid = ip->i_uid; - - /* - * XXXKE Fix this is cr_gid gets separated out - */ - ucred.cr_ngroups = 1; - ucred.cr_groups = &ucred_group; - ucred.cr_gid = ucred_group = pdir->i_gid; + ucred.cr_gid = pdir->i_gid; + ucred.cr_ngroups = 0; ucp = &ucred; #endif } else { diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c index 327cac661044..c01b9e45a32b 100644 --- a/sys/vm/swap_pager.c +++ b/sys/vm/swap_pager.c @@ -3278,6 +3278,7 @@ swapongeom_locked(struct cdev *dev, struct vnode *vp) cp->index = 1; /* Number of active I/Os, plus one for being active. */ cp->flags |= G_CF_DIRECT_SEND | G_CF_DIRECT_RECEIVE; g_attach(cp, pp); + /* * XXX: Every time you think you can improve the margin for * footshooting, somebody depends on the ability to do so: @@ -3285,15 +3286,19 @@ swapongeom_locked(struct cdev *dev, struct vnode *vp) * set an exclusive count :-( */ error = g_access(cp, 1, 1, 0); + + if (error == 0) { + nblks = pp->mediasize / DEV_BSIZE; + error = swaponsomething(vp, cp, nblks, swapgeom_strategy, + swapgeom_close, dev2udev(dev), + (pp->flags & G_PF_ACCEPT_UNMAPPED) != 0 ? SW_UNMAPPED : 0); + if (error != 0) + g_access(cp, -1, -1, 0); + } if (error != 0) { g_detach(cp); g_destroy_consumer(cp); - return (error); } - nblks = pp->mediasize / DEV_BSIZE; - error = swaponsomething(vp, cp, nblks, swapgeom_strategy, - swapgeom_close, dev2udev(dev), - (pp->flags & G_PF_ACCEPT_UNMAPPED) != 0 ? SW_UNMAPPED : 0); return (error); } @@ -3385,6 +3390,8 @@ swaponvp(struct thread *td, struct vnode *vp, u_long nblks) error = swaponsomething(vp, vp, nblks, swapdev_strategy, swapdev_close, NODEV, 0); + if (error != 0) + VOP_CLOSE(vp, FREAD | FWRITE, td->td_ucred, td); return (error); } diff --git a/tools/build/options/WITH_LLVM_ASSERTIONS b/tools/build/options/WITH_LLVM_ASSERTIONS index 6af75221a206..0e7fbfbda0a3 100644 --- a/tools/build/options/WITH_LLVM_ASSERTIONS +++ b/tools/build/options/WITH_LLVM_ASSERTIONS @@ -1,2 +1 @@ Enable debugging assertions in LLVM. -Use when working on or requesting help with LLVM components. diff --git a/usr.bin/find/function.c b/usr.bin/find/function.c index 11455b395022..b260a71ef4a9 100644 --- a/usr.bin/find/function.c +++ b/usr.bin/find/function.c @@ -1449,11 +1449,12 @@ c_printf(OPTION *option, char ***argvp) { PLAN *new; - isoutput = 1; /* * XXX We could scan the format looking for stat-dependent formats, and - * turn off the stat if there's none: `%p`/`%f`/`%h` don't need a stat. + * turn off the nostat bit for trival cases: `%p`/`%f`/`%h`. */ + isoutput = 1; + ftsoptions &= ~FTS_NOSTAT; new = palloc(option); new->c_data = nextarg(option, argvp); diff --git a/usr.bin/sockstat/Makefile b/usr.bin/sockstat/Makefile index 188432dfc27e..7254511f21c6 100644 --- a/usr.bin/sockstat/Makefile +++ b/usr.bin/sockstat/Makefile @@ -2,7 +2,7 @@ PROG= sockstat -LIBADD= jail +LIBADD= jail xo .if ${MK_CASPER} != "no" LIBADD+= casper diff --git a/usr.bin/sockstat/sockstat.1 b/usr.bin/sockstat/sockstat.1 index 4832a09764fd..091911cd0879 100644 --- a/usr.bin/sockstat/sockstat.1 +++ b/usr.bin/sockstat/sockstat.1 @@ -25,7 +25,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd June 30, 2025 +.Dd July 17, 2025 .Dt SOCKSTAT 1 .Os .Sh NAME @@ -33,6 +33,7 @@ .Nd list open sockets .Sh SYNOPSIS .Nm +.Op Fl -libxo .Op Fl 46ACcfIiLlnqSsUuvw .Op Fl j Ar jail .Op Fl p Ar ports @@ -46,6 +47,13 @@ domain sockets. .Pp The following options are available: .Bl -tag -width Fl +.It Fl -libxo +Generate output via +.Xr libxo 3 +in a selection of different human and machine readable formats. +See +.Xr xo_options 7 +for details on command line arguments. .It Fl 4 Show .Dv AF_INET @@ -229,6 +237,11 @@ Show TCP IPv6 sockets which are listening and connected (default): .Bd -literal -offset indent $ sockstat -6 -P tcp .Ed +.Pp +Show all sockets in JSON format with neat alignment: +.Bd -literal -offset indent +$ sockstat --libxo json,pretty +.Ed .Sh SEE ALSO .Xr fstat 1 , .Xr netstat 1 , @@ -237,6 +250,8 @@ $ sockstat -6 -P tcp .Xr inet 4 , .Xr inet6 4 , .Xr protocols 5 +.Xr libxo 3 , +.Xr xo_options 7 .Sh HISTORY The .Nm diff --git a/usr.bin/sockstat/sockstat.c b/usr.bin/sockstat/sockstat.c index d0540c54a1aa..7355eaa272a0 100644 --- a/usr.bin/sockstat/sockstat.c +++ b/usr.bin/sockstat/sockstat.c @@ -55,7 +55,6 @@ #include <capsicum_helpers.h> #include <ctype.h> -#include <err.h> #include <errno.h> #include <inttypes.h> #include <jail.h> @@ -67,6 +66,7 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <libxo/xo.h> #include <libcasper.h> #include <casper/cap_net.h> @@ -74,6 +74,7 @@ #include <casper/cap_pwd.h> #include <casper/cap_sysctl.h> +#define SOCKSTAT_XO_VERSION "1" #define sstosin(ss) ((struct sockaddr_in *)(ss)) #define sstosin6(ss) ((struct sockaddr_in6 *)(ss)) #define sstosun(ss) ((struct sockaddr_un *)(ss)) @@ -197,7 +198,7 @@ static bool _check_ksize(size_t received_size, size_t expected_size, const char *struct_name) { if (received_size != expected_size) { - warnx("%s size mismatch: expected %zd, received %zd", + xo_warnx("%s size mismatch: expected %zd, received %zd", struct_name, expected_size, received_size); return false; } @@ -209,7 +210,7 @@ static void _enforce_ksize(size_t received_size, size_t expected_size, const char *struct_name) { if (received_size != expected_size) { - errx(1, "fatal: struct %s size mismatch: expected %zd, received %zd", + xo_errx(1, "fatal: struct %s size mismatch: expected %zd, received %zd", struct_name, expected_size, received_size); } } @@ -227,7 +228,7 @@ get_proto_type(const char *proto) else pent = getprotobyname(proto); if (pent == NULL) { - warn("cap_getprotobyname"); + xo_warn("cap_getprotobyname"); return (-1); } return (pent->p_proto); @@ -248,7 +249,7 @@ init_protos(int num) } if ((protos = malloc(sizeof(int) * proto_count)) == NULL) - err(1, "malloc"); + xo_err(1, "malloc"); numprotos = proto_count; } @@ -282,17 +283,17 @@ parse_ports(const char *portspec) if (ports == NULL) if ((ports = calloc(65536 / INT_BIT, sizeof(int))) == NULL) - err(1, "calloc()"); + xo_err(1, "calloc()"); p = portspec; while (*p != '\0') { if (!isdigit(*p)) - errx(1, "syntax error in port range"); + xo_errx(1, "syntax error in port range"); for (q = p; *q != '\0' && isdigit(*q); ++q) /* nothing */ ; for (port = 0; p < q; ++p) port = port * 10 + digittoint(*p); if (port < 0 || port > 65535) - errx(1, "invalid port number"); + xo_errx(1, "invalid port number"); SET_PORT(port); switch (*p) { case '-': @@ -310,7 +311,7 @@ parse_ports(const char *portspec) for (end = 0; p < q; ++p) end = end * 10 + digittoint(*p); if (end < port || end > 65535) - errx(1, "invalid port number"); + xo_errx(1, "invalid port number"); while (port++ < end) SET_PORT(port); if (*p == ',') @@ -395,15 +396,15 @@ gather_sctp(void) varname = "net.inet.sctp.assoclist"; if (cap_sysctlbyname(capsysctl, varname, 0, &len, 0, 0) < 0) { if (errno != ENOENT) - err(1, "cap_sysctlbyname()"); + xo_err(1, "cap_sysctlbyname()"); return; } if ((buf = (char *)malloc(len)) == NULL) { - err(1, "malloc()"); + xo_err(1, "malloc()"); return; } if (cap_sysctlbyname(capsysctl, varname, buf, &len, 0, 0) < 0) { - err(1, "cap_sysctlbyname()"); + xo_err(1, "cap_sysctlbyname()"); free(buf); return; } @@ -411,7 +412,7 @@ gather_sctp(void) offset = sizeof(struct xsctp_inpcb); while ((offset < len) && (xinpcb->last == 0)) { if ((sock = calloc(1, sizeof *sock)) == NULL) - err(1, "malloc()"); + xo_err(1, "malloc()"); sock->socket = xinpcb->socket; sock->proto = IPPROTO_SCTP; sock->protoname = "sctp"; @@ -439,7 +440,7 @@ gather_sctp(void) if (xladdr->last == 1) break; if ((laddr = calloc(1, sizeof(struct addr))) == NULL) - err(1, "malloc()"); + xo_err(1, "malloc()"); switch (xladdr->address.sa.sa_family) { case AF_INET: #define __IN_IS_ADDR_LOOPBACK(pina) \ @@ -461,7 +462,7 @@ gather_sctp(void) htons(xinpcb->local_port)); break; default: - errx(1, "address family %d not supported", + xo_errx(1, "address family %d not supported", xladdr->address.sa.sa_family); } laddr->next = NULL; @@ -474,7 +475,7 @@ gather_sctp(void) if (sock->laddr == NULL) { if ((sock->laddr = calloc(1, sizeof(struct addr))) == NULL) - err(1, "malloc()"); + xo_err(1, "malloc()"); sock->laddr->address.ss_family = sock->family; if (sock->family == AF_INET) sock->laddr->address.ss_len = @@ -485,7 +486,7 @@ gather_sctp(void) local_all_loopback = 0; } if ((sock->faddr = calloc(1, sizeof(struct addr))) == NULL) - err(1, "malloc()"); + xo_err(1, "malloc()"); sock->faddr->address.ss_family = sock->family; if (sock->family == AF_INET) sock->faddr->address.ss_len = @@ -512,7 +513,7 @@ gather_sctp(void) no_stcb = 0; if (opt_c) { if ((sock = calloc(1, sizeof *sock)) == NULL) - err(1, "malloc()"); + xo_err(1, "malloc()"); sock->socket = xinpcb->socket; sock->proto = IPPROTO_SCTP; sock->protoname = "sctp"; @@ -542,7 +543,7 @@ gather_sctp(void) continue; laddr = calloc(1, sizeof(struct addr)); if (laddr == NULL) - err(1, "malloc()"); + xo_err(1, "malloc()"); switch (xladdr->address.sa.sa_family) { case AF_INET: #define __IN_IS_ADDR_LOOPBACK(pina) \ @@ -564,7 +565,7 @@ gather_sctp(void) htons(xstcb->local_port)); break; default: - errx(1, + xo_errx(1, "address family %d not supported", xladdr->address.sa.sa_family); } @@ -587,7 +588,7 @@ gather_sctp(void) continue; faddr = calloc(1, sizeof(struct addr)); if (faddr == NULL) - err(1, "malloc()"); + xo_err(1, "malloc()"); switch (xraddr->address.sa.sa_family) { case AF_INET: #define __IN_IS_ADDR_LOOPBACK(pina) \ @@ -609,7 +610,7 @@ gather_sctp(void) htons(xstcb->remote_port)); break; default: - errx(1, + xo_errx(1, "address family %d not supported", xraddr->address.sa.sa_family); } @@ -673,7 +674,7 @@ gather_inet(int proto) protoname = "div"; break; default: - errx(1, "protocol %d not supported", proto); + xo_errx(1, "protocol %d not supported", proto); } buf = NULL; @@ -682,7 +683,7 @@ gather_inet(int proto) do { for (;;) { if ((buf = realloc(buf, bufsize)) == NULL) - err(1, "realloc()"); + xo_err(1, "realloc()"); len = bufsize; if (cap_sysctlbyname(capsysctl, varname, buf, &len, NULL, 0) == 0) @@ -690,7 +691,7 @@ gather_inet(int proto) if (errno == ENOENT) goto out; if (errno != ENOMEM || len != bufsize) - err(1, "cap_sysctlbyname()"); + xo_err(1, "cap_sysctlbyname()"); bufsize *= 2; } xig = (struct xinpgen *)buf; @@ -701,7 +702,7 @@ gather_inet(int proto) } while (xig->xig_gen != exig->xig_gen && retry--); if (xig->xig_gen != exig->xig_gen && opt_v) - warnx("warning: data may be inconsistent"); + xo_warnx("warning: data may be inconsistent"); for (;;) { xig = (struct xinpgen *)(void *)((char *)xig + xig->xig_len); @@ -722,7 +723,7 @@ gather_inet(int proto) goto out; break; default: - errx(1, "protocol %d not supported", proto); + xo_errx(1, "protocol %d not supported", proto); } so = &xip->xi_socket; if ((xip->inp_vflag & vflag) == 0) @@ -748,15 +749,15 @@ gather_inet(int proto) continue; } else { if (opt_v) - warnx("invalid vflag 0x%x", xip->inp_vflag); + xo_warnx("invalid vflag 0x%x", xip->inp_vflag); continue; } if ((sock = calloc(1, sizeof(*sock))) == NULL) - err(1, "malloc()"); + xo_err(1, "malloc()"); if ((laddr = calloc(1, sizeof *laddr)) == NULL) - err(1, "malloc()"); + xo_err(1, "malloc()"); if ((faddr = calloc(1, sizeof *faddr)) == NULL) - err(1, "malloc()"); + xo_err(1, "malloc()"); sock->socket = so->xso_so; sock->pcb = so->so_pcb; sock->splice_socket = so->so_splice_so; @@ -822,7 +823,9 @@ gather_unix(int proto) break; case SOCK_SEQPACKET: varname = "net.local.seqpacket.pcblist"; - protoname = "seqpac"; + protoname = (xo_get_style(NULL) == XO_STYLE_TEXT) + ? "seqpac" + : "seqpacket"; break; default: abort(); @@ -833,13 +836,13 @@ gather_unix(int proto) do { for (;;) { if ((buf = realloc(buf, bufsize)) == NULL) - err(1, "realloc()"); + xo_err(1, "realloc()"); len = bufsize; if (cap_sysctlbyname(capsysctl, varname, buf, &len, NULL, 0) == 0) break; if (errno != ENOMEM || len != bufsize) - err(1, "cap_sysctlbyname()"); + xo_err(1, "cap_sysctlbyname()"); bufsize *= 2; } xug = (struct xunpgen *)buf; @@ -851,7 +854,7 @@ gather_unix(int proto) } while (xug->xug_gen != exug->xug_gen && retry--); if (xug->xug_gen != exug->xug_gen && opt_v) - warnx("warning: data may be inconsistent"); + xo_warnx("warning: data may be inconsistent"); for (;;) { xug = (struct xunpgen *)(void *)((char *)xug + xug->xug_len); @@ -864,11 +867,11 @@ gather_unix(int proto) (xup->unp_conn != 0 && !opt_c)) continue; if ((sock = calloc(1, sizeof(*sock))) == NULL) - err(1, "malloc()"); + xo_err(1, "malloc()"); if ((laddr = calloc(1, sizeof *laddr)) == NULL) - err(1, "malloc()"); + xo_err(1, "malloc()"); if ((faddr = calloc(1, sizeof *faddr)) == NULL) - err(1, "malloc()"); + xo_err(1, "malloc()"); sock->socket = xup->xu_socket.xso_so; sock->pcb = xup->xu_unpp; sock->proto = proto; @@ -899,21 +902,21 @@ getfiles(void) olen = len = sizeof(*xfiles); if ((xfiles = malloc(len)) == NULL) - err(1, "malloc()"); + xo_err(1, "malloc()"); while (cap_sysctlbyname(capsysctl, "kern.file", xfiles, &len, 0, 0) == -1) { if (errno != ENOMEM || len != olen) - err(1, "cap_sysctlbyname()"); + xo_err(1, "cap_sysctlbyname()"); olen = len *= 2; if ((xfiles = realloc(xfiles, len)) == NULL) - err(1, "realloc()"); + xo_err(1, "realloc()"); } if (len > 0) enforce_ksize(xfiles->xf_size, struct xfile); nfiles = len / sizeof(*xfiles); if ((files = malloc(nfiles * sizeof(struct file))) == NULL) - err(1, "malloc()"); + xo_err(1, "malloc()"); for (int i = 0; i < nfiles; i++) { files[i].xf_data = xfiles[i].xf_data; @@ -932,6 +935,7 @@ formataddr(struct sockaddr_storage *ss, char *buf, size_t bufsize) struct sockaddr_un *sun; char addrstr[NI_MAXHOST] = { '\0', '\0' }; int error, off, port = 0; + const bool is_text_style = (xo_get_style(NULL) == XO_STYLE_TEXT); switch (ss->ss_family) { case AF_INET: @@ -947,6 +951,11 @@ formataddr(struct sockaddr_storage *ss, char *buf, size_t bufsize) case AF_UNIX: sun = sstosun(ss); off = (int)((char *)&sun->sun_path - (char *)sun); + if (!is_text_style) { + xo_emit("{:path/%.*s}", sun->sun_len - off, + sun->sun_path); + return 0; + } return snprintf(buf, bufsize, "%.*s", sun->sun_len - off, sun->sun_path); } @@ -954,7 +963,12 @@ formataddr(struct sockaddr_storage *ss, char *buf, size_t bufsize) error = cap_getnameinfo(capnet, sstosa(ss), ss->ss_len, addrstr, sizeof(addrstr), NULL, 0, NI_NUMERICHOST); if (error) - errx(1, "cap_getnameinfo()"); + xo_errx(1, "cap_getnameinfo()"); + } + if (!is_text_style) { + xo_emit("{:address/%s}", addrstr); + xo_emit("{:port/%d}", port); + return 0; } if (port == 0) return snprintf(buf, bufsize, "%s:*", addrstr); @@ -977,7 +991,7 @@ getprocname(pid_t pid) == -1) { /* Do not warn if the process exits before we get its name. */ if (errno != ESRCH) - warn("cap_sysctl()"); + xo_warn("cap_sysctl()"); return ("??"); } return (proc.ki_comm); @@ -999,7 +1013,7 @@ getprocjid(pid_t pid) == -1) { /* Do not warn if the process exits before we get its jid. */ if (errno != ESRCH) - warn("cap_sysctl()"); + xo_warn("cap_sysctl()"); return (-1); } return (proc.ki_jid); @@ -1099,13 +1113,15 @@ format_unix_faddr(struct addr *faddr, char *buf, size_t bufsize) { #define SAFESIZE (buf == NULL ? 0 : bufsize - pos) size_t pos = 0; - /* Remote peer we connect(2) to, if any. */ + const bool is_text_style = (xo_get_style(NULL) == XO_STYLE_TEXT); if (faddr->conn != 0) { + /* Remote peer we connect(2) to, if any. */ struct sock *p; - pos += strlcpy(SAFEBUF, "-> ", SAFESIZE); + if (is_text_style) + pos += strlcpy(SAFEBUF, "-> ", SAFESIZE); p = RB_FIND(pcbs_t, &pcbs, &(struct sock){ .pcb = faddr->conn }); - if (__predict_false(p == NULL)) { + if (__predict_false(p == NULL) && is_text_style) { /* XXGL: can this happen at all? */ pos += snprintf(SAFEBUF, SAFESIZE, "??"); } else if (p->laddr->address.ss_len == 0) { @@ -1114,34 +1130,52 @@ format_unix_faddr(struct addr *faddr, char *buf, size_t bufsize) { &(struct file){ .xf_data = p->socket }); if (f != NULL) { - pos += snprintf(SAFEBUF, SAFESIZE, "[%lu %d]", - (u_long)f->xf_pid, f->xf_fd); + if (is_text_style) { + pos += snprintf(SAFEBUF, SAFESIZE, + "[%lu %d]", (u_long)f->xf_pid, + f->xf_fd); + } else { + xo_open_list("connections"); + xo_open_instance("connections"); + xo_emit("{:pid/%lu}", (u_long)f->xf_pid); + xo_emit("{:fd/%d}", f->xf_fd); + xo_close_instance("connections"); + xo_close_list("connections"); + } } } else pos += formataddr(&p->laddr->address, SAFEBUF, SAFESIZE); - } - /* Remote peer(s) connect(2)ed to us, if any. */ - if (faddr->firstref != 0) { + } else if (faddr->firstref != 0) { + /* Remote peer(s) connect(2)ed to us, if any. */ struct sock *p; struct file *f; kvaddr_t ref = faddr->firstref; bool fref = true; - pos += snprintf(SAFEBUF, SAFESIZE, " <- "); - + if (is_text_style) + pos += snprintf(SAFEBUF, SAFESIZE, " <- "); + xo_open_list("connections"); while ((p = RB_FIND(pcbs_t, &pcbs, &(struct sock){ .pcb = ref })) != 0) { f = RB_FIND(files_t, &ftree, &(struct file){ .xf_data = p->socket }); if (f != NULL) { - pos += snprintf(SAFEBUF, SAFESIZE, - "%s[%lu %d]", fref ? "" : ",", - (u_long)f->xf_pid, f->xf_fd); + if (is_text_style) { + pos += snprintf(SAFEBUF, SAFESIZE, + "%s[%lu %d]", fref ? "" : ",", + (u_long)f->xf_pid, f->xf_fd); + } else { + xo_open_instance("connections"); + xo_emit("{:pid/%lu}", (u_long)f->xf_pid); + xo_emit("{:fd/%d}", f->xf_fd); + xo_close_instance("connections"); + } } ref = p->faddr->nextref; fref = false; } + xo_close_list("connections"); } return pos; } @@ -1183,7 +1217,7 @@ calculate_sock_column_widths(struct col_widths *cw, struct sock *s) while (laddr != NULL || faddr != NULL) { if (opt_w && s->family == AF_UNIX) { if ((laddr == NULL) || (faddr == NULL)) - errx(1, "laddr = %p or faddr = %p is NULL", + xo_errx(1, "laddr = %p or faddr = %p is NULL", (void *)laddr, (void *)faddr); if (laddr->address.ss_len > 0) len = formataddr(&laddr->address, NULL, 0); @@ -1298,6 +1332,7 @@ calculate_column_widths(struct col_widths *cw) struct sock *s; struct passwd *pwd; + cap_setpassent(cappwd, 1); for (xf = files, n = 0; n < nfiles; ++n, ++xf) { if (xf->xf_data == 0) continue; @@ -1345,65 +1380,104 @@ display_sock(struct sock *s, struct col_widths *cw, char *buf, size_t bufsize) laddr = s->laddr; faddr = s->faddr; first = true; + const bool is_text_style = (xo_get_style(NULL) == XO_STYLE_TEXT); snprintf(buf, bufsize, "%s%s%s", s->protoname, s->vflag & INP_IPV4 ? "4" : "", s->vflag & INP_IPV6 ? "6" : ""); - printf(" %-*s", cw->proto, buf); + xo_emit(" {:proto/%-*s}", cw->proto, buf); while (laddr != NULL || faddr != NULL) { if (s->family == AF_UNIX) { if ((laddr == NULL) || (faddr == NULL)) - errx(1, "laddr = %p or faddr = %p is NULL", + xo_errx(1, "laddr = %p or faddr = %p is NULL", (void *)laddr, (void *)faddr); - if (laddr->address.ss_len > 0) + if (laddr->address.ss_len > 0) { + xo_open_container("local"); formataddr(&laddr->address, buf, bufsize); - else if (laddr->address.ss_len == 0 && faddr->conn == 0) - strlcpy(buf, "(not connected)", bufsize); - else - strlcpy(buf, "??", bufsize); - printf(" %-*.*s", cw->local_addr, cw->local_addr, buf); - if (format_unix_faddr(faddr, buf, bufsize) == 0) - strlcpy(buf, "??", bufsize); - printf(" %-*.*s", cw->foreign_addr, - cw->foreign_addr, buf); + if (is_text_style) { + xo_emit(" {:/%-*.*s}", cw->local_addr, + cw->local_addr, buf); + } + xo_close_container("local"); + } else if (laddr->address.ss_len == 0 && + faddr->conn == 0 && is_text_style) { + xo_emit(" {:/%-*.*s}", cw->local_addr, + cw->local_addr, "(not connected)"); + } else if (is_text_style) { + xo_emit(" {:/%-*.*s}", cw->local_addr, + cw->local_addr, "??"); + } + if (faddr->conn != 0 || faddr->firstref != 0) { + xo_open_container("foreign"); + int len = format_unix_faddr(faddr, buf, + bufsize); + if (len == 0 && is_text_style) + xo_emit(" {:/%-*s}", + cw->foreign_addr, "??"); + else if (is_text_style) + xo_emit(" {:/%-*.*s}", cw->foreign_addr, + cw->foreign_addr, buf); + xo_close_container("foreign"); + } else if (is_text_style) + xo_emit(" {:/%-*s}", cw->foreign_addr, "??"); } else { - if (laddr != NULL) + if (laddr != NULL) { + xo_open_container("local"); formataddr(&laddr->address, buf, bufsize); - else - strlcpy(buf, "??", bufsize); - printf(" %-*.*s", cw->local_addr, cw->local_addr, buf); - if (faddr != NULL) + if (is_text_style) { + xo_emit(" {:/%-*.*s}", cw->local_addr, + cw->local_addr, buf); + } + xo_close_container("local"); + } else if (is_text_style) + xo_emit(" {:/%-*.*s}", cw->local_addr, + cw->local_addr, "??"); + if (faddr != NULL) { + xo_open_container("foreign"); formataddr(&faddr->address, buf, bufsize); - else - strlcpy(buf, "??", bufsize); - printf(" %-*.*s", cw->foreign_addr, - cw->foreign_addr, buf); + if (is_text_style) { + xo_emit(" {:/%-*.*s}", cw->foreign_addr, + cw->foreign_addr, buf); + } + xo_close_container("foreign"); + } else if (is_text_style) { + xo_emit(" {:/%-*.*s}", cw->foreign_addr, + cw->foreign_addr, "??"); + } + } + if (opt_A) { + snprintf(buf, bufsize, "%#*" PRIx64, + cw->pcb_kva, s->pcb); + xo_emit(" {:pcb-kva/%s}", buf); } - if (opt_A) - printf(" %#*" PRIx64, cw->pcb_kva, s->pcb); if (opt_f) - printf(" %*d", cw->fib, s->fibnum); + xo_emit(" {:fib/%*d}", cw->fib, s->fibnum); if (opt_I) { if (s->splice_socket != 0) { struct sock *sp; sp = RB_FIND(socks_t, &socks, &(struct sock) { .socket = s->splice_socket }); - if (sp != NULL) + if (sp != NULL) { + xo_open_container("splice"); formataddr(&sp->laddr->address, buf, bufsize); - else + xo_close_container("splice"); + } else if (is_text_style) strlcpy(buf, "??", bufsize); - } else + } else if (is_text_style) strlcpy(buf, "??", bufsize); - printf(" %-*s", cw->splice_address, buf); + if (is_text_style) + xo_emit(" {:/%-*s}", cw->splice_address, buf); } if (opt_i) { if (s->proto == IPPROTO_TCP || s->proto == IPPROTO_UDP) - printf(" %*" PRIu64, cw->inp_gencnt, + { + snprintf(buf, bufsize, "%" PRIu64, s->inp_gencnt); - else - printf(" %*s", cw->inp_gencnt, "??"); + xo_emit(" {:id/%*s}", cw->inp_gencnt, buf); + } else if (is_text_style) + xo_emit(" {:/%*s}", cw->inp_gencnt, "??"); } if (opt_U) { if (faddr != NULL && @@ -1414,10 +1488,10 @@ display_sock(struct sock *s, struct col_widths *cw, char *buf, size_t bufsize) (s->proto == IPPROTO_TCP && s->state != TCPS_CLOSED && s->state != TCPS_LISTEN))) { - printf(" %*u", cw->encaps, + xo_emit(" {:encaps/%*u}", cw->encaps, ntohs(faddr->encaps_port)); - } else - printf(" %*s", cw->encaps, "??"); + } else if (is_text_style) + xo_emit(" {:/%*s}", cw->encaps, "??"); } if (opt_s) { if (faddr != NULL && @@ -1425,10 +1499,10 @@ display_sock(struct sock *s, struct col_widths *cw, char *buf, size_t bufsize) s->state != SCTP_CLOSED && s->state != SCTP_BOUND && s->state != SCTP_LISTEN) { - printf(" %-*s", cw->path_state, + xo_emit(" {:path-state/%-*s}", cw->path_state, sctp_path_state(faddr->state)); - } else - printf(" %-*s", cw->path_state, "??"); + } else if (is_text_style) + xo_emit(" {:/%-*s}", cw->path_state, "??"); } if (first) { if (opt_s) { @@ -1436,47 +1510,52 @@ display_sock(struct sock *s, struct col_widths *cw, char *buf, size_t bufsize) s->proto == IPPROTO_TCP) { switch (s->proto) { case IPPROTO_SCTP: - printf(" %-*s", cw->conn_state, - sctp_conn_state(s->state)); + xo_emit(" {:path-state/%-*s}", + cw->path_state, + sctp_path_state( + faddr->state)); break; case IPPROTO_TCP: if (s->state >= 0 && s->state < TCP_NSTATES) - printf(" %-*s", - cw->conn_state, - tcpstates[s->state]); - else - printf(" %-*s", - cw->conn_state, "??"); + xo_emit(" {:conn-state/%-*s}", + cw->conn_state, + tcpstates[s->state]); + else if (is_text_style) + xo_emit(" {:/%-*s}", + cw->conn_state, "??"); break; } - } else - printf(" %-*s", cw->conn_state, "??"); + } else if (is_text_style) + xo_emit(" {:/%-*s}", + cw->conn_state, "??"); } if (opt_S) { if (s->proto == IPPROTO_TCP) - printf(" %-*s", cw->stack, s->stack); - else - printf(" %-*s", cw->stack, "??"); + xo_emit(" {:stack/%-*s}", + cw->stack, s->stack); + else if (is_text_style) + xo_emit(" {:/%-*s}", + cw->stack, "??"); } if (opt_C) { if (s->proto == IPPROTO_TCP) - printf(" %-*s", cw->cc, s->cc); - else - printf(" %-*s", cw->cc, "??"); + xo_emit(" {:cc/%-*s}", cw->cc, s->cc); + else if (is_text_style) + xo_emit(" {:/%-*s}", cw->cc, "??"); } } if (laddr != NULL) laddr = laddr->next; if (faddr != NULL) faddr = faddr->next; - if (laddr != NULL || faddr != NULL) - printf("%-*s %-*s %-*s %-*s %-*s", cw->user, "", - cw->command, "", cw->pid, "", cw->fd, "", - cw->proto, ""); + if (is_text_style && (laddr != NULL || faddr != NULL)) + xo_emit("{:/%-*s} {:/%-*s} {:/%*s} {:/%*s}", + cw->user, "??", cw->command, "??", + cw->pid, "??", cw->fd, "??"); first = false; } - printf("\n"); + xo_emit("\n"); } static void @@ -1490,56 +1569,63 @@ display(void) const size_t bufsize = 512; void *buf; if ((buf = (char *)malloc(bufsize)) == NULL) { - err(1, "malloc()"); + xo_err(1, "malloc()"); return; } - cw = (struct col_widths) { - .user = strlen("USER"), - .command = 10, - .pid = strlen("PID"), - .fd = strlen("FD"), - .proto = strlen("PROTO"), - .local_addr = opt_w ? strlen("LOCAL ADDRESS") : 21, - .foreign_addr = opt_w ? strlen("FOREIGN ADDRESS") : 21, - .pcb_kva = 18, - .fib = strlen("FIB"), - .splice_address = strlen("SPLICE ADDRESS"), - .inp_gencnt = strlen("ID"), - .encaps = strlen("ENCAPS"), - .path_state = strlen("PATH STATE"), - .conn_state = strlen("CONN STATE"), - .stack = strlen("STACK"), - .cc = strlen("CC"), - }; - calculate_column_widths(&cw); + if (xo_get_style(NULL) == XO_STYLE_TEXT) { + cw = (struct col_widths) { + .user = strlen("USER"), + .command = 10, + .pid = strlen("PID"), + .fd = strlen("FD"), + .proto = strlen("PROTO"), + .local_addr = opt_w ? strlen("LOCAL ADDRESS") : 21, + .foreign_addr = opt_w ? strlen("FOREIGN ADDRESS") : 21, + .pcb_kva = 18, + .fib = strlen("FIB"), + .splice_address = strlen("SPLICE ADDRESS"), + .inp_gencnt = strlen("ID"), + .encaps = strlen("ENCAPS"), + .path_state = strlen("PATH STATE"), + .conn_state = strlen("CONN STATE"), + .stack = strlen("STACK"), + .cc = strlen("CC"), + }; + calculate_column_widths(&cw); + } else + memset(&cw, 0, sizeof(cw)); + xo_set_version(SOCKSTAT_XO_VERSION); + xo_open_container("sockstat"); + xo_open_list("socket"); if (!opt_q) { - printf("%-*s %-*s %*s %*s %-*s %-*s %-*s", - cw.user, "USER", cw.command, "COMMAND", - cw.pid, "PID", cw.fd, "FD", cw.proto, "PROTO", - cw.local_addr, "LOCAL ADDRESS", - cw.foreign_addr,"FOREIGN ADDRESS"); + xo_emit("{T:/%-*s} {T:/%-*s} {T:/%*s} {T:/%*s} {T:/%-*s} " + "{T:/%-*s} {T:/%-*s}", cw.user, "USER", cw.command, + "COMMAND", cw.pid, "PID", cw.fd, "FD", cw.proto, + "PROTO", cw.local_addr, "LOCAL ADDRESS", + cw.foreign_addr, "FOREIGN ADDRESS"); if (opt_A) - printf(" %-*s", cw.pcb_kva, "PCB KVA"); + xo_emit(" {T:/%-*s}", cw.pcb_kva, "PCB KVA"); if (opt_f) /* RT_MAXFIBS is 65535. */ - printf(" %*s", cw.fib, "FIB"); + xo_emit(" {T:/%*s}", cw.fib, "FIB"); if (opt_I) - printf(" %-*s", cw.splice_address, "SPLICE ADDRESS"); + xo_emit(" {T:/%-*s}", cw.splice_address, + "SPLICE ADDRESS"); if (opt_i) - printf(" %*s", cw.inp_gencnt, "ID"); + xo_emit(" {T:/%*s}", cw.inp_gencnt, "ID"); if (opt_U) - printf(" %*s", cw.encaps, "ENCAPS"); + xo_emit(" {T:/%*s}", cw.encaps, "ENCAPS"); if (opt_s) { - printf(" %-*s", cw.path_state, "PATH STATE"); - printf(" %-*s", cw.conn_state, "CONN STATE"); + xo_emit(" {T:/%-*s}", cw.path_state, "PATH STATE"); + xo_emit(" {T:/%-*s}", cw.conn_state, "CONN STATE"); } if (opt_S) - printf(" %-*s", cw.stack, "STACK"); + xo_emit(" {T:/%-*s}", cw.stack, "STACK"); if (opt_C) - printf(" %-*s", cw.cc, "CC"); - printf("\n"); + xo_emit(" {T:/%-*s}", cw.cc, "CC"); + xo_emit("\n"); } cap_setpassent(cappwd, 1); for (xf = files, n = 0; n < nfiles; ++n, ++xf) { @@ -1550,17 +1636,24 @@ display(void) s = RB_FIND(socks_t, &socks, &(struct sock){ .socket = xf->xf_data}); if (s != NULL && check_ports(s)) { + xo_open_instance("socket"); s->shown = 1; if (opt_n || (pwd = cap_getpwuid(cappwd, xf->xf_uid)) == NULL) - printf("%-*lu", cw.user, (u_long)xf->xf_uid); + xo_emit("{:user/%-*lu}", cw.user, + (u_long)xf->xf_uid); + else + xo_emit("{:user/%-*s}", cw.user, pwd->pw_name); + if (xo_get_style(NULL) == XO_STYLE_TEXT) + xo_emit(" {:/%-*.10s}", cw.command, + getprocname(xf->xf_pid)); else - printf("%-*s", cw.user, pwd->pw_name); - printf(" %-*.*s", cw.command, cw.command, - getprocname(xf->xf_pid)); - printf(" %*lu", cw.pid, (u_long)xf->xf_pid); - printf(" %*d", cw.fd, xf->xf_fd); + xo_emit(" {:command/%-*s}", cw.command, + getprocname(xf->xf_pid)); + xo_emit(" {:pid/%*lu}", cw.pid, (u_long)xf->xf_pid); + xo_emit(" {:fd/%*d}", cw.fd, xf->xf_fd); display_sock(s, &cw, buf, bufsize); + xo_close_instance("socket"); } } if (opt_j >= 0) @@ -1568,20 +1661,33 @@ display(void) SLIST_FOREACH(s, &nosocks, socket_list) { if (!check_ports(s)) continue; - printf("%-*s %-*s %*s %*s", cw.user, "??", cw.command, "??", - cw.pid, "??", cw.fd, "??"); + xo_open_instance("socket"); + if (xo_get_style(NULL) == XO_STYLE_TEXT) + xo_emit("{:/%-*s} {:/%-*s} {:/%*s} {:/%*s}", + cw.user, "??", cw.command, "??", + cw.pid, "??", cw.fd, "??"); display_sock(s, &cw, buf, bufsize); + xo_close_instance("socket"); } RB_FOREACH(s, socks_t, &socks) { if (s->shown) continue; if (!check_ports(s)) continue; - printf("%-*s %-*s %*s %*s", cw.user, "??", cw.command, "??", - cw.pid, "??", cw.fd, "??"); + xo_open_instance("socket"); + if (xo_get_style(NULL) == XO_STYLE_TEXT) + xo_emit("{:/%-*s} {:/%-*s} {:/%*s} {:/%*s}", + cw.user, "??", cw.command, "??", + cw.pid, "??", cw.fd, "??"); display_sock(s, &cw, buf, bufsize); + xo_close_instance("socket"); } + xo_close_list("socket"); + xo_close_container("sockstat"); + if (xo_finish() < 0) + xo_err(1, "stdout"); free(buf); + cap_endpwent(cappwd); } static int @@ -1597,7 +1703,7 @@ set_default_protos(void) pname = default_protos[pindex]; prot = cap_getprotobyname(capnetdb, pname); if (prot == NULL) - err(1, "cap_getprotobyname: %s", pname); + xo_err(1, "cap_getprotobyname: %s", pname); protos[pindex] = prot->p_proto; } numprotos = pindex; @@ -1643,8 +1749,10 @@ jail_getvnet(int jid) static void usage(void) { - errx(1, - "usage: sockstat [-46ACcfIiLlnqSsUuvw] [-j jid] [-p ports] [-P protocols]"); + xo_error( +"usage: sockstat [--libxo] [-46ACcfIiLlnqSsUuvw] [-j jid] [-p ports]\n" +" [-P protocols]\n"); + exit(1); } int @@ -1657,6 +1765,9 @@ main(int argc, char *argv[]) int protos_defined = -1; int o, i; + argc = xo_parse_args(argc, argv); + if (argc < 0) + exit(1); opt_j = -1; while ((o = getopt(argc, argv, "46ACcfIij:Llnp:P:qSsUuvw")) != -1) switch (o) { @@ -1687,7 +1798,7 @@ main(int argc, char *argv[]) case 'j': opt_j = jail_getid(optarg); if (opt_j < 0) - errx(1, "jail_getid: %s", jail_errmsg); + xo_errx(1, "jail_getid: %s", jail_errmsg); break; case 'L': opt_L = true; @@ -1738,10 +1849,10 @@ main(int argc, char *argv[]) if (opt_j > 0) { switch (jail_getvnet(opt_j)) { case -1: - errx(2, "jail_getvnet: %s", jail_errmsg); + xo_errx(2, "jail_getvnet: %s", jail_errmsg); case JAIL_SYS_NEW: if (jail_attach(opt_j) < 0) - err(3, "jail_attach()"); + xo_err(3, "jail_attach()"); /* Set back to -1 for normal output in vnet jail. */ opt_j = -1; break; @@ -1752,31 +1863,31 @@ main(int argc, char *argv[]) capcas = cap_init(); if (capcas == NULL) - err(1, "Unable to contact Casper"); + xo_err(1, "Unable to contact Casper"); if (caph_enter_casper() < 0) - err(1, "Unable to enter capability mode"); + xo_err(1, "Unable to enter capability mode"); capnet = cap_service_open(capcas, "system.net"); if (capnet == NULL) - err(1, "Unable to open system.net service"); + xo_err(1, "Unable to open system.net service"); capnetdb = cap_service_open(capcas, "system.netdb"); if (capnetdb == NULL) - err(1, "Unable to open system.netdb service"); + xo_err(1, "Unable to open system.netdb service"); capsysctl = cap_service_open(capcas, "system.sysctl"); if (capsysctl == NULL) - err(1, "Unable to open system.sysctl service"); + xo_err(1, "Unable to open system.sysctl service"); cappwd = cap_service_open(capcas, "system.pwd"); if (cappwd == NULL) - err(1, "Unable to open system.pwd service"); + xo_err(1, "Unable to open system.pwd service"); cap_close(capcas); limit = cap_net_limit_init(capnet, CAPNET_ADDR2NAME); if (limit == NULL) - err(1, "Unable to init cap_net limits"); + xo_err(1, "Unable to init cap_net limits"); if (cap_net_limit(limit) < 0) - err(1, "Unable to apply limits"); + xo_err(1, "Unable to apply limits"); if (cap_pwd_limit_cmds(cappwd, pwdcmds, nitems(pwdcmds)) < 0) - err(1, "Unable to apply pwd commands limits"); + xo_err(1, "Unable to apply pwd commands limits"); if (cap_pwd_limit_fields(cappwd, pwdfields, nitems(pwdfields)) < 0) - err(1, "Unable to apply pwd commands limits"); + xo_err(1, "Unable to apply pwd commands limits"); if ((!opt_4 && !opt_6) && protos_defined != -1) opt_4 = opt_6 = true; diff --git a/usr.sbin/bsdinstall/scripts/pkgbase.in b/usr.sbin/bsdinstall/scripts/pkgbase.in index cf8e84de6923..d123394c170e 100755 --- a/usr.sbin/bsdinstall/scripts/pkgbase.in +++ b/usr.sbin/bsdinstall/scripts/pkgbase.in @@ -165,7 +165,9 @@ local function select_packages(pkg, options) table.insert(components["src"], package) elseif package == "FreeBSD-tests" or package:match("^FreeBSD%-tests%-.*") then table.insert(components["tests"], package) - elseif package:match("^FreeBSD%-kernel%-.*") then + elseif package:match("^FreeBSD%-kernel%-.*") and + package ~= "FreeBSD-kernel-man" + then -- Kernels other than FreeBSD-kernel-generic are ignored if package == "FreeBSD-kernel-generic" then table.insert(components["kernel"], package) diff --git a/usr.sbin/bsnmpd/modules/snmp_wlan/wlan_sys.c b/usr.sbin/bsnmpd/modules/snmp_wlan/wlan_sys.c index b129e42b9d85..e80b53dcf44e 100644 --- a/usr.sbin/bsnmpd/modules/snmp_wlan/wlan_sys.c +++ b/usr.sbin/bsnmpd/modules/snmp_wlan/wlan_sys.c @@ -2167,7 +2167,7 @@ wlan_add_new_scan_result(struct wlan_iface *wif, return (-1); sr->opchannel = wlan_channel_flags_to_snmp_phy(isr->isr_flags); - sr->rssi = isr->isr_rssi; + sr->rssi = (isr->isr_rssi / 2) - isr->isr_noise; sr->frequency = isr->isr_freq; sr->noise = isr->isr_noise; sr->bintval = isr->isr_intval; diff --git a/usr.sbin/syslogd/syslogd.c b/usr.sbin/syslogd/syslogd.c index 726cedc17b1d..fe7427130b78 100644 --- a/usr.sbin/syslogd/syslogd.c +++ b/usr.sbin/syslogd/syslogd.c @@ -2571,7 +2571,7 @@ syslogd_cap_enter(void) if (cap_syslogd == NULL) err(1, "Failed to open the syslogd.casper libcasper service"); cap_net = cap_service_open(cap_casper, "system.net"); - if (cap_syslogd == NULL) + if (cap_net == NULL) err(1, "Failed to open the system.net libcasper service"); cap_close(cap_casper); limit = cap_net_limit_init(cap_net, |