git: 7d929a444587 - main - pf: Fix timestamps and connection rate in source node export

From: Kajetan Staszkiewicz <ks_at_FreeBSD.org>
Date: Thu, 21 Nov 2024 14:28:05 UTC
The branch main has been updated by ks:

URL: https://cgit.FreeBSD.org/src/commit/?id=7d929a444587540205e27caacf72377169611cdf

commit 7d929a444587540205e27caacf72377169611cdf
Author:     Kajetan Staszkiewicz <ks@FreeBSD.org>
AuthorDate: 2024-11-21 14:23:42 +0000
Commit:     Kajetan Staszkiewicz <ks@FreeBSD.org>
CommitDate: 2024-11-21 14:27:32 +0000

    pf: Fix timestamps and connection rate in source node export
    
    When copying struct pf_ksrc_node into a netlink message some fields
    change their meaning. In kernel creation and expire fields are storing
    number of seconds since boot.
    
    Add conversion to number of seconds relative to moment of exporting the
    source node via netlink, as this is what pfctl expects. Add conversion
    of connection rate count.
    
    Reviewed by:            kp
    Approved by:            kp (mentor)
    Sponsored by:           InnoGames GmbH
    Differential Revision:  https://reviews.freebsd.org/D47321
---
 sys/netpfil/pf/pf_nl.c | 31 +++++++++++++++++++++++++------
 1 file changed, 25 insertions(+), 6 deletions(-)

diff --git a/sys/netpfil/pf/pf_nl.c b/sys/netpfil/pf/pf_nl.c
index 7a54ee78c684..bdfa9a60faa4 100644
--- a/sys/netpfil/pf/pf_nl.c
+++ b/sys/netpfil/pf/pf_nl.c
@@ -1714,13 +1714,23 @@ pf_handle_get_ruleset(struct nlmsghdr *hdr, struct nl_pstate *npt)
 }
 
 static bool
-nlattr_add_pf_threshold(struct nl_writer *nw, int attrtype, struct pf_threshold *t)
+nlattr_add_pf_threshold(struct nl_writer *nw, int attrtype,
+    struct pf_threshold *t, int secs)
 {
-	int off = nlattr_add_nested(nw, attrtype);
+	int	 off = nlattr_add_nested(nw, attrtype);
+	int	 diff, conn_rate_count;
+
+	/* Adjust the connection rate estimate. */
+	conn_rate_count = t->count;
+	diff = secs - t->last;
+	if (diff >= t->seconds)
+		conn_rate_count = 0;
+	else
+		conn_rate_count -= t->count * diff / t->seconds;
 
 	nlattr_add_u32(nw, PF_TH_LIMIT, t->limit);
 	nlattr_add_u32(nw, PF_TH_SECONDS, t->seconds);
-	nlattr_add_u32(nw, PF_TH_COUNT, t->count);
+	nlattr_add_u32(nw, PF_TH_COUNT, conn_rate_count);
 	nlattr_add_u32(nw, PF_TH_LAST, t->last);
 
 	nlattr_set_len(nw, off);
@@ -1736,6 +1746,7 @@ pf_handle_get_srcnodes(struct nlmsghdr *hdr, struct nl_pstate *npt)
 	struct pf_ksrc_node	*n;
 	struct pf_srchash	*sh;
 	int			 i;
+	int			 secs;
 
 	hdr->nlmsg_flags |= NLM_F_MULTI;
 
@@ -1746,6 +1757,8 @@ pf_handle_get_srcnodes(struct nlmsghdr *hdr, struct nl_pstate *npt)
 			continue;
 
 		PF_HASHROW_LOCK(sh);
+		secs = time_uptime;
+
 		LIST_FOREACH(n, &sh->nodes, entry) {
 			if (!nlmsg_reply(nw, hdr, sizeof(struct genlmsghdr))) {
 				nlmsg_abort(nw);
@@ -1768,9 +1781,15 @@ pf_handle_get_srcnodes(struct nlmsghdr *hdr, struct nl_pstate *npt)
 			nlattr_add_u32(nw, PF_SN_CONNECTIONS, n->conn);
 			nlattr_add_u8(nw, PF_SN_AF, n->af);
 			nlattr_add_u8(nw, PF_SN_RULE_TYPE, n->ruletype);
-			nlattr_add_u64(nw, PF_SN_CREATION, n->creation);
-			nlattr_add_u64(nw, PF_SN_EXPIRE, n->expire);
-			nlattr_add_pf_threshold(nw, PF_SN_CONNECTION_RATE, &n->conn_rate);
+
+			nlattr_add_u64(nw, PF_SN_CREATION, secs - n->creation);
+			if (n->expire > secs)
+				nlattr_add_u64(nw, PF_SN_EXPIRE, n->expire - secs);
+			else
+				nlattr_add_u64(nw, PF_SN_EXPIRE, 0);
+
+			nlattr_add_pf_threshold(nw, PF_SN_CONNECTION_RATE,
+			    &n->conn_rate, secs);
 
 			if (!nlmsg_end(nw)) {
 				PF_HASHROW_UNLOCK(sh);