#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/netfilter.h>
-#include <linux/mutex.h>
#include <net/sock.h>
#include "nf_internals.h"
/* Sockopts only registered and called from user context, so
net locking would be overkill. Also, [gs]etsockopt calls may
sleep. */
-static DEFINE_MUTEX(nf_sockopt_mutex);
+static DECLARE_MUTEX(nf_sockopt_mutex);
static LIST_HEAD(nf_sockopts);
/* Do exclusive ranges overlap? */
struct list_head *i;
int ret = 0;
- if (mutex_lock_interruptible(&nf_sockopt_mutex) != 0)
+ if (down_interruptible(&nf_sockopt_mutex) != 0)
return -EINTR;
list_for_each(i, &nf_sockopts) {
list_add(®->list, &nf_sockopts);
out:
- mutex_unlock(&nf_sockopt_mutex);
+ up(&nf_sockopt_mutex);
return ret;
}
EXPORT_SYMBOL(nf_register_sockopt);
{
/* No point being interruptible: we're probably in cleanup_module() */
restart:
- mutex_lock(&nf_sockopt_mutex);
+ down(&nf_sockopt_mutex);
if (reg->use != 0) {
/* To be woken by nf_sockopt call... */
/* FIXME: Stuart Young's name appears gratuitously. */
set_current_state(TASK_UNINTERRUPTIBLE);
reg->cleanup_task = current;
- mutex_unlock(&nf_sockopt_mutex);
+ up(&nf_sockopt_mutex);
schedule();
goto restart;
}
list_del(®->list);
- mutex_unlock(&nf_sockopt_mutex);
+ up(&nf_sockopt_mutex);
}
EXPORT_SYMBOL(nf_unregister_sockopt);
struct nf_sockopt_ops *ops;
int ret;
- if (mutex_lock_interruptible(&nf_sockopt_mutex) != 0)
+ if (down_interruptible(&nf_sockopt_mutex) != 0)
return -EINTR;
list_for_each(i, &nf_sockopts) {
if (val >= ops->get_optmin
&& val < ops->get_optmax) {
ops->use++;
- mutex_unlock(&nf_sockopt_mutex);
+ up(&nf_sockopt_mutex);
ret = ops->get(sk, val, opt, len);
goto out;
}
if (val >= ops->set_optmin
&& val < ops->set_optmax) {
ops->use++;
- mutex_unlock(&nf_sockopt_mutex);
+ up(&nf_sockopt_mutex);
ret = ops->set(sk, val, opt, *len);
goto out;
}
}
}
}
- mutex_unlock(&nf_sockopt_mutex);
+ up(&nf_sockopt_mutex);
return -ENOPROTOOPT;
out:
- mutex_lock(&nf_sockopt_mutex);
+ down(&nf_sockopt_mutex);
ops->use--;
if (ops->cleanup_task)
wake_up_process(ops->cleanup_task);
- mutex_unlock(&nf_sockopt_mutex);
+ up(&nf_sockopt_mutex);
return ret;
}
}
EXPORT_SYMBOL(nf_getsockopt);
-#ifdef CONFIG_COMPAT
-static int compat_nf_sockopt(struct sock *sk, int pf, int val,
- char __user *opt, int *len, int get)
-{
- struct list_head *i;
- struct nf_sockopt_ops *ops;
- int ret;
-
- if (mutex_lock_interruptible(&nf_sockopt_mutex) != 0)
- return -EINTR;
-
- list_for_each(i, &nf_sockopts) {
- ops = (struct nf_sockopt_ops *)i;
- if (ops->pf == pf) {
- if (get) {
- if (val >= ops->get_optmin
- && val < ops->get_optmax) {
- ops->use++;
- 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) {
- ops->use++;
- 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;
- }
- }
- }
- }
- mutex_unlock(&nf_sockopt_mutex);
- return -ENOPROTOOPT;
-
- out:
- mutex_lock(&nf_sockopt_mutex);
- ops->use--;
- if (ops->cleanup_task)
- wake_up_process(ops->cleanup_task);
- mutex_unlock(&nf_sockopt_mutex);
- return ret;
-}
-
-int compat_nf_setsockopt(struct sock *sk, int pf,
- int val, char __user *opt, int len)
-{
- return compat_nf_sockopt(sk, pf, val, opt, &len, 0);
-}
-EXPORT_SYMBOL(compat_nf_setsockopt);
-
-int compat_nf_getsockopt(struct sock *sk, int pf,
- int val, char __user *opt, int *len)
-{
- return compat_nf_sockopt(sk, pf, val, opt, len, 1);
-}
-EXPORT_SYMBOL(compat_nf_getsockopt);
-#endif