From ffeab76b68550c347abcd7c31c3b3dfcdea732b5 Mon Sep 17 00:00:00 2001 From: Kristof Provost Date: Fri, 26 Jan 2024 13:29:31 +0100 Subject: [PATCH 01/10] pfil: PFIL_PASS never frees the mbuf pfil hooks (i.e. firewalls) may pass, modify or free the mbuf passed to them. (E.g. when rejecting a packet, or when gathering up packets for reassembly). If the hook returns PFIL_PASS the mbuf must still be present. Assert this in pfil_mem_common() and ensure that ipfilter follows this convention. pf and ipfw already did. Similarly, if the hook returns PFIL_DROPPED or PFIL_CONSUMED the mbuf must have been freed (or now be owned by the firewall for further processing, like packet scheduling or reassembly). This allows us to remove a few extraneous NULL checks. Suggested by: tuexen Reviewed by: tuexen, zlei Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D43617 --- sys/net/if_ethersubr.c | 2 +- sys/net/pfil.c | 7 ++++++- sys/netinet/ip_input.c | 4 ---- sys/netinet6/ip6_input.c | 2 -- sys/netpfil/ipfilter/netinet/ip_fil_freebsd.c | 4 ++++ 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c index ef0b1f705260..4332f4ce864e 100644 --- a/sys/net/if_ethersubr.c +++ b/sys/net/if_ethersubr.c @@ -878,7 +878,7 @@ ether_demux(struct ifnet *ifp, struct mbuf *m) /* Do not grab PROMISC frames in case we are re-entered. */ if (PFIL_HOOKED_IN(V_link_pfil_head) && !(m->m_flags & M_PROMISC)) { i = pfil_mbuf_in(V_link_pfil_head, &m, ifp, NULL); - if (i != 0 || m == NULL) + if (i != PFIL_PASS) return; } diff --git a/sys/net/pfil.c b/sys/net/pfil.c index 3ceffcefb758..fae150839eb3 100644 --- a/sys/net/pfil.c +++ b/sys/net/pfil.c @@ -211,9 +211,14 @@ pfil_mbuf_common(pfil_chain_t *pch, struct mbuf **m, struct ifnet *ifp, CK_STAILQ_FOREACH(link, pch, link_chain) { rv = link->link_mbuf_chk(m, ifp, flags, link->link_ruleset, inp); - if (rv == PFIL_DROPPED || rv == PFIL_CONSUMED) + if (rv == PFIL_DROPPED || rv == PFIL_CONSUMED) { + MPASS(*m == NULL); break; + } else { + MPASS(*m != NULL); + } } + return (rv); } diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index e501c15cb7e8..82d7acdd0710 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -621,8 +621,6 @@ tooshort: if (pfil_mbuf_in(V_inet_pfil_head, &m, ifp, NULL) != PFIL_PASS) return; - if (m == NULL) /* consumed by filter */ - return; ip = mtod(m, struct ip *); dchg = (odst.s_addr != ip->ip_dst.s_addr); @@ -827,8 +825,6 @@ ours: if (pfil_mbuf_out(V_inet_local_pfil_head, &m, V_loif, NULL) != PFIL_PASS) return; - if (m == NULL) /* consumed by filter */ - return; ip = mtod(m, struct ip *); } diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c index 5de8f49b5483..11b92c152a1a 100644 --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -894,8 +894,6 @@ passin: if (pfil_mbuf_out(V_inet6_local_pfil_head, &m, V_loif, NULL) != PFIL_PASS) return; - if (m == NULL) /* consumed by filter */ - return; ip6 = mtod(m, struct ip6_hdr *); } diff --git a/sys/netpfil/ipfilter/netinet/ip_fil_freebsd.c b/sys/netpfil/ipfilter/netinet/ip_fil_freebsd.c index 1922880e90df..bcde0d2c7323 100644 --- a/sys/netpfil/ipfilter/netinet/ip_fil_freebsd.c +++ b/sys/netpfil/ipfilter/netinet/ip_fil_freebsd.c @@ -133,6 +133,8 @@ ipf_check_wrapper(struct mbuf **mp, struct ifnet *ifp, int flags, rv = ipf_check(&V_ipfmain, ip, ip->ip_hl << 2, ifp, !!(flags & PFIL_OUT), mp); CURVNET_RESTORE(); + if (rv == 0 && *mp == NULL) + return (PFIL_CONSUMED); return (rv == 0 ? PFIL_PASS : PFIL_DROPPED); } @@ -147,6 +149,8 @@ ipf_check_wrapper6(struct mbuf **mp, struct ifnet *ifp, int flags, rv = ipf_check(&V_ipfmain, mtod(*mp, struct ip *), sizeof(struct ip6_hdr), ifp, !!(flags & PFIL_OUT), mp); CURVNET_RESTORE(); + if (rv == 0 && *mp == NULL) + return (PFIL_CONSUMED); return (rv == 0 ? PFIL_PASS : PFIL_DROPPED); } From 31828075e456c042cabd47ff4eb127c5c19f16e0 Mon Sep 17 00:00:00 2001 From: Kristof Provost Date: Thu, 25 Jan 2024 11:16:49 +0100 Subject: [PATCH 02/10] pf: bind route-to states to their route-to interface When we route-to the state should be bound to the route-to interface, not the default route interface. However, we should only do so for outbound traffic, because inbound traffic should bind on the arriving interface, not the one we eventually transmit on. Explicitly check for this in BOUND_IFACE(). We must also extend pf_find_state(), because subsequent packets within the established state will attempt to match the original interface, not the route-to interface. Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D43589 --- sys/netpfil/pf/pf.c | 27 +++++++++++++++++--- tests/sys/netpfil/pf/route_to.sh | 43 ++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 4 deletions(-) diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index 2dc6d02d330a..36ff0eac16ad 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -412,8 +412,27 @@ VNET_DEFINE(struct pf_limit, pf_limits[PF_LIMIT_MAX]); return (PF_PASS); \ } while (0) -#define BOUND_IFACE(r, k) \ - ((r)->rule_flag & PFRULE_IFBOUND) ? (k) : V_pfi_all +static struct pfi_kkif * +BOUND_IFACE(struct pf_krule *r, struct pfi_kkif *k, struct pf_pdesc *pd) +{ + /* Floating unless otherwise specified. */ + if (! (r->rule_flag & PFRULE_IFBOUND)) + return (V_pfi_all); + + /* Don't overrule the interface for states created on incoming packets. */ + if (pd->dir == PF_IN) + return (k); + + /* No route-to, so don't overrrule. */ + if (r->rt != PF_ROUTETO) + return (k); + + if (r->rpool.cur == NULL) + return (k); + + /* Bind to the route-to interface. */ + return (r->rpool.cur->kif); +} #define STATE_INC_COUNTERS(s) \ do { \ @@ -1600,7 +1619,7 @@ pf_find_state(struct pfi_kkif *kif, struct pf_state_key_cmp *key, u_int dir) /* List is sorted, if-bound states before floating ones. */ TAILQ_FOREACH(s, &sk->states[idx], key_list[idx]) - if (s->kif == V_pfi_all || s->kif == kif) { + if (s->kif == V_pfi_all || s->kif == kif || s->orig_kif == kif) { PF_STATE_LOCK(s); PF_HASHROW_UNLOCK(kh); if (__predict_false(s->timeout >= PFTM_MAX)) { @@ -4999,7 +5018,7 @@ pf_create_state(struct pf_krule *r, struct pf_krule *nr, struct pf_krule *a, __func__, nr, sk, nk)); /* Swap sk/nk for PF_OUT. */ - if (pf_state_insert(BOUND_IFACE(r, kif), kif, + if (pf_state_insert(BOUND_IFACE(r, kif, pd), kif, (pd->dir == PF_IN) ? sk : nk, (pd->dir == PF_IN) ? nk : sk, s)) { REASON_SET(&reason, PFRES_STATEINS); diff --git a/tests/sys/netpfil/pf/route_to.sh b/tests/sys/netpfil/pf/route_to.sh index d8cfb1b22d8b..7e8310bceb30 100644 --- a/tests/sys/netpfil/pf/route_to.sh +++ b/tests/sys/netpfil/pf/route_to.sh @@ -365,6 +365,48 @@ dummynet_cleanup() pft_cleanup } +atf_test_case "ifbound" "cleanup" +ifbound_head() +{ + atf_set descr 'Test that route-to states bind the expected interface' + atf_set require.user root +} + +ifbound_body() +{ + pft_init + + j="route_to:ifbound" + + epair_one=$(vnet_mkepair) + epair_two=$(vnet_mkepair) + ifconfig ${epair_one}b up + + vnet_mkjail ${j}2 ${epair_two}b + jexec ${j}2 ifconfig ${epair_two}b inet 198.51.100.2/24 up + jexec ${j}2 ifconfig ${epair_two}b inet alias 203.0.113.1/24 + jexec ${j}2 route add default 198.51.100.1 + + vnet_mkjail $j ${epair_one}a ${epair_two}a + jexec $j ifconfig ${epair_one}a 192.0.2.1/24 up + jexec $j ifconfig ${epair_two}a 198.51.100.1/24 up + jexec $j route add default 192.0.2.2 + + jexec $j pfctl -e + pft_set_rules $j \ + "set state-policy if-bound" \ + "block" \ + "pass out route-to (${epair_two}a 198.51.100.2)" + + atf_check -s exit:0 -o ignore \ + jexec $j ping -c 3 203.0.113.1 +} + +ifbound_cleanup() +{ + pft_cleanup +} + atf_init_test_cases() { atf_add_test_case "v4" @@ -373,4 +415,5 @@ atf_init_test_cases() atf_add_test_case "multiwanlocal" atf_add_test_case "icmp_nat" atf_add_test_case "dummynet" + atf_add_test_case "ifbound" } From 5086b6ec32d5c82c3d0894eb7bd74a9b81480644 Mon Sep 17 00:00:00 2001 From: "R. Christian McDonald" Date: Fri, 26 Jan 2024 11:39:38 -0500 Subject: [PATCH 03/10] libbe: handle destroying/renaming temporary/bootonce boot environments When a temporary/bootonce boot environment is renamed, we need to also update the bootenv nvlist on-disk to reflect the new name. Additionally, when a temporary/bootonce boot environment is destroyed, we also need to clear out the on-disk state. Reviewed by: kevans Approved by: kp MFC after: 1 week Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D43591 --- lib/libbe/be.c | 25 ++++++-- lib/libbe/be_impl.h | 1 + lib/libbe/be_info.c | 7 +-- sbin/bectl/tests/bectl_test.sh | 102 +++++++++++++++++++++++++++++---- 4 files changed, 114 insertions(+), 21 deletions(-) diff --git a/lib/libbe/be.c b/lib/libbe/be.c index c74ec9b0f3dc..e61cfc9d68ae 100644 --- a/lib/libbe/be.c +++ b/lib/libbe/be.c @@ -175,6 +175,9 @@ libbe_init(const char *root) strcmp(altroot, "-") != 0) lbh->altroot_len = strlen(altroot); + (void) lzbe_get_boot_device(zpool_get_name(lbh->active_phandle), + &lbh->bootonce); + return (lbh); err: if (lbh != NULL) { @@ -199,6 +202,8 @@ libbe_close(libbe_handle_t *lbh) if (lbh->active_phandle != NULL) zpool_close(lbh->active_phandle); libzfs_fini(lbh->lzh); + + free(lbh->bootonce); free(lbh); } @@ -443,6 +448,12 @@ be_destroy_internal(libbe_handle_t *lbh, const char *name, int options, return (set_error(lbh, BE_ERR_DESTROYMNT)); } } + + /* Handle destroying bootonce */ + if (lbh->bootonce != NULL && + strcmp(path, lbh->bootonce) == 0) + (void) lzbe_set_boot_device( + zpool_get_name(lbh->active_phandle), lzbe_add, NULL); } else { /* * If we're initially destroying a snapshot, origin options do @@ -1021,11 +1032,17 @@ be_rename(libbe_handle_t *lbh, const char *old, const char *new) .nounmount = 1, }; err = zfs_rename(zfs_hdl, full_new, flags); - - zfs_close(zfs_hdl); if (err != 0) - return (set_error(lbh, BE_ERR_UNKNOWN)); - return (0); + goto error; + + /* handle renaming bootonce */ + if (lbh->bootonce != NULL && + strcmp(full_old, lbh->bootonce) == 0) + err = be_activate(lbh, new, true); + +error: + zfs_close(zfs_hdl); + return (set_error(lbh, err)); } diff --git a/lib/libbe/be_impl.h b/lib/libbe/be_impl.h index d5fd26c4f072..0327f8abaa0a 100644 --- a/lib/libbe/be_impl.h +++ b/lib/libbe/be_impl.h @@ -36,6 +36,7 @@ struct libbe_handle { char root[BE_MAXPATHLEN]; char rootfs[BE_MAXPATHLEN]; char bootfs[BE_MAXPATHLEN]; + char *bootonce; size_t altroot_len; zpool_handle_t *active_phandle; libzfs_handle_t *lzh; diff --git a/lib/libbe/be_info.c b/lib/libbe/be_info.c index 88a9b17bf421..509b56cb8cf5 100644 --- a/lib/libbe/be_info.c +++ b/lib/libbe/be_info.c @@ -181,8 +181,8 @@ prop_list_builder_cb(zfs_handle_t *zfs_hdl, void *data_p) dataset = zfs_get_name(zfs_hdl); nvlist_add_string(props, "dataset", dataset); - if (data->bootonce != NULL && - strcmp(dataset, data->bootonce) == 0) + if (data->lbh->bootonce != NULL && + strcmp(dataset, data->lbh->bootonce) == 0) nvlist_add_boolean_value(props, "bootonce", true); name = strrchr(dataset, '/') + 1; @@ -252,9 +252,6 @@ be_proplist_update(prop_data_t *data) ZFS_TYPE_FILESYSTEM)) == NULL) return (BE_ERR_ZFSOPEN); - (void) lzbe_get_boot_device(zpool_get_name(data->lbh->active_phandle), - &data->bootonce); - /* XXX TODO: some error checking here */ zfs_iter_filesystems(root_hdl, prop_list_builder_cb, data); diff --git a/sbin/bectl/tests/bectl_test.sh b/sbin/bectl/tests/bectl_test.sh index 0f167829cf46..00c71e11de09 100755 --- a/sbin/bectl/tests/bectl_test.sh +++ b/sbin/bectl/tests/bectl_test.sh @@ -93,7 +93,6 @@ bectl_cleanup() atf_test_case bectl_create cleanup bectl_create_head() { - atf_set "descr" "Check the various forms of bectl create" atf_set "require.user" root } @@ -157,7 +156,6 @@ bectl_create_cleanup() atf_test_case bectl_destroy cleanup bectl_destroy_head() { - atf_set "descr" "Check bectl destroy" atf_set "require.user" root } @@ -240,14 +238,12 @@ bectl_destroy_body() } bectl_destroy_cleanup() { - bectl_cleanup $(get_zpool_name) } atf_test_case bectl_export_import cleanup bectl_export_import_head() { - atf_set "descr" "Check bectl export and import" atf_set "require.user" root } @@ -278,14 +274,12 @@ bectl_export_import_body() } bectl_export_import_cleanup() { - bectl_cleanup $(get_zpool_name) } atf_test_case bectl_list cleanup bectl_list_head() { - atf_set "descr" "Check bectl list" atf_set "require.user" root } @@ -323,14 +317,12 @@ bectl_list_body() } bectl_list_cleanup() { - bectl_cleanup $(get_zpool_name) } atf_test_case bectl_mount cleanup bectl_mount_head() { - atf_set "descr" "Check bectl mount/unmount" atf_set "require.user" root } @@ -367,14 +359,12 @@ bectl_mount_body() } bectl_mount_cleanup() { - bectl_cleanup $(get_zpool_name) } atf_test_case bectl_rename cleanup bectl_rename_head() { - atf_set "descr" "Check bectl rename" atf_set "require.user" root } @@ -403,14 +393,12 @@ bectl_rename_body() } bectl_rename_cleanup() { - bectl_cleanup $(get_zpool_name) } atf_test_case bectl_jail cleanup bectl_jail_head() { - atf_set "descr" "Check bectl rename" atf_set "require.user" root atf_set "require.progs" jail @@ -577,6 +565,94 @@ bectl_promotion_cleanup() bectl_cleanup $(get_zpool_name) } +atf_test_case bectl_destroy_bootonce cleanup +bectl_destroy_bootonce_head() +{ + atf_set "descr" "Check bectl destroy (bootonce)" + atf_set "require.user" root +} +bectl_destroy_bootonce_body() +{ + if [ "$(atf_config_get ci false)" = "true" ] && \ + [ "$(uname -p)" = "i386" ]; then + atf_skip "https://bugs.freebsd.org/249055" + fi + + if [ "$(atf_config_get ci false)" = "true" ] && \ + [ "$(uname -p)" = "armv7" ]; then + atf_skip "https://bugs.freebsd.org/249229" + fi + + cwd=$(realpath .) + zpool=$(make_zpool_name) + disk=${cwd}/disk.img + mount=${cwd}/mnt + root=${mount}/root + + be=default2 + + bectl_create_setup ${zpool} ${disk} ${mount} + atf_check -s exit:0 -o empty bectl -r ${zpool}/ROOT create -e default ${be} + + # Create boot environment and bootonce activate it + atf_check -s exit:0 -o ignore bectl -r ${zpool}/ROOT activate -t ${be} + atf_check -s exit:0 -o inline:"zfs:${zpool}/ROOT/${be}:\n" zfsbootcfg -z ${zpool} + + # Destroy it + atf_check -s exit:0 -o ignore bectl -r ${zpool}/ROOT destroy ${be} + + # Should be empty + atf_check -s exit:0 -o empty zfsbootcfg -z ${zpool} +} +bectl_destroy_bootonce_cleanup() +{ + bectl_cleanup $(get_zpool_name) +} + +atf_test_case bectl_rename_bootonce cleanup +bectl_rename_bootonce_head() +{ + atf_set "descr" "Check bectl destroy (bootonce)" + atf_set "require.user" root +} +bectl_rename_bootonce_body() +{ + if [ "$(atf_config_get ci false)" = "true" ] && \ + [ "$(uname -p)" = "i386" ]; then + atf_skip "https://bugs.freebsd.org/249055" + fi + + if [ "$(atf_config_get ci false)" = "true" ] && \ + [ "$(uname -p)" = "armv7" ]; then + atf_skip "https://bugs.freebsd.org/249229" + fi + + cwd=$(realpath .) + zpool=$(make_zpool_name) + disk=${cwd}/disk.img + mount=${cwd}/mnt + root=${mount}/root + + be=default2 + + bectl_create_setup ${zpool} ${disk} ${mount} + atf_check -s exit:0 -o empty bectl -r ${zpool}/ROOT create -e default ${be} + + # Create boot environment and bootonce activate it + atf_check -s exit:0 -o ignore bectl -r ${zpool}/ROOT activate -t ${be} + atf_check -s exit:0 -o inline:"zfs:${zpool}/ROOT/${be}:\n" zfsbootcfg -z ${zpool} + + # Rename it + atf_check -s exit:0 -o ignore bectl -r ${zpool}/ROOT rename ${be} ${be}_renamed + + # Should be renamed + atf_check -s exit:0 -o inline:"zfs:${zpool}/ROOT/${be}_renamed:\n" zfsbootcfg -z ${zpool} +} +bectl_rename_bootonce_cleanup() +{ + bectl_cleanup $(get_zpool_name) +} + atf_init_test_cases() { atf_add_test_case bectl_create @@ -587,4 +663,6 @@ atf_init_test_cases() atf_add_test_case bectl_rename atf_add_test_case bectl_jail atf_add_test_case bectl_promotion + atf_add_test_case bectl_destroy_bootonce + atf_add_test_case bectl_rename_bootonce } From 7e77089dccd702eb767350a8bd3d20102c4fb591 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Mon, 29 Jan 2024 09:25:40 -0500 Subject: [PATCH 04/10] linuxkpi: remove invalid KASSERT from hash_add_rcu hash_add_rcu asserted that the node's prev pointer was NULL in an attempt to detect addition of a node already on a list, but the caller is not required to provide a zeroed node. Reported in https://github.com/freebsd/drm-kmod/issues/282 Reviewed by: bz, manu Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D43645 --- sys/compat/linuxkpi/common/include/linux/hashtable.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/sys/compat/linuxkpi/common/include/linux/hashtable.h b/sys/compat/linuxkpi/common/include/linux/hashtable.h index 5703d6282ad7..55755c354959 100644 --- a/sys/compat/linuxkpi/common/include/linux/hashtable.h +++ b/sys/compat/linuxkpi/common/include/linux/hashtable.h @@ -92,8 +92,6 @@ __hash_node_type_assert(struct hlist_node *node) #define hash_add_rcu(ht, node, key) do { \ struct lkpi_hash_head *__head = &(ht)[hash_min(key, HASH_BITS(ht))]; \ __hash_node_type_assert(node); \ - KASSERT(((struct lkpi_hash_entry *)(node))->entry.cle_prev == NULL, \ - ("node is already on list or was not zeroed")); \ CK_LIST_INSERT_HEAD(&__head->head, \ (struct lkpi_hash_entry *)(node), entry); \ } while (0) From 8d5353de74471038bd75a6cb39bf58f50a600642 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Mon, 29 Jan 2024 11:43:50 -0500 Subject: [PATCH 05/10] libc: Annotate a couple of local functions as such No functional change intended. MFC after: 1 week --- lib/libc/net/getservent.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/libc/net/getservent.c b/lib/libc/net/getservent.c index 51fc70658205..26f68f24cc78 100644 --- a/lib/libc/net/getservent.c +++ b/lib/libc/net/getservent.c @@ -937,7 +937,7 @@ fin: return (res); } -int +static int serv_marshal_func(char *buffer, size_t *buffer_size, void *retval, va_list ap, void *cache_mdata) { @@ -1038,7 +1038,7 @@ serv_marshal_func(char *buffer, size_t *buffer_size, void *retval, va_list ap, return (NS_SUCCESS); } -int +static int serv_unmarshal_func(char *buffer, size_t buffer_size, void *retval, va_list ap, void *cache_mdata) { From ee14a9725d73150e89367550206803fe36ae3089 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Mon, 29 Jan 2024 18:26:48 +0100 Subject: [PATCH 06/10] Merge commit 4a39d0890894 from llvm-project (by Mark Johnston): [libc++] Fix filesystem::remove_all() on FreeBSD (#79540) remove_all_impl() opens the target path with O_NOFOLLOW, which fails if the target is a symbolic link. On FreeBSD, rather than returning ELOOP, openat() returns EMLINK. This is unlikely to change for compatibility reasons, see https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=214633 . Thus, check for EMLINK as well. Reported by: markj PR: 276632 MFC after: 3 days --- contrib/llvm-project/libcxx/src/filesystem/operations.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/contrib/llvm-project/libcxx/src/filesystem/operations.cpp b/contrib/llvm-project/libcxx/src/filesystem/operations.cpp index 63a119aa983e..1877bcd79f4d 100644 --- a/contrib/llvm-project/libcxx/src/filesystem/operations.cpp +++ b/contrib/llvm-project/libcxx/src/filesystem/operations.cpp @@ -823,8 +823,9 @@ uintmax_t remove_all_impl(int parent_directory, const path& p, error_code& ec) { // If opening `p` failed because it wasn't a directory, remove it as // a normal file instead. Note that `openat()` can return either ENOTDIR - // or ELOOP depending on the exact reason of the failure. - if (ec == errc::not_a_directory || ec == errc::too_many_symbolic_link_levels) { + // or ELOOP depending on the exact reason of the failure. On FreeBSD it + // may return EMLINK instead of ELOOP, contradicting POSIX. + if (ec == errc::not_a_directory || ec == errc::too_many_symbolic_link_levels || ec == errc::too_many_links) { ec.clear(); if (::unlinkat(parent_directory, p.c_str(), /* flags = */0) == -1) { ec = detail::capture_errno(); From a84e01f02b15dc1ec091feab6e532d5ba36ffbbb Mon Sep 17 00:00:00 2001 From: Lexi Winter Date: Sat, 13 Jan 2024 23:34:46 +0000 Subject: [PATCH 07/10] service(8): direct user to rc(8) for a list of valid commands MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New users may refer to service(8) to discover how to manage services, but this manpage does not explain which commands are permitted besides start/stop (for example, 'enable'). Add a paragraph that directs the reader to rc(8) to discover this. While here, add a few examples of common use-cases. Reported by: Mina Galić Pull request: https://github.com/freebsd/freebsd-src/pull/1057 --- usr.sbin/service/service.8 | 51 +++++++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 6 deletions(-) diff --git a/usr.sbin/service/service.8 b/usr.sbin/service/service.8 index ada0e6361fb8..2c5dfa3f3a66 100644 --- a/usr.sbin/service/service.8 +++ b/usr.sbin/service/service.8 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd November 9, 2021 +.Dd January 29, 2024 .Dt SERVICE 8 .Os .Sh NAME @@ -64,6 +64,13 @@ see It can also be used to list the scripts using various criteria. .Pp +The set of permissible values for +.Ar command +depends on the particular rc.d script being invoked. +For a list of standard commands which are supported by most rc.d +scripts, see +.Xr rc 8 . +.Pp The options are as follows: .Bl -tag -width F1 .It Fl E Ar var=value @@ -129,13 +136,44 @@ option is used, the corresponding variable is set accordingly. .Sh EXIT STATUS .Ex -std .Sh EXAMPLES -The following are examples of typical usage of the -.Nm -command: +These are some examples of the most common service commands. +For a full list of commands available in most rc.d scripts, see +.Xr rc 8 . +.Pp +Enable a service, then start it: +.Bd -literal -offset -indent +service sshd enable +service sshd start +.Ed +.Pp +Stop a service, then disable it: +.Bd -literal -offset -indent +service sshd stop +service sshd disable +.Ed +.Pp +Start a service which is not enabled: +.Bd -literal -offset -indent +service sshd onestart +.Ed +.Pp +Report the status of a service: .Bd -literal -offset -ident service named status -service -j dns named status +.Ed +.Pp +Restart a service running in a jail: +.Bd -literal -offset -indent +service -j dns named restart +.Ed +.Pp +Start a service with a specific environment variable set: +.Bd -literal -offset -indent service -E LC_ALL=C.UTF-8 named start +.Ed +.Pp +Report a verbose listing of all available services: +.Bd -literal -offset -indent service -rv .Ed .Pp @@ -164,7 +202,8 @@ complete -F _service service .Xr bash 1 Pq Pa ports/shells/bash , .Xr rc.conf 5 , .Xr rc 8 , -.Xr rcorder 8 +.Xr rcorder 8 , +.Xr sysrc 8 .Sh HISTORY The .Nm From f30c7d56546b9f36e42351fb385d96e37dbac1d5 Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Mon, 29 Jan 2024 18:41:24 +0100 Subject: [PATCH 08/10] TCP LRO: convert TCP header fields to host byte order earlier This is a preparation for adding dtrace hooks in a follow-up commit, which are missing in the code path, where packets are directly queued to the tcpcb. The dtrace hooks expect the fields to be in host byte order. This only applies when TCP HPTS is used. No functional change intended. Reviewed by: rscheff MFC after: 1 week Sponsored by: Netflix, Inc. Differential Revision: https://reviews.freebsd.org/D43594 --- sys/netinet/tcp_lro_hpts.c | 7 ++++--- sys/netinet/tcp_stacks/rack_bbr_common.c | 4 ---- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/sys/netinet/tcp_lro_hpts.c b/sys/netinet/tcp_lro_hpts.c index 7724e727d5ce..84944c8db1ce 100644 --- a/sys/netinet/tcp_lro_hpts.c +++ b/sys/netinet/tcp_lro_hpts.c @@ -74,15 +74,15 @@ build_ack_entry(struct tcp_ackent *ae, struct tcphdr *th, struct mbuf *m, ae->flags |= TSTMP_LRO; else if (m->m_flags & M_TSTMP) ae->flags |= TSTMP_HDWR; - ae->seq = ntohl(th->th_seq); - ae->ack = ntohl(th->th_ack); + ae->seq = th->th_seq; + ae->ack = th->th_ack; ae->flags |= tcp_get_flags(th); if (ts_ptr != NULL) { ae->ts_value = ntohl(ts_ptr[1]); ae->ts_echo = ntohl(ts_ptr[2]); ae->flags |= HAS_TSTMP; } - ae->win = ntohs(th->th_win); + ae->win = th->th_win; ae->codepoint = iptos; } @@ -310,6 +310,7 @@ do_bpf_strip_and_compress(struct tcpcb *tp, struct lro_ctrl *lc, th = tcp_lro_get_th(m); th->th_sum = 0; /* TCP checksum is valid. */ + tcp_fields_to_host(th); /* Check if ACK can be compressed */ can_compress = tcp_lro_ack_valid(m, th, &ts_ptr, &other_opts); diff --git a/sys/netinet/tcp_stacks/rack_bbr_common.c b/sys/netinet/tcp_stacks/rack_bbr_common.c index b265e8e6f20b..4a4a8af2bd78 100644 --- a/sys/netinet/tcp_stacks/rack_bbr_common.c +++ b/sys/netinet/tcp_stacks/rack_bbr_common.c @@ -415,10 +415,6 @@ skip_vnet: break; #endif } /* end switch */ - /* - * Convert TCP protocol specific fields to host format. - */ - tcp_fields_to_host(th); off = th->th_off << 2; if (off < sizeof (struct tcphdr) || off > tlen) { printf("off:%d < hdrlen:%zu || > tlen:%u -- dump\n", From a5ff900535e24e3a3cd02287d733e1d1e5e9583a Mon Sep 17 00:00:00 2001 From: Emmanuel Vadot Date: Fri, 26 Jan 2024 19:52:03 +0100 Subject: [PATCH 09/10] pkgbase: Create two new rules for creating repo This adds two new rules named create-packages-kernel-repo and create-packages-world-repo. The goal of those rules is to create the {kernel,world} packages and after that the repository. It helps a lot for developing with pkgbase by adding the dev machine repository created by those rules on top of the official pkgbase one. Differential Revision: https://reviews.freebsd.org/D43623 Reviewed by: bapt, emaste Sponsored by: Beckhoff Automation GmbH & Co. KG --- Makefile | 4 +++- Makefile.inc1 | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 2c4f7aaebca0..04d8a014b0c6 100644 --- a/Makefile +++ b/Makefile @@ -172,7 +172,9 @@ TGTS= all all-man buildenv buildenvvars buildetc buildkernel buildworld \ builddtb xdev xdev-build xdev-install \ xdev-links native-xtools native-xtools-install stageworld stagekernel \ stage-packages stage-packages-kernel stage-packages-world stage-packages-source \ - create-packages-world create-packages-kernel create-packages-source create-packages \ + create-packages-world create-packages-kernel \ + create-packages-kernel-repo create-packages-world-repo \ + create-packages-source create-packages \ update-packages packages installconfig real-packages real-update-packages \ sign-packages package-pkg print-dir test-system-compiler test-system-linker \ test-includes diff --git a/Makefile.inc1 b/Makefile.inc1 index 8a0073547ed0..1e86cda657dd 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -2078,6 +2078,10 @@ create-packages-kernel: _pkgbootstrap _repodir .PHONY SOURCE_DATE_EPOCH=${SOURCE_DATE_EPOCH} \ create-kernel-packages +create-packages-kernel-repo: .PHONY create-packages-kernel sign-packages + +create-packages-world-repo: .PHONY create-packages-world sign-packages + create-packages-source: _pkgbootstrap _repodir .PHONY ${_+_}@cd ${.CURDIR}; \ ${MAKE} -f Makefile.inc1 \ From a5afd7920d50ff23f91bdbabb1f0fd7ba028ba9e Mon Sep 17 00:00:00 2001 From: Emmanuel Vadot Date: Sat, 27 Jan 2024 13:20:49 +0100 Subject: [PATCH 10/10] pkgbase: Create a FreeBSD-dtb package Before that dtbs where included in each kernel packages which prevents us to install multiple kernels. Differential Revision: https://reviews.freebsd.org/D43632 Reviewed by: bapt Sponsored by: Beckhoff Automation GmbH & Co. KG --- Makefile.inc1 | 28 +++++++++++++++++++++++++++- release/packages/dtb.ucl | 16 ++++++++++++++++ release/scripts/mtree-to-plist.awk | 20 ++++++++++++++------ 3 files changed, 57 insertions(+), 7 deletions(-) create mode 100644 release/packages/dtb.ucl diff --git a/Makefile.inc1 b/Makefile.inc1 index 1e86cda657dd..7a9917fd8a74 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -2178,9 +2178,35 @@ _default_flavor= -default . if ${MK_DEBUG_FILES} != "no" _debug=-dbg . endif + +create-dtb-package: + @if [ -f ${KSTAGEDIR}/${DISTDIR}/dtb.plist ]; then \ + sed -e "s/%VERSION%/${PKG_VERSION}/" \ + -e "s/%PKGNAME%/dtb/" \ + -e "s/%COMMENT%/FreeBSD Devicetree Blobs/" \ + -e "s/%DESC%/FreeBSD Devicetree Blobs/" \ + -e "s/ %VCS_REVISION%/${VCS_REVISION}/" \ + -e "s/%PKG_NAME_PREFIX%/${PKG_NAME_PREFIX}/" \ + -e "s/%PKG_MAINTAINER%/${PKG_MAINTAINER}/" \ + -e "s|%PKG_WWW%|${PKG_WWW}|" \ + ${SRCDIR}/release/packages/dtb.ucl \ + > ${KSTAGEDIR}/${DISTDIR}/dtb.ucl ; \ + awk -F\" ' \ + /name/ { printf("===> Creating %s-", $$2); next } \ + /version/ {print $$2; next } ' \ + ${KSTAGEDIR}/${DISTDIR}/dtb.ucl ; \ + ${PKG_CMD} -o ABI=${PKG_ABI} -o ALLOW_BASE_SHLIBS=yes \ + -o OSVERSION="${SRCRELDATE}" \ + create -f ${PKG_FORMAT} \ + -M ${KSTAGEDIR}/${DISTDIR}/dtb.ucl \ + -p ${KSTAGEDIR}/${DISTDIR}/dtb.plist \ + -r ${KSTAGEDIR}/${DISTDIR} \ + -o ${REPODIR}/${PKG_ABI}/${PKG_OUTPUT_DIR} ; \ + fi + create-kernel-packages: .PHONY . for flavor in "" ${_debug} -create-kernel-packages: create-kernel-packages-flavor${flavor:C,^""$,${_default_flavor},} +create-kernel-packages: create-kernel-packages-flavor${flavor:C,^""$,${_default_flavor},} create-dtb-package create-kernel-packages-flavor${flavor:C,^""$,${_default_flavor},}: _pkgbootstrap .PHONY @cd ${KSTAGEDIR}/${DISTDIR} ; \ ${METALOG_SORT_CMD} ${KSTAGEDIR}/kernel.meta | \ diff --git a/release/packages/dtb.ucl b/release/packages/dtb.ucl new file mode 100644 index 000000000000..e4717b9054a2 --- /dev/null +++ b/release/packages/dtb.ucl @@ -0,0 +1,16 @@ +# +# + +name = "%PKG_NAME_PREFIX%-%PKGNAME%" +origin = "base" +version = "%VERSION%" +comment = "%COMMENT%" +categories = [ base ] +maintainer = "%PKG_MAINTAINER%" +www = "%PKG_WWW%" +prefix = "/" +licenselogic = "single" +licenses = [ BSD2CLAUSE ] +desc = <