#define ASSERT_READ_LOCK(x)
#define ASSERT_WRITE_LOCK(x)
#include <linux/netfilter_ipv4/listhelp.h>
+#include <linux/mutex.h>
-#if 0
-/* use this for remote debugging
- * Copyright (C) 1998 by Ori Pomerantz
- * Print the string to the appropriate tty, the one
- * the current task uses
- */
-static void print_string(char *str)
-{
- struct tty_struct *my_tty;
-
- /* The tty for the current task */
- my_tty = current->signal->tty;
- if (my_tty != NULL) {
- my_tty->driver->write(my_tty, 0, str, strlen(str));
- my_tty->driver->write(my_tty, 0, "\015\012", 2);
- }
-}
-
-#define BUGPRINT(args) print_string(args);
-#else
#define BUGPRINT(format, args...) printk("kernel msg: ebtables bug: please "\
"report to author: "format, ## args)
/* #define BUGPRINT(format, args...) */
-#endif
#define MEMPRINT(format, args...) printk("kernel msg: ebtables "\
": out of memory: "format, ## args)
/* #define MEMPRINT(format, args...) */
-static DECLARE_MUTEX(ebt_mutex);
+static DEFINE_MUTEX(ebt_mutex);
static LIST_HEAD(ebt_tables);
static LIST_HEAD(ebt_targets);
static LIST_HEAD(ebt_matches);
/* If it succeeds, returns element and locks mutex */
static inline void *
find_inlist_lock_noload(struct list_head *head, const char *name, int *error,
- struct semaphore *mutex)
+ struct mutex *mutex)
{
void *ret;
- *error = down_interruptible(mutex);
+ *error = mutex_lock_interruptible(mutex);
if (*error != 0)
return NULL;
ret = list_named_find(head, name);
if (!ret) {
*error = -ENOENT;
- up(mutex);
+ mutex_unlock(mutex);
}
return ret;
}
#else
static void *
find_inlist_lock(struct list_head *head, const char *name, const char *prefix,
- int *error, struct semaphore *mutex)
+ int *error, struct mutex *mutex)
{
void *ret;
#endif
static inline struct ebt_table *
-find_table_lock(const char *name, int *error, struct semaphore *mutex)
+find_table_lock(const char *name, int *error, struct mutex *mutex)
{
return find_inlist_lock(&ebt_tables, name, "ebtable_", error, mutex);
}
static inline struct ebt_match *
-find_match_lock(const char *name, int *error, struct semaphore *mutex)
+find_match_lock(const char *name, int *error, struct mutex *mutex)
{
return find_inlist_lock(&ebt_matches, name, "ebt_", error, mutex);
}
static inline struct ebt_watcher *
-find_watcher_lock(const char *name, int *error, struct semaphore *mutex)
+find_watcher_lock(const char *name, int *error, struct mutex *mutex)
{
return find_inlist_lock(&ebt_watchers, name, "ebt_", error, mutex);
}
static inline struct ebt_target *
-find_target_lock(const char *name, int *error, struct semaphore *mutex)
+find_target_lock(const char *name, int *error, struct mutex *mutex)
{
return find_inlist_lock(&ebt_targets, name, "ebt_", error, mutex);
}
return ret;
m->u.match = match;
if (!try_module_get(match->me)) {
- up(&ebt_mutex);
+ mutex_unlock(&ebt_mutex);
return -ENOENT;
}
- up(&ebt_mutex);
+ mutex_unlock(&ebt_mutex);
if (match->check &&
match->check(name, hookmask, e, m->data, m->match_size) != 0) {
BUGPRINT("match->check failed\n");
return ret;
w->u.watcher = watcher;
if (!try_module_get(watcher->me)) {
- up(&ebt_mutex);
+ mutex_unlock(&ebt_mutex);
return -ENOENT;
}
- up(&ebt_mutex);
+ mutex_unlock(&ebt_mutex);
if (watcher->check &&
watcher->check(name, hookmask, e, w->data, w->watcher_size) != 0) {
BUGPRINT("watcher->check failed\n");
if (!target)
goto cleanup_watchers;
if (!try_module_get(target->me)) {
- up(&ebt_mutex);
+ mutex_unlock(&ebt_mutex);
ret = -ENOENT;
goto cleanup_watchers;
}
- up(&ebt_mutex);
+ mutex_unlock(&ebt_mutex);
t->u.target = target;
if (t->u.target == &ebt_standard_target) {
if (udc_cnt) {
/* this will get free'd in do_replace()/ebt_register_table()
if an error occurs */
- newinfo->chainstack = (struct ebt_chainstack **)
- vmalloc((highest_possible_processor_id()+1)
- * sizeof(struct ebt_chainstack));
+ newinfo->chainstack =
+ vmalloc((highest_possible_processor_id()+1)
+ * sizeof(*(newinfo->chainstack)));
if (!newinfo->chainstack)
return -ENOMEM;
- for_each_cpu(i) {
+ for_each_possible_cpu(i) {
newinfo->chainstack[i] =
- vmalloc(udc_cnt * sizeof(struct ebt_chainstack));
+ vmalloc(udc_cnt * sizeof(*(newinfo->chainstack[0])));
if (!newinfo->chainstack[i]) {
while (i)
vfree(newinfo->chainstack[--i]);
}
}
- cl_s = (struct ebt_cl_stack *)
- vmalloc(udc_cnt * sizeof(struct ebt_cl_stack));
+ cl_s = vmalloc(udc_cnt * sizeof(*cl_s));
if (!cl_s)
return -ENOMEM;
i = 0; /* the i'th udc */
sizeof(struct ebt_counter) * nentries);
/* add other counters to those of cpu 0 */
- for_each_cpu(cpu) {
+ for_each_possible_cpu(cpu) {
if (cpu == 0)
continue;
counter_base = COUNTER_BASE(oldcounters, nentries, cpu);
countersize = COUNTER_OFFSET(tmp.nentries) *
(highest_possible_processor_id()+1);
- newinfo = (struct ebt_table_info *)
- vmalloc(sizeof(struct ebt_table_info) + countersize);
+ newinfo = vmalloc(sizeof(*newinfo) + countersize);
if (!newinfo)
return -ENOMEM;
/* the user wants counters back
the check on the size is done later, when we have the lock */
if (tmp.num_counters) {
- counterstmp = (struct ebt_counter *)
- vmalloc(tmp.num_counters * sizeof(struct ebt_counter));
+ counterstmp = vmalloc(tmp.num_counters * sizeof(*counterstmp));
if (!counterstmp) {
ret = -ENOMEM;
goto free_entries;
t->private = newinfo;
write_unlock_bh(&t->lock);
- up(&ebt_mutex);
+ mutex_unlock(&ebt_mutex);
/* so, a user can change the chains while having messed up her counter
allocation. Only reason why this is done is because this way the lock
is held only once, while this doesn't bring the kernel into a
vfree(table->entries);
if (table->chainstack) {
- for_each_cpu(i)
+ for_each_possible_cpu(i)
vfree(table->chainstack[i]);
vfree(table->chainstack);
}
return ret;
free_unlock:
- up(&ebt_mutex);
+ mutex_unlock(&ebt_mutex);
free_iterate:
EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
ebt_cleanup_entry, NULL);
vfree(counterstmp);
/* can be initialized in translate_table() */
if (newinfo->chainstack) {
- for_each_cpu(i)
+ for_each_possible_cpu(i)
vfree(newinfo->chainstack[i]);
vfree(newinfo->chainstack);
}
{
int ret;
- ret = down_interruptible(&ebt_mutex);
+ ret = mutex_lock_interruptible(&ebt_mutex);
if (ret != 0)
return ret;
if (!list_named_insert(&ebt_targets, target)) {
- up(&ebt_mutex);
+ mutex_unlock(&ebt_mutex);
return -EEXIST;
}
- up(&ebt_mutex);
+ mutex_unlock(&ebt_mutex);
return 0;
}
void ebt_unregister_target(struct ebt_target *target)
{
- down(&ebt_mutex);
+ mutex_lock(&ebt_mutex);
LIST_DELETE(&ebt_targets, target);
- up(&ebt_mutex);
+ mutex_unlock(&ebt_mutex);
}
int ebt_register_match(struct ebt_match *match)
{
int ret;
- ret = down_interruptible(&ebt_mutex);
+ ret = mutex_lock_interruptible(&ebt_mutex);
if (ret != 0)
return ret;
if (!list_named_insert(&ebt_matches, match)) {
- up(&ebt_mutex);
+ mutex_unlock(&ebt_mutex);
return -EEXIST;
}
- up(&ebt_mutex);
+ mutex_unlock(&ebt_mutex);
return 0;
}
void ebt_unregister_match(struct ebt_match *match)
{
- down(&ebt_mutex);
+ mutex_lock(&ebt_mutex);
LIST_DELETE(&ebt_matches, match);
- up(&ebt_mutex);
+ mutex_unlock(&ebt_mutex);
}
int ebt_register_watcher(struct ebt_watcher *watcher)
{
int ret;
- ret = down_interruptible(&ebt_mutex);
+ ret = mutex_lock_interruptible(&ebt_mutex);
if (ret != 0)
return ret;
if (!list_named_insert(&ebt_watchers, watcher)) {
- up(&ebt_mutex);
+ mutex_unlock(&ebt_mutex);
return -EEXIST;
}
- up(&ebt_mutex);
+ mutex_unlock(&ebt_mutex);
return 0;
}
void ebt_unregister_watcher(struct ebt_watcher *watcher)
{
- down(&ebt_mutex);
+ mutex_lock(&ebt_mutex);
LIST_DELETE(&ebt_watchers, watcher);
- up(&ebt_mutex);
+ mutex_unlock(&ebt_mutex);
}
int ebt_register_table(struct ebt_table *table)
countersize = COUNTER_OFFSET(table->table->nentries) *
(highest_possible_processor_id()+1);
- newinfo = (struct ebt_table_info *)
- vmalloc(sizeof(struct ebt_table_info) + countersize);
+ newinfo = vmalloc(sizeof(*newinfo) + countersize);
ret = -ENOMEM;
if (!newinfo)
return -ENOMEM;
table->private = newinfo;
rwlock_init(&table->lock);
- ret = down_interruptible(&ebt_mutex);
+ ret = mutex_lock_interruptible(&ebt_mutex);
if (ret != 0)
goto free_chainstack;
goto free_unlock;
}
list_prepend(&ebt_tables, table);
- up(&ebt_mutex);
+ mutex_unlock(&ebt_mutex);
return 0;
free_unlock:
- up(&ebt_mutex);
+ mutex_unlock(&ebt_mutex);
free_chainstack:
if (newinfo->chainstack) {
- for_each_cpu(i)
+ for_each_possible_cpu(i)
vfree(newinfo->chainstack[i]);
vfree(newinfo->chainstack);
}
BUGPRINT("Request to unregister NULL table!!!\n");
return;
}
- down(&ebt_mutex);
+ mutex_lock(&ebt_mutex);
LIST_DELETE(&ebt_tables, table);
- up(&ebt_mutex);
+ mutex_unlock(&ebt_mutex);
vfree(table->private->entries);
if (table->private->chainstack) {
- for_each_cpu(i)
+ for_each_possible_cpu(i)
vfree(table->private->chainstack[i]);
vfree(table->private->chainstack);
}
if (hlp.num_counters == 0)
return -EINVAL;
- if ( !(tmp = (struct ebt_counter *)
- vmalloc(hlp.num_counters * sizeof(struct ebt_counter))) ){
+ if (!(tmp = vmalloc(hlp.num_counters * sizeof(*tmp)))) {
MEMPRINT("Update_counters && nomemory\n");
return -ENOMEM;
}
write_unlock_bh(&t->lock);
ret = 0;
unlock_mutex:
- up(&ebt_mutex);
+ mutex_unlock(&ebt_mutex);
free_tmp:
vfree(tmp);
return ret;
return 0;
}
-/* called with ebt_mutex down */
+/* called with ebt_mutex locked */
static int copy_everything_to_user(struct ebt_table *t, void __user *user,
int *len, int cmd)
{
BUGPRINT("Num_counters wrong\n");
return -EINVAL;
}
- counterstmp = (struct ebt_counter *)
- vmalloc(nentries * sizeof(struct ebt_counter));
+ counterstmp = vmalloc(nentries * sizeof(*counterstmp));
if (!counterstmp) {
MEMPRINT("Couldn't copy counters, out of memory\n");
return -ENOMEM;
case EBT_SO_GET_INIT_INFO:
if (*len != sizeof(struct ebt_replace)){
ret = -EINVAL;
- up(&ebt_mutex);
+ mutex_unlock(&ebt_mutex);
break;
}
if (cmd == EBT_SO_GET_INFO) {
tmp.entries_size = t->table->entries_size;
tmp.valid_hooks = t->table->valid_hooks;
}
- up(&ebt_mutex);
+ mutex_unlock(&ebt_mutex);
if (copy_to_user(user, &tmp, *len) != 0){
BUGPRINT("c2u Didn't work\n");
ret = -EFAULT;
case EBT_SO_GET_ENTRIES:
case EBT_SO_GET_INIT_ENTRIES:
ret = copy_everything_to_user(t, user, len, cmd);
- up(&ebt_mutex);
+ mutex_unlock(&ebt_mutex);
break;
default:
- up(&ebt_mutex);
+ mutex_unlock(&ebt_mutex);
ret = -EINVAL;
}
}
static struct nf_sockopt_ops ebt_sockopts =
-{ { NULL, NULL }, PF_INET, EBT_BASE_CTL, EBT_SO_SET_MAX + 1, do_ebt_set_ctl,
- EBT_BASE_CTL, EBT_SO_GET_MAX + 1, do_ebt_get_ctl, 0, NULL
+{
+ .pf = PF_INET,
+ .set_optmin = EBT_BASE_CTL,
+ .set_optmax = EBT_SO_SET_MAX + 1,
+ .set = do_ebt_set_ctl,
+ .get_optmin = EBT_BASE_CTL,
+ .get_optmax = EBT_SO_GET_MAX + 1,
+ .get = do_ebt_get_ctl,
};
-static int __init init(void)
+static int __init ebtables_init(void)
{
int ret;
- down(&ebt_mutex);
+ mutex_lock(&ebt_mutex);
list_named_insert(&ebt_targets, &ebt_standard_target);
- up(&ebt_mutex);
+ mutex_unlock(&ebt_mutex);
if ((ret = nf_register_sockopt(&ebt_sockopts)) < 0)
return ret;
return 0;
}
-static void __exit fini(void)
+static void __exit ebtables_fini(void)
{
nf_unregister_sockopt(&ebt_sockopts);
printk(KERN_NOTICE "Ebtables v2.0 unregistered\n");
EXPORT_SYMBOL(ebt_register_target);
EXPORT_SYMBOL(ebt_unregister_target);
EXPORT_SYMBOL(ebt_do_table);
-module_init(init);
-module_exit(fini);
+module_init(ebtables_init);
+module_exit(ebtables_fini);
MODULE_LICENSE("GPL");