Skip to content

Commit c85e41b

Browse files
committed
Merge tag 'nf-next-24-05-12' 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 #1 skips transaction if object type provides no .update interface. Patch #2 skips NETDEV_CHANGENAME which is unused. Patch #3 enables conntrack to handle Multicast Router Advertisements and Multicast Router Solicitations from the Multicast Router Discovery protocol (RFC4286) as untracked opposed to invalid packets. From Linus Luessing. Patch #4 updates DCCP conntracker to mark invalid as invalid, instead of dropping them, from Jason Xing. Patch #5 uses NF_DROP instead of -NF_DROP since NF_DROP is 0, also from Jason. Patch #6 removes reference in netfilter's sysctl documentation on pickup entries which were already removed by Florian Westphal. Patch #7 removes check for IPS_OFFLOAD flag to disable early drop which allows to evict entries from the conntrack table, also from Florian. Patches #8 to #16 updates nf_tables pipapo set backend to allocate the datastructure copy on-demand from preparation phase, to better deal with OOM situations where .commit step is too late to fail. Series from Florian Westphal. Patch #17 adds a selftest with packetdrill to cover conntrack TCP state transitions, also from Florian. Patch #18 use GFP_KERNEL to clone elements from control plane to avoid quick atomic reserves exhaustion with large sets, reporter refers to million entries magnitude. * tag 'nf-next-24-05-12' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next: netfilter: nf_tables: allow clone callbacks to sleep selftests: netfilter: add packetdrill based conntrack tests netfilter: nft_set_pipapo: remove dirty flag netfilter: nft_set_pipapo: move cloning of match info to insert/removal path netfilter: nft_set_pipapo: prepare pipapo_get helper for on-demand clone netfilter: nft_set_pipapo: merge deactivate helper into caller netfilter: nft_set_pipapo: prepare walk function for on-demand clone netfilter: nft_set_pipapo: prepare destroy function for on-demand clone netfilter: nft_set_pipapo: make pipapo_clone helper return NULL netfilter: nft_set_pipapo: move prove_locking helper around netfilter: conntrack: remove flowtable early-drop test netfilter: conntrack: documentation: remove reference to non-existent sysctl netfilter: use NF_DROP instead of -NF_DROP netfilter: conntrack: dccp: try not to drop skb in conntrack netfilter: conntrack: fix ct-state for ICMPv6 Multicast Router Discovery netfilter: nf_tables: remove NETDEV_CHANGENAME from netdev chain event handler netfilter: nf_tables: skip transaction if update object is not implemented ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents cddd2dc + fa23e0d commit c85e41b

28 files changed

+639
-175
lines changed

Documentation/networking/nf_conntrack-sysctl.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,11 +222,11 @@ nf_flowtable_tcp_timeout - INTEGER (seconds)
222222

223223
Control offload timeout for tcp connections.
224224
TCP connections may be offloaded from nf conntrack to nf flow table.
225-
Once aged, the connection is returned to nf conntrack with tcp pickup timeout.
225+
Once aged, the connection is returned to nf conntrack.
226226

227227
nf_flowtable_udp_timeout - INTEGER (seconds)
228228
default 30
229229

230230
Control offload timeout for udp connections.
231231
UDP connections may be offloaded from nf conntrack to nf flow table.
232-
Once aged, the connection is returned to nf conntrack with udp pickup timeout.
232+
Once aged, the connection is returned to nf conntrack.

include/net/netfilter/nf_tables.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,7 @@ struct nft_expr_info;
416416

417417
int nft_expr_inner_parse(const struct nft_ctx *ctx, const struct nlattr *nla,
418418
struct nft_expr_info *info);
419-
int nft_expr_clone(struct nft_expr *dst, struct nft_expr *src);
419+
int nft_expr_clone(struct nft_expr *dst, struct nft_expr *src, gfp_t gfp);
420420
void nft_expr_destroy(const struct nft_ctx *ctx, struct nft_expr *expr);
421421
int nft_expr_dump(struct sk_buff *skb, unsigned int attr,
422422
const struct nft_expr *expr, bool reset);
@@ -935,7 +935,7 @@ struct nft_expr_ops {
935935
struct nft_regs *regs,
936936
const struct nft_pktinfo *pkt);
937937
int (*clone)(struct nft_expr *dst,
938-
const struct nft_expr *src);
938+
const struct nft_expr *src, gfp_t gfp);
939939
unsigned int size;
940940

941941
int (*init)(const struct nft_ctx *ctx,

include/uapi/linux/icmpv6.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ struct icmp6hdr {
112112
#define ICMPV6_MOBILE_PREFIX_ADV 147
113113

114114
#define ICMPV6_MRDISC_ADV 151
115+
#define ICMPV6_MRDISC_SOL 152
115116

116117
#define ICMPV6_MSG_MAX 255
117118

net/ipv4/netfilter/iptable_filter.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ static int iptable_filter_table_init(struct net *net)
4444
return -ENOMEM;
4545
/* Entry 1 is the FORWARD hook */
4646
((struct ipt_standard *)repl->entries)[1].target.verdict =
47-
forward ? -NF_ACCEPT - 1 : -NF_DROP - 1;
47+
forward ? -NF_ACCEPT - 1 : NF_DROP - 1;
4848

4949
err = ipt_register_table(net, &packet_filter, repl, filter_ops);
5050
kfree(repl);

net/ipv6/netfilter/ip6table_filter.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ static int ip6table_filter_table_init(struct net *net)
4343
return -ENOMEM;
4444
/* Entry 1 is the FORWARD hook */
4545
((struct ip6t_standard *)repl->entries)[1].target.verdict =
46-
forward ? -NF_ACCEPT - 1 : -NF_DROP - 1;
46+
forward ? -NF_ACCEPT - 1 : NF_DROP - 1;
4747

4848
err = ip6t_register_table(net, &packet_filter, repl, filter_ops);
4949
kfree(repl);

net/netfilter/nf_conntrack_core.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1440,8 +1440,6 @@ static bool gc_worker_can_early_drop(const struct nf_conn *ct)
14401440
const struct nf_conntrack_l4proto *l4proto;
14411441
u8 protonum = nf_ct_protonum(ct);
14421442

1443-
if (test_bit(IPS_OFFLOAD_BIT, &ct->status) && protonum != IPPROTO_UDP)
1444-
return false;
14451443
if (!test_bit(IPS_ASSURED_BIT, &ct->status))
14461444
return true;
14471445

@@ -2024,7 +2022,7 @@ nf_conntrack_in(struct sk_buff *skb, const struct nf_hook_state *state)
20242022
goto repeat;
20252023

20262024
NF_CT_STAT_INC_ATOMIC(state->net, invalid);
2027-
if (ret == -NF_DROP)
2025+
if (ret == NF_DROP)
20282026
NF_CT_STAT_INC_ATOMIC(state->net, drop);
20292027

20302028
ret = -ret;

net/netfilter/nf_conntrack_proto_dccp.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -525,15 +525,15 @@ int nf_conntrack_dccp_packet(struct nf_conn *ct, struct sk_buff *skb,
525525

526526
dh = skb_header_pointer(skb, dataoff, sizeof(*dh), &_dh.dh);
527527
if (!dh)
528-
return NF_DROP;
528+
return -NF_ACCEPT;
529529

530530
if (dccp_error(dh, skb, dataoff, state))
531531
return -NF_ACCEPT;
532532

533533
/* pull again, including possible 48 bit sequences and subtype header */
534534
dh = dccp_header_pointer(skb, dataoff, dh, &_dh);
535535
if (!dh)
536-
return NF_DROP;
536+
return -NF_ACCEPT;
537537

538538
type = dh->dccph_type;
539539
if (!nf_ct_is_confirmed(ct) && !dccp_new(ct, skb, dh, state))

net/netfilter/nf_conntrack_proto_icmpv6.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,9 @@ static const u_int8_t noct_valid_new[] = {
6262
[NDISC_ROUTER_ADVERTISEMENT - 130] = 1,
6363
[NDISC_NEIGHBOUR_SOLICITATION - 130] = 1,
6464
[NDISC_NEIGHBOUR_ADVERTISEMENT - 130] = 1,
65-
[ICMPV6_MLD2_REPORT - 130] = 1
65+
[ICMPV6_MLD2_REPORT - 130] = 1,
66+
[ICMPV6_MRDISC_ADV - 130] = 1,
67+
[ICMPV6_MRDISC_SOL - 130] = 1
6668
};
6769

6870
bool nf_conntrack_invert_icmpv6_tuple(struct nf_conntrack_tuple *tuple,

net/netfilter/nf_tables_api.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3333,15 +3333,15 @@ static struct nft_expr *nft_expr_init(const struct nft_ctx *ctx,
33333333
return ERR_PTR(err);
33343334
}
33353335

3336-
int nft_expr_clone(struct nft_expr *dst, struct nft_expr *src)
3336+
int nft_expr_clone(struct nft_expr *dst, struct nft_expr *src, gfp_t gfp)
33373337
{
33383338
int err;
33393339

33403340
if (WARN_ON_ONCE(!src->ops->clone))
33413341
return -EINVAL;
33423342

33433343
dst->ops = src->ops;
3344-
err = src->ops->clone(dst, src);
3344+
err = src->ops->clone(dst, src, gfp);
33453345
if (err < 0)
33463346
return err;
33473347

@@ -6525,7 +6525,7 @@ int nft_set_elem_expr_clone(const struct nft_ctx *ctx, struct nft_set *set,
65256525
if (!expr)
65266526
goto err_expr;
65276527

6528-
err = nft_expr_clone(expr, set->exprs[i]);
6528+
err = nft_expr_clone(expr, set->exprs[i], GFP_KERNEL_ACCOUNT);
65296529
if (err < 0) {
65306530
kfree(expr);
65316531
goto err_expr;
@@ -6564,7 +6564,7 @@ static int nft_set_elem_expr_setup(struct nft_ctx *ctx,
65646564

65656565
for (i = 0; i < num_exprs; i++) {
65666566
expr = nft_setelem_expr_at(elem_expr, elem_expr->size);
6567-
err = nft_expr_clone(expr, expr_array[i]);
6567+
err = nft_expr_clone(expr, expr_array[i], GFP_KERNEL_ACCOUNT);
65686568
if (err < 0)
65696569
goto err_elem_expr_setup;
65706570

@@ -7776,6 +7776,9 @@ static int nf_tables_newobj(struct sk_buff *skb, const struct nfnl_info *info,
77767776
if (WARN_ON_ONCE(!type))
77777777
return -ENOENT;
77787778

7779+
if (!obj->ops->update)
7780+
return 0;
7781+
77797782
nft_ctx_init(&ctx, net, skb, info->nlh, family, table, NULL, nla);
77807783

77817784
return nf_tables_updobj(&ctx, type, nla[NFTA_OBJ_DATA], obj);
@@ -9467,9 +9470,10 @@ static void nft_obj_commit_update(struct nft_trans *trans)
94679470
obj = nft_trans_obj(trans);
94689471
newobj = nft_trans_obj_newobj(trans);
94699472

9470-
if (obj->ops->update)
9471-
obj->ops->update(obj, newobj);
9473+
if (WARN_ON_ONCE(!obj->ops->update))
9474+
return;
94729475

9476+
obj->ops->update(obj, newobj);
94739477
nft_obj_destroy(&trans->ctx, newobj);
94749478
}
94759479

net/netfilter/nft_chain_filter.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -325,9 +325,6 @@ static void nft_netdev_event(unsigned long event, struct net_device *dev,
325325
struct nft_hook *hook, *found = NULL;
326326
int n = 0;
327327

328-
if (event != NETDEV_UNREGISTER)
329-
return;
330-
331328
list_for_each_entry(hook, &basechain->hook_list, list) {
332329
if (hook->ops.dev == dev)
333330
found = hook;
@@ -367,8 +364,7 @@ static int nf_tables_netdev_event(struct notifier_block *this,
367364
.net = dev_net(dev),
368365
};
369366

370-
if (event != NETDEV_UNREGISTER &&
371-
event != NETDEV_CHANGENAME)
367+
if (event != NETDEV_UNREGISTER)
372368
return NOTIFY_DONE;
373369

374370
nft_net = nft_pernet(ctx.net);

net/netfilter/nft_connlimit.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,12 +210,12 @@ static void nft_connlimit_destroy(const struct nft_ctx *ctx,
210210
nft_connlimit_do_destroy(ctx, priv);
211211
}
212212

213-
static int nft_connlimit_clone(struct nft_expr *dst, const struct nft_expr *src)
213+
static int nft_connlimit_clone(struct nft_expr *dst, const struct nft_expr *src, gfp_t gfp)
214214
{
215215
struct nft_connlimit *priv_dst = nft_expr_priv(dst);
216216
struct nft_connlimit *priv_src = nft_expr_priv(src);
217217

218-
priv_dst->list = kmalloc(sizeof(*priv_dst->list), GFP_ATOMIC);
218+
priv_dst->list = kmalloc(sizeof(*priv_dst->list), gfp);
219219
if (!priv_dst->list)
220220
return -ENOMEM;
221221

net/netfilter/nft_counter.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ static void nft_counter_destroy(const struct nft_ctx *ctx,
226226
nft_counter_do_destroy(priv);
227227
}
228228

229-
static int nft_counter_clone(struct nft_expr *dst, const struct nft_expr *src)
229+
static int nft_counter_clone(struct nft_expr *dst, const struct nft_expr *src, gfp_t gfp)
230230
{
231231
struct nft_counter_percpu_priv *priv = nft_expr_priv(src);
232232
struct nft_counter_percpu_priv *priv_clone = nft_expr_priv(dst);
@@ -236,7 +236,7 @@ static int nft_counter_clone(struct nft_expr *dst, const struct nft_expr *src)
236236

237237
nft_counter_fetch(priv, &total);
238238

239-
cpu_stats = alloc_percpu_gfp(struct nft_counter, GFP_ATOMIC);
239+
cpu_stats = alloc_percpu_gfp(struct nft_counter, gfp);
240240
if (cpu_stats == NULL)
241241
return -ENOMEM;
242242

net/netfilter/nft_dynset.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ static int nft_dynset_expr_setup(const struct nft_dynset *priv,
3535

3636
for (i = 0; i < priv->num_exprs; i++) {
3737
expr = nft_setelem_expr_at(elem_expr, elem_expr->size);
38-
if (nft_expr_clone(expr, priv->expr_array[i]) < 0)
38+
if (nft_expr_clone(expr, priv->expr_array[i], GFP_ATOMIC) < 0)
3939
return -1;
4040

4141
elem_expr->size += priv->expr_array[i]->ops->size;

net/netfilter/nft_last.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,12 +102,12 @@ static void nft_last_destroy(const struct nft_ctx *ctx,
102102
kfree(priv->last);
103103
}
104104

105-
static int nft_last_clone(struct nft_expr *dst, const struct nft_expr *src)
105+
static int nft_last_clone(struct nft_expr *dst, const struct nft_expr *src, gfp_t gfp)
106106
{
107107
struct nft_last_priv *priv_dst = nft_expr_priv(dst);
108108
struct nft_last_priv *priv_src = nft_expr_priv(src);
109109

110-
priv_dst->last = kzalloc(sizeof(*priv_dst->last), GFP_ATOMIC);
110+
priv_dst->last = kzalloc(sizeof(*priv_dst->last), gfp);
111111
if (!priv_dst->last)
112112
return -ENOMEM;
113113

net/netfilter/nft_limit.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -150,15 +150,15 @@ static void nft_limit_destroy(const struct nft_ctx *ctx,
150150
}
151151

152152
static int nft_limit_clone(struct nft_limit_priv *priv_dst,
153-
const struct nft_limit_priv *priv_src)
153+
const struct nft_limit_priv *priv_src, gfp_t gfp)
154154
{
155155
priv_dst->tokens_max = priv_src->tokens_max;
156156
priv_dst->rate = priv_src->rate;
157157
priv_dst->nsecs = priv_src->nsecs;
158158
priv_dst->burst = priv_src->burst;
159159
priv_dst->invert = priv_src->invert;
160160

161-
priv_dst->limit = kmalloc(sizeof(*priv_dst->limit), GFP_ATOMIC);
161+
priv_dst->limit = kmalloc(sizeof(*priv_dst->limit), gfp);
162162
if (!priv_dst->limit)
163163
return -ENOMEM;
164164

@@ -223,14 +223,15 @@ static void nft_limit_pkts_destroy(const struct nft_ctx *ctx,
223223
nft_limit_destroy(ctx, &priv->limit);
224224
}
225225

226-
static int nft_limit_pkts_clone(struct nft_expr *dst, const struct nft_expr *src)
226+
static int nft_limit_pkts_clone(struct nft_expr *dst, const struct nft_expr *src,
227+
gfp_t gfp)
227228
{
228229
struct nft_limit_priv_pkts *priv_dst = nft_expr_priv(dst);
229230
struct nft_limit_priv_pkts *priv_src = nft_expr_priv(src);
230231

231232
priv_dst->cost = priv_src->cost;
232233

233-
return nft_limit_clone(&priv_dst->limit, &priv_src->limit);
234+
return nft_limit_clone(&priv_dst->limit, &priv_src->limit, gfp);
234235
}
235236

236237
static struct nft_expr_type nft_limit_type;
@@ -281,12 +282,13 @@ static void nft_limit_bytes_destroy(const struct nft_ctx *ctx,
281282
nft_limit_destroy(ctx, priv);
282283
}
283284

284-
static int nft_limit_bytes_clone(struct nft_expr *dst, const struct nft_expr *src)
285+
static int nft_limit_bytes_clone(struct nft_expr *dst, const struct nft_expr *src,
286+
gfp_t gfp)
285287
{
286288
struct nft_limit_priv *priv_dst = nft_expr_priv(dst);
287289
struct nft_limit_priv *priv_src = nft_expr_priv(src);
288290

289-
return nft_limit_clone(priv_dst, priv_src);
291+
return nft_limit_clone(priv_dst, priv_src, gfp);
290292
}
291293

292294
static const struct nft_expr_ops nft_limit_bytes_ops = {

net/netfilter/nft_quota.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -233,15 +233,15 @@ static void nft_quota_destroy(const struct nft_ctx *ctx,
233233
return nft_quota_do_destroy(ctx, priv);
234234
}
235235

236-
static int nft_quota_clone(struct nft_expr *dst, const struct nft_expr *src)
236+
static int nft_quota_clone(struct nft_expr *dst, const struct nft_expr *src, gfp_t gfp)
237237
{
238238
struct nft_quota *priv_dst = nft_expr_priv(dst);
239239
struct nft_quota *priv_src = nft_expr_priv(src);
240240

241241
priv_dst->quota = priv_src->quota;
242242
priv_dst->flags = priv_src->flags;
243243

244-
priv_dst->consumed = kmalloc(sizeof(*priv_dst->consumed), GFP_ATOMIC);
244+
priv_dst->consumed = kmalloc(sizeof(*priv_dst->consumed), gfp);
245245
if (!priv_dst->consumed)
246246
return -ENOMEM;
247247

0 commit comments

Comments
 (0)