国产精品天干天干,亚洲毛片在线,日韩gay小鲜肉啪啪18禁,女同Gay自慰喷水

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

一文讀懂Linux網(wǎng)絡(luò)命名空間

2022-04-27 20:08 作者:補給站Linux內(nèi)核  | 我要投稿

1.1 Linux網(wǎng)絡(luò)

  • Linux 是因特網(wǎng)的產(chǎn)物, 這是無可爭議的. 首先, 得感謝因特網(wǎng)通信, Linux的開發(fā)過程證明了一個很多人曾持有的觀點是荒謬的 : 對分散在世界各地的一組程序員進行項目管理是不可能的. 第一個內(nèi)核源代碼版本是在十多年前通過FTP服務(wù)器提供的, 此后網(wǎng)絡(luò)便成了數(shù)據(jù)交換的支柱, 無論是概念和代碼的開發(fā), 還是內(nèi)核錯誤的消除, 都是如此.

  • 內(nèi)核郵件列表是個活生生的例子, 它幾乎沒有改變過. 每個人都能夠看到最新貢獻的代碼, 并為促進Linux的開發(fā)提出自己的意見, 當然, 得假定所表達的意見是合理的. Linux對各種網(wǎng)絡(luò)適應(yīng)得都很好, 這是可以理解的, 因為它是與因特網(wǎng)共同成長的.

  • 在構(gòu)成因特網(wǎng)的服務(wù)器中, 大部分是運行Linux的計算機. 不出所料, 網(wǎng)絡(luò)實現(xiàn)是Linux內(nèi)核中一個關(guān)鍵的部分, 正在獲得越來越多的關(guān)注. 實際上, Linux不支持的網(wǎng)絡(luò)方案很少.

  • 網(wǎng)絡(luò)功能的實現(xiàn)是內(nèi)核最復(fù)雜、牽涉最廣的一部分. 除了經(jīng)典的因特網(wǎng)協(xié)議(如TCP、UDP)和相關(guān)的IP傳輸機制之外, Linux還支持許多其他的互聯(lián)方案,使得所有想得到的計算機/操作系統(tǒng)能夠互操作.

  • Linux也支持大量用于數(shù)據(jù)傳輸?shù)挠布? 如以太網(wǎng)卡和令牌環(huán)網(wǎng)適配器及ISDN卡和調(diào)制解調(diào)器, 但這并沒有使內(nèi)核的工作變得簡單.

  • 盡管如此, Linux開發(fā)人員提出了一種結(jié)構(gòu)良好得令人驚訝的模型, 統(tǒng)一了各種不同的方法. 雖然本章是本書最長的章之一, 但并沒有涵蓋網(wǎng)絡(luò)實現(xiàn)的每個細節(jié). 即使概述一下所有的驅(qū)動程序和協(xié)議, 也超出了一本書的范圍, 由于信息量巨大, 實際上可能需要許多本書. 不算網(wǎng)卡驅(qū)動程序, 網(wǎng)絡(luò)子系統(tǒng)的C語言實現(xiàn)在內(nèi)核源代碼中就占了15MB, 如果將相應(yīng)的代碼打印到紙上要有6000多頁. 與網(wǎng)絡(luò)相關(guān)的頭文件的數(shù)目巨大, 使得內(nèi)核開發(fā)者將這些頭文件存儲到一個專門的目錄include/net中, 而不是存儲到標準位置include/linux. 網(wǎng)絡(luò)相關(guān)的代碼中包含了許多概念, 這些形成了網(wǎng)絡(luò)子系統(tǒng)的邏輯支柱, 我們在本章中最感興趣的就是這些概念. 我們的討論主要限于TCP/IP實現(xiàn), 因為它是目前使用最廣泛的網(wǎng)絡(luò)協(xié)議.

  • 當然, 網(wǎng)絡(luò)子系統(tǒng)的開發(fā), 并不是從頭開始的. 在計算機之間交換數(shù)據(jù)的標準和慣例都已經(jīng)存在數(shù)十年之久, 這些都為大家所熟知且沿用已久. Linux也實現(xiàn)了這些標準, 以連接到其他計算機.

1.2 網(wǎng)絡(luò)實現(xiàn)的分層模型

  • 內(nèi)核網(wǎng)絡(luò)子系統(tǒng)的實現(xiàn)與本章開頭介紹的TCP/IP參考模型非常相似

  • 相關(guān)的C語言代碼劃分為不同層次,各層次都有明確定義的任務(wù),各個層次只能通過明確定義的接口與上下緊鄰的層次通信。這種做法的好處在于,可以組合使用各種設(shè)備、傳輸機制和協(xié)議。例如,通常的以太網(wǎng)卡不僅可用于建立因特網(wǎng)(IP)連接,還可以在其上傳輸其他類型的協(xié)議,如Appletalk或IPX,而無須對網(wǎng)卡的設(shè)備驅(qū)動程序做任何類型的修改。

  • 圖12-3說明了內(nèi)核對這個分層模型的實現(xiàn)


  • 網(wǎng)絡(luò)子系統(tǒng)是內(nèi)核中涉及面最廣、要求最高的部分之一。為什么是這樣呢?答案是,該子系統(tǒng)處理了大量特定于協(xié)議的細節(jié)和微妙之處,穿越各層的代碼路徑中有大量的函數(shù)指針,而沒有直接的函數(shù)調(diào)用。這是不可避免的,因為各個層次有多種組合方式,這顯然不會使代碼路徑變得更清楚或更易于跟蹤。此外,其中涉及的數(shù)據(jù)結(jié)構(gòu)通常彼此緊密關(guān)聯(lián)。為降低描述上復(fù)雜性,下文的內(nèi)容主要講述 因特網(wǎng)協(xié)議。

  • 分層模型不僅反映在網(wǎng)絡(luò)子系統(tǒng)的設(shè)計上,而且也反映在數(shù)據(jù)傳輸?shù)姆绞缴希ɑ蚋_地說,對各層產(chǎn)生和傳輸?shù)臄?shù)據(jù)進行封裝的方式)。通常,各層的數(shù)據(jù)都由首部和數(shù)據(jù)兩部分組成, 如圖12-4所示。



  • 首部部分包含了與數(shù)據(jù)部分有關(guān)的元數(shù)據(jù)(目標地址、長度、傳輸協(xié)議類型等),數(shù)據(jù)部分包含有用數(shù)據(jù)(或凈荷)。

  • 傳輸?shù)幕締挝皇牵ㄒ蕴W(wǎng))幀,網(wǎng)卡以幀為單位發(fā)送數(shù)據(jù)。幀首部部分的主數(shù)據(jù)項是目標系統(tǒng)的硬件地址,這是數(shù)據(jù)傳輸?shù)哪康牡?,通過電纜傳輸數(shù)據(jù)時也需要該數(shù)據(jù)項。

  • 高層協(xié)議的數(shù)據(jù)在封裝到以太網(wǎng)幀時,將協(xié)議產(chǎn)生的首部和數(shù)據(jù)二元組封裝到幀的數(shù)據(jù)部分。在因特網(wǎng)網(wǎng)絡(luò)上,這是互聯(lián)網(wǎng)絡(luò)層數(shù)據(jù)。

  • 因為通過以太網(wǎng)不僅可以傳輸IP分組,還可以傳輸其他協(xié)議的分組,如Appletalk或IPX分組,接收系統(tǒng)必須能夠區(qū)分不同的協(xié)議類型,以便將數(shù)據(jù)轉(zhuǎn)發(fā)到正確的例程進一步處理。分析數(shù)據(jù)并查明使用的傳輸協(xié)議是非常耗時的。因此,以太網(wǎng)幀的首部(和所有其他現(xiàn)代網(wǎng)絡(luò)協(xié)議的首部部分)包含了一個標識符,唯一地標識了幀數(shù)據(jù)部分中的協(xié)議類型。這些標識符(用于以太網(wǎng)傳輸)由一個國際組織(IEEE)分配。

  • 協(xié)議棧中的所有協(xié)議都有這種劃分。為此,傳輸?shù)拿總€幀開始都是一系列協(xié)議首部,而后才是應(yīng)用層的數(shù)據(jù),如圖12-5所示

  • 圖12-5清楚地說明了為容納控制信息所犧牲的部分帶寬.

【文章福利】小編推薦自己的Linux內(nèi)核技術(shù)交流群:【891587639】整理了一些個人覺得比較好的學習書籍、視頻資料共享在群文件里面,有需要的可以自行添加哦!??!前100名進群領(lǐng)取,額外贈送一份價值699的內(nèi)核資料包(含視頻教程、電子書、實戰(zhàn)項目及代碼)?



  • pid的命名空間, 我們知道內(nèi)核的許多部分包含在命名空間中. 這可以建立系統(tǒng)的多個虛擬視圖, 并彼此分隔開來. 每個實例看起來像是一臺運行Linux的獨立機器,但在一臺物理機器上,可以同時運行許多這樣的實例。在內(nèi)核版本2.6.24開發(fā)期間,內(nèi)核也開始對網(wǎng)絡(luò)子系統(tǒng)采用命名空間. 這對該子系統(tǒng)增加了一些額外的復(fù)雜性,因為該子系統(tǒng)的所有屬性在此前的版本中都是"全局"的,而現(xiàn)在需要按命名空間來管理, 例如, 可用網(wǎng)卡的數(shù)量. 對特定的網(wǎng)絡(luò)設(shè)備來說,如果它在一個命名空間中可見,在另一個命名空間中就不一定是可見的.

2.1 網(wǎng)絡(luò)命令空間net

  • 照例需要一個中樞結(jié)構(gòu)來跟蹤所有可用的命名空間, 即struct net, 其定義如下:

  • 使網(wǎng)絡(luò)子系統(tǒng)完全感知命名空間的工作才剛剛開始。讀者現(xiàn)在看到的情況,即內(nèi)核版本2.6.24中的情況,仍然處于開發(fā)的早期階段。因此,隨著網(wǎng)絡(luò)子系統(tǒng)中越來越多的組件從全局管理轉(zhuǎn)換為可感知命名空間的實現(xiàn),struct net 的長度在未來會不斷增長?,F(xiàn)在,基本的基礎(chǔ)設(shè)施已經(jīng)轉(zhuǎn)換完畢。

  • 對網(wǎng)絡(luò)設(shè)備的跟蹤已經(jīng)考慮到命名空間的效應(yīng),對最重要的一些協(xié)議的命名空間支持也是可用的。由于本書中尚未討論網(wǎng)絡(luò)實現(xiàn)的任何具體內(nèi)容,struct net 中引用的結(jié)構(gòu)當然還是未知的(但在本章行文過程中,這一點會逐漸改變)?,F(xiàn)在,只需要簡要地概述一下,哪些概念是以可感知命名空間的方式進行處理的即可.

  1. count是一個標準的使用計數(shù)器,在使用特定的net實例前后,需要分別調(diào)用輔助函數(shù)get_net和put_net. 在count降低到0時,將釋放該命名空間,并將其從系統(tǒng)中刪除.

  2. 所有可用的命名空間都保存在一個雙鏈表上,表頭是net_namespace_list。list用作鏈表元素. copy_net_ns函數(shù)向該鏈表添加一個新的命名空間。在用create_new_namespace創(chuàng)建一組新的命名空間時,會自動調(diào)用該函數(shù)。

  3. 由于每個命名空間都包含不同的網(wǎng)絡(luò)設(shè)備,這必然會反映到procfs的內(nèi)容上(參見10.1節(jié))。各命名空間的處理需要三個數(shù)據(jù)項:/proc/net由proc_net表示,而/proc/net/stats由proc_net_stats表示,proc_net_root指向當前命名空間的procfs實例的根結(jié)點,即/proc

  4. 每個命名空間都可以有一個不同的環(huán)回設(shè)備,而loopback_dev指向履行該職責的(虛擬)網(wǎng)絡(luò)設(shè)備.

  5. 網(wǎng)絡(luò)設(shè)備由struct net_device表示。與特定命名空間關(guān)聯(lián)的所有設(shè)備都保存在一個雙鏈表上,表頭為dev_base_head。各個設(shè)備還通過另外兩個雙鏈表維護:一個將設(shè)備名用作散列鍵(dev_name_head),另一個將接口索引用作散列鍵(dev_index_head)。

  • 請注意,術(shù)語“設(shè)備”和“接口”有細微的差別。設(shè)備表示提供物理傳輸能力的硬件設(shè)備,而接口可以是純虛擬的實體,可能在真正的設(shè)備上實現(xiàn)。例如,一個網(wǎng)卡可以提供兩個接口。對我們來說,兩個術(shù)語的區(qū)別不那么重要,在下文中將交替使用這兩個術(shù)語。網(wǎng)絡(luò)子系統(tǒng)的許多組件仍然需要做很多工作才能正確處理命名空間,要使網(wǎng)絡(luò)子系統(tǒng)能夠完全感知命名空間,還有相當長的路要走。例如,內(nèi)核版本2.6.25(在撰寫本章時,仍處于開發(fā)中)將開始一些最初的準備工作,以便使特定的協(xié)議能夠感知到命名空間:

  • ipv4用于存儲協(xié)議參數(shù)(此前是全局的), 為此引入了特定于協(xié)議的結(jié)構(gòu). 這個方 法是逐步進行的:首先設(shè)置好基本框架,后續(xù)的各個步驟,將全局屬性遷移到各命名空間的表示,這些結(jié)構(gòu)最初都是空的。在未來的內(nèi)核版本中,還將引入更多此類代碼

  • linux系統(tǒng)包括默認的命名空間 : "init_net"和用戶自定義的net

  • 我們通常說的namespace 一般是默認的命名空間 : "init_net", 也就是所有的"網(wǎng)絡(luò)通信協(xié)議"+"網(wǎng)絡(luò)設(shè)備"都是屬于默認的命名空間.

  • 大多數(shù)計算機通常都只需要一個網(wǎng)絡(luò)命名空間. 即只有默認命名空間init_net(該變量實際上是全局的,并未包含在另一個命名空間中,其定義如下:

  • init_net會被鏈接到net_namespace_list這個雙向鏈表上, 定義如下所示:

  • net_namespace_list就包含了所有的網(wǎng)絡(luò)命令空間, 其以init_net為表頭

2.2 初始化 & 清理元組 pernet_operations(創(chuàng)建命名空間)

初始化 & 清理元組pernet_operations

  • 每個網(wǎng)絡(luò)命名空間由幾個部分組成, 例如, 在procfs中的表示. 每當創(chuàng)建一個新的網(wǎng)絡(luò)命名空間時, 必須初始化這些部分. 在刪除命名空間時, 也同樣需要一些清理工作. 內(nèi)核采用下列結(jié)構(gòu)來跟蹤所有必需的初始化/清理元組.

  • 這個結(jié)構(gòu)沒什么特別之處 :

  • 內(nèi)核pernet_operations結(jié)構(gòu)將被鏈接到pernet_list這個雙向鏈表上, 定義:

  • 輔助函數(shù)register_pernet_subsys和unregister_pernet_subsys分別向該鏈表添加和刪除數(shù)據(jù)元素. 每當創(chuàng)建一個新的網(wǎng)絡(luò)命名空間時, 內(nèi)核將遍歷pernet_operations的鏈表, 用表示新命名空間的net實例作為參數(shù)來調(diào)用初始化函數(shù)。在刪除網(wǎng)絡(luò)命名空間時,清理工作的處理是類似的

網(wǎng)絡(luò)命令空間的創(chuàng)建

  • 每個network namespace包換許多元件, 所以當一個新的network namespace被創(chuàng)建, 這些元件必須被初始化. 同樣, 當它被刪除時,需要做必要的清理工作.

  • Kernel引入了如下結(jié)構(gòu)pernet_operations來維護所有需要做的 initialization/cleanup工作

  • 當一個新的network namespace被創(chuàng)建, kernel遍歷pernet_operations 的list, 即遍歷pernet_list, 并調(diào)用其init函數(shù).

  • 在linux內(nèi)核中默認情況下, 會有一個"默認的網(wǎng)絡(luò)命名空間", 其名為init_net, 并也將其導(dǎo)出, 作為全局變量.

  • kernel2.4、2.6:通過copy_net_ns和net_create函數(shù)向內(nèi)核中添加一個網(wǎng)絡(luò)命名空間, 其中copy_net_ns函數(shù)

  • kernel 3.10之后刪除了 net_create 函數(shù), 而通過copy_net_ns函數(shù)添加一個網(wǎng)絡(luò)命名空間。

釋放一個網(wǎng)絡(luò)命名空間

  • 內(nèi)核可以通過net_free和net_drop_ns函數(shù)來釋放掉指定的網(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é)

  • 記住下列事實就足夠了

  1. 網(wǎng)絡(luò)子系統(tǒng)實現(xiàn)的所有全局函數(shù),都需要一個網(wǎng)絡(luò)命名空間作為參數(shù),而網(wǎng)絡(luò)子系統(tǒng)的所有全局屬性,只能通過所述命名空間迂回訪問.

  2. linux系統(tǒng)包括默認的命名空間 : init_net和用戶自定義的netnamespace一般是默認的命名空間:init_net, 也就是所有的"網(wǎng)絡(luò)通信協(xié)議"+"網(wǎng)絡(luò)設(shè)備"都是屬于默認的命名空間.

  3. 網(wǎng)絡(luò)命名空間定義了2個鏈表, pernet_list和net_namespace_listinit_net會被鏈接到net_namespace_list這個雙向鏈表上 pernet_operations結(jié)構(gòu)將被鏈接到first_device = pernet_list這個雙向鏈表上

  4. 如果沒自定義網(wǎng)絡(luò)命名空間的話,所有想用網(wǎng)絡(luò)命名空間時都將利用默認的init_net

3、網(wǎng)絡(luò)命令空間設(shè)備

命名空間設(shè)備指的是那些?

  • 就是網(wǎng)絡(luò)設(shè)備. 通過register_pernet_device注冊:就是"注冊一個網(wǎng)絡(luò)設(shè)備"到"所有的網(wǎng)絡(luò)命名空間net", 網(wǎng)絡(luò)設(shè)備包括兩類:虛擬的網(wǎng)絡(luò)設(shè)備和物理網(wǎng)絡(luò)設(shè)備 :

3.1 虛擬網(wǎng)絡(luò)設(shè)備

  • 虛擬網(wǎng)絡(luò)設(shè)備的協(xié)議根據(jù)自身設(shè)計特點對skb數(shù)據(jù)進行處理, 并通過全局變量xx_net_id和各個協(xié)議私有的特殊數(shù)據(jù)結(jié)構(gòu)xx_net, 尋找到該數(shù)據(jù)包對應(yīng)的應(yīng)用層socket插口, 并將其放在該socket插口的接收隊列中; 最后應(yīng)用層在某個時刻會通過read系統(tǒng)調(diào)用讀取該數(shù)據(jù)

3.2 物理網(wǎng)絡(luò)設(shè)備

  • 比如網(wǎng)卡驅(qū)動、無線網(wǎng)卡驅(qū)動

3.3 namespace與socket, 網(wǎng)絡(luò)設(shè)備的關(guān)系

  • 上述的socket索引方法有個繞彎的地方:就是每個協(xié)議私有的xx_net結(jié)構(gòu)可以直接由協(xié)議模塊本身分配,索引起來也方便,不要用到全局的net_generic。而目前內(nèi)核所用的方法,其實是為了另外的目的,那就是命名空間namespace。也就是虛擬多用戶的一套機制,具體的也沒細看,好像目前內(nèi)核整個namespace還沒有全部完成。

  • network的命名空間問題主要在于,每個協(xié)議模塊的xx_net私有結(jié)構(gòu)不僅是一個,而是由內(nèi)核全局決定的,即每注冊一個新的用戶(有點像虛擬機機制),就分配一個新的xx_net結(jié)構(gòu),這樣多用戶間可以用參數(shù)相同的socket連接,但卻指向不同的socket, 可以看到socket的操作,都會有個net參數(shù),就是為了這個作用,主要實現(xiàn)函數(shù)在namespace.c中

  • 在Linux協(xié)議棧中引入網(wǎng)絡(luò)命名空間,是為了支持網(wǎng)絡(luò)協(xié)議棧的多個實例,而這些協(xié)議棧的隔離就是由命名空間來實現(xiàn)的(有點像進程的線性地址空間,協(xié)議棧不能訪問其他協(xié)議棧的私有數(shù)據(jù))。需要納入命名空間的元素包括進程,套接字,網(wǎng)絡(luò)設(shè)備。進程創(chuàng)建的套接字必須屬于某個命名空間,套接字的操作也必須在命名空間內(nèi)進行,網(wǎng)絡(luò)設(shè)備也必須屬于某個命名空間,但可能會改變,因為網(wǎng)絡(luò)設(shè)備屬于公共資源<~/include/net.h>

  • 在內(nèi)核中引入命名空間工作量非常大. 為了保持與向后兼容,網(wǎng)絡(luò)系統(tǒng)在初始化的時候只初始化了一個命名空間,即init_net命名空間。所有的命名空間通過list項組織起來。每個網(wǎng)絡(luò)設(shè)備都對應(yīng)有一個命名空間。命名空間下的所有網(wǎng)絡(luò)設(shè)備通過dev_base_head組織在一起


一文讀懂Linux網(wǎng)絡(luò)命名空間的評論 (共 條)

分享到微博請遵守國家法律
淮安市| 黔西县| 南华县| 屏山县| 洪洞县| 龙江县| 通辽市| 灌云县| 张家口市| 许昌县| 华阴市| 个旧市| 盐山县| 辉南县| 榆林市| 芷江| 武乡县| 遂川县| 泌阳县| 平阴县| 招远市| 凤山市| 搜索| 邢台县| 延庆县| 凤翔县| 嘉兴市| 洪泽县| 来宾市| 文水县| 阳高县| 平顺县| 桃园市| 滦平县| 靖宇县| 海丰县| 阳西县| 五河县| 二连浩特市| 离岛区| 红原县|