Skip to content

Commit dade7f9

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf
Pablo Neira Ayuso says: ==================== Netfilter fixes for net (v2) The following patchset contains Netfilter fixes for net: 1) Move back the defrag users fields to the global netns_nf area. Kernel fails to boot if conntrack is builtin and kernel is booted with: nf_conntrack.enable_hooks=1. From Florian Westphal. 2) Rule event notification is missing relevant context such as the position handle and the NLM_F_APPEND flag. 3) Rule replacement is expanded to add + delete using the existing rule handle, reverse order of this operation so it makes sense from rule notification standpoint. 4) Propagate to userspace the NLM_F_CREATE and NLM_F_EXCL flags from the rule notification path. Patches gregkh#2, gregkh#3 and gregkh#4 are used by 'nft monitor' and 'iptables-monitor' userspace utilities which are not correctly representing the following operations through netlink notifications: - rule insertions - rule addition/insertion from position handle - create table/chain/set/map/flowtable/... ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 5cfe510 + 6fb721c commit dade7f9

File tree

8 files changed

+91
-68
lines changed

8 files changed

+91
-68
lines changed

include/net/netfilter/ipv6/nf_defrag_ipv6.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ struct inet_frags_ctl;
1717
struct nft_ct_frag6_pernet {
1818
struct ctl_table_header *nf_frag_frags_hdr;
1919
struct fqdir *fqdir;
20-
unsigned int users;
2120
};
2221

2322
#endif /* _NF_DEFRAG_IPV6_H */

include/net/netfilter/nf_tables.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1202,7 +1202,7 @@ struct nft_object *nft_obj_lookup(const struct net *net,
12021202

12031203
void nft_obj_notify(struct net *net, const struct nft_table *table,
12041204
struct nft_object *obj, u32 portid, u32 seq,
1205-
int event, int family, int report, gfp_t gfp);
1205+
int event, u16 flags, int family, int report, gfp_t gfp);
12061206

12071207
/**
12081208
* struct nft_object_type - stateful object type

include/net/netns/netfilter.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,11 @@ struct netns_nf {
2727
#if IS_ENABLED(CONFIG_DECNET)
2828
struct nf_hook_entries __rcu *hooks_decnet[NF_DN_NUMHOOKS];
2929
#endif
30+
#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV4)
31+
unsigned int defrag_ipv4_users;
32+
#endif
33+
#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
34+
unsigned int defrag_ipv6_users;
35+
#endif
3036
};
3137
#endif

net/ipv4/netfilter/nf_defrag_ipv4.c

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,8 @@
2020
#endif
2121
#include <net/netfilter/nf_conntrack_zones.h>
2222

23-
static unsigned int defrag4_pernet_id __read_mostly;
2423
static DEFINE_MUTEX(defrag4_mutex);
2524

26-
struct defrag4_pernet {
27-
unsigned int users;
28-
};
29-
3025
static int nf_ct_ipv4_gather_frags(struct net *net, struct sk_buff *skb,
3126
u_int32_t user)
3227
{
@@ -111,19 +106,15 @@ static const struct nf_hook_ops ipv4_defrag_ops[] = {
111106

112107
static void __net_exit defrag4_net_exit(struct net *net)
113108
{
114-
struct defrag4_pernet *nf_defrag = net_generic(net, defrag4_pernet_id);
115-
116-
if (nf_defrag->users) {
109+
if (net->nf.defrag_ipv4_users) {
117110
nf_unregister_net_hooks(net, ipv4_defrag_ops,
118111
ARRAY_SIZE(ipv4_defrag_ops));
119-
nf_defrag->users = 0;
112+
net->nf.defrag_ipv4_users = 0;
120113
}
121114
}
122115

123116
static struct pernet_operations defrag4_net_ops = {
124117
.exit = defrag4_net_exit,
125-
.id = &defrag4_pernet_id,
126-
.size = sizeof(struct defrag4_pernet),
127118
};
128119

129120
static int __init nf_defrag_init(void)
@@ -138,24 +129,23 @@ static void __exit nf_defrag_fini(void)
138129

139130
int nf_defrag_ipv4_enable(struct net *net)
140131
{
141-
struct defrag4_pernet *nf_defrag = net_generic(net, defrag4_pernet_id);
142132
int err = 0;
143133

144134
mutex_lock(&defrag4_mutex);
145-
if (nf_defrag->users == UINT_MAX) {
135+
if (net->nf.defrag_ipv4_users == UINT_MAX) {
146136
err = -EOVERFLOW;
147137
goto out_unlock;
148138
}
149139

150-
if (nf_defrag->users) {
151-
nf_defrag->users++;
140+
if (net->nf.defrag_ipv4_users) {
141+
net->nf.defrag_ipv4_users++;
152142
goto out_unlock;
153143
}
154144

155145
err = nf_register_net_hooks(net, ipv4_defrag_ops,
156146
ARRAY_SIZE(ipv4_defrag_ops));
157147
if (err == 0)
158-
nf_defrag->users = 1;
148+
net->nf.defrag_ipv4_users = 1;
159149

160150
out_unlock:
161151
mutex_unlock(&defrag4_mutex);
@@ -165,12 +155,10 @@ EXPORT_SYMBOL_GPL(nf_defrag_ipv4_enable);
165155

166156
void nf_defrag_ipv4_disable(struct net *net)
167157
{
168-
struct defrag4_pernet *nf_defrag = net_generic(net, defrag4_pernet_id);
169-
170158
mutex_lock(&defrag4_mutex);
171-
if (nf_defrag->users) {
172-
nf_defrag->users--;
173-
if (nf_defrag->users == 0)
159+
if (net->nf.defrag_ipv4_users) {
160+
net->nf.defrag_ipv4_users--;
161+
if (net->nf.defrag_ipv4_users == 0)
174162
nf_unregister_net_hooks(net, ipv4_defrag_ops,
175163
ARRAY_SIZE(ipv4_defrag_ops));
176164
}

net/ipv6/netfilter/nf_conntrack_reasm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333

3434
static const char nf_frags_cache_name[] = "nf-frags";
3535

36-
unsigned int nf_frag_pernet_id __read_mostly;
36+
static unsigned int nf_frag_pernet_id __read_mostly;
3737
static struct inet_frags nf_frags;
3838

3939
static struct nft_ct_frag6_pernet *nf_frag_pernet(struct net *net)

net/ipv6/netfilter/nf_defrag_ipv6_hooks.c

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@
2525
#include <net/netfilter/nf_conntrack_zones.h>
2626
#include <net/netfilter/ipv6/nf_defrag_ipv6.h>
2727

28-
extern unsigned int nf_frag_pernet_id;
29-
3028
static DEFINE_MUTEX(defrag6_mutex);
3129

3230
static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum,
@@ -91,12 +89,10 @@ static const struct nf_hook_ops ipv6_defrag_ops[] = {
9189

9290
static void __net_exit defrag6_net_exit(struct net *net)
9391
{
94-
struct nft_ct_frag6_pernet *nf_frag = net_generic(net, nf_frag_pernet_id);
95-
96-
if (nf_frag->users) {
92+
if (net->nf.defrag_ipv6_users) {
9793
nf_unregister_net_hooks(net, ipv6_defrag_ops,
9894
ARRAY_SIZE(ipv6_defrag_ops));
99-
nf_frag->users = 0;
95+
net->nf.defrag_ipv6_users = 0;
10096
}
10197
}
10298

@@ -134,24 +130,23 @@ static void __exit nf_defrag_fini(void)
134130

135131
int nf_defrag_ipv6_enable(struct net *net)
136132
{
137-
struct nft_ct_frag6_pernet *nf_frag = net_generic(net, nf_frag_pernet_id);
138133
int err = 0;
139134

140135
mutex_lock(&defrag6_mutex);
141-
if (nf_frag->users == UINT_MAX) {
136+
if (net->nf.defrag_ipv6_users == UINT_MAX) {
142137
err = -EOVERFLOW;
143138
goto out_unlock;
144139
}
145140

146-
if (nf_frag->users) {
147-
nf_frag->users++;
141+
if (net->nf.defrag_ipv6_users) {
142+
net->nf.defrag_ipv6_users++;
148143
goto out_unlock;
149144
}
150145

151146
err = nf_register_net_hooks(net, ipv6_defrag_ops,
152147
ARRAY_SIZE(ipv6_defrag_ops));
153148
if (err == 0)
154-
nf_frag->users = 1;
149+
net->nf.defrag_ipv6_users = 1;
155150

156151
out_unlock:
157152
mutex_unlock(&defrag6_mutex);
@@ -161,12 +156,10 @@ EXPORT_SYMBOL_GPL(nf_defrag_ipv6_enable);
161156

162157
void nf_defrag_ipv6_disable(struct net *net)
163158
{
164-
struct nft_ct_frag6_pernet *nf_frag = net_generic(net, nf_frag_pernet_id);
165-
166159
mutex_lock(&defrag6_mutex);
167-
if (nf_frag->users) {
168-
nf_frag->users--;
169-
if (nf_frag->users == 0)
160+
if (net->nf.defrag_ipv6_users) {
161+
net->nf.defrag_ipv6_users--;
162+
if (net->nf.defrag_ipv6_users == 0)
170163
nf_unregister_net_hooks(net, ipv6_defrag_ops,
171164
ARRAY_SIZE(ipv6_defrag_ops));
172165
}

0 commit comments

Comments
 (0)