最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

深入講解linux內(nèi)核學(xué)習(xí)筆記------鄰居子系統(tǒng)(一)

2022-08-14 12:20 作者:補(bǔ)給站Linux內(nèi)核  | 我要投稿

鄰居子系統(tǒng)的結(jié)構(gòu)由多個(gè)數(shù)據(jù)結(jié)構(gòu)組成:

1、neigh_table結(jié)構(gòu):該結(jié)構(gòu)主要用來(lái)存儲(chǔ)與鄰居協(xié)議相關(guān)的參數(shù),功能函數(shù),以及鄰居項(xiàng)散列表;一個(gè)neigh_table結(jié)構(gòu)實(shí)例對(duì)應(yīng)一個(gè)鄰居協(xié)議(例如:arp,arp_tbl),所有的實(shí)例都鏈接在全局鏈表neigh_tables中。linux內(nèi)核源碼剖析——tcp/ip實(shí)現(xiàn)對(duì)這個(gè)結(jié)構(gòu)體做了很詳細(xì)的描述,大家可以去看看

2、neighbor結(jié)構(gòu):鄰居項(xiàng)就是使用該結(jié)構(gòu)來(lái)描述,該結(jié)構(gòu)存儲(chǔ)了鄰居的相關(guān)信息,包括狀態(tài),二層和三層協(xié)議地址,提供給三層協(xié)議的函數(shù)指針,還有定時(shí)器和緩存的二層首部等。注:一個(gè)鄰居并不代表一個(gè)主機(jī),而是一個(gè)三層協(xié)議地址,對(duì)于配置了多接口的主機(jī),一個(gè)主機(jī)將對(duì)應(yīng)多個(gè)三層協(xié)議地址。

3、neigh_ops結(jié)構(gòu):該結(jié)構(gòu)相當(dāng)于是鄰居項(xiàng)函數(shù)指針表,由在鄰居的生存周期中不同時(shí)期被調(diào)用的多個(gè)函數(shù)指針組成。其中有多個(gè)函數(shù)指針是實(shí)現(xiàn)三層與dev_queue_xmit之間的調(diào)用橋梁,適用于不同狀態(tài);

struct neigh_ops
{
	/*
	 * 標(biāo)識(shí)所屬的地址族,比如ARP為AF_INET等。
	 */
	int			family;
	/*
	 * 發(fā)送請(qǐng)求報(bào)文函數(shù)。在發(fā)送第一個(gè)報(bào)文時(shí),需要
	 * 新的鄰居項(xiàng),發(fā)送報(bào)文被緩存到arp_queue隊(duì)列中,
	 * 然后會(huì)調(diào)用solicit()發(fā)送請(qǐng)求報(bào)文。
	 */
	void			(*solicit)(struct neighbour *, struct sk_buff*);
	/*
	 * 當(dāng)鄰居項(xiàng)緩存著未發(fā)送的報(bào)文,而該鄰居項(xiàng)又不可達(dá)時(shí),
	 * 被調(diào)用來(lái)向三層報(bào)告錯(cuò)誤的函數(shù)。ARP中為arp_error_report(),
	 * 最終會(huì)給報(bào)文發(fā)送方發(fā)送一個(gè)主機(jī)不可達(dá)的ICMP差錯(cuò)報(bào)文。
	 */
	void			(*error_report)(struct neighbour *, struct sk_buff*);
	/*
	 * 最通用的輸出函數(shù),可用于所有情況。此輸出函數(shù)實(shí)現(xiàn)了
	 * 完整的輸出過(guò)程,因此存在較多的校驗(yàn)與操作,以確保
	 * 報(bào)文的輸出,因此該函數(shù)相對(duì)較消耗資源。此外,不要
	 * 將neigh_ops->output()與neighbour->output()混淆。
	 */
	int			(*output)(struct sk_buff*);
	/*
	 * 在確定鄰居可達(dá)時(shí),即狀態(tài)為NUD_CONNECTED時(shí)使用的輸出函數(shù)。
	 * 由于所有輸出所需要的信息都已具備,因此該函數(shù)只是簡(jiǎn)單
	 * 地添加二層首部,也因此比output()快得多。
	 */
	int			(*connected_output)(struct sk_buff*);
	/*
	 * 在已緩存了二層首部的情況下使用的輸出函數(shù)。
	 */
	int			(*hh_output)(struct sk_buff*);
	/*
	 * 實(shí)際上,以上幾個(gè)輸出接口,除了hh_output外,并不真正傳輸
	 * 數(shù)據(jù)包,只是在準(zhǔn)備好二層首部之后,調(diào)用queue_xmit接口。
	 */
	int			(*queue_xmit)(struct sk_buff*);
};


【文章福利】小編推薦自己的Linux內(nèi)核技術(shù)交流群:【891587639】整理了一些個(gè)人覺(jué)得比較好的學(xué)習(xí)書籍、視頻資料共享在群文件里面,有需要的可以自行添加哦?。。。ê曨l教程、電子書、實(shí)戰(zhàn)項(xiàng)目及代碼)? ??

注意solicit,output,connected_output,hh_output以及queue_xmit的區(qū)別以及聯(lián)系,注釋中也講了很明顯。 4、neigh_parms結(jié)構(gòu):該結(jié)構(gòu)是鄰居協(xié)議參數(shù)的配置塊,用于存儲(chǔ)可調(diào)節(jié)的鄰居協(xié)議參數(shù),如重傳超時(shí)時(shí)間,proxy_queue隊(duì)列長(zhǎng)度等。一個(gè)鄰居協(xié)議對(duì)應(yīng)一個(gè)參數(shù)配置塊,而每一個(gè)網(wǎng)絡(luò)設(shè)備的ipv4的配置塊中也存在一個(gè)存放默認(rèn)值的鄰居配置塊。

5、pneigh_entry結(jié)構(gòu):該結(jié)構(gòu)用來(lái)保存允許代理的條件,只有和結(jié)構(gòu)中的接收設(shè)備以及目標(biāo)地址想匹配才能代理。所有的pneigh_entry實(shí)例都存儲(chǔ)在鄰居表的phash_buckets散列表中。稱之為代理向,可通過(guò)ip neigh add proxy命令添加。

6、hh_cache結(jié)構(gòu):該結(jié)構(gòu)用來(lái)緩存二層首部,這樣就可以復(fù)制而不是逐個(gè)域的設(shè)置二層首部,從而加速報(bào)文的輸出,但也并非所有的設(shè)備驅(qū)動(dòng)程序都需要緩存二層首部。

鄰居表是由neigh_table_init初始化,對(duì)于arp_tbl的初始化,在arp模塊初始化時(shí)由arp_init

void __init arp_init(void)
{
	neigh_table_init(&arp_tbl);
 
	dev_add_pack(&arp_packet_type);
	arp_proc_init();
#ifdef CONFIG_SYSCTL
	neigh_sysctl_register(NULL, &arp_tbl.parms, NET_IPV4,
			 ? ? ?NET_IPV4_NEIGH, "ipv4", NULL, NULL);
#endif
	register_netdevice_notifier(&arp_netdev_notifier);
}
 
void neigh_table_init(struct neigh_table *tbl)
{
	struct neigh_table *tmp;
 
	neigh_table_init_no_netlink(tbl);
	write_lock(&neigh_tbl_lock);
	for (tmp = neigh_tables; tmp; tmp = tmp->next) {
		if (tmp->family == tbl->family)
			break;
	}
	tbl->next	= neigh_tables;
	neigh_tables	= tbl;
	write_unlock(&neigh_tbl_lock);
 
	if (unlikely(tmp)) {
		printk(KERN_ERR "NEIGH: Registering multiple tables for "
		 ? ? ? "family %d\n", tbl->family);
		dump_stack();
	}
}

從上面的源碼看出,arp初始化首先就會(huì)調(diào)用neigh_table_init對(duì)鄰居表進(jìn)行初始化,而neigh_table_init也比較簡(jiǎn)單,主要就是從neigh_tables中查找,看此鄰居表是否已經(jīng)存在,如果存在會(huì)報(bào)錯(cuò),否則就會(huì)把該鄰居表插入到neigh_tables中;在neigh_table_init_no_netlink這個(gè)函數(shù)中會(huì)做一些初始化的工作,分配緩存,初始化定時(shí)器的功能,創(chuàng)建存儲(chǔ)鄰居項(xiàng)和代理項(xiàng)的hash_buckets,phash_buckets; 鄰居項(xiàng)存在一種狀態(tài)機(jī),鄰居項(xiàng)都有一個(gè)對(duì)于管理和維護(hù)鄰居表來(lái)說(shuō)非常重要的成員,nud_state,用來(lái)表示該鄰居項(xiàng)當(dāng)前所處的狀態(tài)。具體的狀態(tài)遷移圖在上面提到的那本書中有,并且在第二篇博客中博主結(jié)合arp協(xié)議進(jìn)行描繪。下面依依介紹這幾個(gè)狀態(tài):

1、NUD_NONE:鄰居項(xiàng)剛建立時(shí)處于的狀態(tài),在該狀態(tài)下,還沒(méi)有硬件地址可以用,所以還不能發(fā)送請(qǐng)求報(bào)文。一旦有報(bào)文要輸出到該鄰居,便會(huì)出發(fā)對(duì)該鄰居硬件地址的請(qǐng)求,進(jìn)入NUD_INCOMPLETE狀態(tài),并緩存發(fā)送的報(bào)文

2、NUD_INCOMPLETE:該狀態(tài)是請(qǐng)求報(bào)文已發(fā)送,但尚未收到應(yīng)答的狀態(tài)。該狀態(tài)下還沒(méi)解析到硬件地址,因此尚無(wú)可用硬件地址,如果有報(bào)文要輸出到該鄰居,會(huì)將其緩存起來(lái)。這個(gè)狀態(tài)會(huì)啟動(dòng)一個(gè)定時(shí)器,如果在定時(shí)器到期時(shí)還沒(méi)有接收到鄰居的回應(yīng),則會(huì)重復(fù)發(fā)送請(qǐng)求報(bào)文,進(jìn)入NUD_REACHABLE,否則發(fā)送請(qǐng)求報(bào)文的次數(shù)打到上限,便會(huì)進(jìn)入NUD_FAILED

3、NUD_REACHABEL:該狀態(tài)以及得到并緩存了鄰居的硬件地址。進(jìn)入該狀態(tài)首先設(shè)置鄰居項(xiàng)相關(guān)的output函數(shù)(該狀態(tài)使用neighbors_ops結(jié)構(gòu)的connectd_outpt),然后查看是否存在要發(fā)送給該鄰居的報(bào)文。如果在該狀態(tài)下閑置時(shí)間達(dá)到上限,便會(huì)進(jìn)入NUD_STATLE

4、NUD_STATLE:該狀態(tài)一旦有報(bào)文要輸出到該鄰居,則會(huì)進(jìn)入NUD_DELAY并將該報(bào)文輸出。如果在該狀態(tài)下閑置時(shí)間達(dá)到上限,且此時(shí)的引用計(jì)數(shù)為1,則通過(guò)垃圾回收機(jī)制將其刪除,在該狀態(tài)下,報(bào)文的輸出不收限制,使用慢速發(fā)送過(guò)程

5、NUD_DELAY:該狀態(tài)下表示NUD_STATE狀態(tài)下發(fā)送的報(bào)文已經(jīng)發(fā)出,需得到鄰居的可達(dá)性確認(rèn)的狀態(tài)。在為接收到鄰居的應(yīng)答或確認(rèn)時(shí)也會(huì)定時(shí)地重發(fā)請(qǐng)求,如果發(fā)送請(qǐng)求報(bào)文的次數(shù)到上限,如果收到鄰居的應(yīng)答,進(jìn)入NUD_REACHABEL,否則進(jìn)入NUD_FAILED,在該狀態(tài)下,報(bào)文的輸出不收限制,使用慢速發(fā)送過(guò)程

還有幾種狀態(tài)比較容易理解,也就不特意列出了。





深入講解linux內(nèi)核學(xué)習(xí)筆記------鄰居子系統(tǒng)(一)的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
阳泉市| 合山市| 邵武市| 苏尼特右旗| 沂南县| 鄂温| 达拉特旗| 台东市| 望谟县| 哈密市| 中牟县| 甘泉县| 綦江县| 靖边县| 吉木萨尔县| 曲水县| 巴彦淖尔市| 长宁区| 大港区| 台山市| 黄平县| 霍山县| 新宾| 城步| 伊宁市| 吉隆县| 连平县| 茶陵县| 安庆市| 灌阳县| 界首市| 大姚县| 辽阳市| 三江| 金门县| 云林县| 确山县| 察哈| 荃湾区| 苍南县| 延川县|