Commit d0ab89f5 authored by Rusty Russell's avatar Rusty Russell Committed by David S. Miller

[NETFILTER]: Switch over to new-style module refcounting, help from Christoph Hellwig.

parent 061af250
...@@ -229,7 +229,8 @@ ip_conntrack_expect_find_get(const struct ip_conntrack_tuple *tuple); ...@@ -229,7 +229,8 @@ ip_conntrack_expect_find_get(const struct ip_conntrack_tuple *tuple);
/* decrement reference count on an expectation */ /* decrement reference count on an expectation */
void ip_conntrack_expect_put(struct ip_conntrack_expect *exp); void ip_conntrack_expect_put(struct ip_conntrack_expect *exp);
extern struct module *ip_conntrack_module; /* call to create an explicit dependency on ip_conntrack. */
extern void need_ip_conntrack(void);
extern int invert_tuplepr(struct ip_conntrack_tuple *inverse, extern int invert_tuplepr(struct ip_conntrack_tuple *inverse,
const struct ip_conntrack_tuple *orig); const struct ip_conntrack_tuple *orig);
......
...@@ -539,8 +539,10 @@ static inline int check_entry(struct arpt_entry *e, const char *name, unsigned i ...@@ -539,8 +539,10 @@ static inline int check_entry(struct arpt_entry *e, const char *name, unsigned i
duprintf("check_entry: `%s' not found\n", t->u.user.name); duprintf("check_entry: `%s' not found\n", t->u.user.name);
goto out; goto out;
} }
if (target->me) if (!try_module_get((target->me))) {
__MOD_INC_USE_COUNT(target->me); ret = -ENOENT;
goto out_unlock;
}
t->u.kernel.target = target; t->u.kernel.target = target;
up(&arpt_mutex); up(&arpt_mutex);
...@@ -554,8 +556,7 @@ static inline int check_entry(struct arpt_entry *e, const char *name, unsigned i ...@@ -554,8 +556,7 @@ static inline int check_entry(struct arpt_entry *e, const char *name, unsigned i
t->u.target_size t->u.target_size
- sizeof(*t), - sizeof(*t),
e->comefrom)) { e->comefrom)) {
if (t->u.kernel.target->me) module_put(t->u.kernel.target->me);
__MOD_DEC_USE_COUNT(t->u.kernel.target->me);
duprintf("arp_tables: check failed for `%s'.\n", duprintf("arp_tables: check failed for `%s'.\n",
t->u.kernel.target->name); t->u.kernel.target->name);
ret = -EINVAL; ret = -EINVAL;
...@@ -565,6 +566,8 @@ static inline int check_entry(struct arpt_entry *e, const char *name, unsigned i ...@@ -565,6 +566,8 @@ static inline int check_entry(struct arpt_entry *e, const char *name, unsigned i
(*i)++; (*i)++;
return 0; return 0;
out_unlock:
up(&arpt_mutex);
out: out:
return ret; return ret;
} }
...@@ -622,9 +625,7 @@ static inline int cleanup_entry(struct arpt_entry *e, unsigned int *i) ...@@ -622,9 +625,7 @@ static inline int cleanup_entry(struct arpt_entry *e, unsigned int *i)
if (t->u.kernel.target->destroy) if (t->u.kernel.target->destroy)
t->u.kernel.target->destroy(t->data, t->u.kernel.target->destroy(t->data,
t->u.target_size - sizeof(*t)); t->u.target_size - sizeof(*t));
if (t->u.kernel.target->me) module_put(t->u.kernel.target->me);
__MOD_DEC_USE_COUNT(t->u.kernel.target->me);
return 0; return 0;
} }
...@@ -1110,17 +1111,14 @@ int arpt_register_target(struct arpt_target *target) ...@@ -1110,17 +1111,14 @@ int arpt_register_target(struct arpt_target *target)
{ {
int ret; int ret;
MOD_INC_USE_COUNT;
ret = down_interruptible(&arpt_mutex); ret = down_interruptible(&arpt_mutex);
if (ret != 0) { if (ret != 0)
MOD_DEC_USE_COUNT;
return ret; return ret;
}
if (!list_named_insert(&arpt_target, target)) { if (!list_named_insert(&arpt_target, target)) {
duprintf("arpt_register_target: `%s' already in list!\n", duprintf("arpt_register_target: `%s' already in list!\n",
target->name); target->name);
ret = -EINVAL; ret = -EINVAL;
MOD_DEC_USE_COUNT;
} }
up(&arpt_mutex); up(&arpt_mutex);
return ret; return ret;
...@@ -1131,7 +1129,6 @@ void arpt_unregister_target(struct arpt_target *target) ...@@ -1131,7 +1129,6 @@ void arpt_unregister_target(struct arpt_target *target)
down(&arpt_mutex); down(&arpt_mutex);
LIST_DELETE(&arpt_target, target); LIST_DELETE(&arpt_target, target);
up(&arpt_mutex); up(&arpt_mutex);
MOD_DEC_USE_COUNT;
} }
int arpt_register_table(struct arpt_table *table) int arpt_register_table(struct arpt_table *table)
...@@ -1141,12 +1138,10 @@ int arpt_register_table(struct arpt_table *table) ...@@ -1141,12 +1138,10 @@ int arpt_register_table(struct arpt_table *table)
static struct arpt_table_info bootstrap static struct arpt_table_info bootstrap
= { 0, 0, 0, { 0 }, { 0 }, { } }; = { 0, 0, 0, { 0 }, { 0 }, { } };
MOD_INC_USE_COUNT;
newinfo = vmalloc(sizeof(struct arpt_table_info) newinfo = vmalloc(sizeof(struct arpt_table_info)
+ SMP_ALIGN(table->table->size) * NR_CPUS); + SMP_ALIGN(table->table->size) * NR_CPUS);
if (!newinfo) { if (!newinfo) {
ret = -ENOMEM; ret = -ENOMEM;
MOD_DEC_USE_COUNT;
return ret; return ret;
} }
memcpy(newinfo->entries, table->table->entries, table->table->size); memcpy(newinfo->entries, table->table->entries, table->table->size);
...@@ -1159,14 +1154,12 @@ int arpt_register_table(struct arpt_table *table) ...@@ -1159,14 +1154,12 @@ int arpt_register_table(struct arpt_table *table)
duprintf("arpt_register_table: translate table gives %d\n", ret); duprintf("arpt_register_table: translate table gives %d\n", ret);
if (ret != 0) { if (ret != 0) {
vfree(newinfo); vfree(newinfo);
MOD_DEC_USE_COUNT;
return ret; return ret;
} }
ret = down_interruptible(&arpt_mutex); ret = down_interruptible(&arpt_mutex);
if (ret != 0) { if (ret != 0) {
vfree(newinfo); vfree(newinfo);
MOD_DEC_USE_COUNT;
return ret; return ret;
} }
...@@ -1196,7 +1189,6 @@ int arpt_register_table(struct arpt_table *table) ...@@ -1196,7 +1189,6 @@ int arpt_register_table(struct arpt_table *table)
free_unlock: free_unlock:
vfree(newinfo); vfree(newinfo);
MOD_DEC_USE_COUNT;
goto unlock; goto unlock;
} }
...@@ -1210,7 +1202,6 @@ void arpt_unregister_table(struct arpt_table *table) ...@@ -1210,7 +1202,6 @@ void arpt_unregister_table(struct arpt_table *table)
ARPT_ENTRY_ITERATE(table->private->entries, table->private->size, ARPT_ENTRY_ITERATE(table->private->entries, table->private->size,
cleanup_entry, NULL); cleanup_entry, NULL);
vfree(table->private); vfree(table->private);
MOD_DEC_USE_COUNT;
} }
/* The built-in targets: standard (NULL) and error. */ /* The built-in targets: standard (NULL) and error. */
......
...@@ -1128,8 +1128,6 @@ int ip_conntrack_alter_reply(struct ip_conntrack *conntrack, ...@@ -1128,8 +1128,6 @@ int ip_conntrack_alter_reply(struct ip_conntrack *conntrack,
int ip_conntrack_helper_register(struct ip_conntrack_helper *me) int ip_conntrack_helper_register(struct ip_conntrack_helper *me)
{ {
MOD_INC_USE_COUNT;
WRITE_LOCK(&ip_conntrack_lock); WRITE_LOCK(&ip_conntrack_lock);
list_prepend(&helpers, me); list_prepend(&helpers, me);
WRITE_UNLOCK(&ip_conntrack_lock); WRITE_UNLOCK(&ip_conntrack_lock);
...@@ -1166,8 +1164,6 @@ void ip_conntrack_helper_unregister(struct ip_conntrack_helper *me) ...@@ -1166,8 +1164,6 @@ void ip_conntrack_helper_unregister(struct ip_conntrack_helper *me)
/* Someone could be still looking at the helper in a bh. */ /* Someone could be still looking at the helper in a bh. */
br_write_lock_bh(BR_NETPROTO_LOCK); br_write_lock_bh(BR_NETPROTO_LOCK);
br_write_unlock_bh(BR_NETPROTO_LOCK); br_write_unlock_bh(BR_NETPROTO_LOCK);
MOD_DEC_USE_COUNT;
} }
/* Refresh conntrack for this many jiffies. */ /* Refresh conntrack for this many jiffies. */
......
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
#define DEBUGP(format, args...) #define DEBUGP(format, args...)
#endif #endif
struct module *ip_conntrack_module = THIS_MODULE;
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
static int kill_proto(const struct ip_conntrack *i, void *data) static int kill_proto(const struct ip_conntrack *i, void *data)
...@@ -310,7 +309,6 @@ int ip_conntrack_protocol_register(struct ip_conntrack_protocol *proto) ...@@ -310,7 +309,6 @@ int ip_conntrack_protocol_register(struct ip_conntrack_protocol *proto)
} }
list_prepend(&protocol_list, proto); list_prepend(&protocol_list, proto);
MOD_INC_USE_COUNT;
out: out:
WRITE_UNLOCK(&ip_conntrack_lock); WRITE_UNLOCK(&ip_conntrack_lock);
...@@ -332,8 +330,6 @@ void ip_conntrack_protocol_unregister(struct ip_conntrack_protocol *proto) ...@@ -332,8 +330,6 @@ void ip_conntrack_protocol_unregister(struct ip_conntrack_protocol *proto)
/* Remove all contrack entries for this protocol */ /* Remove all contrack entries for this protocol */
ip_ct_selective_cleanup(kill_proto, &proto->proto); ip_ct_selective_cleanup(kill_proto, &proto->proto);
MOD_DEC_USE_COUNT;
} }
static int __init init(void) static int __init init(void)
...@@ -349,13 +345,19 @@ static void __exit fini(void) ...@@ -349,13 +345,19 @@ static void __exit fini(void)
module_init(init); module_init(init);
module_exit(fini); module_exit(fini);
/* Some modules need us, but don't depend directly on any symbol.
They should call this. */
void need_ip_conntrack(void)
{
}
EXPORT_SYMBOL(ip_conntrack_protocol_register); EXPORT_SYMBOL(ip_conntrack_protocol_register);
EXPORT_SYMBOL(ip_conntrack_protocol_unregister); EXPORT_SYMBOL(ip_conntrack_protocol_unregister);
EXPORT_SYMBOL(invert_tuplepr); EXPORT_SYMBOL(invert_tuplepr);
EXPORT_SYMBOL(ip_conntrack_alter_reply); EXPORT_SYMBOL(ip_conntrack_alter_reply);
EXPORT_SYMBOL(ip_conntrack_destroyed); EXPORT_SYMBOL(ip_conntrack_destroyed);
EXPORT_SYMBOL(ip_conntrack_get); EXPORT_SYMBOL(ip_conntrack_get);
EXPORT_SYMBOL(ip_conntrack_module); EXPORT_SYMBOL(need_ip_conntrack);
EXPORT_SYMBOL(ip_conntrack_helper_register); EXPORT_SYMBOL(ip_conntrack_helper_register);
EXPORT_SYMBOL(ip_conntrack_helper_unregister); EXPORT_SYMBOL(ip_conntrack_helper_unregister);
EXPORT_SYMBOL(ip_ct_selective_cleanup); EXPORT_SYMBOL(ip_ct_selective_cleanup);
......
...@@ -478,9 +478,9 @@ int ip_nat_helper_register(struct ip_nat_helper *me) ...@@ -478,9 +478,9 @@ int ip_nat_helper_register(struct ip_nat_helper *me)
if (me->me && !(me->flags & IP_NAT_HELPER_F_STANDALONE)) { if (me->me && !(me->flags & IP_NAT_HELPER_F_STANDALONE)) {
struct ip_conntrack_helper *ct_helper; struct ip_conntrack_helper *ct_helper;
if ((ct_helper = ip_ct_find_helper(&me->tuple)) if ((ct_helper = ip_ct_find_helper(&me->tuple))) {
&& ct_helper->me) { if (!try_module_get(ct_helper->me))
__MOD_INC_USE_COUNT(ct_helper->me); return -EBUSY;
} else { } else {
/* We are a NAT helper for protocol X. If we need /* We are a NAT helper for protocol X. If we need
* respective conntrack helper for protoccol X, compute * respective conntrack helper for protoccol X, compute
...@@ -498,9 +498,9 @@ int ip_nat_helper_register(struct ip_nat_helper *me) ...@@ -498,9 +498,9 @@ int ip_nat_helper_register(struct ip_nat_helper *me)
sprintf(name, "ip_conntrack%s", tmp); sprintf(name, "ip_conntrack%s", tmp);
#ifdef CONFIG_KMOD #ifdef CONFIG_KMOD
if (!request_module(name) if (!request_module(name)
&& (ct_helper = ip_ct_find_helper(&me->tuple)) && (ct_helper = ip_ct_find_helper(&me->tuple))) {
&& ct_helper->me) { if (!try_module_get(ct_helper->me))
__MOD_INC_USE_COUNT(ct_helper->me); return -EBUSY;
} else { } else {
printk("unable to load module %s\n", name); printk("unable to load module %s\n", name);
return -EBUSY; return -EBUSY;
...@@ -516,10 +516,8 @@ int ip_nat_helper_register(struct ip_nat_helper *me) ...@@ -516,10 +516,8 @@ int ip_nat_helper_register(struct ip_nat_helper *me)
WRITE_LOCK(&ip_nat_lock); WRITE_LOCK(&ip_nat_lock);
if (LIST_FIND(&helpers, helper_cmp, struct ip_nat_helper *,&me->tuple)) if (LIST_FIND(&helpers, helper_cmp, struct ip_nat_helper *,&me->tuple))
ret = -EBUSY; ret = -EBUSY;
else { else
list_prepend(&helpers, me); list_prepend(&helpers, me);
MOD_INC_USE_COUNT;
}
WRITE_UNLOCK(&ip_nat_lock); WRITE_UNLOCK(&ip_nat_lock);
return ret; return ret;
...@@ -539,13 +537,10 @@ kill_helper(const struct ip_conntrack *i, void *helper) ...@@ -539,13 +537,10 @@ kill_helper(const struct ip_conntrack *i, void *helper)
void ip_nat_helper_unregister(struct ip_nat_helper *me) void ip_nat_helper_unregister(struct ip_nat_helper *me)
{ {
int found = 0;
WRITE_LOCK(&ip_nat_lock); WRITE_LOCK(&ip_nat_lock);
/* Autoloading conntrack helper might have failed */ /* Autoloading conntrack helper might have failed */
if (LIST_FIND(&helpers, helper_cmp, struct ip_nat_helper *,&me->tuple)) { if (LIST_FIND(&helpers, helper_cmp, struct ip_nat_helper *,&me->tuple)) {
LIST_DELETE(&helpers, me); LIST_DELETE(&helpers, me);
found = 1;
} }
WRITE_UNLOCK(&ip_nat_lock); WRITE_UNLOCK(&ip_nat_lock);
...@@ -562,18 +557,13 @@ void ip_nat_helper_unregister(struct ip_nat_helper *me) ...@@ -562,18 +557,13 @@ void ip_nat_helper_unregister(struct ip_nat_helper *me)
worse. --RR */ worse. --RR */
ip_ct_selective_cleanup(kill_helper, me); ip_ct_selective_cleanup(kill_helper, me);
if (found)
MOD_DEC_USE_COUNT;
/* If we are no standalone NAT helper, we need to decrement usage count /* If we are no standalone NAT helper, we need to decrement usage count
* on our conntrack helper */ * on our conntrack helper */
if (me->me && !(me->flags & IP_NAT_HELPER_F_STANDALONE)) { if (me->me && !(me->flags & IP_NAT_HELPER_F_STANDALONE)) {
struct ip_conntrack_helper *ct_helper; struct ip_conntrack_helper *ct_helper;
if ((ct_helper = ip_ct_find_helper(&me->tuple)) if ((ct_helper = ip_ct_find_helper(&me->tuple)))
&& ct_helper->me) { module_put(ct_helper->me);
__MOD_DEC_USE_COUNT(ct_helper->me);
}
#ifdef CONFIG_MODULES #ifdef CONFIG_MODULES
else else
printk("%s: unable to decrement usage count" printk("%s: unable to decrement usage count"
......
...@@ -255,8 +255,6 @@ int ip_nat_protocol_register(struct ip_nat_protocol *proto) ...@@ -255,8 +255,6 @@ int ip_nat_protocol_register(struct ip_nat_protocol *proto)
} }
list_prepend(&protos, proto); list_prepend(&protos, proto);
MOD_INC_USE_COUNT;
out: out:
WRITE_UNLOCK(&ip_nat_lock); WRITE_UNLOCK(&ip_nat_lock);
return ret; return ret;
...@@ -272,14 +270,14 @@ void ip_nat_protocol_unregister(struct ip_nat_protocol *proto) ...@@ -272,14 +270,14 @@ void ip_nat_protocol_unregister(struct ip_nat_protocol *proto)
/* Someone could be still looking at the proto in a bh. */ /* Someone could be still looking at the proto in a bh. */
br_write_lock_bh(BR_NETPROTO_LOCK); br_write_lock_bh(BR_NETPROTO_LOCK);
br_write_unlock_bh(BR_NETPROTO_LOCK); br_write_unlock_bh(BR_NETPROTO_LOCK);
MOD_DEC_USE_COUNT;
} }
static int init_or_cleanup(int init) static int init_or_cleanup(int init)
{ {
int ret = 0; int ret = 0;
need_ip_conntrack();
if (!init) goto cleanup; if (!init) goto cleanup;
ret = ip_nat_rule_init(); ret = ip_nat_rule_init();
...@@ -314,13 +312,9 @@ static int init_or_cleanup(int init) ...@@ -314,13 +312,9 @@ static int init_or_cleanup(int init)
goto cleanup_localoutops; goto cleanup_localoutops;
} }
#endif #endif
if (ip_conntrack_module)
__MOD_INC_USE_COUNT(ip_conntrack_module);
return ret; return ret;
cleanup: cleanup:
if (ip_conntrack_module)
__MOD_DEC_USE_COUNT(ip_conntrack_module);
#ifdef CONFIG_IP_NF_NAT_LOCAL #ifdef CONFIG_IP_NF_NAT_LOCAL
nf_unregister_hook(&ip_nat_local_in_ops); nf_unregister_hook(&ip_nat_local_in_ops);
cleanup_localoutops: cleanup_localoutops:
......
...@@ -598,10 +598,7 @@ cleanup_match(struct ipt_entry_match *m, unsigned int *i) ...@@ -598,10 +598,7 @@ cleanup_match(struct ipt_entry_match *m, unsigned int *i)
if (m->u.kernel.match->destroy) if (m->u.kernel.match->destroy)
m->u.kernel.match->destroy(m->data, m->u.kernel.match->destroy(m->data,
m->u.match_size - sizeof(*m)); m->u.match_size - sizeof(*m));
module_put(m->u.kernel.match->me);
if (m->u.kernel.match->me)
__MOD_DEC_USE_COUNT(m->u.kernel.match->me);
return 0; return 0;
} }
...@@ -650,8 +647,10 @@ check_match(struct ipt_entry_match *m, ...@@ -650,8 +647,10 @@ check_match(struct ipt_entry_match *m,
duprintf("check_match: `%s' not found\n", m->u.user.name); duprintf("check_match: `%s' not found\n", m->u.user.name);
return ret; return ret;
} }
if (match->me) if (!try_module_get(match->me)) {
__MOD_INC_USE_COUNT(match->me); up(&ipt_mutex);
return -ENOENT;
}
m->u.kernel.match = match; m->u.kernel.match = match;
up(&ipt_mutex); up(&ipt_mutex);
...@@ -659,8 +658,7 @@ check_match(struct ipt_entry_match *m, ...@@ -659,8 +658,7 @@ check_match(struct ipt_entry_match *m,
&& !m->u.kernel.match->checkentry(name, ip, m->data, && !m->u.kernel.match->checkentry(name, ip, m->data,
m->u.match_size - sizeof(*m), m->u.match_size - sizeof(*m),
hookmask)) { hookmask)) {
if (m->u.kernel.match->me) module_put(m->u.kernel.match->me);
__MOD_DEC_USE_COUNT(m->u.kernel.match->me);
duprintf("ip_tables: check failed for `%s'.\n", duprintf("ip_tables: check failed for `%s'.\n",
m->u.kernel.match->name); m->u.kernel.match->name);
return -EINVAL; return -EINVAL;
...@@ -697,8 +695,11 @@ check_entry(struct ipt_entry *e, const char *name, unsigned int size, ...@@ -697,8 +695,11 @@ check_entry(struct ipt_entry *e, const char *name, unsigned int size,
duprintf("check_entry: `%s' not found\n", t->u.user.name); duprintf("check_entry: `%s' not found\n", t->u.user.name);
goto cleanup_matches; goto cleanup_matches;
} }
if (target->me) if (!try_module_get(target->me)) {
__MOD_INC_USE_COUNT(target->me); up(&ipt_mutex);
ret = -ENOENT;
goto cleanup_matches;
}
t->u.kernel.target = target; t->u.kernel.target = target;
up(&ipt_mutex); up(&ipt_mutex);
...@@ -712,8 +713,7 @@ check_entry(struct ipt_entry *e, const char *name, unsigned int size, ...@@ -712,8 +713,7 @@ check_entry(struct ipt_entry *e, const char *name, unsigned int size,
t->u.target_size t->u.target_size
- sizeof(*t), - sizeof(*t),
e->comefrom)) { e->comefrom)) {
if (t->u.kernel.target->me) module_put(t->u.kernel.target->me);
__MOD_DEC_USE_COUNT(t->u.kernel.target->me);
duprintf("ip_tables: check failed for `%s'.\n", duprintf("ip_tables: check failed for `%s'.\n",
t->u.kernel.target->name); t->u.kernel.target->name);
ret = -EINVAL; ret = -EINVAL;
...@@ -785,9 +785,7 @@ cleanup_entry(struct ipt_entry *e, unsigned int *i) ...@@ -785,9 +785,7 @@ cleanup_entry(struct ipt_entry *e, unsigned int *i)
if (t->u.kernel.target->destroy) if (t->u.kernel.target->destroy)
t->u.kernel.target->destroy(t->data, t->u.kernel.target->destroy(t->data,
t->u.target_size - sizeof(*t)); t->u.target_size - sizeof(*t));
if (t->u.kernel.target->me) module_put(t->u.kernel.target->me);
__MOD_DEC_USE_COUNT(t->u.kernel.target->me);
return 0; return 0;
} }
...@@ -1319,17 +1317,14 @@ ipt_register_target(struct ipt_target *target) ...@@ -1319,17 +1317,14 @@ ipt_register_target(struct ipt_target *target)
{ {
int ret; int ret;
MOD_INC_USE_COUNT;
ret = down_interruptible(&ipt_mutex); ret = down_interruptible(&ipt_mutex);
if (ret != 0) { if (ret != 0)
MOD_DEC_USE_COUNT;
return ret; return ret;
}
if (!list_named_insert(&ipt_target, target)) { if (!list_named_insert(&ipt_target, target)) {
duprintf("ipt_register_target: `%s' already in list!\n", duprintf("ipt_register_target: `%s' already in list!\n",
target->name); target->name);
ret = -EINVAL; ret = -EINVAL;
MOD_DEC_USE_COUNT;
} }
up(&ipt_mutex); up(&ipt_mutex);
return ret; return ret;
...@@ -1341,7 +1336,6 @@ ipt_unregister_target(struct ipt_target *target) ...@@ -1341,7 +1336,6 @@ ipt_unregister_target(struct ipt_target *target)
down(&ipt_mutex); down(&ipt_mutex);
LIST_DELETE(&ipt_target, target); LIST_DELETE(&ipt_target, target);
up(&ipt_mutex); up(&ipt_mutex);
MOD_DEC_USE_COUNT;
} }
int int
...@@ -1349,16 +1343,13 @@ ipt_register_match(struct ipt_match *match) ...@@ -1349,16 +1343,13 @@ ipt_register_match(struct ipt_match *match)
{ {
int ret; int ret;
MOD_INC_USE_COUNT;
ret = down_interruptible(&ipt_mutex); ret = down_interruptible(&ipt_mutex);
if (ret != 0) { if (ret != 0)
MOD_DEC_USE_COUNT;
return ret; return ret;
}
if (!list_named_insert(&ipt_match, match)) { if (!list_named_insert(&ipt_match, match)) {
duprintf("ipt_register_match: `%s' already in list!\n", duprintf("ipt_register_match: `%s' already in list!\n",
match->name); match->name);
MOD_DEC_USE_COUNT;
ret = -EINVAL; ret = -EINVAL;
} }
up(&ipt_mutex); up(&ipt_mutex);
...@@ -1372,7 +1363,6 @@ ipt_unregister_match(struct ipt_match *match) ...@@ -1372,7 +1363,6 @@ ipt_unregister_match(struct ipt_match *match)
down(&ipt_mutex); down(&ipt_mutex);
LIST_DELETE(&ipt_match, match); LIST_DELETE(&ipt_match, match);
up(&ipt_mutex); up(&ipt_mutex);
MOD_DEC_USE_COUNT;
} }
int ipt_register_table(struct ipt_table *table) int ipt_register_table(struct ipt_table *table)
...@@ -1382,14 +1372,11 @@ int ipt_register_table(struct ipt_table *table) ...@@ -1382,14 +1372,11 @@ int ipt_register_table(struct ipt_table *table)
static struct ipt_table_info bootstrap static struct ipt_table_info bootstrap
= { 0, 0, 0, { 0 }, { 0 }, { } }; = { 0, 0, 0, { 0 }, { 0 }, { } };
MOD_INC_USE_COUNT;
newinfo = vmalloc(sizeof(struct ipt_table_info) newinfo = vmalloc(sizeof(struct ipt_table_info)
+ SMP_ALIGN(table->table->size) * NR_CPUS); + SMP_ALIGN(table->table->size) * NR_CPUS);
if (!newinfo) { if (!newinfo)
ret = -ENOMEM; return -ENOMEM;
MOD_DEC_USE_COUNT;
return ret;
}
memcpy(newinfo->entries, table->table->entries, table->table->size); memcpy(newinfo->entries, table->table->entries, table->table->size);
ret = translate_table(table->name, table->valid_hooks, ret = translate_table(table->name, table->valid_hooks,
...@@ -1399,14 +1386,12 @@ int ipt_register_table(struct ipt_table *table) ...@@ -1399,14 +1386,12 @@ int ipt_register_table(struct ipt_table *table)
table->table->underflow); table->table->underflow);
if (ret != 0) { if (ret != 0) {
vfree(newinfo); vfree(newinfo);
MOD_DEC_USE_COUNT;
return ret; return ret;
} }
ret = down_interruptible(&ipt_mutex); ret = down_interruptible(&ipt_mutex);
if (ret != 0) { if (ret != 0) {
vfree(newinfo); vfree(newinfo);
MOD_DEC_USE_COUNT;
return ret; return ret;
} }
...@@ -1436,7 +1421,6 @@ int ipt_register_table(struct ipt_table *table) ...@@ -1436,7 +1421,6 @@ int ipt_register_table(struct ipt_table *table)
free_unlock: free_unlock:
vfree(newinfo); vfree(newinfo);
MOD_DEC_USE_COUNT;
goto unlock; goto unlock;
} }
...@@ -1450,7 +1434,6 @@ void ipt_unregister_table(struct ipt_table *table) ...@@ -1450,7 +1434,6 @@ void ipt_unregister_table(struct ipt_table *table)
IPT_ENTRY_ITERATE(table->private->entries, table->private->size, IPT_ENTRY_ITERATE(table->private->entries, table->private->size,
cleanup_entry, NULL); cleanup_entry, NULL);
vfree(table->private); vfree(table->private);
MOD_DEC_USE_COUNT;
} }
/* Returns 1 if the port is matched by the range, 0 otherwise */ /* Returns 1 if the port is matched by the range, 0 otherwise */
......
...@@ -105,17 +105,13 @@ static struct ipt_match conntrack_match ...@@ -105,17 +105,13 @@ static struct ipt_match conntrack_match
static int __init init(void) static int __init init(void)
{ {
/* NULL if ip_conntrack not a module */ need_ip_conntrack();
if (ip_conntrack_module)
__MOD_INC_USE_COUNT(ip_conntrack_module);
return ipt_register_match(&conntrack_match); return ipt_register_match(&conntrack_match);
} }
static void __exit fini(void) static void __exit fini(void)
{ {
ipt_unregister_match(&conntrack_match); ipt_unregister_match(&conntrack_match);
if (ip_conntrack_module)
__MOD_DEC_USE_COUNT(ip_conntrack_module);
} }
module_init(init); module_init(init);
......
...@@ -94,17 +94,13 @@ static struct ipt_match helper_match ...@@ -94,17 +94,13 @@ static struct ipt_match helper_match
static int __init init(void) static int __init init(void)
{ {
/* NULL if ip_conntrack not a module */ need_ip_conntrack();
if (ip_conntrack_module)
__MOD_INC_USE_COUNT(ip_conntrack_module);
return ipt_register_match(&helper_match); return ipt_register_match(&helper_match);
} }
static void __exit fini(void) static void __exit fini(void)
{ {
ipt_unregister_match(&helper_match); ipt_unregister_match(&helper_match);
if (ip_conntrack_module)
__MOD_DEC_USE_COUNT(ip_conntrack_module);
} }
module_init(init); module_init(init);
......
...@@ -46,17 +46,13 @@ static struct ipt_match state_match ...@@ -46,17 +46,13 @@ static struct ipt_match state_match
static int __init init(void) static int __init init(void)
{ {
/* NULL if ip_conntrack not a module */ need_ip_conntrack();
if (ip_conntrack_module)
__MOD_INC_USE_COUNT(ip_conntrack_module);
return ipt_register_match(&state_match); return ipt_register_match(&state_match);
} }
static void __exit fini(void) static void __exit fini(void)
{ {
ipt_unregister_match(&state_match); ipt_unregister_match(&state_match);
if (ip_conntrack_module)
__MOD_DEC_USE_COUNT(ip_conntrack_module);
} }
module_init(init); module_init(init);
......
...@@ -671,10 +671,7 @@ cleanup_match(struct ip6t_entry_match *m, unsigned int *i) ...@@ -671,10 +671,7 @@ cleanup_match(struct ip6t_entry_match *m, unsigned int *i)
if (m->u.kernel.match->destroy) if (m->u.kernel.match->destroy)
m->u.kernel.match->destroy(m->data, m->u.kernel.match->destroy(m->data,
m->u.match_size - sizeof(*m)); m->u.match_size - sizeof(*m));
module_put(m->u.kernel.match->me);
if (m->u.kernel.match->me)
__MOD_DEC_USE_COUNT(m->u.kernel.match->me);
return 0; return 0;
} }
...@@ -723,8 +720,10 @@ check_match(struct ip6t_entry_match *m, ...@@ -723,8 +720,10 @@ check_match(struct ip6t_entry_match *m,
// duprintf("check_match: `%s' not found\n", m->u.name); // duprintf("check_match: `%s' not found\n", m->u.name);
return ret; return ret;
} }
if (match->me) if (!try_module_get(match->me)) {
__MOD_INC_USE_COUNT(match->me); up(&ip6t_mutex);
return -ENOENT;
}
m->u.kernel.match = match; m->u.kernel.match = match;
up(&ip6t_mutex); up(&ip6t_mutex);
...@@ -732,8 +731,7 @@ check_match(struct ip6t_entry_match *m, ...@@ -732,8 +731,7 @@ check_match(struct ip6t_entry_match *m,
&& !m->u.kernel.match->checkentry(name, ipv6, m->data, && !m->u.kernel.match->checkentry(name, ipv6, m->data,
m->u.match_size - sizeof(*m), m->u.match_size - sizeof(*m),
hookmask)) { hookmask)) {
if (m->u.kernel.match->me) module_put(m->u.kernel.match->me);
__MOD_DEC_USE_COUNT(m->u.kernel.match->me);
duprintf("ip_tables: check failed for `%s'.\n", duprintf("ip_tables: check failed for `%s'.\n",
m->u.kernel.match->name); m->u.kernel.match->name);
return -EINVAL; return -EINVAL;
...@@ -770,11 +768,17 @@ check_entry(struct ip6t_entry *e, const char *name, unsigned int size, ...@@ -770,11 +768,17 @@ check_entry(struct ip6t_entry *e, const char *name, unsigned int size,
duprintf("check_entry: `%s' not found\n", t->u.user.name); duprintf("check_entry: `%s' not found\n", t->u.user.name);
goto cleanup_matches; goto cleanup_matches;
} }
if (target->me) if (!try_module_get(target->me)) {
__MOD_INC_USE_COUNT(target->me); up(&ip6t_mutex);
ret = -ENOENT;
goto cleanup_matches;
}
t->u.kernel.target = target; t->u.kernel.target = target;
up(&ip6t_mutex); up(&ip6t_mutex);
if (!t->u.kernel.target) {
ret = -EBUSY;
goto cleanup_matches;
}
if (t->u.kernel.target == &ip6t_standard_target) { if (t->u.kernel.target == &ip6t_standard_target) {
if (!standard_check(t, size)) { if (!standard_check(t, size)) {
ret = -EINVAL; ret = -EINVAL;
...@@ -785,8 +789,7 @@ check_entry(struct ip6t_entry *e, const char *name, unsigned int size, ...@@ -785,8 +789,7 @@ check_entry(struct ip6t_entry *e, const char *name, unsigned int size,
t->u.target_size t->u.target_size
- sizeof(*t), - sizeof(*t),
e->comefrom)) { e->comefrom)) {
if (t->u.kernel.target->me) module_put(t->u.kernel.target->me);
__MOD_DEC_USE_COUNT(t->u.kernel.target->me);
duprintf("ip_tables: check failed for `%s'.\n", duprintf("ip_tables: check failed for `%s'.\n",
t->u.kernel.target->name); t->u.kernel.target->name);
ret = -EINVAL; ret = -EINVAL;
...@@ -858,9 +861,7 @@ cleanup_entry(struct ip6t_entry *e, unsigned int *i) ...@@ -858,9 +861,7 @@ cleanup_entry(struct ip6t_entry *e, unsigned int *i)
if (t->u.kernel.target->destroy) if (t->u.kernel.target->destroy)
t->u.kernel.target->destroy(t->data, t->u.kernel.target->destroy(t->data,
t->u.target_size - sizeof(*t)); t->u.target_size - sizeof(*t));
if (t->u.kernel.target->me) module_put(t->u.kernel.target->me);
__MOD_DEC_USE_COUNT(t->u.kernel.target->me);
return 0; return 0;
} }
...@@ -1388,17 +1389,14 @@ ip6t_register_target(struct ip6t_target *target) ...@@ -1388,17 +1389,14 @@ ip6t_register_target(struct ip6t_target *target)
{ {
int ret; int ret;
MOD_INC_USE_COUNT;
ret = down_interruptible(&ip6t_mutex); ret = down_interruptible(&ip6t_mutex);
if (ret != 0) { if (ret != 0)
MOD_DEC_USE_COUNT;
return ret; return ret;
}
if (!list_named_insert(&ip6t_target, target)) { if (!list_named_insert(&ip6t_target, target)) {
duprintf("ip6t_register_target: `%s' already in list!\n", duprintf("ip6t_register_target: `%s' already in list!\n",
target->name); target->name);
ret = -EINVAL; ret = -EINVAL;
MOD_DEC_USE_COUNT;
} }
up(&ip6t_mutex); up(&ip6t_mutex);
return ret; return ret;
...@@ -1410,7 +1408,6 @@ ip6t_unregister_target(struct ip6t_target *target) ...@@ -1410,7 +1408,6 @@ ip6t_unregister_target(struct ip6t_target *target)
down(&ip6t_mutex); down(&ip6t_mutex);
LIST_DELETE(&ip6t_target, target); LIST_DELETE(&ip6t_target, target);
up(&ip6t_mutex); up(&ip6t_mutex);
MOD_DEC_USE_COUNT;
} }
int int
...@@ -1418,16 +1415,13 @@ ip6t_register_match(struct ip6t_match *match) ...@@ -1418,16 +1415,13 @@ ip6t_register_match(struct ip6t_match *match)
{ {
int ret; int ret;
MOD_INC_USE_COUNT;
ret = down_interruptible(&ip6t_mutex); ret = down_interruptible(&ip6t_mutex);
if (ret != 0) { if (ret != 0)
MOD_DEC_USE_COUNT;
return ret; return ret;
}
if (!list_named_insert(&ip6t_match, match)) { if (!list_named_insert(&ip6t_match, match)) {
duprintf("ip6t_register_match: `%s' already in list!\n", duprintf("ip6t_register_match: `%s' already in list!\n",
match->name); match->name);
MOD_DEC_USE_COUNT;
ret = -EINVAL; ret = -EINVAL;
} }
up(&ip6t_mutex); up(&ip6t_mutex);
...@@ -1441,7 +1435,6 @@ ip6t_unregister_match(struct ip6t_match *match) ...@@ -1441,7 +1435,6 @@ ip6t_unregister_match(struct ip6t_match *match)
down(&ip6t_mutex); down(&ip6t_mutex);
LIST_DELETE(&ip6t_match, match); LIST_DELETE(&ip6t_match, match);
up(&ip6t_mutex); up(&ip6t_mutex);
MOD_DEC_USE_COUNT;
} }
int ip6t_register_table(struct ip6t_table *table) int ip6t_register_table(struct ip6t_table *table)
...@@ -1451,14 +1444,11 @@ int ip6t_register_table(struct ip6t_table *table) ...@@ -1451,14 +1444,11 @@ int ip6t_register_table(struct ip6t_table *table)
static struct ip6t_table_info bootstrap static struct ip6t_table_info bootstrap
= { 0, 0, 0, { 0 }, { 0 }, { }, { } }; = { 0, 0, 0, { 0 }, { 0 }, { }, { } };
MOD_INC_USE_COUNT;
newinfo = vmalloc(sizeof(struct ip6t_table_info) newinfo = vmalloc(sizeof(struct ip6t_table_info)
+ SMP_ALIGN(table->table->size) * NR_CPUS); + SMP_ALIGN(table->table->size) * NR_CPUS);
if (!newinfo) { if (!newinfo)
ret = -ENOMEM; return -ENOMEM;
MOD_DEC_USE_COUNT;
return ret;
}
memcpy(newinfo->entries, table->table->entries, table->table->size); memcpy(newinfo->entries, table->table->entries, table->table->size);
ret = translate_table(table->name, table->valid_hooks, ret = translate_table(table->name, table->valid_hooks,
...@@ -1468,14 +1458,12 @@ int ip6t_register_table(struct ip6t_table *table) ...@@ -1468,14 +1458,12 @@ int ip6t_register_table(struct ip6t_table *table)
table->table->underflow); table->table->underflow);
if (ret != 0) { if (ret != 0) {
vfree(newinfo); vfree(newinfo);
MOD_DEC_USE_COUNT;
return ret; return ret;
} }
ret = down_interruptible(&ip6t_mutex); ret = down_interruptible(&ip6t_mutex);
if (ret != 0) { if (ret != 0) {
vfree(newinfo); vfree(newinfo);
MOD_DEC_USE_COUNT;
return ret; return ret;
} }
...@@ -1505,7 +1493,6 @@ int ip6t_register_table(struct ip6t_table *table) ...@@ -1505,7 +1493,6 @@ int ip6t_register_table(struct ip6t_table *table)
free_unlock: free_unlock:
vfree(newinfo); vfree(newinfo);
MOD_DEC_USE_COUNT;
goto unlock; goto unlock;
} }
...@@ -1519,7 +1506,6 @@ void ip6t_unregister_table(struct ip6t_table *table) ...@@ -1519,7 +1506,6 @@ void ip6t_unregister_table(struct ip6t_table *table)
IP6T_ENTRY_ITERATE(table->private->entries, table->private->size, IP6T_ENTRY_ITERATE(table->private->entries, table->private->size,
cleanup_entry, NULL); cleanup_entry, NULL);
vfree(table->private); vfree(table->private);
MOD_DEC_USE_COUNT;
} }
/* Returns 1 if the port is matched by the range, 0 otherwise */ /* Returns 1 if the port is matched by the range, 0 otherwise */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment