X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fipv6%2Fnetfilter%2Fip6_queue.c;h=af0635084df8217dcc226a82c1a4ea3183e4df58;hb=987b0145d94eecf292d8b301228356f44611ab7c;hp=b4b7d441af25411f04af9e7a657cb21488f51370;hpb=f7ed79d23a47594e7834d66a8f14449796d4f3e6;p=linux-2.6.git diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c index b4b7d441a..af0635084 100644 --- a/net/ipv6/netfilter/ip6_queue.c +++ b/net/ipv6/netfilter/ip6_queue.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include #include @@ -66,7 +65,7 @@ static unsigned int queue_dropped = 0; static unsigned int queue_user_dropped = 0; static struct sock *ipqnl; static LIST_HEAD(queue_list); -static DEFINE_MUTEX(ipqnl_mutex); +static DECLARE_MUTEX(ipqnl_sem); static void ipq_issue_verdict(struct ipq_queue_entry *entry, int verdict) @@ -538,7 +537,7 @@ ipq_rcv_sk(struct sock *sk, int len) struct sk_buff *skb; unsigned int qlen; - mutex_lock(&ipqnl_mutex); + down(&ipqnl_sem); for (qlen = skb_queue_len(&sk->sk_receive_queue); qlen; qlen--) { skb = skb_dequeue(&sk->sk_receive_queue); @@ -546,7 +545,7 @@ ipq_rcv_sk(struct sock *sk, int len) kfree_skb(skb); } - mutex_unlock(&ipqnl_mutex); + up(&ipqnl_sem); } static int @@ -658,11 +657,15 @@ static struct nf_queue_handler nfqh = { .outfn = &ipq_enqueue_packet, }; -static int __init ip6_queue_init(void) +static int +init_or_cleanup(int init) { int status = -ENOMEM; struct proc_dir_entry *proc; + if (!init) + goto cleanup; + netlink_register_notifier(&ipq_nl_notifier); ipqnl = netlink_kernel_create(NETLINK_IP6_FW, 0, ipq_rcv_sk, THIS_MODULE); @@ -689,6 +692,11 @@ static int __init ip6_queue_init(void) } return status; +cleanup: + nf_unregister_queue_handlers(&nfqh); + synchronize_net(); + ipq_flush(NF_DROP); + cleanup_sysctl: unregister_sysctl_table(ipq_sysctl_header); unregister_netdevice_notifier(&ipq_dev_notifier); @@ -696,33 +704,27 @@ cleanup_sysctl: cleanup_ipqnl: sock_release(ipqnl->sk_socket); - mutex_lock(&ipqnl_mutex); - mutex_unlock(&ipqnl_mutex); + down(&ipqnl_sem); + up(&ipqnl_sem); cleanup_netlink_notifier: netlink_unregister_notifier(&ipq_nl_notifier); return status; } -static void __exit ip6_queue_fini(void) +static int __init init(void) { - nf_unregister_queue_handlers(&nfqh); - synchronize_net(); - ipq_flush(NF_DROP); - - unregister_sysctl_table(ipq_sysctl_header); - unregister_netdevice_notifier(&ipq_dev_notifier); - proc_net_remove(IPQ_PROC_FS_NAME); - - sock_release(ipqnl->sk_socket); - mutex_lock(&ipqnl_mutex); - mutex_unlock(&ipqnl_mutex); + + return init_or_cleanup(1); +} - netlink_unregister_notifier(&ipq_nl_notifier); +static void __exit fini(void) +{ + init_or_cleanup(0); } MODULE_DESCRIPTION("IPv6 packet queue handler"); MODULE_LICENSE("GPL"); -module_init(ip6_queue_init); -module_exit(ip6_queue_fini); +module_init(init); +module_exit(fini);