: Netfilter fixes
Subsystems (3)
cover : Netfilter fixes
Hi Dave,
these three patches fix a nf_nat memset error, leading to misbehaviour when unloading and reloading the NAT module, a regression from the bridge netfilter deferred hook removal causing double invocation of the POSTROUTING hook for packets forwarded between two bridge devices and consolidate the nf_sockopt code. I'll push the memset and bridge fixes to -stable once they hit Linus' tree.
Please apply, thanks.
net/bridge/br_netfilter.c | 3 + net/ipv4/netfilter/nf_nat_core.c | 2 +- net/netfilter/nf_sockopt.c | 106 ++++++++++++++++---------------------- 3 files changed, 48 insertions(+), 63 deletions(-)
Li Zefan (1):
[NETFILTER]: nf_nat: fix memset error
Patrick McHardy (1):
[NETFILTER]: bridge: fix double POSTROUTING hook invocation
Pavel Emelyanov (1):
[NETFILTER]: Consolidate nf_sockopt and compat_nf_sockopt
PATCH 1/3 : nf_nat: fix memset error
[NETFILTER]: nf_nat: fix memset error
The size passing to memset is the size of a pointer.
---
commit dd9e04a6e68abf79470ef26e242ce516bba37b3d
tree 0d6b56e83d643661a9726931a577d6626a2cfb3f
parent 325d22df7b19e0116aff3391d3a03f73d0634ded
author Li Zefan <[email protected]> Tue, 13 Nov 2007 11:24:16 +0100 committer Patrick McHardy <[email protected]> Tue, 13 Nov 2007 11:24:16 +0100
net/ipv4/netfilter/nf_nat_core.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
net/ipv4/netfilter/nf_nat_core.c +1 -1
@@ -681,7 +681,7 @@ static int clean_nat(struct nf_conn *i, void *data)if (!nat)return 0 ; -memset (nat,0 ,sizeof (nat)); +memset (nat,0 ,sizeof (*nat)); i->status &= ~(IPS_NAT_MASK |IPS_NAT_DONE_MASK |IPS_SEQ_ADJUST );return 0 ; }
Re: [NETFILTER 01/03]: nf_nat: fix memset error
From: Patrick McHardy <[email protected]>
Date: Tue, 13 Nov 2007 11:55:41 +0100 (MET)
Quoted 6 lines
[NETFILTER]:
nf_nat: fix memset errorThe size passing to memset is the size of a pointer.
Signed-off-by Li Zefan <[email protected]>Signed-off-by Patrick McHardy <[email protected]>
Applied.
PATCH 2/3 : Consolidate nf_sockopt and compat_nf_sockopt
In reply to Patrick McHardy[NETFILTER]: Consolidate nf_sockopt and compat_nf_sockopt
Both lookup the nf_sockopt_ops object to call the get/set callbacks from, but they perform it in a completely similar way.
Introduce the helper for finding the ops.
---
commit c94ac2cb9896fbed3065dc08216a7d13b98f0d92
tree 2e4bd21d850cef9bbc53be588dc7590636232a4b
parent dd9e04a6e68abf79470ef26e242ce516bba37b3d
author Pavel Emelyanov <[email protected]> Tue, 13 Nov 2007 11:24:17 +0100 committer Patrick McHardy <[email protected]> Tue, 13 Nov 2007 11:24:17 +0100
net/netfilter/nf_sockopt.c | 106 ++++++++++++++++++-------------------------- 1 files changed, 44 insertions(+), 62 deletions(-)
net/netfilter/nf_sockopt.c +44 -62
@@ -60,46 +60,57 @@ void nf_unregister_sockopt(struct nf_sockopt_ops *reg) }EXPORT_SYMBOL (nf_unregister_sockopt); -/* Call get/setsockopt() */ -static int nf_sockopt (struct sock *sk,int pf,int val, -char __user *opt,int *len,int get) +static struct nf_sockopt_ops *nf_sockopt_find (struct sock *sk,int pf, +int val,int get) {struct nf_sockopt_ops *ops; -int ret;if (sk->sk_net != &init_net) -return -ENOPROTOOPT ; +return ERR_PTR (-ENOPROTOOPT );if (mutex_lock_interruptible (&nf_sockopt_mutex) !=0 ) -return -EINTR ; +return ERR_PTR (-EINTR );list_for_each_entry (ops, &nf_sockopts, list) {if (ops->pf == pf) {if (!try_module_get (ops->owner)) goto out_nosup; +if (get) { -if (val >= ops->get_optmin - && val < ops->get_optmax) { -mutex_unlock (&nf_sockopt_mutex); - ret = ops->get (sk, val, opt, len); +if (val >= ops->get_optmin && + val < ops->get_optmax) goto out; - } }else { -if (val >= ops->set_optmin - && val < ops->set_optmax) { -mutex_unlock (&nf_sockopt_mutex); - ret = ops->set (sk, val, opt, *len); +if (val >= ops->set_optmin && + val < ops->set_optmax) goto out; - } }module_put (ops->owner); } } - out_nosup: +out_nosup: + ops =ERR_PTR (-ENOPROTOOPT ); +out:mutex_unlock (&nf_sockopt_mutex); -return -ENOPROTOOPT ; +return ops; +} + +/* Call get/setsockopt() */ +static int nf_sockopt (struct sock *sk,int pf,int val, +char __user *opt,int *len,int get) +{ +struct nf_sockopt_ops *ops; +int ret; + + ops =nf_sockopt_find (sk, pf, val, get); +if (IS_ERR (ops)) +return PTR_ERR (ops); + +if (get) + ret = ops->get (sk, val, opt, len); +else + ret = ops->set (sk, val, opt, *len); - out:module_put (ops->owner);return ret; }
@@ -124,51 +135,22 @@ static int compat_nf_sockopt(struct sock *sk, int pf, int val,struct nf_sockopt_ops *ops;int ret; -if (sk->sk_net != &init_net) -return -ENOPROTOOPT ; - - -if (mutex_lock_interruptible (&nf_sockopt_mutex) !=0 ) -return -EINTR ; - -list_for_each_entry (ops, &nf_sockopts, list) { -if (ops->pf == pf) { -if (!try_module_get (ops->owner)) - goto out_nosup; - -if (get) { -if (val >= ops->get_optmin - && val < ops->get_optmax) { -mutex_unlock (&nf_sockopt_mutex); -if (ops->compat_get) - ret = ops->compat_get (sk, - val, opt, len); -else - ret = ops->get (sk, - val, opt, len); - goto out; - } - }else { -if (val >= ops->set_optmin - && val < ops->set_optmax) { -mutex_unlock (&nf_sockopt_mutex); -if (ops->compat_set) - ret = ops->compat_set (sk, - val, opt, *len); -else - ret = ops->set (sk, - val, opt, *len); - goto out; - } - } -module_put (ops->owner); - } + ops =nf_sockopt_find (sk, pf, val, get); +if (IS_ERR (ops)) +return PTR_ERR (ops); + +if (get) { +if (ops->compat_get) + ret = ops->compat_get (sk, val, opt, len); +else + ret = ops->get (sk, val, ops, len); + }else { +if (ops->compat_set) + ret = ops->compat_set (sk, val, ops, *len); +else + ret = ops->set (sk, val, ops, *len); } - out_nosup: -mutex_unlock (&nf_sockopt_mutex); -return -ENOPROTOOPT ; - out:module_put (ops->owner);return ret; }
Re: [NETFILTER 02/03]: Consolidate nf_sockopt and compat_nf_sockopt
From: Patrick McHardy <[email protected]>
Date: Tue, 13 Nov 2007 11:55:42 +0100 (MET)
Quoted 9 lines
[NETFILTER]: Consolidate
nf_sockoptandcompat_nf_sockoptBoth lookup the
nf_sockopt_opsobject to call the get/set callbacks from, but they perform it in a completely similar way.Introduce the helper for finding the ops.
Signed-off-by Pavel Emelyanov <[email protected]>Signed-off-by Patrick McHardy <[email protected]>
Applied.
PATCH 3/3 : bridge: fix double POSTROUTING hook invocation
In reply to Patrick McHardy[NETFILTER]: bridge: fix double POSTROUTING hook invocation
Packets routed between bridges have the POST_ROUTING hook invoked twice since bridging mistakes them for bridged packets because they have skb->nf_bridge set.
---
commit 87a1cd0a4fc1f5ac17e2e752668ae324c595b1fd
tree 38c7fdb13f7232bf77fb78ce4292a4bb1cdd5dfd
parent c94ac2cb9896fbed3065dc08216a7d13b98f0d92
author Patrick McHardy <[email protected]> Tue, 13 Nov 2007 11:24:18 +0100 committer Patrick McHardy <[email protected]> Tue, 13 Nov 2007 11:24:18 +0100
net/bridge/br_netfilter.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-)
net/bridge/br_netfilter.c +3 -0
@@ -766,6 +766,9 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff *skb,if (!nf_bridge)return NF_ACCEPT ; +if (!(nf_bridge->mask & (BRNF_BRIDGED |BRNF_BRIDGED_DNAT ))) +return NF_ACCEPT ; +if (!realoutdev)return NF_DROP ;
David Miller
maintainerRe: [NETFILTER 03/03]: bridge: fix double POSTROUTING hook invocation
From: Patrick McHardy <[email protected]>
Date: Tue, 13 Nov 2007 11:55:44 +0100 (MET)
Quoted 7 lines
[NETFILTER]: bridge: fix double POSTROUTING hook invocation
Packets routed between bridges have the
POST_ROUTINGhook invoked twice since bridging mistakes them for bridged packets because they haveskb->nf_bridgeset.Signed-off-by Patrick McHardy <[email protected]>
Also applied, thanks Patrick.