The branch main has been updated by kp:

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

commit 0493260115db10164246762d6d4923880575e529
Author:     Kristof Provost <[email protected]>
AuthorDate: 2023-12-07 13:35:11 +0000
Commit:     Kristof Provost <[email protected]>
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;

Reply via email to