Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 16 Jan 2024 08:51:59 GMT
From:      Kristof Provost <kp@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 0493260115db - main - pf: store state creation/expiration timestamps with milisecond precision
Message-ID:  <202401160851.40G8px3w077181@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by kp:

URL: https://cgit.FreeBSD.org/src/commit/?id=0493260115db10164246762d6d4923880575e529

commit 0493260115db10164246762d6d4923880575e529
Author:     Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2023-12-07 13:35:11 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2024-01-16 08:45:54 +0000

    pf: store state creation/expiration timestamps with milisecond precision
    
    The primary beneficiary is pflow(4), which expects milisecond precision
    in timestamps.
    
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
    Differential Revision:  https://reviews.freebsd.org/D43112
---
 sys/net/pfvar.h            | 20 ++++++++++++++++++--
 sys/netpfil/pf/if_pfsync.c | 10 +++++-----
 sys/netpfil/pf/pf.c        | 19 +++++++++----------
 sys/netpfil/pf/pf_ioctl.c  |  4 ++--
 sys/netpfil/pf/pf_nl.c     |  2 +-
 sys/netpfil/pf/pf_norm.c   |  2 +-
 sys/netpfil/pf/pf_nv.c     |  2 +-
 sys/netpfil/pf/pflow.c     | 20 ++++++++++----------
 8 files changed, 47 insertions(+), 32 deletions(-)

diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index 037286a756be..f0742c99a4a8 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -1061,8 +1061,8 @@ struct pf_kstate {
 	struct pf_ksrc_node	*nat_src_node;
 	u_int64_t		 packets[2];
 	u_int64_t		 bytes[2];
-	u_int32_t		 creation;
-	u_int32_t	 	 expire;
+	u_int64_t		 creation;
+	u_int64_t	 	 expire;
 	u_int32_t		 pfsync_time;
 	struct pf_rule_actions	 act;
 	u_int16_t		 tag;
@@ -2238,6 +2238,22 @@ pf_release_staten(struct pf_kstate *s, u_int n)
 		return (0);
 }
 
+static __inline uint64_t
+pf_get_uptime(void)
+{
+	struct timeval t;
+	microuptime(&t);
+	return ((t.tv_sec * 1000) + (t.tv_usec / 1000));
+}
+
+static __inline uint64_t
+pf_get_time(void)
+{
+	struct timeval t;
+	microtime(&t);
+	return ((t.tv_sec * 1000) + (t.tv_usec / 1000));
+}
+
 extern struct pf_kstate		*pf_find_state_byid(uint64_t, uint32_t);
 extern struct pf_kstate		*pf_find_state_all(struct pf_state_key_cmp *,
 				    u_int, int *);
diff --git a/sys/netpfil/pf/if_pfsync.c b/sys/netpfil/pf/if_pfsync.c
index 75c361b394e0..c57a89ea052a 100644
--- a/sys/netpfil/pf/if_pfsync.c
+++ b/sys/netpfil/pf/if_pfsync.c
@@ -611,8 +611,8 @@ pfsync_state_import(union pfsync_state_union *sp, int flags, int msg_version)
 
 	/* copy to state */
 	bcopy(&sp->pfs_1301.rt_addr, &st->rt_addr, sizeof(st->rt_addr));
-	st->creation = time_uptime - ntohl(sp->pfs_1301.creation);
-	st->expire = time_uptime;
+	st->creation = (time_uptime - ntohl(sp->pfs_1301.creation)) * 1000;
+	st->expire = pf_get_uptime();
 	if (sp->pfs_1301.expire) {
 		uint32_t timeout;
 
@@ -621,7 +621,7 @@ pfsync_state_import(union pfsync_state_union *sp, int flags, int msg_version)
 			timeout = V_pf_default_rule.timeout[sp->pfs_1301.timeout];
 
 		/* sp->expire may have been adaptively scaled by export. */
-		st->expire -= timeout - ntohl(sp->pfs_1301.expire);
+		st->expire -= (timeout - ntohl(sp->pfs_1301.expire)) * 1000;
 	}
 
 	st->direction = sp->pfs_1301.direction;
@@ -1198,7 +1198,7 @@ pfsync_in_upd(struct mbuf *m, int offset, int count, int flags, int action)
 		if (sync < 2) {
 			pfsync_alloc_scrub_memory(&sp->pfs_1301.dst, &st->dst);
 			pf_state_peer_ntoh(&sp->pfs_1301.dst, &st->dst);
-			st->expire = time_uptime;
+			st->expire = pf_get_uptime();
 			st->timeout = sp->pfs_1301.timeout;
 		}
 		st->pfsync_time = time_uptime;
@@ -1285,7 +1285,7 @@ pfsync_in_upd_c(struct mbuf *m, int offset, int count, int flags, int action)
 		if (sync < 2) {
 			pfsync_alloc_scrub_memory(&up->dst, &st->dst);
 			pf_state_peer_ntoh(&up->dst, &st->dst);
-			st->expire = time_uptime;
+			st->expire = pf_get_uptime();
 			st->timeout = up->timeout;
 		}
 		st->pfsync_time = time_uptime;
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index 7eaac809e487..89f6e000f6cf 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -2037,12 +2037,12 @@ pf_state_expires(const struct pf_kstate *state)
 		if (states < end) {
 			timeout = (u_int64_t)timeout * (end - states) /
 			    (end - start);
-			return (state->expire + timeout);
+			return ((state->expire / 1000) + timeout);
 		}
 		else
 			return (time_uptime);
 	}
-	return (state->expire + timeout);
+	return ((state->expire / 1000) + timeout);
 }
 
 void
@@ -4951,8 +4951,7 @@ pf_create_state(struct pf_krule *r, struct pf_krule *nr, struct pf_krule *a,
 		s->rt = r->rt;
 	}
 
-	s->creation = time_uptime;
-	s->expire = time_uptime;
+	s->creation = s->expire = pf_get_uptime();
 
 	if (sn != NULL)
 		s->src_node = sn;
@@ -5426,7 +5425,7 @@ pf_tcp_track_full(struct pf_kstate **state, struct pfi_kkif *kif,
 			pf_set_protostate(*state, PF_PEER_BOTH, TCPS_TIME_WAIT);
 
 		/* update expire time */
-		(*state)->expire = time_uptime;
+		(*state)->expire = pf_get_uptime();
 		if (src->state >= TCPS_FIN_WAIT_2 &&
 		    dst->state >= TCPS_FIN_WAIT_2)
 			(*state)->timeout = PFTM_TCP_CLOSED;
@@ -5622,7 +5621,7 @@ pf_tcp_track_sloppy(struct pf_kstate **state, struct pf_pdesc *pd, u_short *reas
 		pf_set_protostate(*state, PF_PEER_BOTH, TCPS_TIME_WAIT);
 
 	/* update expire time */
-	(*state)->expire = time_uptime;
+	(*state)->expire = pf_get_uptime();
 	if (src->state >= TCPS_FIN_WAIT_2 &&
 	    dst->state >= TCPS_FIN_WAIT_2)
 		(*state)->timeout = PFTM_TCP_CLOSED;
@@ -5870,7 +5869,7 @@ pf_test_state_udp(struct pf_kstate **state, struct pfi_kkif *kif,
 		pf_set_protostate(*state, pdst, PFUDPS_MULTIPLE);
 
 	/* update expire time */
-	(*state)->expire = time_uptime;
+	(*state)->expire = pf_get_uptime();
 	if (src->state == PFUDPS_MULTIPLE && dst->state == PFUDPS_MULTIPLE)
 		(*state)->timeout = PFTM_UDP_MULTIPLE;
 	else
@@ -5971,7 +5970,7 @@ pf_test_state_sctp(struct pf_kstate **state, struct pfi_kkif *kif,
 			return (PF_DROP);
 	}
 
-	(*state)->expire = time_uptime;
+	(*state)->expire = pf_get_uptime();
 
 	/* translate source/destination address, if necessary */
 	if ((*state)->key[PF_SK_WIRE] != (*state)->key[PF_SK_STACK]) {
@@ -6478,7 +6477,7 @@ pf_test_state_icmp(struct pf_kstate **state, struct pfi_kkif *kif,
 
 		STATE_LOOKUP(kif, &key, *state, pd);
 
-		(*state)->expire = time_uptime;
+		(*state)->expire = pf_get_uptime();
 		(*state)->timeout = PFTM_ICMP_ERROR_REPLY;
 
 		/* translate source/destination address, if necessary */
@@ -7063,7 +7062,7 @@ pf_test_state_other(struct pf_kstate **state, struct pfi_kkif *kif,
 		pf_set_protostate(*state, pdst, PFOTHERS_MULTIPLE);
 
 	/* update expire time */
-	(*state)->expire = time_uptime;
+	(*state)->expire = pf_get_uptime();
 	if (src->state == PFOTHERS_MULTIPLE && dst->state == PFOTHERS_MULTIPLE)
 		(*state)->timeout = PFTM_OTHER_MULTIPLE;
 	else
diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c
index 956d954d652c..20e0b902bd60 100644
--- a/sys/netpfil/pf/pf_ioctl.c
+++ b/sys/netpfil/pf/pf_ioctl.c
@@ -5483,7 +5483,7 @@ pfsync_state_export(union pfsync_state_union *sp, struct pf_kstate *st, int msg_
 	/* copy from state */
 	strlcpy(sp->pfs_1301.ifname, st->kif->pfik_name, sizeof(sp->pfs_1301.ifname));
 	bcopy(&st->rt_addr, &sp->pfs_1301.rt_addr, sizeof(sp->pfs_1301.rt_addr));
-	sp->pfs_1301.creation = htonl(time_uptime - st->creation);
+	sp->pfs_1301.creation = htonl(time_uptime - (st->creation / 1000));
 	sp->pfs_1301.expire = pf_state_expires(st);
 	if (sp->pfs_1301.expire <= time_uptime)
 		sp->pfs_1301.expire = htonl(0);
@@ -5574,7 +5574,7 @@ pf_state_export(struct pf_state_export *sp, struct pf_kstate *st)
 	strlcpy(sp->orig_ifname, st->orig_kif->pfik_name,
 	    sizeof(sp->orig_ifname));
 	bcopy(&st->rt_addr, &sp->rt_addr, sizeof(sp->rt_addr));
-	sp->creation = htonl(time_uptime - st->creation);
+	sp->creation = htonl(time_uptime - (st->creation / 1000));
 	sp->expire = pf_state_expires(st);
 	if (sp->expire <= time_uptime)
 		sp->expire = htonl(0);
diff --git a/sys/netpfil/pf/pf_nl.c b/sys/netpfil/pf/pf_nl.c
index 23c4249714fe..e74d4773b1e7 100644
--- a/sys/netpfil/pf/pf_nl.c
+++ b/sys/netpfil/pf/pf_nl.c
@@ -169,7 +169,7 @@ dump_state(struct nlpcb *nlp, const struct nlmsghdr *hdr, struct pf_kstate *s,
 	nlattr_add_string(nw, PF_ST_IFNAME, s->kif->pfik_name);
 	nlattr_add_string(nw, PF_ST_ORIG_IFNAME, s->orig_kif->pfik_name);
 	dump_addr(nw, PF_ST_RT_ADDR, &s->rt_addr, af);
-	nlattr_add_u32(nw, PF_ST_CREATION, time_uptime - s->creation);
+	nlattr_add_u32(nw, PF_ST_CREATION, time_uptime - (s->creation / 1000));
 	uint32_t expire = pf_state_expires(s);
 	if (expire > time_uptime)
 		expire = expire - time_uptime;
diff --git a/sys/netpfil/pf/pf_norm.c b/sys/netpfil/pf/pf_norm.c
index 3824e7b2f595..f5d1a66f6467 100644
--- a/sys/netpfil/pf/pf_norm.c
+++ b/sys/netpfil/pf/pf_norm.c
@@ -1745,7 +1745,7 @@ pf_normalize_tcp_stateful(struct mbuf *m, int off, struct pf_pdesc *pd,
 	getmicrouptime(&uptime);
 	if (src->scrub && (src->scrub->pfss_flags & PFSS_PAWS) &&
 	    (uptime.tv_sec - src->scrub->pfss_last.tv_sec > TS_MAX_IDLE ||
-	    time_uptime - state->creation > TS_MAX_CONN))  {
+	    time_uptime - (state->creation / 1000) > TS_MAX_CONN))  {
 		if (V_pf_status.debug >= PF_DEBUG_MISC) {
 			DPFPRINTF(("src idled out of PAWS\n"));
 			pf_print_state(state);
diff --git a/sys/netpfil/pf/pf_nv.c b/sys/netpfil/pf/pf_nv.c
index 721d35be8916..016fe52f54d8 100644
--- a/sys/netpfil/pf/pf_nv.c
+++ b/sys/netpfil/pf/pf_nv.c
@@ -974,7 +974,7 @@ pf_state_to_nvstate(const struct pf_kstate *s)
 	    s->anchor.ptr ? s->anchor.ptr->nr : -1);
 	nvlist_add_number(nvl, "nat_rule",
 	    s->nat_rule.ptr ? s->nat_rule.ptr->nr : -1);
-	nvlist_add_number(nvl, "creation", s->creation);
+	nvlist_add_number(nvl, "creation", s->creation / 1000);
 
 	expire = pf_state_expires(s);
 	if (expire <= time_uptime)
diff --git a/sys/netpfil/pf/pflow.c b/sys/netpfil/pf/pflow.c
index a2699240fbc8..9a192c396c2d 100644
--- a/sys/netpfil/pf/pflow.c
+++ b/sys/netpfil/pf/pflow.c
@@ -543,9 +543,9 @@ copy_flow_data(struct pflow_flow *flow1, struct pflow_flow *flow2,
 	 * or was created / expired before this machine came up due to pfsync.
 	 */
 	flow1->flow_start = flow2->flow_start = st->creation < 0 ||
-	    st->creation > st->expire ? htonl(0) : htonl(st->creation * 1000);
+	    st->creation > st->expire ? htonl(0) : htonl(st->creation);
 	flow1->flow_finish = flow2->flow_finish = st->expire < 0 ? htonl(0) :
-	    htonl(st->expire * 1000);
+	    htonl(st->expire);
 	flow1->tcp_flags = flow2->tcp_flags = 0;
 	flow1->protocol = flow2->protocol = sk->proto;
 	flow1->tos = flow2->tos = st->rule.ptr->tos;
@@ -579,10 +579,10 @@ copy_flow_ipfix_4_data(struct pflow_ipfix_flow4 *flow1,
 		flow1->flow_start = flow2->flow_start = htobe64((time_second -
 		    time_uptime)*1000);
 	else
-		flow1->flow_start = flow2->flow_start = htobe64((time_second -
-		    (time_uptime - st->creation))*1000);
-	flow1->flow_finish = flow2->flow_finish = htobe64((time_second -
-	    (time_uptime - st->expire))*1000);
+		flow1->flow_start = flow2->flow_start = htobe64((pf_get_time() -
+		    (pf_get_uptime() - st->creation)));
+	flow1->flow_finish = flow2->flow_finish = htobe64((pf_get_time() -
+	    (pf_get_uptime() - st->expire)));
 
 	flow1->protocol = flow2->protocol = sk->proto;
 	flow1->tos = flow2->tos = st->rule.ptr->tos;
@@ -618,10 +618,10 @@ copy_flow_ipfix_6_data(struct pflow_ipfix_flow6 *flow1,
 		flow1->flow_start = flow2->flow_start = htobe64((time_second -
 		    time_uptime)*1000);
 	else
-		flow1->flow_start = flow2->flow_start = htobe64((time_second -
-		    (time_uptime - st->creation))*1000);
-	flow1->flow_finish = flow2->flow_finish = htobe64((time_second -
-	    (time_uptime - st->expire))*1000);
+		flow1->flow_start = flow2->flow_start = htobe64((pf_get_time() -
+		    (pf_get_uptime() - st->creation)));
+	flow1->flow_finish = flow2->flow_finish = htobe64((pf_get_time() -
+	    (pf_get_uptime() - st->expire)));
 
 	flow1->protocol = flow2->protocol = sk->proto;
 	flow1->tos = flow2->tos = st->rule.ptr->tos;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202401160851.40G8px3w077181>