Skip to content

Commit e30d966

Browse files
committed
Merge: netfilter: stable backport for 10.1 phase 1
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-10/-/merge_requests/626 JIRA: https://issues.redhat.com/browse/RHEL-84544 * 3f54959 netfilter: nfnetlink: Report extack policy errors for batched ops * 08e52cc netfilter: nf_tables: prefer nft_trans_elem_alloc helper * 4ee2918 netfilter: nf_tables: add nft_trans_commit_list_add_elem helper * a8ee6b9 netfilter: nf_tables: prepare for multiple elements in nft_trans_elem structure * 466c9b3 netfilter: nf_tables: prepare nft audit for set element compaction * b0c4946 netfilter: nf_tables: switch trans_elem to real flex array * 5081808 netfilter: nf_tables: allocate element update information dynamically * 5cfe561 netfilter: nft_ct: Use __refcount_inc() for per-CPU nft_ct_pcpu_template. * 6edd78a netfilter: nft_exthdr: fix offset with ipv4_find_option() * fb82865 netfilter: nf_tables: make destruction work queue pernet * 95f1c1e netfilter: xt_hashlimit: htable_selective_cleanup() optimization * 601731f netfilter: conntrack: add conntrack event timestamp * 3176859 netfilter: conntrack: remove skb argument from nf_ct_refresh * 03428ca netfilter: conntrack: rework offload nf_conn timeout extension logic * d9d7b48 netfilter: nft_flow_offload: clear tcp MAXACK flag before moving to slowpath * 7a4b614 netfilter: nft_flow_offload: update tcp state flags under lock * df08c94 netfilter: nf_conncount: garbage collection is not skipped when jiffies wrap around * d653bfe netfilter: nf_conncount: Fully initialize struct nf_conncount_tuple in insert_tree() Signed-off-by: CKI Backport Bot <cki-ci-bot+cki-gitlab-backport-bot@redhat.com> --- <small>Created 2025-03-25 15:22 UTC by backporter - [KWF FAQ](https://red.ht/kernel_workflow_doc) - [Slack #team-kernel-workflow](https://redhat-internal.slack.com/archives/C04LRUPMJQ5) - [Source](https://gitlab.com/cki-project/kernel-workflow/-/blob/main/webhook/utils/backporter.py) - [Documentation](https://gitlab.com/cki-project/kernel-workflow/-/blob/main/docs/README.backporter.md) - [Report an issue](https://gitlab.com/cki-project/kernel-workflow/-/issues/new?issue%5Btitle%5D=backporter%20webhook%20issue)</small> Approved-by: Florian Westphal <fwestpha@redhat.com> Approved-by: Phil Sutter <psutter@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: Julio Faracco <jfaracco@redhat.com>
2 parents bf0b530 + 3af3a2d commit e30d966

20 files changed

+562
-161
lines changed

include/net/netfilter/nf_conntrack.h

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -204,24 +204,22 @@ bool nf_ct_get_tuplepr(const struct sk_buff *skb, unsigned int nhoff,
204204
struct nf_conntrack_tuple *tuple);
205205

206206
void __nf_ct_refresh_acct(struct nf_conn *ct, enum ip_conntrack_info ctinfo,
207-
const struct sk_buff *skb,
208-
u32 extra_jiffies, bool do_acct);
207+
u32 extra_jiffies, unsigned int bytes);
209208

210209
/* Refresh conntrack for this many jiffies and do accounting */
211210
static inline void nf_ct_refresh_acct(struct nf_conn *ct,
212211
enum ip_conntrack_info ctinfo,
213212
const struct sk_buff *skb,
214213
u32 extra_jiffies)
215214
{
216-
__nf_ct_refresh_acct(ct, ctinfo, skb, extra_jiffies, true);
215+
__nf_ct_refresh_acct(ct, ctinfo, extra_jiffies, skb->len);
217216
}
218217

219218
/* Refresh conntrack for this many jiffies */
220219
static inline void nf_ct_refresh(struct nf_conn *ct,
221-
const struct sk_buff *skb,
222220
u32 extra_jiffies)
223221
{
224-
__nf_ct_refresh_acct(ct, 0, skb, extra_jiffies, false);
222+
__nf_ct_refresh_acct(ct, 0, extra_jiffies, 0);
225223
}
226224

227225
/* kill conntrack and do accounting */
@@ -314,16 +312,6 @@ static inline bool nf_ct_should_gc(const struct nf_conn *ct)
314312

315313
#define NF_CT_DAY (86400 * HZ)
316314

317-
/* Set an arbitrary timeout large enough not to ever expire, this save
318-
* us a check for the IPS_OFFLOAD_BIT from the packet path via
319-
* nf_ct_is_expired().
320-
*/
321-
static inline void nf_ct_offload_timeout(struct nf_conn *ct)
322-
{
323-
if (nf_ct_expires(ct) < NF_CT_DAY / 2)
324-
WRITE_ONCE(ct->timeout, nfct_time_stamp + NF_CT_DAY);
325-
}
326-
327315
struct kernel_param;
328316

329317
int nf_conntrack_set_hashsize(const char *val, const struct kernel_param *kp);

include/net/netfilter/nf_conntrack_ecache.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <linux/netfilter/nf_conntrack_common.h>
1313
#include <linux/netfilter/nf_conntrack_tuple_common.h>
1414
#include <net/netfilter/nf_conntrack_extend.h>
15+
#include <asm/local64.h>
1516

1617
enum nf_ct_ecache_state {
1718
NFCT_ECACHE_DESTROY_FAIL, /* tried but failed to send destroy event */
@@ -20,6 +21,9 @@ enum nf_ct_ecache_state {
2021

2122
struct nf_conntrack_ecache {
2223
unsigned long cache; /* bitops want long */
24+
#ifdef CONFIG_NF_CONNTRACK_TIMESTAMP
25+
local64_t timestamp; /* event timestamp, in nanoseconds */
26+
#endif
2327
u16 ctmask; /* bitmask of ct events to be delivered */
2428
u16 expmask; /* bitmask of expect events to be delivered */
2529
u32 missed; /* missed events */
@@ -108,6 +112,14 @@ nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct)
108112
if (e == NULL)
109113
return;
110114

115+
#ifdef CONFIG_NF_CONNTRACK_TIMESTAMP
116+
/* renew only if this is the first cached event, so that the
117+
* timestamp reflects the first, not the last, generated event.
118+
*/
119+
if (local64_read(&e->timestamp) && READ_ONCE(e->cache) == 0)
120+
local64_set(&e->timestamp, ktime_get_real_ns());
121+
#endif
122+
111123
set_bit(event, &e->cache);
112124
#endif
113125
}

include/net/netfilter/nf_tables.h

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1757,28 +1757,29 @@ enum nft_trans_elem_flags {
17571757
NFT_TRANS_UPD_EXPIRATION = (1 << 1),
17581758
};
17591759

1760+
struct nft_elem_update {
1761+
u64 timeout;
1762+
u64 expiration;
1763+
u8 flags;
1764+
};
1765+
1766+
struct nft_trans_one_elem {
1767+
struct nft_elem_priv *priv;
1768+
struct nft_elem_update *update;
1769+
};
1770+
17601771
struct nft_trans_elem {
17611772
struct nft_trans nft_trans;
17621773
struct nft_set *set;
1763-
struct nft_elem_priv *elem_priv;
1764-
u64 timeout;
1765-
u64 expiration;
1766-
u8 update_flags;
17671774
bool bound;
1775+
unsigned int nelems;
1776+
struct nft_trans_one_elem elems[] __counted_by(nelems);
17681777
};
17691778

17701779
#define nft_trans_container_elem(t) \
17711780
container_of(t, struct nft_trans_elem, nft_trans)
17721781
#define nft_trans_elem_set(trans) \
17731782
nft_trans_container_elem(trans)->set
1774-
#define nft_trans_elem_priv(trans) \
1775-
nft_trans_container_elem(trans)->elem_priv
1776-
#define nft_trans_elem_update_flags(trans) \
1777-
nft_trans_container_elem(trans)->update_flags
1778-
#define nft_trans_elem_timeout(trans) \
1779-
nft_trans_container_elem(trans)->timeout
1780-
#define nft_trans_elem_expiration(trans) \
1781-
nft_trans_container_elem(trans)->expiration
17821783
#define nft_trans_elem_set_bound(trans) \
17831784
nft_trans_container_elem(trans)->bound
17841785

@@ -1883,7 +1884,7 @@ void nft_chain_filter_fini(void);
18831884
void __init nft_chain_route_init(void);
18841885
void nft_chain_route_fini(void);
18851886

1886-
void nf_tables_trans_destroy_flush_work(void);
1887+
void nf_tables_trans_destroy_flush_work(struct net *net);
18871888

18881889
int nf_msecs_to_jiffies64(const struct nlattr *nla, u64 *result);
18891890
__be64 nf_jiffies64_to_msecs(u64 input);
@@ -1897,6 +1898,7 @@ static inline int nft_request_module(struct net *net, const char *fmt, ...) { re
18971898
struct nftables_pernet {
18981899
struct list_head tables;
18991900
struct list_head commit_list;
1901+
struct list_head destroy_list;
19001902
struct list_head commit_set_list;
19011903
struct list_head binding_list;
19021904
struct list_head module_list;
@@ -1907,6 +1909,7 @@ struct nftables_pernet {
19071909
unsigned int base_seq;
19081910
unsigned int gc_seq;
19091911
u8 validate_state;
1912+
struct work_struct destroy_work;
19101913
};
19111914

19121915
extern unsigned int nf_tables_net_id;

include/uapi/linux/netfilter/nfnetlink_conntrack.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ enum ctattr_type {
5757
CTA_SYNPROXY,
5858
CTA_FILTER,
5959
CTA_STATUS_MASK,
60+
CTA_TIMESTAMP_EVENT,
6061
__CTA_MAX
6162
};
6263
#define CTA_MAX (__CTA_MAX - 1)

net/netfilter/nf_conncount.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ static int __nf_conncount_add(struct net *net,
132132
struct nf_conn *found_ct;
133133
unsigned int collect = 0;
134134

135-
if (time_is_after_eq_jiffies((unsigned long)list->last_gc))
135+
if ((u32)jiffies == list->last_gc)
136136
goto add_new_node;
137137

138138
/* check the saved connections */
@@ -234,7 +234,7 @@ bool nf_conncount_gc_list(struct net *net,
234234
bool ret = false;
235235

236236
/* don't bother if we just did GC */
237-
if (time_is_after_eq_jiffies((unsigned long)READ_ONCE(list->last_gc)))
237+
if ((u32)jiffies == READ_ONCE(list->last_gc))
238238
return false;
239239

240240
/* don't bother if other cpu is already doing GC */
@@ -377,6 +377,8 @@ insert_tree(struct net *net,
377377

378378
conn->tuple = *tuple;
379379
conn->zone = *zone;
380+
conn->cpu = raw_smp_processor_id();
381+
conn->jiffies32 = (u32)jiffies;
380382
memcpy(rbconn->key, key, sizeof(u32) * data->keylen);
381383

382384
nf_conncount_list_init(&rbconn->list);

net/netfilter/nf_conntrack_amanda.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ static int amanda_help(struct sk_buff *skb,
106106

107107
/* increase the UDP timeout of the master connection as replies from
108108
* Amanda clients to the server can be quite delayed */
109-
nf_ct_refresh(ct, skb, master_timeout * HZ);
109+
nf_ct_refresh(ct, master_timeout * HZ);
110110

111111
/* No data? */
112112
dataoff = protoff + sizeof(struct udphdr);

net/netfilter/nf_conntrack_broadcast.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ int nf_conntrack_broadcast_help(struct sk_buff *skb,
7575
nf_ct_expect_related(exp, 0);
7676
nf_ct_expect_put(exp);
7777

78-
nf_ct_refresh(ct, skb, timeout * HZ);
78+
nf_ct_refresh(ct, timeout * HZ);
7979
out:
8080
return NF_ACCEPT;
8181
}

net/netfilter/nf_conntrack_core.c

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1544,12 +1544,6 @@ static void gc_worker(struct work_struct *work)
15441544

15451545
tmp = nf_ct_tuplehash_to_ctrack(h);
15461546

1547-
if (test_bit(IPS_OFFLOAD_BIT, &tmp->status)) {
1548-
nf_ct_offload_timeout(tmp);
1549-
if (!nf_conntrack_max95)
1550-
continue;
1551-
}
1552-
15531547
if (expired_count > GC_SCAN_EXPIRED_MAX) {
15541548
rcu_read_unlock();
15551549

@@ -2089,9 +2083,8 @@ EXPORT_SYMBOL_GPL(nf_conntrack_in);
20892083
/* Refresh conntrack for this many jiffies and do accounting if do_acct is 1 */
20902084
void __nf_ct_refresh_acct(struct nf_conn *ct,
20912085
enum ip_conntrack_info ctinfo,
2092-
const struct sk_buff *skb,
20932086
u32 extra_jiffies,
2094-
bool do_acct)
2087+
unsigned int bytes)
20952088
{
20962089
/* Only update if this is not a fixed timeout */
20972090
if (test_bit(IPS_FIXED_TIMEOUT_BIT, &ct->status))
@@ -2104,8 +2097,8 @@ void __nf_ct_refresh_acct(struct nf_conn *ct,
21042097
if (READ_ONCE(ct->timeout) != extra_jiffies)
21052098
WRITE_ONCE(ct->timeout, extra_jiffies);
21062099
acct:
2107-
if (do_acct)
2108-
nf_ct_acct_update(ct, CTINFO2DIR(ctinfo), skb->len);
2100+
if (bytes)
2101+
nf_ct_acct_update(ct, CTINFO2DIR(ctinfo), bytes);
21092102
}
21102103
EXPORT_SYMBOL_GPL(__nf_ct_refresh_acct);
21112104

net/netfilter/nf_conntrack_ecache.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,14 @@ static int __nf_conntrack_eventmask_report(struct nf_conntrack_ecache *e,
162162
return ret;
163163
}
164164

165+
static void nf_ct_ecache_tstamp_refresh(struct nf_conntrack_ecache *e)
166+
{
167+
#ifdef CONFIG_NF_CONNTRACK_TIMESTAMP
168+
if (local64_read(&e->timestamp))
169+
local64_set(&e->timestamp, ktime_get_real_ns());
170+
#endif
171+
}
172+
165173
int nf_conntrack_eventmask_report(unsigned int events, struct nf_conn *ct,
166174
u32 portid, int report)
167175
{
@@ -186,6 +194,8 @@ int nf_conntrack_eventmask_report(unsigned int events, struct nf_conn *ct,
186194
/* This is a resent of a destroy event? If so, skip missed */
187195
missed = e->portid ? 0 : e->missed;
188196

197+
nf_ct_ecache_tstamp_refresh(e);
198+
189199
ret = __nf_conntrack_eventmask_report(e, events, missed, &item);
190200
if (unlikely(ret < 0 && (events & (1 << IPCT_DESTROY)))) {
191201
/* This is a destroy event that has been triggered by a process,
@@ -297,6 +307,18 @@ void nf_conntrack_ecache_work(struct net *net, enum nf_ct_ecache_state state)
297307
}
298308
}
299309

310+
static void nf_ct_ecache_tstamp_new(const struct nf_conn *ct, struct nf_conntrack_ecache *e)
311+
{
312+
#ifdef CONFIG_NF_CONNTRACK_TIMESTAMP
313+
u64 ts = 0;
314+
315+
if (nf_ct_ext_exist(ct, NF_CT_EXT_TSTAMP))
316+
ts = ktime_get_real_ns();
317+
318+
local64_set(&e->timestamp, ts);
319+
#endif
320+
}
321+
300322
bool nf_ct_ecache_ext_add(struct nf_conn *ct, u16 ctmask, u16 expmask, gfp_t gfp)
301323
{
302324
struct net *net = nf_ct_net(ct);
@@ -326,6 +348,7 @@ bool nf_ct_ecache_ext_add(struct nf_conn *ct, u16 ctmask, u16 expmask, gfp_t gfp
326348

327349
e = nf_ct_ext_add(ct, NF_CT_EXT_ECACHE, gfp);
328350
if (e) {
351+
nf_ct_ecache_tstamp_new(ct, e);
329352
e->ctmask = ctmask;
330353
e->expmask = expmask;
331354
}

net/netfilter/nf_conntrack_h323_main.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1385,7 +1385,7 @@ static int process_rcf(struct sk_buff *skb, struct nf_conn *ct,
13851385
if (info->timeout > 0) {
13861386
pr_debug("nf_ct_ras: set RAS connection timeout to "
13871387
"%u seconds\n", info->timeout);
1388-
nf_ct_refresh(ct, skb, info->timeout * HZ);
1388+
nf_ct_refresh(ct, info->timeout * HZ);
13891389

13901390
/* Set expect timeout */
13911391
spin_lock_bh(&nf_conntrack_expect_lock);
@@ -1433,7 +1433,7 @@ static int process_urq(struct sk_buff *skb, struct nf_conn *ct,
14331433
info->sig_port[!dir] = 0;
14341434

14351435
/* Give it 30 seconds for UCF or URJ */
1436-
nf_ct_refresh(ct, skb, 30 * HZ);
1436+
nf_ct_refresh(ct, 30 * HZ);
14371437

14381438
return 0;
14391439
}

0 commit comments

Comments
 (0)