From nobody Tue Dec 24 14:26:12 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 4YHcdK1r9qz5hFVG; Tue, 24 Dec 2024 14:26:13 +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 4YHcdK0DWDz3xkn; Tue, 24 Dec 2024 14:26:13 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1735050373; 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=JEvJetuSYcnnvUyc+UZUFtU3ITYhcy4YMXRB1iw2qQQ=; b=KBw7BarFbAtkbYKXGcbcL+nrxe91IcC+L+8W/N7vUZl/F35aV75rjGN58endKDAkqgUaOu YbcgPATx1vU3VV8PoJsByXLGcx3R3/a5aMsy3jisq4vjpjpLV8dbIL14g8gdEDlleMnFAe He/NawnSMIvYOQcOxMn41zBXHUx9ExYdrk+wmkMrvnxwfVYrWNRW0koWFk36V2NTnJZI6l SjPGSMdaGKQszOW86IkYjenXokVJu9kG2OF7zy1yecIteSjoxIU6CpPN5gHikcuzeWg5EE D3aVWICN1CHJf7ctp3dtXUJc51RBVYnyFTDU38JT8uE2gFjK8gw+FHHSe+OV7A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1735050373; 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=JEvJetuSYcnnvUyc+UZUFtU3ITYhcy4YMXRB1iw2qQQ=; b=rVgYeV06mTwgvF+U667OKBL3Pheyix5SRSN7K0MSdX+Bl/kPVTsq5zpit+HI/tGpw2hJRw TYZSROQJvJ870c/zqt4chGg0otdM7j+aXhPa+qMZO2nXr1e9y6Zt//OQi7AQurruKqzw6j 4wBkj1cwfs4tMxm28/dx0uoWkIxhx9SGUqas5hNGQwP3Nmu2zuJ2aGdKNNEvg3Lj0TFvU8 xViXCOR0rE6ha+dlUTwN2OYSJDfX5qk9W+n/0BF9QX5H9gbSYDE3EvXlEpi+zQnYMI/0Ol FytYocz2Be7Edxbt2b3uyIVmWkf00wxkciOyLUeVILJZ2fUGs+Qg+Zr/8LGXWg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1735050373; a=rsa-sha256; cv=none; b=neL5k4vtQRqrjR73FiBx4kzDKSlBjZGAcbEj7ykwlLrQWD57zrF7/b/y47xjVrTxyiSm4u xReoFB9Q3yMCa0BvDCBQ89COitplOv/JQ9Yttqwe3fp6HUYaXlHBaZ/U0eusP0Bo5gkIcL QvMThjMRrUkj5bcTqf3VjxCRGgrR2fp/x3CIp0VtbKZSnvlM3548GduOy1wTl89RxfoodA b0NSYaocS31IIQGPK9wAUrZ0HYjpFoomiySAgFxCLooOlNZFajYT9AMjGp6RVHR4OWtIE+ 1NkHwInyj1AjHhjDTce1P48mVM5c73KP8JRG164Cpvq8SnCcMGNxSD81KxzfJw== 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 4YHcdJ6yhJzhF2; Tue, 24 Dec 2024 14:26:12 +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 4BOEQCnq054085; Tue, 24 Dec 2024 14:26:12 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 4BOEQCWR054082; Tue, 24 Dec 2024 14:26:12 GMT (envelope-from git) Date: Tue, 24 Dec 2024 14:26:12 GMT Message-Id: <202412241426.4BOEQCWR054082@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: 30b9d8a73721 - stable/14 - 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/14 X-Git-Reftype: branch X-Git-Commit: 30b9d8a73721ed762aaf02244e9429ed5fac7142 Auto-Submitted: auto-generated The branch stable/14 has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=30b9d8a73721ed762aaf02244e9429ed5fac7142 commit 30b9d8a73721ed762aaf02244e9429ed5fac7142 Author: Leonid Evdokimov AuthorDate: 2024-12-06 12:08:54 +0000 Commit: Kristof Provost CommitDate: 2024-12-24 10:16:53 +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 3a75c9a62eec..b399da94c800 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 @@ -503,6 +503,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 621d97d6c555..5b5bfc636807 100644 --- a/sbin/pfctl/pfctl.c +++ b/sbin/pfctl/pfctl.c @@ -238,7 +238,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 95a0d0c9171c..c5106e6c4ba9 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 828d76a998be..62c9d66d80ce 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 "automatic" atf_add_test_case "network"