Skip to content

Commit 77bbcb6

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next
Pablo Neira Ayuso says: ==================== Netfilter updates for net-next The following patchset contains Netfilter updates for net-next. This includes one patch to update ovs and act_ct to use nf_ct_put() instead of nf_conntrack_put(). 1) Add netns_tracker to nfnetlink_log and masquerade, from Eric Dumazet. 2) Remove redundant rcu read-size lock in nf_tables packet path. 3) Replace BUG() by WARN_ON_ONCE() in nft_payload. 4) Consolidate rule verdict tracing. 5) Replace WARN_ON() by WARN_ON_ONCE() in nf_tables core. 6) Make counter support built-in in nf_tables. 7) Add new field to conntrack object to identify locally generated traffic, from Florian Westphal. 8) Prevent NAT from shadowing well-known ports, from Florian Westphal. 9) Merge nf_flow_table_{ipv4,ipv6} into nf_flow_table_inet, also from Florian. 10) Remove redundant pointer in nft_pipapo AVX2 support, from Colin Ian King. 11) Replace opencoded max() in conntrack, from Jiapeng Chong. 12) Update conntrack to use refcount_t API, from Florian Westphal. 13) Move ip_ct_attach indirection into the nf_ct_hook structure. 14) Constify several pointer object in the netfilter codebase, from Florian Westphal. 15) Tree-wide replacement of nf_conntrack_put() by nf_ct_put(), also from Florian. 16) Fix egress splat due to incorrect rcu notation, from Florian. 17) Move stateful fields of connlimit, last, quota, numgen and limit out of the expression data area. 18) Build a blob to represent the ruleset in nf_tables, this is a requirement of the new register tracking infrastructure. 19) Add NFT_REG32_NUM to define the maximum number of 32-bit registers. 20) Add register tracking infrastructure to skip redundant store-to-register operations, this includes support for payload, meta and bitwise expresssions. * git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next: (32 commits) netfilter: nft_meta: cancel register tracking after meta update netfilter: nft_payload: cancel register tracking after payload update netfilter: nft_bitwise: track register operations netfilter: nft_meta: track register operations netfilter: nft_payload: track register operations netfilter: nf_tables: add register tracking infrastructure netfilter: nf_tables: add NFT_REG32_NUM netfilter: nf_tables: add rule blob layout netfilter: nft_limit: move stateful fields out of expression data netfilter: nft_limit: rename stateful structure netfilter: nft_numgen: move stateful fields out of expression data netfilter: nft_quota: move stateful fields out of expression data netfilter: nft_last: move stateful fields out of expression data netfilter: nft_connlimit: move stateful fields out of expression data netfilter: egress: avoid a lockdep splat net: prefer nf_ct_put instead of nf_conntrack_put netfilter: conntrack: avoid useless indirection during conntrack destruction netfilter: make function op structures const netfilter: core: move ip_ct_attach indirection to struct nf_ct_hook netfilter: conntrack: convert to refcount_t api ... ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents 9f3248c + 4a80e02 commit 77bbcb6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+887
-404
lines changed

include/linux/netfilter.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -381,13 +381,13 @@ struct nf_nat_hook {
381381
enum ip_conntrack_dir dir);
382382
};
383383

384-
extern struct nf_nat_hook __rcu *nf_nat_hook;
384+
extern const struct nf_nat_hook __rcu *nf_nat_hook;
385385

386386
static inline void
387387
nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, u_int8_t family)
388388
{
389389
#if IS_ENABLED(CONFIG_NF_NAT)
390-
struct nf_nat_hook *nat_hook;
390+
const struct nf_nat_hook *nat_hook;
391391

392392
rcu_read_lock();
393393
nat_hook = rcu_dereference(nf_nat_hook);
@@ -440,7 +440,6 @@ nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, u_int8_t family)
440440
#if IS_ENABLED(CONFIG_NF_CONNTRACK)
441441
#include <linux/netfilter/nf_conntrack_zones_common.h>
442442

443-
extern void (*ip_ct_attach)(struct sk_buff *, const struct sk_buff *) __rcu;
444443
void nf_ct_attach(struct sk_buff *, const struct sk_buff *);
445444
struct nf_conntrack_tuple;
446445
bool nf_ct_get_tuple_skb(struct nf_conntrack_tuple *dst_tuple,
@@ -463,8 +462,9 @@ struct nf_ct_hook {
463462
void (*destroy)(struct nf_conntrack *);
464463
bool (*get_tuple_skb)(struct nf_conntrack_tuple *,
465464
const struct sk_buff *);
465+
void (*attach)(struct sk_buff *nskb, const struct sk_buff *skb);
466466
};
467-
extern struct nf_ct_hook __rcu *nf_ct_hook;
467+
extern const struct nf_ct_hook __rcu *nf_ct_hook;
468468

469469
struct nlattr;
470470

@@ -479,7 +479,7 @@ struct nfnl_ct_hook {
479479
void (*seq_adjust)(struct sk_buff *skb, struct nf_conn *ct,
480480
enum ip_conntrack_info ctinfo, s32 off);
481481
};
482-
extern struct nfnl_ct_hook __rcu *nfnl_ct_hook;
482+
extern const struct nfnl_ct_hook __rcu *nfnl_ct_hook;
483483

484484
/**
485485
* nf_skb_duplicated - TEE target has sent a packet

include/linux/netfilter/nf_conntrack_common.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#ifndef _NF_CONNTRACK_COMMON_H
33
#define _NF_CONNTRACK_COMMON_H
44

5-
#include <linux/atomic.h>
5+
#include <linux/refcount.h>
66
#include <uapi/linux/netfilter/nf_conntrack_common.h>
77

88
struct ip_conntrack_stat {
@@ -25,19 +25,21 @@ struct ip_conntrack_stat {
2525
#define NFCT_PTRMASK ~(NFCT_INFOMASK)
2626

2727
struct nf_conntrack {
28-
atomic_t use;
28+
refcount_t use;
2929
};
3030

3131
void nf_conntrack_destroy(struct nf_conntrack *nfct);
32+
33+
/* like nf_ct_put, but without module dependency on nf_conntrack */
3234
static inline void nf_conntrack_put(struct nf_conntrack *nfct)
3335
{
34-
if (nfct && atomic_dec_and_test(&nfct->use))
36+
if (nfct && refcount_dec_and_test(&nfct->use))
3537
nf_conntrack_destroy(nfct);
3638
}
3739
static inline void nf_conntrack_get(struct nf_conntrack *nfct)
3840
{
3941
if (nfct)
40-
atomic_inc(&nfct->use);
42+
refcount_inc(&nfct->use);
4143
}
4244

4345
#endif /* _NF_CONNTRACK_COMMON_H */

include/linux/netfilter_netdev.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ static inline struct sk_buff *nf_hook_egress(struct sk_buff *skb, int *rc,
9494
return skb;
9595
#endif
9696

97-
e = rcu_dereference(dev->nf_hooks_egress);
97+
e = rcu_dereference_check(dev->nf_hooks_egress, rcu_read_lock_bh_held());
9898
if (!e)
9999
return skb;
100100

include/net/netfilter/nf_conntrack.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ struct nf_conn {
7676
* Hint, SKB address this struct and refcnt via skb->_nfct and
7777
* helpers nf_conntrack_get() and nf_conntrack_put().
7878
* Helper nf_ct_put() equals nf_conntrack_put() by dec refcnt,
79+
* except that the latter uses internal indirection and does not
80+
* result in a conntrack module dependency.
7981
* beware nf_ct_get() is different and don't inc refcnt.
8082
*/
8183
struct nf_conntrack ct_general;
@@ -95,6 +97,7 @@ struct nf_conn {
9597
unsigned long status;
9698

9799
u16 cpu;
100+
u16 local_origin:1;
98101
possible_net_t ct_net;
99102

100103
#if IS_ENABLED(CONFIG_NF_NAT)
@@ -169,11 +172,13 @@ nf_ct_get(const struct sk_buff *skb, enum ip_conntrack_info *ctinfo)
169172
return (struct nf_conn *)(nfct & NFCT_PTRMASK);
170173
}
171174

175+
void nf_ct_destroy(struct nf_conntrack *nfct);
176+
172177
/* decrement reference count on a conntrack */
173178
static inline void nf_ct_put(struct nf_conn *ct)
174179
{
175-
WARN_ON(!ct);
176-
nf_conntrack_put(&ct->ct_general);
180+
if (ct && refcount_dec_and_test(&ct->ct_general.use))
181+
nf_ct_destroy(&ct->ct_general);
177182
}
178183

179184
/* Protocol module loading */
@@ -278,7 +283,7 @@ static inline unsigned long nf_ct_expires(const struct nf_conn *ct)
278283
{
279284
s32 timeout = READ_ONCE(ct->timeout) - nfct_time_stamp;
280285

281-
return timeout > 0 ? timeout : 0;
286+
return max(timeout, 0);
282287
}
283288

284289
static inline bool nf_ct_is_expired(const struct nf_conn *ct)

include/net/netfilter/nf_tables.h

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ struct nft_data {
105105
};
106106
} __attribute__((aligned(__alignof__(u64))));
107107

108+
#define NFT_REG32_NUM 20
109+
108110
/**
109111
* struct nft_regs - nf_tables register set
110112
*
@@ -115,11 +117,21 @@ struct nft_data {
115117
*/
116118
struct nft_regs {
117119
union {
118-
u32 data[20];
120+
u32 data[NFT_REG32_NUM];
119121
struct nft_verdict verdict;
120122
};
121123
};
122124

125+
struct nft_regs_track {
126+
struct {
127+
const struct nft_expr *selector;
128+
const struct nft_expr *bitwise;
129+
} regs[NFT_REG32_NUM];
130+
131+
const struct nft_expr *cur;
132+
const struct nft_expr *last;
133+
};
134+
123135
/* Store/load an u8, u16 or u64 integer to/from the u32 data register.
124136
*
125137
* Note, when using concatenations, register allocation happens at 32-bit
@@ -346,6 +358,8 @@ int nft_expr_clone(struct nft_expr *dst, struct nft_expr *src);
346358
void nft_expr_destroy(const struct nft_ctx *ctx, struct nft_expr *expr);
347359
int nft_expr_dump(struct sk_buff *skb, unsigned int attr,
348360
const struct nft_expr *expr);
361+
bool nft_expr_reduce_bitwise(struct nft_regs_track *track,
362+
const struct nft_expr *expr);
349363

350364
struct nft_set_ext;
351365

@@ -884,6 +898,8 @@ struct nft_expr_ops {
884898
int (*validate)(const struct nft_ctx *ctx,
885899
const struct nft_expr *expr,
886900
const struct nft_data **data);
901+
bool (*reduce)(struct nft_regs_track *track,
902+
const struct nft_expr *expr);
887903
bool (*gc)(struct net *net,
888904
const struct nft_expr *expr);
889905
int (*offload)(struct nft_offload_ctx *ctx,
@@ -974,6 +990,20 @@ static inline void nft_set_elem_update_expr(const struct nft_set_ext *ext,
974990

975991
#define NFT_CHAIN_POLICY_UNSET U8_MAX
976992

993+
struct nft_rule_dp {
994+
u64 is_last:1,
995+
dlen:12,
996+
handle:42; /* for tracing */
997+
unsigned char data[]
998+
__attribute__((aligned(__alignof__(struct nft_expr))));
999+
};
1000+
1001+
struct nft_rule_blob {
1002+
unsigned long size;
1003+
unsigned char data[]
1004+
__attribute__((aligned(__alignof__(struct nft_rule_dp))));
1005+
};
1006+
9771007
/**
9781008
* struct nft_chain - nf_tables chain
9791009
*
@@ -987,8 +1017,8 @@ static inline void nft_set_elem_update_expr(const struct nft_set_ext *ext,
9871017
* @name: name of the chain
9881018
*/
9891019
struct nft_chain {
990-
struct nft_rule *__rcu *rules_gen_0;
991-
struct nft_rule *__rcu *rules_gen_1;
1020+
struct nft_rule_blob __rcu *blob_gen_0;
1021+
struct nft_rule_blob __rcu *blob_gen_1;
9921022
struct list_head rules;
9931023
struct list_head list;
9941024
struct rhlist_head rhlhead;
@@ -1003,7 +1033,7 @@ struct nft_chain {
10031033
u8 *udata;
10041034

10051035
/* Only used during control plane commit phase: */
1006-
struct nft_rule **rules_next;
1036+
struct nft_rule_blob *blob_next;
10071037
};
10081038

10091039
int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain);
@@ -1321,7 +1351,7 @@ struct nft_traceinfo {
13211351
const struct nft_pktinfo *pkt;
13221352
const struct nft_base_chain *basechain;
13231353
const struct nft_chain *chain;
1324-
const struct nft_rule *rule;
1354+
const struct nft_rule_dp *rule;
13251355
const struct nft_verdict *verdict;
13261356
enum nft_trace_types type;
13271357
bool packet_dumped;

include/net/netfilter/nf_tables_core.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
extern struct nft_expr_type nft_imm_type;
99
extern struct nft_expr_type nft_cmp_type;
10+
extern struct nft_expr_type nft_counter_type;
1011
extern struct nft_expr_type nft_lookup_type;
1112
extern struct nft_expr_type nft_bitwise_type;
1213
extern struct nft_expr_type nft_byteorder_type;
@@ -21,6 +22,7 @@ extern struct nft_expr_type nft_last_type;
2122
#ifdef CONFIG_NETWORK_SECMARK
2223
extern struct nft_object_type nft_secmark_obj_type;
2324
#endif
25+
extern struct nft_object_type nft_counter_obj_type;
2426

2527
int nf_tables_core_module_init(void);
2628
void nf_tables_core_module_exit(void);
@@ -120,6 +122,8 @@ bool nft_pipapo_lookup(const struct net *net, const struct nft_set *set,
120122
bool nft_pipapo_avx2_lookup(const struct net *net, const struct nft_set *set,
121123
const u32 *key, const struct nft_set_ext **ext);
122124

125+
void nft_counter_init_seqcount(void);
126+
123127
struct nft_expr;
124128
struct nft_regs;
125129
struct nft_pktinfo;
@@ -143,4 +147,6 @@ void nft_dynset_eval(const struct nft_expr *expr,
143147
struct nft_regs *regs, const struct nft_pktinfo *pkt);
144148
void nft_rt_get_eval(const struct nft_expr *expr,
145149
struct nft_regs *regs, const struct nft_pktinfo *pkt);
150+
void nft_counter_eval(const struct nft_expr *expr, struct nft_regs *regs,
151+
const struct nft_pktinfo *pkt);
146152
#endif /* _NET_NF_TABLES_CORE_H */

net/bridge/netfilter/nft_meta_bridge.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,13 +100,33 @@ static const struct nft_expr_ops nft_meta_bridge_get_ops = {
100100
.dump = nft_meta_get_dump,
101101
};
102102

103+
static bool nft_meta_bridge_set_reduce(struct nft_regs_track *track,
104+
const struct nft_expr *expr)
105+
{
106+
int i;
107+
108+
for (i = 0; i < NFT_REG32_NUM; i++) {
109+
if (!track->regs[i].selector)
110+
continue;
111+
112+
if (track->regs[i].selector->ops != &nft_meta_bridge_get_ops)
113+
continue;
114+
115+
track->regs[i].selector = NULL;
116+
track->regs[i].bitwise = NULL;
117+
}
118+
119+
return false;
120+
}
121+
103122
static const struct nft_expr_ops nft_meta_bridge_set_ops = {
104123
.type = &nft_meta_bridge_type,
105124
.size = NFT_EXPR_SIZE(sizeof(struct nft_meta)),
106125
.eval = nft_meta_set_eval,
107126
.init = nft_meta_set_init,
108127
.destroy = nft_meta_set_destroy,
109128
.dump = nft_meta_set_dump,
129+
.reduce = nft_meta_bridge_set_reduce,
110130
.validate = nft_meta_set_validate,
111131
};
112132

net/ipv4/netfilter/Kconfig

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,8 @@ config NF_TABLES_ARP
5959
endif # NF_TABLES
6060

6161
config NF_FLOW_TABLE_IPV4
62-
tristate "Netfilter flow table IPv4 module"
63-
depends on NF_FLOW_TABLE
64-
help
65-
This option adds the flow table IPv4 support.
66-
67-
To compile it as a module, choose M here.
62+
tristate
63+
select NF_FLOW_TABLE_INET
6864

6965
config NF_DUP_IPV4
7066
tristate "Netfilter IPv4 packet duplication to alternate destination"

net/ipv4/netfilter/Makefile

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@ obj-$(CONFIG_NFT_REJECT_IPV4) += nft_reject_ipv4.o
2424
obj-$(CONFIG_NFT_FIB_IPV4) += nft_fib_ipv4.o
2525
obj-$(CONFIG_NFT_DUP_IPV4) += nft_dup_ipv4.o
2626

27-
# flow table support
28-
obj-$(CONFIG_NF_FLOW_TABLE_IPV4) += nf_flow_table_ipv4.o
29-
3027
# generic IP tables
3128
obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o
3229

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +0,0 @@
1-
// SPDX-License-Identifier: GPL-2.0-only
2-
#include <linux/kernel.h>
3-
#include <linux/init.h>
4-
#include <linux/module.h>
5-
#include <linux/netfilter.h>
6-
#include <net/netfilter/nf_flow_table.h>
7-
#include <net/netfilter/nf_tables.h>
8-
9-
static struct nf_flowtable_type flowtable_ipv4 = {
10-
.family = NFPROTO_IPV4,
11-
.init = nf_flow_table_init,
12-
.setup = nf_flow_table_offload_setup,
13-
.action = nf_flow_rule_route_ipv4,
14-
.free = nf_flow_table_free,
15-
.hook = nf_flow_offload_ip_hook,
16-
.owner = THIS_MODULE,
17-
};
18-
19-
static int __init nf_flow_ipv4_module_init(void)
20-
{
21-
nft_register_flowtable_type(&flowtable_ipv4);
22-
23-
return 0;
24-
}
25-
26-
static void __exit nf_flow_ipv4_module_exit(void)
27-
{
28-
nft_unregister_flowtable_type(&flowtable_ipv4);
29-
}
30-
31-
module_init(nf_flow_ipv4_module_init);
32-
module_exit(nf_flow_ipv4_module_exit);
33-
34-
MODULE_LICENSE("GPL");
35-
MODULE_AUTHOR("Pablo Neira Ayuso <[email protected]>");
36-
MODULE_ALIAS_NF_FLOWTABLE(AF_INET);
37-
MODULE_DESCRIPTION("Netfilter flow table support");

net/ipv6/netfilter/Kconfig

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,8 @@ endif # NF_TABLES_IPV6
4848
endif # NF_TABLES
4949

5050
config NF_FLOW_TABLE_IPV6
51-
tristate "Netfilter flow table IPv6 module"
52-
depends on NF_FLOW_TABLE
53-
help
54-
This option adds the flow table IPv6 support.
55-
56-
To compile it as a module, choose M here.
51+
tristate
52+
select NF_FLOW_TABLE_INET
5753

5854
config NF_DUP_IPV6
5955
tristate "Netfilter IPv6 packet duplication to alternate destination"

0 commit comments

Comments
 (0)