Skip to content

Commit 0f74d0c

Browse files
author
Paolo Abeni
committed
Merge tag 'nf-24-06-19' 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: Patch #1 fixes the suspicious RCU usage warning that resulted from the recent fix for the race between namespace cleanup and gc in ipset left out checking the pernet exit phase when calling rcu_dereference_protected(), from Jozsef Kadlecsik. Patch Rust-for-Linux#2 fixes incorrect input and output netdevice in SRv6 prerouting hooks, from Jianguo Wu. Patch Rust-for-Linux#3 moves nf_hooks_lwtunnel sysctl toggle to the netfilter core. The connection tracking system is loaded on-demand, this ensures availability of this knob regardless. Patch Rust-for-Linux#4-Rust-for-Linux#5 adds selftests for SRv6 netfilter hooks also from Jianguo Wu. netfilter pull request 24-06-19 * tag 'nf-24-06-19' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf: selftests: add selftest for the SRv6 End.DX6 behavior with netfilter selftests: add selftest for the SRv6 End.DX4 behavior with netfilter netfilter: move the sysctl nf_hooks_lwtunnel into the netfilter core seg6: fix parameter passing when calling NF_HOOK() in End.DX4 and End.DX6 behaviors netfilter: ipset: Fix suspicious rcu_dereference_protected() ==================== Link: https://lore.kernel.org/r/20240619170537.2846-1-pablo@netfilter.org Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2 parents 6cd4a78 + 221200f commit 0f74d0c

11 files changed

+776
-26
lines changed

include/net/netns/netfilter.h

+3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ struct netns_nf {
1515
const struct nf_logger __rcu *nf_loggers[NFPROTO_NUMPROTO];
1616
#ifdef CONFIG_SYSCTL
1717
struct ctl_table_header *nf_log_dir_header;
18+
#ifdef CONFIG_LWTUNNEL
19+
struct ctl_table_header *nf_lwtnl_dir_header;
20+
#endif
1821
#endif
1922
struct nf_hook_entries __rcu *hooks_ipv4[NF_INET_NUMHOOKS];
2023
struct nf_hook_entries __rcu *hooks_ipv6[NF_INET_NUMHOOKS];

net/ipv6/seg6_local.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -941,8 +941,8 @@ static int input_action_end_dx6(struct sk_buff *skb,
941941

942942
if (static_branch_unlikely(&nf_hooks_lwtunnel_enabled))
943943
return NF_HOOK(NFPROTO_IPV6, NF_INET_PRE_ROUTING,
944-
dev_net(skb->dev), NULL, skb, NULL,
945-
skb_dst(skb)->dev, input_action_end_dx6_finish);
944+
dev_net(skb->dev), NULL, skb, skb->dev,
945+
NULL, input_action_end_dx6_finish);
946946

947947
return input_action_end_dx6_finish(dev_net(skb->dev), NULL, skb);
948948
drop:
@@ -991,8 +991,8 @@ static int input_action_end_dx4(struct sk_buff *skb,
991991

992992
if (static_branch_unlikely(&nf_hooks_lwtunnel_enabled))
993993
return NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING,
994-
dev_net(skb->dev), NULL, skb, NULL,
995-
skb_dst(skb)->dev, input_action_end_dx4_finish);
994+
dev_net(skb->dev), NULL, skb, skb->dev,
995+
NULL, input_action_end_dx4_finish);
996996

997997
return input_action_end_dx4_finish(dev_net(skb->dev), NULL, skb);
998998
drop:

net/netfilter/core.c

+11-2
Original file line numberDiff line numberDiff line change
@@ -815,12 +815,21 @@ int __init netfilter_init(void)
815815
if (ret < 0)
816816
goto err;
817817

818+
#ifdef CONFIG_LWTUNNEL
819+
ret = netfilter_lwtunnel_init();
820+
if (ret < 0)
821+
goto err_lwtunnel_pernet;
822+
#endif
818823
ret = netfilter_log_init();
819824
if (ret < 0)
820-
goto err_pernet;
825+
goto err_log_pernet;
821826

822827
return 0;
823-
err_pernet:
828+
err_log_pernet:
829+
#ifdef CONFIG_LWTUNNEL
830+
netfilter_lwtunnel_fini();
831+
err_lwtunnel_pernet:
832+
#endif
824833
unregister_pernet_subsys(&netfilter_net_ops);
825834
err:
826835
return ret;

net/netfilter/ipset/ip_set_core.c

+6-5
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,13 @@ MODULE_DESCRIPTION("core IP set support");
5353
MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_IPSET);
5454

5555
/* When the nfnl mutex or ip_set_ref_lock is held: */
56-
#define ip_set_dereference(p) \
57-
rcu_dereference_protected(p, \
56+
#define ip_set_dereference(inst) \
57+
rcu_dereference_protected((inst)->ip_set_list, \
5858
lockdep_nfnl_is_held(NFNL_SUBSYS_IPSET) || \
59-
lockdep_is_held(&ip_set_ref_lock))
59+
lockdep_is_held(&ip_set_ref_lock) || \
60+
(inst)->is_deleted)
6061
#define ip_set(inst, id) \
61-
ip_set_dereference((inst)->ip_set_list)[id]
62+
ip_set_dereference(inst)[id]
6263
#define ip_set_ref_netlink(inst,id) \
6364
rcu_dereference_raw((inst)->ip_set_list)[id]
6465
#define ip_set_dereference_nfnl(p) \
@@ -1133,7 +1134,7 @@ static int ip_set_create(struct sk_buff *skb, const struct nfnl_info *info,
11331134
if (!list)
11341135
goto cleanup;
11351136
/* nfnl mutex is held, both lists are valid */
1136-
tmp = ip_set_dereference(inst->ip_set_list);
1137+
tmp = ip_set_dereference(inst);
11371138
memcpy(list, tmp, sizeof(struct ip_set *) * inst->ip_set_max);
11381139
rcu_assign_pointer(inst->ip_set_list, list);
11391140
/* Make sure all current packets have passed through */

net/netfilter/nf_conntrack_standalone.c

-15
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,6 @@
2222
#include <net/netfilter/nf_conntrack_acct.h>
2323
#include <net/netfilter/nf_conntrack_zones.h>
2424
#include <net/netfilter/nf_conntrack_timestamp.h>
25-
#ifdef CONFIG_LWTUNNEL
26-
#include <net/netfilter/nf_hooks_lwtunnel.h>
27-
#endif
2825
#include <linux/rculist_nulls.h>
2926

3027
static bool enable_hooks __read_mostly;
@@ -612,9 +609,6 @@ enum nf_ct_sysctl_index {
612609
NF_SYSCTL_CT_PROTO_TIMEOUT_GRE,
613610
NF_SYSCTL_CT_PROTO_TIMEOUT_GRE_STREAM,
614611
#endif
615-
#ifdef CONFIG_LWTUNNEL
616-
NF_SYSCTL_CT_LWTUNNEL,
617-
#endif
618612

619613
NF_SYSCTL_CT_LAST_SYSCTL,
620614
};
@@ -946,15 +940,6 @@ static struct ctl_table nf_ct_sysctl_table[] = {
946940
.proc_handler = proc_dointvec_jiffies,
947941
},
948942
#endif
949-
#ifdef CONFIG_LWTUNNEL
950-
[NF_SYSCTL_CT_LWTUNNEL] = {
951-
.procname = "nf_hooks_lwtunnel",
952-
.data = NULL,
953-
.maxlen = sizeof(int),
954-
.mode = 0644,
955-
.proc_handler = nf_hooks_lwtunnel_sysctl_handler,
956-
},
957-
#endif
958943
};
959944

960945
static struct ctl_table nf_ct_netfilter_table[] = {

net/netfilter/nf_hooks_lwtunnel.c

+67
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
#include <linux/sysctl.h>
44
#include <net/lwtunnel.h>
55
#include <net/netfilter/nf_hooks_lwtunnel.h>
6+
#include <linux/netfilter.h>
7+
8+
#include "nf_internals.h"
69

710
static inline int nf_hooks_lwtunnel_get(void)
811
{
@@ -50,4 +53,68 @@ int nf_hooks_lwtunnel_sysctl_handler(struct ctl_table *table, int write,
5053
return ret;
5154
}
5255
EXPORT_SYMBOL_GPL(nf_hooks_lwtunnel_sysctl_handler);
56+
57+
static struct ctl_table nf_lwtunnel_sysctl_table[] = {
58+
{
59+
.procname = "nf_hooks_lwtunnel",
60+
.data = NULL,
61+
.maxlen = sizeof(int),
62+
.mode = 0644,
63+
.proc_handler = nf_hooks_lwtunnel_sysctl_handler,
64+
},
65+
};
66+
67+
static int __net_init nf_lwtunnel_net_init(struct net *net)
68+
{
69+
struct ctl_table_header *hdr;
70+
struct ctl_table *table;
71+
72+
table = nf_lwtunnel_sysctl_table;
73+
if (!net_eq(net, &init_net)) {
74+
table = kmemdup(nf_lwtunnel_sysctl_table,
75+
sizeof(nf_lwtunnel_sysctl_table),
76+
GFP_KERNEL);
77+
if (!table)
78+
goto err_alloc;
79+
}
80+
81+
hdr = register_net_sysctl_sz(net, "net/netfilter", table,
82+
ARRAY_SIZE(nf_lwtunnel_sysctl_table));
83+
if (!hdr)
84+
goto err_reg;
85+
86+
net->nf.nf_lwtnl_dir_header = hdr;
87+
88+
return 0;
89+
err_reg:
90+
if (!net_eq(net, &init_net))
91+
kfree(table);
92+
err_alloc:
93+
return -ENOMEM;
94+
}
95+
96+
static void __net_exit nf_lwtunnel_net_exit(struct net *net)
97+
{
98+
const struct ctl_table *table;
99+
100+
table = net->nf.nf_lwtnl_dir_header->ctl_table_arg;
101+
unregister_net_sysctl_table(net->nf.nf_lwtnl_dir_header);
102+
if (!net_eq(net, &init_net))
103+
kfree(table);
104+
}
105+
106+
static struct pernet_operations nf_lwtunnel_net_ops = {
107+
.init = nf_lwtunnel_net_init,
108+
.exit = nf_lwtunnel_net_exit,
109+
};
110+
111+
int __init netfilter_lwtunnel_init(void)
112+
{
113+
return register_pernet_subsys(&nf_lwtunnel_net_ops);
114+
}
115+
116+
void netfilter_lwtunnel_fini(void)
117+
{
118+
unregister_pernet_subsys(&nf_lwtunnel_net_ops);
119+
}
53120
#endif /* CONFIG_SYSCTL */

net/netfilter/nf_internals.h

+6
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ void nf_queue_nf_hook_drop(struct net *net);
2929
/* nf_log.c */
3030
int __init netfilter_log_init(void);
3131

32+
#ifdef CONFIG_LWTUNNEL
33+
/* nf_hooks_lwtunnel.c */
34+
int __init netfilter_lwtunnel_init(void);
35+
void netfilter_lwtunnel_fini(void);
36+
#endif
37+
3238
/* core.c */
3339
void nf_hook_entries_delete_raw(struct nf_hook_entries __rcu **pp,
3440
const struct nf_hook_ops *reg);

tools/testing/selftests/net/Makefile

+2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ TEST_PROGS += srv6_hl2encap_red_l2vpn_test.sh
4343
TEST_PROGS += srv6_end_next_csid_l3vpn_test.sh
4444
TEST_PROGS += srv6_end_x_next_csid_l3vpn_test.sh
4545
TEST_PROGS += srv6_end_flavors_test.sh
46+
TEST_PROGS += srv6_end_dx4_netfilter_test.sh
47+
TEST_PROGS += srv6_end_dx6_netfilter_test.sh
4648
TEST_PROGS += vrf_strict_mode_test.sh
4749
TEST_PROGS += arp_ndisc_evict_nocarrier.sh
4850
TEST_PROGS += ndisc_unsolicited_na_test.sh

tools/testing/selftests/net/config

+2
Original file line numberDiff line numberDiff line change
@@ -101,3 +101,5 @@ CONFIG_NETFILTER_XT_MATCH_POLICY=m
101101
CONFIG_CRYPTO_ARIA=y
102102
CONFIG_XFRM_INTERFACE=m
103103
CONFIG_XFRM_USER=m
104+
CONFIG_IP_NF_MATCH_RPFILTER=m
105+
CONFIG_IP6_NF_MATCH_RPFILTER=m

0 commit comments

Comments
 (0)