mirror of
https://github.com/torvalds/linux.git
synced 2024-12-18 17:12:55 +00:00
netfilter pull request 24-12-11
-----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEjF9xRqF1emXiQiqU1w0aZmrPKyEFAmdaFt8ACgkQ1w0aZmrP KyGzow//fio7wR3vGa+l822MpbXxtyPindBNdNbdIrc1UajcyWaja1fG0vrvnLC5 Ze6OUI0Q4OumjmKHYRbWGxTufCURFA4IXJ92mnftu0d/7AFIoRms3F3rTSXzFQbJ Osgt6yUAUlw3naG0TSvUjejWBI8L/ISRyZlz/olJSubww54+4h3VcsrhAFvV8RWr cHoRwTnrIG2q0ACk77AX7pmP13kO8rvFG8Qv2lcGxhDCJUglQG+KYVleY0oddkEO 9O8fNi9WocUCjkFGIpMUBxSSNIXbX1GY0qj52aSGfowgqgQNVHykHxSOiow84Qbg ea5uUBmtzswNzbSsRkNPX/rsk1FIVzmWDT3Gyt/rrED2/8gUuH9RvTWgjVHhB75G UpZYmnsFLTJXDBk3Y8q5RKR0+nntmVtsIqL8UoSJR1Ck8Kz3Xp1qSJqPJMGjfYkm 3rstS2T2SPh9As0pqq0/ACEgCz+Gzztuoo4L+JZJRo3clu/lEtbJVnQy/6MkckcA Y5U6IHWEctB+xMvRirPcx6cJa/7dX8sCg4UdRVberdGKq+XUXmQpbPo1w89gVA5l BQq3eeX9lxEDNEjxgpVapm5BkDsA23sbCrjM26NryAJSkGh2MwXxp4zqWz4WIQGW R6FVUi4JgR2+LGkchHSZUULpVjNWyq9U8RWvv4ge00tSj5XEHmw= =JEfQ -----END PGP SIGNATURE----- Merge tag 'nf-24-12-11' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf Pablo Neira Ayuso says: ==================== Netfilter fixes for net The following patchset contains Netfilter fixes for net: 1) Fix bogus test reports in rpath.sh selftest by adding permanent neighbor entries, from Phil Sutter. 2) Lockdep reports possible ABBA deadlock in xt_IDLETIMER, fix it by removing sysfs out of the mutex section, also from Phil Sutter. 3) It is illegal to release basechain via RCU callback, for several reasons. Keep it simple and safe by calling synchronize_rcu() instead. This is a partially reverting a botched recent attempt of me to fix this basechain release path on netdevice removal. From Florian Westphal. netfilter pull request 24-12-11 * tag 'nf-24-12-11' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf: netfilter: nf_tables: do not defer rule destruction via call_rcu netfilter: IDLETIMER: Fix for possible ABBA deadlock selftests: netfilter: Stabilize rpath.sh ==================== Link: https://patch.msgid.link/20241211230130.176937-1-pablo@netfilter.org Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
commit
3d64c3d3c6
@ -1103,7 +1103,6 @@ struct nft_rule_blob {
|
||||
* @name: name of the chain
|
||||
* @udlen: user data length
|
||||
* @udata: user data in the chain
|
||||
* @rcu_head: rcu head for deferred release
|
||||
* @blob_next: rule blob pointer to the next in the chain
|
||||
*/
|
||||
struct nft_chain {
|
||||
@ -1121,7 +1120,6 @@ struct nft_chain {
|
||||
char *name;
|
||||
u16 udlen;
|
||||
u8 *udata;
|
||||
struct rcu_head rcu_head;
|
||||
|
||||
/* Only used during control plane commit phase: */
|
||||
struct nft_rule_blob *blob_next;
|
||||
@ -1265,7 +1263,6 @@ static inline void nft_use_inc_restore(u32 *use)
|
||||
* @sets: sets in the table
|
||||
* @objects: stateful objects in the table
|
||||
* @flowtables: flow tables in the table
|
||||
* @net: netnamespace this table belongs to
|
||||
* @hgenerator: handle generator state
|
||||
* @handle: table handle
|
||||
* @use: number of chain references to this table
|
||||
@ -1285,7 +1282,6 @@ struct nft_table {
|
||||
struct list_head sets;
|
||||
struct list_head objects;
|
||||
struct list_head flowtables;
|
||||
possible_net_t net;
|
||||
u64 hgenerator;
|
||||
u64 handle;
|
||||
u32 use;
|
||||
|
@ -1596,7 +1596,6 @@ static int nf_tables_newtable(struct sk_buff *skb, const struct nfnl_info *info,
|
||||
INIT_LIST_HEAD(&table->sets);
|
||||
INIT_LIST_HEAD(&table->objects);
|
||||
INIT_LIST_HEAD(&table->flowtables);
|
||||
write_pnet(&table->net, net);
|
||||
table->family = family;
|
||||
table->flags = flags;
|
||||
table->handle = ++nft_net->table_handle;
|
||||
@ -3987,8 +3986,11 @@ void nf_tables_rule_destroy(const struct nft_ctx *ctx, struct nft_rule *rule)
|
||||
kfree(rule);
|
||||
}
|
||||
|
||||
/* can only be used if rule is no longer visible to dumps */
|
||||
static void nf_tables_rule_release(const struct nft_ctx *ctx, struct nft_rule *rule)
|
||||
{
|
||||
lockdep_commit_lock_is_held(ctx->net);
|
||||
|
||||
nft_rule_expr_deactivate(ctx, rule, NFT_TRANS_RELEASE);
|
||||
nf_tables_rule_destroy(ctx, rule);
|
||||
}
|
||||
@ -5757,6 +5759,8 @@ void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set,
|
||||
struct nft_set_binding *binding,
|
||||
enum nft_trans_phase phase)
|
||||
{
|
||||
lockdep_commit_lock_is_held(ctx->net);
|
||||
|
||||
switch (phase) {
|
||||
case NFT_TRANS_PREPARE_ERROR:
|
||||
nft_set_trans_unbind(ctx, set);
|
||||
@ -11695,19 +11699,6 @@ static void __nft_release_basechain_now(struct nft_ctx *ctx)
|
||||
nf_tables_chain_destroy(ctx->chain);
|
||||
}
|
||||
|
||||
static void nft_release_basechain_rcu(struct rcu_head *head)
|
||||
{
|
||||
struct nft_chain *chain = container_of(head, struct nft_chain, rcu_head);
|
||||
struct nft_ctx ctx = {
|
||||
.family = chain->table->family,
|
||||
.chain = chain,
|
||||
.net = read_pnet(&chain->table->net),
|
||||
};
|
||||
|
||||
__nft_release_basechain_now(&ctx);
|
||||
put_net(ctx.net);
|
||||
}
|
||||
|
||||
int __nft_release_basechain(struct nft_ctx *ctx)
|
||||
{
|
||||
struct nft_rule *rule;
|
||||
@ -11722,11 +11713,18 @@ int __nft_release_basechain(struct nft_ctx *ctx)
|
||||
nft_chain_del(ctx->chain);
|
||||
nft_use_dec(&ctx->table->use);
|
||||
|
||||
if (maybe_get_net(ctx->net))
|
||||
call_rcu(&ctx->chain->rcu_head, nft_release_basechain_rcu);
|
||||
else
|
||||
if (!maybe_get_net(ctx->net)) {
|
||||
__nft_release_basechain_now(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* wait for ruleset dumps to complete. Owning chain is no longer in
|
||||
* lists, so new dumps can't find any of these rules anymore.
|
||||
*/
|
||||
synchronize_rcu();
|
||||
|
||||
__nft_release_basechain_now(ctx);
|
||||
put_net(ctx->net);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__nft_release_basechain);
|
||||
|
@ -407,21 +407,23 @@ static void idletimer_tg_destroy(const struct xt_tgdtor_param *par)
|
||||
|
||||
mutex_lock(&list_mutex);
|
||||
|
||||
if (--info->timer->refcnt == 0) {
|
||||
pr_debug("deleting timer %s\n", info->label);
|
||||
|
||||
list_del(&info->timer->entry);
|
||||
timer_shutdown_sync(&info->timer->timer);
|
||||
cancel_work_sync(&info->timer->work);
|
||||
sysfs_remove_file(idletimer_tg_kobj, &info->timer->attr.attr);
|
||||
kfree(info->timer->attr.attr.name);
|
||||
kfree(info->timer);
|
||||
} else {
|
||||
if (--info->timer->refcnt > 0) {
|
||||
pr_debug("decreased refcnt of timer %s to %u\n",
|
||||
info->label, info->timer->refcnt);
|
||||
mutex_unlock(&list_mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
pr_debug("deleting timer %s\n", info->label);
|
||||
|
||||
list_del(&info->timer->entry);
|
||||
mutex_unlock(&list_mutex);
|
||||
|
||||
timer_shutdown_sync(&info->timer->timer);
|
||||
cancel_work_sync(&info->timer->work);
|
||||
sysfs_remove_file(idletimer_tg_kobj, &info->timer->attr.attr);
|
||||
kfree(info->timer->attr.attr.name);
|
||||
kfree(info->timer);
|
||||
}
|
||||
|
||||
static void idletimer_tg_destroy_v1(const struct xt_tgdtor_param *par)
|
||||
@ -432,25 +434,27 @@ static void idletimer_tg_destroy_v1(const struct xt_tgdtor_param *par)
|
||||
|
||||
mutex_lock(&list_mutex);
|
||||
|
||||
if (--info->timer->refcnt == 0) {
|
||||
pr_debug("deleting timer %s\n", info->label);
|
||||
|
||||
list_del(&info->timer->entry);
|
||||
if (info->timer->timer_type & XT_IDLETIMER_ALARM) {
|
||||
alarm_cancel(&info->timer->alarm);
|
||||
} else {
|
||||
timer_shutdown_sync(&info->timer->timer);
|
||||
}
|
||||
cancel_work_sync(&info->timer->work);
|
||||
sysfs_remove_file(idletimer_tg_kobj, &info->timer->attr.attr);
|
||||
kfree(info->timer->attr.attr.name);
|
||||
kfree(info->timer);
|
||||
} else {
|
||||
if (--info->timer->refcnt > 0) {
|
||||
pr_debug("decreased refcnt of timer %s to %u\n",
|
||||
info->label, info->timer->refcnt);
|
||||
mutex_unlock(&list_mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
pr_debug("deleting timer %s\n", info->label);
|
||||
|
||||
list_del(&info->timer->entry);
|
||||
mutex_unlock(&list_mutex);
|
||||
|
||||
if (info->timer->timer_type & XT_IDLETIMER_ALARM) {
|
||||
alarm_cancel(&info->timer->alarm);
|
||||
} else {
|
||||
timer_shutdown_sync(&info->timer->timer);
|
||||
}
|
||||
cancel_work_sync(&info->timer->work);
|
||||
sysfs_remove_file(idletimer_tg_kobj, &info->timer->attr.attr);
|
||||
kfree(info->timer->attr.attr.name);
|
||||
kfree(info->timer);
|
||||
}
|
||||
|
||||
|
||||
|
@ -61,9 +61,20 @@ ip -net "$ns2" a a 192.168.42.1/24 dev d0
|
||||
ip -net "$ns1" a a fec0:42::2/64 dev v0 nodad
|
||||
ip -net "$ns2" a a fec0:42::1/64 dev d0 nodad
|
||||
|
||||
# avoid neighbor lookups and enable martian IPv6 pings
|
||||
ns2_hwaddr=$(ip -net "$ns2" link show dev v0 | \
|
||||
sed -n 's, *link/ether \([^ ]*\) .*,\1,p')
|
||||
ns1_hwaddr=$(ip -net "$ns1" link show dev v0 | \
|
||||
sed -n 's, *link/ether \([^ ]*\) .*,\1,p')
|
||||
ip -net "$ns1" neigh add fec0:42::1 lladdr "$ns2_hwaddr" nud permanent dev v0
|
||||
ip -net "$ns1" neigh add fec0:23::1 lladdr "$ns2_hwaddr" nud permanent dev v0
|
||||
ip -net "$ns2" neigh add fec0:42::2 lladdr "$ns1_hwaddr" nud permanent dev d0
|
||||
ip -net "$ns2" neigh add fec0:23::2 lladdr "$ns1_hwaddr" nud permanent dev v0
|
||||
|
||||
# firewall matches to test
|
||||
[ -n "$iptables" ] && {
|
||||
common='-t raw -A PREROUTING -s 192.168.0.0/16'
|
||||
common+=' -p icmp --icmp-type echo-request'
|
||||
if ! ip netns exec "$ns2" "$iptables" $common -m rpfilter;then
|
||||
echo "Cannot add rpfilter rule"
|
||||
exit $ksft_skip
|
||||
@ -72,6 +83,7 @@ ip -net "$ns2" a a fec0:42::1/64 dev d0 nodad
|
||||
}
|
||||
[ -n "$ip6tables" ] && {
|
||||
common='-t raw -A PREROUTING -s fec0::/16'
|
||||
common+=' -p icmpv6 --icmpv6-type echo-request'
|
||||
if ! ip netns exec "$ns2" "$ip6tables" $common -m rpfilter;then
|
||||
echo "Cannot add rpfilter rule"
|
||||
exit $ksft_skip
|
||||
@ -82,8 +94,10 @@ ip -net "$ns2" a a fec0:42::1/64 dev d0 nodad
|
||||
table inet t {
|
||||
chain c {
|
||||
type filter hook prerouting priority raw;
|
||||
ip saddr 192.168.0.0/16 fib saddr . iif oif exists counter
|
||||
ip6 saddr fec0::/16 fib saddr . iif oif exists counter
|
||||
ip saddr 192.168.0.0/16 icmp type echo-request \
|
||||
fib saddr . iif oif exists counter
|
||||
ip6 saddr fec0::/16 icmpv6 type echo-request \
|
||||
fib saddr . iif oif exists counter
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
Loading…
Reference in New Issue
Block a user