diff options
146 files changed, 2334 insertions, 1729 deletions
diff --git a/.github/workflows/checklist.yml b/.github/workflows/checklist.yml index 7f7b0d51f46e..ecc3939f34b8 100644 --- a/.github/workflows/checklist.yml +++ b/.github/workflows/checklist.yml @@ -89,7 +89,7 @@ jobs: /* Loop for each key in "checklist". */ for (const c in checklist) msg += "- " + c + "<sup>" + checklist[c].join(", ") + "</sup>\n"; - msg += "\nPlease review CONTRIBUTING.md, then update and push your branch again.\n" + msg += "\nPlease review [CONTRIBUTING.md](https://github.com/freebsd/freebsd-src/blob/main/CONTRIBUTING.md), then update and push your branch again.\n" comment_func({ owner: context.repo.owner, diff --git a/Makefile.inc1 b/Makefile.inc1 index 010f5ac2bb55..b66743e154eb 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -2627,8 +2627,6 @@ _kerberos5_bootstrap_tools= \ krb5/util/compile_et \ krb5/util/support \ krb5/util/et \ - lib/ncurses/tinfo \ - lib/libedit \ krb5/util/ss \ krb5/util/profile \ krb5/util/verto diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index f1e230f91e95..83fb2d3f3a2c 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -51,6 +51,13 @@ # xargs -n1 | sort | uniq -d; # done +# 20250728: zfsboot (MBR) removed +OLD_FILES+=boot/zfsboot +OLD_FILES+=usr/share/man/man8/zfsboot.8.gz + +# 20250728: Machine versions of 'runq.h' do not exist anymore +OLD_FILES+=usr/include/machine/runq.h + # 20250726: MIT KRB5 DSO bump OLD_LIBS+=usr/lib/libcom_err.so.121 OLD_LIBS+=usr/lib/libgssapi_krb5.so.121 @@ -27,10 +27,20 @@ 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: - 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. + 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. 20250726: amd64 kernel configurations must contain "options SMP". diff --git a/crypto/krb5/src/util/ss/listen.c b/crypto/krb5/src/util/ss/listen.c index 08427df1e5c7..fe18475447be 100644 --- a/crypto/krb5/src/util/ss/listen.c +++ b/crypto/krb5/src/util/ss/listen.c @@ -14,9 +14,6 @@ #include <termios.h> #include <sys/param.h> -#ifdef __FreeBSD__ -#include <edit/readline/readline.h> -#else #if defined(HAVE_LIBEDIT) #include <editline/readline.h> #elif defined(HAVE_READLINE) @@ -25,7 +22,6 @@ #else #define NO_READLINE #endif -#endif static ss_data *current_info; static jmp_buf listen_jmpb; diff --git a/crypto/openssh/sshd_config b/crypto/openssh/sshd_config index a17484b1da2d..88c93386db65 100644 --- a/crypto/openssh/sshd_config +++ b/crypto/openssh/sshd_config @@ -56,12 +56,15 @@ AuthorizedKeysFile .ssh/authorized_keys # Don't read the user's ~/.rhosts and ~/.shosts files #IgnoreRhosts yes -# Change to yes to enable built-in password authentication. +# Change to "yes" to enable built-in password authentication. # Note that passwords may also be accepted via KbdInteractiveAuthentication. #PasswordAuthentication no #PermitEmptyPasswords no -# Change to no to disable PAM authentication +# Change to "no" to disable keyboard-interactive authentication. Depending on +# the system's configuration, this may involve passwords, challenge-response, +# one-time passwords or some combination of these and other methods. +# Keyboard interactive authentication is also used for PAM authentication. #KbdInteractiveAuthentication yes # Kerberos options diff --git a/etc/gss-krb5/mech b/etc/gss-krb5/mech index 94fed68a24eb..b13f665705c5 100644 --- a/etc/gss-krb5/mech +++ b/etc/gss-krb5/mech @@ -1,10 +1,10 @@ # # Name OID Library name Kernel module -kerberosv5 1.2.840.113554.1.2.2 /usr/lib/libgssapi_krb5.so.121 kgssapi_krb5 -kerberosv5 1.2.840.113554.1.2.3 /usr/lib/libgssapi_krb5.so.121 kgssapi_krb5 -kerberosv5 1.3.6.1.5.5.2 /usr/lib/libgssapi_krb5.so.121 kgssapi_krb5 -kerberosv5 1.2.840.48018.1.2.2.1 /usr/lib/libgssapi_krb5.so.121 kgssapi_krb5 -kerberosv5 1.2.840.48018.1.2.2.2 /usr/lib/libgssapi_krb5.so.121 kgssapi_krb5 -kerberosv5 1.2.840.48018.1.2.2.4 /usr/lib/libgssapi_krb5.so.121 kgssapi_krb5 -kerberosv5 1.2.840.48018.1.2.2.5 /usr/lib/libgssapi_krb5.so.121 kgssapi_krb5 -kerberosv5 1.3.5.1.5.2 /usr/lib/libgssapi_krb5.so.121 kgssapi_krb5 +kerberosv5 1.2.840.113554.1.2.2 /usr/lib/libgssapi_krb5.so.122 kgssapi_krb5 +kerberosv5 1.2.840.113554.1.2.3 /usr/lib/libgssapi_krb5.so.122 kgssapi_krb5 +kerberosv5 1.3.6.1.5.5.2 /usr/lib/libgssapi_krb5.so.122 kgssapi_krb5 +kerberosv5 1.2.840.48018.1.2.2.1 /usr/lib/libgssapi_krb5.so.122 kgssapi_krb5 +kerberosv5 1.2.840.48018.1.2.2.2 /usr/lib/libgssapi_krb5.so.122 kgssapi_krb5 +kerberosv5 1.2.840.48018.1.2.2.4 /usr/lib/libgssapi_krb5.so.122 kgssapi_krb5 +kerberosv5 1.2.840.48018.1.2.2.5 /usr/lib/libgssapi_krb5.so.122 kgssapi_krb5 +kerberosv5 1.3.5.1.5.2 /usr/lib/libgssapi_krb5.so.122 kgssapi_krb5 diff --git a/krb5/include/autoconf.h b/krb5/include/autoconf.h index a5e2ea5838b0..fe281d136954 100644 --- a/krb5/include/autoconf.h +++ b/krb5/include/autoconf.h @@ -260,7 +260,7 @@ #define HAVE_LIBCRYPTO 1 /* Define if building with libedit. */ -#define HAVE_LIBEDIT 1 +/* #undef HAVE_LIBEDIT */ /* Define to 1 if you have the `nsl' library (-lnsl). */ /* #undef HAVE_LIBNSL */ diff --git a/krb5/usr.bin/kadmin/Makefile b/krb5/usr.bin/kadmin/Makefile index b2a094795d48..182cabb8f9f6 100644 --- a/krb5/usr.bin/kadmin/Makefile +++ b/krb5/usr.bin/kadmin/Makefile @@ -9,8 +9,8 @@ PROG= kadmin -LIBADD= kadmin_common edit kadm5clnt_mit gssrpc gssapi_krb5 krb5 k5crypto \ - com_err krb5ss krb5profile krb5support tinfow sys +LIBADD= kadmin_common kadm5clnt_mit gssrpc gssapi_krb5 krb5 k5crypto \ + com_err krb5ss krb5profile krb5support sys SRCS= keytab.c diff --git a/krb5/usr.bin/ktutil/Makefile b/krb5/usr.bin/ktutil/Makefile index 6bcb4877ed6f..15991cb49bce 100644 --- a/krb5/usr.bin/ktutil/Makefile +++ b/krb5/usr.bin/ktutil/Makefile @@ -9,7 +9,7 @@ PROG= ktutil -LIBADD= edit krb5 k5crypto com_err krb5profile krb5support krb5ss tinfow sys +LIBADD= krb5 k5crypto com_err krb5profile krb5support krb5ss sys SRCS= ktutil.c \ ktutil_ct.c \ diff --git a/krb5/usr.sbin/kadmin.local/Makefile b/krb5/usr.sbin/kadmin.local/Makefile index 4b99f490bd7b..3930c0fc4694 100644 --- a/krb5/usr.sbin/kadmin.local/Makefile +++ b/krb5/usr.sbin/kadmin.local/Makefile @@ -11,8 +11,8 @@ PACKAGE= kerberos-kdc PROG= kadmin.local -LIBADD= kadmin_common edit kadm5srv_mit kdb5 gssrpc gssapi_krb5 krb5 \ - k5crypto com_err krb5profile krb5support krb5ss tinfow sys +LIBADD= kadmin_common kadm5srv_mit kdb5 gssrpc gssapi_krb5 krb5 \ + k5crypto com_err krb5profile krb5support krb5ss sys SRCS= keytab_local.c diff --git a/krb5/util/ss/Makefile b/krb5/util/ss/Makefile index e7e025184284..2c43f2b5934f 100644 --- a/krb5/util/ss/Makefile +++ b/krb5/util/ss/Makefile @@ -47,6 +47,11 @@ CFLAGS+=-I${KRB5_DIR}/util/ss \ -I${.OBJDIR:H} \ -I${.OBJDIR} +.if !defined(BOOTSTRAPPING) +CFLAGS+= -DHAVE_READLINE=1 \ + -I${SYSROOT:U${DESTDIR}}/${INCLUDEDIR}/edit +.endif + GEN= std_rqs.c ${GEN_SS_ERR_C} ${GEN_SS_ERR_H} GEN_SCRIPTS= ct_c.awk ct_c.sed mk_cmds GEN_SS_ERR_C= ${GEN_SS_ERR:S/.et$/.c/} 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/libnvmf/libnvmf.h b/lib/libnvmf/libnvmf.h index 7cdd7e433455..6b38fd286596 100644 --- a/lib/libnvmf/libnvmf.h +++ b/lib/libnvmf/libnvmf.h @@ -111,8 +111,13 @@ const void *nvmf_capsule_cqe(const struct nvmf_capsule *nc); /* Return a string name for a transport type. */ const char *nvmf_transport_type(uint8_t trtype); -/* Validate a NVMe Qualified Name. */ +/* + * Validate a NVMe Qualified Name. The second version enforces + * stricter checks inline with the specification. The first version + * enforces more minimal checks. + */ bool nvmf_nqn_valid(const char *nqn); +bool nvmf_nqn_valid_strict(const char *nqn); /* Controller-specific APIs. */ diff --git a/lib/libnvmf/nvmf_controller.c b/lib/libnvmf/nvmf_controller.c index 971dccbe039e..f26f11633e03 100644 --- a/lib/libnvmf/nvmf_controller.c +++ b/lib/libnvmf/nvmf_controller.c @@ -7,6 +7,7 @@ #include <sys/utsname.h> #include <assert.h> +#include <ctype.h> #include <errno.h> #include <string.h> #include <unistd.h> @@ -15,6 +16,55 @@ #include "internal.h" #include "nvmft_subr.h" +bool +nvmf_nqn_valid_strict(const char *nqn) +{ + size_t len; + + if (!nvmf_nqn_valid(nqn)) + return (false); + + /* + * Stricter checks from the spec. Linux does not seem to + * require these. + */ + len = strlen(nqn); + + /* + * NVMF_NQN_MIN_LEN does not include '.' and require at least + * one character of a domain name. + */ + if (len < NVMF_NQN_MIN_LEN + 2) + return (false); + if (memcmp("nqn.", nqn, strlen("nqn.")) != 0) + return (false); + nqn += strlen("nqn."); + + /* Next 4 digits must be a year. */ + for (u_int i = 0; i < 4; i++) { + if (!isdigit(nqn[i])) + return (false); + } + nqn += 4; + + /* '-' between year and month. */ + if (nqn[0] != '-') + return (false); + nqn++; + + /* 2 digit month. */ + for (u_int i = 0; i < 2; i++) { + if (!isdigit(nqn[i])) + return (false); + } + nqn += 2; + + /* '.' between month and reverse domain name. */ + if (nqn[0] != '.') + return (false); + return (true); +} + void nvmf_init_cqe(void *cqe, const struct nvmf_capsule *nc, uint16_t status) { 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/libexec/comsat/comsat.c b/libexec/comsat/comsat.c index d5d1eedeb5f3..cb00ee4a9392 100644 --- a/libexec/comsat/comsat.c +++ b/libexec/comsat/comsat.c @@ -113,29 +113,24 @@ mailfor(char *name) char *file; off_t offset; int folder; - char buf[sizeof(_PATH_MAILDIR) + sizeof(utp->ut_user) + 1]; - char buf2[sizeof(_PATH_MAILDIR) + sizeof(utp->ut_user) + 1]; + char buf[MAXPATHLEN]; - if (!(cp = strchr(name, '@'))) + if ((cp = strchr(name, '@')) == NULL) return; *cp = '\0'; offset = strtoll(cp + 1, NULL, 10); - if (!(cp = strchr(cp + 1, ':'))) - file = name; - else - file = cp + 1; - sprintf(buf, "%s/%.*s", _PATH_MAILDIR, (int)sizeof(utp->ut_user), - name); - if (*file != '/') { - sprintf(buf2, "%s/%.*s", _PATH_MAILDIR, - (int)sizeof(utp->ut_user), file); - file = buf2; + if ((cp = strchr(cp + 1, ':')) != NULL && + strchr((file = cp + 1), '/') == NULL) { + snprintf(buf, sizeof(buf), "%s/%s", _PATH_MAILDIR, file); + folder = 1; + } else { + snprintf(buf, sizeof(buf), "%s/%s", _PATH_MAILDIR, name); + folder = 0; } - folder = strcmp(buf, file); setutxent(); while ((utp = getutxent()) != NULL) if (utp->ut_type == USER_PROCESS && !strcmp(utp->ut_user, name)) - notify(utp, file, offset, folder); + notify(utp, buf, offset, folder); endutxent(); } @@ -159,8 +154,7 @@ notify(struct utmpx *utp, char file[], off_t offset, int folder) utp->ut_line); return; } - (void)snprintf(tty, sizeof(tty), "%s%.*s", - _PATH_DEV, (int)sizeof(utp->ut_line), utp->ut_line); + (void)snprintf(tty, sizeof(tty), "%s%s", _PATH_DEV, utp->ut_line); if (stat(tty, &stb) == -1 || !(stb.st_mode & (S_IXUSR | S_IXGRP))) { dsyslog(LOG_DEBUG, "%s: wrong mode on %s", utp->ut_user, tty); return; @@ -187,26 +181,20 @@ notify(struct utmpx *utp, char file[], off_t offset, int folder) initgroups(p->pw_name, p->pw_gid) == -1 || setgid(p->pw_gid) == -1 || setuid(p->pw_uid) == -1) - return; + _exit(1); - switch (stb.st_mode & (S_IXUSR | S_IXGRP)) { - case S_IXUSR: - case (S_IXUSR | S_IXGRP): + if (stb.st_mode & S_IXUSR) { (void)fprintf(tp, "%s\007New mail for %s@%.*s\007 has arrived%s%s%s:%s----%s", cr, utp->ut_user, (int)sizeof(hostname), hostname, folder ? cr : "", folder ? "to " : "", folder ? file : "", cr, cr); jkfprintf(tp, file, offset); - break; - case S_IXGRP: + } else if (stb.st_mode & S_IXGRP) { (void)fprintf(tp, "\007"); (void)fflush(tp); (void)sleep(1); (void)fprintf(tp, "\007"); - break; - default: - break; } (void)fclose(tp); _exit(0); diff --git a/release/packages/ucl/bmake-all.ucl b/release/packages/ucl/bmake-all.ucl new file mode 100644 index 000000000000..ee8175d1dd8a --- /dev/null +++ b/release/packages/ucl/bmake-all.ucl @@ -0,0 +1,5 @@ +comment = "Program maintenance utility" +desc = <<EOD +make(1) allows programs to be built from source files based on a specification +of the program's dependencies called a Makefile. +EOD diff --git a/release/packages/ucl/sendmail.ucl b/release/packages/ucl/sendmail.ucl new file mode 100644 index 000000000000..c79775eb8af4 --- /dev/null +++ b/release/packages/ucl/sendmail.ucl @@ -0,0 +1,7 @@ +deps { + # sendmail requires make to build its configuration file. + "bmake": { + version = "${VERSION}" + origin = "base" + } +} diff --git a/release/packages/ucl/yp.ucl b/release/packages/ucl/yp.ucl new file mode 100644 index 000000000000..14b2327e56d1 --- /dev/null +++ b/release/packages/ucl/yp.ucl @@ -0,0 +1,7 @@ +deps { + # YP requires bmake to rebuild the database. + "bmake": { + version = "${VERSION}" + origin = "base" + } +} 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/ifconfig/af_inet6.c b/sbin/ifconfig/af_inet6.c index 17dc068ee875..7986edf490b4 100644 --- a/sbin/ifconfig/af_inet6.c +++ b/sbin/ifconfig/af_inet6.c @@ -759,7 +759,7 @@ static struct afswtch af_inet6 = { #else .af_difaddr = NL_RTM_DELADDR, .af_aifaddr = NL_RTM_NEWADDR, - .af_ridreq = &in6_add, + .af_ridreq = &in6_del, .af_addreq = &in6_add, .af_exec = in6_exec_nl, #endif diff --git a/sbin/ifconfig/ifbridge.c b/sbin/ifconfig/ifbridge.c index 3465dc223ada..a75c37e640a2 100644 --- a/sbin/ifconfig/ifbridge.c +++ b/sbin/ifconfig/ifbridge.c @@ -80,6 +80,20 @@ get_val(const char *cp, u_long *valp) } static int +get_vlan_id(const char *cp, ether_vlanid_t *valp) +{ + u_long val; + + if (get_val(cp, &val) == -1) + return (-1); + if (val < DOT1Q_VID_MIN || val > DOT1Q_VID_MAX) + return (-1); + + *valp = (ether_vlanid_t)val; + return (0); +} + +static int do_cmd(if_ctx *ctx, u_long op, void *arg, size_t argsize, int set) { struct ifdrv ifd = {}; @@ -242,8 +256,8 @@ bridge_status(if_ctx *ctx) else printf(" <unknown state %d>", state); } - if (member->ifbr_untagged != 0) - printf(" untagged %u", (unsigned)member->ifbr_untagged); + if (member->ifbr_pvid != 0) + printf(" untagged %u", (unsigned)member->ifbr_pvid); print_vlans(&bridge->member_vlans[i]); printf("\n"); } @@ -614,25 +628,15 @@ static void setbridge_untagged(if_ctx *ctx, const char *ifn, const char *vlanid) { struct ifbreq req; - u_long val; memset(&req, 0, sizeof(req)); + strlcpy(req.ifbr_ifsname, ifn, sizeof(req.ifbr_ifsname)); - if (get_val(vlanid, &val) < 0) + if (get_vlan_id(vlanid, &req.ifbr_pvid) < 0) errx(1, "invalid VLAN identifier: %s", vlanid); - /* - * Reject vlan 0, since it's not a valid vlan identifier and has a - * special meaning in the kernel interface. - */ - if (val == 0) - errx(1, "invalid VLAN identifier: %lu", val); - - strlcpy(req.ifbr_ifsname, ifn, sizeof(req.ifbr_ifsname)); - req.ifbr_untagged = val; - - if (do_cmd(ctx, BRDGSIFUNTAGGED, &req, sizeof(req), 1) < 0) - err(1, "BRDGSIFUNTAGGED %s", vlanid); + if (do_cmd(ctx, BRDGSIFPVID, &req, sizeof(req), 1) < 0) + err(1, "BRDGSIFPVID %s", vlanid); } static void @@ -643,10 +647,10 @@ unsetbridge_untagged(if_ctx *ctx, const char *ifn, int dummy __unused) memset(&req, 0, sizeof(req)); strlcpy(req.ifbr_ifsname, ifn, sizeof(req.ifbr_ifsname)); - req.ifbr_untagged = 0; + req.ifbr_pvid = 0; - if (do_cmd(ctx, BRDGSIFUNTAGGED, &req, sizeof(req), 1) < 0) - err(1, "BRDGSIFUNTAGGED"); + if (do_cmd(ctx, BRDGSIFPVID, &req, sizeof(req), 1) < 0) + err(1, "BRDGSIFPVID"); } static void diff --git a/sbin/ifconfig/tests/inet6.sh b/sbin/ifconfig/tests/inet6.sh index edfd88d93af7..22399915a64d 100644 --- a/sbin/ifconfig/tests/inet6.sh +++ b/sbin/ifconfig/tests/inet6.sh @@ -76,8 +76,38 @@ broadcast_cleanup() vnet_cleanup } +atf_test_case "delete6" "cleanup" +delete6_head() +{ + atf_set descr 'Test removing IPv6 addresses' + atf_set require.user root +} + +delete6_body() +{ + vnet_init + + ep=$(vnet_mkepair) + + atf_check -s exit:0 \ + ifconfig ${ep}a inet6 fe80::42/64 + atf_check -s exit:0 -o match:"fe80::42%${ep}" \ + ifconfig ${ep}a inet6 + + atf_check -s exit:0 \ + ifconfig ${ep}a inet6 -alias fe80::42 + atf_check -s exit:0 -o not-match:"fe80::42%${ep}" \ + ifconfig ${ep}a inet6 +} + +delete6_cleanup() +{ + vnet_cleanup +} + atf_init_test_cases() { atf_add_test_case netmask atf_add_test_case broadcast + atf_add_test_case delete6 } 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/sbin/zfsbootcfg/zfsbootcfg.8 b/sbin/zfsbootcfg/zfsbootcfg.8 index 5e7f02b2578c..3831adfc81bd 100644 --- a/sbin/zfsbootcfg/zfsbootcfg.8 +++ b/sbin/zfsbootcfg/zfsbootcfg.8 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd July 22, 2020 +.Dd July 28, 2025 .Dt ZFSBOOTCFG 8 .Os .Sh NAME @@ -44,14 +44,11 @@ is used to set .Xr boot.config 5 Ns -style options to be used by -.Xr zfsboot 8 , .Xr gptzfsboot 8 or .Xr loader 8 the next time the machine is booted. Once -.Xr zfsboot 8 -or .Xr gptzfsboot 8 or .Xr loader 8 @@ -130,8 +127,7 @@ To clear the boot options: .Xr boot.config 5 , .Xr bectl 8 , .Xr gptzfsboot 8 , -.Xr loader 8 , -.Xr zfsboot 8 +.Xr loader 8 .Sh HISTORY .Nm appeared in 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/man4/vtnet.4 b/share/man/man4/vtnet.4 index 270366488a98..8b99cd9f17b9 100644 --- a/share/man/man4/vtnet.4 +++ b/share/man/man4/vtnet.4 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd January 22, 2012 +.Dd July 29, 2025 .Dt VTNET 4 .Os .Sh NAME @@ -70,6 +70,11 @@ prompt before booting the kernel or stored in .It Va hw.vtnet. Ns Ar X Ns Va .csum_disable This tunable disables receive and send checksum offload. The default value is 0. +.It Va hw.vtnet.fixup_needs_csum +.It Va hw.vtnet. Ns Ar X Ns Va .fixup_needs_csum +This tunable enforces the calculation of a valid checksum for NEEDS_CSUM +packets. +The default value is 0. .It Va hw.vtnet.tso_disable .It Va hw.vtnet. Ns Ar X Ns Va .tso_disable This tunable disables TSO. @@ -91,6 +96,22 @@ The number of queue pairs used is the lesser of the maximum supported by the driver and the hypervisor, the number of CPUs present in the guest, and this tunable if not zero. The default value is 0. +.It Va hw.vtnet.tso_maxlen +.It Va hw.vtnet. Ns Ar X Ns Va .tso_maxlen +This tunable sets the TSO burst limit. +The default value is 65535. +.It Va hw.vtnet.rx_process_limit +.It Va hw.vtnet. Ns Ar X Ns Va .rx_process_limit +This tunable sets the number of RX segments processed in one pass. +The default value is 1024. +.It Va hw.vtnet.lro_entry_count +.It Va hw.vtnet. Ns Ar X Ns Va .lro_entry_count +This tunable sets the software LRO entry count. +The default value is 128, the minimum value is 8. +.It Va hw.vtnet.lro_mbufq_depth +.It Va hw.vtnet. Ns Ar X Ns Va .lro_mbufq_depth +This tunable sets the depth of the software LRO mbuf queue. +The default value is 0. .It Va hw.vtnet.altq_disable This tunable disables ALTQ support, allowing the use of multiqueue instead. This option applies to all interfaces. 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/mbuf.9 b/share/man/man9/mbuf.9 index 0262c598ed18..c05505716a30 100644 --- a/share/man/man9/mbuf.9 +++ b/share/man/man9/mbuf.9 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd December 28, 2023 +.Dd July 29, 2025 .Dt MBUF 9 .Os .\" @@ -1091,7 +1091,7 @@ network code, when data must be encrypted or otherwise altered prior to transmission. .El .Sh HARDWARE-ASSISTED CHECKSUM CALCULATION -This section currently applies to TCP/IP only. +This section currently applies to SCTP, TCP, and UDP over IP only. In order to save the host CPU resources, computing checksums is offloaded to the network interface hardware if possible. The @@ -1117,7 +1117,7 @@ in the .Vt mbuf chain containing the packet. .Pp -On output, checksum offloading is attempted after the outgoing +On output, the computation of the checksum is delayed until the outgoing interface has been determined for a packet. The interface-specific field .Va ifnet.if_data.ifi_hwassist @@ -1135,12 +1135,15 @@ such actions will never be requested through .Va csum_flags . .Pp The flags demanding a particular action from an interface are as follows: -.Bl -tag -width ".Dv CSUM_TCP" -offset indent +.Bl -tag -width ".Dv CSUM_SCTP" -offset indent .It Dv CSUM_IP The IP header checksum is to be computed and stored in the corresponding field of the packet. The hardware is expected to know the format of an IP header to determine the offset of the IP checksum field. +.It Dv CSUM_SCTP +The SCTP checksum is to be computed. +(See below.) .It Dv CSUM_TCP The TCP checksum is to be computed. (See below.) @@ -1149,14 +1152,16 @@ The UDP checksum is to be computed. (See below.) .El .Pp -Should a TCP or UDP checksum be offloaded to the hardware, +Should a SCTP, TCP, or UDP checksum be offloaded to the hardware, the field .Va csum_data will contain the byte offset of the checksum field relative to the end of the IP header. -In this case, the checksum field will be initially -set by the TCP/IP module to the checksum of the pseudo header +In the case of TCP or UDP, the checksum field will be initially +set by the TCP or UDP implementation to the checksum of the pseudo header defined by the TCP and UDP specifications. +In the case of SCTP, the checksum field will be initially +set by the SCTP implementation to 0. .Pp On input, an interface indicates the actions it has performed on a packet by setting one or more of the following flags in @@ -1187,13 +1192,13 @@ to obtain the final checksum to be used for TCP or UDP validation purposes. .El .Pp If a particular network interface just indicates success or -failure of TCP or UDP checksum validation without returning +failure of SCTP, TCP, or UDP checksum validation without returning the exact value of the checksum to the host CPU, its driver can mark .Dv CSUM_DATA_VALID -and -.Dv CSUM_PSEUDO_HDR in -.Va csum_flags , +.Va csum_flags +as well as, for TCP and UDP, +.Dv CSUM_PSEUDO_HDR and set .Va csum_data to @@ -1203,6 +1208,13 @@ It is a peculiarity of the algorithm used that the Internet checksum calculated over any valid packet will be .Li 0xFFFF as long as the original checksum field is included. +Note that for SCTP the value of +.Va csum_data +is not relevant and +.Dv CSUM_PSEUDO_HDR +in +.Va csum_flags +is not set, since SCTP does not use a pseudo header checksum. .Sh STRESS TESTING When running a kernel compiled with the option .Dv MBUF_STRESS_TEST , diff --git a/share/man/man9/style.9 b/share/man/man9/style.9 index 484b4f144b2e..26c7a3b2aa64 100644 --- a/share/man/man9/style.9 +++ b/share/man/man9/style.9 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd March 27, 2025 +.Dd July 28, 2025 .Dt STYLE 9 .Os .Sh NAME @@ -766,8 +766,7 @@ to any pointer type. .Pp Values in .Ic return -statements should be enclosed in parentheses where possible. -For example, parentheses cannot be used if the value is a C++ braced-init-list. +statements should be enclosed in parentheses. .Pp Use .Xr err 3 @@ -918,6 +917,161 @@ Only use the annotation for the entire if statement, rather than individual clauses. Do not add these annotations without empirical evidence of the likelihood of the branch. +.Ss C++ +KNF style was originally defined as a style for C. +C++ introduces several new idioms which do not have an existing corollary +in KNF C such as inline function definitions in classes. +C++ is also not always compatible with some KNF guidelines such as +enclosing return values in parentheses. +For C++ code, FreeBSD aims to follow broadly accepted C++ practices while +also following the general shape of KNF. +This section enumerates C++ specific guidelines that differ from KNF C. +.Pp +The preferred suffixes for C++ source files are +.Dq .cc +and +.Dq .hh . +Header files should always use a suffix, +unlike headers from the C++ standard library. +.Pp +Return values should not be enclosed in parentheses. +When converting existing C code to C++, +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. +Nested namespaces should be declared using a single namespace declaration. +.Bd -literal +namespace foo::bar { +} +.Ed +.Pp +Member function declarations should follow the same style used for standalone +function protoypes except that a space should be used between a function's +return type and name. +.Pp +Function definitions at the top level should use a newline after the function +type similar to C function definitions. +.Pp +Nested member function definitions inside of a class, structure, or union +should not use a newline after the function type. +Instead, these should follow the style of member function declarations. +This is more common C++ style and is more compact for small methods such as +getters and setters. +.Pp +Inline functions whose body consists of a single statement may use a single +line for the function body. +Inline functions with an empty body should always use a single line. +.Bd -literal +struct widget { + int foo() { return 4; } + int bar(); +}; + +int +widget::bar() +{ + return 6; +} +.Ed +.Pp +Default and deleted methods should be declared as a single line. +.Bd -literal +class box { + ~box() = default; +}; +.Ed +.Pp +In template declarations, the +.Ic template +keyword and list of template parameters should be followed by a newline +before the templated declaration. +.Bd -literal +template <typename T> +class box { + T data; +}; +.Ed +.Pp +The +.Ic & +for reference variables should be placed on the variable name rather +than the type similar to the style used with +.Ic * +for pointers. +.Bd -literal + int x; + int &xp = x; +.Ed +.Pp +Variables may be declared at any point within a function, +not just at the start of blocks. +.Pp +Standard library containers should be used in preference to +.Xr queue 3 +or +.Xr tree 3 +macros. +.Pp +.Ic nullptr +should be used instead of +.Dv NULL +or 0. +.Pp +Use standard library types for managing strings such as +.Vt std::string +and +.Vt std::string_view +rather than +.Vt "char *" +and +.Vt "const char *" . +C types may be used when interfacing with C code. +.Pp +The +.Ic auto +keyword can be used in various contexts which improve readability. +Examples include iterators, non-trivial types of ranged-for values, +and return values of obvious types, +such as +.Ic static_cast +or +.Fn std::make_unique . +Place any qualifiers before +.Ic auto , +for example: +.Ic const auto . +.Pp +Use the +.Vt std::unique_ptr +and +.Vt std::shared_ptr +smart pointers to manage the lifetime of dynamically allocated objects +instead of +.Ic new +and +.Ic delete . +Construct smart pointers with +.Fn std::make_unique +or +.Fn std::make_shared . +Do not use +.Xr malloc 3 +except when necessary to interface with C code. +.Pp +Do not import any namespaces with +.Ic using +at global scope in header files. +Namespaces other than the +.Ic std +namespace (for example, +.Ic std::literals ) +may be imported in source files and in function scope in header files. +.Pp +Define type aliases using +.Ic using +instead of +.Ic typedef . .Sh FILES .Bl -tag -width indent .It Pa /usr/src/tools/build/checkstyle9.pl diff --git a/share/man/man9/ucred.9 b/share/man/man9/ucred.9 index e9fe2e1d02fc..16de37dd8b35 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 @@ -119,8 +119,7 @@ It also truncates 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. .Pp The .Fn cru2x diff --git a/share/misc/committers-ports.dot b/share/misc/committers-ports.dot index 7bb3d936e5e5..fb6c168f1425 100644 --- a/share/misc/committers-ports.dot +++ b/share/misc/committers-ports.dot @@ -153,6 +153,7 @@ ak [label="Alex Kozlov\nak@FreeBSD.org\n2012/02/29"] ale [label="Alex Dupre\nale@FreeBSD.org\n2004/01/12"] alepulver [label="Alejandro Pulver\nalepulver@FreeBSD.org\n2006/04/01"] alexey [label="Alexey Degtyarev\nalexey@FreeBSD.org\n2013/11/09"] +alven [label="Älven\nalven@FreeBSD.org\n2025/07/28"] amdmi3 [label="Dmitry Marakasov\namdmi3@FreeBSD.org\n2008/06/19"] antoine [label="Antoine Brodin\nantoine@FreeBSD.org\n2013/04/03"] arrowd [label="Gleb Popov\narrowd@FreeBSD.org\n2018/05/18"] @@ -420,6 +421,7 @@ culot -> marino culot -> pi culot -> wg +db -> alven db -> tj db -> shurd @@ -865,6 +867,7 @@ wxs -> zi ygy -> yasu +yuri -> alven yuri -> rea zirias -> jbo 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/Makefile b/share/mk/Makefile index 837f7da68b4b..4ab5c8cc314b 100644 --- a/share/mk/Makefile +++ b/share/mk/Makefile @@ -10,6 +10,7 @@ UPDATE_DEPENDFILE= no .include <src.opts.mk> +PACKAGE= bmake FILES= \ auto.obj.mk \ bsd.README \ diff --git a/share/mk/src.libnames.mk b/share/mk/src.libnames.mk index f21d519160d2..88202aeb78fe 100644 --- a/share/mk/src.libnames.mk +++ b/share/mk/src.libnames.mk @@ -487,6 +487,7 @@ _DP_be= zfs spl nvpair zfsbootenv _DP_netmap= _DP_ifconfig= m _DP_pfctl= nv +_DP_krb5ss= edit # OFED support .if ${MK_OFED} != "no" 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/i386/Makefile b/stand/i386/Makefile index 768496598575..299e070d8cd5 100644 --- a/stand/i386/Makefile +++ b/stand/i386/Makefile @@ -18,7 +18,7 @@ SUBDIR.yes+= loader_simp # special boot programs, 'self-extracting boot2+loader' SUBDIR.${MK_LOADER_PXEBOOT}+= pxeldr -SUBDIR.${MK_LOADER_ZFS}+= zfsboot gptzfsboot +SUBDIR.${MK_LOADER_ZFS}+= gptzfsboot .if defined(PXEBOOT_DEFAULT_INTERP) L=${PXEBOOT_DEFAULT_INTERP} diff --git a/stand/i386/common/bootargs.h b/stand/i386/common/bootargs.h index dafcf6a55554..072f7ee505fd 100644 --- a/stand/i386/common/bootargs.h +++ b/stand/i386/common/bootargs.h @@ -88,7 +88,7 @@ struct bootargs /* * geli_boot_data is embedded in geli_boot_args (passed from gptboot to loader) - * and in zfs_boot_args (passed from zfsboot and gptzfsboot to loader). + * and in zfs_boot_args (passed from gptzfsboot to loader). */ struct geli_boot_data { diff --git a/stand/i386/gptboot/Makefile b/stand/i386/gptboot/Makefile index b91875d242f5..a829be6c745d 100644 --- a/stand/i386/gptboot/Makefile +++ b/stand/i386/gptboot/Makefile @@ -1,6 +1,6 @@ .include <bsd.init.mk> -.PATH: ${BOOTSRC}/i386/boot2 ${BOOTSRC}/i386/common ${SASRC} +.PATH: ${BOOTSRC}/i386/boot2 ${BOOTSRC}/i386/common FILES= gptboot MAN= gptboot.8 @@ -53,12 +53,12 @@ gptldr.out: gptldr.o ${LD} ${LD_FLAGS} -e start --defsym ORG=${ORG1} -T ${LDSCRIPT} -o ${.TARGET} gptldr.o CLEANFILES+= gptboot.bin gptboot.out gptboot.o sio.o drv.o \ - cons.o ${OPENCRYPTO_XTS} + cons.o gptboot.bin: gptboot.out ${OBJCOPY} -S -O binary gptboot.out ${.TARGET} -gptboot.out: ${BTXCRT} gptboot.o sio.o drv.o cons.o ${OPENCRYPTO_XTS} +gptboot.out: ${BTXCRT} gptboot.o sio.o drv.o cons.o ${LD} ${LD_FLAGS} --defsym ORG=${ORG2} -T ${LDSCRIPT} -o ${.TARGET} ${.ALLSRC} ${LIBSA32} .include <bsd.prog.mk> diff --git a/stand/i386/gptzfsboot/Makefile b/stand/i386/gptzfsboot/Makefile index 0d9fa8b043df..0b67ff8cdaf4 100644 --- a/stand/i386/gptzfsboot/Makefile +++ b/stand/i386/gptzfsboot/Makefile @@ -1,7 +1,7 @@ .include <bsd.init.mk> .PATH: ${BOOTSRC}/i386/boot2 ${BOOTSRC}/i386/gptboot \ - ${BOOTSRC}/i386/zfsboot ${BOOTSRC}/i386/common \ + ${BOOTSRC}/i386/common \ ${BOOTSRC}/common FILES= gptzfsboot @@ -65,7 +65,7 @@ gptldr.out: gptldr.o ${LD} ${LD_FLAGS} -e start --defsym ORG=${ORG1} -T ${LDSCRIPT} -o ${.TARGET} gptldr.o OBJS= zfsboot.o sio.o cons.o bcache.o devopen.o disk.o part.o zfs_cmd.o misc.o -CLEANFILES+= gptzfsboot.bin gptzfsboot.out ${OBJS} ${OPENCRYPTO_XTS} +CLEANFILES+= gptzfsboot.bin gptzfsboot.out ${OBJS} # i386 standalone support library LIBI386= ${BOOTOBJ}/i386/libi386/libi386.a @@ -73,8 +73,7 @@ LIBI386= ${BOOTOBJ}/i386/libi386/libi386.a gptzfsboot.bin: gptzfsboot.out ${OBJCOPY} -S -O binary gptzfsboot.out ${.TARGET} -gptzfsboot.out: ${BTXCRT} ${OBJS} \ - ${OPENCRYPTO_XTS} +gptzfsboot.out: ${BTXCRT} ${OBJS} ${LD} ${LD_FLAGS} --defsym ORG=${ORG2} -T ${LDSCRIPT} -o ${.TARGET} ${.ALLSRC} ${LIBI386} ${LIBSA32} zfsboot.o: ${ZFSSRC}/zfsimpl.c diff --git a/stand/i386/zfsboot/zfsboot.c b/stand/i386/gptzfsboot/zfsboot.c index 4c8eae9b65e5..4c8eae9b65e5 100644 --- a/stand/i386/zfsboot/zfsboot.c +++ b/stand/i386/gptzfsboot/zfsboot.c diff --git a/stand/i386/isoboot/Makefile b/stand/i386/isoboot/Makefile index 7973f8029aa0..0049e7fd3e0a 100644 --- a/stand/i386/isoboot/Makefile +++ b/stand/i386/isoboot/Makefile @@ -1,7 +1,7 @@ .include <bsd.init.mk> .PATH: ${BOOTSRC}/i386/boot2 ${BOOTSRC}/i386/gptboot \ - ${BOOTSRC}/i386/common ${SASRC} + ${BOOTSRC}/i386/common FILES= isoboot MAN= isoboot.8 @@ -51,12 +51,12 @@ gptldr.out: gptldr.o ${LD} ${LD_FLAGS} -e start --defsym ORG=${ORG1} -T ${LDSCRIPT} -o ${.TARGET} gptldr.o CLEANFILES+= isoboot.bin isoboot.out isoboot.o sio.o drv.o \ - cons.o ${OPENCRYPTO_XTS} + cons.o isoboot.bin: isoboot.out ${OBJCOPY} -S -O binary isoboot.out ${.TARGET} -isoboot.out: ${BTXCRT} isoboot.o sio.o drv.o cons.o ${OPENCRYPTO_XTS} +isoboot.out: ${BTXCRT} isoboot.o sio.o drv.o cons.o ${LD} ${LD_FLAGS} --defsym ORG=${ORG2} -T ${LDSCRIPT} -o ${.TARGET} ${.ALLSRC} ${LIBSA32} .include <bsd.prog.mk> diff --git a/stand/i386/loader/main.c b/stand/i386/loader/main.c index fd95cf5243cf..a70b3a253b90 100644 --- a/stand/i386/loader/main.c +++ b/stand/i386/loader/main.c @@ -198,7 +198,7 @@ main(void) #ifdef LOADER_ZFS_SUPPORT /* - * zfsboot and gptzfsboot have always passed KARGS_FLAGS_ZFS, + * gptzfsboot has always passed KARGS_FLAGS_ZFS, * so if that is set along with KARGS_FLAGS_EXTARG we know we * can interpret the extarg data as a struct zfs_boot_args. */ diff --git a/stand/i386/zfsboot/Makefile b/stand/i386/zfsboot/Makefile deleted file mode 100644 index b619b84c368e..000000000000 --- a/stand/i386/zfsboot/Makefile +++ /dev/null @@ -1,92 +0,0 @@ -.include <bsd.init.mk> - -.PATH: ${BOOTSRC}/i386/boot2 ${BOOTSRC}/i386/common ${BOOTSRC}/common - -FILES= zfsboot -MAN= zfsboot.8 - -BOOT_COMCONSOLE_PORT?= 0x3f8 -BOOT_COMCONSOLE_SPEED?= 115200 -B2SIOFMT?= 0x3 - -REL1= 0x700 -ORG1= 0x7c00 -ORG2= 0x2000 - -CFLAGS+=-DBOOTPROG=\"zfsboot\" \ - -O1 \ - -DBOOT2 \ - -DLOADER_GPT_SUPPORT \ - -DLOADER_MBR_SUPPORT \ - -DLOADER_ZFS_SUPPORT \ - -DLOADER_UFS_SUPPORT \ - -DSIOPRT=${BOOT_COMCONSOLE_PORT} \ - -DSIOFMT=${B2SIOFMT} \ - -DSIOSPD=${BOOT_COMCONSOLE_SPEED} \ - -I${LDRSRC} \ - -I${BOOTSRC}/i386/common \ - -I${BOOTSRC}/i386/libi386 \ - -I${ZFSSRC} \ - -I${SYSDIR}/crypto/skein \ - -I${SYSDIR}/cddl/boot/zfs \ - -I${SYSDIR}/contrib/openzfs/include \ - -I${SYSDIR}/contrib/openzfs/include/os/freebsd/spl \ - -I${SYSDIR}/contrib/openzfs/include/os/freebsd/zfs \ - -I${SYSDIR}/cddl/contrib/opensolaris/common/lz4 \ - -I${BOOTSRC}/i386/boot2 \ - -Wall -Waggregate-return -Wbad-function-cast -Wno-cast-align \ - -Wmissing-declarations -Wmissing-prototypes -Wnested-externs \ - -Wpointer-arith -Wshadow -Wstrict-prototypes -Wwrite-strings - -CFLAGS.part.c+= -DHAVE_MEMCPY -I${SRCTOP}/sys/contrib/zlib - -CFLAGS.gcc+= --param max-inline-insns-single=100 - -LD_FLAGS+=${LD_FLAGS_BIN} - -CLEANFILES+= zfsboot - -zfsboot: zfsboot1 zfsboot2 - cat zfsboot1 zfsboot2 > zfsboot - -CLEANFILES+= zfsboot1 zfsldr.out zfsldr.o - -zfsboot1: zfsldr.out - ${OBJCOPY} -S -O binary zfsldr.out ${.TARGET} - -zfsldr.out: zfsldr.o - ${LD} ${LD_FLAGS} -e start --defsym ORG=${ORG1} -T ${LDSCRIPT} -o ${.TARGET} zfsldr.o - -OBJS= zfsboot.o sio.o cons.o bcache.o devopen.o disk.o part.o zfs_cmd.o misc.o -CLEANFILES+= zfsboot2 zfsboot.ld zfsboot.ldr zfsboot.bin zfsboot.out \ - ${OBJS} - -# We currently allow 256k bytes for zfsboot - in practice it could be -# any size up to 3.5Mb but keeping it fixed size simplifies zfsldr. -# -BOOT2SIZE= 262144 - -# i386 standalone support library -LIBI386= ${BOOTOBJ}/i386/libi386/libi386.a - -zfsboot2: zfsboot.ld - @set -- `ls -l ${.ALLSRC}`; x=$$((${BOOT2SIZE}-$$5)); \ - echo "$$x bytes available"; test $$x -ge 0 - ${DD} if=${.ALLSRC} of=${.TARGET} bs=${BOOT2SIZE} conv=sync - -zfsboot.ld: zfsboot.ldr zfsboot.bin ${BTXKERN} - btxld -v -E ${ORG2} -f bin -b ${BTXKERN} -l zfsboot.ldr \ - -o ${.TARGET} -P 1 zfsboot.bin - -zfsboot.ldr: - :> ${.TARGET} - -zfsboot.bin: zfsboot.out - ${OBJCOPY} -S -O binary zfsboot.out ${.TARGET} - -zfsboot.out: ${BTXCRT} ${OBJS} - ${LD} ${LD_FLAGS} --defsym ORG=${ORG2} -T ${LDSCRIPT} -o ${.TARGET} ${.ALLSRC} ${LIBI386} ${LIBSA32} - -SRCS= zfsboot.c - -.include <bsd.prog.mk> diff --git a/stand/i386/zfsboot/Makefile.depend b/stand/i386/zfsboot/Makefile.depend deleted file mode 100644 index 92ab022283fd..000000000000 --- a/stand/i386/zfsboot/Makefile.depend +++ /dev/null @@ -1,17 +0,0 @@ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - include \ - include/xlocale \ - lib/libmd \ - stand/i386/btx/btx \ - stand/i386/btx/lib \ - stand/libsa32 \ - stand/zfs32 \ - - -.include <dirdeps.mk> - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif diff --git a/stand/i386/zfsboot/zfsboot.8 b/stand/i386/zfsboot/zfsboot.8 deleted file mode 100644 index a8411bc065d0..000000000000 --- a/stand/i386/zfsboot/zfsboot.8 +++ /dev/null @@ -1,130 +0,0 @@ -.\" Copyright (c) 2014 Andriy Gapon <avg@FreeBSD.org> -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (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 March 27, 2018 -.Dt ZFSBOOT 8 -.Os -.Sh NAME -.Nm zfsboot -.Nd bootcode for ZFS on BIOS-based computers -.Sh DESCRIPTION -.Nm -is used on BIOS-based computers to boot from a filesystem in -a ZFS pool. -.Nm -is installed in two parts on a disk or a partition used by a ZFS pool. -The first part, a single-sector starter boot block, is installed -at the beginning of the disk or partition. -The second part, a main boot block, is installed at a special offset -within the disk or partition. -Both areas are reserved by the ZFS on-disk specification for boot use. -If -.Nm -is installed in a partition, then that partition should be made -bootable using appropriate configuration and boot blocks described in -.Xr boot 8 . -.Sh BOOTING -The -.Nm -boot process is very similar to that of -.Xr gptzfsboot 8 . -One significant difference is that -.Nm -does not currently support the GPT partitioning scheme. -Thus only whole disks and MBR partitions, traditionally referred to as -slices, are probed for ZFS disk labels. -See the BUGS section in -.Xr gptzfsboot 8 -for some limitations of the MBR scheme support. -.Sh USAGE -.Nm -supports all the same prompt and configuration file arguments as -.Xr gptzfsboot 8 . -.Sh FILES -.Bl -tag -width /boot/zfsboot -compact -.It Pa /boot/zfsboot -boot code binary -.It Pa /boot.config -parameters for the boot block -.Pq optional -.It Pa /boot/config -alternative parameters for the boot block -.Pq optional -.El -.Sh EXAMPLES -.Nm -is typically installed using -.Xr dd 1 . -To install -.Nm -on the -.Pa ada0 -drive: -.Bd -literal -offset indent -dd if=/boot/zfsboot of=/dev/ada0 count=1 -dd if=/boot/zfsboot of=/dev/ada0 iseek=1 oseek=1024 -.Ed -.Pp -If the drive is currently in use, the GEOM safety will prevent writes -and must be disabled before running the above commands: -.Bd -literal -offset indent -sysctl kern.geom.debugflags=0x10 -.Ed -.Pp -.Nm -can also be installed in an MBR slice: -.Bd -literal -offset indent -gpart create -s mbr ada0 -gpart add -t freebsd ada0 -gpart bootcode -b /boot/boot0 ada0 -gpart set -a active -i 1 ada0 -dd if=/dev/zero of=/dev/ada0s1 count=2 -dd if=/boot/zfsboot of=/dev/ada0s1 count=1 -dd if=/boot/zfsboot of=/dev/ada0s1 iseek=1 oseek=1024 -.Ed -.Pp -Note that commands to create and populate a pool are not shown -in the example above. -.Sh SEE ALSO -.Xr dd 1 , -.Xr boot.config 5 , -.Xr boot 8 , -.Xr gptzfsboot 8 , -.Xr loader 8 , -.Xr zpool 8 -.Sh HISTORY -.Nm -appeared in FreeBSD 7.3. -.Sh AUTHORS -This manual page was written by -.An Andriy Gapon Aq avg@FreeBSD.org . -.Sh BUGS -Installing -.Nm -with -.Xr dd 1 -is a hack. -ZFS needs a command to properly install -.Nm -onto a ZFS-controlled disk or partition. diff --git a/stand/i386/zfsboot/zfsldr.S b/stand/i386/zfsboot/zfsldr.S deleted file mode 100644 index cd8289f952fd..000000000000 --- a/stand/i386/zfsboot/zfsldr.S +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Copyright (c) 1998 Robert Nordier - * All rights reserved. - * - * Redistribution and use in source and binary forms are freely - * permitted provided that the above copyright notice and this - * paragraph and the following disclaimer are duplicated in all - * such forms. - * - * This software is provided "AS IS" and without any express or - * implied warranties, including, without limitation, the implied - * warranties of merchantability and fitness for a particular - * purpose. - */ - -/* Memory Locations */ - .set MEM_ARG,0x900 # Arguments - .set MEM_ORG,0x7c00 # Origin - .set MEM_BUF,0x8000 # Load area - .set MEM_BTX,0x9000 # BTX start - .set MEM_JMP,0x9010 # BTX entry point - .set MEM_USR,0xa000 # Client start - .set BDA_BOOT,0x472 # Boot howto flag - -/* Partition Constants */ - .set PRT_OFF,0x1be # Partition offset - .set PRT_NUM,0x4 # Partitions - .set PRT_BSD,0xa5 # Partition type - -/* Misc. Constants */ - .set SIZ_PAG,0x1000 # Page size - .set SIZ_SEC,0x200 # Sector size - .set COPY_BLKS,0x8 # Number of blocks - # to copy for boot2 (<= 15) - .set COPY_BLK_SZ,0x8000 # Copy in 32k blocks; must be - # a multiple of 16 bytes - .set NSECT,(COPY_BLK_SZ / SIZ_SEC * COPY_BLKS) - .globl start - .code16 - -/* - * Load the rest of zfsboot2 and BTX up, copy the parts to the right locations, - * and start it all up. - */ - -/* - * Setup the segment registers to flat addressing (segment 0) and setup the - * stack to end just below the start of our code. - */ -start: cld # String ops inc - xor %cx,%cx # Zero - mov %cx,%es # Address - mov %cx,%ds # data - mov %cx,%ss # Set up - mov $start,%sp # stack -/* - * Load the MBR and look for the first FreeBSD slice. We use the fake - * partition entry below that points to the MBR when we call read. - * The first pass looks for the first active FreeBSD slice. The - * second pass looks for the first non-active FreeBSD slice if the - * first one fails. - */ - call check_edd # Make sure EDD works - mov $part4,%si # Dummy partition - xor %eax,%eax # Read MBR - movl $MEM_BUF,%ebx # from first - call read # sector - mov $0x1,%cx # Two passes -main.1: mov $MEM_BUF+PRT_OFF,%si # Partition table - movb $0x1,%dh # Partition -main.2: cmpb $PRT_BSD,0x4(%si) # Our partition type? - jne main.3 # No - jcxz main.5 # If second pass - testb $0x80,(%si) # Active? - jnz main.5 # Yes -main.3: add $0x10,%si # Next entry - incb %dh # Partition - cmpb $0x1+PRT_NUM,%dh # In table? - jb main.2 # Yes - dec %cx # Do two - jcxz main.1 # passes -/* - * If we get here, we didn't find any FreeBSD slices at all, so print an - * error message and die. - */ - mov $msg_part,%si # Message - jmp error # Error - -/* - * Ok, we have a slice and drive in %dx now, so use that to locate and - * load boot2. %si references the start of the slice we are looking - * for, so go ahead and load up the COPY_BLKS*COPY_BLK_SZ/SIZ_SEC sectors - * starting at sector 1024 (i.e. after the two vdev labels). We don't - * have do anything fancy here to allow for an extra copy of boot1 and - * a partition table (compare to this section of the UFS bootstrap) so we - * just load it all at 0x9000. The first part of boot2 is BTX, which wants - * to run at 0x9000. The boot2.bin binary starts right after the end of BTX, - * so we have to figure out where the start of it is and then move the - * binary to 0xc000. Normally, BTX clients start at MEM_USR, or 0xa000, - * but when we use btxld to create zfsboot2, we use an entry point of - * 0x2000. That entry point is relative to MEM_USR; thus boot2.bin - * starts at 0xc000. - * - * The load area and the target area for the client overlap so we have - * to use a decrementing string move. We also play segment register - * games with the destination address for the move so that the client - * can be larger than 16k (which would overflow the zero segment since - * the client starts at 0xc000). - */ -main.5: mov %dx,MEM_ARG # Save args - mov $NSECT,%cx # Sector count - movl $1024,%eax # Offset to boot2 - mov $MEM_BTX,%ebx # Destination buffer -main.6: pushal # Save params - call read # Read disk - popal # Restore - incl %eax # Advance to - add $SIZ_SEC,%ebx # next sector - loop main.6 # If not last, read another - - mov $MEM_BTX,%bx # BTX - mov 0xa(%bx),%si # Get BTX length and set - add %bx,%si # %si to start of boot2 - dec %si # Set %ds:%si to point at the - mov %si,%ax # last byte we want to copy - shr $4,%ax # from boot2, with %si made as - add $(COPY_BLKS*COPY_BLK_SZ/16),%ax # small as possible. - and $0xf,%si # - mov %ax,%ds # - mov $(MEM_USR+2*SIZ_PAG)/16,%ax # Set %es:(-1) to point at - add $(COPY_BLKS*COPY_BLK_SZ/16),%ax # the last byte we - mov %ax,%es # want to copy boot2 into. - mov $COPY_BLKS,%bx # Copy COPY_BLKS 32k blocks -copyloop: - add $COPY_BLK_SZ,%si # Adjust %ds:%si to point at - mov %ds,%ax # the end of the next 32k to - sub $COPY_BLK_SZ/16,%ax # copy from boot2 - mov %ax,%ds - mov $COPY_BLK_SZ-1,%di # Adjust %es:%di to point at - mov %es,%ax # the end of the next 32k into - sub $COPY_BLK_SZ/16,%ax # which we want boot2 copied - mov %ax,%es - mov $COPY_BLK_SZ,%cx # Copy 32k - std - rep movsb - dec %bx - jnz copyloop - mov %cx,%ds # Reset %ds and %es - mov %cx,%es - cld # Back to increment - -/* - * Enable A20 so we can access memory above 1 meg. - * Use the zero-valued %cx as a timeout for embedded hardware which do not - * have a keyboard controller. - */ -seta20: cli # Disable interrupts -seta20.1: dec %cx # Timeout? - jz seta20.3 # Yes - inb $0x64,%al # Get status - testb $0x2,%al # Busy? - jnz seta20.1 # Yes - movb $0xd1,%al # Command: Write - outb %al,$0x64 # output port -seta20.2: inb $0x64,%al # Get status - testb $0x2,%al # Busy? - jnz seta20.2 # Yes - movb $0xdf,%al # Enable - outb %al,$0x60 # A20 -seta20.3: sti # Enable interrupts - - jmp start+MEM_JMP-MEM_ORG # Start BTX - - -/* - * Read a sector from the disk. Sets up an EDD packet on the stack - * and passes it to read. We assume that the destination address is - * always segment-aligned. - * - * %eax - int - LBA to read in relative to partition start - * %ebx - ptr - destination address - * %dl - byte - drive to read from - * %si - ptr - MBR partition entry - */ -read: xor %ecx,%ecx # Get - addl 0x8(%si),%eax # LBA - adc $0,%ecx - pushl %ecx # Starting absolute block - pushl %eax # block number - shr $4,%ebx # Convert to segment - push %bx # Address of - push $0 # transfer buffer - push $0x1 # Read 1 sector - push $0x10 # Size of packet - mov %sp,%si # Packet pointer - mov $0x42,%ah # BIOS: Extended - int $0x13 # read - jc read.1 # If error, fail - lea 0x10(%si),%sp # Clear stack - ret # If success, return -read.1: mov %ah,%al # Format - mov $read_err,%di # error - call hex8 # code - mov $msg_read,%si # Set the error message and - # fall through to the error - # routine -/* - * Print out the error message pointed to by %ds:(%si) followed - * by a prompt, wait for a keypress, and then reboot the machine. - */ -error: callw putstr # Display message - mov $prompt,%si # Display - callw putstr # prompt - xorb %ah,%ah # BIOS: Get - int $0x16 # keypress - movw $0x1234, BDA_BOOT # Do a warm boot - ljmp $0xffff,$0x0 # reboot the machine -/* - * Display a null-terminated string using the BIOS output. - */ -putstr.0: mov $0x7,%bx # Page:attribute - movb $0xe,%ah # BIOS: Display - int $0x10 # character -putstr: lodsb # Get char - testb %al,%al # End of string? - jne putstr.0 # No - ret # To caller -/* - * Check to see if the disk supports EDD. zfsboot requires EDD and does not - * support older C/H/S disk I/O. - */ -check_edd: cmpb $0x80,%dl # Hard drive? - jb check_edd.1 # No, fail to boot - mov $0x55aa,%bx # Magic - push %dx # Save - movb $0x41,%ah # BIOS: Check - int $0x13 # extensions present - pop %dx # Restore - jc check_edd.1 # If error, fail - cmp $0xaa55,%bx # Magic? - jne check_edd.1 # No, so fail - testb $0x1,%cl # Packet interface? - jz check_edd.1 # No, so fail - ret # EDD ok, keep booting -check_edd.1: mov $msg_chs,%si # Warn that CHS is - jmp error # unsupported and fail -/* - * AL to hex, saving the result to [EDI]. - */ -hex8: push %ax # Save - shrb $0x4,%al # Do upper - call hex8.1 # 4 - pop %ax # Restore -hex8.1: andb $0xf,%al # Get lower 4 - cmpb $0xa,%al # Convert - sbbb $0x69,%al # to hex - das # digit - orb $0x20,%al # To lower case - stosb # Save char - ret # (Recursive) - -/* Messages */ - -msg_chs: .asciz "CHS not supported" -msg_read: .ascii "Read error: " -read_err: .asciz "XX" -msg_part: .asciz "Boot error" - -prompt: .asciz "\r\n" - - .org PRT_OFF,0x90 - -/* Partition table */ - - .fill 0x30,0x1,0x0 -part4: .byte 0x80, 0x00, 0x01, 0x00 - .byte 0xa5, 0xfe, 0xff, 0xff - .byte 0x00, 0x00, 0x00, 0x00 - .byte 0x50, 0xc3, 0x00, 0x00 # 50000 sectors long, bleh - - .word 0xaa55 # Magic number 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/cddl/dev/sdt/sdt.c b/sys/cddl/dev/sdt/sdt.c index a8da618204af..0a9059104671 100644 --- a/sys/cddl/dev/sdt/sdt.c +++ b/sys/cddl/dev/sdt/sdt.c @@ -72,6 +72,7 @@ static void sdt_load(void); static int sdt_unload(void); static void sdt_create_provider(struct sdt_provider *); static void sdt_create_probe(struct sdt_probe *); +static void sdt_init_probe(struct sdt_probe *, linker_file_t); static void sdt_kld_load(void *, struct linker_file *); static void sdt_kld_unload_try(void *, struct linker_file *, int *); @@ -204,6 +205,14 @@ sdt_create_probe(struct sdt_probe *probe) (void)dtrace_probe_create(prov->id, mod, func, name, aframes, probe); } +static void +sdt_init_probe(struct sdt_probe *probe, linker_file_t lf) +{ + probe->sdtp_lf = lf; + TAILQ_INIT(&probe->argtype_list); + STAILQ_INIT(&probe->tracepoint_list); +} + /* * Probes are created through the SDT module load/unload hook, so this function * has nothing to do. It only exists because the DTrace provider framework @@ -361,12 +370,19 @@ static void sdt_kld_load_providers(struct linker_file *lf) { struct sdt_provider **prov, **begin, **end; + struct sdt_probe **p_begin, **p_end; if (linker_file_lookup_set(lf, "sdt_providers_set", &begin, &end, NULL) == 0) { for (prov = begin; prov < end; prov++) sdt_create_provider(*prov); } + + if (linker_file_lookup_set(lf, "sdt_probes_set", &p_begin, &p_end, + NULL) == 0) { + for (struct sdt_probe **probe = p_begin; probe < p_end; probe++) + sdt_init_probe(*probe, lf); + } } static void @@ -378,13 +394,8 @@ sdt_kld_load_probes(struct linker_file *lf) if (linker_file_lookup_set(lf, "sdt_probes_set", &p_begin, &p_end, NULL) == 0) { - for (struct sdt_probe **probe = p_begin; probe < p_end; - probe++) { - (*probe)->sdtp_lf = lf; + for (struct sdt_probe **probe = p_begin; probe < p_end; probe++) sdt_create_probe(*probe); - TAILQ_INIT(&(*probe)->argtype_list); - STAILQ_INIT(&(*probe)->tracepoint_list); - } } if (linker_file_lookup_set(lf, "sdt_argtypes_set", &a_begin, &a_end, diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c index b88f1451f1a2..31460819e6ab 100644 --- a/sys/compat/linux/linux_misc.c +++ b/sys/compat/linux/linux_misc.c @@ -1030,47 +1030,32 @@ 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]; setsugid(p); proc_set_cred(p, newcred); @@ -1092,13 +1077,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 +1091,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..9fe799c0b9de 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,9 @@ 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]; setsugid(td->td_proc); proc_set_cred(p, newcred); @@ -155,13 +139,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 +153,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/conf/files.arm64 b/sys/conf/files.arm64 index 901da27e63f2..641001efab5e 100644 --- a/sys/conf/files.arm64 +++ b/sys/conf/files.arm64 @@ -368,6 +368,10 @@ dev/ice/irdma_di_if.m optional ice pci \ compile-with "${NORMAL_M} -I$S/dev/ice" dev/ice/ice_ddp_common.c optional ice pci \ compile-with "${NORMAL_C} -I$S/dev/ice" +dev/ice/ice_iov.c optional ice pci pci_iov \ + compile-with "${NORMAL_C} -I$S/dev/ice" +dev/ice/ice_vf_mbx.c optional ice pci pci_iov \ + compile-with "${NORMAL_C} -I$S/dev/ice" ice_ddp.c optional ice_ddp \ compile-with "${AWK} -f $S/tools/fw_stub.awk ice_ddp.fw:ice_ddp:0x01032900 -mice_ddp -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ diff --git a/sys/dev/iicbus/iichid.c b/sys/dev/iicbus/iichid.c index 9c0324a24685..3f1d7a0cefba 100644 --- a/sys/dev/iicbus/iichid.c +++ b/sys/dev/iicbus/iichid.c @@ -275,62 +275,36 @@ iichid_cmd_read(struct iichid_softc* sc, void *buf, iichid_size_t maxlen, * 6.1.3 - Retrieval of Input Reports * DEVICE returns the length (2 Bytes) and the entire Input Report. */ - uint8_t actbuf[2] = { 0, 0 }; - /* Read actual input report length. */ + + memset(buf, 0xaa, 2); // In case nothing gets read struct iic_msg msgs[] = { - { sc->addr, IIC_M_RD | IIC_M_NOSTOP, sizeof(actbuf), actbuf }, + { sc->addr, IIC_M_RD, maxlen, buf }, }; - uint16_t actlen; int error; error = iicbus_transfer(sc->dev, msgs, nitems(msgs)); if (error != 0) return (error); - actlen = actbuf[0] | actbuf[1] << 8; -#ifdef IICHID_SAMPLING - if ((actlen == 0 && sc->sampling_rate_slow < 0) || - (maxlen == 0 && sc->sampling_rate_slow >= 0)) { -#else + DPRINTFN(sc, 5, "%*D\n", msgs[0].len, msgs[0].buf, " "); + + uint16_t actlen = le16dec(buf); + if (actlen == 0) { -#endif - /* Read and discard reset command response. */ - msgs[0] = (struct iic_msg) - { sc->addr, IIC_M_RD | IIC_M_NOSTART, - le16toh(sc->desc.wMaxInputLength) - 2, sc->intr_buf }; - actlen = 0; if (!sc->reset_acked) { mtx_lock(&sc->mtx); sc->reset_acked = true; wakeup(&sc->reset_acked); mtx_unlock(&sc->mtx); } -#ifdef IICHID_SAMPLING - } else if ((actlen <= 2 || actlen == 0xFFFF) && - sc->sampling_rate_slow >= 0) { - /* Read and discard 1 byte to send I2C STOP condition. */ - msgs[0] = (struct iic_msg) - { sc->addr, IIC_M_RD | IIC_M_NOSTART, 1, actbuf }; - actlen = 0; -#endif - } else { - actlen -= 2; - if (actlen > maxlen) { - DPRINTF(sc, "input report too big. requested=%d " - "received=%d\n", maxlen, actlen); - actlen = maxlen; - } - /* Read input report itself. */ - msgs[0] = (struct iic_msg) - { sc->addr, IIC_M_RD | IIC_M_NOSTART, actlen, buf }; } - error = iicbus_transfer(sc->dev, msgs, 1); - if (error == 0 && actual_len != NULL) + if (actlen <= 2 || actlen > maxlen) { + actlen = 0; + } + if (actual_len != NULL) { *actual_len = actlen; - - DPRINTFN(sc, 5, - "%*D - %*D\n", 2, actbuf, " ", msgs[0].len, msgs[0].buf, " "); + } return (error); } @@ -566,7 +540,7 @@ iichid_sampling_task(void *context, int pending) error = iichid_cmd_read(sc, sc->intr_buf, sc->intr_bufsize, &actual); if (error == 0) { if (actual > 0) { - sc->intr_handler(sc->intr_ctx, sc->intr_buf, actual); + sc->intr_handler(sc->intr_ctx, sc->intr_buf + 2, actual); sc->missing_samples = 0; if (sc->dup_size != actual || memcmp(sc->dup_buf, sc->intr_buf, actual) != 0) { @@ -577,7 +551,7 @@ iichid_sampling_task(void *context, int pending) ++sc->dup_samples; } else { if (++sc->missing_samples == 1) - sc->intr_handler(sc->intr_ctx, sc->intr_buf, 0); + sc->intr_handler(sc->intr_ctx, sc->intr_buf + 2, 0); sc->dup_samples = 0; } } else @@ -632,7 +606,7 @@ iichid_intr(void *context) if (error == 0) { if (sc->power_on && sc->open) { if (actual != 0) - sc->intr_handler(sc->intr_ctx, sc->intr_buf, + sc->intr_handler(sc->intr_ctx, sc->intr_buf + 2, actual); else DPRINTF(sc, "no data received\n"); @@ -842,11 +816,12 @@ iichid_intr_setup(device_t dev, device_t child __unused, hid_intr_t intr, sc = device_get_softc(dev); /* - * Do not rely on wMaxInputLength, as some devices may set it to - * a wrong length. Find the longest input report in report descriptor. + * Do not rely just on wMaxInputLength, as some devices (which?) + * may set it to a wrong length. Also find the longest input report + * in report descriptor, and add two for the length field. */ - rdesc->rdsize = - MAX(rdesc->isize, le16toh(sc->desc.wMaxInputLength) - 2); + rdesc->rdsize = 2 + + MAX(rdesc->isize, le16toh(sc->desc.wMaxInputLength)); /* Write and get/set_report sizes are limited by I2C-HID protocol. */ rdesc->grsize = rdesc->srsize = IICHID_SIZE_MAX; rdesc->wrsize = IICHID_SIZE_MAX; @@ -919,7 +894,7 @@ iichid_intr_poll(device_t dev, device_t child __unused) sc = device_get_softc(dev); error = iichid_cmd_read(sc, sc->intr_buf, sc->intr_bufsize, &actual); if (error == 0 && actual != 0) - sc->intr_handler(sc->intr_ctx, sc->intr_buf, actual); + sc->intr_handler(sc->intr_ctx, sc->intr_buf + 2, actual); } /* @@ -946,6 +921,7 @@ iichid_read(device_t dev, device_t child __unused, void *buf, { struct iichid_softc *sc; device_t parent; + uint8_t *tmpbuf; int error; if (maxlen > IICHID_SIZE_MAX) @@ -954,8 +930,12 @@ iichid_read(device_t dev, device_t child __unused, void *buf, parent = device_get_parent(sc->dev); error = iicbus_request_bus(parent, sc->dev, IIC_WAIT); if (error == 0) { - error = iichid_cmd_read(sc, buf, maxlen, actlen); + tmpbuf = malloc(maxlen + 2, M_DEVBUF, M_WAITOK | M_ZERO); + error = iichid_cmd_read(sc, tmpbuf, maxlen + 2, actlen); iicbus_release_bus(parent, sc->dev); + if (*actlen > 0) + memcpy(buf, tmpbuf + 2, *actlen); + free(tmpbuf, M_DEVBUF); } return (iic2errno(error)); } 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/nvmf/controller/nvmft_subr.c b/sys/dev/nvmf/controller/nvmft_subr.c index bb2bc0988e81..245971813854 100644 --- a/sys/dev/nvmf/controller/nvmft_subr.c +++ b/sys/dev/nvmf/controller/nvmft_subr.c @@ -26,46 +26,6 @@ nvmf_nqn_valid(const char *nqn) len = strnlen(nqn, NVME_NQN_FIELD_SIZE); if (len == 0 || len > NVMF_NQN_MAX_LEN) return (false); - -#ifdef STRICT_CHECKS - /* - * Stricter checks from the spec. Linux does not seem to - * require these. - */ - - /* - * NVMF_NQN_MIN_LEN does not include '.', and require at least - * one character of a domain name. - */ - if (len < NVMF_NQN_MIN_LEN + 2) - return (false); - if (memcmp("nqn.", nqn, strlen("nqn.")) != 0) - return (false); - nqn += strlen("nqn."); - - /* Next 4 digits must be a year. */ - for (u_int i = 0; i < 4; i++) { - if (!isdigit(nqn[i])) - return (false); - } - nqn += 4; - - /* '-' between year and month. */ - if (nqn[0] != '-') - return (false); - nqn++; - - /* 2 digit month. */ - for (u_int i = 0; i < 2; i++) { - if (!isdigit(nqn[i])) - return (false); - } - nqn += 2; - - /* '.' between month and reverse domain name. */ - if (nqn[0] != '.') - return (false); -#endif return (true); } diff --git a/sys/dev/pci/pci_iov.c b/sys/dev/pci/pci_iov.c index 1f72391fb6b4..0efcfeac9eff 100644 --- a/sys/dev/pci/pci_iov.c +++ b/sys/dev/pci/pci_iov.c @@ -734,11 +734,18 @@ pci_iov_config(struct cdev *cdev, struct pci_iov_arg *arg) first_rid = pci_get_rid(dev) + rid_off; last_rid = first_rid + (num_vfs - 1) * rid_stride; - /* We don't yet support allocating extra bus numbers for VFs. */ if (pci_get_bus(dev) != PCI_RID2BUS(last_rid)) { - device_printf(dev, "not enough PCIe bus numbers for VFs\n"); - error = ENOSPC; - goto out; + int rid = 0; + uint16_t last_rid_bus = PCI_RID2BUS(last_rid); + + iov->iov_bus_res = bus_alloc_resource(bus, PCI_RES_BUS, &rid, + last_rid_bus, last_rid_bus, 1, RF_ACTIVE); + if (iov->iov_bus_res == NULL) { + device_printf(dev, + "failed to allocate PCIe bus number for VFs\n"); + error = ENOSPC; + goto out; + } } if (!ari_enabled && PCI_RID2SLOT(last_rid) != 0) { @@ -786,6 +793,11 @@ out: } } + if (iov->iov_bus_res != NULL) { + bus_release_resource(bus, iov->iov_bus_res); + iov->iov_bus_res = NULL; + } + if (iov->iov_flags & IOV_RMAN_INITED) { rman_fini(&iov->rman); iov->iov_flags &= ~IOV_RMAN_INITED; @@ -896,6 +908,11 @@ pci_iov_delete_iov_children(struct pci_devinfo *dinfo) } } + if (iov->iov_bus_res != NULL) { + bus_release_resource(bus, iov->iov_bus_res); + iov->iov_bus_res = NULL; + } + if (iov->iov_flags & IOV_RMAN_INITED) { rman_fini(&iov->rman); iov->iov_flags &= ~IOV_RMAN_INITED; diff --git a/sys/dev/pci/pci_iov_private.h b/sys/dev/pci/pci_iov_private.h index 7ae2219b936d..ecf0a9b21be5 100644 --- a/sys/dev/pci/pci_iov_private.h +++ b/sys/dev/pci/pci_iov_private.h @@ -39,6 +39,8 @@ struct pcicfg_iov { struct cdev *iov_cdev; nvlist_t *iov_schema; + struct resource *iov_bus_res; + struct pci_iov_bar iov_bar[PCIR_MAX_BAR_0 + 1]; struct rman rman; char rman_name[64]; 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..e382b22fed74 100644 --- a/sys/fs/nfs/nfs_commonport.c +++ b/sys/fs/nfs/nfs_commonport.c @@ -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/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..9e1a198bf34a 100644 --- a/sys/fs/nfsserver/nfs_nfsdport.c +++ b/sys/fs/nfsserver/nfs_nfsdport.c @@ -3463,6 +3463,7 @@ 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 diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c index d4529e096929..7ef1d19f0ea8 100644 --- a/sys/kern/kern_jail.c +++ b/sys/kern/kern_jail.c @@ -3466,7 +3466,7 @@ prison_check_af(struct ucred *cred, int af) pr = cred->cr_prison; #ifdef VIMAGE /* Prisons with their own network stack are not limited. */ - if (prison_owns_vnet(cred)) + if (prison_owns_vnet(pr)) return (0); #endif @@ -3531,7 +3531,7 @@ prison_if(struct ucred *cred, const struct sockaddr *sa) KASSERT(sa != NULL, ("%s: sa is NULL", __func__)); #ifdef VIMAGE - if (prison_owns_vnet(cred)) + if (prison_owns_vnet(cred->cr_prison)) return (0); #endif @@ -3648,7 +3648,7 @@ jailed_without_vnet(struct ucred *cred) if (!jailed(cred)) return (false); #ifdef VIMAGE - if (prison_owns_vnet(cred)) + if (prison_owns_vnet(cred->cr_prison)) return (false); #endif @@ -3711,20 +3711,17 @@ getjailname(struct ucred *cred, char *name, size_t len) #ifdef VIMAGE /* - * Determine whether the prison represented by cred owns - * its vnet rather than having it inherited. - * - * Returns true in case the prison owns the vnet, false otherwise. + * Determine whether the prison owns its VNET. */ bool -prison_owns_vnet(struct ucred *cred) +prison_owns_vnet(struct prison *pr) { /* * vnets cannot be added/removed after jail creation, * so no need to lock here. */ - return ((cred->cr_prison->pr_flags & PR_VNET) != 0); + return ((pr->pr_flags & PR_VNET) != 0); } #endif @@ -4425,7 +4422,7 @@ sysctl_jail_vnet(SYSCTL_HANDLER_ARGS) #ifdef VIMAGE struct ucred *cred = req->td->td_ucred; - havevnet = jailed(cred) && prison_owns_vnet(cred); + havevnet = jailed(cred) && prison_owns_vnet(cred->cr_prison); #else havevnet = 0; #endif diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c index 0f0bc056cafd..48ab7c0b520b 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 @@ -2809,12 +2833,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 +2845,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) { @@ -2876,7 +2896,7 @@ crsetgroups_internal(struct ucred *cr, int ngrp, const gid_t *groups) * 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,8 +2904,8 @@ 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; /* * 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 @@ -2893,6 +2913,9 @@ crsetgroups(struct ucred *cr, int ngrp, const gid_t *groups) * consider the old ones thrown away. */ cr->cr_ngroups = 0; + if (ngrp == 0) + return; + crextend(cr, ngrp); crsetgroups_internal(cr, ngrp, groups); groups_normalize(&cr->cr_ngroups, cr->cr_groups); @@ -2902,18 +2925,22 @@ crsetgroups(struct ucred *cr, int ngrp, const gid_t *groups) * Same as crsetgroups() but accepts an empty groups array. * * 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 fallback, 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) { - if (ngrp == 0) - /* Shortcut. */ - crsetgroups_internal(cr, 1, &fallback); - else - crsetgroups(cr, ngrp, groups); + if (ngrp == 0) { + cr->cr_gid = fallback; + cr->cr_ngroups = 0; + return; + } + + crsetgroups(cr, ngrp - 1, groups + 1); + cr->cr_gid = groups[0]; } /* diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index 46226cc31980..25da134661e9 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -2368,7 +2368,7 @@ sysctl_root(SYSCTL_HANDLER_ARGS) priv = PRIV_SYSCTL_WRITEJAIL; #ifdef VIMAGE else if ((oid->oid_kind & CTLFLAG_VNET) && - prison_owns_vnet(req->td->td_ucred)) + prison_owns_vnet(req->td->td_ucred->cr_prison)) priv = PRIV_SYSCTL_WRITEJAIL; #endif else diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c index f853af193016..50b040132396 100644 --- a/sys/kern/kern_thread.c +++ b/sys/kern/kern_thread.c @@ -571,7 +571,7 @@ threadinit(void) /* * Thread structures are specially aligned so that (at least) the - * 5 lower bits of a pointer to 'struct thead' must be 0. These bits + * 5 lower bits of a pointer to 'struct thread' must be 0. These bits * are used by synchronization primitives to store flags in pointers to * such structures. */ diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c index b472aaea89e6..5606b36f772f 100644 --- a/sys/kern/sys_generic.c +++ b/sys/kern/sys_generic.c @@ -2269,6 +2269,7 @@ exterr_copyout(struct thread *td) ue.error = 0; sz = sizeof(ue.error); } else { + ktrexterr(td); sz = sizeof(ue) - __offsetof(struct uexterror, error); } error = copyout(&ue.error, uloc, sz); @@ -2335,7 +2336,6 @@ exterr_set(int eerror, int category, const char *mmsg, uintptr_t pp1, td->td_kexterr.p1 = pp1; td->td_kexterr.p2 = pp2; td->td_kexterr.src_line = line; - ktrexterr(td); } return (eerror); } 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/net/if_bridge.c b/sys/net/if_bridge.c index 5b3ee740d75e..0a35fb4095fb 100644 --- a/sys/net/if_bridge.c +++ b/sys/net/if_bridge.c @@ -76,31 +76,34 @@ * heterogeneous bridges). */ -#include <sys/cdefs.h> #include "opt_inet.h" #include "opt_inet6.h" +#define EXTERR_CATEGORY EXTERR_CAT_BRIDGE + #include <sys/param.h> +#include <sys/ctype.h> /* string functions */ #include <sys/eventhandler.h> -#include <sys/mbuf.h> +#include <sys/exterrvar.h> +#include <sys/jail.h> +#include <sys/kernel.h> +#include <sys/lock.h> #include <sys/malloc.h> +#include <sys/mbuf.h> +#include <sys/module.h> +#include <sys/mutex.h> +#include <sys/priv.h> +#include <sys/proc.h> #include <sys/protosw.h> +#include <sys/random.h> #include <sys/systm.h> -#include <sys/jail.h> -#include <sys/time.h> #include <sys/socket.h> /* for net/if.h */ #include <sys/sockio.h> -#include <sys/ctype.h> /* string functions */ -#include <sys/kernel.h> -#include <sys/random.h> #include <sys/syslog.h> #include <sys/sysctl.h> +#include <sys/time.h> + #include <vm/uma.h> -#include <sys/module.h> -#include <sys/priv.h> -#include <sys/proc.h> -#include <sys/lock.h> -#include <sys/mutex.h> #include <net/bpf.h> #include <net/if.h> @@ -254,8 +257,8 @@ struct bridge_iflist { uint32_t bif_addrcnt; /* cur. # of addresses */ uint32_t bif_addrexceeded;/* # of address violations */ struct epoch_context bif_epoch_ctx; - ether_vlanid_t bif_untagged; /* untagged vlan id */ - ifbvlan_set_t bif_vlan_set; /* allowed tagged vlans */ + ether_vlanid_t bif_pvid; /* port vlan id */ + ifbvlan_set_t bif_vlan_set; /* if allowed tagged vlans */ }; /* @@ -404,7 +407,7 @@ static int bridge_ioctl_sma(struct bridge_softc *, void *); static int bridge_ioctl_sifprio(struct bridge_softc *, void *); static int bridge_ioctl_sifcost(struct bridge_softc *, void *); static int bridge_ioctl_sifmaxaddr(struct bridge_softc *, void *); -static int bridge_ioctl_sifuntagged(struct bridge_softc *, void *); +static int bridge_ioctl_sifpvid(struct bridge_softc *, void *); static int bridge_ioctl_sifvlanset(struct bridge_softc *, void *); static int bridge_ioctl_gifvlanset(struct bridge_softc *, void *); static int bridge_ioctl_addspan(struct bridge_softc *, void *); @@ -625,7 +628,7 @@ static const struct bridge_control bridge_control_table[] = { { bridge_ioctl_sifmaxaddr, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_SUSER }, - { bridge_ioctl_sifuntagged, sizeof(struct ifbreq), + { bridge_ioctl_sifpvid, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_SUSER }, { bridge_ioctl_sifvlanset, sizeof(struct ifbif_vlan_req), @@ -986,31 +989,37 @@ bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) case SIOCGDRVSPEC: case SIOCSDRVSPEC: if (ifd->ifd_cmd >= bridge_control_table_size) { - error = EINVAL; + error = EXTERROR(EINVAL, "Invalid control command"); break; } bc = &bridge_control_table[ifd->ifd_cmd]; if (cmd == SIOCGDRVSPEC && (bc->bc_flags & BC_F_COPYOUT) == 0) { - error = EINVAL; + error = EXTERROR(EINVAL, + "Inappropriate ioctl for command " + "(expected SIOCSDRVSPEC)"); break; } else if (cmd == SIOCSDRVSPEC && (bc->bc_flags & BC_F_COPYOUT) != 0) { - error = EINVAL; + error = EXTERROR(EINVAL, + "Inappropriate ioctl for command " + "(expected SIOCGDRVSPEC)"); break; } if (bc->bc_flags & BC_F_SUSER) { error = priv_check(td, PRIV_NET_BRIDGE); - if (error) + if (error) { + EXTERROR(error, "PRIV_NET_BRIDGE required"); break; + } } if (ifd->ifd_len != bc->bc_argsize || ifd->ifd_len > sizeof(args)) { - error = EINVAL; + error = EXTERROR(EINVAL, "Invalid argument size"); break; } @@ -1062,7 +1071,8 @@ bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) oldmtu = sc->sc_ifp->if_mtu; if (ifr->ifr_mtu < IF_MINMTU) { - error = EINVAL; + error = EXTERROR(EINVAL, + "Requested MTU is lower than IF_MINMTU"); break; } if (CK_LIST_EMPTY(&sc->sc_iflist)) { @@ -1088,6 +1098,8 @@ bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) (*bif->bif_ifp->if_ioctl)(bif->bif_ifp, SIOCSIFMTU, (caddr_t)ifr); } + EXTERROR(error, + "Failed to set MTU on member interface"); } else { sc->sc_ifp->if_mtu = ifr->ifr_mtu; } @@ -1125,14 +1137,14 @@ bridge_mutecaps(struct bridge_softc *sc) mask = BRIDGE_IFCAPS_MASK; CK_LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { - /* Every member must support it or its disabled */ + /* Every member must support it or it's disabled */ mask &= bif->bif_savedcaps; } CK_LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { enabled = bif->bif_ifp->if_capenable; enabled &= ~BRIDGE_IFCAPS_STRIP; - /* strip off mask bits and enable them again if allowed */ + /* Strip off mask bits and enable them again if allowed */ enabled &= ~BRIDGE_IFCAPS_MASK; enabled |= mask; bridge_set_ifcap(sc, bif, enabled); @@ -1282,7 +1294,7 @@ bridge_delete_member(struct bridge_softc *sc, struct bridge_iflist *bif, #endif break; } - /* reneable any interface capabilities */ + /* Re-enable any interface capabilities */ bridge_set_ifcap(sc, bif, bif->bif_savedcaps); } bstp_destroy(&bif->bif_stp); /* prepare to free */ @@ -1318,21 +1330,48 @@ bridge_ioctl_add(struct bridge_softc *sc, void *arg) ifs = ifunit(req->ifbr_ifsname); if (ifs == NULL) - return (ENOENT); + return (EXTERROR(ENOENT, "No such interface", + req->ifbr_ifsname)); if (ifs->if_ioctl == NULL) /* must be supported */ - return (EINVAL); + return (EXTERROR(EINVAL, "Interface must support ioctl(2)")); + + /* + * If the new interface is a vlan(4), it could be a bridge SVI. + * Don't allow such things to be added to bridges. + */ + if (ifs->if_type == IFT_L2VLAN) { + struct ifnet *parent; + struct epoch_tracker et; + bool is_bridge; + + /* + * Entering NET_EPOCH with BRIDGE_LOCK held, but this is okay + * since we don't sleep here. + */ + NET_EPOCH_ENTER(et); + parent = VLAN_TRUNKDEV(ifs); + is_bridge = (parent != NULL && parent->if_type == IFT_BRIDGE); + NET_EPOCH_EXIT(et); + + if (is_bridge) + return (EXTERROR(EINVAL, + "Bridge SVI cannot be added to a bridge")); + } /* If it's in the span list, it can't be a member. */ CK_LIST_FOREACH(bif, &sc->sc_spanlist, bif_next) if (ifs == bif->bif_ifp) - return (EBUSY); + return (EXTERROR(EBUSY, + "Span interface cannot be a member")); if (ifs->if_bridge) { struct bridge_iflist *sbif = ifs->if_bridge; if (sbif->bif_sc == sc) - return (EEXIST); + return (EXTERROR(EEXIST, + "Interface is already a member of this bridge")); - return (EBUSY); + return (EXTERROR(EBUSY, + "Interface is already a member of another bridge")); } switch (ifs->if_type) { @@ -1342,7 +1381,7 @@ bridge_ioctl_add(struct bridge_softc *sc, void *arg) /* permitted interface types */ break; default: - return (EINVAL); + return (EXTERROR(EINVAL, "Unsupported interface type")); } #ifdef INET6 @@ -1394,11 +1433,15 @@ bridge_ioctl_add(struct bridge_softc *sc, void *arg) CK_STAILQ_FOREACH(ifa, &ifs->if_addrhead, ifa_link) { #ifdef INET if (ifa->ifa_addr->sa_family == AF_INET) - return (EINVAL); + return (EXTERROR(EINVAL, + "Member interface may not have " + "an IPv4 address configured")); #endif #ifdef INET6 if (ifa->ifa_addr->sa_family == AF_INET6) - return (EINVAL); + return (EXTERROR(EINVAL, + "Member interface may not have " + "an IPv6 address configured")); #endif } } @@ -1420,7 +1463,8 @@ bridge_ioctl_add(struct bridge_softc *sc, void *arg) " new member %s\n", sc->sc_ifp->if_xname, ifr.ifr_mtu, ifs->if_xname); - return (EINVAL); + return (EXTERROR(EINVAL, + "Failed to set MTU on new member")); } } @@ -1482,7 +1526,7 @@ bridge_ioctl_del(struct bridge_softc *sc, void *arg) bif = bridge_lookup_member(sc, req->ifbr_ifsname); if (bif == NULL) - return (ENOENT); + return (EXTERROR(ENOENT, "Interface is not a bridge member")); bridge_delete_member(sc, bif, 0); @@ -1498,7 +1542,7 @@ bridge_ioctl_gifflags(struct bridge_softc *sc, void *arg) bif = bridge_lookup_member(sc, req->ifbr_ifsname); if (bif == NULL) - return (ENOENT); + return (EXTERROR(ENOENT, "Interface is not a bridge member")); bp = &bif->bif_stp; req->ifbr_ifsflags = bif->bif_flags; @@ -1512,7 +1556,7 @@ bridge_ioctl_gifflags(struct bridge_softc *sc, void *arg) req->ifbr_addrcnt = bif->bif_addrcnt; req->ifbr_addrmax = bif->bif_addrmax; req->ifbr_addrexceeded = bif->bif_addrexceeded; - req->ifbr_untagged = bif->bif_untagged; + req->ifbr_pvid = bif->bif_pvid; /* Copy STP state options as flags */ if (bp->bp_operedge) @@ -1541,12 +1585,12 @@ bridge_ioctl_sifflags(struct bridge_softc *sc, void *arg) bif = bridge_lookup_member(sc, req->ifbr_ifsname); if (bif == NULL) - return (ENOENT); + return (EXTERROR(ENOENT, "Interface is not a bridge member")); bp = &bif->bif_stp; if (req->ifbr_ifsflags & IFBIF_SPAN) /* SPAN is readonly */ - return (EINVAL); + return (EXTERROR(EINVAL, "Span interface cannot be modified")); NET_EPOCH_ENTER(et); @@ -1555,7 +1599,8 @@ bridge_ioctl_sifflags(struct bridge_softc *sc, void *arg) error = bstp_enable(&bif->bif_stp); if (error) { NET_EPOCH_EXIT(et); - return (error); + return (EXTERROR(error, + "Failed to enable STP")); } } } else { @@ -1724,7 +1769,7 @@ bridge_ioctl_saddr(struct bridge_softc *sc, void *arg) bif = bridge_lookup_member(sc, req->ifba_ifsname); if (bif == NULL) { NET_EPOCH_EXIT(et); - return (ENOENT); + return (EXTERROR(ENOENT, "Interface is not a bridge member")); } /* bridge_rtupdate() may acquire the lock. */ @@ -1858,7 +1903,7 @@ bridge_ioctl_sifprio(struct bridge_softc *sc, void *arg) bif = bridge_lookup_member(sc, req->ifbr_ifsname); if (bif == NULL) - return (ENOENT); + return (EXTERROR(ENOENT, "Interface is not a bridge member")); return (bstp_set_port_priority(&bif->bif_stp, req->ifbr_priority)); } @@ -1871,7 +1916,7 @@ bridge_ioctl_sifcost(struct bridge_softc *sc, void *arg) bif = bridge_lookup_member(sc, req->ifbr_ifsname); if (bif == NULL) - return (ENOENT); + return (EXTERROR(ENOENT, "Interface is not a bridge member")); return (bstp_set_path_cost(&bif->bif_stp, req->ifbr_path_cost)); } @@ -1884,28 +1929,28 @@ bridge_ioctl_sifmaxaddr(struct bridge_softc *sc, void *arg) bif = bridge_lookup_member(sc, req->ifbr_ifsname); if (bif == NULL) - return (ENOENT); + return (EXTERROR(ENOENT, "Interface is not a bridge member")); bif->bif_addrmax = req->ifbr_addrmax; return (0); } static int -bridge_ioctl_sifuntagged(struct bridge_softc *sc, void *arg) +bridge_ioctl_sifpvid(struct bridge_softc *sc, void *arg) { struct ifbreq *req = arg; struct bridge_iflist *bif; bif = bridge_lookup_member(sc, req->ifbr_ifsname); if (bif == NULL) - return (ENOENT); + return (EXTERROR(ENOENT, "Interface is not a bridge member")); - if (req->ifbr_untagged > DOT1Q_VID_MAX) - return (EINVAL); + if (req->ifbr_pvid > DOT1Q_VID_MAX) + return (EXTERROR(EINVAL, "Invalid VLAN ID")); - if (req->ifbr_untagged != DOT1Q_VID_NULL) + if (req->ifbr_pvid != DOT1Q_VID_NULL) bif->bif_flags |= IFBIF_VLANFILTER; - bif->bif_untagged = req->ifbr_untagged; + bif->bif_pvid = req->ifbr_pvid; return (0); } @@ -1917,12 +1962,12 @@ bridge_ioctl_sifvlanset(struct bridge_softc *sc, void *arg) bif = bridge_lookup_member(sc, req->bv_ifname); if (bif == NULL) - return (ENOENT); + return (EXTERROR(ENOENT, "Interface is not a bridge member")); /* Reject invalid VIDs. */ if (BRVLAN_TEST(&req->bv_set, DOT1Q_VID_NULL) || BRVLAN_TEST(&req->bv_set, DOT1Q_VID_RSVD_IMPL)) - return (EINVAL); + return (EXTERROR(EINVAL, "Invalid VLAN ID in set")); switch (req->bv_op) { /* Replace the existing vlan set with the new set */ @@ -1942,7 +1987,8 @@ bridge_ioctl_sifvlanset(struct bridge_softc *sc, void *arg) /* Invalid or unknown operation */ default: - return (EINVAL); + return (EXTERROR(EINVAL, + "Unsupported BRDGSIFVLANSET operation")); } /* @@ -1962,7 +2008,7 @@ bridge_ioctl_gifvlanset(struct bridge_softc *sc, void *arg) bif = bridge_lookup_member(sc, req->bv_ifname); if (bif == NULL) - return (ENOENT); + return (EXTERROR(ENOENT, "Interface is not a bridge member")); BIT_COPY(BRVLAN_SETSIZE, &bif->bif_vlan_set, &req->bv_set); return (0); @@ -1977,14 +2023,16 @@ bridge_ioctl_addspan(struct bridge_softc *sc, void *arg) ifs = ifunit(req->ifbr_ifsname); if (ifs == NULL) - return (ENOENT); + return (EXTERROR(ENOENT, "No such interface")); CK_LIST_FOREACH(bif, &sc->sc_spanlist, bif_next) if (ifs == bif->bif_ifp) - return (EBUSY); + return (EXTERROR(EBUSY, + "Interface is already a span port")); if (ifs->if_bridge != NULL) - return (EBUSY); + return (EXTERROR(EEXIST, + "Interface is already a bridge member")); switch (ifs->if_type) { case IFT_ETHER: @@ -1992,7 +2040,7 @@ bridge_ioctl_addspan(struct bridge_softc *sc, void *arg) case IFT_L2VLAN: break; default: - return (EINVAL); + return (EXTERROR(EINVAL, "Unsupported interface type")); } bif = malloc(sizeof(*bif), M_DEVBUF, M_NOWAIT|M_ZERO); @@ -2016,14 +2064,14 @@ bridge_ioctl_delspan(struct bridge_softc *sc, void *arg) ifs = ifunit(req->ifbr_ifsname); if (ifs == NULL) - return (ENOENT); + return (EXTERROR(ENOENT, "No such interface")); CK_LIST_FOREACH(bif, &sc->sc_spanlist, bif_next) if (ifs == bif->bif_ifp) break; if (bif == NULL) - return (ENOENT); + return (EXTERROR(ENOENT, "Interface is not a span port")); bridge_delete_span(sc, bif); @@ -2278,8 +2326,8 @@ bridge_enqueue(struct bridge_softc *sc, struct ifnet *dst_ifp, struct mbuf *m, * the VLAN header. */ if ((bif->bif_flags & IFBIF_VLANFILTER) && - bif->bif_untagged != DOT1Q_VID_NULL && - VLANTAGOF(m) == bif->bif_untagged) { + bif->bif_pvid != DOT1Q_VID_NULL && + VLANTAGOF(m) == bif->bif_pvid) { m->m_flags &= ~M_VLANTAG; m->m_pkthdr.ether_vtag = 0; } @@ -3145,14 +3193,14 @@ bridge_vfilter_in(const struct bridge_iflist *sbif, struct mbuf *m) * The frame doesn't have a tag. If the interface does not * have an untagged vlan configured, drop the frame. */ - if (sbif->bif_untagged == DOT1Q_VID_NULL) + if (sbif->bif_pvid == DOT1Q_VID_NULL) return (false); /* * Otherwise, insert a new tag based on the interface's * untagged vlan id. */ - m->m_pkthdr.ether_vtag = sbif->bif_untagged; + m->m_pkthdr.ether_vtag = sbif->bif_pvid; m->m_flags |= M_VLANTAG; } else { /* @@ -3213,7 +3261,7 @@ bridge_vfilter_out(const struct bridge_iflist *dbif, const struct mbuf *m) * If the frame's vlan matches the interfaces's untagged vlan, * allow it. */ - if (vlan == dbif->bif_untagged) + if (vlan == dbif->bif_pvid) return (true); /* @@ -3244,10 +3292,11 @@ bridge_rtupdate(struct bridge_softc *sc, const uint8_t *dst, BRIDGE_LOCK_OR_NET_EPOCH_ASSERT(sc); /* Check the source address is valid and not multicast. */ - if (ETHER_IS_MULTICAST(dst) || - (dst[0] == 0 && dst[1] == 0 && dst[2] == 0 && - dst[3] == 0 && dst[4] == 0 && dst[5] == 0) != 0) - return (EINVAL); + if (ETHER_IS_MULTICAST(dst)) + return (EXTERROR(EINVAL, "Multicast address not permitted")); + if (dst[0] == 0 && dst[1] == 0 && dst[2] == 0 && + dst[3] == 0 && dst[4] == 0 && dst[5] == 0) + return (EXTERROR(EINVAL, "Zero address not permitted")); /* * A route for this destination might already exist. If so, @@ -3266,13 +3315,14 @@ bridge_rtupdate(struct bridge_softc *sc, const uint8_t *dst, if (sc->sc_brtcnt >= sc->sc_brtmax) { sc->sc_brtexceeded++; BRIDGE_RT_UNLOCK(sc); - return (ENOSPC); + return (EXTERROR(ENOSPC, "Address table is full")); } /* Check per interface address limits (if enabled) */ if (bif->bif_addrmax && bif->bif_addrcnt >= bif->bif_addrmax) { bif->bif_addrexceeded++; BRIDGE_RT_UNLOCK(sc); - return (ENOSPC); + return (EXTERROR(ENOSPC, + "Interface address limit exceeded")); } /* @@ -3283,7 +3333,8 @@ bridge_rtupdate(struct bridge_softc *sc, const uint8_t *dst, brt = uma_zalloc(V_bridge_rtnode_zone, M_NOWAIT | M_ZERO); if (brt == NULL) { BRIDGE_RT_UNLOCK(sc); - return (ENOMEM); + return (EXTERROR(ENOMEM, + "Cannot allocate address node")); } brt->brt_vnet = curvnet; @@ -3631,7 +3682,7 @@ bridge_rtnode_insert(struct bridge_softc *sc, struct bridge_rtnode *brt) do { dir = bridge_rtnode_addr_cmp(brt->brt_addr, lbrt->brt_addr); if (dir == 0 && brt->brt_vlan == lbrt->brt_vlan) - return (EEXIST); + return (EXTERROR(EEXIST, "Address already exists")); if (dir > 0) { CK_LIST_INSERT_BEFORE(lbrt, brt, brt_hash); goto out; diff --git a/sys/net/if_bridgevar.h b/sys/net/if_bridgevar.h index 97b63e3d4416..c458dcc152a0 100644 --- a/sys/net/if_bridgevar.h +++ b/sys/net/if_bridgevar.h @@ -124,7 +124,7 @@ #define BRDGSPROTO 28 /* set protocol (ifbrparam) */ #define BRDGSTXHC 29 /* set tx hold count (ifbrparam) */ #define BRDGSIFAMAX 30 /* set max interface addrs (ifbreq) */ -#define BRDGSIFUNTAGGED 31 /* set if untagged vlan */ +#define BRDGSIFPVID 31 /* set if PVID */ #define BRDGSIFVLANSET 32 /* set if vlan set */ #define BRDGGIFVLANSET 33 /* get if vlan set */ @@ -144,7 +144,7 @@ struct ifbreq { uint32_t ifbr_addrcnt; /* member if addr number */ uint32_t ifbr_addrmax; /* member if addr max */ uint32_t ifbr_addrexceeded; /* member if addr violations */ - ether_vlanid_t ifbr_untagged; /* member if untagged vlan */ + ether_vlanid_t ifbr_pvid; /* member if PVID */ uint8_t pad[32]; }; diff --git a/sys/net/if_ovpn.c b/sys/net/if_ovpn.c index 853a0556a080..fe3e7bbd7fff 100644 --- a/sys/net/if_ovpn.c +++ b/sys/net/if_ovpn.c @@ -34,11 +34,13 @@ #include <sys/epoch.h> #include <sys/file.h> #include <sys/filedesc.h> +#include <sys/jail.h> #include <sys/kernel.h> #include <sys/malloc.h> #include <sys/mbuf.h> #include <sys/module.h> #include <sys/nv.h> +#include <sys/osd.h> #include <sys/priv.h> #include <sys/protosw.h> #include <sys/rmlock.h> @@ -131,6 +133,9 @@ struct ovpn_notification { /* Delete notification */ enum ovpn_del_reason del_reason; struct ovpn_peer_counters counters; + + /* Float notification */ + struct sockaddr_storage address; }; struct ovpn_softc; @@ -195,6 +200,10 @@ struct ovpn_softc { struct epoch_context epoch_ctx; }; +struct ovpn_mtag { + struct sockaddr_storage addr; +}; + static struct ovpn_kpeer *ovpn_find_peer(struct ovpn_softc *, uint32_t); static bool ovpn_udp_input(struct mbuf *, int, struct inpcb *, const struct sockaddr *, void *); @@ -206,6 +215,8 @@ static void ovpn_free_kkey_dir(struct ovpn_kkey_dir *); static bool ovpn_check_replay(struct ovpn_kkey_dir *, uint32_t); static int ovpn_peer_compare(const struct ovpn_kpeer *, const struct ovpn_kpeer *); +static bool ovpn_sockaddr_compare(const struct sockaddr *, + const struct sockaddr *); static RB_PROTOTYPE(ovpn_kpeers, ovpn_kpeer, tree, ovpn_peer_compare); static RB_GENERATE(ovpn_kpeers, ovpn_kpeer, tree, ovpn_peer_compare); @@ -283,6 +294,43 @@ ovpn_peer_compare(const struct ovpn_kpeer *a, const struct ovpn_kpeer *b) return (a->peerid - b->peerid); } +static bool +ovpn_sockaddr_compare(const struct sockaddr *a, + const struct sockaddr *b) +{ + if (a->sa_family != b->sa_family) + return (false); + MPASS(a->sa_len == b->sa_len); + + switch (a->sa_family) { + case AF_INET: { + const struct sockaddr_in *a4, *b4; + + a4 = (const struct sockaddr_in *)a; + b4 = (const struct sockaddr_in *)b; + + if (a4->sin_port != b4->sin_port) + return (false); + + return (a4->sin_addr.s_addr == b4->sin_addr.s_addr); + } + case AF_INET6: { + const struct sockaddr_in6 *a6, *b6; + + a6 = (const struct sockaddr_in6 *)a; + b6 = (const struct sockaddr_in6 *)b; + + if (a6->sin6_port != b6->sin6_port) + return (false); + + return (memcmp(&a6->sin6_addr, &b6->sin6_addr, + sizeof(a6->sin6_addr)) == 0); + } + default: + panic("Unknown address family %d", a->sa_family); + } +} + static struct ovpn_kpeer * ovpn_find_peer(struct ovpn_softc *sc, uint32_t peerid) { @@ -394,6 +442,44 @@ ovpn_nvlist_to_sockaddr(const nvlist_t *nvl, struct sockaddr_storage *sa) return (0); } +static int +ovpn_add_sockaddr(nvlist_t *parent, const char *name, const struct sockaddr *s) +{ + nvlist_t *nvl; + + nvl = nvlist_create(0); + if (nvl == NULL) + return (ENOMEM); + + nvlist_add_number(nvl, "af", s->sa_family); + + switch (s->sa_family) { + case AF_INET: { + const struct sockaddr_in *s4 = (const struct sockaddr_in *)s; + + nvlist_add_number(nvl, "port", s4->sin_port); + nvlist_add_binary(nvl, "address", &s4->sin_addr, + sizeof(s4->sin_addr)); + break; + } + case AF_INET6: { + const struct sockaddr_in6 *s6 = (const struct sockaddr_in6 *)s; + + nvlist_add_number(nvl, "port", s6->sin6_port); + nvlist_add_binary(nvl, "address", &s6->sin6_addr, + sizeof(s6->sin6_addr)); + break; + } + default: + nvlist_destroy(nvl); + return (EINVAL); + } + + nvlist_move_nvlist(parent, name, nvl); + + return (0); +} + static void ovpn_notify_del_peer(struct ovpn_softc *sc, struct ovpn_kpeer *peer) { @@ -446,6 +532,33 @@ ovpn_notify_key_rotation(struct ovpn_softc *sc, struct ovpn_kpeer *peer) } } +static int +ovpn_notify_float(struct ovpn_softc *sc, uint32_t peerid, + const struct sockaddr_storage *remote) +{ + struct ovpn_notification *n; + + n = malloc(sizeof(*n), M_OVPN, M_NOWAIT | M_ZERO); + if (n == NULL) + return (ENOMEM); + + n->peerid = peerid; + n->type = OVPN_NOTIF_FLOAT; + memcpy(&n->address, remote, sizeof(n->address)); + + if (buf_ring_enqueue(sc->notifring, n) != 0) { + free(n, M_OVPN); + return (ENOMEM); + } else if (sc->so != NULL) { + /* Wake up userspace */ + sc->so->so_error = EAGAIN; + sorwakeup(sc->so); + sowwakeup(sc->so); + } + + return (0); +} + static void ovpn_peer_release_ref(struct ovpn_kpeer *peer, bool locked) { @@ -1377,12 +1490,36 @@ opvn_get_pkt(struct ovpn_softc *sc, nvlist_t **onvl) } nvlist_add_number(nvl, "peerid", n->peerid); nvlist_add_number(nvl, "notification", n->type); - if (n->type == OVPN_NOTIF_DEL_PEER) { + switch (n->type) { + case OVPN_NOTIF_DEL_PEER: { nvlist_add_number(nvl, "del_reason", n->del_reason); /* No error handling, because we want to send the notification * even if we can't attach the counters. */ ovpn_notif_add_counters(nvl, n); + break; + } + case OVPN_NOTIF_FLOAT: { + int ret; + + ret = ovpn_add_sockaddr(nvl, "address", + (struct sockaddr *)&n->address); + + if (ret) { + /* + * Try to re-enqueue the notification. Maybe we'll + * have better luck next time. No error handling, + * because if we fail to re-enqueue there's nothing we can do. + */ + (void)ovpn_notify_float(sc, n->peerid, &n->address); + nvlist_destroy(nvl); + free(n, M_OVPN); + return (ret); + } + break; + } + default: + break; } free(n, M_OVPN); @@ -1538,6 +1675,7 @@ ovpn_finish_rx(struct ovpn_softc *sc, struct mbuf *m, struct rm_priotracker *_ovpn_lock_trackerp) { uint32_t af; + struct m_tag *mtag; OVPN_RASSERT(sc); NET_EPOCH_ASSERT(); @@ -1556,6 +1694,38 @@ ovpn_finish_rx(struct ovpn_softc *sc, struct mbuf *m, OVPN_RUNLOCK(sc); + /* Check if the peer changed to a new source address. */ + mtag = m_tag_find(m, PACKET_TAG_OVPN, NULL); + if (mtag != NULL) { + struct ovpn_mtag *ot = (struct ovpn_mtag *)(mtag + 1); + + OVPN_WLOCK(sc); + + /* + * Check the address against the peer's remote again, because we may race + * against ourselves (i.e. we may have tagged multiple packets to indicate we + * floated). + */ + if (ovpn_sockaddr_compare((struct sockaddr *)&ot->addr, + (struct sockaddr *)&peer->remote)) { + OVPN_WUNLOCK(sc); + goto skip_float; + } + + /* And notify userspace. */ + if (ovpn_notify_float(sc, peer->peerid, &ot->addr) == 0) { + /* + * Update the 'remote' for this peer, but only if + * we've actually enqueued the notification. + * Otherwise we can try again later. + */ + memcpy(&peer->remote, &ot->addr, sizeof(peer->remote)); + } + + OVPN_WUNLOCK(sc); + } + +skip_float: OVPN_COUNTER_ADD(sc, received_data_pkts, 1); OVPN_COUNTER_ADD(sc, tunnel_bytes_received, m->m_pkthdr.len); OVPN_PEER_COUNTER_ADD(peer, pkt_in, 1); @@ -2318,6 +2488,29 @@ ovpn_udp_input(struct mbuf *m, int off, struct inpcb *inp, return (true); } + /* + * If we got this from a different address than we expected tag the packet. + * We'll deal with notifiying userspace later, after we've decrypted and + * verified. + */ + if (! ovpn_sockaddr_compare((struct sockaddr *)&peer->remote, sa)) { + struct m_tag *mt; + struct ovpn_mtag *ot; + + MPASS(sa->sa_len <= sizeof(ot->addr)); + mt = m_tag_get(PACKET_TAG_OVPN, sizeof(*ot), M_NOWAIT); + /* + * If we fail to allocate here we'll just try again on the next + * packet. + */ + if (mt != NULL) { + ot = (struct ovpn_mtag *)(mt + 1); + memcpy(&ot->addr, sa, sa->sa_len); + + m_tag_prepend(m, mt); + } + } + if (key->decrypt->cipher == OVPN_CIPHER_ALG_NONE) { /* Now remove the outer headers */ m_adj_decap(m, sizeof(struct udphdr) + ohdrlen); @@ -2593,23 +2786,53 @@ vnet_ovpn_init(const void *unused __unused) VNET_SYSINIT(vnet_ovpn_init, SI_SUB_PSEUDO, SI_ORDER_ANY, vnet_ovpn_init, NULL); -static void -vnet_ovpn_uninit(const void *unused __unused) +static int +ovpn_prison_remove(void *obj, void *data __unused) { - if_clone_detach(V_ovpn_cloner); +#ifdef VIMAGE + struct prison *pr; + + pr = obj; + if (prison_owns_vnet(pr)) { + CURVNET_SET(pr->pr_vnet); + if (V_ovpn_cloner != NULL) { + ifc_detach_cloner(V_ovpn_cloner); + V_ovpn_cloner = NULL; + } + CURVNET_RESTORE(); + } +#endif + return (0); } -VNET_SYSUNINIT(vnet_ovpn_uninit, SI_SUB_PSEUDO, SI_ORDER_ANY, - vnet_ovpn_uninit, NULL); static int ovpnmodevent(module_t mod, int type, void *data) { + static int ovpn_osd_jail_slot; + switch (type) { - case MOD_LOAD: - /* Done in vnet_ovpn_init() */ + case MOD_LOAD: { + /* + * Registration is handled in vnet_ovpn_init(), but cloned + * interfaces must be destroyed via PR_METHOD_REMOVE since they + * hold a reference to the prison via the UDP socket, which + * prevents the prison from being destroyed. + */ + osd_method_t methods[PR_MAXMETHOD] = { + [PR_METHOD_REMOVE] = ovpn_prison_remove, + }; + ovpn_osd_jail_slot = osd_jail_register(NULL, methods); break; + } case MOD_UNLOAD: - /* Done in vnet_ovpn_uninit() */ + if (ovpn_osd_jail_slot != 0) + osd_jail_deregister(ovpn_osd_jail_slot); + CURVNET_SET(vnet0); + if (V_ovpn_cloner != NULL) { + ifc_detach_cloner(V_ovpn_cloner); + V_ovpn_cloner = NULL; + } + CURVNET_RESTORE(); break; default: return (EOPNOTSUPP); diff --git a/sys/net/if_ovpn.h b/sys/net/if_ovpn.h index 2d6b8c1e7eff..2a24c35788a9 100644 --- a/sys/net/if_ovpn.h +++ b/sys/net/if_ovpn.h @@ -37,6 +37,7 @@ enum ovpn_notif_type { OVPN_NOTIF_DEL_PEER, OVPN_NOTIF_ROTATE_KEY, + OVPN_NOTIF_FLOAT, }; enum ovpn_del_reason { diff --git a/sys/net/if_tuntap.c b/sys/net/if_tuntap.c index 3bab04aa4d38..5e6f65c04b2f 100644 --- a/sys/net/if_tuntap.c +++ b/sys/net/if_tuntap.c @@ -74,6 +74,7 @@ #include <sys/malloc.h> #include <sys/random.h> #include <sys/ctype.h> +#include <sys/osd.h> #include <net/ethernet.h> #include <net/if.h> @@ -178,6 +179,7 @@ struct tuntap_softc { static struct mtx tunmtx; static eventhandler_tag arrival_tag; static eventhandler_tag clone_tag; +static int tuntap_osd_jail_slot; static const char tunname[] = "tun"; static const char tapname[] = "tap"; static const char vmnetname[] = "vmnet"; @@ -497,6 +499,10 @@ vmnet_clone_match(struct if_clone *ifc, const char *name) return (0); } +/* + * Create a clone via the ifnet cloning mechanism. Note that this is invoked + * indirectly by tunclone() below. + */ static int tun_clone_create(struct if_clone *ifc, char *name, size_t len, struct ifc_data *ifd, struct ifnet **ifpp) @@ -532,15 +538,19 @@ tun_clone_create(struct if_clone *ifc, char *name, size_t len, if (i != 0) i = tun_create_device(drv, unit, NULL, &dev, name); if (i == 0) { - dev_ref(dev); + struct tuntap_softc *tp; + tuncreate(dev); - struct tuntap_softc *tp = dev->si_drv1; + tp = dev->si_drv1; *ifpp = tp->tun_ifp; } return (i); } +/* + * Create a clone via devfs access. + */ static void tunclone(void *arg, struct ucred *cred, char *name, int namelen, struct cdev **dev) @@ -595,11 +605,12 @@ tunclone(void *arg, struct ucred *cred, char *name, int namelen, } i = tun_create_device(drv, u, cred, dev, name); - } - if (i == 0) { + } else { + /* Consumed by the dev_clone invoker. */ dev_ref(*dev); - if_clone_create(name, namelen, NULL); } + if (i == 0) + if_clone_create(name, namelen, NULL); out: CURVNET_RESTORE(); } @@ -670,16 +681,6 @@ VNET_SYSINIT(vnet_tun_init, SI_SUB_PROTO_IF, SI_ORDER_ANY, vnet_tun_init, NULL); static void -vnet_tun_uninit(const void *unused __unused) -{ - - for (u_int i = 0; i < NDRV; ++i) - if_clone_detach(V_tuntap_driver_cloners[i]); -} -VNET_SYSUNINIT(vnet_tun_uninit, SI_SUB_PROTO_IF, SI_ORDER_ANY, - vnet_tun_uninit, NULL); - -static void tun_uninit(const void *unused __unused) { struct tuntap_driver *drv; @@ -689,6 +690,16 @@ tun_uninit(const void *unused __unused) EVENTHANDLER_DEREGISTER(ifnet_arrival_event, arrival_tag); EVENTHANDLER_DEREGISTER(dev_clone, clone_tag); + CURVNET_SET(vnet0); + for (u_int i = 0; i < NDRV; i++) { + if_clone_detach(V_tuntap_driver_cloners[i]); + V_tuntap_driver_cloners[i] = NULL; + } + CURVNET_RESTORE(); + + if (tuntap_osd_jail_slot != 0) + osd_jail_deregister(tuntap_osd_jail_slot); + mtx_lock(&tunmtx); while ((tp = TAILQ_FIRST(&tunhead)) != NULL) { TAILQ_REMOVE(&tunhead, tp, tun_list); @@ -724,6 +735,30 @@ tuntap_driver_from_ifnet(const struct ifnet *ifp) return (NULL); } +/* + * Remove devices that were created by devfs cloning, as they hold references + * which prevent the prison from collapsing, in which state VNET sysuninits will + * not be invoked. + */ +static int +tuntap_prison_remove(void *obj, void *data __unused) +{ +#ifdef VIMAGE + struct prison *pr; + + pr = obj; + if (prison_owns_vnet(pr)) { + CURVNET_SET(pr->pr_vnet); + for (u_int i = 0; i < NDRV; i++) { + if_clone_detach(V_tuntap_driver_cloners[i]); + V_tuntap_driver_cloners[i] = NULL; + } + CURVNET_RESTORE(); + } +#endif + return (0); +} + static int tuntapmodevent(module_t mod, int type, void *data) { @@ -738,8 +773,12 @@ tuntapmodevent(module_t mod, int type, void *data) clone_setup(&drv->clones); drv->unrhdr = new_unrhdr(0, IF_MAXUNIT, &tunmtx); } + osd_method_t methods[PR_MAXMETHOD] = { + [PR_METHOD_REMOVE] = tuntap_prison_remove, + }; + tuntap_osd_jail_slot = osd_jail_register(NULL, methods); arrival_tag = EVENTHANDLER_REGISTER(ifnet_arrival_event, - tunrename, 0, 1000); + tunrename, 0, 1000); if (arrival_tag == NULL) return (ENOMEM); clone_tag = EVENTHANDLER_REGISTER(dev_clone, tunclone, 0, 1000); @@ -747,7 +786,7 @@ tuntapmodevent(module_t mod, int type, void *data) return (ENOMEM); break; case MOD_UNLOAD: - /* See tun_uninit, so it's done after the vnet_sysuninit() */ + /* See tun_uninit(). */ break; default: return EOPNOTSUPP; @@ -798,6 +837,8 @@ tun_create_device(struct tuntap_driver *drv, int unit, struct ucred *cr, args.mda_si_drv1 = tp; error = make_dev_s(&args, dev, "%s", name); if (error != 0) { + mtx_destroy(&tp->tun_mtx); + cv_destroy(&tp->tun_cv); free(tp, M_TUN); return (error); } @@ -914,7 +955,6 @@ tap_transmit(struct ifnet *ifp, struct mbuf *m) return (error); } -/* XXX: should return an error code so it can fail. */ static void tuncreate(struct cdev *dev) { diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c index 22fcb7bf7c64..61000018e5a4 100644 --- a/sys/net/if_vlan.c +++ b/sys/net/if_vlan.c @@ -2336,6 +2336,18 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) error = ENOENT; break; } + + /* + * If the ifp is in a bridge, do not allow setting the device + * to a bridge; this prevents having a bridge SVI as a bridge + * member (which is not permitted). + */ + if (ifp->if_bridge != NULL && p->if_type == IFT_BRIDGE) { + if_rele(p); + error = EINVAL; + break; + } + if (vlr.vlr_proto == 0) vlr.vlr_proto = ETHERTYPE_VLAN; oldmtu = ifp->if_mtu; 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/netinet6/scope6.c b/sys/netinet6/scope6.c index 0987ea7e99ad..08702a2e81ab 100644 --- a/sys/netinet6/scope6.c +++ b/sys/netinet6/scope6.c @@ -505,8 +505,23 @@ in6_set_unicast_scopeid(struct in6_addr *in6, uint32_t scopeid) struct ifnet* in6_getlinkifnet(uint32_t zoneid) { + struct ifnet *ifp; - return (ifnet_byindex((u_short)zoneid)); + ifp = ifnet_byindex((u_short)zoneid); + + if (ifp == NULL) + return (NULL); + + /* An interface might not be IPv6 capable. */ + if (ifp->if_afdata[AF_INET6] == NULL) { + log(LOG_NOTICE, + "%s: embedded scope points to an interface without " + "IPv6: %s%%%d.\n", __func__, + if_name(ifp), zoneid); + return (NULL); + } + + return (ifp); } /* 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/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index 41e9ca27912d..79c298c18b46 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -7399,7 +7399,7 @@ pf_sctp_multihome_delayed(struct pf_pdesc *pd, struct pfi_kkif *kif, { struct pf_sctp_multihome_job *j, *tmp; struct pf_sctp_source *i; - int ret __unused; + int ret; struct pf_kstate *sm = NULL; struct pf_krule *ra = NULL; struct pf_krule *r = &V_pf_default_rule; diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c index ea9f7fe441c6..9abc07c36788 100644 --- a/sys/netpfil/pf/pf_ioctl.c +++ b/sys/netpfil/pf/pf_ioctl.c @@ -2092,19 +2092,18 @@ pf_ioctl_addrule(struct pf_krule *rule, uint32_t ticket, int rs_num; int error = 0; - if ((rule->return_icmp >> 8) > ICMP_MAXTYPE) { - error = EINVAL; - goto errout_unlocked; - } +#define ERROUT(x) ERROUT_FUNCTION(errout, x) +#define ERROUT_UNLOCKED(x) ERROUT_FUNCTION(errout_unlocked, x) -#define ERROUT(x) ERROUT_FUNCTION(errout, x) + if ((rule->return_icmp >> 8) > ICMP_MAXTYPE) + ERROUT_UNLOCKED(EINVAL); if ((error = pf_rule_checkaf(rule))) - ERROUT(error); + ERROUT_UNLOCKED(error); if (pf_validate_range(rule->src.port_op, rule->src.port)) - ERROUT(EINVAL); + ERROUT_UNLOCKED(EINVAL); if (pf_validate_range(rule->dst.port_op, rule->dst.port)) - ERROUT(EINVAL); + ERROUT_UNLOCKED(EINVAL); if (rule->ifname[0]) kif = pf_kkif_create(M_WAITOK); @@ -2294,6 +2293,7 @@ pf_ioctl_addrule(struct pf_krule *rule, uint32_t ticket, return (0); #undef ERROUT +#undef ERROUT_UNLOCKED errout: PF_RULES_WUNLOCK(); PF_CONFIG_UNLOCK(); 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/svc_auth.c b/sys/rpc/svc_auth.c index 92f1ee0f2844..838fa9ed313a 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_fallback(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_fallback(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/exterr_cat.h b/sys/sys/exterr_cat.h index cab94ac511a5..80cff53b3576 100644 --- a/sys/sys/exterr_cat.h +++ b/sys/sys/exterr_cat.h @@ -18,6 +18,8 @@ #define EXTERR_CAT_FUSE 4 #define EXTERR_CAT_INOTIFY 5 #define EXTERR_CAT_GENIO 6 +#define EXTERR_CAT_BRIDGE 7 +#define EXTERR_CAT_SWAP 8 #endif diff --git a/sys/sys/jail.h b/sys/sys/jail.h index 08caa9f49270..24c420e2c976 100644 --- a/sys/sys/jail.h +++ b/sys/sys/jail.h @@ -435,7 +435,7 @@ void prison0_init(void); bool prison_allow(struct ucred *, unsigned); int prison_check(struct ucred *cred1, struct ucred *cred2); bool prison_check_nfsd(struct ucred *cred); -bool prison_owns_vnet(struct ucred *); +bool prison_owns_vnet(struct prison *pr); int prison_canseemount(struct ucred *cred, struct mount *mp); void prison_enforce_statfs(struct ucred *cred, struct mount *mp, struct statfs *sp); diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h index c75094aea450..304bd019c9fc 100644 --- a/sys/sys/mbuf.h +++ b/sys/sys/mbuf.h @@ -1391,6 +1391,7 @@ extern bool mb_use_ext_pgs; /* Use ext_pgs for sendfile */ #define PACKET_TAG_PF_REASSEMBLED 31 #define PACKET_TAG_IPSEC_ACCEL_OUT 32 /* IPSEC accel out */ #define PACKET_TAG_IPSEC_ACCEL_IN 33 /* IPSEC accel in */ +#define PACKET_TAG_OVPN 34 /* if_ovpn */ /* Specific cookies and tags. */ 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..4831d8cb6e1b 100644 --- a/sys/sys/ucred.h +++ b/sys/sys/ucred.h @@ -76,15 +76,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 +108,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 +129,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. 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 17308706c3f4..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"); @@ -1268,7 +1268,8 @@ ufs_rename( struct inode *fip, *tip, *tdp, *fdp; struct direct newdir; off_t endoff; - int doingdirectory, newparent; + int doingdirectory; + u_int newparent; int error = 0; struct mount *mp; ino_t ino; @@ -1475,7 +1476,7 @@ relock: * the user must have write permission in the source so * as to be able to change "..". */ - if (doingdirectory && newparent) { + if (doingdirectory && newparent != 0) { error = VOP_ACCESS(fvp, VWRITE, tcnp->cn_cred, curthread); if (error) goto unlockout; @@ -1538,7 +1539,7 @@ relock: if (tip == NULL) { if (ITODEV(tdp) != ITODEV(fip)) panic("ufs_rename: EXDEV"); - if (doingdirectory && newparent) { + if (doingdirectory && newparent != 0) { /* * Account for ".." in new directory. * When source and destination have the same @@ -1631,7 +1632,7 @@ relock: goto bad; } if (doingdirectory) { - if (!newparent) { + if (newparent == 0) { tdp->i_effnlink--; if (DOINGSOFTDEP(tdvp)) softdep_change_linkcnt(tdp); @@ -1641,11 +1642,11 @@ relock: softdep_change_linkcnt(tip); } error = ufs_dirrewrite(tdp, tip, fip->i_number, - IFTODT(fip->i_mode), - (doingdirectory && newparent) ? newparent : doingdirectory); + IFTODT(fip->i_mode), (doingdirectory && newparent != 0) ? + newparent : doingdirectory); if (error) { if (doingdirectory) { - if (!newparent) { + if (newparent == 0) { tdp->i_effnlink++; if (DOINGSOFTDEP(tdvp)) softdep_change_linkcnt(tdp); @@ -1668,7 +1669,7 @@ relock: * disk, so when running with that code we avoid doing * them now. */ - if (!newparent) { + if (newparent == 0) { tdp->i_nlink--; DIP_SET_NLINK(tdp, tdp->i_nlink); UFS_INODE_SET_FLAG(tdp, IN_CHANGE); @@ -1697,7 +1698,7 @@ relock: * parent directory must be decremented * and ".." set to point to the new parent. */ - if (doingdirectory && newparent) { + if (doingdirectory && newparent != 0) { /* * Set the directory depth based on its new parent. */ @@ -1727,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. @@ -2037,7 +2038,6 @@ ufs_mkdir( { #ifdef QUOTA struct ucred ucred, *ucp; - gid_t ucred_group; ucp = cnp->cn_cred; #endif /* @@ -2064,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 @@ -2308,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++; @@ -2801,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 /* @@ -2827,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 d6bd06226d04..c01b9e45a32b 100644 --- a/sys/vm/swap_pager.c +++ b/sys/vm/swap_pager.c @@ -65,9 +65,9 @@ * from: Utah $Hdr: swap_pager.c 1.4 91/04/30$ */ -#include <sys/cdefs.h> #include "opt_vm.h" +#define EXTERR_CATEGORY EXTERR_CAT_SWAP #include <sys/param.h> #include <sys/bio.h> #include <sys/blist.h> @@ -76,6 +76,7 @@ #include <sys/disk.h> #include <sys/disklabel.h> #include <sys/eventhandler.h> +#include <sys/exterrvar.h> #include <sys/fcntl.h> #include <sys/limits.h> #include <sys/lock.h> @@ -2686,7 +2687,7 @@ swapon_check_swzone(void) } } -static void +static int swaponsomething(struct vnode *vp, void *id, u_long nblks, sw_strategy_t *strategy, sw_close_t *close, dev_t dev, int flags) { @@ -2701,6 +2702,8 @@ swaponsomething(struct vnode *vp, void *id, u_long nblks, */ nblks &= ~(ctodb(1) - 1); nblks = dbtoc(nblks); + if (nblks == 0) + return (EXTERROR(EINVAL, "swap device too small")); sp = malloc(sizeof *sp, M_VMPGDATA, M_WAITOK | M_ZERO); sp->sw_blist = blist_create(nblks, M_WAITOK); @@ -2742,6 +2745,8 @@ swaponsomething(struct vnode *vp, void *id, u_long nblks, swp_sizecheck(); mtx_unlock(&sw_dev_mtx); EVENTHANDLER_INVOKE(swapon, sp); + + return (0); } /* @@ -3273,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: @@ -3280,16 +3286,20 @@ 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; - swaponsomething(vp, cp, nblks, swapgeom_strategy, - swapgeom_close, dev2udev(dev), - (pp->flags & G_PF_ACCEPT_UNMAPPED) != 0 ? SW_UNMAPPED : 0); - return (0); + return (error); } static int @@ -3378,9 +3388,11 @@ swaponvp(struct thread *td, struct vnode *vp, u_long nblks) if (error != 0) return (error); - swaponsomething(vp, vp, nblks, swapdev_strategy, swapdev_close, + error = swaponsomething(vp, vp, nblks, swapdev_strategy, swapdev_close, NODEV, 0); - return (0); + if (error != 0) + VOP_CLOSE(vp, FREAD | FWRITE, td->td_ucred, td); + return (error); } static int diff --git a/targets/pseudo/userland/misc/Makefile.depend b/targets/pseudo/userland/misc/Makefile.depend index d3c97fc56b40..546800004d11 100644 --- a/targets/pseudo/userland/misc/Makefile.depend +++ b/targets/pseudo/userland/misc/Makefile.depend @@ -54,7 +54,6 @@ DIRDEPS.x86sys= \ .if ${MK_ZFS} != "no" DIRDEPS.x86sys+= \ stand/i386/gptzfsboot \ - stand/i386/zfsboot \ stand/i386/zfsloader \ DIRDEPS+= \ diff --git a/tests/sys/net/if_bridge_test.sh b/tests/sys/net/if_bridge_test.sh index cd38adea28ad..c0c085f22273 100755 --- a/tests/sys/net/if_bridge_test.sh +++ b/tests/sys/net/if_bridge_test.sh @@ -1221,6 +1221,29 @@ vlan_qinq_cleanup() vnet_cleanup } +# Adding a bridge SVI to a bridge should not be allowed. +atf_test_case "bridge_svi_in_bridge" "cleanup" +bridge_svi_in_bridge_head() +{ + atf_set descr 'adding a bridge SVI to a bridge is not allowed (1)' + atf_set require.user root +} + +bridge_svi_in_bridge_body() +{ + vnet_init + vnet_init_bridge + + bridge=$(vnet_mkbridge) + atf_check -s exit:0 ifconfig ${bridge}.1 create + atf_check -s exit:1 -e ignore ifconfig ${bridge} addm ${bridge}.1 +} + +bridge_svi_in_bridge_cleanup() +{ + vnet_cleanup +} + atf_init_test_cases() { atf_add_test_case "bridge_transmit_ipv4_unicast" @@ -1247,4 +1270,5 @@ atf_init_test_cases() atf_add_test_case "vlan_ifconfig_tagged" atf_add_test_case "vlan_svi" atf_add_test_case "vlan_qinq" + atf_add_test_case "bridge_svi_in_bridge" } diff --git a/tests/sys/net/if_ovpn/if_ovpn.sh b/tests/sys/net/if_ovpn/if_ovpn.sh index 26807a095455..c42344da1a3b 100644 --- a/tests/sys/net/if_ovpn/if_ovpn.sh +++ b/tests/sys/net/if_ovpn/if_ovpn.sh @@ -1314,6 +1314,96 @@ multihome6_cleanup() ovpn_cleanup } +atf_test_case "float" "cleanup" +float_head() +{ + atf_set descr 'Test peer float notification' + atf_set require.user root +} + +float_body() +{ + ovpn_init + + l=$(vnet_mkepair) + + vnet_mkjail a ${l}a + jexec a ifconfig ${l}a 192.0.2.1/24 up + jexec a ifconfig lo0 127.0.0.1/8 up + vnet_mkjail b ${l}b + jexec b ifconfig ${l}b 192.0.2.2/24 up + + # Sanity check + atf_check -s exit:0 -o ignore jexec a ping -c 1 192.0.2.2 + + ovpn_start a " + dev ovpn0 + dev-type tun + proto udp4 + + cipher AES-256-GCM + auth SHA256 + + local 192.0.2.1 + server 198.51.100.0 255.255.255.0 + ca $(atf_get_srcdir)/ca.crt + cert $(atf_get_srcdir)/server.crt + key $(atf_get_srcdir)/server.key + dh $(atf_get_srcdir)/dh.pem + + mode server + script-security 2 + auth-user-pass-verify /usr/bin/true via-env + topology subnet + + keepalive 2 10 + + management 192.0.2.1 1234 + " + ovpn_start b " + dev tun0 + dev-type tun + + client + + remote 192.0.2.1 + auth-user-pass $(atf_get_srcdir)/user.pass + + ca $(atf_get_srcdir)/ca.crt + cert $(atf_get_srcdir)/client.crt + key $(atf_get_srcdir)/client.key + dh $(atf_get_srcdir)/dh.pem + + keepalive 2 10 + " + + # Give the tunnel time to come up + sleep 10 + + atf_check -s exit:0 -o ignore jexec b ping -c 3 198.51.100.1 + + # We expect the client on 192.0.2.2 + if ! echo "status" | jexec a nc -N 192.0.2.1 1234 | grep 192.0.2.2; then + atf_fail "Client not found in status list!" + fi + + # Now change the client IP + jexec b ifconfig ${l}b 192.0.2.3/24 up + + # And wait for keepalives to trigger the float notification + sleep 5 + + # So the client now has the new address in userspace + if ! echo "status" | jexec a nc -N 192.0.2.1 1234 | grep 192.0.2.3; then + atf_fail "Client not found in status list!" + fi +} + +float_cleanup() +{ + ovpn_cleanup +} + atf_init_test_cases() { atf_add_test_case "4in4" @@ -1332,4 +1422,5 @@ atf_init_test_cases() atf_add_test_case "destroy_unused" atf_add_test_case "multihome4" atf_add_test_case "multihome6" + atf_add_test_case "float" } diff --git a/tests/sys/net/if_vlan.sh b/tests/sys/net/if_vlan.sh index 424eac705b94..8122203337e2 100755 --- a/tests/sys/net/if_vlan.sh +++ b/tests/sys/net/if_vlan.sh @@ -333,6 +333,32 @@ conflict_id_cleanup() } +# If a vlan interface is in a bridge, changing the vlandev to refer to +# a bridge should not be allowed. +atf_test_case "bridge_vlandev" "cleanup" +bridge_vlandev_head() +{ + atf_set descr 'transforming a bridge member vlan into an SVI is not allowed' + atf_set require.user root +} + +bridge_vlandev_body() +{ + vnet_init + vnet_init_bridge + + bridge=$(vnet_mkbridge) + vlan=$(vnet_mkvlan) + + atf_check -s exit:0 ifconfig ${bridge} addm ${vlan} + atf_check -s exit:1 -e ignore ifconfig ${vlan} vlan 1 vlandev ${bridge} +} + +bridge_vlandev_cleanup() +{ + vnet_cleanup +} + atf_init_test_cases() { atf_add_test_case "basic" @@ -343,4 +369,5 @@ atf_init_test_cases() atf_add_test_case "qinq_setflags" atf_add_test_case "bpf_pcp" atf_add_test_case "conflict_id" + atf_add_test_case "bridge_vlandev" } diff --git a/tests/sys/netpfil/pf/nat64.py b/tests/sys/netpfil/pf/nat64.py index 5cc4713a16cc..a5890fc4a161 100644 --- a/tests/sys/netpfil/pf/nat64.py +++ b/tests/sys/netpfil/pf/nat64.py @@ -33,7 +33,7 @@ from atf_python.sys.net.tools import ToolsHelper from atf_python.sys.net.vnet import VnetTestTemplate class TestNAT64(VnetTestTemplate): - REQUIRED_MODULES = [ "pf" ] + REQUIRED_MODULES = [ "pf", "pflog" ] TOPOLOGY = { "vnet1": {"ifaces": ["if1"]}, "vnet2": {"ifaces": ["if1", "if2"]}, @@ -92,12 +92,15 @@ class TestNAT64(VnetTestTemplate): def vnet2_handler(self, vnet): ifname = vnet.iface_alias_map["if1"].name + ToolsHelper.print_output("/sbin/sysctl net.inet6.ip6.forwarding=1") ToolsHelper.print_output("/sbin/route add default 192.0.2.2") ToolsHelper.print_output("/sbin/pfctl -e") ToolsHelper.pf_rules([ "pass inet6 proto icmp6", "pass in on %s inet6 af-to inet from 192.0.2.1" % ifname]) + vnet.pipe.send(socket.if_nametoindex("pflog0")) + @pytest.mark.require_user("root") @pytest.mark.require_progs(["scapy"]) def test_tcp_rst(self): @@ -287,3 +290,39 @@ class TestNAT64(VnetTestTemplate): reply = sp.sr1(packet, timeout=3) # We don't expect a reply to a corrupted packet assert not reply + + @pytest.mark.require_user("root") + @pytest.mark.require_progs(["scapy"]) + def test_noip6(self): + """ + PR 288263: link-local target address in icmp6 ADVERT can cause NULL deref + """ + ifname = self.vnet.iface_alias_map["if1"].name + gw_mac = self.vnet.iface_alias_map["if1"].epairb.ether + scopeid = self.wait_object(self.vnet_map["vnet2"].pipe) + ToolsHelper.print_output("/sbin/route -6 add default 2001:db8::1") + + import scapy.all as sp + + pkt = sp.Ether(dst=gw_mac) \ + / sp.IPv6(dst="64:ff9b::203.0.113.2") \ + / sp.ICMPv6ND_NA(tgt="FFA2:%x:2821:125F:1D27:B3B2:3F6F:C43C" % scopeid) + pkt.show() + sp.hexdump(pkt) + s = DelayedSend(pkt, sendif=ifname) + + packets = sp.sniff(iface=ifname, timeout=5) + for r in packets: + r.show() + + # Try scope id that likely doesn't have an interface at all + pkt = sp.Ether(dst=gw_mac) \ + / sp.IPv6(dst="64:ff9b::203.0.113.2") \ + / sp.ICMPv6ND_NA(tgt="FFA2:%x:2821:125F:1D27:B3B2:3F6F:C43C" % 255) + pkt.show() + sp.hexdump(pkt) + s = DelayedSend(pkt, sendif=ifname) + + packets = sp.sniff(iface=ifname, timeout=5) + for r in packets: + r.show() diff --git a/tools/boot/install-boot.sh b/tools/boot/install-boot.sh index 217bf0ff1457..10e62dd32ba8 100755 --- a/tools/boot/install-boot.sh +++ b/tools/boot/install-boot.sh @@ -294,27 +294,9 @@ boot_nogeli_mbr_ufs_both() { boot_nogeli_mbr_ufs_uefi $1 $2 $3 } +# ZFS+MBR+BIOS is not a supported configuration boot_nogeli_mbr_zfs_legacy() { - dev=$1 - dst=$2 - - # search to find the BSD slice - s=$(find_part $dev "freebsd") - if [ -z "$s" ] ; then - die "No BSD slice found" - fi - idx=$(find_part ${dev}s${s} "freebsd-zfs") - if [ -z "$idx" ] ; then - die "No freebsd-zfs slice found" - fi - # search to find the freebsd-zfs partition within the slice - # Or just assume it is 'a' because it has to be since it fails otherwise - doit gpart bootcode -b ${dst}/boot/mbr ${dev} - dd if=${dst}/boot/zfsboot of=/tmp/zfsboot1 count=1 - doit gpart bootcode -b /tmp/zfsboot1 ${dev}s${s} # Put boot1 into the start of part - sysctl kern.geom.debugflags=0x10 # Put boot2 into ZFS boot slot - doit dd if=${dst}/boot/zfsboot of=/dev/${dev}s${s}a skip=1 seek=1024 - sysctl kern.geom.debugflags=0x0 + exit 1 } boot_nogeli_mbr_zfs_uefi() { @@ -322,7 +304,6 @@ boot_nogeli_mbr_zfs_uefi() { } boot_nogeli_mbr_zfs_both() { - boot_nogeli_mbr_zfs_legacy $1 $2 $3 boot_nogeli_mbr_zfs_uefi $1 $2 $3 } diff --git a/tools/boot/rootgen.sh b/tools/boot/rootgen.sh index d87eb481e2c1..2cd65bdd180d 100755 --- a/tools/boot/rootgen.sh +++ b/tools/boot/rootgen.sh @@ -202,33 +202,6 @@ mk_nogeli_mbr_ufs_both() { rm -f ${src}/etc/fstab } -mk_nogeli_mbr_zfs_legacy() { - src=$1 - img=$2 - mntpt=$3 - geli=$4 - scheme=$5 - fs=$6 - bios=$7 - pool=nogeli-mbr-zfs-legacy - - zfs_extra $src $dst - makefs -t zfs -s 200m \ - -o poolname=${pool} -o bootfs=${pool} -o rootpath=/ \ - ${img}.s1a ${src} ${dst} - # The old boot1/boot2 boot split is also used by zfs. We need to extract zfsboot1 - # from this image. Since there's no room in the mbr format for the rest of the loader, - # it will load the zfsboot loader from the reserved for bootloader area of the ZFS volume - # being booted, hence the need to dd it into the raw img later. - # Please note: zfsboot only works with partition 'a' which must be the root - # partition / zfs volume - dd if=${src}/boot/zfsboot of=${dst}/zfsboot1 count=1 - mkimg -s bsd -b ${dst}zfsboot1 -p freebsd-zfs:=${img}.s1a -o ${img}.s1 - dd if=${src}/boot/zfsboot of=${img}.s1a skip=1 seek=1024 - mkimg -a 1 -s mbr -b ${src}/boot/mbr -p freebsd:=${img}.s1 -o ${img} - rm -rf ${dst} -} - mk_nogeli_mbr_zfs_uefi() { src=$1 img=$2 @@ -244,38 +217,11 @@ mk_nogeli_mbr_zfs_uefi() { makefs -t zfs -s 200m \ -o poolname=${pool} -o bootfs=${pool} -o rootpath=/ \ ${img}.s2a ${src} ${dst} - mkimg -s bsd -b ${dst}zfsboot1 -p freebsd-zfs:=${img}.s2a -o ${img}.s2 + mkimg -s bsd -p freebsd-zfs:=${img}.s2a -o ${img}.s2 mkimg -a 1 -s mbr -b ${src}/boot/mbr -p efi:=${img}.s1 -p freebsd:=${img}.s2 -o ${img} rm -rf ${dst} } -mk_nogeli_mbr_zfs_both() { - src=$1 - img=$2 - mntpt=$3 - geli=$4 - scheme=$5 - fs=$6 - bios=$7 - pool=nogeli-mbr-zfs-both - - zfs_extra $src $dst - make_esp_file ${img}.s1 ${espsize} ${src}/boot/loader.efi - makefs -t zfs -s 200m \ - -o poolname=${pool} -o bootfs=${pool} -o rootpath=/ \ - ${img}.s2a ${src} ${dst} - # The old boot1/boot2 boot split is also used by zfs. We need to extract zfsboot1 - # from this image. Since there's no room in the mbr format for the rest of the loader, - # it will load the zfsboot loader from the reserved for bootloader area of the ZFS volume - # being booted, hence the need to dd it into the raw img later. - # Please note: zfsboot only works with partition 'a' which must be the root - # partition / zfs volume - dd if=${src}/boot/zfsboot of=${dst}/zfsboot1 count=1 - mkimg -s bsd -b ${dst}zfsboot1 -p freebsd-zfs:=${img}.s2a -o ${img}.s2 - dd if=${src}/boot/zfsboot of=${img}.s1a skip=1 seek=1024 - mkimg -a 1 -s mbr -b ${src}/boot/mbr -p efi:=${img}.s1 -p freebsd:=${img}.s2 -o ${img} -} - mk_geli_gpt_ufs_legacy() { src=$1 img=$2 @@ -728,6 +674,10 @@ for arch in amd64; do for scheme in gpt mbr; do for fs in ufs zfs; do for bios in legacy uefi both; do + # ZFS+MBR+BIOS is not supported + if [ "$scheme" = "mbr" -a "$fs" = "zfs" -a "$bios" != "uefi" ]; then + continue + fi make_one_image ${arch} ${geli} ${scheme} ${fs} ${bios} done done @@ -750,6 +700,11 @@ for arch in i386; do for bios in legacy; do # The legacy boot is shared with amd64 so those routines could # likely be used here. + + # ZFS+MBR+BIOS is not supported + if [ "$scheme" = "mbr" -a "$fs" = "zfs" -a "$bios" != "uefi" ]; then + continue + fi make_one_image ${arch} ${geli} ${scheme} ${fs} ${bios} done done diff --git a/tools/build/cross-build/include/mac/endian.h b/tools/build/cross-build/include/mac/endian.h new file mode 100644 index 000000000000..11788044f05a --- /dev/null +++ b/tools/build/cross-build/include/mac/endian.h @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2025 John Baldwin <jhb@FreeBSD.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <sys/endian.h> diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc index da7f57eec2d5..580be4362a18 100644 --- a/tools/build/mk/OptionalObsoleteFiles.inc +++ b/tools/build/mk/OptionalObsoleteFiles.inc @@ -357,7 +357,6 @@ OLD_FILES+=boot/shortcuts.4th OLD_FILES+=boot/support.4th OLD_FILES+=boot/userboot.so OLD_FILES+=boot/version.4th -OLD_FILES+=boot/zfsboot OLD_FILES+=boot/zfsloader OLD_FILES+=usr/lib/kgzldr.o OLD_FILES+=usr/share/man/man5/loader.conf.5.gz @@ -374,7 +373,6 @@ OLD_FILES+=usr/share/man/man8/menu.4th.8.gz OLD_FILES+=usr/share/man/man8/menusets.4th.8.gz OLD_FILES+=usr/share/man/man8/pxeboot.8.gz OLD_FILES+=usr/share/man/man8/version.4th.8.gz -OLD_FILES+=usr/share/man/man8/zfsboot.8.gz OLD_FILES+=usr/share/man/man8/zfsloader.8.gz .endif @@ -12277,7 +12275,6 @@ OLD_FILES+=usr/share/snmp/mibs/BEGEMOT-WIRELESS-MIB.txt .if ${MK_ZFS} == no OLD_FILES+=boot/gptzfsboot -OLD_FILES+=boot/zfsboot OLD_FILES+=boot/zfsloader OLD_FILES+=etc/rc.d/zfs OLD_FILES+=etc/rc.d/zfsbe @@ -12380,7 +12377,6 @@ OLD_FILES+=usr/share/man/man8/gptzfsboot.8.gz OLD_FILES+=usr/share/man/man8/zdb.8.gz OLD_FILES+=usr/share/man/man8/zfs-program.8.gz OLD_FILES+=usr/share/man/man8/zfs.8.gz -OLD_FILES+=usr/share/man/man8/zfsboot.8.gz OLD_FILES+=usr/share/man/man8/zfsbootcfg.8.gz OLD_FILES+=usr/share/man/man8/zfsd.8.gz OLD_FILES+=usr/share/man/man8/zfsloader.8.gz 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/bmake/Makefile.inc b/usr.bin/bmake/Makefile.inc index 5140bd18bb37..a064563a2283 100644 --- a/usr.bin/bmake/Makefile.inc +++ b/usr.bin/bmake/Makefile.inc @@ -3,6 +3,8 @@ MK_host_egacy= no .sinclude <src.opts.mk> +PACKAGE?= bmake + .if defined(.PARSEDIR) # make sure this is available to unit-tests/Makefile .export SRCTOP diff --git a/usr.bin/clang/clang-scan-deps/Makefile b/usr.bin/clang/clang-scan-deps/Makefile index 16fecdb88867..8da12faccc45 100644 --- a/usr.bin/clang/clang-scan-deps/Makefile +++ b/usr.bin/clang/clang-scan-deps/Makefile @@ -10,13 +10,14 @@ SRCS+= ClangScanDeps.cpp \ .include "${SRCTOP}/lib/clang/clang.pre.mk" CFLAGS+= -I${.OBJDIR} -TDFILE= Opts.td -INCFILE= ${TDFILE:.td=.inc} + +INCFILE= Opts.inc +TDFILE= ${LLVM_BASE}/${SRCDIR}/Opts.td GENOPT= -gen-opt-parser-defs ${INCFILE}: ${TDFILE} ${LLVM_TBLGEN} ${GENOPT} -I ${LLVM_SRCS}/include -d ${.TARGET:C/$/.d/} \ - -o ${.TARGET} ${.ALLSRC} + -o ${.TARGET} ${TDFILE} TGHDRS+= ${INCFILE} DEPENDFILES+= ${TGHDRS:C/$/.d/} diff --git a/usr.bin/clang/clang.prog.mk b/usr.bin/clang/clang.prog.mk index 36c601bcbe36..3baf3d0baf0f 100644 --- a/usr.bin/clang/clang.prog.mk +++ b/usr.bin/clang/clang.prog.mk @@ -31,7 +31,7 @@ DPADD+= ${OBJTOP}/lib/clang/lib${lib}/lib${LIBPRIV}${lib}.${LIBEXT} LDADD+= ${OBJTOP}/lib/clang/lib${lib}/lib${LIBPRIV}${lib}.${LIBEXT} .endfor -PACKAGE= clang +PACKAGE?= clang .if ${.MAKE.OS} == "FreeBSD" || !defined(BOOTSTRAPPING) LIBADD+= execinfo diff --git a/usr.bin/clang/llvm-ar/Makefile b/usr.bin/clang/llvm-ar/Makefile index fd12b1ddef57..e019c89b3581 100644 --- a/usr.bin/clang/llvm-ar/Makefile +++ b/usr.bin/clang/llvm-ar/Makefile @@ -1,5 +1,6 @@ .include <src.opts.mk> +PACKAGE= toolchain PROG_CXX= llvm-ar MAN= llvm-ar.1 llvm-ranlib.1 diff --git a/usr.bin/clang/llvm-nm/Makefile b/usr.bin/clang/llvm-nm/Makefile index 825faf74719b..7e089d1b408d 100644 --- a/usr.bin/clang/llvm-nm/Makefile +++ b/usr.bin/clang/llvm-nm/Makefile @@ -1,5 +1,6 @@ .include <src.opts.mk> +PACKAGE= toolchain PROG_CXX= llvm-nm SRCDIR= llvm/tools/llvm-nm diff --git a/usr.bin/clang/llvm-size/Makefile b/usr.bin/clang/llvm-size/Makefile index 2860a0069538..9d3505cdd319 100644 --- a/usr.bin/clang/llvm-size/Makefile +++ b/usr.bin/clang/llvm-size/Makefile @@ -1,5 +1,6 @@ .include <src.opts.mk> +PACKAGE= toolchain PROG_CXX= llvm-size SRCDIR= llvm/tools/llvm-size diff --git a/usr.bin/clang/llvm.prog.mk b/usr.bin/clang/llvm.prog.mk index f702082e31bd..c369fe8d5944 100644 --- a/usr.bin/clang/llvm.prog.mk +++ b/usr.bin/clang/llvm.prog.mk @@ -25,7 +25,7 @@ DPADD+= ${OBJTOP}/lib/clang/lib${lib}/lib${LIBPRIV}${lib}.${LIBEXT} LDADD+= ${OBJTOP}/lib/clang/lib${lib}/lib${LIBPRIV}${lib}.${LIBEXT} .endfor -PACKAGE= clang +PACKAGE?= clang .if ${.MAKE.OS} == "FreeBSD" || !defined(BOOTSTRAPPING) LIBADD+= execinfo 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.bin/strings/Makefile b/usr.bin/strings/Makefile index 8e2572810947..c01e775b0b89 100644 --- a/usr.bin/strings/Makefile +++ b/usr.bin/strings/Makefile @@ -1,5 +1,7 @@ .include <src.opts.mk> +PACKAGE= toolchain + ELFTCDIR= ${SRCTOP}/contrib/elftoolchain .PATH: ${ELFTCDIR}/strings diff --git a/usr.sbin/bsdinstall/bsdinstall.8 b/usr.sbin/bsdinstall/bsdinstall.8 index 8fadacab9189..181abdcf9d05 100644 --- a/usr.sbin/bsdinstall/bsdinstall.8 +++ b/usr.sbin/bsdinstall/bsdinstall.8 @@ -451,7 +451,7 @@ Each option must be preceded by the -O flag to be taken into consideration or the pool will not be created due to errors using the command .Cm zpool . Default: -.Dq Li "-O compress=lz4 -O atime=off" +.Dq Li "-O compression=on -O atime=off" .It Ev ZFSBOOT_BEROOT_NAME Name for the boot environment parent dataset. This is a non-mountable dataset meant to be a parent dataset where different 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/bsdinstall/scripts/zfsboot b/usr.sbin/bsdinstall/scripts/zfsboot index 60feec28e888..a3c1e2ddb89f 100755 --- a/usr.sbin/bsdinstall/scripts/zfsboot +++ b/usr.sbin/bsdinstall/scripts/zfsboot @@ -51,7 +51,7 @@ f_include $BSDCFG_SHARE/variable.subr # # Default options to use when creating zroot pool # -: ${ZFSBOOT_POOL_CREATE_OPTIONS:=-O compress=lz4 -O atime=off} +: ${ZFSBOOT_POOL_CREATE_OPTIONS:=-O compression=on -O atime=off} # # Default name for the boot environment parent dataset 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/chroot/chroot.8 b/usr.sbin/chroot/chroot.8 index f26b7e937da9..4a1a5a396631 100644 --- a/usr.sbin/chroot/chroot.8 +++ b/usr.sbin/chroot/chroot.8 @@ -25,7 +25,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd July 20, 2021 +.Dd July 25, 2025 .Dt CHROOT 8 .Os .Sh NAME @@ -52,13 +52,15 @@ or an interactive copy of the user's login shell. The options are as follows: .Bl -tag -width "-G group[,group ...]" .It Fl G Ar group Ns Op Cm \&, Ns Ar group ... -Run the command with the permissions of the specified groups. +Run the command with the specified groups as supplementary groups. .It Fl g Ar group -Run the command with the permissions of the specified -.Ar group . +Run the command with the specified +.Ar group +as the real, effective and saved groups. .It Fl u Ar user -Run the command as the -.Ar user . +Run the command with the specified +.Ar user +as the real, effective and saved users. .It Fl n Use the .Dv PROC_NO_NEW_PRIVS_CTL diff --git a/usr.sbin/makefs/zfs/dsl.c b/usr.sbin/makefs/zfs/dsl.c index 8a8cee7c82b2..1977521d7f92 100644 --- a/usr.sbin/makefs/zfs/dsl.c +++ b/usr.sbin/makefs/zfs/dsl.c @@ -119,7 +119,7 @@ dsl_dir_get_mountpoint(zfs_opt_t *zfs, zfs_dsl_dir_t *dir) if (nvlist_find_string(pdir->propsnv, "mountpoint", &tmp) == 0) { - easprintf(&mountpoint, "%s%s%s", tmp, + (void)easprintf(&mountpoint, "%s%s%s", tmp, tmp[strlen(tmp) - 1] == '/' ? "" : "/", origmountpoint); free(tmp); @@ -127,7 +127,7 @@ dsl_dir_get_mountpoint(zfs_opt_t *zfs, zfs_dsl_dir_t *dir) break; } - easprintf(&mountpoint, "%s/%s", pdir->name, + (void)easprintf(&mountpoint, "%s/%s", pdir->name, origmountpoint); free(origmountpoint); } @@ -175,22 +175,22 @@ dsl_dir_set_prop(zfs_opt_t *zfs, zfs_dsl_dir_t *dir, const char *key, "the root path `%s'", val, zfs->rootpath); } } - nvlist_add_string(nvl, key, val); + (void)nvlist_add_string(nvl, key, val); } else if (strcmp(key, "atime") == 0 || strcmp(key, "exec") == 0 || strcmp(key, "setuid") == 0) { if (strcmp(val, "on") == 0) - nvlist_add_uint64(nvl, key, 1); + (void)nvlist_add_uint64(nvl, key, 1); else if (strcmp(val, "off") == 0) - nvlist_add_uint64(nvl, key, 0); + (void)nvlist_add_uint64(nvl, key, 0); else errx(1, "invalid value `%s' for %s", val, key); } else if (strcmp(key, "canmount") == 0) { if (strcmp(val, "noauto") == 0) - nvlist_add_uint64(nvl, key, 2); + (void)nvlist_add_uint64(nvl, key, 2); else if (strcmp(val, "on") == 0) - nvlist_add_uint64(nvl, key, 1); + (void)nvlist_add_uint64(nvl, key, 1); else if (strcmp(val, "off") == 0) - nvlist_add_uint64(nvl, key, 0); + (void)nvlist_add_uint64(nvl, key, 0); else errx(1, "invalid value `%s' for %s", val, key); } else if (strcmp(key, "compression") == 0) { @@ -237,7 +237,7 @@ dsl_metadir_alloc(zfs_opt_t *zfs, const char *name) zfs_dsl_dir_t *dir; char *path; - easprintf(&path, "%s/%s", zfs->poolname, name); + (void)easprintf(&path, "%s/%s", zfs->poolname, name); dir = dsl_dir_alloc(zfs, path); free(path); return (dir); @@ -322,11 +322,11 @@ dsl_init(zfs_opt_t *zfs) * user didn't override the defaults. */ if (nvpair_find(zfs->rootdsldir->propsnv, "compression") == NULL) { - nvlist_add_uint64(zfs->rootdsldir->propsnv, "compression", - ZIO_COMPRESS_OFF); + (void)nvlist_add_uint64(zfs->rootdsldir->propsnv, + "compression", ZIO_COMPRESS_OFF); } if (nvpair_find(zfs->rootdsldir->propsnv, "mountpoint") == NULL) { - nvlist_add_string(zfs->rootdsldir->propsnv, "mountpoint", + (void)nvlist_add_string(zfs->rootdsldir->propsnv, "mountpoint", zfs->rootpath); } } @@ -431,6 +431,7 @@ dsl_dir_alloc(zfs_opt_t *zfs, const char *name) STAILQ_INIT(&l); STAILQ_INSERT_HEAD(&l, zfs->rootdsldir, next); origname = dirname = nextdir = estrdup(name); + parent = NULL; for (lp = &l;; lp = &parent->children) { dirname = strsep(&nextdir, "/"); if (nextdir == NULL) diff --git a/usr.sbin/makefs/zfs/fs.c b/usr.sbin/makefs/zfs/fs.c index 073dce3ce697..75f6e30e1500 100644 --- a/usr.sbin/makefs/zfs/fs.c +++ b/usr.sbin/makefs/zfs/fs.c @@ -28,6 +28,7 @@ * SUCH DAMAGE. */ +#include <sys/param.h> #include <sys/stat.h> #include <assert.h> @@ -383,22 +384,34 @@ fs_populate_sattrs(struct fs_populate_arg *arg, const fsnode *cur, links = 1; /* .. */ objsize = 1; /* .. */ - /* - * The size of a ZPL directory is the number of entries - * (including "." and ".."), and the link count is the number of - * entries which are directories (including "." and ".."). - */ - for (fsnode *c = fsnode_isroot(cur) ? cur->next : cur->child; - c != NULL; c = c->next) { - switch (c->type) { - case S_IFDIR: - links++; - /* FALLTHROUGH */ - case S_IFREG: - case S_IFLNK: - objsize++; - break; + if ((cur->inode->flags & FI_ROOT) == 0 ) { + /* + * The size of a ZPL directory is the number of entries + * (including "." and ".."), and the link count is the + * number of entries which are directories + * (including "." and ".."). + */ + for (fsnode *c = + fsnode_isroot(cur) ? cur->next : cur->child; + c != NULL; c = c->next) { + switch (c->type) { + case S_IFDIR: + links++; + /* FALLTHROUGH */ + case S_IFREG: + case S_IFLNK: + objsize++; + break; + } } + } else { + /* + * Root directory children do belong to + * different dataset and this directory is + * empty in the current objset. + */ + links++; /* . */ + objsize++; /* . */ } /* The root directory is its own parent. */ @@ -734,7 +747,7 @@ fs_add_zpl_attr_layout(zfs_zap_t *zap, unsigned int index, assert(sizeof(layout[0]) == 2); - snprintf(ti, sizeof(ti), "%u", index); + (void)snprintf(ti, sizeof(ti), "%u", index); zap_add(zap, ti, sizeof(sa_attr_type_t), sacnt, (const uint8_t *)layout); } diff --git a/usr.sbin/makefs/zfs/objset.c b/usr.sbin/makefs/zfs/objset.c index 6be732db477a..f47953ac4339 100644 --- a/usr.sbin/makefs/zfs/objset.c +++ b/usr.sbin/makefs/zfs/objset.c @@ -28,6 +28,7 @@ * SUCH DAMAGE. */ +#include <sys/param.h> #include <assert.h> #include <stdlib.h> #include <string.h> diff --git a/usr.sbin/makefs/zfs/vdev.c b/usr.sbin/makefs/zfs/vdev.c index ef9e681af2da..afcce402cb13 100644 --- a/usr.sbin/makefs/zfs/vdev.c +++ b/usr.sbin/makefs/zfs/vdev.c @@ -28,6 +28,7 @@ * SUCH DAMAGE. */ +#include <sys/param.h> #include <assert.h> #include <fcntl.h> #include <stdlib.h> diff --git a/usr.sbin/makefs/zfs/zap.c b/usr.sbin/makefs/zfs/zap.c index decf5fc6a473..316d1446cecf 100644 --- a/usr.sbin/makefs/zfs/zap.c +++ b/usr.sbin/makefs/zfs/zap.c @@ -28,7 +28,7 @@ * SUCH DAMAGE. */ -#include <sys/types.h> +#include <sys/param.h> #include <sys/endian.h> #include <assert.h> @@ -172,14 +172,14 @@ zap_add_uint64_self(zfs_zap_t *zap, uint64_t val) { char name[32]; - snprintf(name, sizeof(name), "%jx", (uintmax_t)val); + (void)snprintf(name, sizeof(name), "%jx", (uintmax_t)val); zap_add(zap, name, sizeof(uint64_t), 1, (uint8_t *)&val); } void zap_add_string(zfs_zap_t *zap, const char *name, const char *val) { - zap_add(zap, name, 1, strlen(val) + 1, val); + zap_add(zap, name, 1, strlen(val) + 1, (const uint8_t *)val); } bool @@ -221,7 +221,8 @@ zap_micro_write(zfs_opt_t *zfs, zfs_zap_t *zap) STAILQ_FOREACH(ent, &zap->kvps, next) { memcpy(&ment->mze_value, ent->valp, ent->intsz * ent->intcnt); ment->mze_cd = cd++; - strlcpy(ment->mze_name, ent->name, sizeof(ment->mze_name)); + (void)strlcpy(ment->mze_name, ent->name, + sizeof(ment->mze_name)); ment++; } @@ -247,6 +248,7 @@ zap_fat_write_array_chunk(zap_leaf_t *l, uint16_t li, size_t sz, struct zap_leaf_array *la; assert(sz <= ZAP_MAXVALUELEN); + assert(sz > 0); for (uint16_t n, resid = sz; resid > 0; resid -= n, val += n, li++) { n = MIN(resid, ZAP_LEAF_ARRAY_BYTES); @@ -503,7 +505,8 @@ zap_fat_write(zfs_opt_t *zfs, zfs_zap_t *zap) le->le_value_intlen = ent->intsz; le->le_value_numints = ent->intcnt; le->le_hash = ent->hash; - zap_fat_write_array_chunk(&l, *lptr + 1, namelen, ent->name); + zap_fat_write_array_chunk(&l, *lptr + 1, namelen, + (uint8_t *)ent->name); zap_fat_write_array_chunk(&l, *lptr + 1 + nnamechunks, ent->intcnt * ent->intsz, ent->valp); } 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, |