網絡子係統11_arp子係統初始化
// 1.鄰居:
// 網絡中的鄰居指連接到同一個LAN中,且至少有一個接口有相同的ip子網配置
// 2.鄰居協議的作用:
// 通過l3地址獲取主機的l2地址
// 3.通過l3獲取l2地址辦法:
// 3.1 點到點連接,此時不需要l2地址
// 3.2 特殊的l3地址,通過簡單的規則獲取l2的映射
// 3.3 多播地址通過簡單的轉換規則轉換為l2地址
// 3.4 ip中使用arp協議完成映射
// arp協議的初始化
// 向內核鄰居子係統注冊arp地址解析協議。
// 調用路徑:inet_init->arp_init
// 函數主要任務:
// 1. 注冊arp協議
// 2. 初始化proc中相應的項
// 3. 向netdev_chain注冊監聽塊
1.1 void __init arp_init(void)
{
//向通用鄰居子係統注冊arp協議
neigh_table_init(&arp_tbl);
//注冊一個l3協議
dev_add_pack(&arp_packet_type);
//初始化proc文件係統中的對應項
arp_proc_init();
...
//係那個netdev_chain注冊監聽者
register_netdevice_notifier(&arp_netdev_notifier);
}
// arp協議表
// 參考 深入理解linux網絡技術內幕
2.1 struct neigh_table arp_tbl = {
.family = AF_INET,//協議所屬的地址族
.entry_size = sizeof(struct neighbour) + 4,//多預留4個字節
.key_len = 4,//hash函數使用的key的長度,ip地址長度
.hash = arp_hash,//hash函數
.constructor = arp_constructor,//初始化struct neighbour的回調函數
.proxy_redo = parp_redo,//代理相關
.id = "arp_cache",//分配struct neighbour SLAB時,用於指定名字
.parms = { //默認提供一個調整鄰居協議的控製塊
.tbl = &arp_tbl,
.base_reachable_time = 30 * HZ,//默認可到達性時間間隔基值
.retrans_time = 1 * HZ,//當一台主機在retrans_time時間間隔內沒有收到solicitation請求的應答時,就會發出一個新的solicitation請求
.gc_staletime = 60 * HZ,//一個鄰居項在gc_staletime時間還沒有被用到,並且沒有程序引用它,則它會被刪除
.reachable_time = 30 * HZ,//由rand(0, base_reachable_time) + base_reachable_time/2計算
.delay_probe_time = 5 * HZ,//NUD_DELAY->NUD_PROBE的時間間隔
.queue_len = 3,//arp_queue隊列中能容納的元素最大數目
.ucast_probes = 3,//為證實一個地址的可到達性,能發送的單播solicitation數目量
.mcast_probes = 3,//為解析一個鄰居地址,可以發出的多播solicitation請求數
.anycast_delay = 1 * HZ,//暫不使用
.proxy_delay = (8 * HZ) / 10,//代理相關
.proxy_qlen = 64,
.locktime = 1 * HZ,//相鄰兩次對一個neighbour項字段更新時,必須經曆的時間間隔
},
.gc_interval = 30 * HZ,//控製gc_timer定時器的超時時間
.gc_thresh1 = 128,//三個不同級別的內存狀態
.gc_thresh2 = 512,
.gc_thresh3 = 1024,
};
// arp子係統對網絡設備事件的監聽控製塊
2.1 static struct notifier_block arp_netdev_notifier = {
.notifier_call = arp_netdev_event,
};
// 網絡設備事件的處理函數
// arp協議隻處理到達此鄰居項的接口設備地址改變消息。
2.2 static int arp_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
{
struct net_device *dev = ptr;
//設備的硬件地址已改變
switch (event) {
case NETDEV_CHANGEADDR:
//通用例程
neigh_changeaddr(&arp_tbl, dev);
//刷新路由緩存
rt_cache_flush(0);
break;
default:
break;
}
return NOTIFY_DONE;
}
最後更新:2017-04-03 15:21:56