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>