diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2005-01-04 04:13:42 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-01-04 04:13:42 -0800 |
commit | 5d9ed066ad6dff86b86688ba53eb0cb22e4c3ce9 (patch) | |
tree | ce14057ab8e6638e881f4e91866dde4300ee3b9b /net | |
parent | a22405d433bbdc3131c5327e9b2d2fbcf4744705 (diff) | |
download | history-5d9ed066ad6dff86b86688ba53eb0cb22e4c3ce9.tar.gz |
[PATCH] Steal a Character To Create a Revision Number
Pablo Neira <pablo@eurodev.net> came up with the idea of stealing the
last byte in the (already nul-terminated) name of a target/match to
create a version.
That patch motivated me to clean up the match and target searching in
ip_tables, which makes this patch more trivial. I also renamed
"version" to "revision" since the word "version" was used for iptables
itself.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/netfilter/ip_tables.c | 71 |
1 files changed, 46 insertions, 25 deletions
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index c0f6d4081e1bab..187bac7f91b74a 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -430,34 +430,62 @@ static inline struct ipt_table *find_table_lock(const char *name) return NULL; } -/* Find match by name, grabs mutex & ref. Returns ERR_PTR() on error. */ -static inline struct ipt_match *find_match_lock(const char *name) +/* Find match, grabs mutex & ref. Returns ERR_PTR() on error. */ +static inline struct ipt_match *find_match_lock(const char *name, u8 revision) { struct ipt_match *m; + int found = 0; if (down_interruptible(&ipt_mutex) != 0) return ERR_PTR(-EINTR); - list_for_each_entry(m, &ipt_match, list) - if (strcmp(m->name, name) == 0 && try_module_get(m->me)) - return m; + list_for_each_entry(m, &ipt_match, list) { + if (strcmp(m->name, name) == 0) { + found = 1; + if (m->revision == revision) { + if (!try_module_get(m->me)) + found = 0; + else + return m; + } + } + } up(&ipt_mutex); - return NULL; + + /* Not found at all? NULL so try_then_request_module loads module. */ + if (!found) + return NULL; + + return ERR_PTR(-EPROTOTYPE); } -/* Find target by name, grabs mutex & ref. Returns ERR_PTR() on error. */ -static inline struct ipt_target *find_target_lock(const char *name) +/* Find target, grabs mutex & ref. Returns ERR_PTR() on error. */ +static inline struct ipt_target *find_target_lock(const char *name, u8 revision) { struct ipt_target *t; + int found = 0; if (down_interruptible(&ipt_mutex) != 0) return ERR_PTR(-EINTR); - list_for_each_entry(t, &ipt_target, list) - if (strcmp(t->name, name) == 0 && try_module_get(t->me)) - return t; + list_for_each_entry(t, &ipt_target, list) { + if (strcmp(t->name, name) == 0) { + found = 1; + if (t->revision == revision) { + if (!try_module_get(t->me)) + found = 0; + else + return t; + } + } + } up(&ipt_mutex); - return NULL; + + /* Not found at all? NULL so try_then_request_module loads module. */ + if (!found) + return NULL; + + return ERR_PTR(-EPROTOTYPE); } /* All zeroes == unconditional rule. */ @@ -621,7 +649,8 @@ check_match(struct ipt_entry_match *m, { struct ipt_match *match; - match = try_then_request_module(find_match_lock(m->u.user.name), + match = try_then_request_module(find_match_lock(m->u.user.name, + m->u.user.revision), "ipt_%s", m->u.user.name); if (IS_ERR(match) || !match) { duprintf("check_match: `%s' not found\n", m->u.user.name); @@ -666,7 +695,8 @@ check_entry(struct ipt_entry *e, const char *name, unsigned int size, goto cleanup_matches; t = ipt_get_target(e); - target = try_then_request_module(find_target_lock(t->u.user.name), + target = try_then_request_module(find_target_lock(t->u.user.name, + t->u.user.revision), "ipt_%s", t->u.user.name); if (IS_ERR(target) || !target) { duprintf("check_entry: `%s' not found\n", t->u.user.name); @@ -1303,12 +1333,7 @@ ipt_register_target(struct ipt_target *target) ret = down_interruptible(&ipt_mutex); if (ret != 0) return ret; - - if (!list_named_insert(&ipt_target, target)) { - duprintf("ipt_register_target: `%s' already in list!\n", - target->name); - ret = -EINVAL; - } + list_add(&target->list, &ipt_target); up(&ipt_mutex); return ret; } @@ -1330,11 +1355,7 @@ ipt_register_match(struct ipt_match *match) if (ret != 0) return ret; - if (!list_named_insert(&ipt_match, match)) { - duprintf("ipt_register_match: `%s' already in list!\n", - match->name); - ret = -EINVAL; - } + list_add(&match->list, &ipt_match); up(&ipt_mutex); return ret; |