Skip to content

Commit f723224

Browse files
committed
Merge tag 'nf-next-24-09-06' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next
Pablo Neira Ayuso says: ==================== Netfilter updates for net-next The following patchset contains Netfilter updates for net-next: Patch kernel-patches#1 adds ctnetlink support for kernel side filtering for deletions, from Changliang Wu. Patch kernel-patches#2 updates nft_counter support to Use u64_stats_t, from Sebastian Andrzej Siewior. Patch kernel-patches#3 uses kmemdup_array() in all xtables frontends, from Yan Zhen. Patch kernel-patches#4 is a oneliner to use ERR_CAST() in nf_conntrack instead opencoded casting, from Shen Lichuan. Patch kernel-patches#5 removes unused argument in nftables .validate interface, from Florian Westphal. Patch kernel-patches#6 is a oneliner to correct a typo in nftables kdoc, from Simon Horman. Patch kernel-patches#7 fixes missing kdoc in nftables, also from Simon. Patch kernel-patches#8 updates nftables to handle timeout less than CONFIG_HZ. Patch kernel-patches#9 rejects element expiration if timeout is zero, otherwise it is silently ignored. Patch kernel-patches#10 disallows element expiration larger than timeout. Patch kernel-patches#11 removes unnecessary READ_ONCE annotation while mutex is held. Patch kernel-patches#12 adds missing READ_ONCE/WRITE_ONCE annotation in dynset. Patch kernel-patches#13 annotates data-races around element expiration. Patch kernel-patches#14 allocates timeout and expiration in one single set element extension, they are tighly couple, no reason to keep them separated anymore. Patch kernel-patches#15 updates nftables to interpret zero timeout element as never times out. Note that it is already possible to declare sets with elements that never time out but this generalizes to all kind of set with timeouts. Patch kernel-patches#16 supports for element timeout and expiration updates. * tag 'nf-next-24-09-06' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next: netfilter: nf_tables: set element timeout update support netfilter: nf_tables: zero timeout means element never times out netfilter: nf_tables: consolidate timeout extension for elements netfilter: nf_tables: annotate data-races around element expiration netfilter: nft_dynset: annotate data-races around set timeout netfilter: nf_tables: remove annotation to access set timeout while holding lock netfilter: nf_tables: reject expiration higher than timeout netfilter: nf_tables: reject element expiration with no timeout netfilter: nf_tables: elements with timeout below CONFIG_HZ never expire netfilter: nf_tables: Add missing Kernel doc netfilter: nf_tables: Correct spelling in nf_tables.h netfilter: nf_tables: drop unused 3rd argument from validate callback ops netfilter: conntrack: Convert to use ERR_CAST() netfilter: Use kmemdup_array instead of kmemdup for multiple allocation netfilter: nft_counter: Use u64_stats_t for statistic. netfilter: ctnetlink: support CTA_FILTER for flush ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents aa05fe6 + 4201f39 commit f723224

38 files changed

+206
-178
lines changed

include/net/netfilter/nf_tables.h

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ static inline void nft_data_copy(u32 *dst, const struct nft_data *src,
209209
* @family: protocol family
210210
* @level: depth of the chains
211211
* @report: notify via unicast netlink message
212+
* @reg_inited: bitmap of initialised registers
212213
*/
213214
struct nft_ctx {
214215
struct net *net;
@@ -313,6 +314,7 @@ static inline void *nft_elem_priv_cast(const struct nft_elem_priv *priv)
313314
/**
314315
* enum nft_iter_type - nftables set iterator type
315316
*
317+
* @NFT_ITER_UNSPEC: unspecified, to catch errors
316318
* @NFT_ITER_READ: read-only iteration over set elements
317319
* @NFT_ITER_UPDATE: iteration under mutex to update set element state
318320
*/
@@ -685,9 +687,8 @@ void nf_tables_destroy_set(const struct nft_ctx *ctx, struct nft_set *set);
685687
* @NFT_SET_EXT_DATA: mapping data
686688
* @NFT_SET_EXT_FLAGS: element flags
687689
* @NFT_SET_EXT_TIMEOUT: element timeout
688-
* @NFT_SET_EXT_EXPIRATION: element expiration time
689690
* @NFT_SET_EXT_USERDATA: user data associated with the element
690-
* @NFT_SET_EXT_EXPRESSIONS: expressions assiciated with the element
691+
* @NFT_SET_EXT_EXPRESSIONS: expressions associated with the element
691692
* @NFT_SET_EXT_OBJREF: stateful object reference associated with element
692693
* @NFT_SET_EXT_NUM: number of extension types
693694
*/
@@ -697,7 +698,6 @@ enum nft_set_extensions {
697698
NFT_SET_EXT_DATA,
698699
NFT_SET_EXT_FLAGS,
699700
NFT_SET_EXT_TIMEOUT,
700-
NFT_SET_EXT_EXPIRATION,
701701
NFT_SET_EXT_USERDATA,
702702
NFT_SET_EXT_EXPRESSIONS,
703703
NFT_SET_EXT_OBJREF,
@@ -809,14 +809,14 @@ static inline u8 *nft_set_ext_flags(const struct nft_set_ext *ext)
809809
return nft_set_ext(ext, NFT_SET_EXT_FLAGS);
810810
}
811811

812-
static inline u64 *nft_set_ext_timeout(const struct nft_set_ext *ext)
813-
{
814-
return nft_set_ext(ext, NFT_SET_EXT_TIMEOUT);
815-
}
812+
struct nft_timeout {
813+
u64 timeout;
814+
u64 expiration;
815+
};
816816

817-
static inline u64 *nft_set_ext_expiration(const struct nft_set_ext *ext)
817+
static inline struct nft_timeout *nft_set_ext_timeout(const struct nft_set_ext *ext)
818818
{
819-
return nft_set_ext(ext, NFT_SET_EXT_EXPIRATION);
819+
return nft_set_ext(ext, NFT_SET_EXT_TIMEOUT);
820820
}
821821

822822
static inline struct nft_userdata *nft_set_ext_userdata(const struct nft_set_ext *ext)
@@ -832,8 +832,11 @@ static inline struct nft_set_elem_expr *nft_set_ext_expr(const struct nft_set_ex
832832
static inline bool __nft_set_elem_expired(const struct nft_set_ext *ext,
833833
u64 tstamp)
834834
{
835-
return nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION) &&
836-
time_after_eq64(tstamp, *nft_set_ext_expiration(ext));
835+
if (!nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT) ||
836+
READ_ONCE(nft_set_ext_timeout(ext)->timeout) == 0)
837+
return false;
838+
839+
return time_after_eq64(tstamp, READ_ONCE(nft_set_ext_timeout(ext)->expiration));
837840
}
838841

839842
static inline bool nft_set_elem_expired(const struct nft_set_ext *ext)
@@ -961,8 +964,7 @@ struct nft_expr_ops {
961964
const struct nft_expr *expr,
962965
bool reset);
963966
int (*validate)(const struct nft_ctx *ctx,
964-
const struct nft_expr *expr,
965-
const struct nft_data **data);
967+
const struct nft_expr *expr);
966968
bool (*reduce)(struct nft_regs_track *track,
967969
const struct nft_expr *expr);
968970
bool (*gc)(struct net *net,
@@ -1747,10 +1749,18 @@ struct nft_trans_table {
17471749
#define nft_trans_table_update(trans) \
17481750
nft_trans_container_table(trans)->update
17491751

1752+
enum nft_trans_elem_flags {
1753+
NFT_TRANS_UPD_TIMEOUT = (1 << 0),
1754+
NFT_TRANS_UPD_EXPIRATION = (1 << 1),
1755+
};
1756+
17501757
struct nft_trans_elem {
17511758
struct nft_trans nft_trans;
17521759
struct nft_set *set;
17531760
struct nft_elem_priv *elem_priv;
1761+
u64 timeout;
1762+
u64 expiration;
1763+
u8 update_flags;
17541764
bool bound;
17551765
};
17561766

@@ -1760,6 +1770,12 @@ struct nft_trans_elem {
17601770
nft_trans_container_elem(trans)->set
17611771
#define nft_trans_elem_priv(trans) \
17621772
nft_trans_container_elem(trans)->elem_priv
1773+
#define nft_trans_elem_update_flags(trans) \
1774+
nft_trans_container_elem(trans)->update_flags
1775+
#define nft_trans_elem_timeout(trans) \
1776+
nft_trans_container_elem(trans)->timeout
1777+
#define nft_trans_elem_expiration(trans) \
1778+
nft_trans_container_elem(trans)->expiration
17631779
#define nft_trans_elem_set_bound(trans) \
17641780
nft_trans_container_elem(trans)->bound
17651781

include/net/netfilter/nf_tproxy.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ __be32 nf_tproxy_laddr4(struct sk_buff *skb, __be32 user_laddr, __be32 daddr);
3636

3737
/**
3838
* nf_tproxy_handle_time_wait4 - handle IPv4 TCP TIME_WAIT reopen redirections
39+
* @net: The network namespace.
3940
* @skb: The skb being processed.
4041
* @laddr: IPv4 address to redirect to or zero.
4142
* @lport: TCP port to redirect to or zero.

include/net/netfilter/nft_fib.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,7 @@ nft_fib_is_loopback(const struct sk_buff *skb, const struct net_device *in)
2121
int nft_fib_dump(struct sk_buff *skb, const struct nft_expr *expr, bool reset);
2222
int nft_fib_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
2323
const struct nlattr * const tb[]);
24-
int nft_fib_validate(const struct nft_ctx *ctx, const struct nft_expr *expr,
25-
const struct nft_data **data);
26-
24+
int nft_fib_validate(const struct nft_ctx *ctx, const struct nft_expr *expr);
2725

2826
void nft_fib4_eval_type(const struct nft_expr *expr, struct nft_regs *regs,
2927
const struct nft_pktinfo *pkt);

include/net/netfilter/nft_meta.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,7 @@ void nft_meta_set_destroy(const struct nft_ctx *ctx,
4141
const struct nft_expr *expr);
4242

4343
int nft_meta_set_validate(const struct nft_ctx *ctx,
44-
const struct nft_expr *expr,
45-
const struct nft_data **data);
44+
const struct nft_expr *expr);
4645

4746
bool nft_meta_get_reduce(struct nft_regs_track *track,
4847
const struct nft_expr *expr);

include/net/netfilter/nft_reject.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ struct nft_reject {
1515
extern const struct nla_policy nft_reject_policy[];
1616

1717
int nft_reject_validate(const struct nft_ctx *ctx,
18-
const struct nft_expr *expr,
19-
const struct nft_data **data);
18+
const struct nft_expr *expr);
2019

2120
int nft_reject_init(const struct nft_ctx *ctx,
2221
const struct nft_expr *expr,

include/uapi/linux/netfilter/nf_tables.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ enum nft_set_elem_flags {
436436
* @NFTA_SET_ELEM_KEY: key value (NLA_NESTED: nft_data)
437437
* @NFTA_SET_ELEM_DATA: data value of mapping (NLA_NESTED: nft_data_attributes)
438438
* @NFTA_SET_ELEM_FLAGS: bitmask of nft_set_elem_flags (NLA_U32)
439-
* @NFTA_SET_ELEM_TIMEOUT: timeout value (NLA_U64)
439+
* @NFTA_SET_ELEM_TIMEOUT: timeout value, zero means never times out (NLA_U64)
440440
* @NFTA_SET_ELEM_EXPIRATION: expiration time (NLA_U64)
441441
* @NFTA_SET_ELEM_USERDATA: user data (NLA_BINARY)
442442
* @NFTA_SET_ELEM_EXPR: expression (NLA_NESTED: nft_expr_attributes)

net/bridge/netfilter/ebtables.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1256,7 +1256,7 @@ int ebt_register_table(struct net *net, const struct ebt_table *input_table,
12561256
goto free_unlock;
12571257
}
12581258

1259-
ops = kmemdup(template_ops, sizeof(*ops) * num_ops, GFP_KERNEL);
1259+
ops = kmemdup_array(template_ops, num_ops, sizeof(*ops), GFP_KERNEL);
12601260
if (!ops) {
12611261
ret = -ENOMEM;
12621262
if (newinfo->nentries)

net/bridge/netfilter/nft_meta_bridge.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,7 @@ static bool nft_meta_bridge_set_reduce(struct nft_regs_track *track,
168168
}
169169

170170
static int nft_meta_bridge_set_validate(const struct nft_ctx *ctx,
171-
const struct nft_expr *expr,
172-
const struct nft_data **data)
171+
const struct nft_expr *expr)
173172
{
174173
struct nft_meta *priv = nft_expr_priv(expr);
175174
unsigned int hooks;
@@ -179,7 +178,7 @@ static int nft_meta_bridge_set_validate(const struct nft_ctx *ctx,
179178
hooks = 1 << NF_BR_PRE_ROUTING;
180179
break;
181180
default:
182-
return nft_meta_set_validate(ctx, expr, data);
181+
return nft_meta_set_validate(ctx, expr);
183182
}
184183

185184
return nft_chain_validate_hooks(ctx->chain, hooks);

net/bridge/netfilter/nft_reject_bridge.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,7 @@ static void nft_reject_bridge_eval(const struct nft_expr *expr,
170170
}
171171

172172
static int nft_reject_bridge_validate(const struct nft_ctx *ctx,
173-
const struct nft_expr *expr,
174-
const struct nft_data **data)
173+
const struct nft_expr *expr)
175174
{
176175
return nft_chain_validate_hooks(ctx->chain, (1 << NF_BR_PRE_ROUTING) |
177176
(1 << NF_BR_LOCAL_IN));

net/ipv4/netfilter/arp_tables.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1547,7 +1547,7 @@ int arpt_register_table(struct net *net,
15471547
goto out_free;
15481548
}
15491549

1550-
ops = kmemdup(template_ops, sizeof(*ops) * num_ops, GFP_KERNEL);
1550+
ops = kmemdup_array(template_ops, num_ops, sizeof(*ops), GFP_KERNEL);
15511551
if (!ops) {
15521552
ret = -ENOMEM;
15531553
goto out_free;

net/ipv4/netfilter/ip_tables.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1767,7 +1767,7 @@ int ipt_register_table(struct net *net, const struct xt_table *table,
17671767
goto out_free;
17681768
}
17691769

1770-
ops = kmemdup(template_ops, sizeof(*ops) * num_ops, GFP_KERNEL);
1770+
ops = kmemdup_array(template_ops, num_ops, sizeof(*ops), GFP_KERNEL);
17711771
if (!ops) {
17721772
ret = -ENOMEM;
17731773
goto out_free;

net/ipv6/netfilter/ip6_tables.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1773,7 +1773,7 @@ int ip6t_register_table(struct net *net, const struct xt_table *table,
17731773
goto out_free;
17741774
}
17751775

1776-
ops = kmemdup(template_ops, sizeof(*ops) * num_ops, GFP_KERNEL);
1776+
ops = kmemdup_array(template_ops, num_ops, sizeof(*ops), GFP_KERNEL);
17771777
if (!ops) {
17781778
ret = -ENOMEM;
17791779
goto out_free;

net/netfilter/nf_conntrack_core.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1722,7 +1722,7 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
17221722
ct = __nf_conntrack_alloc(net, zone, tuple, &repl_tuple, GFP_ATOMIC,
17231723
hash);
17241724
if (IS_ERR(ct))
1725-
return (struct nf_conntrack_tuple_hash *)ct;
1725+
return ERR_CAST(ct);
17261726

17271727
if (!nf_ct_add_synproxy(ct, tmpl)) {
17281728
nf_conntrack_free(ct);

net/netfilter/nf_conntrack_netlink.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1579,9 +1579,6 @@ static int ctnetlink_flush_conntrack(struct net *net,
15791579
};
15801580

15811581
if (ctnetlink_needs_filter(family, cda)) {
1582-
if (cda[CTA_FILTER])
1583-
return -EOPNOTSUPP;
1584-
15851582
filter = ctnetlink_alloc_filter(cda, family);
15861583
if (IS_ERR(filter))
15871584
return PTR_ERR(filter);
@@ -1610,14 +1607,14 @@ static int ctnetlink_del_conntrack(struct sk_buff *skb,
16101607
if (err < 0)
16111608
return err;
16121609

1613-
if (cda[CTA_TUPLE_ORIG])
1610+
if (cda[CTA_TUPLE_ORIG] && !cda[CTA_FILTER])
16141611
err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG,
16151612
family, &zone);
1616-
else if (cda[CTA_TUPLE_REPLY])
1613+
else if (cda[CTA_TUPLE_REPLY] && !cda[CTA_FILTER])
16171614
err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_REPLY,
16181615
family, &zone);
16191616
else {
1620-
u_int8_t u3 = info->nfmsg->version ? family : AF_UNSPEC;
1617+
u8 u3 = info->nfmsg->version || cda[CTA_FILTER] ? family : AF_UNSPEC;
16211618

16221619
return ctnetlink_flush_conntrack(info->net, cda,
16231620
NETLINK_CB(skb).portid,

net/netfilter/nf_nat_core.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1104,7 +1104,7 @@ int nf_nat_register_fn(struct net *net, u8 pf, const struct nf_hook_ops *ops,
11041104
if (!nat_proto_net->nat_hook_ops) {
11051105
WARN_ON(nat_proto_net->users != 0);
11061106

1107-
nat_ops = kmemdup(orig_nat_ops, sizeof(*orig_nat_ops) * ops_count, GFP_KERNEL);
1107+
nat_ops = kmemdup_array(orig_nat_ops, ops_count, sizeof(*orig_nat_ops), GFP_KERNEL);
11081108
if (!nat_ops) {
11091109
mutex_unlock(&nf_nat_proto_mutex);
11101110
return -ENOMEM;

0 commit comments

Comments
 (0)