[NETFILTER]: nf_nat: switch rwlock to spinlock
Since we're using RCU, all users of nf_nat_lock take a write_lock. Switch it to a spinlock. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
4d354c5782
commit
02502f6224
|
@ -31,7 +31,7 @@
|
||||||
#include <net/netfilter/nf_conntrack_l3proto.h>
|
#include <net/netfilter/nf_conntrack_l3proto.h>
|
||||||
#include <net/netfilter/nf_conntrack_l4proto.h>
|
#include <net/netfilter/nf_conntrack_l4proto.h>
|
||||||
|
|
||||||
static DEFINE_RWLOCK(nf_nat_lock);
|
static DEFINE_SPINLOCK(nf_nat_lock);
|
||||||
|
|
||||||
static struct nf_conntrack_l3proto *l3proto __read_mostly;
|
static struct nf_conntrack_l3proto *l3proto __read_mostly;
|
||||||
|
|
||||||
|
@ -330,12 +330,12 @@ nf_nat_setup_info(struct nf_conn *ct,
|
||||||
unsigned int srchash;
|
unsigned int srchash;
|
||||||
|
|
||||||
srchash = hash_by_src(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
|
srchash = hash_by_src(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
|
||||||
write_lock_bh(&nf_nat_lock);
|
spin_lock_bh(&nf_nat_lock);
|
||||||
/* nf_conntrack_alter_reply might re-allocate exntension aera */
|
/* nf_conntrack_alter_reply might re-allocate exntension aera */
|
||||||
nat = nfct_nat(ct);
|
nat = nfct_nat(ct);
|
||||||
nat->ct = ct;
|
nat->ct = ct;
|
||||||
hlist_add_head_rcu(&nat->bysource, &bysource[srchash]);
|
hlist_add_head_rcu(&nat->bysource, &bysource[srchash]);
|
||||||
write_unlock_bh(&nf_nat_lock);
|
spin_unlock_bh(&nf_nat_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* It's done. */
|
/* It's done. */
|
||||||
|
@ -521,14 +521,14 @@ int nf_nat_protocol_register(const struct nf_nat_protocol *proto)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
write_lock_bh(&nf_nat_lock);
|
spin_lock_bh(&nf_nat_lock);
|
||||||
if (nf_nat_protos[proto->protonum] != &nf_nat_unknown_protocol) {
|
if (nf_nat_protos[proto->protonum] != &nf_nat_unknown_protocol) {
|
||||||
ret = -EBUSY;
|
ret = -EBUSY;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
rcu_assign_pointer(nf_nat_protos[proto->protonum], proto);
|
rcu_assign_pointer(nf_nat_protos[proto->protonum], proto);
|
||||||
out:
|
out:
|
||||||
write_unlock_bh(&nf_nat_lock);
|
spin_unlock_bh(&nf_nat_lock);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(nf_nat_protocol_register);
|
EXPORT_SYMBOL(nf_nat_protocol_register);
|
||||||
|
@ -536,10 +536,10 @@ EXPORT_SYMBOL(nf_nat_protocol_register);
|
||||||
/* Noone stores the protocol anywhere; simply delete it. */
|
/* Noone stores the protocol anywhere; simply delete it. */
|
||||||
void nf_nat_protocol_unregister(const struct nf_nat_protocol *proto)
|
void nf_nat_protocol_unregister(const struct nf_nat_protocol *proto)
|
||||||
{
|
{
|
||||||
write_lock_bh(&nf_nat_lock);
|
spin_lock_bh(&nf_nat_lock);
|
||||||
rcu_assign_pointer(nf_nat_protos[proto->protonum],
|
rcu_assign_pointer(nf_nat_protos[proto->protonum],
|
||||||
&nf_nat_unknown_protocol);
|
&nf_nat_unknown_protocol);
|
||||||
write_unlock_bh(&nf_nat_lock);
|
spin_unlock_bh(&nf_nat_lock);
|
||||||
synchronize_rcu();
|
synchronize_rcu();
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(nf_nat_protocol_unregister);
|
EXPORT_SYMBOL(nf_nat_protocol_unregister);
|
||||||
|
@ -594,10 +594,10 @@ static void nf_nat_cleanup_conntrack(struct nf_conn *ct)
|
||||||
|
|
||||||
NF_CT_ASSERT(nat->ct->status & IPS_NAT_DONE_MASK);
|
NF_CT_ASSERT(nat->ct->status & IPS_NAT_DONE_MASK);
|
||||||
|
|
||||||
write_lock_bh(&nf_nat_lock);
|
spin_lock_bh(&nf_nat_lock);
|
||||||
hlist_del_rcu(&nat->bysource);
|
hlist_del_rcu(&nat->bysource);
|
||||||
nat->ct = NULL;
|
nat->ct = NULL;
|
||||||
write_unlock_bh(&nf_nat_lock);
|
spin_unlock_bh(&nf_nat_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nf_nat_move_storage(struct nf_conn *conntrack, void *old)
|
static void nf_nat_move_storage(struct nf_conn *conntrack, void *old)
|
||||||
|
@ -609,10 +609,10 @@ static void nf_nat_move_storage(struct nf_conn *conntrack, void *old)
|
||||||
if (!ct || !(ct->status & IPS_NAT_DONE_MASK))
|
if (!ct || !(ct->status & IPS_NAT_DONE_MASK))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
write_lock_bh(&nf_nat_lock);
|
spin_lock_bh(&nf_nat_lock);
|
||||||
hlist_replace_rcu(&old_nat->bysource, &new_nat->bysource);
|
hlist_replace_rcu(&old_nat->bysource, &new_nat->bysource);
|
||||||
new_nat->ct = ct;
|
new_nat->ct = ct;
|
||||||
write_unlock_bh(&nf_nat_lock);
|
spin_unlock_bh(&nf_nat_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct nf_ct_ext_type nat_extend __read_mostly = {
|
static struct nf_ct_ext_type nat_extend __read_mostly = {
|
||||||
|
@ -646,13 +646,13 @@ static int __init nf_nat_init(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sew in builtin protocols. */
|
/* Sew in builtin protocols. */
|
||||||
write_lock_bh(&nf_nat_lock);
|
spin_lock_bh(&nf_nat_lock);
|
||||||
for (i = 0; i < MAX_IP_NAT_PROTO; i++)
|
for (i = 0; i < MAX_IP_NAT_PROTO; i++)
|
||||||
rcu_assign_pointer(nf_nat_protos[i], &nf_nat_unknown_protocol);
|
rcu_assign_pointer(nf_nat_protos[i], &nf_nat_unknown_protocol);
|
||||||
rcu_assign_pointer(nf_nat_protos[IPPROTO_TCP], &nf_nat_protocol_tcp);
|
rcu_assign_pointer(nf_nat_protos[IPPROTO_TCP], &nf_nat_protocol_tcp);
|
||||||
rcu_assign_pointer(nf_nat_protos[IPPROTO_UDP], &nf_nat_protocol_udp);
|
rcu_assign_pointer(nf_nat_protos[IPPROTO_UDP], &nf_nat_protocol_udp);
|
||||||
rcu_assign_pointer(nf_nat_protos[IPPROTO_ICMP], &nf_nat_protocol_icmp);
|
rcu_assign_pointer(nf_nat_protos[IPPROTO_ICMP], &nf_nat_protocol_icmp);
|
||||||
write_unlock_bh(&nf_nat_lock);
|
spin_unlock_bh(&nf_nat_lock);
|
||||||
|
|
||||||
/* Initialize fake conntrack so that NAT will skip it */
|
/* Initialize fake conntrack so that NAT will skip it */
|
||||||
nf_conntrack_untracked.status |= IPS_NAT_DONE_MASK;
|
nf_conntrack_untracked.status |= IPS_NAT_DONE_MASK;
|
||||||
|
|
Loading…
Reference in a new issue