Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 286174
b: refs/heads/master
c: 088067f
h: refs/heads/master
v: v3
  • Loading branch information
Jozsef Kadlecsik authored and Pablo Neira Ayuso committed Jan 17, 2012
1 parent 14bda4d commit e7a0524
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 11 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9bf04646b0b41c5438ed8a27c5f8dbe0ff40d756
refs/heads/master: 088067f4f14d6ee5c6a196b015a560cbe7744224
36 changes: 26 additions & 10 deletions trunk/net/netfilter/ipset/ip_set_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,43 +77,51 @@ find_set_type(const char *name, u8 family, u8 revision)
}

/* Unlock, try to load a set type module and lock again */
static int
try_to_load_type(const char *name)
static bool
load_settype(const char *name)
{
nfnl_unlock();
pr_debug("try to load ip_set_%s\n", name);
if (request_module("ip_set_%s", name) < 0) {
pr_warning("Can't find ip_set type %s\n", name);
nfnl_lock();
return -IPSET_ERR_FIND_TYPE;
return false;
}
nfnl_lock();
return -EAGAIN;
return true;
}

/* Find a set type and reference it */
#define find_set_type_get(name, family, revision, found) \
__find_set_type_get(name, family, revision, found, false)

static int
find_set_type_get(const char *name, u8 family, u8 revision,
struct ip_set_type **found)
__find_set_type_get(const char *name, u8 family, u8 revision,
struct ip_set_type **found, bool retry)
{
struct ip_set_type *type;
int err;

if (retry && !load_settype(name))
return -IPSET_ERR_FIND_TYPE;

rcu_read_lock();
*found = find_set_type(name, family, revision);
if (*found) {
err = !try_module_get((*found)->me) ? -EFAULT : 0;
goto unlock;
}
/* Make sure the type is loaded but we don't support the revision */
/* Make sure the type is already loaded
* but we don't support the revision */
list_for_each_entry_rcu(type, &ip_set_type_list, list)
if (STREQ(type->name, name)) {
err = -IPSET_ERR_FIND_TYPE;
goto unlock;
}
rcu_read_unlock();

return try_to_load_type(name);
return retry ? -IPSET_ERR_FIND_TYPE :
__find_set_type_get(name, family, revision, found, true);

unlock:
rcu_read_unlock();
Expand All @@ -124,12 +132,19 @@ find_set_type_get(const char *name, u8 family, u8 revision,
* If we succeeded, the supported minimal and maximum revisions are
* filled out.
*/
#define find_set_type_minmax(name, family, min, max) \
__find_set_type_minmax(name, family, min, max, false)

static int
find_set_type_minmax(const char *name, u8 family, u8 *min, u8 *max)
__find_set_type_minmax(const char *name, u8 family, u8 *min, u8 *max,
bool retry)
{
struct ip_set_type *type;
bool found = false;

if (retry && !load_settype(name))
return -IPSET_ERR_FIND_TYPE;

*min = 255; *max = 0;
rcu_read_lock();
list_for_each_entry_rcu(type, &ip_set_type_list, list)
Expand All @@ -145,7 +160,8 @@ find_set_type_minmax(const char *name, u8 family, u8 *min, u8 *max)
if (found)
return 0;

return try_to_load_type(name);
return retry ? -IPSET_ERR_FIND_TYPE :
__find_set_type_minmax(name, family, min, max, true);
}

#define family_name(f) ((f) == AF_INET ? "inet" : \
Expand Down

0 comments on commit e7a0524

Please sign in to comment.