Understanding.Linux.Network.Internals 讀書筆記 Chapter 4. Notification Chains
來源:互聯網
上載者:User
本章介紹核心子系統之間的相互連信機制
核心子系統之間的相互連信使用了通知鏈表機制,什麼意思?比如系統探測到某個介面串連的網路斷開,於是通過通知鏈表來告知路由子系統這個介面失效,並修正相應的路由表。
通知鏈表的定義
struct notifier_block{ //通知鏈表中的節點
int (*notifier_call)(struct notifier_block *self,unsigned long,void *); //需要執行的函數
struct notifier_block *next;
int priority;
}
在通知鏈表上註冊通知結構
如果某個核心組件對某個通知鏈表上的事件感興趣,它可以調用函數notifier_chain_register往這個鏈表上註冊一個節點
int notifier_chain_register(struct notifier_block **list,struct notifier_block *n){
write_lock(¬ifier_lock);
while(*list){
if(n->priority>(*list)->priority) break;
list=&((*list)->next);
}
n->next =*list;
*list=n;
write_unlock(¬ifier_lock);
return 0;
}
給通知鏈表發送事件
int notifier_call_chain(struct notifier_block **n,unsigned long val,void *v){ // 按順序啟用所有通知鏈表上註冊的函數 n--通知鏈表 val--事件類型 v--註冊的函數輸入參數
int ret =NOTIFY_DONE;
struct notifier_block *nb=*n;
while(nb){
ret=nb->notifier_call(nb,val,v);
if(ret&NOTIFY_STOP_MASK){
return ret;
}
nb=nb->next;
}
return ret; //ret傳回值在include/linux/notifier.h中有定義
}
舉例
下面是兩個網路代碼中常用的通知鏈表
inetaddr_chain 在本地介面上添加。刪除和修改地址時發送通知
netdev_chain 網路裝置狀態改變時發送通知
路由初始化代碼中會有如下;
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); //此處是封裝函數 最後實際上是要調用notifier_chain_register(&netdev_chain,*fib_netdev_notifier);
register_inetaddr_notifier(&fib_inetaddr_notifier);
} //ip地址的改變和網路裝置狀態的改變都會影響路由表