All of lore.kernel.org
 help / color / mirror / Atom feed
From: Florian Westphal <fw@strlen.de>
To: Pablo Neira Ayuso <pablo@netfilter.org>
Cc: Florian Westphal <fw@strlen.de>,
	Nadia Pinaeva <n.m.pinaeva@gmail.com>,
	netfilter-devel@vger.kernel.org,
	Antonio Ojea <antonio.ojea.garcia@gmail.com>
Subject: Re: [PATCH nf-next v2] netfilter: conntrack: collect start time as early as possible
Date: Tue, 5 Nov 2024 18:32:47 +0100	[thread overview]
Message-ID: <20241105173247.GA10152@breakpoint.cc> (raw)
In-Reply-To: <ZypLmxmAb_Hp2HBS@calendula>

Pablo Neira Ayuso <pablo@netfilter.org> wrote:
> Thanks, I'd rather convince you this is the way to go, if after
> quickly sketching a patchset you think it is not worth for more
> reasons, we can revisit.

Untested.  I'm not sure about skb_tstamp() usage.
As-is CTA_EVENT_TIMESTAMP in the NEW event would be before
the start time reported as the start time by the timestamp extension.

diff --git a/include/net/netfilter/nf_conntrack_ecache.h b/include/net/netfilter/nf_conntrack_ecache.h
--- a/include/net/netfilter/nf_conntrack_ecache.h
+++ b/include/net/netfilter/nf_conntrack_ecache.h
@@ -20,6 +20,7 @@ enum nf_ct_ecache_state {
 
 struct nf_conntrack_ecache {
 	unsigned long cache;		/* bitops want long */
+	u64 timestamp;			/* event timestamp, in nanoseconds */
 	u16 ctmask;			/* bitmask of ct events to be delivered */
 	u16 expmask;			/* bitmask of expect events to be delivered */
 	u32 missed;			/* missed events */
@@ -50,6 +51,7 @@ static inline bool nf_ct_ecache_exist(const struct nf_conn *ct)
 /* This structure is passed to event handler */
 struct nf_ct_event {
 	struct nf_conn *ct;
+	u64 timestamp;
 	u32 portid;
 	int report;
 };
@@ -73,7 +75,7 @@ void nf_ct_deliver_cached_events(struct nf_conn *ct);
 int nf_conntrack_eventmask_report(unsigned int eventmask, struct nf_conn *ct,
 				  u32 portid, int report);
 
-bool nf_ct_ecache_ext_add(struct nf_conn *ct, u16 ctmask, u16 expmask, gfp_t gfp);
+bool nf_ct_ecache_ext_add(struct nf_conn *ct, u16 ctmask, u16 expmask, ktime_t tstamp, gfp_t gfp);
 #else
 
 static inline void nf_ct_deliver_cached_events(const struct nf_conn *ct)
@@ -88,7 +90,8 @@ static inline int nf_conntrack_eventmask_report(unsigned int eventmask,
 	return 0;
 }
 
-static inline bool nf_ct_ecache_ext_add(struct nf_conn *ct, u16 ctmask, u16 expmask, gfp_t gfp)
+static inline bool nf_ct_ecache_ext_add(struct nf_conn *ct, u16 ctmask, u16 expmask,
+					ktime_t tstamp, gfp_t gfp)
 {
 	return false;
 }
@@ -108,6 +111,9 @@ nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct)
 	if (e == NULL)
 		return;
 
+	if (READ_ONCE(e->cache) == 0)
+		e->timestamp = ktime_get_real_ns();
+
 	set_bit(event, &e->cache);
 #endif
 }
diff --git a/include/uapi/linux/netfilter/nfnetlink_conntrack.h b/include/uapi/linux/netfilter/nfnetlink_conntrack.h
--- a/include/uapi/linux/netfilter/nfnetlink_conntrack.h
+++ b/include/uapi/linux/netfilter/nfnetlink_conntrack.h
@@ -57,6 +57,7 @@ enum ctattr_type {
 	CTA_SYNPROXY,
 	CTA_FILTER,
 	CTA_STATUS_MASK,
+	CTA_EVENT_TIMESTAMP,
 	__CTA_MAX
 };
 #define CTA_MAX (__CTA_MAX - 1)
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -1791,6 +1791,7 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
 	if ((ecache || net->ct.sysctl_events) &&
 	    !nf_ct_ecache_ext_add(ct, ecache ? ecache->ctmask : 0,
 				  ecache ? ecache->expmask : 0,
+				  ktime_to_ns(skb_get_ktime(skb)),
 				  GFP_ATOMIC)) {
 		nf_conntrack_free(ct);
 		return ERR_PTR(-ENOMEM);
diff --git a/net/netfilter/nf_conntrack_ecache.c b/net/netfilter/nf_conntrack_ecache.c
index 69948e1d6974..661d69da6d9a 100644
--- a/net/netfilter/nf_conntrack_ecache.c
+++ b/net/netfilter/nf_conntrack_ecache.c
@@ -182,6 +182,7 @@ int nf_conntrack_eventmask_report(unsigned int events, struct nf_conn *ct,
 	item.ct = ct;
 	item.portid = e->portid ? e->portid : portid;
 	item.report = report;
+	item.timestamp = e->timestamp;
 
 	/* This is a resent of a destroy event? If so, skip missed */
 	missed = e->portid ? 0 : e->missed;
@@ -297,7 +298,7 @@ void nf_conntrack_ecache_work(struct net *net, enum nf_ct_ecache_state state)
 	}
 }
 
-bool nf_ct_ecache_ext_add(struct nf_conn *ct, u16 ctmask, u16 expmask, gfp_t gfp)
+bool nf_ct_ecache_ext_add(struct nf_conn *ct, u16 ctmask, u16 expmask, ktime_t tstamp, gfp_t gfp)
 {
 	struct net *net = nf_ct_net(ct);
 	struct nf_conntrack_ecache *e;
@@ -326,6 +327,7 @@ bool nf_ct_ecache_ext_add(struct nf_conn *ct, u16 ctmask, u16 expmask, gfp_t gfp
 
 	e = nf_ct_ext_add(ct, NF_CT_EXT_ECACHE, gfp);
 	if (e) {
+		e->timestamp = tstamp;
 		e->ctmask  = ctmask;
 		e->expmask = expmask;
 	}
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 6a1239433830..e6b908a1cfef 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -717,6 +717,7 @@ static size_t ctnetlink_nlmsg_size(const struct nf_conn *ct)
 #endif
 	       + ctnetlink_proto_size(ct)
 	       + ctnetlink_label_size(ct)
+	       + nla_total_size(sizeof(u64)) /* CTA_EVENT_TIMESTAMP */
 	       ;
 }
 
@@ -1557,6 +1558,7 @@ static const struct nla_policy ct_nla_policy[CTA_MAX+1] = {
 				    .len = NF_CT_LABELS_MAX_SIZE },
 	[CTA_FILTER]		= { .type = NLA_NESTED },
 	[CTA_STATUS_MASK]	= { .type = NLA_U32 },
+	[CTA_EVENT_TIMESTAMP]	= { .type = NLA_U64 },
 };
 
 static int ctnetlink_flush_iterate(struct nf_conn *ct, void *data)
@@ -2304,7 +2306,7 @@ ctnetlink_create_conntrack(struct net *net,
 
 	nf_ct_acct_ext_add(ct, GFP_ATOMIC);
 	nf_ct_tstamp_ext_add(ct, GFP_ATOMIC);
-	nf_ct_ecache_ext_add(ct, 0, 0, GFP_ATOMIC);
+	nf_ct_ecache_ext_add(ct, 0, 0, 0, GFP_ATOMIC);
 	nf_ct_labels_ext_add(ct);
 	nfct_seqadj_ext_add(ct);
 	nfct_synproxy_ext_add(ct);
diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
index 67a41cd2baaf..c57d3715287d 100644
--- a/net/netfilter/nft_ct.c
+++ b/net/netfilter/nft_ct.c
@@ -322,7 +322,7 @@ static void nft_ct_set_eval(const struct nft_expr *expr,
 		}
 
 		if (ctmask && !nf_ct_is_confirmed(ct))
-			nf_ct_ecache_ext_add(ct, ctmask, 0, GFP_ATOMIC);
+			nf_ct_ecache_ext_add(ct, ctmask, 0, skb_tstamp(skb), GFP_ATOMIC);
 		break;
 	}
 #endif
diff --git a/net/netfilter/xt_CT.c b/net/netfilter/xt_CT.c
index 2be2f7a7b60f..b2563bcf0c17 100644
--- a/net/netfilter/xt_CT.c
+++ b/net/netfilter/xt_CT.c
@@ -189,7 +189,7 @@ static int xt_ct_tg_check(const struct xt_tgchk_param *par,
 
 	if ((info->ct_events || info->exp_events) &&
 	    !nf_ct_ecache_ext_add(ct, info->ct_events, info->exp_events,
-				  GFP_KERNEL)) {
+				  0, GFP_KERNEL)) {
 		ret = -EINVAL;
 		goto err3;
 	}

  reply	other threads:[~2024-11-05 17:32 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-10-30 13:12 [PATCH nf-next v2] netfilter: conntrack: collect start time as early as possible Florian Westphal
2024-11-03 10:26 ` Nadia Pinaeva
2024-11-04  9:09   ` Pablo Neira Ayuso
2024-11-04  9:39     ` Florian Westphal
2024-11-04 10:03       ` Nadia Pinaeva
2024-11-04 11:09         ` Antonio Ojea
2024-11-05 16:08   ` Pablo Neira Ayuso
2024-11-05 16:23     ` Florian Westphal
2024-11-05 16:28       ` Pablo Neira Ayuso
2024-11-05 16:33         ` Florian Westphal
2024-11-05 16:45           ` Pablo Neira Ayuso
2024-11-05 17:32             ` Florian Westphal [this message]
2024-11-05 23:20               ` Pablo Neira Ayuso
2024-11-06  8:26                 ` Florian Westphal
2024-11-06  8:32                   ` Pablo Neira Ayuso
2024-11-06  8:34                     ` Florian Westphal
2024-11-06  9:10                       ` Pablo Neira Ayuso
2024-11-06 12:39                         ` Florian Westphal

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20241105173247.GA10152@breakpoint.cc \
    --to=fw@strlen.de \
    --cc=antonio.ojea.garcia@gmail.com \
    --cc=n.m.pinaeva@gmail.com \
    --cc=netfilter-devel@vger.kernel.org \
    --cc=pablo@netfilter.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.