mirror of
https://github.com/freebsd/freebsd-src
synced 2024-09-06 09:10:28 +00:00
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
This commit is contained in:
parent
6bd36d1cf4
commit
0493260115
|
@ -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 *);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue