diff options
| -rw-r--r-- | UPDATING | 3 | ||||
| -rw-r--r-- | bin/date/date.1 | 35 | ||||
| -rw-r--r-- | lib/libpfctl/libpfctl.c | 86 | ||||
| -rw-r--r-- | lib/libpfctl/libpfctl.h | 2 | ||||
| -rw-r--r-- | sbin/ipf/libipf/interror.c | 6 | ||||
| -rw-r--r-- | sbin/pfctl/pfctl_radix.c | 2 | ||||
| -rw-r--r-- | sys/dev/mmc/mmc_fdt_helpers.c | 11 | ||||
| -rw-r--r-- | sys/netpfil/ipfilter/netinet/ip_htable.c | 43 | ||||
| -rw-r--r-- | sys/netpfil/ipfilter/netinet/ip_htable.h | 2 | ||||
| -rw-r--r-- | sys/netpfil/pf/pf_nl.c | 88 | ||||
| -rw-r--r-- | sys/netpfil/pf/pf_nl.h | 2 |
11 files changed, 258 insertions, 22 deletions
@@ -27,6 +27,9 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 16.x IS SLOW: world, or to merely disable the most expensive debugging functionality at runtime, run "ln -s 'abort:false,junk:false' /etc/malloc.conf".) +20251105: + pf(4) now supports nat64 via the af-to keyword. + 20251102: Commit e5aa60d06958 changed the internal KAPI between the NFS modules. As such, they all need to be rebuilt diff --git a/bin/date/date.1 b/bin/date/date.1 index b86a660a924d..f68892bd408d 100644 --- a/bin/date/date.1 +++ b/bin/date/date.1 @@ -29,7 +29,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd September 1, 2025 +.Dd November 5, 2025 .Dt DATE 1 .Os .Sh NAME @@ -143,7 +143,8 @@ values are .Cm minutes , .Cm seconds , and -.Cm ns No Pq for nanoseconds . +.Cm ns +.Pq for nanoseconds . The date and time is formatted to the specified precision. When .Ar FMT @@ -172,7 +173,7 @@ Obsolete flag, accepted and ignored for compatibility. .It Fl R Use RFC 2822 date and time output format. This is equivalent to using -.Dq Li %a, %d %b %Y \&%T %z +.Ql %a, %d %b %Y \&%T %z as .Ar output_fmt while @@ -194,9 +195,7 @@ and can be specified in decimal, octal, or hex. Print the date and time of the last modification of .Ar filename . .It Fl u -Display or set the date in -.Tn UTC -(Coordinated Universal) time. +Display or set the date in UTC (Coordinated Universal) time. By default .Nm displays the time in the time zone described by @@ -328,7 +327,7 @@ The format string may contain any of the conversion specifications described in the .Xr strftime 3 manual page and -.Ql %N +.Ql \&%N for nanoseconds, as well as any arbitrary text. A newline .Pq Ql \en @@ -468,7 +467,7 @@ will display: .Dl "Sun Jan 4 04:15:24 GMT 1998" .Pp where it is currently -.Li "Mon Aug 4 04:15:24 BST 1997" . +.Ql "Mon Aug 4 04:15:24 BST 1997" . .Pp The command: .Pp @@ -493,29 +492,31 @@ will display the last Friday of the month: .Dl "Fri Aug 29 04:31:11 BST 1997" .Pp where it is currently -.Li "Mon Aug 4 04:31:11 BST 1997" . +.Ql "Mon Aug 4 04:31:11 BST 1997" . .Pp The command: .Pp .Dl "date 8506131627" .Pp sets the date to -.Dq Li "June 13, 1985, 4:27 PM" . +.Ql "June 13, 1985, 4:27 PM" . .Pp .Dl "date ""+%Y%m%d%H%M.%S""" .Pp may be used on one machine to print out the date suitable for setting on another. -.Qq ( Li "+%m%d%H%M%Y.%S" -for use on -.Tn Linux . ) +.Po Use +.Ql "+%m%d%H%M%Y.%S" +with GNU date on +Linux . +.Pc .Pp The command: .Pp .Dl "date 1432" .Pp sets the time to -.Li "2:32 PM" , +.Ql "2:32 PM" , without modifying the date. .Pp The command @@ -591,10 +592,10 @@ flag is compatible with .St -iso8601 . .Pp The -.Ql %N +.Ql \&%N conversion specification for nanoseconds is a non-standard extension. It is compatible with GNU date's -.Ql %N . +.Ql \&%N . .Sh HISTORY A .Nm @@ -615,6 +616,6 @@ flag was added in .Fx 12.0 . .Pp The -.Ql %N +.Ql \&%N conversion specification was added in .Fx 14.1 . diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c index e739e55033e2..e747763ae6ef 100644 --- a/lib/libpfctl/libpfctl.c +++ b/lib/libpfctl/libpfctl.c @@ -1491,7 +1491,7 @@ snl_attr_get_pf_rule_labels(struct snl_state *ss, struct nlattr *nla, bool ret; if (l->i >= PF_RULE_MAX_LABEL_COUNT) - return (E2BIG); + return (false); ret = snl_attr_copy_string(ss, nla, (void *)PF_RULE_LABEL_SIZE, l->labels[l->i]); @@ -1561,7 +1561,7 @@ snl_attr_get_pf_timeout(struct snl_state *ss, struct nlattr *nla, bool ret; if (t->i >= PFTM_MAX) - return (E2BIG); + return (false); ret = snl_attr_get_uint32(ss, nla, NULL, &t->timeouts[t->i]); if (ret) @@ -2742,6 +2742,88 @@ int pfctl_table_get_addrs(int dev, struct pfr_table *tbl, struct pfr_addr *addr, return (0); } +struct nl_addrs { + size_t max; + struct pfr_addr *addrs; + size_t count; + size_t total_count; +}; + +#define _OUT(_field) offsetof(struct pfr_addr, _field) +static const struct snl_attr_parser ap_pfr_addr[] = { + { .type = PFR_A_AF, .off = _OUT(pfra_af), .cb = snl_attr_get_uint32 }, + { .type = PFR_A_NET, .off = _OUT(pfra_net), .cb = snl_attr_get_uint8 }, + { .type = PFR_A_NOT, .off = _OUT(pfra_not), .cb = snl_attr_get_bool }, + { .type = PFR_A_ADDR, .off = _OUT(pfra_ip6addr), .cb = snl_attr_get_in6_addr }, +}; +#undef _OUT +SNL_DECLARE_ATTR_PARSER(pfr_addr_parser, ap_pfr_addr); + +static bool +snl_attr_get_pfr_addrs(struct snl_state *ss, struct nlattr *nla, + const void *arg __unused, void *target) +{ + struct nl_addrs *a = (struct nl_addrs *)target; + bool ret; + + if (a->count >= a->max) + return (false); + + ret = snl_parse_header(ss, NLA_DATA(nla), NLA_DATA_LEN(nla), + &pfr_addr_parser, &a->addrs[a->count]); + if (ret) + a->count++; + + return (ret); +} + +#define _OUT(_field) offsetof(struct nl_addrs, _field) +static struct snl_attr_parser ap_table_get_addr[] = { + { .type = PF_TA_ADDR, .off = 0, .cb = snl_attr_get_pfr_addrs }, + { .type = PF_TA_ADDR_COUNT, .off = _OUT(total_count), .cb = snl_attr_get_uint32 }, +}; +#undef _OUT +SNL_DECLARE_PARSER(table_get_addr_parser, struct genlmsghdr, snl_f_p_empty, ap_table_get_addr); +int +pfctl_table_get_addrs_h(struct pfctl_handle *h, struct pfr_table *tbl, + struct pfr_addr *addr, int *size, int flags) +{ + struct nl_addrs addrs = { 0 }; + struct snl_writer nw; + struct snl_errmsg_data e = {}; + struct nlmsghdr *hdr; + uint32_t seq_id; + int family_id; + + family_id = snl_get_genl_family(&h->ss, PFNL_FAMILY_NAME); + if (family_id == 0) + return (ENOTSUP); + + snl_init_writer(&h->ss, &nw); + hdr = snl_create_genl_msg_request(&nw, family_id, PFNL_CMD_TABLE_GET_ADDR); + + snl_add_msg_attr_table(&nw, PF_TA_TABLE, tbl); + snl_add_msg_attr_u32(&nw, PF_TA_FLAGS, flags); + + if ((hdr = snl_finalize_msg(&nw)) == NULL) + return (ENXIO); + + seq_id = hdr->nlmsg_seq; + if (! snl_send_message(&h->ss, hdr)) + return (ENXIO); + + addrs.addrs = addr; + addrs.max = *size; + while ((hdr = snl_read_reply_multi(&h->ss, seq_id, &e)) != NULL) { + if (! snl_parse_nlmsg(&h->ss, hdr, &table_get_addr_parser, &addrs)) + continue; + } + + *size = addrs.total_count; + + return (e.error); +} + int pfctl_set_statusif(struct pfctl_handle *h, const char *ifname) { diff --git a/lib/libpfctl/libpfctl.h b/lib/libpfctl/libpfctl.h index ae4b18dabe75..a5b7e1c23bd0 100644 --- a/lib/libpfctl/libpfctl.h +++ b/lib/libpfctl/libpfctl.h @@ -529,6 +529,8 @@ int pfctl_table_set_addrs_h(struct pfctl_handle *h, struct pfr_table *tbl, int pfctl_table_set_addrs(int dev, struct pfr_table *tbl, struct pfr_addr *addr, int size, int *size2, int *nadd, int *ndel, int *nchange, int flags); +int pfctl_table_get_addrs_h(struct pfctl_handle *h, struct pfr_table *tbl, struct pfr_addr *addr, + int *size, int flags); int pfctl_table_get_addrs(int dev, struct pfr_table *tbl, struct pfr_addr *addr, int *size, int flags); int pfctl_set_statusif(struct pfctl_handle *h, const char *ifname); diff --git a/sbin/ipf/libipf/interror.c b/sbin/ipf/libipf/interror.c index 981823ca6bb9..a8dc3be2d5d1 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 477 +#define IPF_NUM_ERRORS sizeof(ipf_errors) / sizeof(ipf_error_entry_t) /* * NO REUSE OF NUMBERS! @@ -25,7 +25,7 @@ static ipf_error_entry_t *find_error(int); * IF YOU WANT TO ADD AN ERROR TO THIS TABLE, _ADD_ A NEW NUMBER. * DO _NOT_ USE AN EMPTY NUMBER OR FILL IN A GAP. */ -static ipf_error_entry_t ipf_errors[IPF_NUM_ERRORS] = { +static ipf_error_entry_t ipf_errors[] = { { 1, "auth table locked/full" }, { 2, "" }, { 3, "copyinptr received bad address" }, @@ -228,6 +228,8 @@ static ipf_error_entry_t ipf_errors[IPF_NUM_ERRORS] = { { 30024, "object size incorrect for hash table" }, { 30025, "hash table size must be at least 1"}, { 30026, "cannot allocate memory for hash table context" }, + { 30027, "hash table larger than maximum allowed" }, + { 30028, "hash table multiplication overflow" }, /* -------------------------------------------------------------------------- */ { 40001, "invalid minor device number for log read" }, { 40002, "read size too small" }, diff --git a/sbin/pfctl/pfctl_radix.c b/sbin/pfctl/pfctl_radix.c index 3b7161420e33..823921953eaf 100644 --- a/sbin/pfctl/pfctl_radix.c +++ b/sbin/pfctl/pfctl_radix.c @@ -182,7 +182,7 @@ pfr_get_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int *size, { int ret; - ret = pfctl_table_get_addrs(dev, tbl, addr, size, flags); + ret = pfctl_table_get_addrs_h(pfh, tbl, addr, size, flags); if (ret) { errno = ret; return (-1); diff --git a/sys/dev/mmc/mmc_fdt_helpers.c b/sys/dev/mmc/mmc_fdt_helpers.c index aed85dab55f4..980785464a00 100644 --- a/sys/dev/mmc/mmc_fdt_helpers.c +++ b/sys/dev/mmc/mmc_fdt_helpers.c @@ -160,6 +160,17 @@ cd_setup(struct mmc_helper *helper, phandle_t node) } /* + * If the device has no card-detection, treat it as non-removable. + * This could be improved by polling for detection. + */ + if (helper->props & MMC_PROP_BROKEN_CD) { + helper->cd_disabled = true; + if (bootverbose) + device_printf(dev, "Broken card-detect\n"); + return; + } + + /* * If there is no cd-gpios property, then presumably the hardware * PRESENT_STATE register and interrupts will reflect card state * properly, and there's nothing more for us to do. Our get_present() diff --git a/sys/netpfil/ipfilter/netinet/ip_htable.c b/sys/netpfil/ipfilter/netinet/ip_htable.c index 3f765cfab947..5f5c04732d69 100644 --- a/sys/netpfil/ipfilter/netinet/ip_htable.c +++ b/sys/netpfil/ipfilter/netinet/ip_htable.c @@ -96,6 +96,8 @@ typedef struct ipf_htable_softc_s { u_long ipf_nhtnodes[LOOKUP_POOL_SZ]; iphtable_t *ipf_htables[LOOKUP_POOL_SZ]; iphtent_t *ipf_node_explist; + ipftuneable_t *ipf_htable_tune; + u_int ipf_htable_size_max; } ipf_htable_softc_t; ipf_lookup_t ipf_htable_backend = { @@ -122,6 +124,18 @@ ipf_lookup_t ipf_htable_backend = { }; +static ipftuneable_t ipf_htable_tuneables[] = { + { { (void *)offsetof(ipf_htable_softc_t, ipf_htable_size_max) }, + "htable_size_max", 1, 0x7fffffff, + stsizeof(ipf_htable_softc_t, ipf_htable_size_max), + 0, NULL, NULL }, + { { NULL }, + NULL, 0, 0, + 0, + 0, NULL, NULL } +}; + + /* ------------------------------------------------------------------------ */ /* Function: ipf_htable_soft_create */ /* Returns: void * - NULL = failure, else pointer to local context */ @@ -142,6 +156,18 @@ ipf_htable_soft_create(ipf_main_softc_t *softc) bzero((char *)softh, sizeof(*softh)); + softh->ipf_htable_tune = ipf_tune_array_copy(softh, + sizeof(ipf_htable_tuneables), + ipf_htable_tuneables); + if (softh->ipf_htable_tune == NULL) { + ipf_htable_soft_destroy(softc, softh); + return (NULL); + } + if (ipf_tune_array_link(softc, softh->ipf_htable_tune) == -1) { + ipf_htable_soft_destroy(softc, softh); + return (NULL); + } + return (softh); } @@ -160,6 +186,12 @@ ipf_htable_soft_destroy(ipf_main_softc_t *softc, void *arg) { ipf_htable_softc_t *softh = arg; + if (softh->ipf_htable_tune != NULL) { + ipf_tune_array_unlink(softc, softh->ipf_htable_tune); + KFREES(softh->ipf_htable_tune, sizeof(ipf_htable_tuneables)); + softh->ipf_htable_tune = NULL; + } + KFREE(softh); } @@ -179,6 +211,8 @@ ipf_htable_soft_init(ipf_main_softc_t *softc, void *arg) bzero((char *)softh, sizeof(*softh)); + softh->ipf_htable_size_max = IPHTABLE_MAX_SIZE; + return (0); } @@ -327,6 +361,15 @@ ipf_htable_create(ipf_main_softc_t *softc, void *arg, iplookupop_t *op) iph->iph_name[sizeof(iph->iph_name) - 1] = '\0'; } + if ((iph->iph_size == 0) || + (iph->iph_size > softh->ipf_htable_size_max)) { + IPFERROR(30027); + return (EINVAL); + } + if (iph->iph_size > ( SIZE_MAX / sizeof(*iph->iph_table))) { + IPFERROR(30028); + return (EINVAL); + } KMALLOCS(iph->iph_table, iphtent_t **, iph->iph_size * sizeof(*iph->iph_table)); if (iph->iph_table == NULL) { diff --git a/sys/netpfil/ipfilter/netinet/ip_htable.h b/sys/netpfil/ipfilter/netinet/ip_htable.h index 55c289e57ff6..3a8782ccd4b2 100644 --- a/sys/netpfil/ipfilter/netinet/ip_htable.h +++ b/sys/netpfil/ipfilter/netinet/ip_htable.h @@ -55,6 +55,8 @@ typedef struct iphtable_s { char iph_name[FR_GROUPLEN]; /* hash table number */ } iphtable_t; +#define IPHTABLE_MAX_SIZE 1024 + /* iph_type */ #define IPHASH_LOOKUP 0 #define IPHASH_GROUPMAP 1 diff --git a/sys/netpfil/pf/pf_nl.c b/sys/netpfil/pf/pf_nl.c index 21d4db1b8478..993981a9c0de 100644 --- a/sys/netpfil/pf/pf_nl.c +++ b/sys/netpfil/pf/pf_nl.c @@ -2246,6 +2246,87 @@ pf_handle_table_set_addrs(struct nlmsghdr *hdr, struct nl_pstate *npt) return (error); } +static int +nlattr_add_pfr_addr(struct nl_writer *nw, int attr, const struct pfr_addr *a) +{ + int off = nlattr_add_nested(nw, attr); + if (off == 0) + return (false); + + nlattr_add_u32(nw, PFR_A_AF, a->pfra_af); + nlattr_add_u8(nw, PFR_A_NET, a->pfra_net); + nlattr_add_bool(nw, PFR_A_NOT, a->pfra_not); + nlattr_add_in6_addr(nw, PFR_A_ADDR, &a->pfra_u._pfra_ip6addr); + + nlattr_set_len(nw, off); + + return (true); +} + +static int +pf_handle_table_get_addrs(struct nlmsghdr *hdr, struct nl_pstate *npt) +{ + struct pfioc_table attrs = { 0 }; + struct pfr_addr *pfras; + struct nl_writer *nw = npt->nw; + struct genlmsghdr *ghdr_new; + int size = 0; + int error; + + PF_RULES_RLOCK_TRACKER; + + error = nl_parse_nlmsg(hdr, &table_addr_parser, npt, &attrs); + if (error != 0) + return (error); + + PF_RULES_RLOCK(); + /* Get required size. */ + error = pfr_get_addrs(&attrs.pfrio_table, NULL, + &size, attrs.pfrio_flags | PFR_FLAG_USERIOCTL); + if (error != 0) { + PF_RULES_RUNLOCK(); + return (error); + } + pfras = mallocarray(size, sizeof(struct pfr_addr), M_PF, + M_NOWAIT | M_ZERO); + if (pfras == NULL) { + PF_RULES_RUNLOCK(); + return (ENOMEM); + } + /* Now get the addresses. */ + error = pfr_get_addrs(&attrs.pfrio_table, pfras, + &size, attrs.pfrio_flags | PFR_FLAG_USERIOCTL); + PF_RULES_RUNLOCK(); + if (error != 0) + goto out; + + for (int i = 0; i < size; i++) { + if (!nlmsg_reply(nw, hdr, sizeof(struct genlmsghdr))) { + nlmsg_abort(nw); + error = ENOMEM; + goto out; + } + ghdr_new = nlmsg_reserve_object(nw, struct genlmsghdr); + ghdr_new->cmd = PFNL_CMD_TABLE_GET_ADDR; + ghdr_new->version = 0; + ghdr_new->reserved = 0; + + if (i == 0) + nlattr_add_u32(nw, PF_TA_ADDR_COUNT, size); + + nlattr_add_pfr_addr(nw, PF_TA_ADDR, &pfras[i]); + if (!nlmsg_end(nw)) { + nlmsg_abort(nw); + error = ENOMEM; + goto out; + } + } + +out: + free(pfras, M_PF); + return (error); +} + static const struct nlhdr_parser *all_parsers[] = { &state_parser, &addrule_parser, @@ -2504,6 +2585,13 @@ static const struct genl_cmd pf_cmds[] = { .cmd_flags = GENL_CMD_CAP_DO | GENL_CMD_CAP_HASPOL, .cmd_priv = PRIV_NETINET_PF, }, + { + .cmd_num = PFNL_CMD_TABLE_GET_ADDR, + .cmd_name = "TABLE_GET_ADDRS", + .cmd_cb = pf_handle_table_get_addrs, + .cmd_flags = GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL, + .cmd_priv = PRIV_NETINET_PF, + }, }; void diff --git a/sys/netpfil/pf/pf_nl.h b/sys/netpfil/pf/pf_nl.h index d1538ab4ff5b..e1eb3e628df5 100644 --- a/sys/netpfil/pf/pf_nl.h +++ b/sys/netpfil/pf/pf_nl.h @@ -70,6 +70,7 @@ enum { PFNL_CMD_TABLE_ADD_ADDR = 32, PFNL_CMD_TABLE_DEL_ADDR = 33, PFNL_CMD_TABLE_SET_ADDR = 34, + PFNL_CMD_TABLE_GET_ADDR = 35, __PFNL_CMD_MAX, }; #define PFNL_CMD_MAX (__PFNL_CMD_MAX -1) @@ -485,6 +486,7 @@ enum pf_table_addrs_t { PF_TA_NBR_ADDED = 4, /* u32 */ PF_TA_NBR_DELETED = 5, /* u32 */ PF_TA_NBR_CHANGED = 6, /* u32 */ + PF_TA_ADDR_COUNT = 7, /* u32 */ }; #ifdef _KERNEL |
