[NETFILTER]: nfnetlink: use mutex instead of semaphore
Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
c6a1e615d1
commit
a3c5029cf7
@@ -129,19 +129,6 @@ extern void __nfa_fill(struct sk_buff *skb, int attrtype,
|
|||||||
({ if (skb_tailroom(skb) < (int)NFA_SPACE(attrlen)) goto nfattr_failure; \
|
({ if (skb_tailroom(skb) < (int)NFA_SPACE(attrlen)) goto nfattr_failure; \
|
||||||
__nfa_fill(skb, attrtype, attrlen, data); })
|
__nfa_fill(skb, attrtype, attrlen, data); })
|
||||||
|
|
||||||
extern struct semaphore nfnl_sem;
|
|
||||||
|
|
||||||
#define nfnl_shlock() down(&nfnl_sem)
|
|
||||||
#define nfnl_shlock_nowait() down_trylock(&nfnl_sem)
|
|
||||||
|
|
||||||
#define nfnl_shunlock() do { up(&nfnl_sem); \
|
|
||||||
if(nfnl && nfnl->sk_receive_queue.qlen) \
|
|
||||||
nfnl->sk_data_ready(nfnl, 0); \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
extern void nfnl_lock(void);
|
|
||||||
extern void nfnl_unlock(void);
|
|
||||||
|
|
||||||
extern int nfnetlink_subsys_register(struct nfnetlink_subsystem *n);
|
extern int nfnetlink_subsys_register(struct nfnetlink_subsystem *n);
|
||||||
extern int nfnetlink_subsys_unregister(struct nfnetlink_subsystem *n);
|
extern int nfnetlink_subsys_unregister(struct nfnetlink_subsystem *n);
|
||||||
|
|
||||||
|
@@ -90,10 +90,7 @@ extern struct nf_conntrack_l3proto *nf_ct_l3protos[AF_MAX];
|
|||||||
/* Protocol registration. */
|
/* Protocol registration. */
|
||||||
extern int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto);
|
extern int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto);
|
||||||
extern void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto);
|
extern void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto);
|
||||||
|
extern struct nf_conntrack_l3proto *nf_ct_l3proto_find_get(u_int16_t l3proto);
|
||||||
extern struct nf_conntrack_l3proto *
|
|
||||||
nf_ct_l3proto_find_get(u_int16_t l3proto);
|
|
||||||
|
|
||||||
extern void nf_ct_l3proto_put(struct nf_conntrack_l3proto *p);
|
extern void nf_ct_l3proto_put(struct nf_conntrack_l3proto *p);
|
||||||
|
|
||||||
/* Existing built-in protocols */
|
/* Existing built-in protocols */
|
||||||
|
@@ -28,6 +28,7 @@
|
|||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include <asm/system.h>
|
#include <asm/system.h>
|
||||||
#include <net/sock.h>
|
#include <net/sock.h>
|
||||||
|
#include <net/netlink.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
|
|
||||||
@@ -51,16 +52,28 @@ static char __initdata nfversion[] = "0.30";
|
|||||||
|
|
||||||
static struct sock *nfnl = NULL;
|
static struct sock *nfnl = NULL;
|
||||||
static struct nfnetlink_subsystem *subsys_table[NFNL_SUBSYS_COUNT];
|
static struct nfnetlink_subsystem *subsys_table[NFNL_SUBSYS_COUNT];
|
||||||
DECLARE_MUTEX(nfnl_sem);
|
static DEFINE_MUTEX(nfnl_mutex);
|
||||||
|
|
||||||
void nfnl_lock(void)
|
static void nfnl_lock(void)
|
||||||
{
|
{
|
||||||
nfnl_shlock();
|
mutex_lock(&nfnl_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nfnl_unlock(void)
|
static int nfnl_trylock(void)
|
||||||
{
|
{
|
||||||
nfnl_shunlock();
|
return !mutex_trylock(&nfnl_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __nfnl_unlock(void)
|
||||||
|
{
|
||||||
|
mutex_unlock(&nfnl_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nfnl_unlock(void)
|
||||||
|
{
|
||||||
|
mutex_unlock(&nfnl_mutex);
|
||||||
|
if (nfnl->sk_receive_queue.qlen)
|
||||||
|
nfnl->sk_data_ready(nfnl, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int nfnetlink_subsys_register(struct nfnetlink_subsystem *n)
|
int nfnetlink_subsys_register(struct nfnetlink_subsystem *n)
|
||||||
@@ -248,11 +261,11 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb,
|
|||||||
ss = nfnetlink_get_subsys(type);
|
ss = nfnetlink_get_subsys(type);
|
||||||
if (!ss) {
|
if (!ss) {
|
||||||
#ifdef CONFIG_KMOD
|
#ifdef CONFIG_KMOD
|
||||||
/* don't call nfnl_shunlock, since it would reenter
|
/* don't call nfnl_unlock, since it would reenter
|
||||||
* with further packet processing */
|
* with further packet processing */
|
||||||
up(&nfnl_sem);
|
__nfnl_unlock();
|
||||||
request_module("nfnetlink-subsys-%d", NFNL_SUBSYS_ID(type));
|
request_module("nfnetlink-subsys-%d", NFNL_SUBSYS_ID(type));
|
||||||
nfnl_shlock();
|
nfnl_lock();
|
||||||
ss = nfnetlink_get_subsys(type);
|
ss = nfnetlink_get_subsys(type);
|
||||||
if (!ss)
|
if (!ss)
|
||||||
#endif
|
#endif
|
||||||
@@ -322,7 +335,7 @@ static void nfnetlink_rcv(struct sock *sk, int len)
|
|||||||
do {
|
do {
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
|
|
||||||
if (nfnl_shlock_nowait())
|
if (nfnl_trylock())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
|
while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
|
||||||
@@ -337,9 +350,9 @@ static void nfnetlink_rcv(struct sock *sk, int len)
|
|||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* don't call nfnl_shunlock, since it would reenter
|
/* don't call nfnl_unlock, since it would reenter
|
||||||
* with further packet processing */
|
* with further packet processing */
|
||||||
up(&nfnl_sem);
|
__nfnl_unlock();
|
||||||
} while(nfnl && nfnl->sk_receive_queue.qlen);
|
} while(nfnl && nfnl->sk_receive_queue.qlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user