netlink 是一种基于网络的通信机制,允许在内核内部以及内核与用户层之间进行通信,其正式定义见RFC3549
netlink 相对于 procfs 或 sysfs 具有以下优势:
1.不需要轮询。
2. 简单、容易实现。
3. 内核可以直接向用户层发送信息,而无需用户层事先请求。
netlink 只支持数据报信息,但提供了双向通信。此外,netlink 不仅支持单播信息,也可以进行多播。类似于其他socket机制,netlink的工作方式是异步的。
审计子系统代码: kernle/audit.c
/* Initialize audit support at boot time. */ static int __init audit_init(void) { int i; if (audit_initialized == AUDIT_DISABLED) return 0; printk(KERN_INFO "audit: initializing netlink socket (%s)\n", audit_default ? "enabled" : "disabled"); audit_sock = netlink_kernel_create(&init_net, NETLINK_AUDIT, 0, audit_receive, NULL, THIS_MODULE); if (!audit_sock) audit_panic("cannot initialize netlink socket"); else audit_sock->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT; skb_queue_head_init(&audit_skb_queue); skb_queue_head_init(&audit_skb_hold_queue); audit_initialized = AUDIT_INITIALIZED; audit_enabled = audit_default; audit_ever_enabled |= !!audit_default; audit_log(NULL, GFP_KERNEL, AUDIT_KERNEL, "initialized"); for (i = 0; i < AUDIT_INODE_BUCKETS; i++) INIT_LIST_HEAD(&audit_inode_hash[i]); return 0; }
回调函数
/* Receive messages from netlink socket. */ static void audit_receive(struct sk_buff *skb) { mutex_lock(&audit_cmd_mutex); audit_receive_skb(skb); mutex_unlock(&audit_cmd_mutex); }
具体实现
/* * Get message from skb. Each message is processed by audit_receive_msg. * Malformed skbs with wrong length are discarded silently. */ static void audit_receive_skb(struct sk_buff *skb) { struct nlmsghdr *nlh; /* * len MUST be signed for NLMSG_NEXT to be able to dec it below 0 * if the nlmsg_len was not aligned */ int len; int err; nlh = nlmsg_hdr(skb); len = skb->len; while (NLMSG_OK(nlh, len)) { err = audit_receive_msg(skb, nlh); /* if err or if this message says it wants a response */ if (err || (nlh->nlmsg_flags & NLM_F_ACK)) netlink_ack(skb, nlh, err); nlh = NLMSG_NEXT(nlh, len); } }
参考:
http://my.oschina.net/longscu/blog/59534
http://www.cnitblog.com/SpiWolf/archive/2006/06/14/5514.html