From nobody Fri Apr 22 17:53:55 2022 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 7529D1997704; Fri, 22 Apr 2022 17:53:55 +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 "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4KlMTv2kgRz3CG8; Fri, 22 Apr 2022 17:53:55 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1650650035; 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=xhQmQupAueMWATo4YpHJKHMzIE1N7P4TGlKL+MLzk2Q=; b=MJiAu9oGI9yWGcmNYhZufzYSJZM03+4TgAu7AoLzKXAq0Pa5G5Hq9a5FutWIToz1Si5rcl obXwQhsBRcOsHR9HOKN5K4+g1GDrZ64pLdNpr54K2R/Wk8ULDJjyTpOtcFCH7wm2s8HuaJ Mge0a8ttEjhfnS+6gcURv4AU0siq/j4e22kKAJeJY3EaYbkhsVm4OQrootFKDCsNEHufKS gnUSbQYQFifnFIaLQ5bxnhphLnQsmqvwqJf6dqcNyPb+aWUm5Cmh6czXAeDZnH8qeZ8Unu AMr9n/drPPehrooa0RsiLvjHe6M1Ok+JNZMBsCmtX04TWWOJU0+YNWpQWGuNiQ== 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 3DA79216EC; Fri, 22 Apr 2022 17:53:55 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 23MHrt7O087333; Fri, 22 Apr 2022 17:53:55 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 23MHrtUU087332; Fri, 22 Apr 2022 17:53:55 GMT (envelope-from git) Date: Fri, 22 Apr 2022 17:53:55 GMT Message-Id: <202204221753.23MHrtUU087332@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kristof Provost Subject: git: 0abcc1d2d33a - main - pf: Add per-rule timestamps for rule and eth_rule 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: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: 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/main X-Git-Reftype: branch X-Git-Commit: 0abcc1d2d33aef2333dab28e1ec1858cf45b314a Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1650650035; 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=xhQmQupAueMWATo4YpHJKHMzIE1N7P4TGlKL+MLzk2Q=; b=itcsjVWtsrn00cyNJ5t4dPNwmgUQF9sKXfRDu5dO+zGsRMGzYTp1FQgg1G/3d1PaQiT2CM HyZZ6fuOLyA0HLm0Dp6Hs1JGpnrWct5kMWu4DiXqtVLceO9GKE4c4e+QZqEt4vgqGx3vLd xIeepHlTUYJOBF/cjr+q74VOENVigBvS2MZFncai1hYsc1h2YSX/dPuK5o29M6xWrhqJuZ UFZeMTHOYNiRUD1e2H4b90wQTJSqNIaH3hdbbVjzttl8BPXOjufhXKfAzWXil+UFOswQkq uuSTLJWSzJsE5NsAKJZqaAYQWIUc0KXaKdo0JCplqVqZkkB3n3cujOyc4n3egQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1650650035; a=rsa-sha256; cv=none; b=wHTFJRkaZKwEwIqw4iKHs2G6uWVkSkqx+DuwsLrA/3Q+wr8C5LmKjrGaexZe6wJKCpDCgn TPkCVdRPEnvKhQ6qRgwytbCbo/u8cwdBO+2P8RYUJFaI1uDEvTSR6gSlcsSBMmI2KMY3ae zMgCpkn98xGymSFj0FkQm1Dn4++6wUTM9FRd0ZFcI7KqxvX/aQnSBEqZ+axGRml1myZNbK 1PdCBEdofoxX2GpoeYoMeH8ozwer0OFAXeI/qTC1d6jLmyQAT9bwEsJGXBwVRmjFQE59QP eZ4GPTzjLmfFInE+4qnw0cv0KcE/K4MvwJ+9J7PFZpclmNKZuNGWwthuF5J7Tw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=0abcc1d2d33aef2333dab28e1ec1858cf45b314a commit 0abcc1d2d33aef2333dab28e1ec1858cf45b314a Author: Reid Linnemann AuthorDate: 2022-04-22 11:54:51 +0000 Commit: Kristof Provost CommitDate: 2022-04-22 17:53:20 +0000 pf: Add per-rule timestamps for rule and eth_rule Similar to ipfw rule timestamps, these timestamps internally are uint32_t snaps of the system time in seconds. The timestamp is CPU local and updated each time a rule or a state associated with a rule or state is matched. Reviewed by: kp Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D34970 --- lib/libpfctl/libpfctl.c | 10 +++++++++- lib/libpfctl/libpfctl.h | 2 ++ sbin/pfctl/pfctl.c | 23 +++++++++++++++++++++++ sys/net/pfvar.h | 22 ++++++++++++++++++++++ sys/netpfil/pf/pf.c | 3 +++ sys/netpfil/pf/pf_ioctl.c | 9 +++++++++ sys/netpfil/pf/pf_nv.c | 2 ++ 7 files changed, 70 insertions(+), 1 deletion(-) diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c index 89123bd80ad5..6a883a814902 100644 --- a/lib/libpfctl/libpfctl.c +++ b/lib/libpfctl/libpfctl.c @@ -512,6 +512,10 @@ pf_nvrule_to_rule(const nvlist_t *nvl, struct pfctl_rule *rule) pf_nvuint_64_array(nvl, "packets", 2, rule->packets, NULL); pf_nvuint_64_array(nvl, "bytes", 2, rule->bytes, NULL); + if (nvlist_exists_number(nvl, "timestamp")) { + rule->last_active_timestamp = nvlist_get_number(nvl, "timestamp"); + } + rule->os_fingerprint = nvlist_get_number(nvl, "os_fingerprint"); rule->rtableid = nvlist_get_number(nvl, "rtableid"); @@ -642,6 +646,10 @@ pfctl_nveth_rule_to_eth_rule(const nvlist_t *nvl, struct pfctl_eth_rule *rule) rule->bytes[0] = nvlist_get_number(nvl, "bytes-in"); rule->bytes[1] = nvlist_get_number(nvl, "bytes-out"); + if (nvlist_exists_number(nvl, "timestamp")) { + rule->last_active_timestamp = nvlist_get_number(nvl, "timestamp"); + } + strlcpy(rule->qname, nvlist_get_string(nvl, "qname"), PF_QNAME_SIZE); strlcpy(rule->tagname, nvlist_get_string(nvl, "tagname"), PF_TAG_NAME_SIZE); @@ -737,7 +745,7 @@ pfctl_get_eth_rule(int dev, uint32_t nr, uint32_t ticket, nvlist_add_number(nvl, "nr", nr); nvlist_add_bool(nvl, "clear", clear); - if ((ret = pfctl_do_ioctl(dev, DIOCGETETHRULE, 2048, &nvl)) != 0) + if ((ret = pfctl_do_ioctl(dev, DIOCGETETHRULE, 4096, &nvl)) != 0) return (ret); pfctl_nveth_rule_to_eth_rule(nvl, rule); diff --git a/lib/libpfctl/libpfctl.h b/lib/libpfctl/libpfctl.h index 440ca2fe0d10..ab4b6a27c787 100644 --- a/lib/libpfctl/libpfctl.h +++ b/lib/libpfctl/libpfctl.h @@ -99,6 +99,7 @@ struct pfctl_eth_rule { uint64_t evaluations; uint64_t packets[2]; uint64_t bytes[2]; + uint32_t last_active_timestamp; /* Action */ char qname[PF_QNAME_SIZE]; @@ -171,6 +172,7 @@ struct pfctl_rule { uint64_t evaluations; uint64_t packets[2]; uint64_t bytes[2]; + uint32_t last_active_timestamp; struct pfi_kif *kif; struct pfctl_anchor *anchor; diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c index 150a375b316a..a1f8e5fedd4c 100644 --- a/sbin/pfctl/pfctl.c +++ b/sbin/pfctl/pfctl.c @@ -1016,6 +1016,18 @@ pfctl_print_eth_rule_counters(struct pfctl_eth_rule *rule, int opts) (unsigned long long)(rule->bytes[0] + rule->bytes[1])); } + if (opts & PF_OPT_VERBOSE2) { + char timestr[30]; + + if (rule->last_active_timestamp != 0) { + time_t last_active = rule->last_active_timestamp; + bcopy(ctime(&last_active), timestr, sizeof(timestr)); + *strchr(timestr, '\n') = '\0'; + } else { + snprintf(timestr, sizeof(timestr), "N/A"); + } + printf(" [ Last Active Time: %s ]\n", timestr); + } } void @@ -1055,6 +1067,17 @@ pfctl_print_rule_counters(struct pfctl_rule *rule, int opts) (unsigned)rule->cuid, (unsigned)rule->cpid, (uintmax_t)rule->states_tot); } + if (opts & PF_OPT_VERBOSE2) { + char timestr[30]; + if (rule->last_active_timestamp != 0) { + time_t last_active = rule->last_active_timestamp; + bcopy(ctime(&last_active), timestr, sizeof(timestr)); + *strchr(timestr, '\n') = '\0'; + } else { + snprintf(timestr, sizeof(timestr), "N/A"); + } + printf(" [ Last Active Time: %s ]\n", timestr); + } } void diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index adcf69905698..4ad758fe439b 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -286,6 +286,26 @@ pf_counter_u64_zero(struct pf_counter_u64 *pfcu64) } #endif +#define pf_get_timestamp(prule)({ \ + uint32_t _ts = 0; \ + uint32_t __ts; \ + int cpu; \ + CPU_FOREACH(cpu) { \ + __ts = *zpcpu_get_cpu(prule->timestamp, cpu); \ + if (__ts > _ts) \ + _ts = __ts; \ + } \ + _ts; \ +}) + +#define pf_update_timestamp(prule) \ + do { \ + critical_enter(); \ + *zpcpu_get((prule)->timestamp) = time_second; \ + critical_exit(); \ + } while (0) + + SYSCTL_DECL(_net_pf); MALLOC_DECLARE(M_PFHASH); @@ -657,6 +677,7 @@ struct pf_keth_rule { counter_u64_t evaluations; counter_u64_t packets[2]; counter_u64_t bytes[2]; + uint32_t *timestamp; /* Action */ char qname[PF_QNAME_SIZE]; @@ -696,6 +717,7 @@ struct pf_krule { struct pf_counter_u64 evaluations; struct pf_counter_u64 packets[2]; struct pf_counter_u64 bytes[2]; + uint32_t *timestamp; struct pfi_kkif *kif; struct pf_kanchor *anchor; diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index d27e6f30f945..5eee9dcf5b91 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -3971,6 +3971,7 @@ pf_test_eth_rule(int dir, struct pfi_kkif *kif, struct mbuf **m0) /* Execute action. */ counter_u64_add(r->packets[dir == PF_OUT], 1); counter_u64_add(r->bytes[dir == PF_OUT], m_length(m, NULL)); + pf_update_timestamp(r); /* Shortcut. Don't tag if we're just going to drop anyway. */ if (r->action == PF_DROP) { @@ -7198,6 +7199,8 @@ done: dirndx = (dir == PF_OUT); pf_counter_u64_add_protected(&r->packets[dirndx], 1); pf_counter_u64_add_protected(&r->bytes[dirndx], pd.tot_len); + pf_update_timestamp(r); + if (a != NULL) { pf_counter_u64_add_protected(&a->packets[dirndx], 1); pf_counter_u64_add_protected(&a->bytes[dirndx], pd.tot_len); diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c index 86cbf7aa3808..65839d1d31d9 100644 --- a/sys/netpfil/pf/pf_ioctl.c +++ b/sys/netpfil/pf/pf_ioctl.c @@ -344,6 +344,8 @@ pfattach_vnet(void) V_pf_default_rule.states_tot = counter_u64_alloc(M_WAITOK); V_pf_default_rule.src_nodes = counter_u64_alloc(M_WAITOK); + V_pf_default_rule.timestamp = uma_zalloc_pcpu(pcpu_zone_4, M_WAITOK | M_ZERO); + #ifdef PF_WANT_32_TO_64_COUNTER V_pf_kifmarker = malloc(sizeof(*V_pf_kifmarker), PFI_MTYPE, M_WAITOK | M_ZERO); V_pf_rulemarker = malloc(sizeof(*V_pf_rulemarker), M_PFRULE, M_WAITOK | M_ZERO); @@ -530,6 +532,7 @@ pf_free_eth_rule(struct pf_keth_rule *rule) counter_u64_free(rule->packets[i]); counter_u64_free(rule->bytes[i]); } + uma_zfree_pcpu(pcpu_zone_4, rule->timestamp); pf_keth_anchor_remove(rule); free(rule, M_PFRULE); @@ -1801,6 +1804,7 @@ pf_krule_free(struct pf_krule *rule) counter_u64_free(rule->states_cur); counter_u64_free(rule->states_tot); counter_u64_free(rule->src_nodes); + uma_zfree_pcpu(pcpu_zone_4, rule->timestamp); mtx_destroy(&rule->rpool.mtx); free(rule, M_PFRULE); @@ -2130,6 +2134,7 @@ pf_ioctl_addrule(struct pf_krule *rule, uint32_t ticket, rule->states_cur = counter_u64_alloc(M_WAITOK); rule->states_tot = counter_u64_alloc(M_WAITOK); rule->src_nodes = counter_u64_alloc(M_WAITOK); + rule->timestamp = uma_zalloc_pcpu(pcpu_zone_4, M_WAITOK | M_ZERO); rule->cuid = td->td_ucred->cr_ruid; rule->cpid = td->td_proc ? td->td_proc->p_pid : 0; TAILQ_INIT(&rule->rpool.list); @@ -2832,6 +2837,7 @@ DIOCGETETHRULE_error: rule = malloc(sizeof(*rule), M_PFRULE, M_WAITOK); if (rule == NULL) ERROUT(ENOMEM); + rule->timestamp = NULL; error = pf_nveth_rule_to_keth_rule(nvl, rule); if (error != 0) @@ -2844,6 +2850,8 @@ DIOCGETETHRULE_error: rule->packets[i] = counter_u64_alloc(M_WAITOK); rule->bytes[i] = counter_u64_alloc(M_WAITOK); } + rule->timestamp = uma_zalloc_pcpu(pcpu_zone_4, + M_WAITOK | M_ZERO); PF_RULES_WLOCK(); @@ -6697,6 +6705,7 @@ pf_unload_vnet(void) counter_u64_free(V_pf_default_rule.states_cur); counter_u64_free(V_pf_default_rule.states_tot); counter_u64_free(V_pf_default_rule.src_nodes); + uma_zfree_pcpu(pcpu_zone_4, V_pf_default_rule.timestamp); for (int i = 0; i < PFRES_MAX; i++) counter_u64_free(V_pf_status.counters[i]); diff --git a/sys/netpfil/pf/pf_nv.c b/sys/netpfil/pf/pf_nv.c index 4dcb5441f835..5476b59d859f 100644 --- a/sys/netpfil/pf/pf_nv.c +++ b/sys/netpfil/pf/pf_nv.c @@ -737,6 +737,7 @@ pf_krule_to_nvrule(struct pf_krule *rule) nvlist_append_number_array(nvl, "bytes", pf_counter_u64_fetch(&rule->bytes[i])); } + nvlist_add_number(nvl, "timestamp", pf_get_timestamp(rule)); nvlist_add_number(nvl, "os_fingerprint", rule->os_fingerprint); @@ -1098,6 +1099,7 @@ pf_keth_rule_to_nveth_rule(const struct pf_keth_rule *krule) nvlist_add_number(nvl, "bytes-out", counter_u64_fetch(krule->bytes[1])); + nvlist_add_number(nvl, "timestamp", pf_get_timestamp(krule)); nvlist_add_string(nvl, "qname", krule->qname); nvlist_add_string(nvl, "tagname", krule->tagname);