[IPSEC] pfkey: Load specific algorithm in pfkey_add rather than all
This is a natural extension of the changeset [XFRM]: Probe selected algorithm only. which only removed the probe call for xfrm_user. This patch does exactly the same thing for af_key. In other words, we load the algorithm requested by the user rather than everything when adding xfrm states in af_key. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
580e572a4a
Коммит
c92b3a2f1f
|
@ -1448,8 +1448,6 @@ static int pfkey_add(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr,
|
||||||
int err;
|
int err;
|
||||||
struct km_event c;
|
struct km_event c;
|
||||||
|
|
||||||
xfrm_probe_algs();
|
|
||||||
|
|
||||||
x = pfkey_msg2xfrm_state(hdr, ext_hdrs);
|
x = pfkey_msg2xfrm_state(hdr, ext_hdrs);
|
||||||
if (IS_ERR(x))
|
if (IS_ERR(x))
|
||||||
return PTR_ERR(x);
|
return PTR_ERR(x);
|
||||||
|
|
|
@ -347,67 +347,44 @@ static inline int calg_entries(void)
|
||||||
return ARRAY_SIZE(calg_list);
|
return ARRAY_SIZE(calg_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Todo: generic iterators */
|
struct xfrm_algo_list {
|
||||||
struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id)
|
struct xfrm_algo_desc *algs;
|
||||||
{
|
int entries;
|
||||||
int i;
|
u32 type;
|
||||||
|
u32 mask;
|
||||||
for (i = 0; i < aalg_entries(); i++) {
|
};
|
||||||
if (aalg_list[i].desc.sadb_alg_id == alg_id) {
|
|
||||||
if (aalg_list[i].available)
|
static const struct xfrm_algo_list xfrm_aalg_list = {
|
||||||
return &aalg_list[i];
|
.algs = aalg_list,
|
||||||
else
|
.entries = ARRAY_SIZE(aalg_list),
|
||||||
break;
|
.type = CRYPTO_ALG_TYPE_HASH,
|
||||||
}
|
.mask = CRYPTO_ALG_TYPE_HASH_MASK | CRYPTO_ALG_ASYNC,
|
||||||
}
|
};
|
||||||
return NULL;
|
|
||||||
}
|
static const struct xfrm_algo_list xfrm_ealg_list = {
|
||||||
EXPORT_SYMBOL_GPL(xfrm_aalg_get_byid);
|
.algs = ealg_list,
|
||||||
|
.entries = ARRAY_SIZE(ealg_list),
|
||||||
struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id)
|
.type = CRYPTO_ALG_TYPE_BLKCIPHER,
|
||||||
{
|
.mask = CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC,
|
||||||
int i;
|
};
|
||||||
|
|
||||||
for (i = 0; i < ealg_entries(); i++) {
|
static const struct xfrm_algo_list xfrm_calg_list = {
|
||||||
if (ealg_list[i].desc.sadb_alg_id == alg_id) {
|
.algs = calg_list,
|
||||||
if (ealg_list[i].available)
|
.entries = ARRAY_SIZE(calg_list),
|
||||||
return &ealg_list[i];
|
.type = CRYPTO_ALG_TYPE_COMPRESS,
|
||||||
else
|
.mask = CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC,
|
||||||
break;
|
};
|
||||||
}
|
|
||||||
}
|
static struct xfrm_algo_desc *xfrm_find_algo(
|
||||||
return NULL;
|
const struct xfrm_algo_list *algo_list,
|
||||||
}
|
int match(const struct xfrm_algo_desc *entry, const void *data),
|
||||||
EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid);
|
const void *data, int probe)
|
||||||
|
|
||||||
struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
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 struct xfrm_algo_desc *xfrm_get_byname(struct xfrm_algo_desc *list,
|
|
||||||
int entries, u32 type, u32 mask,
|
|
||||||
char *name, int probe)
|
|
||||||
{
|
{
|
||||||
|
struct xfrm_algo_desc *list = algo_list->algs;
|
||||||
int i, status;
|
int i, status;
|
||||||
|
|
||||||
if (!name)
|
for (i = 0; i < algo_list->entries; i++) {
|
||||||
return NULL;
|
if (!match(list + i, data))
|
||||||
|
|
||||||
for (i = 0; i < entries; i++) {
|
|
||||||
if (strcmp(name, list[i].name) &&
|
|
||||||
(!list[i].compat || strcmp(name, list[i].compat)))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (list[i].available)
|
if (list[i].available)
|
||||||
|
@ -416,8 +393,8 @@ static struct xfrm_algo_desc *xfrm_get_byname(struct xfrm_algo_desc *list,
|
||||||
if (!probe)
|
if (!probe)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
status = crypto_has_alg(list[i].name, type,
|
status = crypto_has_alg(list[i].name, algo_list->type,
|
||||||
mask | CRYPTO_ALG_ASYNC);
|
algo_list->mask);
|
||||||
if (!status)
|
if (!status)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -427,27 +404,60 @@ static struct xfrm_algo_desc *xfrm_get_byname(struct xfrm_algo_desc *list,
|
||||||
return NULL;
|
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)
|
struct xfrm_algo_desc *xfrm_aalg_get_byname(char *name, int probe)
|
||||||
{
|
{
|
||||||
return xfrm_get_byname(aalg_list, aalg_entries(),
|
return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_name_match, name,
|
||||||
CRYPTO_ALG_TYPE_HASH, CRYPTO_ALG_TYPE_HASH_MASK,
|
probe);
|
||||||
name, probe);
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(xfrm_aalg_get_byname);
|
EXPORT_SYMBOL_GPL(xfrm_aalg_get_byname);
|
||||||
|
|
||||||
struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name, int probe)
|
struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name, int probe)
|
||||||
{
|
{
|
||||||
return xfrm_get_byname(ealg_list, ealg_entries(),
|
return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_name_match, name,
|
||||||
CRYPTO_ALG_TYPE_BLKCIPHER, CRYPTO_ALG_TYPE_MASK,
|
probe);
|
||||||
name, probe);
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(xfrm_ealg_get_byname);
|
EXPORT_SYMBOL_GPL(xfrm_ealg_get_byname);
|
||||||
|
|
||||||
struct xfrm_algo_desc *xfrm_calg_get_byname(char *name, int probe)
|
struct xfrm_algo_desc *xfrm_calg_get_byname(char *name, int probe)
|
||||||
{
|
{
|
||||||
return xfrm_get_byname(calg_list, calg_entries(),
|
return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_name_match, name,
|
||||||
CRYPTO_ALG_TYPE_COMPRESS, CRYPTO_ALG_TYPE_MASK,
|
probe);
|
||||||
name, probe);
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(xfrm_calg_get_byname);
|
EXPORT_SYMBOL_GPL(xfrm_calg_get_byname);
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче