net/key/af_key.c
Source file repositories/reference/linux-study-clean/net/key/af_key.c
File Facts
- System
- Linux kernel
- Corpus path
net/key/af_key.c- Extension
.c- Size
- 104486 bytes
- Lines
- 3954
- Domain
- Networking Core
- Bucket
- Sockets, Protocols, Packet Path, And Network Policy
- Inferred role
- Networking Core: operation-table or driver-model contract
- Status
- pattern implementation candidate
Why This File Exists
Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.
- Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.
- 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/capability.hlinux/module.hlinux/kernel.hlinux/socket.hlinux/pfkeyv2.hlinux/ipsec.hlinux/skbuff.hlinux/rtnetlink.hlinux/in.hlinux/in6.hlinux/proc_fs.hlinux/init.hlinux/slab.hnet/net_namespace.hnet/netns/generic.hnet/xfrm.hnet/sock.h
Detected Declarations
struct netns_pfkeystruct pfkey_sockfunction pfkey_can_dumpfunction pfkey_terminate_dumpfunction pfkey_sock_destructfunction pfkey_insertfunction pfkey_removefunction pfkey_createfunction pfkey_releasefunction pfkey_broadcast_onefunction pfkey_broadcastfunction pfkey_do_dumpfunction pfkey_hdr_dupfunction pfkey_errorfunction verify_address_lenfunction sadb_key_lenfunction verify_key_lenfunction pfkey_sec_ctx_lenfunction verify_sec_ctx_lenfunction present_and_same_familyfunction parse_exthdrsfunction pfkey_satype2protofunction pfkey_proto2satypefunction pfkey_proto_to_xfrmfunction pfkey_proto_from_xfrmfunction pfkey_sockaddr_lenfunction pfkey_sockaddr_extractfunction pfkey_sadb_addr2xfrm_addrfunction pfkey_sockaddr_sizefunction pfkey_mode_from_xfrmfunction pfkey_mode_to_xfrmfunction pfkey_sockaddr_fillfunction pfkey_sockaddr_fill_zero_tailfunction pfkey_msg2xfrm_statefunction pfkey_reservedfunction pfkey_getspifunction pfkey_acquirefunction event2poltypefunction event2keytypefunction key_notify_safunction pfkey_addfunction pfkey_deletefunction pfkey_getfunction pfkey_registerfunction unicast_flush_respfunction key_notify_sa_flushfunction pfkey_flushfunction dump_sa
Annotated Snippet
static const struct proto_ops pfkey_ops;
static void pfkey_insert(struct sock *sk)
{
struct net *net = sock_net(sk);
struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id);
mutex_lock(&pfkey_mutex);
sk_add_node_rcu(sk, &net_pfkey->table);
mutex_unlock(&pfkey_mutex);
}
static void pfkey_remove(struct sock *sk)
{
mutex_lock(&pfkey_mutex);
sk_del_node_init_rcu(sk);
mutex_unlock(&pfkey_mutex);
}
static struct proto key_proto = {
.name = "KEY",
.owner = THIS_MODULE,
.obj_size = sizeof(struct pfkey_sock),
};
static int pfkey_create(struct net *net, struct socket *sock, int protocol,
int kern)
{
struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id);
struct sock *sk;
struct pfkey_sock *pfk;
if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
return -EPERM;
if (sock->type != SOCK_RAW)
return -ESOCKTNOSUPPORT;
if (protocol != PF_KEY_V2)
return -EPROTONOSUPPORT;
sk = sk_alloc(net, PF_KEY, GFP_KERNEL, &key_proto, kern);
if (sk == NULL)
return -ENOMEM;
pfk = pfkey_sk(sk);
mutex_init(&pfk->dump_lock);
sock->ops = &pfkey_ops;
sock_init_data(sock, sk);
sk->sk_family = PF_KEY;
sk->sk_destruct = pfkey_sock_destruct;
atomic_inc(&net_pfkey->socks_nr);
pfkey_insert(sk);
return 0;
}
static int pfkey_release(struct socket *sock)
{
struct sock *sk = sock->sk;
if (!sk)
return 0;
pfkey_remove(sk);
sock_orphan(sk);
sock->sk = NULL;
skb_queue_purge(&sk->sk_write_queue);
synchronize_rcu();
sock_put(sk);
return 0;
}
static int pfkey_broadcast_one(struct sk_buff *skb, gfp_t allocation,
struct sock *sk)
{
int err = -ENOBUFS;
if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf)
return err;
skb = skb_clone(skb, allocation);
if (skb) {
skb_set_owner_r(skb, sk);
Annotation
- Immediate include surface: `linux/capability.h`, `linux/module.h`, `linux/kernel.h`, `linux/socket.h`, `linux/pfkeyv2.h`, `linux/ipsec.h`, `linux/skbuff.h`, `linux/rtnetlink.h`.
- Detected declarations: `struct netns_pfkey`, `struct pfkey_sock`, `function pfkey_can_dump`, `function pfkey_terminate_dump`, `function pfkey_sock_destruct`, `function pfkey_insert`, `function pfkey_remove`, `function pfkey_create`, `function pfkey_release`, `function pfkey_broadcast_one`.
- Atlas domain: Networking Core / Sockets, Protocols, Packet Path, And Network Policy.
- 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.