From nobody Tue Dec 24 14:26:11 2024 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4YHcdJ0kjsz5hFsk; Tue, 24 Dec 2024 14:26:12 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R11" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4YHcdJ06Q1z3xwP; Tue, 24 Dec 2024 14:26:12 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1735050372; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=5TsBzK1vwQ11eTzViuODoCmawl/kDXNhGqo/ywhYlRI=; b=LEaVKGB7Yv9FAKR9oViSbwODHbn8vj5HeWLHPok6o9SyyrLDpM7qAy7zJNletThJiU8ZxE gzjLLVobJNLbeNjihBhUknZ/twg4Is6xzgLt2HKtQ9eV+G+H+B06iGIoPPvxod1YBn5+vJ Zrnv8kAV+HiSVxsZLojNfIPlgJx/9bhjcVOHgxdbfd1542RKlqSPita04gVFesqq/7Tn+a /F/C46WNMAUFxrcJjOe02C4dR9v3Guzp5BvIcT/mhpZov7DvGPYE/1wDbv6Njc8KbEeK0i fhKm5v9gqs0yngwJLaWZ9EKAHOtuHrkO3jpkA2W18G5DNNQolY76NgoHKX1+Ag== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1735050372; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=5TsBzK1vwQ11eTzViuODoCmawl/kDXNhGqo/ywhYlRI=; b=n17qW3X1rH2SkSnBQz7oSK+tDnbJZ/XUeD3rOdLtek9LuQDc1mgXo2/DnV0jS47un0cGCQ hPNXUzw+MMSKWjtJdJcI1ChKJA+mlokMzYktF3bBwVgFjm8hC8lc103gXTSnfzTg/ozU9Y 63mvRkvOAqRJDm8InJ9RNZYJ2gLLKccfVJPT9c0rWMhTcRhB+1+RpYqcEFsnA5ehSjuIPp Jb4mGQ3eSeSYtsJdLiWk73PMNl/d1wSQcBAMTinjJOoMIKmnlGg4+ZDwAd37owQxIEPudh mDvSufzEoQNw2i+ixnVY5UzD+mfWKZT/T9NilZpdDiPwa/lbxYtsO8yAti/qGg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1735050372; a=rsa-sha256; cv=none; b=v4f8jjdCuNGcbWRDlTrACc8KzstF60tDXH9TWo6cRguJ8SSVi+OVBgvCpkPEBwjrir2SsJ IqkrPsCDqo33sJD0vMhIxiLcyUNgQK0cn9rz8WEinMjtm6OdDs+CsT0+GUoXYJ6iRKoyZN koN0bAkOXj8qMcsurC6dEQ0l56sm66uIHbdQUcnHHkrwLyD4n6SF8NU1xhslrxzIgkcd8S cNkSp0+G3My7/1bqNOQ6FkvPvmm5CAjcUPoG4i7jSEdskj1r/2isHHUWaQF3fybCUT+yy3 HjI+pB97CyEeP+a4ZB2qgxHT/q4aPCX0NVUKKaGJg5l1k/gMB3thQBatUb97XQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4YHcdH6qmmzj8b; Tue, 24 Dec 2024 14:26:11 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 4BOEQBWR053964; Tue, 24 Dec 2024 14:26:11 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 4BOEQBWq053961; Tue, 24 Dec 2024 14:26:11 GMT (envelope-from git) Date: Tue, 24 Dec 2024 14:26:11 GMT Message-Id: <202412241426.4BOEQBWq053961@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Kristof Provost Subject: git: 3fa5d13c5be0 - stable/13 - pfctl: add -T `reset` to touch pfras_tzero only for non-zero entries List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kp X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: 3fa5d13c5be01da5796e0f3617d6da277cc16432 Auto-Submitted: auto-generated The branch stable/13 has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=3fa5d13c5be01da5796e0f3617d6da277cc16432 commit 3fa5d13c5be01da5796e0f3617d6da277cc16432 Author: Leonid Evdokimov AuthorDate: 2024-12-06 12:08:54 +0000 Commit: Kristof Provost CommitDate: 2024-12-24 10:16:50 +0000 pfctl: add -T `reset` to touch pfras_tzero only for non-zero entries This will make it easier for scripts to detect idle hosts in tables. PR: 282984 Reviewed by: kp MFC after: 2 weeks (cherry picked from commit 5b59b0c61e29f684a019afdd2848ffe2d5604e0c) --- sbin/pfctl/pfctl.8 | 7 +++- sbin/pfctl/pfctl.c | 2 +- sbin/pfctl/pfctl_radix.c | 2 +- sbin/pfctl/pfctl_table.c | 44 ++++++++++++++++++++++++ tests/sys/netpfil/pf/table.sh | 80 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 132 insertions(+), 3 deletions(-) diff --git a/sbin/pfctl/pfctl.8 b/sbin/pfctl/pfctl.8 index c1b570f225b1..642ca844023f 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 November 20, 2024 +.Dd November 25, 2024 .Dt PFCTL 8 .Os .Sh NAME @@ -495,6 +495,11 @@ Show the content (addresses) of a table. Test if the given addresses match a table. .It Fl T Cm zero Op Ar address ... Clear all the statistics of a table, or only for specified addresses. +.It Fl T Cm reset +Clear statistics only for addresses with non-zero statistics. Addresses +with counter values at zero and their +.Dq Cleared +timestamp are left untouched. .It Fl T Cm load Load only the table definitions from .Xr pf.conf 5 . diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c index 1cdcd1d0b912..8399051048b8 100644 --- a/sbin/pfctl/pfctl.c +++ b/sbin/pfctl/pfctl.c @@ -227,7 +227,7 @@ static const char * const showopt_list[] = { static const char * const tblcmdopt_list[] = { "kill", "flush", "add", "delete", "load", "replace", "show", - "test", "zero", "expire", NULL + "test", "zero", "expire", "reset", NULL }; static const char * const debugopt_list[] = { diff --git a/sbin/pfctl/pfctl_radix.c b/sbin/pfctl/pfctl_radix.c index 7d8c146c1dda..aa27652db2ec 100644 --- a/sbin/pfctl/pfctl_radix.c +++ b/sbin/pfctl/pfctl_radix.c @@ -293,7 +293,7 @@ pfr_clr_astats(struct pfr_table *tbl, struct pfr_addr *addr, int size, { struct pfioc_table io; - if (size < 0 || (size && !tbl) || addr == NULL) { + if (size < 0 || !tbl || (size && !addr)) { errno = EINVAL; return (-1); } diff --git a/sbin/pfctl/pfctl_table.c b/sbin/pfctl/pfctl_table.c index cb04b2b30bac..d645846c7fd0 100644 --- a/sbin/pfctl/pfctl_table.c +++ b/sbin/pfctl/pfctl_table.c @@ -61,6 +61,7 @@ static void print_table(struct pfr_table *, int, int); static void print_tstats(struct pfr_tstats *, int); static int load_addr(struct pfr_buffer *, int, char *[], char *, int); static void print_addrx(struct pfr_addr *, struct pfr_addr *, int); +static int nonzero_astats(struct pfr_astats *); static void print_astats(struct pfr_astats *, int); static void radix_perror(void); static void xprintf(int, const char *, ...); @@ -294,6 +295,36 @@ pfctl_table(int argc, char *argv[], char *tname, const char *command, if ((opts & PF_OPT_VERBOSE2) || a->pfra_fback) print_addrx(a, NULL, opts & PF_OPT_USEDNS); + } else if (!strcmp(command, "reset")) { + struct pfr_astats *as; + + b.pfrb_type = PFRB_ASTATS; + b2.pfrb_type = PFRB_ADDRS; + if (argc || file != NULL) + usage(); + do { + pfr_buf_grow(&b, b.pfrb_size); + b.pfrb_size = b.pfrb_msize; + RVTEST(pfr_get_astats(&table, b.pfrb_caddr, + &b.pfrb_size, flags)); + } while (b.pfrb_size > b.pfrb_msize); + PFRB_FOREACH(as, &b) { + as->pfras_a.pfra_fback = 0; + if (nonzero_astats(as)) + if (pfr_buf_add(&b2, &as->pfras_a)) + err(1, "duplicate buffer"); + } + + if (opts & PF_OPT_VERBOSE) + flags |= PFR_FLAG_FEEDBACK; + RVTEST(pfr_clr_astats(&table, b2.pfrb_caddr, b2.pfrb_size, + &nzero, flags)); + xprintf(opts, "%d/%d stats cleared", nzero, b.pfrb_size); + if (opts & PF_OPT_VERBOSE) + PFRB_FOREACH(a, &b2) + if ((opts & PF_OPT_VERBOSE2) || a->pfra_fback) + print_addrx(a, NULL, + opts & PF_OPT_USEDNS); } else if (!strcmp(command, "show")) { b.pfrb_type = (opts & PF_OPT_VERBOSE) ? PFRB_ASTATS : PFRB_ADDRS; @@ -485,6 +516,19 @@ print_addrx(struct pfr_addr *ad, struct pfr_addr *rad, int dns) printf("\n"); } +int +nonzero_astats(struct pfr_astats *as) +{ + uint64_t s = 0; + + for (int dir = 0; dir < PFR_DIR_MAX; dir++) + for (int op = 0; op < PFR_OP_ADDR_MAX; op++) + s |= as->pfras_packets[dir][op] | + as->pfras_bytes[dir][op]; + + return (!!s); +} + void print_astats(struct pfr_astats *as, int dns) { diff --git a/tests/sys/netpfil/pf/table.sh b/tests/sys/netpfil/pf/table.sh index 9e0990941466..b650884c7c30 100644 --- a/tests/sys/netpfil/pf/table.sh +++ b/tests/sys/netpfil/pf/table.sh @@ -165,6 +165,85 @@ zero_one_cleanup() pft_cleanup } +atf_test_case "reset_nonzero" "cleanup" +reset_nonzero_head() +{ + atf_set descr 'Test zeroing an address with non-zero counters' + atf_set require.user root +} + +reset_nonzero_body() +{ + epair_send=$(vnet_mkepair) + ifconfig ${epair_send}a 192.0.2.1/24 up + ifconfig ${epair_send}a inet alias 192.0.2.3/24 + + vnet_mkjail alcatraz ${epair_send}b + jexec alcatraz ifconfig ${epair_send}b 192.0.2.2/24 up + jexec alcatraz pfctl -e + + pft_set_rules alcatraz \ + "table counters { 192.0.2.1, 192.0.2.3 }" \ + "table counters { }" \ + "block all" \ + "pass in from to any" \ + "pass out from any to " \ + "pass on notReallyAnIf from to " \ + "set skip on lo" + + # Nonexisting table can't be reset, following `-T show`. + atf_check -o ignore \ + -s not-exit:0 \ + -e inline:"pfctl: Table does not exist.\n" \ + jexec alcatraz pfctl -t nonexistent -T reset + + atf_check -o ignore \ + -s exit:0 \ + -e inline:"0/0 stats cleared.\n" \ + jexec alcatraz pfctl -t bar -T reset + + # No-op is a valid operation. + atf_check -s exit:0 \ + -e inline:"0/2 stats cleared.\n" \ + jexec alcatraz pfctl -t foo -T reset + + atf_check -s exit:0 -o ignore ping -c 3 -S 192.0.2.3 192.0.2.2 + + atf_check -s exit:0 -e ignore \ + -o match:'In/Pass:.*'"$TABLE_STATS_ZERO_REGEXP" \ + -o match:'In/Pass:.*'"$TABLE_STATS_NONZERO_REGEXP" \ + -o match:'Out/Pass:.*'"$TABLE_STATS_ZERO_REGEXP" \ + -o match:'Out/Pass:.*'"$TABLE_STATS_NONZERO_REGEXP" \ + jexec alcatraz pfctl -t foo -vvT show + + local clrd uniq + clrd=`jexec alcatraz pfctl -t foo -vvT show | grep -c Cleared` + uniq=`jexec alcatraz pfctl -t foo -vvT show | sort -u | grep -c Cleared` + atf_check_equal "$clrd" 2 + atf_check_equal "$uniq" 1 # time they were added + + atf_check -s exit:0 -e ignore \ + -e inline:"1/2 stats cleared.\n" \ + jexec alcatraz pfctl -t foo -T reset + + clrd=`jexec alcatraz pfctl -t foo -vvT show | grep -c Cleared` + uniq=`jexec alcatraz pfctl -t foo -vvT show | sort -u | grep -c Cleared` + atf_check_equal "$clrd" 2 + atf_check_equal "$uniq" 2 # 192.0.2.3 should get new timestamp + + atf_check -s exit:0 -e ignore \ + -o not-match:'In/Pass:.*'"$TABLE_STATS_NONZERO_REGEXP" \ + -o not-match:'Out/Pass:.*'"$TABLE_STATS_NONZERO_REGEXP" \ + -o match:'In/Pass:.*'"$TABLE_STATS_ZERO_REGEXP" \ + -o match:'Out/Pass:.*'"$TABLE_STATS_ZERO_REGEXP" \ + jexec alcatraz pfctl -t foo -vvT show +} + +reset_nonzero_cleanup() +{ + pft_cleanup +} + atf_test_case "pr251414" "cleanup" pr251414_head() { @@ -381,6 +460,7 @@ atf_init_test_cases() atf_add_test_case "v4_counters" atf_add_test_case "v6_counters" atf_add_test_case "zero_one" + atf_add_test_case "reset_nonzero" atf_add_test_case "pr251414" atf_add_test_case "network" atf_add_test_case "automatic"