aboutsummaryrefslogtreecommitdiff
path: root/net/xfrm
diff options
context:
space:
mode:
Diffstat (limited to 'net/xfrm')
-rw-r--r--net/xfrm/xfrm_algo.c140
-rw-r--r--net/xfrm/xfrm_hash.c3
-rw-r--r--net/xfrm/xfrm_policy.c4
3 files changed, 81 insertions, 66 deletions
diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c
index 6249a9405bb8..8a72def25a34 100644
--- a/net/xfrm/xfrm_algo.c
+++ b/net/xfrm/xfrm_algo.c
@@ -347,67 +347,44 @@ static inline int calg_entries(void)
return ARRAY_SIZE(calg_list);
}
-/* Todo: generic iterators */
-struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id)
-{
- int i;
-
- for (i = 0; i < aalg_entries(); i++) {
- if (aalg_list[i].desc.sadb_alg_id == alg_id) {
- if (aalg_list[i].available)
- return &aalg_list[i];
- else
- break;
- }
- }
- return NULL;
-}
-EXPORT_SYMBOL_GPL(xfrm_aalg_get_byid);
-
-struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id)
-{
- int i;
+struct xfrm_algo_list {
+ struct xfrm_algo_desc *algs;
+ int entries;
+ u32 type;
+ u32 mask;
+};
- for (i = 0; i < ealg_entries(); i++) {
- if (ealg_list[i].desc.sadb_alg_id == alg_id) {
- if (ealg_list[i].available)
- return &ealg_list[i];
- else
- break;
- }
- }
- return NULL;
-}
-EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid);
+static const struct xfrm_algo_list xfrm_aalg_list = {
+ .algs = aalg_list,
+ .entries = ARRAY_SIZE(aalg_list),
+ .type = CRYPTO_ALG_TYPE_HASH,
+ .mask = CRYPTO_ALG_TYPE_HASH_MASK | CRYPTO_ALG_ASYNC,
+};
-struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id)
-{
- int i;
+static const struct xfrm_algo_list xfrm_ealg_list = {
+ .algs = ealg_list,
+ .entries = ARRAY_SIZE(ealg_list),
+ .type = CRYPTO_ALG_TYPE_BLKCIPHER,
+ .mask = CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC,
+};
- for (i = 0; i < calg_entries(); i++) {
- if (calg_list[i].desc.sadb_alg_id == alg_id) {
- if (calg_list[i].available)
- return &calg_list[i];
- else
- break;
- }
- }
- return NULL;
-}
-EXPORT_SYMBOL_GPL(xfrm_calg_get_byid);
+static const struct xfrm_algo_list xfrm_calg_list = {
+ .algs = calg_list,
+ .entries = ARRAY_SIZE(calg_list),
+ .type = CRYPTO_ALG_TYPE_COMPRESS,
+ .mask = CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC,
+};
-static struct xfrm_algo_desc *xfrm_get_byname(struct xfrm_algo_desc *list,
- int entries, u32 type, u32 mask,
- char *name, int probe)
+static struct xfrm_algo_desc *xfrm_find_algo(
+ const struct xfrm_algo_list *algo_list,
+ int match(const struct xfrm_algo_desc *entry, const void *data),
+ const void *data, int probe)
{
+ struct xfrm_algo_desc *list = algo_list->algs;
int i, status;
- if (!name)
- return NULL;
-
- for (i = 0; i < entries; i++) {
- if (strcmp(name, list[i].name) &&
- (!list[i].compat || strcmp(name, list[i].compat)))
+ for (i = 0; i < algo_list->entries; i++) {
+ if (!match(list + i, data))
continue;
if (list[i].available)
@@ -416,8 +393,8 @@ static struct xfrm_algo_desc *xfrm_get_byname(struct xfrm_algo_desc *list,
if (!probe)
break;
- status = crypto_has_alg(list[i].name, type,
- mask | CRYPTO_ALG_ASYNC);
+ status = crypto_has_alg(list[i].name, algo_list->type,
+ algo_list->mask);
if (!status)
break;
@@ -427,27 +404,60 @@ static struct xfrm_algo_desc *xfrm_get_byname(struct xfrm_algo_desc *list,
return NULL;
}
+static int xfrm_alg_id_match(const struct xfrm_algo_desc *entry,
+ const void *data)
+{
+ return entry->desc.sadb_alg_id == (int)data;
+}
+
+struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id)
+{
+ return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_id_match,
+ (void *)alg_id, 1);
+}
+EXPORT_SYMBOL_GPL(xfrm_aalg_get_byid);
+
+struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id)
+{
+ return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_id_match,
+ (void *)alg_id, 1);
+}
+EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid);
+
+struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id)
+{
+ return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_id_match,
+ (void *)alg_id, 1);
+}
+EXPORT_SYMBOL_GPL(xfrm_calg_get_byid);
+
+static int xfrm_alg_name_match(const struct xfrm_algo_desc *entry,
+ const void *data)
+{
+ const char *name = data;
+
+ return name && (!strcmp(name, entry->name) ||
+ (entry->compat && !strcmp(name, entry->compat)));
+}
+
struct xfrm_algo_desc *xfrm_aalg_get_byname(char *name, int probe)
{
- return xfrm_get_byname(aalg_list, aalg_entries(),
- CRYPTO_ALG_TYPE_HASH, CRYPTO_ALG_TYPE_HASH_MASK,
- name, probe);
+ return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_name_match, name,
+ probe);
}
EXPORT_SYMBOL_GPL(xfrm_aalg_get_byname);
struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name, int probe)
{
- return xfrm_get_byname(ealg_list, ealg_entries(),
- CRYPTO_ALG_TYPE_BLKCIPHER, CRYPTO_ALG_TYPE_MASK,
- name, probe);
+ return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_name_match, name,
+ probe);
}
EXPORT_SYMBOL_GPL(xfrm_ealg_get_byname);
struct xfrm_algo_desc *xfrm_calg_get_byname(char *name, int probe)
{
- return xfrm_get_byname(calg_list, calg_entries(),
- CRYPTO_ALG_TYPE_COMPRESS, CRYPTO_ALG_TYPE_MASK,
- name, probe);
+ return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_name_match, name,
+ probe);
}
EXPORT_SYMBOL_GPL(xfrm_calg_get_byname);
diff --git a/net/xfrm/xfrm_hash.c b/net/xfrm/xfrm_hash.c
index 37643bb8768a..55ab5792af56 100644
--- a/net/xfrm/xfrm_hash.c
+++ b/net/xfrm/xfrm_hash.c
@@ -22,7 +22,8 @@ struct hlist_head *xfrm_hash_alloc(unsigned int sz)
n = __vmalloc(sz, GFP_KERNEL, PAGE_KERNEL);
else
n = (struct hlist_head *)
- __get_free_pages(GFP_KERNEL, get_order(sz));
+ __get_free_pages(GFP_KERNEL | __GFP_NOWARN,
+ get_order(sz));
if (n)
memset(n, 0, sz);
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 95271e8426a1..d0882e53b6fc 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -796,6 +796,10 @@ struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete,
struct hlist_head *chain;
struct hlist_node *entry;
+ *err = -ENOENT;
+ if (xfrm_policy_id2dir(id) != dir)
+ return NULL;
+
*err = 0;
write_lock_bh(&xfrm_policy_lock);
chain = xfrm_policy_byidx + idx_hash(id);