一文讀懂Linux網(wǎng)絡(luò)命名空間
1.1 Linux網(wǎng)絡(luò)
Linux 是因特網(wǎng)的產(chǎn)物, 這是無(wú)可爭(zhēng)議的. 首先, 得感謝因特網(wǎng)通信, Linux的開(kāi)發(fā)過(guò)程證明了一個(gè)很多人曾持有的觀(guān)點(diǎn)是荒謬的 : 對(duì)分散在世界各地的一組程序員進(jìn)行項(xiàng)目管理是不可能的. 第一個(gè)內(nèi)核源代碼版本是在十多年前通過(guò)FTP服務(wù)器提供的, 此后網(wǎng)絡(luò)便成了數(shù)據(jù)交換的支柱, 無(wú)論是概念和代碼的開(kāi)發(fā), 還是內(nèi)核錯(cuò)誤的消除, 都是如此.
內(nèi)核郵件列表是個(gè)活生生的例子, 它幾乎沒(méi)有改變過(guò). 每個(gè)人都能夠看到最新貢獻(xiàn)的代碼, 并為促進(jìn)Linux的開(kāi)發(fā)提出自己的意見(jiàn), 當(dāng)然, 得假定所表達(dá)的意見(jiàn)是合理的. Linux對(duì)各種網(wǎng)絡(luò)適應(yīng)得都很好, 這是可以理解的, 因?yàn)樗桥c因特網(wǎng)共同成長(zhǎng)的.
在構(gòu)成因特網(wǎng)的服務(wù)器中, 大部分是運(yùn)行Linux的計(jì)算機(jī). 不出所料, 網(wǎng)絡(luò)實(shí)現(xiàn)是Linux內(nèi)核中一個(gè)關(guān)鍵的部分, 正在獲得越來(lái)越多的關(guān)注. 實(shí)際上, Linux不支持的網(wǎng)絡(luò)方案很少.
網(wǎng)絡(luò)功能的實(shí)現(xiàn)是內(nèi)核最復(fù)雜、牽涉最廣的一部分. 除了經(jīng)典的因特網(wǎng)協(xié)議(如TCP、UDP)和相關(guān)的IP傳輸機(jī)制之外, Linux還支持許多其他的互聯(lián)方案,使得所有想得到的計(jì)算機(jī)/操作系統(tǒng)能夠互操作.
Linux也支持大量用于數(shù)據(jù)傳輸?shù)挠布? 如以太網(wǎng)卡和令牌環(huán)網(wǎng)適配器及ISDN卡和調(diào)制解調(diào)器, 但這并沒(méi)有使內(nèi)核的工作變得簡(jiǎn)單.
盡管如此, Linux開(kāi)發(fā)人員提出了一種結(jié)構(gòu)良好得令人驚訝的模型, 統(tǒng)一了各種不同的方法. 雖然本章是本書(shū)最長(zhǎng)的章之一, 但并沒(méi)有涵蓋網(wǎng)絡(luò)實(shí)現(xiàn)的每個(gè)細(xì)節(jié). 即使概述一下所有的驅(qū)動(dòng)程序和協(xié)議, 也超出了一本書(shū)的范圍, 由于信息量巨大, 實(shí)際上可能需要許多本書(shū). 不算網(wǎng)卡驅(qū)動(dòng)程序, 網(wǎng)絡(luò)子系統(tǒng)的C語(yǔ)言實(shí)現(xiàn)在內(nèi)核源代碼中就占了15MB, 如果將相應(yīng)的代碼打印到紙上要有6000多頁(yè). 與網(wǎng)絡(luò)相關(guān)的頭文件的數(shù)目巨大, 使得內(nèi)核開(kāi)發(fā)者將這些頭文件存儲(chǔ)到一個(gè)專(zhuān)門(mén)的目錄include/net中, 而不是存儲(chǔ)到標(biāo)準(zhǔn)位置include/linux. 網(wǎng)絡(luò)相關(guān)的代碼中包含了許多概念, 這些形成了網(wǎng)絡(luò)子系統(tǒng)的邏輯支柱, 我們?cè)诒菊轮凶罡信d趣的就是這些概念. 我們的討論主要限于TCP/IP實(shí)現(xiàn), 因?yàn)樗悄壳笆褂米顝V泛的網(wǎng)絡(luò)協(xié)議.
當(dāng)然, 網(wǎng)絡(luò)子系統(tǒng)的開(kāi)發(fā), 并不是從頭開(kāi)始的. 在計(jì)算機(jī)之間交換數(shù)據(jù)的標(biāo)準(zhǔn)和慣例都已經(jīng)存在數(shù)十年之久, 這些都為大家所熟知且沿用已久. Linux也實(shí)現(xiàn)了這些標(biāo)準(zhǔn), 以連接到其他計(jì)算機(jī).
1.2 網(wǎng)絡(luò)實(shí)現(xiàn)的分層模型
內(nèi)核網(wǎng)絡(luò)子系統(tǒng)的實(shí)現(xiàn)與本章開(kāi)頭介紹的TCP/IP參考模型非常相似
相關(guān)的C語(yǔ)言代碼劃分為不同層次,各層次都有明確定義的任務(wù),各個(gè)層次只能通過(guò)明確定義的接口與上下緊鄰的層次通信。這種做法的好處在于,可以組合使用各種設(shè)備、傳輸機(jī)制和協(xié)議。例如,通常的以太網(wǎng)卡不僅可用于建立因特網(wǎng)(IP)連接,還可以在其上傳輸其他類(lèi)型的協(xié)議,如Appletalk或IPX,而無(wú)須對(duì)網(wǎng)卡的設(shè)備驅(qū)動(dòng)程序做任何類(lèi)型的修改。
圖12-3說(shuō)明了內(nèi)核對(duì)這個(gè)分層模型的實(shí)現(xiàn)

網(wǎng)絡(luò)子系統(tǒng)是內(nèi)核中涉及面最廣、要求最高的部分之一。為什么是這樣呢?答案是,該子系統(tǒng)處理了大量特定于協(xié)議的細(xì)節(jié)和微妙之處,穿越各層的代碼路徑中有大量的函數(shù)指針,而沒(méi)有直接的函數(shù)調(diào)用。這是不可避免的,因?yàn)楦鱾€(gè)層次有多種組合方式,這顯然不會(huì)使代碼路徑變得更清楚或更易于跟蹤。此外,其中涉及的數(shù)據(jù)結(jié)構(gòu)通常彼此緊密關(guān)聯(lián)。為降低描述上復(fù)雜性,下文的內(nèi)容主要講述 因特網(wǎng)協(xié)議。
分層模型不僅反映在網(wǎng)絡(luò)子系統(tǒng)的設(shè)計(jì)上,而且也反映在數(shù)據(jù)傳輸?shù)姆绞缴希ɑ蚋_地說(shuō),對(duì)各層產(chǎn)生和傳輸?shù)臄?shù)據(jù)進(jìn)行封裝的方式)。通常,各層的數(shù)據(jù)都由首部和數(shù)據(jù)兩部分組成, 如圖12-4所示。

首部部分包含了與數(shù)據(jù)部分有關(guān)的元數(shù)據(jù)(目標(biāo)地址、長(zhǎng)度、傳輸協(xié)議類(lèi)型等),數(shù)據(jù)部分包含有用數(shù)據(jù)(或凈荷)。
傳輸?shù)幕締挝皇牵ㄒ蕴W(wǎng))幀,網(wǎng)卡以幀為單位發(fā)送數(shù)據(jù)。幀首部部分的主數(shù)據(jù)項(xiàng)是目標(biāo)系統(tǒng)的硬件地址,這是數(shù)據(jù)傳輸?shù)哪康牡?,通過(guò)電纜傳輸數(shù)據(jù)時(shí)也需要該數(shù)據(jù)項(xiàng)。
高層協(xié)議的數(shù)據(jù)在封裝到以太網(wǎng)幀時(shí),將協(xié)議產(chǎn)生的首部和數(shù)據(jù)二元組封裝到幀的數(shù)據(jù)部分。在因特網(wǎng)網(wǎng)絡(luò)上,這是互聯(lián)網(wǎng)絡(luò)層數(shù)據(jù)。
因?yàn)橥ㄟ^(guò)以太網(wǎng)不僅可以傳輸IP分組,還可以傳輸其他協(xié)議的分組,如Appletalk或IPX分組,接收系統(tǒng)必須能夠區(qū)分不同的協(xié)議類(lèi)型,以便將數(shù)據(jù)轉(zhuǎn)發(fā)到正確的例程進(jìn)一步處理。分析數(shù)據(jù)并查明使用的傳輸協(xié)議是非常耗時(shí)的。因此,以太網(wǎng)幀的首部(和所有其他現(xiàn)代網(wǎng)絡(luò)協(xié)議的首部部分)包含了一個(gè)標(biāo)識(shí)符,唯一地標(biāo)識(shí)了幀數(shù)據(jù)部分中的協(xié)議類(lèi)型。這些標(biāo)識(shí)符(用于以太網(wǎng)傳輸)由一個(gè)國(guó)際組織(IEEE)分配。
協(xié)議棧中的所有協(xié)議都有這種劃分。為此,傳輸?shù)拿總€(gè)幀開(kāi)始都是一系列協(xié)議首部,而后才是應(yīng)用層的數(shù)據(jù),如圖12-5所示

圖12-5清楚地說(shuō)明了為容納控制信息所犧牲的部分帶寬.
【文章福利】小編推薦自己的Linux內(nèi)核技術(shù)交流群:【891587639】整理了一些個(gè)人覺(jué)得比較好的學(xué)習(xí)書(shū)籍、視頻資料共享在群文件里面,有需要的可以自行添加哦!??!前100名進(jìn)群領(lǐng)取,額外贈(zèng)送一份價(jià)值699的內(nèi)核資料包(含視頻教程、電子書(shū)、實(shí)戰(zhàn)項(xiàng)目及代碼)?


pid的命名空間, 我們知道內(nèi)核的許多部分包含在命名空間中. 這可以建立系統(tǒng)的多個(gè)虛擬視圖, 并彼此分隔開(kāi)來(lái). 每個(gè)實(shí)例看起來(lái)像是一臺(tái)運(yùn)行Linux的獨(dú)立機(jī)器,但在一臺(tái)物理機(jī)器上,可以同時(shí)運(yùn)行許多這樣的實(shí)例。在內(nèi)核版本2.6.24開(kāi)發(fā)期間,內(nèi)核也開(kāi)始對(duì)網(wǎng)絡(luò)子系統(tǒng)采用命名空間. 這對(duì)該子系統(tǒng)增加了一些額外的復(fù)雜性,因?yàn)樵撟酉到y(tǒng)的所有屬性在此前的版本中都是"全局"的,而現(xiàn)在需要按命名空間來(lái)管理, 例如, 可用網(wǎng)卡的數(shù)量. 對(duì)特定的網(wǎng)絡(luò)設(shè)備來(lái)說(shuō),如果它在一個(gè)命名空間中可見(jiàn),在另一個(gè)命名空間中就不一定是可見(jiàn)的.
2.1 網(wǎng)絡(luò)命令空間net
照例需要一個(gè)中樞結(jié)構(gòu)來(lái)跟蹤所有可用的命名空間, 即struct net, 其定義如下:
使網(wǎng)絡(luò)子系統(tǒng)完全感知命名空間的工作才剛剛開(kāi)始。讀者現(xiàn)在看到的情況,即內(nèi)核版本2.6.24中的情況,仍然處于開(kāi)發(fā)的早期階段。因此,隨著網(wǎng)絡(luò)子系統(tǒng)中越來(lái)越多的組件從全局管理轉(zhuǎn)換為可感知命名空間的實(shí)現(xiàn),struct net 的長(zhǎng)度在未來(lái)會(huì)不斷增長(zhǎng)?,F(xiàn)在,基本的基礎(chǔ)設(shè)施已經(jīng)轉(zhuǎn)換完畢。
對(duì)網(wǎng)絡(luò)設(shè)備的跟蹤已經(jīng)考慮到命名空間的效應(yīng),對(duì)最重要的一些協(xié)議的命名空間支持也是可用的。由于本書(shū)中尚未討論網(wǎng)絡(luò)實(shí)現(xiàn)的任何具體內(nèi)容,struct net 中引用的結(jié)構(gòu)當(dāng)然還是未知的(但在本章行文過(guò)程中,這一點(diǎn)會(huì)逐漸改變)?,F(xiàn)在,只需要簡(jiǎn)要地概述一下,哪些概念是以可感知命名空間的方式進(jìn)行處理的即可.
count是一個(gè)標(biāo)準(zhǔn)的使用計(jì)數(shù)器,在使用特定的net實(shí)例前后,需要分別調(diào)用輔助函數(shù)get_net和put_net. 在count降低到0時(shí),將釋放該命名空間,并將其從系統(tǒng)中刪除.
所有可用的命名空間都保存在一個(gè)雙鏈表上,表頭是net_namespace_list。list用作鏈表元素. copy_net_ns函數(shù)向該鏈表添加一個(gè)新的命名空間。在用create_new_namespace創(chuàng)建一組新的命名空間時(shí),會(huì)自動(dòng)調(diào)用該函數(shù)。
由于每個(gè)命名空間都包含不同的網(wǎng)絡(luò)設(shè)備,這必然會(huì)反映到procfs的內(nèi)容上(參見(jiàn)10.1節(jié))。各命名空間的處理需要三個(gè)數(shù)據(jù)項(xiàng):/proc/net由proc_net表示,而/proc/net/stats由proc_net_stats表示,proc_net_root指向當(dāng)前命名空間的procfs實(shí)例的根結(jié)點(diǎn),即/proc
每個(gè)命名空間都可以有一個(gè)不同的環(huán)回設(shè)備,而loopback_dev指向履行該職責(zé)的(虛擬)網(wǎng)絡(luò)設(shè)備.
網(wǎng)絡(luò)設(shè)備由struct net_device表示。與特定命名空間關(guān)聯(lián)的所有設(shè)備都保存在一個(gè)雙鏈表上,表頭為dev_base_head。各個(gè)設(shè)備還通過(guò)另外兩個(gè)雙鏈表維護(hù):一個(gè)將設(shè)備名用作散列鍵(dev_name_head),另一個(gè)將接口索引用作散列鍵(dev_index_head)。
請(qǐng)注意,術(shù)語(yǔ)“設(shè)備”和“接口”有細(xì)微的差別。設(shè)備表示提供物理傳輸能力的硬件設(shè)備,而接口可以是純虛擬的實(shí)體,可能在真正的設(shè)備上實(shí)現(xiàn)。例如,一個(gè)網(wǎng)卡可以提供兩個(gè)接口。對(duì)我們來(lái)說(shuō),兩個(gè)術(shù)語(yǔ)的區(qū)別不那么重要,在下文中將交替使用這兩個(gè)術(shù)語(yǔ)。網(wǎng)絡(luò)子系統(tǒng)的許多組件仍然需要做很多工作才能正確處理命名空間,要使網(wǎng)絡(luò)子系統(tǒng)能夠完全感知命名空間,還有相當(dāng)長(zhǎng)的路要走。例如,內(nèi)核版本2.6.25(在撰寫(xiě)本章時(shí),仍處于開(kāi)發(fā)中)將開(kāi)始一些最初的準(zhǔn)備工作,以便使特定的協(xié)議能夠感知到命名空間:
ipv4用于存儲(chǔ)協(xié)議參數(shù)(此前是全局的), 為此引入了特定于協(xié)議的結(jié)構(gòu). 這個(gè)方 法是逐步進(jìn)行的:首先設(shè)置好基本框架,后續(xù)的各個(gè)步驟,將全局屬性遷移到各命名空間的表示,這些結(jié)構(gòu)最初都是空的。在未來(lái)的內(nèi)核版本中,還將引入更多此類(lèi)代碼
linux系統(tǒng)包括默認(rèn)的命名空間 : "init_net"和用戶(hù)自定義的net
我們通常說(shuō)的namespace 一般是默認(rèn)的命名空間 : "init_net", 也就是所有的"網(wǎng)絡(luò)通信協(xié)議"+"網(wǎng)絡(luò)設(shè)備"都是屬于默認(rèn)的命名空間.
大多數(shù)計(jì)算機(jī)通常都只需要一個(gè)網(wǎng)絡(luò)命名空間. 即只有默認(rèn)命名空間init_net(該變量實(shí)際上是全局的,并未包含在另一個(gè)命名空間中,其定義如下:
init_net會(huì)被鏈接到net_namespace_list這個(gè)雙向鏈表上, 定義如下所示:
net_namespace_list就包含了所有的網(wǎng)絡(luò)命令空間, 其以init_net為表頭
2.2 初始化 & 清理元組 pernet_operations(創(chuàng)建命名空間)
初始化 & 清理元組pernet_operations
每個(gè)網(wǎng)絡(luò)命名空間由幾個(gè)部分組成, 例如, 在procfs中的表示. 每當(dāng)創(chuàng)建一個(gè)新的網(wǎng)絡(luò)命名空間時(shí), 必須初始化這些部分. 在刪除命名空間時(shí), 也同樣需要一些清理工作. 內(nèi)核采用下列結(jié)構(gòu)來(lái)跟蹤所有必需的初始化/清理元組.
這個(gè)結(jié)構(gòu)沒(méi)什么特別之處 :

內(nèi)核pernet_operations結(jié)構(gòu)將被鏈接到pernet_list這個(gè)雙向鏈表上, 定義:
輔助函數(shù)register_pernet_subsys和unregister_pernet_subsys分別向該鏈表添加和刪除數(shù)據(jù)元素. 每當(dāng)創(chuàng)建一個(gè)新的網(wǎng)絡(luò)命名空間時(shí), 內(nèi)核將遍歷pernet_operations的鏈表, 用表示新命名空間的net實(shí)例作為參數(shù)來(lái)調(diào)用初始化函數(shù)。在刪除網(wǎng)絡(luò)命名空間時(shí),清理工作的處理是類(lèi)似的
網(wǎng)絡(luò)命令空間的創(chuàng)建
每個(gè)network namespace包換許多元件, 所以當(dāng)一個(gè)新的network namespace被創(chuàng)建, 這些元件必須被初始化. 同樣, 當(dāng)它被刪除時(shí),需要做必要的清理工作.
Kernel引入了如下結(jié)構(gòu)pernet_operations來(lái)維護(hù)所有需要做的 initialization/cleanup工作
當(dāng)一個(gè)新的network namespace被創(chuàng)建, kernel遍歷pernet_operations 的list, 即遍歷pernet_list, 并調(diào)用其init函數(shù).
在linux內(nèi)核中默認(rèn)情況下, 會(huì)有一個(gè)"默認(rèn)的網(wǎng)絡(luò)命名空間", 其名為init_net, 并也將其導(dǎo)出, 作為全局變量.
kernel2.4、2.6:通過(guò)copy_net_ns和net_create函數(shù)向內(nèi)核中添加一個(gè)網(wǎng)絡(luò)命名空間, 其中copy_net_ns函數(shù)
kernel 3.10之后刪除了 net_create 函數(shù), 而通過(guò)copy_net_ns函數(shù)添加一個(gè)網(wǎng)絡(luò)命名空間。
釋放一個(gè)網(wǎng)絡(luò)命名空間
內(nèi)核可以通過(guò)net_free和net_drop_ns函數(shù)來(lái)釋放掉指定的網(wǎng)絡(luò)命名空間.
定義:
static void net_free(struct net *net) { ? ?kfree(rcu_access_pointer(net->gen)); ? ?kmem_cache_free(net_cachep, net); } void net_drop_ns(void *p) { ? ?struct net *ns = p; ? ?if (ns && atomic_dec_and_test(&ns->passive)) ? ? ? ?net_free(ns); }
2.3 總結(jié)
記住下列事實(shí)就足夠了
網(wǎng)絡(luò)子系統(tǒng)實(shí)現(xiàn)的所有全局函數(shù),都需要一個(gè)網(wǎng)絡(luò)命名空間作為參數(shù),而網(wǎng)絡(luò)子系統(tǒng)的所有全局屬性,只能通過(guò)所述命名空間迂回訪(fǎng)問(wèn).
linux系統(tǒng)包括默認(rèn)的命名空間 : init_net和用戶(hù)自定義的netnamespace一般是默認(rèn)的命名空間:init_net, 也就是所有的"網(wǎng)絡(luò)通信協(xié)議"+"網(wǎng)絡(luò)設(shè)備"都是屬于默認(rèn)的命名空間.
網(wǎng)絡(luò)命名空間定義了2個(gè)鏈表, pernet_list和net_namespace_listinit_net會(huì)被鏈接到net_namespace_list這個(gè)雙向鏈表上 pernet_operations結(jié)構(gòu)將被鏈接到first_device = pernet_list這個(gè)雙向鏈表上
如果沒(méi)自定義網(wǎng)絡(luò)命名空間的話(huà),所有想用網(wǎng)絡(luò)命名空間時(shí)都將利用默認(rèn)的init_net
3、網(wǎng)絡(luò)命令空間設(shè)備
命名空間設(shè)備指的是那些?
就是網(wǎng)絡(luò)設(shè)備. 通過(guò)register_pernet_device注冊(cè):就是"注冊(cè)一個(gè)網(wǎng)絡(luò)設(shè)備"到"所有的網(wǎng)絡(luò)命名空間net", 網(wǎng)絡(luò)設(shè)備包括兩類(lèi):虛擬的網(wǎng)絡(luò)設(shè)備和物理網(wǎng)絡(luò)設(shè)備 :
3.1 虛擬網(wǎng)絡(luò)設(shè)備
虛擬網(wǎng)絡(luò)設(shè)備的協(xié)議根據(jù)自身設(shè)計(jì)特點(diǎn)對(duì)skb數(shù)據(jù)進(jìn)行處理, 并通過(guò)全局變量xx_net_id和各個(gè)協(xié)議私有的特殊數(shù)據(jù)結(jié)構(gòu)xx_net, 尋找到該數(shù)據(jù)包對(duì)應(yīng)的應(yīng)用層socket插口, 并將其放在該socket插口的接收隊(duì)列中; 最后應(yīng)用層在某個(gè)時(shí)刻會(huì)通過(guò)read系統(tǒng)調(diào)用讀取該數(shù)據(jù)

3.2 物理網(wǎng)絡(luò)設(shè)備
比如網(wǎng)卡驅(qū)動(dòng)、無(wú)線(xiàn)網(wǎng)卡驅(qū)動(dòng)
3.3 namespace與socket, 網(wǎng)絡(luò)設(shè)備的關(guān)系
上述的socket索引方法有個(gè)繞彎的地方:就是每個(gè)協(xié)議私有的xx_net結(jié)構(gòu)可以直接由協(xié)議模塊本身分配,索引起來(lái)也方便,不要用到全局的net_generic。而目前內(nèi)核所用的方法,其實(shí)是為了另外的目的,那就是命名空間namespace。也就是虛擬多用戶(hù)的一套機(jī)制,具體的也沒(méi)細(xì)看,好像目前內(nèi)核整個(gè)namespace還沒(méi)有全部完成。
network的命名空間問(wèn)題主要在于,每個(gè)協(xié)議模塊的xx_net私有結(jié)構(gòu)不僅是一個(gè),而是由內(nèi)核全局決定的,即每注冊(cè)一個(gè)新的用戶(hù)(有點(diǎn)像虛擬機(jī)機(jī)制),就分配一個(gè)新的xx_net結(jié)構(gòu),這樣多用戶(hù)間可以用參數(shù)相同的socket連接,但卻指向不同的socket, 可以看到socket的操作,都會(huì)有個(gè)net參數(shù),就是為了這個(gè)作用,主要實(shí)現(xiàn)函數(shù)在namespace.c中
在Linux協(xié)議棧中引入網(wǎng)絡(luò)命名空間,是為了支持網(wǎng)絡(luò)協(xié)議棧的多個(gè)實(shí)例,而這些協(xié)議棧的隔離就是由命名空間來(lái)實(shí)現(xiàn)的(有點(diǎn)像進(jìn)程的線(xiàn)性地址空間,協(xié)議棧不能訪(fǎng)問(wèn)其他協(xié)議棧的私有數(shù)據(jù))。需要納入命名空間的元素包括進(jìn)程,套接字,網(wǎng)絡(luò)設(shè)備。進(jìn)程創(chuàng)建的套接字必須屬于某個(gè)命名空間,套接字的操作也必須在命名空間內(nèi)進(jìn)行,網(wǎng)絡(luò)設(shè)備也必須屬于某個(gè)命名空間,但可能會(huì)改變,因?yàn)榫W(wǎng)絡(luò)設(shè)備屬于公共資源<~/include/net.h>
在內(nèi)核中引入命名空間工作量非常大. 為了保持與向后兼容,網(wǎng)絡(luò)系統(tǒng)在初始化的時(shí)候只初始化了一個(gè)命名空間,即init_net命名空間。所有的命名空間通過(guò)list項(xiàng)組織起來(lái)。每個(gè)網(wǎng)絡(luò)設(shè)備都對(duì)應(yīng)有一個(gè)命名空間。命名空間下的所有網(wǎng)絡(luò)設(shè)備通過(guò)dev_base_head組織在一起
