《深入理解LINUX网络内幕》读书笔记2

用户空间和内核接口

Linux有用户空间和内核空间,编程时用户空间想使用内核空间的功能只能通过特定的接口,这些接口就是系统调用。

内核把内部信息输出到用户空间,除了system call外,还有三个特殊的接口:

  • procfs:一个虚拟文件系统,mount在/proc下,内核以文件的形式输出内部信息到用户空间,这里的文件用户空间只可读不可写。

  • sysctl:mount在/proc/sys下,允许用户空间读写内核变量的值。

2.6以后procfs、sysctl部分移植到了sysfs(/sys文件系统)

ioctl系统调用和Netlink套接字(Socket,RFC3549)

通知链

一种编程模型:发布-订阅(publish-and-subscribe)模型

作用:模块间事件同步,好处是降低了模块间的耦合。

主动端是发送事件的通知者,维护一个本模块全局链表,被动端即订阅者在初始化的时候,通过通知接口注册一个回调函数到主动端的链表上,当主动端发生事件时,依次调用链表上的回调函数,使得其他模块对该事件做响应。

定义链:

struct notifier_block {
	int (*notifier_call)(struct notifier_block *, unsigned long, void *);
	struct notifier_block *next;
	int priority;
};

接口主要有注册函数notifier_chain_register、删除函数notifier_chain_unregister和执行函数notifier_call_chain

这三个接口都是内部接口,实际使用时都封装了包裹函数,通常因为要上锁。尤其是注册函数,模块通常封装成该模块特定的包裹函数。

典型例子参见net/ipv4/fib_frontend.c路由代码的初始化函数:

static struct notifier_block fib_inetaddr_notifier = {
	.notifier_call =fib_inetaddr_event,
};
static struct notifier_block fib_netdev_notifier = {
	.notifier_call =fib_netdev_event,
};
void __init ip_fib_init(void)
{
    。。。
    register_netdevice_notifier(&fib_netdev_notifier);
    register_inetaddr_notifier(&fib_inetaddr_notifier);
    nl_fib_lookup_init();
}

当发生IP地址的插入、删除等事件时,就会调用回调fib_inetaddr_event来更新路由模块。

注意:通知链的执行可以是直接调用,也可以是使用消息队列,实现进程间通信。

你可能感兴趣的:(《深入理解LINUX网络内幕》读书笔记2)