aboutsummaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
Diffstat (limited to 'sbin')
-rw-r--r--sbin/Makefile.mips4
-rw-r--r--sbin/ddb/ddb.81
-rw-r--r--sbin/devd/apple.conf4
-rw-r--r--sbin/devd/asus.conf8
-rw-r--r--sbin/devfs/devfs.rules1
-rw-r--r--sbin/devmatch/devmatch.c4
-rw-r--r--sbin/dhclient/tests/Makefile2
-rw-r--r--sbin/dhclient/tests/pcp.sh196
-rw-r--r--sbin/dump/main.c2
-rw-r--r--sbin/dumpfs/dumpfs.c15
-rw-r--r--sbin/fsck_ffs/fsutil.c3
-rw-r--r--sbin/fsck_ffs/setup.c76
-rw-r--r--sbin/fsirand/fsirand.c8
-rw-r--r--sbin/geom/core/geom.c5
-rw-r--r--sbin/geom/misc/subr.c2
-rw-r--r--sbin/growfs/growfs.c19
-rw-r--r--sbin/hastd/ebuf.c18
-rw-r--r--sbin/ifconfig/ifconfig.861
-rw-r--r--sbin/ifconfig/ifconfig.c123
-rw-r--r--sbin/ifconfig/ifconfig.h79
-rw-r--r--sbin/ifconfig/ifvlan.c10
-rw-r--r--sbin/ipf/libipf/interror.c4
-rw-r--r--sbin/ipfw/ipfw.838
-rw-r--r--sbin/ipfw/ipfw2.c132
-rw-r--r--sbin/ipfw/ipfw2.h2
-rw-r--r--sbin/ipfw/tables.c29
-rw-r--r--sbin/kldload/kldload.c32
-rw-r--r--sbin/md5/md5.111
-rw-r--r--sbin/md5/md5.c2
-rw-r--r--sbin/mount/mount.c6
-rw-r--r--sbin/mount_nfs/mount_nfs.85
-rw-r--r--sbin/mount_nfs/mount_nfs.c34
-rw-r--r--sbin/newfs/mkfs.c23
-rw-r--r--sbin/nvmecontrol/ns.c4
-rw-r--r--sbin/pfctl/parse.y35
-rw-r--r--sbin/pfctl/pfctl_altq.c2
-rw-r--r--sbin/pfctl/pfctl_parser.c12
-rw-r--r--sbin/pfctl/tests/files/pf1010.in2
-rw-r--r--sbin/pfctl/tests/files/pf1010.ok2
-rw-r--r--sbin/pfctl/tests/pfctl_test_list.inc1
-rw-r--r--sbin/quotacheck/quotacheck.c2
-rw-r--r--sbin/routed/routed.89
-rw-r--r--sbin/sysctl/sysctl.85
-rw-r--r--sbin/veriexec/veriexec.88
-rw-r--r--sbin/veriexec/veriexec.c214
45 files changed, 959 insertions, 296 deletions
diff --git a/sbin/Makefile.mips b/sbin/Makefile.mips
deleted file mode 100644
index 2d231b0cb2b0..000000000000
--- a/sbin/Makefile.mips
+++ /dev/null
@@ -1,4 +0,0 @@
-# $FreeBSD$
-
-SUBDIR += bsdlabel
-SUBDIR += fdisk
diff --git a/sbin/ddb/ddb.8 b/sbin/ddb/ddb.8
index 0fb9687991e5..54e5aa1b390c 100644
--- a/sbin/ddb/ddb.8
+++ b/sbin/ddb/ddb.8
@@ -150,6 +150,7 @@ and
manual pages.
.Sh SEE ALSO
.Xr ddb 4 ,
+.Xr mac_ddb 4 ,
.Xr textdump 4 ,
.Xr sysctl 8
.Sh HISTORY
diff --git a/sbin/devd/apple.conf b/sbin/devd/apple.conf
index 0729a9c86e7a..0a9143f7b5a5 100644
--- a/sbin/devd/apple.conf
+++ b/sbin/devd/apple.conf
@@ -52,7 +52,7 @@ notify 0 {
match "subsystem" "keys";
match "type" "volume";
match "notify" "down";
- action "mixer vol.volume=-10";
+ action "mixer vol.volume=-10%";
};
notify 0 {
@@ -60,7 +60,7 @@ notify 0 {
match "subsystem" "keys";
match "type" "volume";
match "notify" "up";
- action "mixer vol.volume=+10";
+ action "mixer vol.volume=+10%";
};
# Eject key
diff --git a/sbin/devd/asus.conf b/sbin/devd/asus.conf
index eed369f6ca4d..0074e7a7c55f 100644
--- a/sbin/devd/asus.conf
+++ b/sbin/devd/asus.conf
@@ -14,14 +14,14 @@ notify 0 {
match "system" "ACPI";
match "subsystem" "ASUS";
match "notify" "0x31";
- action "mixer vol.volume=-10";
+ action "mixer vol.volume=-10%";
};
notify 0 {
match "system" "ACPI";
match "subsystem" "ASUS";
match "notify" "0x30";
- action "mixer vol.volume=+10";
+ action "mixer vol.volume=+10%";
};
# The next blocks enable volume hotkeys that can be found on the Asus EeePC
@@ -36,14 +36,14 @@ notify 0 {
match "system" "ACPI";
match "subsystem" "ASUS-Eee";
match "notify" "0x14";
- action "mixer vol.volume=-10";
+ action "mixer vol.volume=-10%";
};
notify 0 {
match "system" "ACPI";
match "subsystem" "ASUS-Eee";
match "notify" "0x15";
- action "mixer vol.volume=+10";
+ action "mixer vol.volume=+10%";
};
# Enable user hotkeys that can be found on the Asus EeePC
diff --git a/sbin/devfs/devfs.rules b/sbin/devfs/devfs.rules
index 9543e20947d9..a92cd03a019b 100644
--- a/sbin/devfs/devfs.rules
+++ b/sbin/devfs/devfs.rules
@@ -26,7 +26,6 @@ add hide
# Requires: devfsrules_hide_all
#
[devfsrules_unhide_basic=2]
-add path log unhide
add path null unhide
add path zero unhide
add path crypto unhide
diff --git a/sbin/devmatch/devmatch.c b/sbin/devmatch/devmatch.c
index fbb05222fa5e..20a57353ecf6 100644
--- a/sbin/devmatch/devmatch.c
+++ b/sbin/devmatch/devmatch.c
@@ -313,7 +313,7 @@ search_hints(const char *bus, const char *dev, const char *pnpinfo)
}
if (bit >= 0 && ((1 << bit) & mask) == 0)
break;
- if (strcmp(cp + 2, "#") == 0) {
+ if (cp[2] == '#') {
if (verbose_flag) {
printf("Ignoring %s (%c) table=%#x tomatch=%#x\n",
cp + 2, *cp, v, ival);
@@ -358,7 +358,7 @@ search_hints(const char *bus, const char *dev, const char *pnpinfo)
break;
if (bit >= 0 && ((1 << bit) & mask) == 0)
break;
- if (strcmp(cp + 2, "#") == 0) {
+ if (cp[2] == '#') {
if (verbose_flag) {
printf("Ignoring %s (%c) table=%#x tomatch=%#x\n",
cp + 2, *cp, v, ival);
diff --git a/sbin/dhclient/tests/Makefile b/sbin/dhclient/tests/Makefile
index 822699c9dd01..ce4c7acb822e 100644
--- a/sbin/dhclient/tests/Makefile
+++ b/sbin/dhclient/tests/Makefile
@@ -2,6 +2,8 @@
.PATH: ${.CURDIR:H}
+ATF_TESTS_SH= pcp
+
PLAIN_TESTS_C= option-domain-search_test
SRCS.option-domain-search_test= alloc.c convert.c hash.c options.c \
tables.c fake.c option-domain-search.c
diff --git a/sbin/dhclient/tests/pcp.sh b/sbin/dhclient/tests/pcp.sh
new file mode 100644
index 000000000000..4875a10a10ce
--- /dev/null
+++ b/sbin/dhclient/tests/pcp.sh
@@ -0,0 +1,196 @@
+#!/usr/bin/env atf-sh
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright 2022 John-Mark Gurney
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+# OWNER 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.
+
+#
+# Run the tests:
+# make WITH_TESTS=yes -j 4 all install && kyua test -k /usr/tests/Kyuafile sbin/dhclient/pcp
+#
+# Output last run:
+# kyua report --verbose -r $(ls -tr ~/.kyua/store/results.*.db | tail -n 1)
+
+. $(atf_get_srcdir)/../../sys/common/vnet.subr
+
+generic_dhcp_cleanup()
+{
+
+ # clean up programs
+ kill $(cat dhclient.test.pid) $(cat dhcpd.pid)
+
+ # clean up files
+ rm -f dhclient.dhcpd.conf lease.dhclient.test dhclient.test.pid
+
+ vnet_cleanup
+}
+
+atf_test_case normal cleanup
+normal_head()
+{
+ atf_set descr 'test dhclient against a server'
+ atf_set require.user root
+}
+
+normal_body()
+{
+ dhcpd=$(which dhcpd)
+
+ if ! [ -x "$dhcpd" ]; then
+ atf_skip "ISC dhcp server (isc-dhcp44-server) not installed"
+ fi
+
+ vnet_init
+
+ epair=$(vnet_mkepair)
+
+ vnet_mkjail dhclient_normal_test ${epair}b
+
+ # Set IP on server iface
+ ifconfig ${epair}a 192.0.2.2/24 up
+
+ # Create dhcp server config
+ cat > dhclient.dhcpd.conf << EOF
+default-lease-time 36000;
+max-lease-time 86400;
+authoritative;
+subnet 192.0.2.0 netmask 255.255.255.0 {
+ range 192.0.2.10 192.0.2.10;
+ option routers 192.0.2.2;
+ option domain-name-servers 192.0.2.2;
+}
+EOF
+
+ # Start dhcp server
+ touch dhcpd.leases.conf
+ atf_check -e ignore ${dhcpd} -cf ./dhclient.dhcpd.conf -lf ./dhcpd.leases.conf -pf ./dhcpd.pid ${epair}a
+
+ # Expect that we get an IP assigned
+ atf_check -e match:'DHCPACK from 192.0.2.2' jexec dhclient_normal_test dhclient -c /dev/null -l ./lease.dhclient.test -p ./dhclient.test.pid ${epair}b
+
+ # And it's the correct one
+ atf_check -o match:'inet 192.0.2.10' jexec dhclient_normal_test ifconfig ${epair}b
+
+}
+
+normal_cleanup()
+{
+
+ generic_dhcp_cleanup
+}
+
+atf_test_case pcp cleanup
+pcp_head()
+{
+ atf_set descr 'test dhclient on pcp interface'
+ atf_set require.user root
+}
+
+pcp_body()
+{
+ dhcpd=$(which dhcpd)
+
+ if ! [ -x "$dhcpd" ]; then
+ atf_skip "ISC dhcp server (isc-dhcp44-server) not installed"
+ fi
+
+ vnet_init
+
+ epair=$(vnet_mkepair)
+
+ # Server side needs to be up to pass packets
+ ifconfig ${epair}a up
+
+ # Make sure necessary netgraph modules are loaded
+ kldstat -q -n ng_ether || kldload ng_ether
+ kldstat -q -n ng_iface || kldload ng_iface
+ kldstat -q -n ng_vlan || kldload ng_vlan
+
+ # create vlan, and attach epair to it (has incoming/outgoing vlan
+ # 0 tagged frames)
+ ngctl mkpeer ${epair}a: vlan lower downstream
+
+ # create new interface on other side of vlan (untagged/pcp)
+ ngctl mkpeer ${epair}a:lower. eiface vlan0 ether
+
+ # get the interface created
+ ngiface=$(ngctl show ${epair}a:lower.vlan0 | head -n 1 | awk '{ print $2}')
+
+ # schedule it for clean up
+ echo ${ngiface} >> ngctl.shutdown
+
+ # set the filter on it
+ ngctl msg ${epair}a:lower. 'addfilter { vlan=0 hook="vlan0" }'
+
+ vnet_mkjail dhclient_pcp_test ${epair}b
+
+ # Set IP on server iface
+ ifconfig ${ngiface} up 192.0.2.2/24
+
+ # Set pcp in jail
+ jexec dhclient_pcp_test ifconfig ${epair}b pcp 0 up
+
+ # Create dhcp server config
+ cat > dhclient.dhcpd.conf << EOF
+default-lease-time 36000;
+max-lease-time 86400;
+authoritative;
+subnet 192.0.2.0 netmask 255.255.255.0 {
+ range 192.0.2.10 192.0.2.10;
+ option routers 192.0.2.2;
+ option domain-name-servers 192.0.2.2;
+}
+EOF
+
+ # Start dhcp server
+ touch dhcpd.leases.conf
+ atf_check -e ignore ${dhcpd} -cf ./dhclient.dhcpd.conf -lf ./dhcpd.leases.conf -pf ./dhcpd.pid ${ngiface}
+
+ # Expect that we get an IP assigned
+ atf_check -e match:'DHCPACK from 192.0.2.2' jexec dhclient_pcp_test dhclient -c /dev/null -l ./lease.dhclient.test -p ./dhclient.test.pid ${epair}b
+
+ # And it's the correct one
+ atf_check -o match:'inet 192.0.2.10' jexec dhclient_pcp_test ifconfig ${epair}b
+}
+
+pcp_cleanup()
+{
+
+ generic_dhcp_cleanup
+
+ # Clean up netgraph nodes
+ for i in $(cat ngctl.shutdown); do
+ ngctl shutdown ${i}:
+ done
+ rm -f ngctl.shutdown
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case normal
+ atf_add_test_case pcp
+}
+
diff --git a/sbin/dump/main.c b/sbin/dump/main.c
index 8752f2c1bea5..779db5fb4b43 100644
--- a/sbin/dump/main.c
+++ b/sbin/dump/main.c
@@ -457,7 +457,7 @@ main(int argc, char *argv[])
msgtail("to %s\n", tape);
sync();
- if ((ret = sbget(diskfd, &sblock, STDSB)) != 0) {
+ if ((ret = sbget(diskfd, &sblock, UFS_STDSB, UFS_NOCSUM)) != 0) {
switch (ret) {
case ENOENT:
warn("Cannot find file system superblock");
diff --git a/sbin/dumpfs/dumpfs.c b/sbin/dumpfs/dumpfs.c
index 7c43cf4489a8..6a586ffb95ec 100644
--- a/sbin/dumpfs/dumpfs.c
+++ b/sbin/dumpfs/dumpfs.c
@@ -130,7 +130,13 @@ main(int argc, char *argv[])
usage();
while ((name = *argv++) != NULL) {
- if (ufs_disk_fillout(&disk, name) == -1) {
+ if (ufs_disk_fillout_blank(&disk, name) == -1) {
+ ufserr(name);
+ eval |= 1;
+ continue;
+ }
+ disk.d_lookupflags |= UFS_NOHASHFAIL;
+ if (sbread(&disk) == -1) {
ufserr(name);
eval |= 1;
continue;
@@ -233,8 +239,8 @@ dumpfs(const char *name, int dosb)
printf("sbsize\t%d\tcgsize\t%d\tcgoffset %d\tcgmask\t0x%08x\n",
afs.fs_sbsize, afs.fs_cgsize, afs.fs_old_cgoffset,
afs.fs_old_cgmask);
- printf("csaddr\t%d\tcssize\t%d\n",
- afs.fs_old_csaddr, afs.fs_cssize);
+ printf("csaddr\t%jd\tcssize\t%d\n",
+ (intmax_t)afs.fs_csaddr, afs.fs_cssize);
printf("rotdelay %dms\trps\t%d\ttrackskew %d\tinterleave %d\n",
afs.fs_old_rotdelay, afs.fs_old_rps, afs.fs_old_trackskew,
afs.fs_old_interleave);
@@ -308,9 +314,6 @@ dumpfs(const char *name, int dosb)
afs.fs_volname, (uintmax_t)afs.fs_swuid,
(uintmax_t)afs.fs_providersize);
printf("\ncs[].cs_(nbfree,ndir,nifree,nffree):\n\t");
- afs.fs_csp = calloc(1, afs.fs_cssize);
- if (bread(&disk, fsbtodb(&afs, afs.fs_csaddr), afs.fs_csp, afs.fs_cssize) == -1)
- goto err;
for (i = 0; i < afs.fs_ncg; i++) {
struct csum *cs = &afs.fs_cs(&afs, i);
if (i && i % 4 == 0)
diff --git a/sbin/fsck_ffs/fsutil.c b/sbin/fsck_ffs/fsutil.c
index 711c9bb63549..424f8d9794f6 100644
--- a/sbin/fsck_ffs/fsutil.c
+++ b/sbin/fsck_ffs/fsutil.c
@@ -129,7 +129,8 @@ reply(const char *question)
if (preen)
pfatal("INTERNAL ERROR: GOT TO reply()");
- persevere = !strcmp(question, "CONTINUE");
+ persevere = strcmp(question, "CONTINUE") == 0 ||
+ strcmp(question, "LOOK FOR ALTERNATE SUPERBLOCKS") == 0;
printf("\n");
if (!persevere && (nflag || (fswritefd < 0 && bkgrdflag == 0))) {
printf("%s? no\n\n", question);
diff --git a/sbin/fsck_ffs/setup.c b/sbin/fsck_ffs/setup.c
index 0f0d9b61a076..cb95d18859b0 100644
--- a/sbin/fsck_ffs/setup.c
+++ b/sbin/fsck_ffs/setup.c
@@ -60,8 +60,6 @@ __FBSDID("$FreeBSD$");
struct inoinfo **inphead, **inpsort; /* info about all inodes */
-struct bufarea asblk;
-#define altsblock (*asblk.b_un.b_fs)
#define POWEROF2(num) (((num) & ((num) - 1)) == 0)
static int calcsb(char *dev, int devfd, struct fs *fs);
@@ -163,10 +161,6 @@ setup(char *dev)
pfatal("from before 2002 with the command ``fsck -c 2''\n");
exit(EEXIT);
}
- if ((asblk.b_flags & B_DIRTY) != 0 && !bflag) {
- memmove(&altsblock, &sblock, (size_t)sblock.fs_sbsize);
- flush(fswritefd, &asblk);
- }
if (preen == 0 && yflag == 0 && sblock.fs_magic == FS_UFS2_MAGIC &&
fswritefd != -1 && chkrecovery(fsreadfd) == 0 &&
reply("SAVE DATA TO FIND ALTERNATE SUPERBLOCKS") != 0)
@@ -252,18 +246,20 @@ int
readsb(int listerr)
{
off_t super;
- int bad, ret;
+ int ret, flags;
struct fs *fs;
- super = bflag ? bflag * dev_bsize :
- sbhashfailed ? STDSB_NOHASHFAIL_NOMSG : STDSB_NOMSG;
+ super = bflag ? bflag * dev_bsize : UFS_STDSB;
+ flags = sbhashfailed ? UFS_NOHASHFAIL | UFS_NOMSG : UFS_NOMSG;
readcnt[sblk.b_type]++;
- while ((ret = sbget(fsreadfd, &fs, super)) != 0) {
+ while ((ret = sbget(fsreadfd, &fs, super, flags)) != 0) {
switch (ret) {
case EINTEGRITY:
- if (bflag || super == STDSB_NOHASHFAIL_NOMSG)
+ if (bflag || (super == UFS_STDSB &&
+ flags == (UFS_NOHASHFAIL | UFS_NOMSG)))
return (0);
- super = STDSB_NOHASHFAIL_NOMSG;
+ super = UFS_STDSB;
+ flags = UFS_NOHASHFAIL | UFS_NOMSG;
sbhashfailed = 1;
continue;
case ENOENT:
@@ -292,58 +288,6 @@ readsb(int listerr)
sblk.b_bno = sblock.fs_sblockactualloc / dev_bsize;
sblk.b_size = SBLOCKSIZE;
/*
- * Compare all fields that should not differ in alternate super block.
- * When an alternate super-block is specified this check is skipped.
- */
- if (bflag)
- goto out;
- getblk(&asblk, cgsblock(&sblock, sblock.fs_ncg - 1), sblock.fs_sbsize);
- if (asblk.b_errs)
- return (0);
- bad = 0;
-#define CHK(x, y) \
- if (altsblock.x != sblock.x) { \
- bad++; \
- if (listerr && debug) \
- printf("SUPER BLOCK VS ALTERNATE MISMATCH %s: " y " vs " y "\n", \
- #x, (intmax_t)sblock.x, (intmax_t)altsblock.x); \
- }
- CHK(fs_sblkno, "%jd");
- CHK(fs_cblkno, "%jd");
- CHK(fs_iblkno, "%jd");
- CHK(fs_dblkno, "%jd");
- CHK(fs_ncg, "%jd");
- CHK(fs_bsize, "%jd");
- CHK(fs_fsize, "%jd");
- CHK(fs_frag, "%jd");
- CHK(fs_bmask, "%#jx");
- CHK(fs_fmask, "%#jx");
- CHK(fs_bshift, "%jd");
- CHK(fs_fshift, "%jd");
- CHK(fs_fragshift, "%jd");
- CHK(fs_fsbtodb, "%jd");
- CHK(fs_sbsize, "%jd");
- CHK(fs_nindir, "%jd");
- CHK(fs_inopb, "%jd");
- CHK(fs_cssize, "%jd");
- CHK(fs_ipg, "%jd");
- CHK(fs_fpg, "%jd");
- CHK(fs_magic, "%#jx");
-#undef CHK
- if (bad) {
- if (listerr == 0)
- return (0);
- if (preen)
- printf("%s: ", cdevname);
- printf(
- "VALUES IN SUPER BLOCK LSB=%jd DISAGREE WITH THOSE IN\n"
- "LAST ALTERNATE LSB=%jd\n",
- sblk.b_bno, asblk.b_bno);
- if (reply("IGNORE ALTERNATE SUPER BLOCK") == 0)
- return (0);
- }
-out:
- /*
* If not yet done, update UFS1 superblock with new wider fields.
*/
if (sblock.fs_magic == FS_UFS1_MAGIC &&
@@ -371,10 +315,8 @@ sblock_init(void)
fsmodified = 0;
lfdir = 0;
initbarea(&sblk, BT_SUPERBLK);
- initbarea(&asblk, BT_SUPERBLK);
sblk.b_un.b_buf = Malloc(SBLOCKSIZE);
- asblk.b_un.b_buf = Malloc(SBLOCKSIZE);
- if (sblk.b_un.b_buf == NULL || asblk.b_un.b_buf == NULL)
+ if (sblk.b_un.b_buf == NULL)
errx(EEXIT, "cannot allocate space for superblock");
dev_bsize = secsize = DEV_BSIZE;
}
diff --git a/sbin/fsirand/fsirand.c b/sbin/fsirand/fsirand.c
index c4db8848f18b..90305416f556 100644
--- a/sbin/fsirand/fsirand.c
+++ b/sbin/fsirand/fsirand.c
@@ -112,7 +112,7 @@ fsirand(char *device)
struct fs *sblock;
ino_t inumber;
ufs2_daddr_t dblk;
- int devfd, n, cg, ret;
+ int devfd, n, cg;
u_int32_t bsize = DEV_BSIZE;
if ((devfd = open(device, printonly ? O_RDONLY : O_RDWR)) < 0) {
@@ -124,10 +124,10 @@ fsirand(char *device)
dp2 = NULL;
/* Read in master superblock */
- if ((ret = sbget(devfd, &sblock, STDSB)) != 0) {
- switch (ret) {
+ if ((errno = sbget(devfd, &sblock, UFS_STDSB, UFS_NOCSUM)) != 0) {
+ switch (errno) {
case ENOENT:
- warn("Cannot find file system superblock");
+ warnx("Cannot find file system superblock");
return (1);
default:
warn("Unable to read file system superblock");
diff --git a/sbin/geom/core/geom.c b/sbin/geom/core/geom.c
index 9b43910b88f9..535d7d9f6f21 100644
--- a/sbin/geom/core/geom.c
+++ b/sbin/geom/core/geom.c
@@ -503,7 +503,10 @@ run_command(int argc, char *argv[])
}
if (errstr != NULL && errstr[0] != '\0') {
warnx("%s", errstr);
- if (strncmp(errstr, "warning: ", strlen("warning: ")) != 0) {
+ /* Suppress EXIT_FAILURE for warnings */
+ if (strncmp(errstr, "warning: ", strlen("warning: ")) == 0)
+ req->nerror = 0;
+ if (req->nerror != 0) {
gctl_free(req);
exit(EXIT_FAILURE);
}
diff --git a/sbin/geom/misc/subr.c b/sbin/geom/misc/subr.c
index 3985ae56edc6..297a1cc09a36 100644
--- a/sbin/geom/misc/subr.c
+++ b/sbin/geom/misc/subr.c
@@ -398,6 +398,8 @@ gctl_error(struct gctl_req *req, const char *error, ...)
fprintf(stderr, "\n");
}
va_end(ap);
+ if (req != NULL && req->nerror == 0)
+ req->nerror = EINVAL;
}
static void *
diff --git a/sbin/growfs/growfs.c b/sbin/growfs/growfs.c
index 1f1bcf82c965..4a8d935d91c7 100644
--- a/sbin/growfs/growfs.c
+++ b/sbin/growfs/growfs.c
@@ -427,6 +427,7 @@ initcg(int cylno, time_t modtime, int fso, unsigned int Nflag)
sblock.fs_dsize += dlower;
}
sblock.fs_dsize += acg.cg_ndblk - dupper;
+ sblock.fs_old_dsize = sblock.fs_dsize;
if ((i = dupper % sblock.fs_frag)) {
acg.cg_frsum[sblock.fs_frag - i]++;
for (d = dupper + sblock.fs_frag - i; dupper < d; dupper++) {
@@ -560,7 +561,7 @@ static void
updjcg(int cylno, time_t modtime, int fsi, int fso, unsigned int Nflag)
{
DBG_FUNC("updjcg")
- ufs2_daddr_t cbase, dmax, dupper;
+ ufs2_daddr_t cbase, dmax;
struct csum *cs;
int i, k;
int j = 0;
@@ -607,9 +608,6 @@ updjcg(int cylno, time_t modtime, int fsi, int fso, unsigned int Nflag)
dmax = cbase + sblock.fs_fpg;
if (dmax > sblock.fs_size)
dmax = sblock.fs_size;
- dupper = cgdmin(&sblock, cylno) - cbase;
- if (cylno == 0) /* XXX fscs may be relocated */
- dupper += howmany(sblock.fs_cssize, sblock.fs_fsize);
/*
* Set pointer to the cylinder summary for our cylinder group.
@@ -639,6 +637,7 @@ updjcg(int cylno, time_t modtime, int fsi, int fso, unsigned int Nflag)
DBG_PRINT0("\n");
acg.cg_ndblk = dmax - cbase;
sblock.fs_dsize += acg.cg_ndblk - aocg.cg_ndblk;
+ sblock.fs_old_dsize = sblock.fs_dsize;
if (sblock.fs_contigsumsize > 0)
acg.cg_nclusterblks = acg.cg_ndblk / sblock.fs_frag;
@@ -816,6 +815,10 @@ updcsloc(time_t modtime, int fsi, int fso, unsigned int Nflag)
DBG_LEAVE;
return;
}
+ /* Adjust fs_dsize by added summary blocks */
+ sblock.fs_dsize -= howmany(sblock.fs_cssize, sblock.fs_fsize) -
+ howmany(osblock.fs_cssize, osblock.fs_fsize);
+ sblock.fs_old_dsize = sblock.fs_dsize;
ocscg = dtog(&osblock, osblock.fs_csaddr);
cs = fscs + ocscg;
@@ -1452,7 +1455,7 @@ main(int argc, char **argv)
/*
* Read the current superblock, and take a backup.
*/
- if ((ret = sbget(fsi, &fs, STDSB)) != 0) {
+ if ((ret = sbget(fsi, &fs, UFS_STDSB, 0)) != 0) {
switch (ret) {
case ENOENT:
errx(1, "superblock not recognized");
@@ -1510,7 +1513,8 @@ main(int argc, char **argv)
"filesystem size %s", newsizebuf, oldsizebuf);
}
- sblock.fs_size = dbtofsb(&osblock, size / DEV_BSIZE);
+ sblock.fs_old_size = sblock.fs_size =
+ dbtofsb(&osblock, size / DEV_BSIZE);
sblock.fs_providersize = dbtofsb(&osblock, mediasize / DEV_BSIZE);
/*
@@ -1631,7 +1635,8 @@ main(int argc, char **argv)
sblock.fs_ncg--;
if (sblock.fs_magic == FS_UFS1_MAGIC)
sblock.fs_old_ncyl = sblock.fs_ncg * sblock.fs_old_cpg;
- sblock.fs_size = sblock.fs_ncg * sblock.fs_fpg;
+ sblock.fs_old_size = sblock.fs_size =
+ sblock.fs_ncg * sblock.fs_fpg;
}
/*
diff --git a/sbin/hastd/ebuf.c b/sbin/hastd/ebuf.c
index 22d3251ec75c..83f99f834288 100644
--- a/sbin/hastd/ebuf.c
+++ b/sbin/hastd/ebuf.c
@@ -70,12 +70,14 @@ struct ebuf *
ebuf_alloc(size_t size)
{
struct ebuf *eb;
+ size_t page_size;
int rerrno;
eb = malloc(sizeof(*eb));
if (eb == NULL)
return (NULL);
- size += PAGE_SIZE;
+ page_size = getpagesize();
+ size += page_size;
eb->eb_start = malloc(size);
if (eb->eb_start == NULL) {
rerrno = errno;
@@ -88,7 +90,7 @@ ebuf_alloc(size_t size)
* We set start address for real data not at the first entry, because
* we want to be able to add data at the front.
*/
- eb->eb_used = eb->eb_start + PAGE_SIZE / 4;
+ eb->eb_used = eb->eb_start + page_size / 4;
eb->eb_size = 0;
eb->eb_magic = EBUF_MAGIC;
@@ -215,17 +217,18 @@ static int
ebuf_head_extend(struct ebuf *eb, size_t size)
{
unsigned char *newstart, *newused;
- size_t newsize;
+ size_t newsize, page_size;
PJDLOG_ASSERT(eb != NULL && eb->eb_magic == EBUF_MAGIC);
- newsize = eb->eb_end - eb->eb_start + (PAGE_SIZE / 4) + size;
+ page_size = getpagesize();
+ newsize = eb->eb_end - eb->eb_start + (page_size / 4) + size;
newstart = malloc(newsize);
if (newstart == NULL)
return (-1);
newused =
- newstart + (PAGE_SIZE / 4) + size + (eb->eb_used - eb->eb_start);
+ newstart + (page_size / 4) + size + (eb->eb_used - eb->eb_start);
bcopy(eb->eb_used, newused, eb->eb_size);
@@ -243,11 +246,12 @@ static int
ebuf_tail_extend(struct ebuf *eb, size_t size)
{
unsigned char *newstart;
- size_t newsize;
+ size_t newsize, page_size;
PJDLOG_ASSERT(eb != NULL && eb->eb_magic == EBUF_MAGIC);
- newsize = eb->eb_end - eb->eb_start + size + ((3 * PAGE_SIZE) / 4);
+ page_size = getpagesize();
+ newsize = eb->eb_end - eb->eb_start + size + ((3 * page_size) / 4);
newstart = realloc(eb->eb_start, newsize);
if (newstart == NULL)
diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8
index bd1a79bee897..f95607b77cf2 100644
--- a/sbin/ifconfig/ifconfig.8
+++ b/sbin/ifconfig/ifconfig.8
@@ -28,7 +28,7 @@
.\" From: @(#)ifconfig.8 8.3 (Berkeley) 1/5/94
.\" $FreeBSD$
.\"
-.Dd April 11, 2022
+.Dd July 11, 2022
.Dt IFCONFIG 8
.Os
.Sh NAME
@@ -199,6 +199,12 @@ Only one option
should be specified as later override previous ones
.Ar groupname
may contain shell patterns in which case it should be quoted.
+.Pp
+Setting
+.Ar groupname
+to
+.Cm all
+selects all interfaces.
.It Fl g Ar groupname
Limit the output to the members of the specified
.Ar groupname .
@@ -212,7 +218,7 @@ or
.Fl C ,
then
.Nm
-lists names of interfaces beloning to
+lists names of interfaces belonging to
.Ar groupname .
Any other flags and arguments are ignored in this case.
.Pp
@@ -221,6 +227,12 @@ Only one option
should be specified as later override previous ones
.Ar groupname
may contain shell patterns in which case it should be quoted.
+.Pp
+Setting
+.Ar groupname
+to
+.Cm all
+selects all interfaces.
.It Fl k
Print keying information for the
.Ar interface ,
@@ -265,20 +277,20 @@ of the supported media for the specified interface.
.It Fl n
Disable automatic loading of network interface drivers.
.Pp
-If the network interface driver is not present in the kernel then
+By default if the network interface driver is not present in the kernel
+then
.Nm
will attempt to load it.
-This flag disables this behavior.
.It Fl u
Display only the interfaces that are up.
.It Fl v
Get more verbose status for an interface.
.It Ar address
-For the DARPA-Internet family,
+For the inet family,
the address is either a host name present in the host name data
base,
.Xr hosts 5 ,
-or a DARPA Internet address expressed in the Internet standard
+or an IPv4 address expressed in the Internet standard
.Dq dot notation .
.Pp
It is also possible to use the CIDR notation (also known as the
@@ -406,8 +418,8 @@ Enable the use of the Address Resolution Protocol
.Pq Xr arp 4
in mapping
between network level addresses and link level addresses (default).
-This is currently implemented for mapping between DARPA Internet addresses
-and IEEE 802 48-bit MAC addresses (Ethernet, FDDI, and Token Ring addresses).
+This is currently implemented for mapping between Internet Protocol addresses
+and IEEE 802 48-bit MAC addresses (Ethernet addresses).
.It Fl arp
Disable the use of the Address Resolution Protocol
.Pq Xr arp 4 .
@@ -419,6 +431,23 @@ and will never send any requests.
If the Address Resolution Protocol is enabled,
the host will perform normally,
sending out requests and listening for replies.
+.It Cm stickyarp
+Enable the so-called sticky ARP mode for the interface.
+If this option is enabled on the given interface, any resolved address is
+marked as a static one and never expires. This may be used to increase
+security of the network by preventing ARP spoofing or to reduce latency for
+high-performance Ethernet networks where the time needed for ARP resolution is
+too high. Please note that a similar feature is also provided for bridges. See
+the sticky option in the
+.Sx Bridge Interface Parameters
+section. Enabling this
+option may impact techniques which rely on ARP expiration/overwriting feature
+such as load-balancers or high-availabity solutions such as
+.Xr carp 4 .
+.It Fl stickyarp
+Disable the so-called sticky ARP mode for the interface (default).
+Resolved addresses will expire normally respecting the kernel ARP
+configuration.
.It Cm broadcast
(Inet only.)
Specify the address to use to represent broadcasts to the
@@ -458,13 +487,10 @@ Assign the interface to a
Any interface can be in multiple groups.
.Pp
Cloned interfaces are members of their interface family group by default.
-For example, a PPP interface such as
-.Em ppp0
-is a member of the PPP interface family group,
-.Em ppp .
-.\" The interface(s) the default route(s) point to are members of the
-.\" .Em egress
-.\" interface group.
+For example, a VLAN interface such as
+.Em vlan10
+is a member of the VLAN interface family group,
+.Em vlan .
.It Cm -group Ar groupname
Remove the interface from the given
.Dq group .
@@ -491,9 +517,10 @@ Specify tunnel FIB.
A FIB
.Ar fib_number
is assigned to all packets encapsulated by tunnel interface, e.g.,
-.Xr gif 4
+.Xr gif 4 ,
+.Xr gre 4
and
-.Xr gre 4 .
+.Xr vxlan 4 .
.It Cm maclabel Ar label
If Mandatory Access Control support is enabled in the kernel,
set the MAC label to
diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c
index 9e7d38d4c2a4..ec8a3fd52803 100644
--- a/sbin/ifconfig/ifconfig.c
+++ b/sbin/ifconfig/ifconfig.c
@@ -44,6 +44,7 @@ static const char rcsid[] =
#include <sys/ioctl.h>
#include <sys/module.h>
#include <sys/linker.h>
+#include <sys/nv.h>
#include <sys/queue.h>
#include <sys/socket.h>
#include <sys/time.h>
@@ -991,6 +992,8 @@ top:
p->c_name);
p->c_u.c_func2(argv[1], argv[2], s, afp);
argc -= 2, argv += 2;
+ } else if (p->c_parameter == SPARAM && p->c_u.c_func3) {
+ p->c_u.c_func3(*argv, p->c_sparameter, s, afp);
} else if (p->c_u.c_func)
p->c_u.c_func(*argv, p->c_parameter, s, afp);
argc--, argv++;
@@ -1251,6 +1254,53 @@ setifcap(const char *vname, int value, int s, const struct afswtch *afp)
Perror(vname);
}
+void
+setifcapnv(const char *vname, const char *arg, int s, const struct afswtch *afp)
+{
+ nvlist_t *nvcap;
+ void *buf;
+ char *marg, *mopt;
+ size_t nvbuflen;
+ bool neg;
+
+ if (ioctl(s, SIOCGIFCAP, (caddr_t)&ifr) < 0)
+ Perror("ioctl (SIOCGIFCAP)");
+ if ((ifr.ifr_curcap & IFCAP_NV) == 0) {
+ warnx("IFCAP_NV not supported");
+ return; /* Not exit() */
+ }
+
+ marg = strdup(arg);
+ if (marg == NULL)
+ Perror("strdup");
+ nvcap = nvlist_create(0);
+ if (nvcap == NULL)
+ Perror("nvlist_create");
+ while ((mopt = strsep(&marg, ",")) != NULL) {
+ neg = *mopt == '-';
+ if (neg)
+ mopt++;
+ if (strcmp(mopt, "rxtls") == 0) {
+ nvlist_add_bool(nvcap, "rxtls4", !neg);
+ nvlist_add_bool(nvcap, "rxtls6", !neg);
+ } else {
+ nvlist_add_bool(nvcap, mopt, !neg);
+ }
+ }
+ buf = nvlist_pack(nvcap, &nvbuflen);
+ if (buf == NULL) {
+ errx(1, "nvlist_pack error");
+ exit(1);
+ }
+ ifr.ifr_cap_nv.buf_length = ifr.ifr_cap_nv.length = nvbuflen;
+ ifr.ifr_cap_nv.buffer = buf;
+ if (ioctl(s, SIOCSIFCAPNV, (caddr_t)&ifr) < 0)
+ Perror(vname);
+ free(buf);
+ nvlist_destroy(nvcap);
+ free(marg);
+}
+
static void
setifmetric(const char *val, int dummy __unused, int s,
const struct afswtch *afp)
@@ -1357,7 +1407,7 @@ unsetifdescr(const char *val, int value, int s, const struct afswtch *afp)
#define IFFBITS \
"\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\7RUNNING" \
"\10NOARP\11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX\15LINK0\16LINK1\17LINK2" \
-"\20MULTICAST\22PPROMISC\23MONITOR\24STATICARP"
+"\20MULTICAST\22PPROMISC\23MONITOR\24STATICARP\25STICKYARP"
#define IFCAPBITS \
"\020\1RXCSUM\2TXCSUM\3NETCONS\4VLAN_MTU\5VLAN_HWTAGGING\6JUMBO_MTU\7POLLING" \
@@ -1375,8 +1425,12 @@ status(const struct afswtch *afp, const struct sockaddr_dl *sdl,
struct ifaddrs *ifa)
{
struct ifaddrs *ift;
- int allfamilies, s;
struct ifstat ifs;
+ nvlist_t *nvcap;
+ const char *nvname;
+ void *buf, *cookie;
+ int allfamilies, s, type;
+ bool first, val;
if (afp == NULL) {
allfamilies = 1;
@@ -1421,13 +1475,62 @@ status(const struct afswtch *afp, const struct sockaddr_dl *sdl,
}
if (ioctl(s, SIOCGIFCAP, (caddr_t)&ifr) == 0) {
- if (ifr.ifr_curcap != 0) {
+ if ((ifr.ifr_curcap & IFCAP_NV) != 0) {
+ buf = malloc(IFR_CAP_NV_MAXBUFSIZE);
+ if (buf == NULL)
+ Perror("malloc");
+ ifr.ifr_cap_nv.buffer = buf;
+ ifr.ifr_cap_nv.buf_length = IFR_CAP_NV_MAXBUFSIZE;
+ if (ioctl(s, SIOCGIFCAPNV, (caddr_t)&ifr) != 0)
+ Perror("ioctl (SIOCGIFCAPNV)");
+ nvcap = nvlist_unpack(ifr.ifr_cap_nv.buffer,
+ ifr.ifr_cap_nv.length, 0);
+ if (nvcap == NULL)
+ Perror("nvlist_unpack");
+ printf("\toptions");
+ cookie = NULL;
+ for (first = true;; first = false) {
+ nvname = nvlist_next(nvcap, &type, &cookie);
+ if (nvname == NULL) {
+ printf("\n");
+ break;
+ }
+ if (type == NV_TYPE_BOOL) {
+ val = nvlist_get_bool(nvcap, nvname);
+ if (val) {
+ printf("%c%s",
+ first ? ' ' : ',', nvname);
+ }
+ }
+ }
+ if (supmedia) {
+ printf("\tcapabilities");
+ cookie = NULL;
+ for (first = true;; first = false) {
+ nvname = nvlist_next(nvcap, &type,
+ &cookie);
+ if (nvname == NULL) {
+ printf("\n");
+ break;
+ }
+ if (type == NV_TYPE_BOOL)
+ printf("%c%s", first ? ' ' :
+ ',', nvname);
+ }
+ }
+ nvlist_destroy(nvcap);
+ free(buf);
+
+ if (ioctl(s, SIOCGIFCAP, (caddr_t)&ifr) != 0)
+ Perror("ioctl (SIOCGIFCAP)");
+ } else if (ifr.ifr_curcap != 0) {
printb("\toptions", ifr.ifr_curcap, IFCAPBITS);
putchar('\n');
- }
- if (supmedia && ifr.ifr_reqcap != 0) {
- printb("\tcapabilities", ifr.ifr_reqcap, IFCAPBITS);
- putchar('\n');
+ if (supmedia && ifr.ifr_reqcap != 0) {
+ printb("\tcapabilities", ifr.ifr_reqcap,
+ IFCAPBITS);
+ putchar('\n');
+ }
}
}
@@ -1668,6 +1771,8 @@ static struct cmd basic_cmds[] = {
DEF_CMD("-mextpg", -IFCAP_MEXTPG, setifcap),
DEF_CMD("staticarp", IFF_STATICARP, setifflags),
DEF_CMD("-staticarp", -IFF_STATICARP, setifflags),
+ DEF_CMD("stickyarp", IFF_STICKYARP, setifflags),
+ DEF_CMD("-stickyarp", -IFF_STICKYARP, setifflags),
DEF_CMD("rxcsum6", IFCAP_RXCSUM_IPV6, setifcap),
DEF_CMD("-rxcsum6", -IFCAP_RXCSUM_IPV6, setifcap),
DEF_CMD("txcsum6", IFCAP_TXCSUM_IPV6, setifcap),
@@ -1694,6 +1799,10 @@ static struct cmd basic_cmds[] = {
DEF_CMD("-lro", -IFCAP_LRO, setifcap),
DEF_CMD("txtls", IFCAP_TXTLS, setifcap),
DEF_CMD("-txtls", -IFCAP_TXTLS, setifcap),
+ DEF_CMD_SARG("rxtls", IFCAP2_RXTLS4_NAME "," IFCAP2_RXTLS6_NAME,
+ setifcapnv),
+ DEF_CMD_SARG("-rxtls", "-"IFCAP2_RXTLS4_NAME ",-" IFCAP2_RXTLS6_NAME,
+ setifcapnv),
DEF_CMD("wol", IFCAP_WOL, setifcap),
DEF_CMD("-wol", -IFCAP_WOL, setifcap),
DEF_CMD("wol_ucast", IFCAP_WOL_UCAST, setifcap),
diff --git a/sbin/ifconfig/ifconfig.h b/sbin/ifconfig/ifconfig.h
index 2c0b8a100b0d..26f68d67cec2 100644
--- a/sbin/ifconfig/ifconfig.h
+++ b/sbin/ifconfig/ifconfig.h
@@ -46,7 +46,10 @@ struct afswtch;
struct cmd;
typedef void c_func(const char *cmd, int arg, int s, const struct afswtch *afp);
-typedef void c_func2(const char *arg1, const char *arg2, int s, const struct afswtch *afp);
+typedef void c_func2(const char *arg1, const char *arg2, int s,
+ const struct afswtch *afp);
+typedef void c_func3(const char *cmd, const char *arg, int s,
+ const struct afswtch *afp);
struct cmd {
const char *c_name;
@@ -54,9 +57,12 @@ struct cmd {
#define NEXTARG 0xffffff /* has following arg */
#define NEXTARG2 0xfffffe /* has 2 following args */
#define OPTARG 0xfffffd /* has optional following arg */
+#define SPARAM 0xfffffc /* parameter is string c_sparameter */
+ const char *c_sparameter;
union {
c_func *c_func;
c_func2 *c_func2;
+ c_func3 *c_func3;
} c_u;
int c_iscloneop;
struct cmd *c_next;
@@ -72,15 +78,66 @@ void callback_register(callback_func *, void *);
#define DECL_CMD_FUNC(name, cmd, arg) \
void name(const char *cmd, int arg, int s, const struct afswtch *afp)
#define DECL_CMD_FUNC2(name, arg1, arg2) \
- void name(const char *arg1, const char *arg2, int s, const struct afswtch *afp)
-
-#define DEF_CMD(name, param, func) { name, param, { .c_func = func }, 0, NULL }
-#define DEF_CMD_ARG(name, func) { name, NEXTARG, { .c_func = func }, 0, NULL }
-#define DEF_CMD_OPTARG(name, func) { name, OPTARG, { .c_func = func }, 0, NULL }
-#define DEF_CMD_ARG2(name, func) { name, NEXTARG2, { .c_func2 = func }, 0, NULL }
-#define DEF_CLONE_CMD(name, param, func) { name, param, { .c_func = func }, 1, NULL }
-#define DEF_CLONE_CMD_ARG(name, func) { name, NEXTARG, { .c_func = func }, 1, NULL }
-#define DEF_CLONE_CMD_ARG2(name, func) { name, NEXTARG2, { .c_func2 = func }, 1, NULL }
+ void name(const char *arg1, const char *arg2, int s, \
+ const struct afswtch *afp)
+
+#define DEF_CMD(name, param, func) { \
+ .c_name = (name), \
+ .c_parameter = (param), \
+ .c_u = { .c_func = (func) }, \
+ .c_iscloneop = 0, \
+ .c_next = NULL, \
+}
+#define DEF_CMD_ARG(name, func) { \
+ .c_name = (name), \
+ .c_parameter = NEXTARG, \
+ .c_u = { .c_func = (func) }, \
+ .c_iscloneop = 0, \
+ .c_next = NULL, \
+}
+#define DEF_CMD_OPTARG(name, func) { \
+ .c_name = (name), \
+ .c_parameter = OPTARG, \
+ .c_u = { .c_func = (func) }, \
+ .c_iscloneop = 0, \
+ .c_next = NULL, \
+}
+#define DEF_CMD_ARG2(name, func) { \
+ .c_name = (name), \
+ .c_parameter = NEXTARG2, \
+ .c_u = { .c_func2 = (func) }, \
+ .c_iscloneop = 0, \
+ .c_next = NULL, \
+}
+#define DEF_CMD_SARG(name, sparam, func) { \
+ .c_name = (name), \
+ .c_parameter = SPARAM, \
+ .c_sparameter = (sparam), \
+ .c_u = { .c_func3 = (func) }, \
+ .c_iscloneop = 0, \
+ .c_next = NULL, \
+}
+#define DEF_CLONE_CMD(name, param, func) { \
+ .c_name = (name), \
+ .c_parameter = (param), \
+ .c_u = { .c_func = (func) }, \
+ .c_iscloneop = 1, \
+ .c_next = NULL, \
+}
+#define DEF_CLONE_CMD_ARG(name, func) { \
+ .c_name = (name), \
+ .c_parameter = NEXTARG, \
+ .c_u = { .c_func = (func) }, \
+ .c_iscloneop = 1, \
+ .c_next = NULL, \
+}
+#define DEF_CLONE_CMD_ARG2(name, func) { \
+ .c_name = (name), \
+ .c_parameter = NEXTARG2, \
+ .c_u = { .c_func2 = (func) }, \
+ .c_iscloneop = 1, \
+ .c_next = NULL, \
+}
struct ifaddrs;
struct addrinfo;
@@ -145,6 +202,8 @@ extern int printifname;
extern int exit_code;
void setifcap(const char *, int value, int s, const struct afswtch *);
+void setifcapnv(const char *vname, const char *arg, int s,
+ const struct afswtch *afp);
void Perror(const char *cmd);
void printb(const char *s, unsigned value, const char *bits);
diff --git a/sbin/ifconfig/ifvlan.c b/sbin/ifconfig/ifvlan.c
index 8b7b6e9daf9a..74d683ebb55a 100644
--- a/sbin/ifconfig/ifvlan.c
+++ b/sbin/ifconfig/ifvlan.c
@@ -204,8 +204,11 @@ DECL_CMD_FUNC(setvlantag, val, d)
if (params.vlr_tag != ul)
errx(1, "value for vlan out of range");
- if (getvlan(s, &ifr, &vreq) != -1)
+ if (getvlan(s, &ifr, &vreq) != -1) {
+ vreq.vlr_tag = params.vlr_tag;
+ memcpy(&params, &vreq, sizeof(params));
vlan_set(s, &ifr);
+ }
}
static
@@ -233,8 +236,11 @@ DECL_CMD_FUNC(setvlanproto, val, d)
} else
errx(1, "invalid value for vlanproto");
- if (getvlan(s, &ifr, &vreq) != -1)
+ if (getvlan(s, &ifr, &vreq) != -1) {
+ vreq.vlr_proto = params.vlr_proto;
+ memcpy(&params, &vreq, sizeof(params));
vlan_set(s, &ifr);
+ }
}
static
diff --git a/sbin/ipf/libipf/interror.c b/sbin/ipf/libipf/interror.c
index ca97254cb382..994fb9d2b320 100644
--- a/sbin/ipf/libipf/interror.c
+++ b/sbin/ipf/libipf/interror.c
@@ -17,7 +17,7 @@ typedef struct {
static ipf_error_entry_t *find_error(int);
-#define IPF_NUM_ERRORS 475
+#define IPF_NUM_ERRORS 477
/*
* NO REUSE OF NUMBERS!
@@ -355,6 +355,7 @@ log" },
{ 60073, "unknown lookup group for next address (ipv6)" },
{ 60074, "unknown next address type (ipv6)" },
{ 60075, "one object at a time must be copied" },
+ { 60076, "NAT ioctl denied in jail without VNET" },
/* -------------------------------------------------------------------------- */
{ 70001, "incorrect object size to get pool stats" },
{ 70002, "could not malloc memory for new pool node" },
@@ -516,6 +517,7 @@ log" },
{ 130015, "ipf_init_all failed" },
{ 130016, "finding pfil head failed" },
{ 130017, "ipfilter is already initialised and running" },
+ { 130018, "ioctl denied in jail without VNET" },
};
diff --git a/sbin/ipfw/ipfw.8 b/sbin/ipfw/ipfw.8
index 0e663fa44bdf..db8a11525b4d 100644
--- a/sbin/ipfw/ipfw.8
+++ b/sbin/ipfw/ipfw.8
@@ -1,7 +1,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd June 14, 2021
+.Dd June 4, 2022
.Dt IPFW 8
.Os
.Sh NAME
@@ -1610,6 +1610,20 @@ Matches IPv6 packets containing any of the flow labels given in
.Ar labels .
.Ar labels
is a comma separated list of numeric flow labels.
+.It Cm dst-mac Ar table Ns Pq Ar name Ns Op , Ns Ar value
+Search for the destination MAC address entry in lookup table
+.Ar name .
+If not found, the match fails.
+Otherwise, the match succeeds and
+.Cm tablearg
+is set to the value extracted from the table.
+.It Cm src-mac Ar table Ns Pq Ar name Ns Op , Ns Ar value
+Search for the source MAC address entry in lookup table
+.Ar name .
+If not found, the match fails.
+Otherwise, the match succeeds and
+.Cm tablearg
+is set to the value extracted from the table.
.It Cm frag Ar spec
Matches IPv4 packets whose
.Cm ip_off
@@ -1823,7 +1837,7 @@ set of parameters as specified in the rule.
One or more
of source and destination addresses and ports can be
specified.
-.It Cm lookup Bro Cm dst-ip | dst-port | src-ip | src-port | uid | jail Brc Ar name
+.It Cm lookup Bro Cm dst-ip | dst-port | dst-mac | src-ip | src-port | src-mac | uid | jail Brc Ar name
Search an entry in lookup table
.Ar name
that matches the field specified as argument.
@@ -2133,7 +2147,7 @@ There may be up to 65535 different lookup tables.
.Pp
The following table types are supported:
.Bl -tag -width indent
-.It Ar table-type : Ar addr | iface | number | flow
+.It Ar table-type : Ar addr | iface | number | flow | mac
.It Ar table-key : Ar addr Ns Oo / Ns Ar masklen Oc | iface-name | number | flow-spec
.It Ar flow-spec : Ar flow-field Ns Op , Ns Ar flow-spec
.It Ar flow-field : src-ip | proto | src-port | dst-ip | dst-port
@@ -2163,6 +2177,20 @@ Ranges are not supported.
Matches packet fields specified by
.Ar flow
type suboptions with table entries.
+.It Cm mac
+Matches MAC address.
+Each entry is represented by an
+.Ar addr Ns Op / Ns Ar masklen
+and will match all addresses with base
+.Ar addr
+and mask width of
+.Ar masklen
+bits.
+If
+.Ar masklen
+is not specified, it defaults to 48.
+When looking up an MAC address in a table, the most specific
+entry will match.
.El
.Pp
Tables require explicit creation via
@@ -2266,7 +2294,7 @@ Shows generic table information and algo-specific data.
The following lookup algorithms are supported:
.Bl -tag -width indent
.It Ar algo-desc : algo-name | "algo-name algo-data"
-.It Ar algo-name : Ar addr: radix | addr: hash | iface: array | number: array | flow: hash
+.It Ar algo-name : Ar addr: radix | addr: hash | iface: array | number: array | flow: hash | mac: radix
.It Cm addr: radix
Separate Radix trees for IPv4 and IPv6, the same way as the routing table (see
.Xr route 4 ) .
@@ -2291,6 +2319,8 @@ Array storing sorted u32 numbers.
Auto-growing hash storing flow entries.
Search calculates hash on required packet fields and searches for matching
entries in selected bucket.
+.It Cm mac: radix
+Radix tree for MAC address
.El
.Pp
The
diff --git a/sbin/ipfw/ipfw2.c b/sbin/ipfw/ipfw2.c
index e210cbfd02ec..7d820698a25d 100644
--- a/sbin/ipfw/ipfw2.c
+++ b/sbin/ipfw/ipfw2.c
@@ -300,12 +300,20 @@ static struct _s_x rule_action_params[] = {
/*
* The 'lookup' instruction accepts one of the following arguments.
- * -1 is a terminator for the list.
* Arguments are passed as v[1] in O_DST_LOOKUP options.
*/
-static int lookup_key[] = {
- TOK_DSTIP, TOK_SRCIP, TOK_DSTPORT, TOK_SRCPORT,
- TOK_UID, TOK_JAIL, TOK_DSCP, -1 };
+static struct _s_x lookup_keys[] = {
+ { "dst-ip", LOOKUP_DST_IP },
+ { "src-ip", LOOKUP_SRC_IP },
+ { "dst-port", LOOKUP_DST_PORT },
+ { "src-port", LOOKUP_SRC_PORT },
+ { "dst-mac", LOOKUP_DST_MAC },
+ { "src-mac", LOOKUP_SRC_MAC },
+ { "uid", LOOKUP_UID },
+ { "jail", LOOKUP_JAIL },
+ { "dscp", LOOKUP_DSCP },
+ { NULL, 0 },
+};
static struct _s_x rule_options[] = {
{ "tagged", TOK_TAGGED },
@@ -358,6 +366,8 @@ static struct _s_x rule_options[] = {
{ "src-ip", TOK_SRCIP },
{ "dst-port", TOK_DSTPORT },
{ "src-port", TOK_SRCPORT },
+ { "dst-mac", TOK_DSTMAC },
+ { "src-mac", TOK_SRCMAC },
{ "proto", TOK_PROTO },
{ "MAC", TOK_MAC },
{ "mac", TOK_MAC },
@@ -368,18 +378,18 @@ static struct _s_x rule_options[] = {
{ "ipsec", TOK_IPSEC },
{ "icmp6type", TOK_ICMP6TYPES },
{ "icmp6types", TOK_ICMP6TYPES },
- { "ext6hdr", TOK_EXT6HDR},
- { "flow-id", TOK_FLOWID},
- { "ipv6", TOK_IPV6},
- { "ip6", TOK_IPV6},
- { "ipv4", TOK_IPV4},
- { "ip4", TOK_IPV4},
- { "dst-ipv6", TOK_DSTIP6},
- { "dst-ip6", TOK_DSTIP6},
- { "src-ipv6", TOK_SRCIP6},
- { "src-ip6", TOK_SRCIP6},
- { "lookup", TOK_LOOKUP},
- { "flow", TOK_FLOW},
+ { "ext6hdr", TOK_EXT6HDR },
+ { "flow-id", TOK_FLOWID },
+ { "ipv6", TOK_IPV6 },
+ { "ip6", TOK_IPV6 },
+ { "ipv4", TOK_IPV4 },
+ { "ip4", TOK_IPV4 },
+ { "dst-ipv6", TOK_DSTIP6 },
+ { "dst-ip6", TOK_DSTIP6 },
+ { "src-ipv6", TOK_SRCIP6 },
+ { "src-ip6", TOK_SRCIP6 },
+ { "lookup", TOK_LOOKUP },
+ { "flow", TOK_FLOW },
{ "defer-action", TOK_SKIPACTION },
{ "defer-immediate-action", TOK_SKIPACTION },
{ "//", TOK_COMMENT },
@@ -1211,11 +1221,9 @@ print_ip(struct buf_pr *bp, const struct format_opts *fo,
bprintf(bp, " ");
if (cmd->o.opcode == O_IP_DST_LOOKUP && len > F_INSN_SIZE(ipfw_insn_u32)) {
- uint32_t d = a[1];
- const char *arg = "<invalid>";
+ const char *arg;
- if (d < sizeof(lookup_key)/sizeof(lookup_key[0]))
- arg = match_value(rule_options, lookup_key[d]);
+ arg = match_value(lookup_keys, a[1]);
t = table_search_ctlv(fo->tstate,
((const ipfw_insn *)cmd)->arg1);
bprintf(bp, "lookup %s %s", arg, t);
@@ -1332,6 +1340,22 @@ print_mac(struct buf_pr *bp, const ipfw_insn_mac *mac)
}
static void
+print_mac_lookup(struct buf_pr *bp, const struct format_opts *fo,
+ const ipfw_insn *cmd)
+{
+ uint32_t len = F_LEN(cmd);
+ char *t;
+
+ bprintf(bp, " ");
+
+ t = table_search_ctlv(fo->tstate, cmd->arg1);
+ bprintf(bp, "table(%s", t);
+ if (len == F_INSN_SIZE(ipfw_insn_u32))
+ bprintf(bp, ",%u", ((const ipfw_insn_u32 *)cmd)->d[0]);
+ bprintf(bp, ")");
+}
+
+static void
fill_icmptypes(ipfw_insn_u32 *cmd, char *av)
{
uint8_t type;
@@ -1518,6 +1542,14 @@ print_instruction(struct buf_pr *bp, const struct format_opts *fo,
bprintf(bp, " dst-ip6");
print_ip6(bp, insntod(cmd, ip6));
break;
+ case O_MAC_SRC_LOOKUP:
+ bprintf(bp, " src-mac");
+ print_mac_lookup(bp, fo, cmd);
+ break;
+ case O_MAC_DST_LOOKUP:
+ bprintf(bp, " dst-mac");
+ print_mac_lookup(bp, fo, cmd);
+ break;
case O_FLOW6ID:
print_flow6id(bp, insntod(cmd, u32));
break;
@@ -2650,7 +2682,6 @@ list_static_range(struct cmdline_opts *co, struct format_opts *fo,
int n, seen;
struct ip_fw_rule *r;
struct ip_fw_bcounter *cntr;
- int c = 0;
for (n = seen = 0; n < rcnt; n++,
rtlv = (ipfw_obj_tlv *)((caddr_t)rtlv + rtlv->length)) {
@@ -2669,7 +2700,6 @@ list_static_range(struct cmdline_opts *co, struct format_opts *fo,
if (r->rulenum >= fo->first && r->rulenum <= fo->last) {
show_static_rule(co, fo, bp, r, cntr);
printf("%s", bp->buf);
- c += rtlv->length;
bp_flush(bp);
seen++;
}
@@ -2788,13 +2818,12 @@ ipfw_show_config(struct cmdline_opts *co, struct format_opts *fo,
char *endptr;
size_t readsz;
struct buf_pr bp;
- ipfw_obj_ctlv *ctlv, *tstate;
+ ipfw_obj_ctlv *ctlv;
ipfw_obj_tlv *rbase;
/*
* Handle tablenames TLV first, if any
*/
- tstate = NULL;
rbase = NULL;
dynbase = NULL;
dynsz = 0;
@@ -3682,6 +3711,29 @@ add_dstip(ipfw_insn *cmd, char *av, int cblen, struct tidx *tstate)
return cmd;
}
+static ipfw_insn *
+add_srcmac(ipfw_insn *cmd, char *av, struct tidx *tstate)
+{
+
+ if (strncmp(av, "table(", 6) == 0)
+ fill_table(cmd, av, O_MAC_SRC_LOOKUP, tstate);
+ else
+ errx(EX_DATAERR, "only mac table lookup is supported %s", av);
+ return cmd;
+}
+
+static ipfw_insn *
+add_dstmac(ipfw_insn *cmd, char *av, struct tidx *tstate)
+{
+
+ if (strncmp(av, "table(", 6) == 0)
+ fill_table(cmd, av, O_MAC_DST_LOOKUP, tstate);
+ else
+ errx(EX_DATAERR, "only mac table lookup is supported %s", av);
+ return cmd;
+}
+
+
static struct _s_x f_reserved_keywords[] = {
{ "altq", TOK_OR },
{ "//", TOK_OR },
@@ -4912,6 +4964,21 @@ read_options:
}
break;
+
+ case TOK_SRCMAC:
+ NEED1("missing source MAC");
+ if (add_srcmac(cmd, *av, tstate)) {
+ av++;
+ }
+ break;
+
+ case TOK_DSTMAC:
+ NEED1("missing destination MAC");
+ if (add_dstmac(cmd, *av, tstate)) {
+ av++;
+ }
+ break;
+
case TOK_SRCPORT:
NEED1("missing source port");
if (_substrcmp(*av, "any") == 0 ||
@@ -5013,28 +5080,23 @@ read_options:
case TOK_LOOKUP: {
ipfw_insn_u32 *c = (ipfw_insn_u32 *)cmd;
- int j;
if (!av[0] || !av[1])
errx(EX_USAGE, "format: lookup argument tablenum");
cmd->opcode = O_IP_DST_LOOKUP;
cmd->len |= F_INSN_SIZE(ipfw_insn) + 2;
- i = match_token(rule_options, *av);
- for (j = 0; lookup_key[j] >= 0 ; j++) {
- if (i == lookup_key[j])
- break;
- }
- if (lookup_key[j] <= 0)
+ i = match_token(lookup_keys, *av);
+ if (i == -1)
errx(EX_USAGE, "format: cannot lookup on %s", *av);
- __PAST_END(c->d, 1) = j; // i converted to option
+ __PAST_END(c->d, 1) = i;
av++;
- if ((j = pack_table(tstate, *av)) == 0)
+ if ((i = pack_table(tstate, *av)) == 0)
errx(EX_DATAERR, "Invalid table name: %s", *av);
- cmd->arg1 = j;
+ cmd->arg1 = i;
av++;
- }
+ }
break;
case TOK_FLOW:
NEED1("missing table name");
diff --git a/sbin/ipfw/ipfw2.h b/sbin/ipfw/ipfw2.h
index 9a39c215692d..dd7699987434 100644
--- a/sbin/ipfw/ipfw2.h
+++ b/sbin/ipfw/ipfw2.h
@@ -177,6 +177,8 @@ enum tokens {
TOK_SRCIP,
TOK_DSTPORT,
TOK_SRCPORT,
+ TOK_DSTMAC,
+ TOK_SRCMAC,
TOK_ALL,
TOK_MASK,
TOK_FLOW_MASK,
diff --git a/sbin/ipfw/tables.c b/sbin/ipfw/tables.c
index 81cf7e392586..9e6390492e96 100644
--- a/sbin/ipfw/tables.c
+++ b/sbin/ipfw/tables.c
@@ -31,6 +31,7 @@
#include <string.h>
#include <sysexits.h>
+#include <net/ethernet.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/ip_fw.h>
@@ -77,6 +78,7 @@ static int tables_foreach(table_cb_t *f, void *arg, int sort);
static struct _s_x tabletypes[] = {
{ "addr", IPFW_TABLE_ADDR },
+ { "mac", IPFW_TABLE_MAC },
{ "iface", IPFW_TABLE_INTERFACE },
{ "number", IPFW_TABLE_NUMBER },
{ "flow", IPFW_TABLE_FLOW },
@@ -1188,6 +1190,7 @@ tentry_fill_key_type(char *arg, ipfw_obj_tentry *tentry, uint8_t type,
char *p, *pp;
int mask, af;
struct in6_addr *paddr, tmp;
+ struct ether_addr *mac;
struct tflow_entry *tfe;
uint32_t key, *pkey;
uint16_t port;
@@ -1234,6 +1237,24 @@ tentry_fill_key_type(char *arg, ipfw_obj_tentry *tentry, uint8_t type,
af = AF_INET;
}
break;
+ case IPFW_TABLE_MAC:
+ /* Remove / if exists */
+ if ((p = strchr(arg, '/')) != NULL) {
+ *p = '\0';
+ mask = atoi(p + 1);
+ }
+
+ if (p != NULL && mask > 8 * ETHER_ADDR_LEN)
+ errx(EX_DATAERR, "bad MAC mask width: %s",
+ p + 1);
+
+ if ((mac = ether_aton(arg)) == NULL)
+ errx(EX_DATAERR, "Incorrect MAC address");
+
+ memcpy(tentry->k.mac, mac->octet, ETHER_ADDR_LEN);
+ masklen = p ? mask : 8 * ETHER_ADDR_LEN;
+ af = AF_LINK;
+ break;
case IPFW_TABLE_INTERFACE:
/* Assume interface name. Copy significant data only */
mask = MIN(strlen(arg), IF_NAMESIZE - 1);
@@ -1872,6 +1893,7 @@ table_show_entry(ipfw_xtable_info *i, ipfw_obj_tentry *tent)
{
char tbuf[128], pval[128];
const char *comma;
+ const u_char *mac;
void *paddr;
struct tflow_entry *tfe;
@@ -1884,6 +1906,13 @@ table_show_entry(ipfw_xtable_info *i, ipfw_obj_tentry *tent)
inet_ntop(tent->subtype, &tent->k, tbuf, sizeof(tbuf));
printf("%s/%u %s\n", tbuf, tent->masklen, pval);
break;
+ case IPFW_TABLE_MAC:
+ /* MAC prefixes */
+ mac = tent->k.mac;
+ printf("%02x:%02x:%02x:%02x:%02x:%02x/%u %s\n",
+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
+ tent->masklen, pval);
+ break;
case IPFW_TABLE_INTERFACE:
/* Interface names */
printf("%s %s\n", tent->k.iface, pval);
diff --git a/sbin/kldload/kldload.c b/sbin/kldload/kldload.c
index 254a409cd2a7..a8e43fdd1f92 100644
--- a/sbin/kldload/kldload.c
+++ b/sbin/kldload/kldload.c
@@ -171,21 +171,23 @@ main(int argc, char** argv)
printf("%s is already "
"loaded\n", argv[0]);
} else {
- switch (errno) {
- case EEXIST:
- warnx("can't load %s: module "
- "already loaded or "
- "in kernel", argv[0]);
- break;
- case ENOEXEC:
- warnx("an error occurred while "
- "loading module %s. "
- "Please check dmesg(8) for "
- "more details.", argv[0]);
- break;
- default:
- warn("can't load %s", argv[0]);
- break;
+ if (!quiet) {
+ switch (errno) {
+ case EEXIST:
+ warnx("can't load %s: module "
+ "already loaded or "
+ "in kernel", argv[0]);
+ break;
+ case ENOEXEC:
+ warnx("an error occurred while "
+ "loading module %s. "
+ "Please check dmesg(8) for "
+ "more details.", argv[0]);
+ break;
+ default:
+ warn("can't load %s", argv[0]);
+ break;
+ }
}
errors++;
}
diff --git a/sbin/md5/md5.1 b/sbin/md5/md5.1
index 899e49ba3517..a3db48596606 100644
--- a/sbin/md5/md5.1
+++ b/sbin/md5/md5.1
@@ -1,5 +1,5 @@
.\" $FreeBSD$
-.Dd Feb 5, 2022
+.Dd July 26, 2022
.Dt MD5 1
.Os
.Sh NAME
@@ -86,6 +86,9 @@ coreutils versions of these programs.
If the program was called with a name that does not end in
.Nm sum ,
compare the digest of the file against this string.
+If combined with the
+.Fl q
+option, the calculated digest is printed in addition to the exit status being set.
.Pq Note that this option is not yet useful if multiple files are specified.
.It Fl c Ar file
If the program was called with a name that does end in
@@ -94,7 +97,7 @@ the file passed as argument must contain digest lines generated by the same
digest algorithm with or without the
.Fl r
option
-.Pq i.e. in either classical BSD format or in GNU coreutils format .
+.Pq i.e., in either classical BSD format or in GNU coreutils format .
A line with the file name followed by a colon
.Dq ":"
and either OK or FAILED is written for each well-formed line in the digest file.
@@ -164,7 +167,7 @@ d80bf36c332dc0fdc479366ec3fa44cd /etc/rc.conf
.Pd
The
.Nm -sum
-variants put 2 blank characters between hash and file name for full compatibility
+variants put 2 blank characters between hash and file name for full compatibility
with the coreutils versions of these commands.
.Ed
.Pp
@@ -207,7 +210,7 @@ $ md5 -c digest /boot/loader.conf
The digest file may contain any number of lines in the format generated with or without the
.Fl r
option
-.Pq i.e. in either classical BSD format or in GNU coreutils format .
+.Pq i.e., in either classical BSD format or in GNU coreutils format .
If a hash value does not match the file, FAILED is printed instead of OK.
.Sh SEE ALSO
.Xr cksum 1 ,
diff --git a/sbin/md5/md5.c b/sbin/md5/md5.c
index 7235e6e0a39f..97c587efd63c 100644
--- a/sbin/md5/md5.c
+++ b/sbin/md5/md5.c
@@ -436,6 +436,8 @@ MDOutput(const Algorithm_t *alg, char *p, char *argv[])
printf("%s: %s\n", *argv, checkfailed ? "FAILED" : "OK");
} else if (qflag || argv == NULL) {
printf("%s\n", p);
+ if (cflag)
+ checkfailed = strcasecmp(checkAgainst, p) != 0;
} else {
if (rflag)
if (gnu_emu)
diff --git a/sbin/mount/mount.c b/sbin/mount/mount.c
index 79d9d6cb0caf..6c986907bcda 100644
--- a/sbin/mount/mount.c
+++ b/sbin/mount/mount.c
@@ -692,6 +692,12 @@ prmount(struct statfs *sfp)
xo_emit("{D:, }{Lw:fsid}{:fsid}", fsidbuf);
free(fsidbuf);
}
+ if (sfp->f_nvnodelistsize != 0) {
+ xo_open_container("vnodes");
+ xo_emit("{D:, }{Lwc:vnodes}{Lw:count}{w:count/%ju}",
+ (uintmax_t)sfp->f_nvnodelistsize);
+ xo_close_container("vnodes");
+ }
}
xo_emit("{D:)}\n");
}
diff --git a/sbin/mount_nfs/mount_nfs.8 b/sbin/mount_nfs/mount_nfs.8
index 5725b6eccf65..88c9b11e9392 100644
--- a/sbin/mount_nfs/mount_nfs.8
+++ b/sbin/mount_nfs/mount_nfs.8
@@ -28,7 +28,7 @@
.\" @(#)mount_nfs.8 8.3 (Berkeley) 3/29/95
.\" $FreeBSD$
.\"
-.Dd January 11, 2022
+.Dd July 2, 2022
.Dt MOUNT_NFS 8
.Os
.Sh NAME
@@ -662,5 +662,8 @@ enforced by the server, the options
and
.Cm soft
cannot be safely used.
+For NFSv4 minor version 1 or 2 mounts, these options may
+also result
+in hung mount points, due to corruption of session slots.
.Cm hard
nfsv4 mounts are strongly recommended.
diff --git a/sbin/mount_nfs/mount_nfs.c b/sbin/mount_nfs/mount_nfs.c
index 898a6dc9d724..284b34323885 100644
--- a/sbin/mount_nfs/mount_nfs.c
+++ b/sbin/mount_nfs/mount_nfs.c
@@ -73,6 +73,7 @@ __FBSDID("$FreeBSD$");
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -139,7 +140,7 @@ enum tryret {
static int sec_name_to_num(const char *sec);
static const char *sec_num_to_name(int num);
-static int getnfsargs(char *, struct iovec **iov, int *iovlen);
+static int getnfsargs(char **, char **, struct iovec **iov, int *iovlen);
/* void set_rpc_maxgrouplist(int); */
static struct netconfig *getnetconf_cached(const char *netid);
static const char *netidbytype(int af, int sotype);
@@ -156,11 +157,13 @@ main(int argc, char *argv[])
int c;
struct iovec *iov;
int num, iovlen;
- char *mntname, *p, *spec, *tmp;
+ char *host, *mntname, *p, *spec, *tmp;
char mntpath[MAXPATHLEN], errmsg[255];
char hostname[MAXHOSTNAMELEN + 1], gssn[MAXHOSTNAMELEN + 50];
const char *gssname, *nmount_errstr;
+ bool softintr;
+ softintr = false;
iov = NULL;
iovlen = 0;
memset(errmsg, 0, sizeof(errmsg));
@@ -210,6 +213,7 @@ main(int argc, char *argv[])
case 'i':
printf("-i deprecated, use -o intr\n");
build_iovec(&iov, &iovlen, "intr", NULL, 0);
+ softintr = true;
break;
case 'L':
printf("-L deprecated, use -o nolockd\n");
@@ -366,6 +370,10 @@ main(int argc, char *argv[])
"value -- %s", val);
}
pass_flag_to_nmount=0;
+ } else if (strcmp(opt, "soft") == 0) {
+ softintr = true;
+ } else if (strcmp(opt, "intr") == 0) {
+ softintr = true;
}
if (pass_flag_to_nmount) {
build_iovec(&iov, &iovlen, opt,
@@ -395,6 +403,7 @@ main(int argc, char *argv[])
case 's':
printf("-s deprecated, use -o soft\n");
build_iovec(&iov, &iovlen, "soft", NULL, 0);
+ softintr = true;
break;
case 'T':
nfsproto = IPPROTO_TCP;
@@ -433,6 +442,11 @@ main(int argc, char *argv[])
/* NOTREACHED */
}
+ /* Warn that NFSv4 mounts only work correctly as hard mounts. */
+ if (mountmode == V4 && softintr)
+ warnx("Warning, options soft and/or intr cannot be safely used"
+ " for NFSv4. See the BUGS section of mount_nfs(8)");
+
spec = *argv++;
mntname = *argv;
@@ -461,7 +475,7 @@ main(int argc, char *argv[])
__DECONST(void *, gssname), strlen(gssname) + 1);
}
- if (!getnfsargs(spec, &iov, &iovlen))
+ if (!getnfsargs(&spec, &host, &iov, &iovlen))
exit(1);
/* resolve the mountpoint with realpath(3) */
@@ -479,6 +493,9 @@ main(int argc, char *argv[])
else
err(1, "nmount: %s%s%s", mntpath, errmsg[0] ? ", " : "",
errmsg);
+ } else if (mountmode != V4 && !add_mtab(host, spec)) {
+ /* Add mounted file system to PATH_MOUNTTAB */
+ warnx("can't update %s for %s:%s", PATH_MOUNTTAB, host, spec);
}
exit(0);
@@ -568,15 +585,16 @@ rtm_ifinfo_sleep(time_t sec)
}
static int
-getnfsargs(char *spec, struct iovec **iov, int *iovlen)
+getnfsargs(char **specp, char **hostpp, struct iovec **iov, int *iovlen)
{
struct addrinfo hints, *ai_nfs, *ai;
enum tryret ret;
int ecode, speclen, remoteerr, offset, have_bracket = 0;
- char *hostp, *delimp, *errstr;
+ char *hostp, *delimp, *errstr, *spec;
size_t len;
static char nam[MNAMELEN + 1], pname[MAXHOSTNAMELEN + 5];
+ spec = *specp;
if (*spec == '[' && (delimp = strchr(spec + 1, ']')) != NULL &&
*(delimp + 1) == ':') {
hostp = spec + 1;
@@ -718,9 +736,9 @@ getnfsargs(char *spec, struct iovec **iov, int *iovlen)
freeaddrinfo(ai_nfs);
build_iovec(iov, iovlen, "hostname", nam, (size_t)-1);
- /* Add mounted file system to PATH_MOUNTTAB */
- if (mountmode != V4 && !add_mtab(hostp, spec))
- warnx("can't update %s for %s:%s", PATH_MOUNTTAB, hostp, spec);
+
+ *specp = spec;
+ *hostpp = hostp;
return (1);
}
diff --git a/sbin/newfs/mkfs.c b/sbin/newfs/mkfs.c
index a6c4ee60c2d5..48091d7882d0 100644
--- a/sbin/newfs/mkfs.c
+++ b/sbin/newfs/mkfs.c
@@ -636,23 +636,26 @@ restart:
* Read the last sector of the boot block, replace the last
* 20 bytes with the recovery information, then write it back.
* The recovery information only works for UFS2 filesystems.
+ * For UFS1, zero out the area to ensure that an old UFS2
+ * recovery block is not accidentally found.
*/
- if (sblock.fs_magic == FS_UFS2_MAGIC) {
- if ((fsrbuf = malloc(realsectorsize)) == NULL || bread(&disk,
- part_ofs + (SBLOCK_UFS2 - realsectorsize) / disk.d_bsize,
- fsrbuf, realsectorsize) == -1)
- err(1, "can't read recovery area: %s", disk.d_error);
- fsr =
- (struct fsrecovery *)&fsrbuf[realsectorsize - sizeof *fsr];
+ if ((fsrbuf = malloc(realsectorsize)) == NULL || bread(&disk,
+ part_ofs + (SBLOCK_UFS2 - realsectorsize) / disk.d_bsize,
+ fsrbuf, realsectorsize) == -1)
+ err(1, "can't read recovery area: %s", disk.d_error);
+ fsr = (struct fsrecovery *)&fsrbuf[realsectorsize - sizeof *fsr];
+ if (sblock.fs_magic != FS_UFS2_MAGIC) {
+ memset(fsr, 0, sizeof *fsr);
+ } else {
fsr->fsr_magic = sblock.fs_magic;
fsr->fsr_fpg = sblock.fs_fpg;
fsr->fsr_fsbtodb = sblock.fs_fsbtodb;
fsr->fsr_sblkno = sblock.fs_sblkno;
fsr->fsr_ncg = sblock.fs_ncg;
- wtfs((SBLOCK_UFS2 - realsectorsize) / disk.d_bsize,
- realsectorsize, fsrbuf);
- free(fsrbuf);
}
+ wtfs((SBLOCK_UFS2 - realsectorsize) / disk.d_bsize,
+ realsectorsize, fsrbuf);
+ free(fsrbuf);
/*
* Update information about this partition in pack
* label, to that it may be updated on disk.
diff --git a/sbin/nvmecontrol/ns.c b/sbin/nvmecontrol/ns.c
index 5ec6a305b8b9..5c537e920dc3 100644
--- a/sbin/nvmecontrol/ns.c
+++ b/sbin/nvmecontrol/ns.c
@@ -371,8 +371,8 @@ static struct ns_result_str ns_result[] = {
{ 0x2, "Invalid Field"},
{ 0xa, "Invalid Format"},
{ 0xb, "Invalid Namespace or format"},
- { 0x15, "Namespace insufficent capacity"},
- { 0x16, "Namespace ID unavaliable"},
+ { 0x15, "Namespace insufficient capacity"},
+ { 0x16, "Namespace ID unavailable"},
{ 0x18, "Namespace already attached"},
{ 0x19, "Namespace is private"},
{ 0x1a, "Namespace is not attached"},
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
index 21729fc7ba4e..7bb6223319c4 100644
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -1197,6 +1197,14 @@ etherrule : ETHER action dir quick interface etherproto etherfromto l3fromto eth
r.quick = $4.quick;
if ($9.tag != NULL)
memcpy(&r.tagname, $9.tag, sizeof(r.tagname));
+ if ($9.match_tag)
+ if (strlcpy(r.match_tagname, $9.match_tag,
+ PF_TAG_NAME_SIZE) >= PF_TAG_NAME_SIZE) {
+ yyerror("tag too long, max %u chars",
+ PF_TAG_NAME_SIZE - 1);
+ YYERROR;
+ }
+ r.match_tag_not = $9.match_tag_not;
if ($9.queues.qname != NULL)
memcpy(&r.qname, $9.queues.qname, sizeof(r.qname));
r.dnpipe = $9.dnpipe;
@@ -1320,6 +1328,10 @@ etherfilter_opt : etherqname {
| TAG string {
filter_opts.tag = $2;
}
+ | not TAGGED string {
+ filter_opts.match_tag = $3;
+ filter_opts.match_tag_not = $1;
+ }
| DNPIPE number {
filter_opts.dnpipe = $2;
filter_opts.free_flags |= PFRULE_DN_IS_PIPE;
@@ -4454,7 +4466,7 @@ pool_opt : BITMASK {
pool_opts.staticport = 1;
}
| STICKYADDRESS {
- if (filter_opts.marker & POM_STICKYADDRESS) {
+ if (pool_opts.marker & POM_STICKYADDRESS) {
yyerror("sticky-address cannot be redefined");
YYERROR;
}
@@ -5772,6 +5784,18 @@ expand_eth_rule(struct pfctl_eth_rule *r,
struct node_mac *srcs, struct node_mac *dsts,
struct node_host *ipsrcs, struct node_host *ipdsts, const char *anchor_call)
{
+ char tagname[PF_TAG_NAME_SIZE];
+ char match_tagname[PF_TAG_NAME_SIZE];
+ char qname[PF_QNAME_SIZE];
+
+ if (strlcpy(tagname, r->tagname, sizeof(tagname)) >= sizeof(tagname))
+ errx(1, "expand_eth_rule: tagname");
+ if (strlcpy(match_tagname, r->match_tagname, sizeof(match_tagname)) >=
+ sizeof(match_tagname))
+ errx(1, "expand_eth_rule: match_tagname");
+ if (strlcpy(qname, r->qname, sizeof(qname)) >= sizeof(qname))
+ errx(1, "expand_eth_rule: qname");
+
LOOP_THROUGH(struct node_if, interface, interfaces,
LOOP_THROUGH(struct node_etherproto, proto, protos,
LOOP_THROUGH(struct node_mac, src, srcs,
@@ -5800,6 +5824,15 @@ expand_eth_rule(struct pfctl_eth_rule *r,
r->dst.isset = dst->isset;
r->nr = pf->eastack[pf->asd]->match++;
+ if (strlcpy(r->tagname, tagname, sizeof(r->tagname)) >=
+ sizeof(r->tagname))
+ errx(1, "expand_eth_rule: r->tagname");
+ if (strlcpy(r->match_tagname, match_tagname,
+ sizeof(r->match_tagname)) >= sizeof(r->match_tagname))
+ errx(1, "expand_eth_rule: r->match_tagname");
+ if (strlcpy(r->qname, qname, sizeof(r->qname)) >= sizeof(r->qname))
+ errx(1, "expand_eth_rule: r->qname");
+
pfctl_append_eth_rule(pf, r, anchor_call);
))))));
diff --git a/sbin/pfctl/pfctl_altq.c b/sbin/pfctl/pfctl_altq.c
index 6d35ae77240f..66075258f106 100644
--- a/sbin/pfctl/pfctl_altq.c
+++ b/sbin/pfctl/pfctl_altq.c
@@ -1227,7 +1227,7 @@ char *
rate2str(double rate)
{
char *buf;
- static char r2sbuf[R2S_BUFS][RATESTR_MAX]; /* ring bufer */
+ static char r2sbuf[R2S_BUFS][RATESTR_MAX]; /* ring buffer */
static int idx = 0;
int i;
static const char unit[] = " KMG";
diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c
index 1f6a194591c0..c65fe6abe3f6 100644
--- a/sbin/pfctl/pfctl_parser.c
+++ b/sbin/pfctl/pfctl_parser.c
@@ -74,7 +74,7 @@ void print_fromto(struct pf_rule_addr *, pf_osfp_t,
struct pf_rule_addr *, u_int8_t, u_int8_t, int, int);
int ifa_skip_if(const char *filter, struct node_host *p);
-struct node_host *host_if(const char *, int);
+struct node_host *host_if(const char *, int, int *);
struct node_host *host_v4(const char *, int);
struct node_host *host_v6(const char *, int);
struct node_host *host_dns(const char *, int, int);
@@ -791,6 +791,11 @@ print_eth_rule(struct pfctl_eth_rule *r, const char *anchor_call,
printf(" queue %s", r->qname);
if (r->tagname[0])
printf(" tag %s", r->tagname);
+ if (r->match_tagname[0]) {
+ if (r->match_tag_not)
+ printf(" !");
+ printf(" tagged %s", r->match_tagname);
+ }
if (r->dnpipe)
printf(" %s %d",
r->dnflags & PFRULE_DN_IS_PIPE ? "dnpipe" : "dnqueue",
@@ -1690,7 +1695,7 @@ host(const char *s)
/* interface with this name exists? */
/* expensive with thousands of interfaces - prioritze IPv4/6 check */
- if (cont && (h = host_if(ps, mask)) != NULL)
+ if (cont && (h = host_if(ps, mask, &cont)) != NULL)
cont = 0;
/* dns lookup */
@@ -1706,7 +1711,7 @@ host(const char *s)
}
struct node_host *
-host_if(const char *s, int mask)
+host_if(const char *s, int mask, int *cont)
{
struct node_host *n, *h = NULL;
char *p, *ps;
@@ -1728,6 +1733,7 @@ host_if(const char *s, int mask)
return (NULL);
}
*p = '\0';
+ *cont = 0;
}
if (flags & (flags - 1) & PFI_AFLAG_MODEMASK) { /* Yep! */
fprintf(stderr, "illegal combination of interface modifiers\n");
diff --git a/sbin/pfctl/tests/files/pf1010.in b/sbin/pfctl/tests/files/pf1010.in
new file mode 100644
index 000000000000..2baf4dc360af
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1010.in
@@ -0,0 +1,2 @@
+pass inet proto icmp icmp-type {unreach}
+pass in route-to (if0 127.0.0.1/8) sticky-address inet
diff --git a/sbin/pfctl/tests/files/pf1010.ok b/sbin/pfctl/tests/files/pf1010.ok
new file mode 100644
index 000000000000..b960dbfc50b8
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1010.ok
@@ -0,0 +1,2 @@
+pass inet proto icmp all icmp-type unreach keep state
+pass in route-to (if0 127.0.0.0/8) sticky-address inet all flags S/SA keep state
diff --git a/sbin/pfctl/tests/pfctl_test_list.inc b/sbin/pfctl/tests/pfctl_test_list.inc
index aa3f625e905f..0b6d5110034d 100644
--- a/sbin/pfctl/tests/pfctl_test_list.inc
+++ b/sbin/pfctl/tests/pfctl_test_list.inc
@@ -120,3 +120,4 @@ PFCTL_TEST(1006, "pfctl crashes with certain fairq configurations")
PFCTL_TEST(1007, "Basic ethernet rule")
PFCTL_TEST(1008, "Ethernet rule with mask length")
PFCTL_TEST(1009, "Ethernet rule with mask")
+PFCTL_TEST(1010, "POM_STICKYADDRESS test")
diff --git a/sbin/quotacheck/quotacheck.c b/sbin/quotacheck/quotacheck.c
index 9a01be11d9d0..1e656d2a5811 100644
--- a/sbin/quotacheck/quotacheck.c
+++ b/sbin/quotacheck/quotacheck.c
@@ -321,7 +321,7 @@ chkquota(char *specname, struct quotafile *qfu, struct quotafile *qfg)
}
}
sync();
- if ((ret = sbget(fi, &fs, STDSB)) != 0) {
+ if ((ret = sbget(fi, &fs, UFS_STDSB, UFS_NOCSUM)) != 0) {
switch (ret) {
case ENOENT:
warn("Cannot find file system superblock");
diff --git a/sbin/routed/routed.8 b/sbin/routed/routed.8
index 63f8f4da66ed..6988e916fa78 100644
--- a/sbin/routed/routed.8
+++ b/sbin/routed/routed.8
@@ -30,7 +30,7 @@
.\" @(#)routed.8 8.2 (Berkeley) 12/11/93
.\" $FreeBSD$
.\"
-.Dd August 26, 2014
+.Dd June 27, 2022
.Dt ROUTED 8
.Os
.Sh NAME
@@ -488,10 +488,9 @@ specified in "dot" notation (see
.Pa /etc/networks
or
.Pa /etc/hosts ,
-or
-.Xr named 8 ,
-must have been started before
-.Nm . )
+or a method in
+.Xr nsswitch.conf 5
+must be able to resolve it.)
.Pp
.Ar Mask
is an optional number between 1 and 32 indicating the netmask associated
diff --git a/sbin/sysctl/sysctl.8 b/sbin/sysctl/sysctl.8
index eb3a5a5f79e9..bd4000697552 100644
--- a/sbin/sysctl/sysctl.8
+++ b/sbin/sysctl/sysctl.8
@@ -28,7 +28,7 @@
.\" From: @(#)sysctl.8 8.1 (Berkeley) 6/6/93
.\" $FreeBSD$
.\"
-.Dd March 20, 2022
+.Dd June 30, 2022
.Dt SYSCTL 8
.Os
.Sh NAME
@@ -327,6 +327,7 @@ was significantly remodeled.
The
.Nm
utility presently exploits an undocumented interface to the kernel
-sysctl facility to traverse the sysctl tree and to retrieve format
+.Xr sysctl 9
+facility to traverse the sysctl tree and to retrieve format
and name information.
This correct interface is being thought about for the time being.
diff --git a/sbin/veriexec/veriexec.8 b/sbin/veriexec/veriexec.8
index 161406ae6de2..d191f5175074 100644
--- a/sbin/veriexec/veriexec.8
+++ b/sbin/veriexec/veriexec.8
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd February 14, 2022
+.Dd July 8, 2022
.Dt VERIEXEC 8
.Os
.Sh NAME
@@ -34,6 +34,7 @@
.Nm
.Op Fl v
.Op Fl C Ar directory
+.Op Fl S
.Pa manifest
.Nm
.Fl z Ar state
@@ -53,6 +54,11 @@ The first form is for loading a
first verifies a digital signature of the
.Ar manifest
and if successful, parses it and feeds its content to kernel.
+The
+.Fl S
+flag indicates that certificate validity should be checked.
+Without this, a valid signature with an expired certificate
+will still be accepted.
.Pp
The second form with
.Fl z
diff --git a/sbin/veriexec/veriexec.c b/sbin/veriexec/veriexec.c
index 1eb7a9af7d6f..0162eeda5347 100644
--- a/sbin/veriexec/veriexec.c
+++ b/sbin/veriexec/veriexec.c
@@ -33,16 +33,36 @@ __FBSDID("$FreeBSD$");
#include <syslog.h>
#include <libsecureboot.h>
#include <libveriexec.h>
+#include <sys/types.h>
#include "veriexec.h"
+/* Globals that are shared with manifest_parser.c */
int dev_fd = -1;
int ForceFlags = 0;
int Verbose = 0;
int VeriexecVersion = 0;
-
const char *Cdir = NULL;
+/*!
+ * @brief Print help message describing program's usage
+ * @param void
+ * @return always returns code 0
+ */
+static int
+veriexec_usage()
+{
+ printf("%s",
+ "Usage:\tveriexec [-h] [-i state] [-C] [-xv state|verbosity] [path]\n");
+
+ return (0);
+}
+
+/*!
+ * @brief Load a veriexec manifest
+ * @param manifest Pointer to the location of the manifest file
+ * @retval the error code returned from the parser
+ */
static int
veriexec_load(const char *manifest)
{
@@ -52,7 +72,7 @@ veriexec_load(const char *manifest)
content = verify_signed(manifest, VEF_VERBOSE);
if (!content)
errx(EX_USAGE, "cannot verify %s", manifest);
- if (manifest_open(manifest, content)) {
+ if (manifest_open(manifest, (const char *)content)) {
rc = yyparse();
} else {
err(EX_NOINPUT, "cannot load %s", manifest);
@@ -61,21 +81,87 @@ veriexec_load(const char *manifest)
return (rc);
}
+/*!
+ * @brief Get the veriexec state for the supplied argument
+ * @param arg_text String containing the argument to be processed
+ * @retval The veriexec state number for the specified argument
+ */
+static uint32_t
+veriexec_state_query(const char *arg_text)
+{
+ uint32_t state = 0;
+ unsigned long len;
+
+ len = strlen(arg_text);
+
+ if (strncmp(arg_text, "active", len) == 0)
+ state |= VERIEXEC_STATE_ACTIVE;
+ else if (strncmp(arg_text, "enforce", len) == 0)
+ state |= VERIEXEC_STATE_ENFORCE;
+ if (strncmp(arg_text, "loaded", len) == 0)
+ state |= VERIEXEC_STATE_LOADED;
+ if (strncmp(arg_text, "locked", len) == 0)
+ state |= VERIEXEC_STATE_LOCKED;
+ if (state == 0 || __bitcount(state) > 1)
+ errx(EX_USAGE, "Unknown state \'%s\'", arg_text);
+
+ return (state);
+}
+
+/*!
+ * @brief Get the veriexec command state for the supplied argument
+ * @param arg_text String containing the argument to be processed
+ * @retval The veriexec command state for the specified argument
+ */
+static uint32_t
+veriexec_state_modify(const char *arg_text)
+{
+ uint32_t state = 0;
+ unsigned long len;
+
+ len = strlen(arg_text);
+
+ if (strncmp(arg_text, "active", len) == 0)
+ state = VERIEXEC_ACTIVE;
+ else if (strncmp(arg_text, "enforce", len) == 0)
+ state = VERIEXEC_ENFORCE;
+ else if (strncmp(arg_text, "getstate", len) == 0)
+ state = VERIEXEC_GETSTATE;
+ else if (strncmp(arg_text, "lock", len) == 0)
+ state = VERIEXEC_LOCK;
+ else
+ errx(EX_USAGE, "Unknown command \'%s\'", arg_text);
+
+ return (state);
+}
+
int
main(int argc, char *argv[])
{
- unsigned long ctl;
- int c;
+ long long converted_int;
+ uint32_t state;
+ char c;
int x;
+ if (argc < 2)
+ return (veriexec_usage());
+
dev_fd = open(_PATH_DEV_VERIEXEC, O_WRONLY, 0);
- while ((c = getopt(argc, argv, "C:i:xvz:")) != -1) {
+ while ((c = getopt(argc, argv, "hC:i:Sxvz:")) != -1) {
switch (c) {
+ case 'h':
+ /* Print usage info */
+
+ return (veriexec_usage());
case 'C':
+ /* Get the provided directory argument */
+
Cdir = optarg;
break;
case 'i':
+ /* Query the current state */
+
if (dev_fd < 0) {
err(EX_UNAVAILABLE, "cannot open veriexec");
}
@@ -83,32 +169,27 @@ main(int argc, char *argv[])
err(EX_UNAVAILABLE,
"Cannot get veriexec state");
}
- switch (optarg[0]) {
- case 'a': /* active */
- ctl = VERIEXEC_STATE_ACTIVE;
- break;
- case 'e': /* enforce */
- ctl = VERIEXEC_STATE_ENFORCE;
- break;
- case 'l': /* loaded/locked */
- ctl = (strncmp(optarg, "lock", 4) == 0) ?
- VERIEXEC_STATE_LOCKED :
- VERIEXEC_STATE_LOADED;
- break;
- default:
- errx(EX_USAGE, "unknown state %s", optarg);
- break;
- }
- exit((x & ctl) == 0);
+
+ state = veriexec_state_query(optarg);
+
+ exit((x & state) == 0);
+ break;
+ case 'S':
+ /* Strictly enforce certificate validity */
+ ve_enforce_validity_set(1);
break;
case 'v':
+ /* Increase the verbosity */
+
Verbose++;
break;
case 'x':
+ /* Check veriexec paths */
+
/*
* -x says all other args are paths to check.
*/
- for (x = 0; optind < argc; optind++) {
+ for (x = EX_OK; optind < argc; optind++) {
if (veriexec_check_path(argv[optind])) {
warn("%s", argv[optind]);
x = 2;
@@ -117,48 +198,63 @@ main(int argc, char *argv[])
exit(x);
break;
case 'z':
- switch (optarg[0]) {
- case 'a': /* active */
- ctl = VERIEXEC_ACTIVE;
- break;
- case 'd': /* debug* */
- ctl = (strstr(optarg, "off")) ?
- VERIEXEC_DEBUG_OFF : VERIEXEC_DEBUG_ON;
- if (optind < argc && ctl == VERIEXEC_DEBUG_ON) {
- x = atoi(argv[optind]);
+ /* Modify the state */
+
+ if (strncmp(optarg, "debug", strlen(optarg)) == 0) {
+ const char *error;
+
+ if (optind >= argc)
+ errx(EX_USAGE,
+ "Missing mac_veriexec verbosity level \'N\', veriexec -z debug N, where N is \'off\' or the value 0 or greater");
+
+ if (strncmp(argv[optind], "off", strlen(argv[optind])) == 0) {
+ state = VERIEXEC_DEBUG_OFF;
+ x = 0;
+ } else {
+ state = VERIEXEC_DEBUG_ON;
+
+ converted_int = strtonum(argv[optind], 0, INT_MAX, &error);
+
+ if (error != NULL)
+ errx(EX_USAGE, "Conversion error for argument \'%s\' : %s",
+ argv[optind], error);
+
+ x = (int) converted_int;
+
+
if (x == 0)
- ctl = VERIEXEC_DEBUG_OFF;
+ state = VERIEXEC_DEBUG_OFF;
}
- break;
- case 'e': /* enforce */
- ctl = VERIEXEC_ENFORCE;
- break;
- case 'g':
- ctl = VERIEXEC_GETSTATE; /* get state */
- break;
- case 'l': /* lock */
- ctl = VERIEXEC_LOCK;
- break;
- default:
- errx(EX_USAGE, "unknown command %s", optarg);
- break;
- }
- if (dev_fd < 0) {
- err(EX_UNAVAILABLE, "cannot open veriexec");
- }
- if (ioctl(dev_fd, ctl, &x)) {
- err(EX_UNAVAILABLE, "cannot %s veriexec", optarg);
- }
- if (ctl == VERIEXEC_DEBUG_ON ||
- ctl == VERIEXEC_DEBUG_OFF) {
- printf("debug is: %d\n", x);
- } else if (ctl == VERIEXEC_GETSTATE) {
- printf("%#o\n", x);
- }
+ } else
+ state = veriexec_state_modify(optarg);
+
+ if (dev_fd < 0)
+ err(EX_UNAVAILABLE, "Cannot open veriexec");
+ if (ioctl(dev_fd, state, &x))
+ err(EX_UNAVAILABLE, "Cannot %s veriexec", optarg);
+
+ if (state == VERIEXEC_DEBUG_ON || state == VERIEXEC_DEBUG_OFF)
+ printf("mac_veriexec debug verbosity level: %d\n", x);
+ else if (state == VERIEXEC_GETSTATE)
+ printf("Veriexec state (octal) : %#o\n", x);
+
exit(EX_OK);
break;
+ default:
+
+ /* Missing argument, print usage info.*/
+ veriexec_usage();
+ exit(EX_USAGE);
+ break;
}
}
+
+ if (Verbose)
+ printf("Verbosity level : %d\n", Verbose);
+
+ if (dev_fd < 0)
+ err(EX_UNAVAILABLE, "Cannot open veriexec");
+
openlog(getprogname(), LOG_PID, LOG_AUTH);
if (ve_trust_init() < 1)
errx(EX_OSFILE, "cannot initialize trust store");