Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c92b3a2f authored by Herbert Xu's avatar Herbert Xu Committed by David S. Miller
Browse files

[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: default avatarHerbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 580e572a
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -1448,8 +1448,6 @@ static int pfkey_add(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr,
	int err;
	struct km_event c;

	xfrm_probe_algs();

	x = pfkey_msg2xfrm_state(hdr, ext_hdrs);
	if (IS_ERR(x))
		return PTR_ERR(x);
+75 −65
Original line number Diff line number Diff line
@@ -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);