crypto/af_alg.c
Source file repositories/reference/linux-study-clean/crypto/af_alg.c
File Facts
- System
- Linux kernel
- Corpus path
crypto/af_alg.c- Extension
.c- Size
- 27466 bytes
- Lines
- 1253
- Domain
- Kernel Services
- Bucket
- crypto
- Inferred role
- Kernel Services: operation-table or driver-model contract
- Status
- pattern implementation candidate
Why This File Exists
Shared kernel service surface used by multiple subsystems, including helpers, cryptography, virtualization support, and async I/O infrastructure.
- Shared kernel service surface used by multiple subsystems, including helpers, cryptography, virtualization support, and async I/O infrastructure.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/atomic.hcrypto/if_alg.hlinux/crypto.hlinux/init.hlinux/kernel.hlinux/key.hlinux/key-type.hlinux/list.hlinux/module.hlinux/net.hlinux/rwsem.hlinux/sched.hlinux/sched/signal.hlinux/security.hlinux/string.hkeys/user-type.hkeys/trusted-type.hkeys/encrypted-type.h
Detected Declarations
struct alg_type_listfunction af_alg_register_typefunction af_alg_unregister_typefunction alg_do_releasefunction af_alg_releasefunction af_alg_release_parentfunction alg_bindfunction alg_setkeyfunction alg_setkey_by_key_serialfunction alg_setkey_by_key_serialfunction alg_setsockoptfunction af_alg_acceptfunction alg_acceptfunction alg_sock_destructfunction alg_createfunction af_alg_link_sgfunction af_alg_free_sgfunction af_alg_cmsg_sendfunction for_each_cmsghdrfunction af_alg_alloc_tsglfunction af_alg_count_tsglfunction list_for_each_entryfunction af_alg_pull_tsglfunction af_alg_free_areq_sglsfunction list_for_each_entry_safefunction for_each_sgfunction af_alg_wait_for_wmemfunction af_alg_wmem_wakeupfunction af_alg_wait_for_datafunction af_alg_data_wakeupfunction af_alg_sendmsgfunction af_alg_free_resourcesfunction af_alg_pollfunction af_alg_get_rsglfunction af_alg_initfunction af_alg_exitmodule init af_alg_initexport af_alg_register_typeexport af_alg_unregister_typeexport af_alg_releaseexport af_alg_release_parentexport af_alg_acceptexport af_alg_free_sgexport af_alg_count_tsglexport af_alg_pull_tsglexport af_alg_wmem_wakeupexport af_alg_wait_for_dataexport af_alg_sendmsg
Annotated Snippet
static const struct proto_ops alg_proto_ops = {
.family = PF_ALG,
.owner = THIS_MODULE,
.connect = sock_no_connect,
.socketpair = sock_no_socketpair,
.getname = sock_no_getname,
.ioctl = sock_no_ioctl,
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
.mmap = sock_no_mmap,
.sendmsg = sock_no_sendmsg,
.recvmsg = sock_no_recvmsg,
.bind = alg_bind,
.release = af_alg_release,
.setsockopt = alg_setsockopt,
.accept = alg_accept,
};
static void alg_sock_destruct(struct sock *sk)
{
struct alg_sock *ask = alg_sk(sk);
alg_do_release(ask->type, ask->private);
}
static int alg_create(struct net *net, struct socket *sock, int protocol,
int kern)
{
struct sock *sk;
int err;
if (sock->type != SOCK_SEQPACKET)
return -ESOCKTNOSUPPORT;
if (protocol != 0)
return -EPROTONOSUPPORT;
err = -ENOMEM;
sk = sk_alloc(net, PF_ALG, GFP_KERNEL, &alg_proto, kern);
if (!sk)
goto out;
sock->ops = &alg_proto_ops;
sock_init_data(sock, sk);
sk->sk_destruct = alg_sock_destruct;
return 0;
out:
return err;
}
static const struct net_proto_family alg_family = {
.family = PF_ALG,
.create = alg_create,
.owner = THIS_MODULE,
};
static void af_alg_link_sg(struct af_alg_sgl *sgl_prev,
struct af_alg_sgl *sgl_new)
{
sg_unmark_end(sgl_prev->sgt.sgl + sgl_prev->sgt.nents - 1);
sg_chain(sgl_prev->sgt.sgl, sgl_prev->sgt.nents + 1, sgl_new->sgt.sgl);
}
void af_alg_free_sg(struct af_alg_sgl *sgl)
{
int i;
if (sgl->sgt.sgl) {
if (sgl->need_unpin)
for (i = 0; i < sgl->sgt.nents; i++)
unpin_user_page(sg_page(&sgl->sgt.sgl[i]));
if (sgl->sgt.sgl != sgl->sgl)
kvfree(sgl->sgt.sgl);
sgl->sgt.sgl = NULL;
}
}
EXPORT_SYMBOL_GPL(af_alg_free_sg);
static int af_alg_cmsg_send(struct msghdr *msg, struct af_alg_control *con)
{
struct cmsghdr *cmsg;
for_each_cmsghdr(cmsg, msg) {
if (!CMSG_OK(msg, cmsg))
return -EINVAL;
if (cmsg->cmsg_level != SOL_ALG)
continue;
Annotation
- Immediate include surface: `linux/atomic.h`, `crypto/if_alg.h`, `linux/crypto.h`, `linux/init.h`, `linux/kernel.h`, `linux/key.h`, `linux/key-type.h`, `linux/list.h`.
- Detected declarations: `struct alg_type_list`, `function af_alg_register_type`, `function af_alg_unregister_type`, `function alg_do_release`, `function af_alg_release`, `function af_alg_release_parent`, `function alg_bind`, `function alg_setkey`, `function alg_setkey_by_key_serial`, `function alg_setkey_by_key_serial`.
- Atlas domain: Kernel Services / crypto.
- Implementation status: pattern implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.