aboutsummaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
Diffstat (limited to 'sbin')
-rw-r--r--sbin/comcontrol/comcontrol.818
-rw-r--r--sbin/comcontrol/comcontrol.c30
-rw-r--r--sbin/devd/devd.cc21
-rw-r--r--sbin/dhclient/packet.c53
-rw-r--r--sbin/geom/core/geom.c2
-rw-r--r--sbin/hastd/subr.c11
-rw-r--r--sbin/ifconfig/af_inet6.c2
-rw-r--r--sbin/ifconfig/ifconfig.868
-rw-r--r--sbin/ipfw/Makefile3
-rw-r--r--sbin/ipfw/nptv6.c49
-rw-r--r--sbin/ipfw/tests/Makefile1
-rw-r--r--sbin/ipfw/tests/ipfw_test.sh107
-rw-r--r--sbin/nvmecontrol/modules/Makefile5
-rw-r--r--sbin/nvmecontrol/modules/intel/intel.c15
-rw-r--r--sbin/nvmecontrol/modules/micron/Makefile6
-rw-r--r--sbin/nvmecontrol/modules/micron/micron.c129
-rw-r--r--sbin/nvmecontrol/nvmecontrol.87
-rw-r--r--sbin/pfctl/parse.y56
-rw-r--r--sbin/pfctl/pfctl.824
-rw-r--r--sbin/pfctl/pfctl.c29
-rw-r--r--sbin/pfctl/pfctl_parser.c14
-rw-r--r--sbin/pfctl/pfctl_parser.h1
-rw-r--r--sbin/pfctl/pfctl_radix.c3
-rw-r--r--sbin/pfctl/pfctl_table.c18
-rw-r--r--sbin/pfctl/tests/files/pf1073.in1
-rw-r--r--sbin/pfctl/tests/files/pf1073.ok1
-rw-r--r--sbin/pfctl/tests/files/pf1074.fail1
-rw-r--r--sbin/pfctl/tests/files/pf1074.in1
-rw-r--r--sbin/pfctl/tests/pfctl_test_list.inc2
-rw-r--r--sbin/recoverdisk/recoverdisk.16
-rw-r--r--sbin/recoverdisk/recoverdisk.c72
-rw-r--r--sbin/veriexec/veriexec.82
32 files changed, 550 insertions, 208 deletions
diff --git a/sbin/comcontrol/comcontrol.8 b/sbin/comcontrol/comcontrol.8
index bee0fdab102b..f51a1f011167 100644
--- a/sbin/comcontrol/comcontrol.8
+++ b/sbin/comcontrol/comcontrol.8
@@ -1,13 +1,17 @@
-.Dd May 15, 1994
+.Dd August 31, 2025
.Dt COMCONTROL 8
.Os
.Sh NAME
.Nm comcontrol
.Nd control a special tty device
+.Sh DEPRECATION NOTICE
+The
+.Nm
+utility is deprecated and will be removed in
+.Fx 16.0 .
.Sh SYNOPSIS
.Nm
.Ar special_device
-.Op dtrwait Ar number
.Op drainwait Ar number
.Sh DESCRIPTION
The
@@ -22,13 +26,6 @@ Only the superuser can change the settings.
.Pp
The following options are available:
.Bl -tag -width indent
-.It Cm dtrwait Ar number
-Set the time to wait after dropping DTR
-to the given number.
-The units are hundredths of a second.
-The default is 300 hundredths, i.e., 3 seconds.
-This option needed mainly to set proper recover time after
-modem reset.
.It Cm drainwait Ar number
Set the time to wait for output drain
to the given number.
@@ -57,7 +54,6 @@ dialout devices
Originally part of cgd's com package patches, version 0.2.1, to
.Bx 386 0.1 .
Once controlled bidirectional capabilities.
-Little is left to control now
-that these capabilities are standard.
+Little is left to control now that these capabilities are standard.
.Sh AUTHORS
.An Christopher G. Demetriou
diff --git a/sbin/comcontrol/comcontrol.c b/sbin/comcontrol/comcontrol.c
index 7a03b3a569cf..d6d24e8acab8 100644
--- a/sbin/comcontrol/comcontrol.c
+++ b/sbin/comcontrol/comcontrol.c
@@ -46,7 +46,7 @@ static void
usage(void)
{
fprintf(stderr,
- "usage: comcontrol <filename> [dtrwait <n>] [drainwait <n>]\n");
+ "usage: comcontrol <filename> [drainwait <n>]\n");
exit(1);
}
@@ -55,8 +55,8 @@ main(int argc, char *argv[])
{
int fd;
int res = 0;
- int print_dtrwait = 1, print_drainwait = 1;
- int dtrwait = -1, drainwait = -1;
+ int print_drainwait = 1;
+ int drainwait = -1;
if (argc < 2)
usage();
@@ -71,13 +71,6 @@ main(int argc, char *argv[])
}
}
if (argc == 2) {
- if (ioctl(fd, TIOCMGDTRWAIT, &dtrwait) < 0) {
- print_dtrwait = 0;
- if (errno != ENOTTY) {
- res = 1;
- warn("TIOCMGDTRWAIT");
- }
- }
if (ioctl(fd, TIOCGDRAINWAIT, &drainwait) < 0) {
print_drainwait = 0;
if (errno != ENOTTY) {
@@ -85,21 +78,12 @@ main(int argc, char *argv[])
warn("TIOCGDRAINWAIT");
}
}
- if (print_dtrwait)
- printf("dtrwait %d ", dtrwait);
if (print_drainwait)
printf("drainwait %d ", drainwait);
printf("\n");
} else {
while (argv[2] != NULL) {
- if (!strcmp(argv[2],"dtrwait")) {
- if (dtrwait >= 0)
- usage();
- if (argv[3] == NULL || !isdigit(argv[3][0]))
- usage();
- dtrwait = atoi(argv[3]);
- argv += 2;
- } else if (!strcmp(argv[2],"drainwait")) {
+ if (!strcmp(argv[2],"drainwait")) {
if (drainwait >= 0)
usage();
if (argv[3] == NULL || !isdigit(argv[3][0]))
@@ -109,12 +93,6 @@ main(int argc, char *argv[])
} else
usage();
}
- if (dtrwait >= 0) {
- if (ioctl(fd, TIOCMSDTRWAIT, &dtrwait) < 0) {
- res = 1;
- warn("TIOCMSDTRWAIT");
- }
- }
if (drainwait >= 0) {
if (ioctl(fd, TIOCSDRAINWAIT, &drainwait) < 0) {
res = 1;
diff --git a/sbin/devd/devd.cc b/sbin/devd/devd.cc
index 1ff405244cde..ee38fbb2ccee 100644
--- a/sbin/devd/devd.cc
+++ b/sbin/devd/devd.cc
@@ -1208,27 +1208,6 @@ new_action(const char *cmd)
eps *
new_match(const char *var, const char *re)
{
- /*
- * In FreeBSD 14, we changed the system=kern to system=kernel for the
- * resume message to match all the other 'kernel' messages. Generate a
- * warning for the life of 14.x that we've 'fixed' the file on the fly,
- * but make it a fatal error in 15.x and newer.
- */
- if (strcmp(var, "kern") == 0) {
-#if __FreeBSD_version < 1500000
- devdlog(LOG_WARNING,
- "Changing deprecated system='kern' to new name 'kernel' in %s line %d.",
- curr_cf, lineno);
- free(const_cast<char *>(var));
- var = strdup("kernel");
-#elif __FreeBSD_version < 1600000
- errx(1, "Encountered deprecated system=\"kern\" rule in %s line %d",
- curr_cf, lineno);
-#else
-#error "Remove this gross hack"
-#endif
- }
-
eps *e = new match(cfg, var, re);
free(const_cast<char *>(var));
free(const_cast<char *>(re));
diff --git a/sbin/dhclient/packet.c b/sbin/dhclient/packet.c
index 3d7390c06ee0..fc0305a8cb0c 100644
--- a/sbin/dhclient/packet.c
+++ b/sbin/dhclient/packet.c
@@ -135,11 +135,14 @@ assemble_udp_ip_header(unsigned char *buf, int *bufix, u_int32_t from,
udp.uh_ulen = htons(sizeof(udp) + len);
memset(&udp.uh_sum, 0, sizeof(udp.uh_sum));
- udp.uh_sum = wrapsum(checksum((unsigned char *)&udp, sizeof(udp),
- checksum(data, len, checksum((unsigned char *)&ip.ip_src,
+ udp.uh_sum = wrapsum(checksum(data, len, checksum((unsigned char *)&udp,
+ sizeof(udp), checksum((unsigned char *)&ip.ip_src,
2 * sizeof(ip.ip_src),
IPPROTO_UDP + (u_int32_t)ntohs(udp.uh_ulen)))));
+ if (udp.uh_sum == htons(0))
+ udp.uh_sum = htons(0xffff);
+
memcpy(&buf[*bufix], &udp, sizeof(udp));
*bufix += sizeof(udp);
}
@@ -166,7 +169,7 @@ decode_udp_ip_header(unsigned char *buf, int bufix, struct sockaddr_in *from,
struct ip *ip;
struct udphdr *udp;
u_int32_t ip_len = (buf[bufix] & 0xf) << 2;
- u_int32_t sum, usum;
+ u_int32_t sum, usum, pseudo_sum;
static int ip_packets_seen;
static int ip_packets_bad_checksum;
static int udp_packets_seen;
@@ -224,23 +227,37 @@ decode_udp_ip_header(unsigned char *buf, int bufix, struct sockaddr_in *from,
}
usum = udp->uh_sum;
- udp->uh_sum = 0;
-
- sum = wrapsum(checksum((unsigned char *)udp, sizeof(*udp),
- checksum(data, len, checksum((unsigned char *)&ip->ip_src,
- 2 * sizeof(ip->ip_src),
- IPPROTO_UDP + (u_int32_t)ntohs(udp->uh_ulen)))));
-
udp_packets_seen++;
- if (usum && usum != sum) {
- udp_packets_bad_checksum++;
- if (udp_packets_seen > 4 && udp_packets_bad_checksum != 0 &&
- (udp_packets_seen / udp_packets_bad_checksum) < 2) {
- note("%d bad udp checksums in %d packets",
- udp_packets_bad_checksum, udp_packets_seen);
- udp_packets_seen = udp_packets_bad_checksum = 0;
+
+ if (usum != htons(0)) {
+ udp->uh_sum = 0;
+
+ pseudo_sum = checksum((unsigned char *)&ip->ip_src,
+ 2 * sizeof(ip->ip_src),
+ IPPROTO_UDP + (u_int32_t)ntohs(udp->uh_ulen));
+ sum = wrapsum(checksum(data, len,
+ checksum((unsigned char *)udp, sizeof(*udp), pseudo_sum)));
+ if (sum == htons(0))
+ sum = htons(0xffff);
+
+ /*
+ * In addition to accepting UDP packets with the correct
+ * checksum in the checksum field, accept also the ones which
+ * have the correct pseudo header checksum in the checksum
+ * field. This allows to process UDP packets, which have been
+ * marked for transmit checksum offloading by the sender side.
+ */
+ if (usum != sum && usum != htons(pseudo_sum & 0x0000ffff)) {
+ udp_packets_bad_checksum++;
+ if (udp_packets_seen > 4 &&
+ udp_packets_bad_checksum != 0 &&
+ (udp_packets_seen / udp_packets_bad_checksum) < 2) {
+ note("%d bad udp checksums in %d packets",
+ udp_packets_bad_checksum, udp_packets_seen);
+ udp_packets_seen = udp_packets_bad_checksum = 0;
+ }
+ return (-1);
}
- return (-1);
}
memcpy(&from->sin_port, &udp->uh_sport, sizeof(udp->uh_sport));
diff --git a/sbin/geom/core/geom.c b/sbin/geom/core/geom.c
index 950f6790b1a8..b78021194ddd 100644
--- a/sbin/geom/core/geom.c
+++ b/sbin/geom/core/geom.c
@@ -249,7 +249,7 @@ static void
set_option(struct gctl_req *req, struct g_option *opt, const char *val)
{
const char *optname;
- uint64_t number;
+ int64_t number;
void *ptr;
if (G_OPT_ISMULTI(opt)) {
diff --git a/sbin/hastd/subr.c b/sbin/hastd/subr.c
index 2a26482b3727..add1280e960b 100644
--- a/sbin/hastd/subr.c
+++ b/sbin/hastd/subr.c
@@ -207,10 +207,8 @@ drop_privs(const struct hast_resource *res)
}
}
PJDLOG_VERIFY(chdir("/") == 0);
- gidset[0] = pw->pw_gid;
- if (setgroups(1, gidset) == -1) {
- pjdlog_errno(LOG_ERR, "Unable to set groups to gid %u",
- (unsigned int)pw->pw_gid);
+ if (setgroups(0, NULL) == -1) {
+ pjdlog_errno(LOG_ERR, "Unable to drop supplementary groups");
return (-1);
}
if (setgid(pw->pw_gid) == -1) {
@@ -286,9 +284,8 @@ drop_privs(const struct hast_resource *res)
PJDLOG_VERIFY(rgid == pw->pw_gid);
PJDLOG_VERIFY(egid == pw->pw_gid);
PJDLOG_VERIFY(sgid == pw->pw_gid);
- PJDLOG_VERIFY(getgroups(0, NULL) == 1);
- PJDLOG_VERIFY(getgroups(1, gidset) == 1);
- PJDLOG_VERIFY(gidset[0] == pw->pw_gid);
+ PJDLOG_VERIFY(getgroups(0, NULL) == 0);
+ PJDLOG_VERIFY(getgroups(1, gidset) == 0);
pjdlog_debug(1,
"Privileges successfully dropped using %s%s+setgid+setuid.",
diff --git a/sbin/ifconfig/af_inet6.c b/sbin/ifconfig/af_inet6.c
index 7986edf490b4..e0f34f0c4d82 100644
--- a/sbin/ifconfig/af_inet6.c
+++ b/sbin/ifconfig/af_inet6.c
@@ -753,7 +753,7 @@ static struct afswtch af_inet6 = {
#ifdef WITHOUT_NETLINK
.af_difaddr = SIOCDIFADDR_IN6,
.af_aifaddr = SIOCAIFADDR_IN6,
- .af_ridreq = &in6_addreq,
+ .af_ridreq = &in6_ridreq,
.af_addreq = &in6_addreq,
.af_exec = af_exec_ioctl,
#else
diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8
index b562f9e4c0c5..b580191383b3 100644
--- a/sbin/ifconfig/ifconfig.8
+++ b/sbin/ifconfig/ifconfig.8
@@ -28,7 +28,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd August 5, 2025
+.Dd August 10, 2025
.Dt IFCONFIG 8
.Os
.Sh NAME
@@ -2718,30 +2718,17 @@ Set the maximum number of hosts allowed from an interface, packets with unknown
source addresses are dropped until an existing host cache entry expires or is
removed.
Set to 0 to disable.
-.El
-.Ss Bridge VLAN Filtering Parameters
-The behaviour of these options is described in the
-.Dq VLAN SUPPORT
-section of
-.Xr bridge 4 .
-.Bl -tag -width indent
.It Cm vlanfilter
Enable VLAN filtering on the bridge.
+Incoming frames on member interfaces will be dropped unless the frame
+is explicitly permitted by the interface's
+.Cm ifuntagged
+or
+.Cm iftagged
+configuration.
.It Cm -vlanfilter
Disable VLAN filtering on the bridge.
This is the default.
-.It Cm ifuntagged Ar interface Ar vlan-id
-Set the untagged VLAN identifier for an interface.
-.It Cm -ifuntagged Ar interface Ar vlan-id
-Clear the untagged VLAN identifier for an interface.
-.It Cm defuntagged Ar vlan-id
-Enable the
-.Cm untagged
-option by default on newly added members.
-.It Cm -defuntagged
-Do not enable the
-.Cm untagged
-option by default on newly added members.
.It Cm iftagged Ar interface Ar vlan-list
Set the interface's VLAN access list to the provided list of VLANs.
The list should be a comma-separated list of one or more VLAN IDs
@@ -2753,24 +2740,61 @@ meaning the empty set,
or the value
.Dq all
meaning all VLANs (1-4094).
+.Pp
+This option is only meaningful if the
+.Cm vlanfilter
+option is enabled for the bridge;
+otherwise, all VLANs will be permitted.
.It Cm +iftagged Ar interface Ar vlan-list
Add the provided list of VLAN IDs to the interface's VLAN access list.
The list should be formatted as described for
.Cm iftagged .
+.Pp
+This option is only meaningful if the
+.Cm vlanfilter
+option is enabled for the bridge;
+otherwise, all VLANs will be permitted.
.It Cm -iftagged Ar interface Ar vlan-list
Remove the provided list of VLAN IDs from the interface's VLAN access
list.
The list should be formatted as described for
.Cm iftagged .
+.Pp
+This option is only meaningful if the
+.Cm vlanfilter
+option is enabled for the bridge;
+otherwise, all VLANs will be permitted.
+.It Cm ifuntagged Ar interface Ar vlan-id
+Set the untagged VLAN identifier for an interface.
+Frames received on this interface without an 802.1Q tag will be assigned
+to this VLAN instead of the default VLAN 0,
+and outgoing frames on this VLAN will have their 802.1Q tag removed.
+.It Cm -ifuntagged Ar interface Ar vlan-id
+Clear the untagged VLAN identifier for an interface.
+.It Cm defuntagged Ar vlan-id
+Enable the
+.Cm untagged
+option by default on newly added members.
+.It Cm -defuntagged
+Do not enable the
+.Cm untagged
+option by default on newly added members.
+This is the default.
.It Cm qinq Ar interface
Allow this interface to send 802.1ad
.Dq Q-in-Q
frames.
+This option is only meaningful if the
+.Cm vlanfilter
+option is enabled for the bridge;
+otherwise, Q-in-Q frames are always allowed.
.It Cm -qinq Ar interface
Do not allow this interface to send 802.1ad
.Dq Q-in-Q
frames.
-This is the default behavior.
+This is the default if the
+.Cm vlanfilter
+option is enabled.
.It Cm defqinq
Enable the
.Cm qinq
@@ -2779,7 +2803,7 @@ option by default on newly added members.
Do not enable the
.Cm qinq
option by default on newly added members.
-This is the default behavior.
+This is the default.
.It Cm ifvlanproto Ar interface Ar proto
Set the VLAN encapsulation protocol on
.Ar interface
diff --git a/sbin/ipfw/Makefile b/sbin/ipfw/Makefile
index bfbe70130de7..418c0f613741 100644
--- a/sbin/ipfw/Makefile
+++ b/sbin/ipfw/Makefile
@@ -17,6 +17,9 @@ CFLAGS+=-DPF
LIBADD= jail util
MAN= ipfw.8
+HAS_TESTS=
+SUBDIR.${MK_TESTS}= tests
+
.include <bsd.prog.mk>
CWARNFLAGS+= -Wno-cast-align
diff --git a/sbin/ipfw/nptv6.c b/sbin/ipfw/nptv6.c
index 83bf4c768fd9..eee6109a3d9e 100644
--- a/sbin/ipfw/nptv6.c
+++ b/sbin/ipfw/nptv6.c
@@ -153,10 +153,10 @@ static struct _s_x nptv6newcmds[] = {
{ NULL, 0 }
};
-
static void
nptv6_parse_prefix(const char *arg, struct in6_addr *prefix, int *len)
{
+ long plen;
char *p, *l;
p = strdup(arg);
@@ -167,13 +167,15 @@ nptv6_parse_prefix(const char *arg, struct in6_addr *prefix, int *len)
if (inet_pton(AF_INET6, p, prefix) != 1)
errx(EX_USAGE, "Bad prefix: %s", p);
if (l != NULL) {
- *len = (int)strtol(l, &l, 10);
- if (*l != '\0' || *len <= 0 || *len > 64)
+ plen = strtol(l, &l, 10);
+ if (*l != '\0' || plen < 8 || plen > 64)
errx(EX_USAGE, "Bad prefix length: %s", arg);
+ *len = plen;
} else
*len = 0;
free(p);
}
+
/*
* Creates new nptv6 instance
* ipfw nptv6 <NAME> create int_prefix <prefix> ext_prefix <prefix>
@@ -189,10 +191,10 @@ nptv6_create(const char *name, uint8_t set, int ac, char *av[])
struct in6_addr mask;
ipfw_nptv6_cfg *cfg;
ipfw_obj_lheader *olh;
- int tcmd, flags, plen;
+ int tcmd, flags, iplen, eplen, pplen;
char *p;
- plen = 0;
+ iplen = eplen = pplen = 0;
memset(buf, 0, sizeof(buf));
olh = (ipfw_obj_lheader *)buf;
cfg = (ipfw_nptv6_cfg *)(olh + 1);
@@ -205,10 +207,8 @@ nptv6_create(const char *name, uint8_t set, int ac, char *av[])
switch (tcmd) {
case TOK_INTPREFIX:
NEED1("IPv6 prefix required");
- nptv6_parse_prefix(*av, &cfg->internal, &plen);
+ nptv6_parse_prefix(*av, &cfg->internal, &iplen);
flags |= NPTV6_HAS_INTPREFIX;
- if (plen > 0)
- goto check_prefix;
ac--; av++;
break;
case TOK_EXTPREFIX:
@@ -216,10 +216,8 @@ nptv6_create(const char *name, uint8_t set, int ac, char *av[])
errx(EX_USAGE,
"Only one ext_prefix or ext_if allowed");
NEED1("IPv6 prefix required");
- nptv6_parse_prefix(*av, &cfg->external, &plen);
+ nptv6_parse_prefix(*av, &cfg->external, &eplen);
flags |= NPTV6_HAS_EXTPREFIX;
- if (plen > 0)
- goto check_prefix;
ac--; av++;
break;
case TOK_EXTIF:
@@ -236,24 +234,29 @@ nptv6_create(const char *name, uint8_t set, int ac, char *av[])
break;
case TOK_PREFIXLEN:
NEED1("IPv6 prefix length required");
- plen = strtol(*av, &p, 10);
-check_prefix:
- if (*p != '\0' || plen < 8 || plen > 64)
+ pplen = strtol(*av, &p, 10);
+ if (*p != '\0' || pplen < 8 || pplen > 64)
errx(EX_USAGE, "wrong prefix length: %s", *av);
- /* RFC 6296 Sec. 3.1 */
- if (cfg->plen > 0 && cfg->plen != plen) {
- warnx("Prefix length mismatch (%d vs %d). "
- "It was extended up to %d",
- cfg->plen, plen, MAX(plen, cfg->plen));
- plen = MAX(plen, cfg->plen);
- }
- cfg->plen = plen;
- flags |= NPTV6_HAS_PREFIXLEN;
ac--; av++;
break;
}
}
+ /* RFC 6296 Sec. 3.1 */
+ if (pplen != 0) {
+ if ((eplen != 0 && eplen != pplen) ||
+ (iplen != 0 && iplen != pplen))
+ errx(EX_USAGE, "prefix length mismatch");
+ cfg->plen = pplen;
+ flags |= NPTV6_HAS_PREFIXLEN;
+ } else if (eplen != 0 || iplen != 0) {
+ if (eplen != 0 && iplen != 0 && eplen != iplen)
+ errx(EX_USAGE, "prefix length mismatch");
+ warnx("use prefixlen instead");
+ cfg->plen = eplen ? eplen : iplen;
+ flags |= NPTV6_HAS_PREFIXLEN;
+ }
+
/* Check validness */
if ((flags & NPTV6_HAS_INTPREFIX) != NPTV6_HAS_INTPREFIX)
errx(EX_USAGE, "int_prefix required");
diff --git a/sbin/ipfw/tests/Makefile b/sbin/ipfw/tests/Makefile
index 987410f5d710..e2d4dab2729a 100644
--- a/sbin/ipfw/tests/Makefile
+++ b/sbin/ipfw/tests/Makefile
@@ -1,5 +1,6 @@
PACKAGE= tests
ATF_TESTS_PYTEST+= test_add_rule.py
+ATF_TESTS_SH+= ipfw_test
.include <bsd.test.mk>
diff --git a/sbin/ipfw/tests/ipfw_test.sh b/sbin/ipfw/tests/ipfw_test.sh
new file mode 100644
index 000000000000..c7993c430a3d
--- /dev/null
+++ b/sbin/ipfw/tests/ipfw_test.sh
@@ -0,0 +1,107 @@
+#
+# Copyright (c) 2025 Dag-Erling Smørgrav <des@FreeBSD.org>
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+. $(atf_get_srcdir)/../../sys/common/vnet.subr
+
+atf_test_case nptv6 cleanup
+nptv6_head()
+{
+ atf_set "descr" "Test creation of NPTv6 rules"
+ atf_set "require.user" "root"
+ atf_set "require.kmods" "ipfw_nptv6"
+}
+nptv6_body()
+{
+ vnet_init
+ local jail=ipfw_$(atf_get ident)
+ local epair=$(vnet_mkepair)
+ vnet_mkjail ${jail} ${epair}a
+
+ local rule="xyzzy"
+ local int="2001:db8:1::"
+ local ext="2001:db8:2::"
+
+ atf_check jexec ${jail} \
+ ifconfig "${epair}"a inet6 ${ext}1/64 up
+
+ # This is how it's supposed to be used
+ atf_check jexec ${jail} ipfw nptv6 ${rule} create \
+ int_prefix ${int} ext_prefix ${ext} prefixlen 64
+ atf_check -o inline:\
+"nptv6 $rule int_prefix $int ext_prefix $ext prefixlen 64\n" \
+ jexec ${jail} ipfw nptv6 all list
+ atf_check jexec ${jail} ipfw nptv6 all destroy
+
+ # Specify external interface rather than network
+ atf_check jexec ${jail} ipfw nptv6 ${rule} create \
+ int_prefix ${int} ext_if ${epair}a prefixlen 64
+ atf_check -o inline:\
+"nptv6 $rule int_prefix $int ext_if ${epair}a prefixlen 64\n" \
+ jexec ${jail} ipfw nptv6 all list
+ atf_check jexec ${jail} ipfw nptv6 all destroy
+
+ # This should also work
+ atf_check jexec ${jail} ipfw nptv6 ${rule} create \
+ int_prefix ${int}/64 ext_prefix ${ext}/64 prefixlen 64
+ atf_check -o inline:\
+"nptv6 $rule int_prefix $int ext_prefix $ext prefixlen 64\n" \
+ jexec ${jail} ipfw nptv6 all list
+ atf_check jexec ${jail} ipfw nptv6 all destroy
+
+ # This should also work, although it's not encouraged
+ atf_check -e match:"use prefixlen instead" \
+ jexec ${jail} ipfw nptv6 ${rule} create \
+ int_prefix ${int}/64 ext_prefix ${ext}/64
+ atf_check -o inline:\
+"nptv6 $rule int_prefix $int ext_prefix $ext prefixlen 64\n" \
+ jexec ${jail} ipfw nptv6 all list
+ atf_check jexec ${jail} ipfw nptv6 all destroy
+
+ # These should all fail
+ atf_check -s not-exit:0 -e match:"one ext_prefix or ext_if" \
+ jexec ${jail} ipfw nptv6 ${rule} create \
+ int_prefix ${int} ext_prefix ${ext} ext_if ${epair}a
+ atf_check -o empty jexec ${jail} ipfw nptv6 all list
+
+ atf_check -s not-exit:0 -e match:"one ext_prefix or ext_if" \
+ jexec ${jail} ipfw nptv6 ${rule} create \
+ int_prefix ${int} ext_if ${epair}a ext_prefix ${ext}
+ atf_check -o empty jexec ${jail} ipfw nptv6 all list
+
+ atf_check -s not-exit:0 -e match:"prefix length mismatch" \
+ jexec ${jail} ipfw nptv6 ${rule} create \
+ int_prefix ${int}/48 ext_prefix ${ext}/64
+ atf_check -o empty jexec ${jail} ipfw nptv6 all list
+
+ atf_check -s not-exit:0 -e match:"prefix length mismatch" \
+ jexec ${jail} ipfw nptv6 ${rule} create \
+ int_prefix ${int}/64 ext_prefix ${ext}/64 prefixlen 48
+ atf_check -o empty jexec ${jail} ipfw nptv6 all list
+
+ atf_check -s not-exit:0 -e match:"prefix length mismatch" \
+ jexec ${jail} ipfw nptv6 ${rule} create \
+ int_prefix ${int}/64 ext_prefix ${ext} prefixlen 48
+ atf_check -o empty jexec ${jail} ipfw nptv6 all list
+
+ atf_check -s not-exit:0 -e match:"prefix length mismatch" \
+ jexec ${jail} ipfw nptv6 ${rule} create \
+ int_prefix ${int} ext_prefix ${ext}/64 prefixlen 48
+ atf_check -o empty jexec ${jail} ipfw nptv6 all list
+
+ atf_check -s not-exit:0 -e match:"prefix length mismatch" \
+ jexec ${jail} ipfw nptv6 ${rule} create \
+ int_prefix ${int}/64 ext_if ${epair}a prefixlen 48
+ atf_check -o empty jexec ${jail} ipfw nptv6 all list
+}
+nptv6_cleanup()
+{
+ vnet_cleanup
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case nptv6
+}
diff --git a/sbin/nvmecontrol/modules/Makefile b/sbin/nvmecontrol/modules/Makefile
index 70d1ba40a1e2..f3c3572acb34 100644
--- a/sbin/nvmecontrol/modules/Makefile
+++ b/sbin/nvmecontrol/modules/Makefile
@@ -1,3 +1,6 @@
-SUBDIR= intel wdc samsung
+SUBDIR= intel
+SUBDIR+=micron
+SUBDIR+=samsung
+SUBDIR+=wdc
.include <bsd.subdir.mk>
diff --git a/sbin/nvmecontrol/modules/intel/intel.c b/sbin/nvmecontrol/modules/intel/intel.c
index 4229a48e4153..6ffe2c4c1563 100644
--- a/sbin/nvmecontrol/modules/intel/intel.c
+++ b/sbin/nvmecontrol/modules/intel/intel.c
@@ -195,6 +195,18 @@ print_intel_add_smart(const struct nvme_controller_data *cdata __unused, void *b
}
}
+static void
+print_intel_drive_marketing_name(const struct nvme_controller_data *cdata __unused, void *buf, uint32_t size __unused)
+{
+ const char *p = buf;
+
+ printf("Intel Drive Marketing Name Log\n");
+ printf("=======================\n");
+ printf("%.*s\n", 29, p);
+}
+
+#define INTEL_LOG_DRIVE_MARKETING_NAME 0xdd
+
NVME_LOGPAGE(intel_temp,
INTEL_LOG_TEMP_STATS, "intel", "Temperature Stats",
print_intel_temp_stats, sizeof(struct intel_log_temp_stats));
@@ -207,3 +219,6 @@ NVME_LOGPAGE(intel_wlat,
NVME_LOGPAGE(intel_smart, /* Note: Samsung and Micron also use this */
INTEL_LOG_ADD_SMART, "intel", "Extra Health/SMART Data",
print_intel_add_smart, DEFAULT_SIZE);
+NVME_LOGPAGE(intel_dmn,
+ INTEL_LOG_DRIVE_MARKETING_NAME, "intel", "Drive Marketing Name Log",
+ print_intel_drive_marketing_name, DEFAULT_SIZE);
diff --git a/sbin/nvmecontrol/modules/micron/Makefile b/sbin/nvmecontrol/modules/micron/Makefile
new file mode 100644
index 000000000000..3cefd455f711
--- /dev/null
+++ b/sbin/nvmecontrol/modules/micron/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+LIB= micron
+SRCS= micron.c
+
+.include <bsd.lib.mk>
diff --git a/sbin/nvmecontrol/modules/micron/micron.c b/sbin/nvmecontrol/modules/micron/micron.c
new file mode 100644
index 000000000000..2d4731e7da47
--- /dev/null
+++ b/sbin/nvmecontrol/modules/micron/micron.c
@@ -0,0 +1,129 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2022 Wanpeng Qian <wanpengqian@gmail.com>
+ *
+ * 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 AUTHOR 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 AUTHOR 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/ioccom.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/endian.h>
+
+#include "nvmecontrol.h"
+
+static void
+print_micron_unique_smart(const struct nvme_controller_data *cdata __unused, void *buf, uint32_t size __unused)
+{
+ uint8_t *walker = buf;
+ uint8_t *end = walker + 150;
+ const char *name;
+ uint64_t raw;
+ uint8_t normalized;
+
+ static struct kv_name kv[] =
+ {
+ { 0xf9, "NAND Writes 1GiB" },
+ { 0xfa, "NAND Reads 1GiB" },
+ { 0xea, "Thermal Throttle Status" },
+ { 0xe7, "Temperature" },
+ { 0xe8, "Power Consumption" },
+ { 0xaf, "Power Loss Protection" },
+ };
+
+ printf("Vendor Unique SMART Information\n");
+ printf("=========================\n");
+ /*
+ * walker[0] = Key
+ * walker[1,2] = reserved
+ * walker[3] = Normalized Value
+ * walker[4] = reserved
+ * walker[5..10] = Little Endian Raw value
+ * (or other represenations)
+ * walker[11] = reserved
+ */
+ while (walker < end) {
+ name = kv_lookup(kv, nitems(kv), *walker);
+ normalized = walker[3];
+ raw = le48dec(walker + 5);
+ switch (*walker){
+ case 0:
+ break;
+ case 0xf9:
+ /* FALLTHOUGH */
+ case 0xfa:
+ printf("%2X %-24s: %ju GiB\n", *walker, name, (uintmax_t)raw);
+ break;
+ case 0xea:
+ printf("%2X %-24s:", *walker, name);
+ if (*(walker + 5) == 0)
+ printf(" inactive\n");
+ if (*(walker + 5) == 1)
+ printf(" active, total throttling time %u mins\n", le32dec(walker + 6));
+ break;
+ case 0xe7:
+ printf("%2X %-24s: max ", *walker, name);
+ print_temp_C(le16dec(walker + 5));
+ printf(" : min ");
+ print_temp_C(le16dec(walker + 7));
+ printf(" : cur ");
+ print_temp_C(le16dec(walker + 9));
+ break;
+ case 0xe8:
+ printf("%2X %-24s: max %u W, min %u W, ave %u W\n",
+ *walker, name, le16dec(walker + 5), le16dec(walker + 7), le16dec(walker + 9));
+ break;
+ case 0xaf:
+ printf("%2X %-24s:", *walker, name);
+ if (normalized == 100)
+ printf(" success");
+ if (normalized == 0)
+ printf(" failed");
+ printf(" %3d\n", normalized);
+ break;
+ default:
+ printf("%2X %-24s: %3d %ju\n",
+ *walker, name, normalized, (uintmax_t)raw);
+ break;
+ }
+ walker += 12;
+ }
+}
+
+#define MICRON_LOG_UNIQUE_SMART 0xca
+
+NVME_LOGPAGE(micron_smart,
+ MICRON_LOG_UNIQUE_SMART, "micron", "Vendor Unique SMART Information",
+ print_micron_unique_smart, DEFAULT_SIZE);
diff --git a/sbin/nvmecontrol/nvmecontrol.8 b/sbin/nvmecontrol/nvmecontrol.8
index 624a0c93719b..dc757bcf90c3 100644
--- a/sbin/nvmecontrol/nvmecontrol.8
+++ b/sbin/nvmecontrol/nvmecontrol.8
@@ -303,7 +303,8 @@ data associated with that drive.
.El
.Ss logpage
The logpage command knows how to print log pages of various types.
-It also knows about vendor specific log pages from hgst/wdc, samsung and intel.
+It also knows about vendor specific log pages from HGST/WDC, Samsung,
+Micron and Intel.
Note that some vendors use the same log page numbers for different data.
.Pp
.Bl -tag -compact -width "Page 0x00"
@@ -328,13 +329,15 @@ Advanced SMART information (WDC/HGST)
.It Dv Page 0xc1
Read latency stats (Intel)
.It Dv Page 0xc2
-Wite latency stats (Intel)
+Write latency stats (Intel)
.It Dv Page 0xc5
Temperature stats (Intel)
.It Dv Page 0xca
Advanced SMART information (Intel)
.It Dv Page 0xca
Extended SMART information (Samsung)
+.It Dv Page 0xca
+Vendor Unique SMART information (Micron)
.El
.Pp
Specifying
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
index 00c36b218055..46e9f60fe48e 100644
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -166,8 +166,8 @@ struct node_gid {
};
struct node_icmp {
- u_int8_t code;
- u_int8_t type;
+ uint16_t code;
+ uint16_t type;
u_int8_t proto;
struct node_icmp *next;
struct node_icmp *tail;
@@ -238,6 +238,7 @@ static struct pool_opts {
#define POM_TYPE 0x01
#define POM_STICKYADDRESS 0x02
#define POM_ENDPI 0x04
+#define POM_IPV6NH 0x08
u_int8_t opts;
int type;
int staticport;
@@ -543,7 +544,7 @@ int parseport(char *, struct range *r, int);
%token MAXSRCCONN MAXSRCCONNRATE OVERLOAD FLUSH SLOPPY PFLOW ALLOW_RELATED
%token TAGGED TAG IFBOUND FLOATING STATEPOLICY STATEDEFAULTS ROUTE SETTOS
%token DIVERTTO DIVERTREPLY BRIDGE_TO RECEIVEDON NE LE GE AFTO NATTO RDRTO
-%token BINATTO MAXPKTRATE MAXPKTSIZE
+%token BINATTO MAXPKTRATE MAXPKTSIZE IPV6NH
%token <v.string> STRING
%token <v.number> NUMBER
%token <v.i> PORTBINARY
@@ -2648,13 +2649,16 @@ pfrule : action dir logquick interface route af proto fromto
YYERROR;
}
r.rt = $5.rt;
- decide_address_family($5.redirspec->host, &r.af);
- if (!(r.rule_flag & PFRULE_AFTO))
- remove_invalid_hosts(&($5.redirspec->host), &r.af);
- if ($5.redirspec->host == NULL) {
- yyerror("no routing address with "
- "matching address family found.");
- YYERROR;
+
+ if (!($5.redirspec->pool_opts.opts & PF_POOL_IPV6NH)) {
+ decide_address_family($5.redirspec->host, &r.af);
+ if (!(r.rule_flag & PFRULE_AFTO))
+ remove_invalid_hosts(&($5.redirspec->host), &r.af);
+ if ($5.redirspec->host == NULL) {
+ yyerror("no routing address with "
+ "matching address family found.");
+ YYERROR;
+ }
}
}
#ifdef __FreeBSD__
@@ -2978,7 +2982,8 @@ filter_opt : USER uids {
filter_opts.nat = $4;
filter_opts.nat->af = $2;
- if ($4->af && $4->af != $2) {
+ remove_invalid_hosts(&($4->host), &(filter_opts.nat->af));
+ if ($4->host == NULL) {
yyerror("af-to addresses must be in the "
"target address family");
YYERROR;
@@ -2998,8 +3003,9 @@ filter_opt : USER uids {
filter_opts.nat->af = $2;
filter_opts.rdr = $6;
filter_opts.rdr->af = $2;
- if (($4->af && $4->host->af != $2) ||
- ($6->af && $6->host->af != $2)) {
+ remove_invalid_hosts(&($4->host), &(filter_opts.nat->af));
+ remove_invalid_hosts(&($6->host), &(filter_opts.rdr->af));
+ if ($4->host == NULL || $6->host == NULL) {
yyerror("af-to addresses must be in the "
"target address family");
YYERROR;
@@ -4674,6 +4680,14 @@ pool_opt : BITMASK {
pool_opts.marker |= POM_ENDPI;
pool_opts.opts |= PF_POOL_ENDPI;
}
+ | IPV6NH {
+ if (pool_opts.marker & POM_IPV6NH) {
+ yyerror("prefer-ipv6-nexthop cannot be redefined");
+ YYERROR;
+ }
+ pool_opts.marker |= POM_IPV6NH;
+ pool_opts.opts |= PF_POOL_IPV6NH;
+ }
| MAPEPORTSET number '/' number '/' number {
if (pool_opts.mape.offset) {
yyerror("map-e-portset cannot be redefined");
@@ -4813,6 +4827,12 @@ natrule : nataction interface af proto fromto tag tagged rtable
"address'");
YYERROR;
}
+ if ($9->pool_opts.opts & PF_POOL_IPV6NH) {
+ yyerror("The prefer-ipv6-nexthop option "
+ "can't be used for nat/rdr/binat pools"
+ );
+ YYERROR;
+ }
if (!r.af && ! $9->host->ifindex)
r.af = $9->host->af;
@@ -5074,13 +5094,6 @@ route_host : STRING {
route_host_list : route_host optnl { $$ = $1; }
| route_host_list comma route_host optnl {
- if ($1->af == 0)
- $1->af = $3->af;
- if ($1->af != $3->af) {
- yyerror("all pool addresses must be in the "
- "same address family");
- YYERROR;
- }
$1->tail->next = $3;
$1->tail = $3->tail;
$$ = $1;
@@ -6678,6 +6691,7 @@ lookup(char *s)
{ "pass", PASS},
{ "pflow", PFLOW},
{ "port", PORT},
+ { "prefer-ipv6-nexthop", IPV6NH},
{ "prio", PRIO},
{ "priority", PRIORITY},
{ "priq", PRIQ},
@@ -7077,7 +7091,7 @@ pushfile(const char *name, int secret)
free(nfile);
return (NULL);
}
- } else if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
+ } else if ((nfile->stream = pfctl_fopen(nfile->name, "r")) == NULL) {
warn("%s: %s", __func__, nfile->name);
free(nfile->name);
free(nfile);
diff --git a/sbin/pfctl/pfctl.8 b/sbin/pfctl/pfctl.8
index f582c6301124..5a74a8fd3444 100644
--- a/sbin/pfctl/pfctl.8
+++ b/sbin/pfctl/pfctl.8
@@ -24,7 +24,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 July 7, 2025
+.Dd August 5, 2025
.Dt PFCTL 8
.Os
.Sh NAME
@@ -410,6 +410,7 @@ This is the default behaviour.
.It Fl o Cm profile
Enable basic ruleset optimizations with profiling.
.El
+.Pp
For further information on the ruleset optimizer, see
.Xr pf.conf 5 .
.It Fl P
@@ -431,7 +432,7 @@ Perform reverse DNS lookups on states and tables when displaying them.
and
.Fl r
are mutually exclusive.
-.It Fl s Ar modifier
+.It Fl s Ar modifier Op Fl R Ar id
Show the filter parameters specified by
.Ar modifier
(may be abbreviated):
@@ -563,19 +564,16 @@ no free ports in translation port range
.It Fl S
Do not perform domain name resolution.
If a name cannot be resolved without DNS, an error will be reported.
-.It Fl T Ar command Op Ar address ...
+.It Fl t Ar table Fl T Ar command Op Ar address ...
Specify the
.Ar command
-(may be abbreviated) to apply to the table.
+(may be abbreviated) to apply to
+.Ar table .
Commands include:
.Pp
-.Bl -tag -width xxxxxxxxxxxx -compact
-.It Fl T Cm kill
-Kill a table.
-.It Fl T Cm flush
-Flush all addresses of a table.
+.Bl -tag -width "-T expire number" -compact
.It Fl T Cm add
-Add one or more addresses in a table.
+Add one or more addresses to a table.
Automatically create a persistent table if it does not exist.
.It Fl T Cm delete
Delete one or more addresses from a table.
@@ -586,6 +584,10 @@ seconds ago.
For entries which have never had their statistics cleared,
.Ar number
refers to the time they were added to the table.
+.It Fl T Cm flush
+Flush all addresses in a table.
+.It Fl T Cm kill
+Kill a table.
.It Fl T Cm replace
Replace the addresses of the table.
Automatically create a persistent table if it does not exist.
@@ -765,8 +767,6 @@ tables of the same name from anchors attached below it.
.It C
This flag is set when per-address counters are enabled on the table.
.El
-.It Fl t Ar table
-Specify the name of the table.
.It Fl v
Produce more verbose output.
A second use of
diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c
index 36bdd9705830..2c12387ee388 100644
--- a/sbin/pfctl/pfctl.c
+++ b/sbin/pfctl/pfctl.c
@@ -137,6 +137,7 @@ int pfctl_recurse(int, int, const char *,
int pfctl_call_clearrules(int, int, struct pfr_anchoritem *);
int pfctl_call_cleartables(int, int, struct pfr_anchoritem *);
int pfctl_call_clearanchors(int, int, struct pfr_anchoritem *);
+int pfctl_call_showtables(int, int, struct pfr_anchoritem *);
static struct pfctl_anchor_global pf_anchors;
struct pfctl_anchor pf_main_anchor;
@@ -700,7 +701,7 @@ pfctl_kill_src_nodes(int dev, int opts)
dests++;
- copy_satopfaddr(&psnk.psnk_src.addr.v.a.addr,
+ copy_satopfaddr(&psnk.psnk_dst.addr.v.a.addr,
resp[1]->ai_addr);
if (ioctl(dev, DIOCKILLSRCNODES, &psnk))
err(1, "DIOCKILLSRCNODES");
@@ -789,7 +790,7 @@ pfctl_net_kill_states(int dev, const char *iface, int opts)
dests++;
- copy_satopfaddr(&kill.src.addr.v.a.addr,
+ copy_satopfaddr(&kill.dst.addr.v.a.addr,
resp[1]->ai_addr);
if ((ret = pfctl_kill_states_h(pfh, &kill, &newkilled)) != 0)
@@ -3057,6 +3058,13 @@ pfctl_call_clearanchors(int dev, int opts, struct pfr_anchoritem *pfra)
}
int
+pfctl_call_showtables(int dev, int opts, struct pfr_anchoritem *pfra)
+{
+ pfctl_show_tables(pfra->pfra_anchorname, opts);
+ return (0);
+}
+
+int
pfctl_recurse(int dev, int opts, const char *anchorname,
int(*walkf)(int, int, struct pfr_anchoritem *))
{
@@ -3070,11 +3078,13 @@ pfctl_recurse(int dev, int opts, const char *anchorname,
* so that failures on one anchor do not prevent clearing others.
*/
opts |= PF_OPT_IGNFAIL;
- printf("Removing:\n");
+ if ((opts & PF_OPT_CALLSHOW) == 0)
+ printf("Removing:\n");
SLIST_FOREACH_SAFE(pfra, anchors, pfra_sle, pfra_save) {
- printf(" %s\n",
- (*pfra->pfra_anchorname == '\0') ? "/" :
- pfra->pfra_anchorname);
+ if ((opts & PF_OPT_CALLSHOW) == 0)
+ printf(" %s\n",
+ (*pfra->pfra_anchorname == '\0') ? "/" :
+ pfra->pfra_anchorname);
rv |= walkf(dev, opts, pfra);
SLIST_REMOVE(anchors, pfra, pfr_anchoritem, pfra_sle);
free(pfra->pfra_anchorname);
@@ -3477,7 +3487,12 @@ main(int argc, char *argv[])
pfctl_show_fingerprints(opts);
break;
case 'T':
- pfctl_show_tables(anchorname, opts);
+ if (opts & PF_OPT_RECURSE) {
+ opts |= PF_OPT_CALLSHOW;
+ pfctl_recurse(dev, opts, anchorname,
+ pfctl_call_showtables);
+ } else
+ pfctl_show_tables(anchorname, opts);
break;
case 'o':
pfctl_load_fingerprints(dev, opts);
diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c
index 18b78a150c28..ce58e0636022 100644
--- a/sbin/pfctl/pfctl_parser.c
+++ b/sbin/pfctl/pfctl_parser.c
@@ -242,7 +242,7 @@ copy_satopfaddr(struct pf_addr *pfa, struct sockaddr *sa)
const struct icmptypeent *
geticmptypebynumber(u_int8_t type, sa_family_t af)
{
- unsigned int i;
+ size_t i;
if (af != AF_INET6) {
for (i=0; i < nitems(icmp_type); i++) {
@@ -261,7 +261,7 @@ geticmptypebynumber(u_int8_t type, sa_family_t af)
const struct icmptypeent *
geticmptypebyname(char *w, sa_family_t af)
{
- unsigned int i;
+ size_t i;
if (af != AF_INET6) {
for (i=0; i < nitems(icmp_type); i++) {
@@ -280,7 +280,7 @@ geticmptypebyname(char *w, sa_family_t af)
const struct icmpcodeent *
geticmpcodebynumber(u_int8_t type, u_int8_t code, sa_family_t af)
{
- unsigned int i;
+ size_t i;
if (af != AF_INET6) {
for (i=0; i < nitems(icmp_code); i++) {
@@ -301,7 +301,7 @@ geticmpcodebynumber(u_int8_t type, u_int8_t code, sa_family_t af)
const struct icmpcodeent *
geticmpcodebyname(u_long type, char *w, sa_family_t af)
{
- unsigned int i;
+ size_t i;
if (af != AF_INET6) {
for (i=0; i < nitems(icmp_code); i++) {
@@ -508,6 +508,8 @@ print_pool(struct pfctl_pool *pool, u_int16_t p1, u_int16_t p2, int id)
if (pool->mape.offset > 0)
printf(" map-e-portset %u/%u/%u",
pool->mape.offset, pool->mape.psidlen, pool->mape.psid);
+ if (pool->opts & PF_POOL_IPV6NH)
+ printf(" prefer-ipv6-nexthop");
}
void
@@ -1438,7 +1440,7 @@ ifa_add_groups_to_map(char *ifa_name)
ENTRY item;
ENTRY *ret_item;
int *answer;
-
+
item.key = ifg->ifgrq_group;
if (hsearch_r(item, FIND, &ret_item, &isgroup_map) == 0) {
struct ifgroupreq ifgr2;
@@ -1580,7 +1582,7 @@ is_a_group(char *name)
{
ENTRY item;
ENTRY *ret_item;
-
+
item.key = name;
if (hsearch_r(item, FIND, &ret_item, &isgroup_map) == 0)
return (0);
diff --git a/sbin/pfctl/pfctl_parser.h b/sbin/pfctl/pfctl_parser.h
index 721950967661..58d3abc36691 100644
--- a/sbin/pfctl/pfctl_parser.h
+++ b/sbin/pfctl/pfctl_parser.h
@@ -56,6 +56,7 @@
#define PF_OPT_KILLMATCH 0x08000
#define PF_OPT_NODNS 0x10000
#define PF_OPT_IGNFAIL 0x20000
+#define PF_OPT_CALLSHOW 0x40000
#define PF_NAT_PROXY_PORT_LOW 50001
#define PF_NAT_PROXY_PORT_HIGH 65535
diff --git a/sbin/pfctl/pfctl_radix.c b/sbin/pfctl/pfctl_radix.c
index 0fe9ca8813bb..398c5e998330 100644
--- a/sbin/pfctl/pfctl_radix.c
+++ b/sbin/pfctl/pfctl_radix.c
@@ -122,6 +122,9 @@ pfr_add_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
{
int ret;
+ if (*nadd)
+ *nadd = 0;
+
ret = pfctl_table_add_addrs_h(pfh, tbl, addr, size, nadd, flags);
if (ret) {
errno = ret;
diff --git a/sbin/pfctl/pfctl_table.c b/sbin/pfctl/pfctl_table.c
index f583f5ef8e79..0845f765a063 100644
--- a/sbin/pfctl/pfctl_table.c
+++ b/sbin/pfctl/pfctl_table.c
@@ -417,21 +417,21 @@ print_table(const struct pfr_table *ta, int verbose, int debug)
{
if (!debug && !(ta->pfrt_flags & PFR_TFLAG_ACTIVE))
return;
- if (verbose) {
- printf("%c%c%c%c%c%c%c\t%s",
+ if (verbose)
+ printf("%c%c%c%c%c%c%c\t",
(ta->pfrt_flags & PFR_TFLAG_CONST) ? 'c' : '-',
(ta->pfrt_flags & PFR_TFLAG_PERSIST) ? 'p' : '-',
(ta->pfrt_flags & PFR_TFLAG_ACTIVE) ? 'a' : '-',
(ta->pfrt_flags & PFR_TFLAG_INACTIVE) ? 'i' : '-',
(ta->pfrt_flags & PFR_TFLAG_REFERENCED) ? 'r' : '-',
(ta->pfrt_flags & PFR_TFLAG_REFDANCHOR) ? 'h' : '-',
- (ta->pfrt_flags & PFR_TFLAG_COUNTERS) ? 'C' : '-',
- ta->pfrt_name);
- if (ta->pfrt_anchor[0])
- printf("\t%s", ta->pfrt_anchor);
- puts("");
- } else
- puts(ta->pfrt_name);
+ (ta->pfrt_flags & PFR_TFLAG_COUNTERS) ? 'C' : '-');
+
+ printf("%s", ta->pfrt_name);
+ if (ta->pfrt_anchor[0] != '\0')
+ printf("@%s", ta->pfrt_anchor);
+
+ printf("\n");
}
int
diff --git a/sbin/pfctl/tests/files/pf1073.in b/sbin/pfctl/tests/files/pf1073.in
new file mode 100644
index 000000000000..477995893ac3
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1073.in
@@ -0,0 +1 @@
+pass in on vtnet0 route-to ( vtnet1 2001:db8::1 ) prefer-ipv6-nexthop inet
diff --git a/sbin/pfctl/tests/files/pf1073.ok b/sbin/pfctl/tests/files/pf1073.ok
new file mode 100644
index 000000000000..f34867508c75
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1073.ok
@@ -0,0 +1 @@
+pass in on vtnet0 route-to (vtnet1 2001:db8::1) prefer-ipv6-nexthop inet all flags S/SA keep state
diff --git a/sbin/pfctl/tests/files/pf1074.fail b/sbin/pfctl/tests/files/pf1074.fail
new file mode 100644
index 000000000000..afe8ee3c458f
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1074.fail
@@ -0,0 +1 @@
+no routing address with matching address family found.
diff --git a/sbin/pfctl/tests/files/pf1074.in b/sbin/pfctl/tests/files/pf1074.in
new file mode 100644
index 000000000000..5d285bc5d6e8
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1074.in
@@ -0,0 +1 @@
+pass in on vtnet0 route-to ( vtnet1 2001:db8::1 ) inet
diff --git a/sbin/pfctl/tests/pfctl_test_list.inc b/sbin/pfctl/tests/pfctl_test_list.inc
index 3a68cc06ec74..8bfccddf50e5 100644
--- a/sbin/pfctl/tests/pfctl_test_list.inc
+++ b/sbin/pfctl/tests/pfctl_test_list.inc
@@ -181,3 +181,5 @@ PFCTL_TEST(1069, "max-pkt-size")
PFCTL_TEST_FAIL(1070, "include line number")
PFCTL_TEST(1071, "mask length on (lo0)")
PFCTL_TEST_FAIL(1072, "Invalid port range")
+PFCTL_TEST(1073, "Filter AF different than route-to AF, with prefer-ipv6-nexthop")
+PFCTL_TEST_FAIL(1074, "Filter AF different than route-to AF, without prefer-ipv6-nexthop")
diff --git a/sbin/recoverdisk/recoverdisk.1 b/sbin/recoverdisk/recoverdisk.1
index 9f1deb4c0c23..90849755ea0c 100644
--- a/sbin/recoverdisk/recoverdisk.1
+++ b/sbin/recoverdisk/recoverdisk.1
@@ -31,6 +31,7 @@
.Sh SYNOPSIS
.Nm
.Op Fl b Ar bigsize
+.Op Fl i Ar interval
.Op Fl r Ar readlist
.Op Fl s Ar interval
.Op Fl u Ar pattern
@@ -109,6 +110,11 @@ reports for character and block devices or
if
.Ar source
is a regular file.
+.It Fl i Ar pause
+.Xr sleep 3
+this long between reads. This reduces the load on the
+.Ar source
+device and the system in general.
.It Fl p Ar pause
.Xr sleep 3
this long whenever a read fails. This makes the
diff --git a/sbin/recoverdisk/recoverdisk.c b/sbin/recoverdisk/recoverdisk.c
index f13a1f211863..5971f78738ac 100644
--- a/sbin/recoverdisk/recoverdisk.c
+++ b/sbin/recoverdisk/recoverdisk.c
@@ -28,6 +28,11 @@
#include <time.h>
#include <unistd.h>
+/*
+ * This is a compromise between speed and wasted effort
+ */
+#define COMPROMISE_SIZE (128<<10)
+
struct lump {
uint64_t start;
uint64_t len;
@@ -51,6 +56,7 @@ static uint64_t medium_read;
static uint64_t small_read;
static uint64_t total_size;
static uint64_t done_size;
+static uint64_t wasted_size;
static char *input;
static char *write_worklist_file = NULL;
static char *read_worklist_file = NULL;
@@ -61,6 +67,7 @@ static FILE *log_file = NULL;
static char *work_buf;
static char *pattern_buf;
static double error_pause;
+static double interval;
static unsigned nlumps;
static double n_reads, n_good_reads;
@@ -418,7 +425,8 @@ fill_buf(char *buf, int64_t len, const char *pattern)
static void
usage(void)
{
- fprintf(stderr, "usage: recoverdisk [-b big_read] [-r readlist] "
+ fprintf(stderr, "usage: recoverdisk "
+ "[-b big_read] [-i interval ] [-r readlist] "
"[-s interval] [-w writelist] source [destination]\n");
/* XXX update */
exit(1);
@@ -486,6 +494,7 @@ attempt_one_lump(time_t t_now)
fflush(log_file);
}
} else {
+ wasted_size += sz;
printf("%14ju %7ju read error %d: (%s)",
(uintmax_t)lp->start,
(uintmax_t)sz, error, strerror(error));
@@ -557,8 +566,6 @@ determine_read_sizes(void)
u_int sectorsize;
off_t stripesize;
- determine_total_size();
-
#ifdef DIOCGSECTORSIZE
if (small_read == 0) {
error = ioctl(read_fd, DIOCGSECTORSIZE, &sectorsize);
@@ -572,8 +579,8 @@ determine_read_sizes(void)
#endif
if (small_read == 0) {
- printf("Assuming 512 for small_read\n");
small_read = 512;
+ printf("# Defaulting small_read to %ju\n", (uintmax_t)small_read);
}
if (medium_read && (medium_read % small_read)) {
@@ -593,13 +600,13 @@ determine_read_sizes(void)
#ifdef DIOCGSTRIPESIZE
if (medium_read == 0) {
error = ioctl(read_fd, DIOCGSTRIPESIZE, &stripesize);
- if (error < 0 || stripesize < 0) {
+ if (error < 0 || stripesize <= 0) {
// nope
} else if ((uint64_t)stripesize < small_read) {
// nope
} else if (stripesize % small_read) {
// nope
- } else if (0 < stripesize && stripesize < (128<<10)) {
+ } else if (stripesize <= COMPROMISE_SIZE) {
medium_read = stripesize;
printf("# Got medium_read from DIOCGSTRIPESIZE: %ju\n",
(uintmax_t)medium_read
@@ -607,6 +614,7 @@ determine_read_sizes(void)
}
}
#endif
+
#if defined(DIOCGFWSECTORS) && defined(DIOCGFWHEADS)
if (medium_read == 0) {
u_int fwsectors = 0, fwheads = 0;
@@ -616,10 +624,16 @@ determine_read_sizes(void)
error = ioctl(read_fd, DIOCGFWHEADS, &fwheads);
if (error)
fwheads = 0;
- if (fwsectors && fwheads) {
+ if (fwsectors * fwheads * small_read <= COMPROMISE_SIZE) {
medium_read = fwsectors * fwheads * small_read;
printf(
- "# Got medium_read from DIOCGFW{SECTORS,HEADS}: %ju\n",
+ "# Got medium_read from DIOCGFW{SECTORS*HEADS}: %ju\n",
+ (uintmax_t)medium_read
+ );
+ } else if (fwsectors * small_read <= COMPROMISE_SIZE) {
+ medium_read = fwsectors * small_read;
+ printf(
+ "# Got medium_read from DIOCGFWSECTORS: %ju\n",
(uintmax_t)medium_read
);
}
@@ -627,10 +641,11 @@ determine_read_sizes(void)
#endif
if (big_read == 0 && medium_read != 0) {
- if (medium_read > (64<<10)) {
+ if (medium_read * 2 > COMPROMISE_SIZE) {
big_read = medium_read;
+ medium_read = 0;
} else {
- big_read = 128 << 10;
+ big_read = COMPROMISE_SIZE;
big_read -= big_read % medium_read;
}
printf("# Got big_read from medium_read: %ju\n",
@@ -639,12 +654,16 @@ determine_read_sizes(void)
}
if (big_read == 0) {
- big_read = 128 << 10;
+ big_read = COMPROMISE_SIZE;
+ big_read -= big_read % small_read;
printf("# Defaulting big_read to %ju\n",
(uintmax_t)big_read
);
}
+ if (medium_read >= big_read)
+ medium_read = 0;
+
if (medium_read == 0) {
/*
* We do not want to go directly to single sectors, but
@@ -662,12 +681,20 @@ determine_read_sizes(void)
(uintmax_t)medium_read
);
}
- fprintf(stderr,
- "# Bigsize = %ju, medium_read = %ju, small_read = %ju\n",
+ printf("# Bigsize = %ju, medium_read = %ju, small_read = %ju\n",
(uintmax_t)big_read, (uintmax_t)medium_read, (uintmax_t)small_read);
-}
+ assert(0 < small_read);
+
+ assert(0 < medium_read);
+ assert(medium_read >= small_read);
+ assert(medium_read <= big_read);
+ assert(medium_read % small_read == 0);
+ assert(0 < big_read);
+ assert(big_read >= medium_read);
+ assert(big_read % small_read == 0);
+}
/**********************************************************************/
@@ -687,15 +714,14 @@ monitor_read_sizes(uint64_t failed_size)
);
big_read = medium_read;
medium_read = small_read;
+ wasted_size = 0;
return;
}
- if (failed_size > small_read) {
- if (n_reads < n_good_reads + 100)
- return;
+ if (big_read > small_read && wasted_size / small_read > 200) {
fprintf(
stderr,
- "Too many failures."
+ "Too much wasted effort."
" (%.0f bad of %.0f)"
" Shifting to small_reads.\n",
n_reads - n_good_reads, n_reads
@@ -719,11 +745,14 @@ main(int argc, char * const argv[])
setbuf(stdout, NULL);
setbuf(stderr, NULL);
- while ((ch = getopt(argc, argv, "b:l:p:m:r:w:s:t:u:v")) != -1) {
+ while ((ch = getopt(argc, argv, "b:i:l:p:m:r:w:s:t:u:v")) != -1) {
switch (ch) {
case 'b':
big_read = strtoul(optarg, NULL, 0);
break;
+ case 'i':
+ interval = strtod(optarg, NULL);
+ break;
case 'l':
log_file = fopen(optarg, "a");
if (log_file == NULL) {
@@ -774,6 +803,8 @@ main(int argc, char * const argv[])
if (read_fd < 0)
err(1, "Cannot open read descriptor %s", argv[0]);
+ determine_total_size();
+
determine_read_sizes();
work_buf = malloc(big_read);
@@ -816,6 +847,9 @@ main(int argc, char * const argv[])
t_save = t_first;
unsaved = 0;
while (!aborting) {
+ if (interval > 0) {
+ usleep((unsigned long)(1e6 * interval));
+ }
t_now = time(NULL);
sz = attempt_one_lump(t_now);
error = errno;
diff --git a/sbin/veriexec/veriexec.8 b/sbin/veriexec/veriexec.8
index 8e99f1d61faf..8352dd8e5e49 100644
--- a/sbin/veriexec/veriexec.8
+++ b/sbin/veriexec/veriexec.8
@@ -195,7 +195,7 @@ and be strict about enforcing certificate validity:
.Ed
.Nm
-will look for a detatched signature that it recognizes, such as
+will look for a detached signature that it recognizes, such as
.Pa manifest.asc
(OpenPGP) or
.Pa manifest.*sig