net/xfrm/xfrm_algo.c

Source file repositories/reference/linux-study-clean/net/xfrm/xfrm_algo.c

File Facts

System
Linux kernel
Corpus path
net/xfrm/xfrm_algo.c
Extension
.c
Size
14471 bytes
Lines
842
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.

Dependency Surface

Detected Declarations

Annotated Snippet

struct xfrm_algo_list {
	int (*find)(const char *name, u32 type, u32 mask);
	struct xfrm_algo_desc *algs;
	int entries;
};

static const struct xfrm_algo_list xfrm_aead_list = {
	.find = crypto_has_aead,
	.algs = aead_list,
	.entries = ARRAY_SIZE(aead_list),
};

static const struct xfrm_algo_list xfrm_aalg_list = {
	.find = crypto_has_ahash,
	.algs = aalg_list,
	.entries = ARRAY_SIZE(aalg_list),
};

static const struct xfrm_algo_list xfrm_ealg_list = {
	.find = crypto_has_skcipher,
	.algs = ealg_list,
	.entries = ARRAY_SIZE(ealg_list),
};

static const struct xfrm_algo_list xfrm_calg_list = {
	.find = crypto_has_acomp,
	.algs = calg_list,
	.entries = ARRAY_SIZE(calg_list),
};

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;

	for (i = 0; i < algo_list->entries; i++) {
		if (!match(list + i, data))
			continue;

		if (list[i].available)
			return &list[i];

		if (!probe)
			break;

		status = algo_list->find(list[i].name, 0, 0);
		if (!status)
			break;

		list[i].available = status;
		return &list[i];
	}
	return NULL;
}

static int xfrm_alg_id_match(const struct xfrm_algo_desc *entry,
			     const void *data)
{
	return entry->desc.sadb_alg_id == (unsigned long)data;
}

struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id)
{
	return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_id_match,
			      (void *)(unsigned long)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 *)(unsigned long)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 *)(unsigned long)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;

Annotation

Implementation Notes