2015年5月27日 星期三

[Linux 文章收集] Linux 上的基礎網絡設備詳解

Source From Here
Introduction
網絡虛擬化是 Cloud 中的一個重要部分。作為基礎知識,本文詳細講述Linux 抽像出來的各種網絡設備的原理、用法、數據流向。您通過此文,能夠知道如何使用Linux 的基礎網絡設備進行配置以達到特定的目的,分析出 Linux 可能的網絡故障原因。

Linux 抽象網絡設備簡介
和磁盤設備類似,Linux 用戶想要使用網絡功能,不能通過直接操作硬件完成,而需要直接或間接的操作一個Linux 為我們抽像出來的設備,既通用的Linux 網絡設備來完成。一個常見的情況是,系統裡裝有一個硬件網卡,Linux 會在系統里為其生成一個網絡設備實例,如eth0,用戶需要對eth0 發出命令以配置或使用它了。更多的硬件會帶來更多的設備實例,虛擬的硬件也會帶來更多的設備實例。隨著網絡技術,虛擬化技術的發展,更多的高級網絡設備被加入了到了Linux 中,使得情況變得更加複雜。在以下章節中,將一一分析在虛擬化技術中經常使用的幾種Linux 網絡設備抽像類型:Bridge、802.1.q VLAN device、VETH、TAP,詳細解釋如何用它們配合 Linux 中的 Route table、IP table 簡單的創建出本地虛擬網絡。

相關網絡設備工作原理

Bridge
Bridge(橋)是Linux 上用來做TCP/IP 二層協議交換的設備,與現實世界中的 網路交換器 (Network Switch) 功能相似。Bridge 設備實例可以和 Linux 上其他網絡設備實例連接,既 attach 一個從設備,類似於在現實世界中的交換機和一個用戶終端之間連接一根網線。當有數據到達時,Bridge 會根據報文中的MAC 信息進行廣播、轉發、丟棄處理:
A bridge is a piece of software used to unite two or more network segments. A bridge behaves like a virtual network switch, working transparently (the other machines do not need to know or care about its existence). Any real devices (e.g. eth0) and virtual devices (e.g. tap0) can be connected to it.



如圖所示,Bridge 的功能主要在內核裡實現。當一個從設備被 attach 到 Bridge 上時,相當於現實世界裡交換機的端口被插入了一根連有終端的網線。這時在內核程序裡,netdev_rx_handler_register() 被調用,一個用於接受數據的回調函數被註冊。以後每當這個從設備收到數據時都會調用這個函數可以把數據轉發到Bridge 上。當Bridge 接收到此數據時,br_handle_frame() 被調用,進行一個和現實世界中的交換機類似的處理過程:判斷包的類別(廣播/單點),查找內部 MAC 端口映射表,定位目標端口號,將數據轉發到目標端口或丟棄,自動更新內部 MAC 端口映射表以自我學習。

Bridge 和現實世界中的二層交換機有一個區別,圖中左側畫出了這種情況:數據被直接發到 Bridge 上,而不是從一個端口接受。這種情況可以看做 Bridge 自己有一個 MAC 可以主動發送報文,或者說 Bridge 自帶了一個隱藏端口和寄主Linux 系統自動連接,Linux 上的程序可以直接從這個端口向 Bridge 上的其他端口發數據。所以當一個Bridge 擁有一個網絡設備時,如 bridge0 加入了 eth0 時,實際上 bridge0 擁有兩個有效 MAC 地址,一個是 bridge0 的,一個是 eth0 的,他們之間可以通訊。由此帶來一個有意思的事情是,Bridge 可以設置IP 地址。通常來說IP 地址是三層協議的內容,不應該出現在二層設備 Bridge 上。但是 Linux 裡 Bridge 是通用網絡設備抽象的一種,只要是網絡設備就能夠設定 IP 地址。當一個 bridge0 擁有 IP 後,Linux 便可以通過路由表或者 IP 表規則在三層定位 bridge0,此時相當於 Linux 擁有了另外一個隱藏的虛擬網卡和Bridge 的隱藏端口相連,這個網卡就是名為 bridge0 的通用網絡設備,IP 可以看成是這個網卡的。當有符合此IP 的數據到達bridge0 時,內核協議棧認為收到了一包目標為本機的數據,此時應用程序可以通過 Socket 接收到它。一個更好的對比例子是現實世界中的帶路由的交換機設備,它也擁有一個隱藏的MAC 地址,供設備中的三層協議處理程序和管理程序使用。設備裡的三層協議處理程序,對應名為 bridge0 的通用網絡設備的三層協議處理程序,即寄主 Linux 系統內核協議棧程序。設備裡的管理程序,對應 bridge0 寄主 Linux 系統裡的應用程序。

Bridge 的實現當前有一個限制:當一個設備被 attach 到Bridge 上時,那個設備的 IP 會變的無效,Linux 不再使用那個 IP 在三層接受數據。舉例如下:如果eth0 本來的IP 是192.168.1.2,此時如果收到一個目標地址是192.168.1.2 的數據,Linux 的應用程序能通過 Socket 操作接受到它。而當 eth0 被 attach 到一個bridge0 時,儘管 eth0 的 IP 還在,但應用程序是無法接受到上述數據的。此時應該把IP 192.168.1.2 賦予 bridge0。

另外需要注意的是數據流的方向。對於一個被 attach 到 Bridge 上的設備來說,只有它收到數據時,此包數據才會被轉發到 Bridge 上,進而完成查表廣播等後續操作。當請求是發送類型時,數據是不會被轉發到 Bridge 上的,它會尋找下一個發送出口。用戶在配置網絡時經常忽略這一點從而造成網絡故障。

VLAN device for 802.1.q
VLAN 又稱虛擬網絡,是一個被廣泛使用的概念,有些應用程序把自己的內部網絡也稱為VLAN。此處主要說的是在物理世界中存在的,需要協議支持的VLAN。它的種類很多,按照協議原理一般分為:MACVLAN、802.1.q VLAN、802.1.qbg VLAN、802.1.qbh VLAN。其中出現較早,應用廣泛並且比較成熟的是802.1.q VLAN,其基本原理是在二層協議裡插入額外的VLAN 協議數據(稱為802.1.q VLAN Tag),同時保持和傳統二層設備的兼容性。Linux 裡的VLAN 設備是對802.1.q 協議的一種內部軟件實現,模擬現實世界中的 802.1.q 交換機。


如圖所示,Linux 裡802.1.q VLAN 設備是以母子關係成對出現的,母設備相當於現實世界中的交換機TRUNK 口,用於連接上級網絡,子設備相當於普通接口用於連接下級網絡。當數據在母子設備間傳遞時,內核將會根據802.1.q VLAN Tag 進行對應操作。母子設備之間是一對多的關係,一個母設備可以有多個子設備,一個子設備只有一個母設備。當一個子設備有一包數據需要發送時,數據將被加入VLAN Tag 然後從母設備發送出去。當母設備收到一包數據時,它將會分析其中的VLAN Tag,如果有對應的子設備存在,則把數據轉發到那個子設備上並根據設置移除VLAN Tag,否則丟棄該數據。在某些設置下,VLAN Tag 可以不被移除以滿足某些監聽程序的需要,如DHCP 服務程序。舉例說明如下:eth0 作為母設備創建一個ID 為100 的子設備eth0.100。此時如果有程序要求從eth0.100 發送一包數據,數據將被打上VLAN 100 的Tag 從eth0 發送出去。如果eth0 收到一包數據,VLAN Tag 是100,數據將被轉發到eth0.100 上,並根據設置決定是否移除VLAN Tag。如果eth0 收到一包包含VLAN Tag 101 的數據,其將被丟棄。上述過程隱含以下事實:對於寄主Linux 系統來說,母設備只能用來收數據,子設備只能用來發送數據。和Bridge 一樣,母子設備的數據也是有方向的,子設備收到的數據不會進入母設備,同樣母設備上請求發送的數據不會被轉到子設備上。可以把VLAN 母子設備作為一個整體想像為現實世界中的802.1.q 交換機,下級接口通過子設備連接到寄主Linux 系統網絡裡,上級接口同過主設備連接到上級網絡,當母設備是物理網卡時上級網絡是外界真實網絡,當母設備是另外一個Linux 虛擬網絡設備時上級網絡仍然是寄主Linux 系統網絡。

需要注意的是母子 VLAN 設備擁有相同的MAC 地址,可以把它當成現實世界中 802.1.q 交換機的 MAC,因此多個 VLAN 設備會共享一個MAC。當一個母設備擁有多個VLAN 子設備時,子設備之間是隔離的,不存在 Bridge 那樣的交換轉發關係,原因如下:802.1.q VLAN 協議的主要目的是從邏輯上隔離子網。現實世界中的 802.1.q 交換機存在多個 VLAN,每個 VLAN 擁有多個端口,同一 VLAN 端口之間可以交換轉發,不同 VLAN 端口之間隔離,所以其包含兩層功能:交換與隔離。Linux VLAN device 實現的是隔離功能,沒有交換功能。一個 VLAN 母設備不可能擁有兩個相同 ID 的 VLAN 子設備,因此也就不可能出現數據交換情況。如果想讓一個 VLAN 裡接多個設備,就需要交換功能。在 Linux 裡 Bridge 專門實現交換功能,因此將 VLAN 子設備 attach 到一個 Bridge 上就能完成後續的交換功能。總結起來,Bridge 加 VLAN device 能在功能層面完整模擬現實世界裡的 802.1.q 交換機。

Linux 支持VLAN 硬件加速,在安裝有特定硬件情況下,圖中所述內核處理過程可以被放到物理設備上完成。

TAP 設備與VETH 設備
TUN/TAP 設備是一種讓用戶態程序向內核協議棧注入數據的設備,一個工作在三層,一個工作在二層,使用較多的是TAP 設備。VETH 設備出現較早,它的作用是反轉通訊數據的方向,需要發送的數據會被轉換成需要收到的數據重新送入內核網絡層進行處理,從而間接的完成數據的注入。


如圖所示,當一個 TAP 設備被創建時,在Linux 設備文件目錄下將會生成一個對應 char 設備,用戶程序可以像打開普通文件一樣打開這個文件進行讀寫。當執行 write() 操作時,數據進入 TAP 設備,此時對於 Linux 網絡層來說,相當於 TAP 設備收到了一包數據,請求內核接受它,如同普通的物理網卡從外界收到一包數據一樣,不同的是其實數據來自 Linux 上的一個用戶程序。Linux 收到此數據後將根據網絡配置進行後續處理,從而完成了用戶程序向 Linux 內核網絡層注入數據的功能。當用戶程序執行 read() 請求時,相當於向內核查詢 TAP 設備上是否有需要被發送出去的數據,有的話取出到用戶程序裡,完成 TAP 設備的發送數據功能。針對 TAP 設備的一個形象的比喻是:使用 TAP 設備的應用程序相當於另外一台計算機,TAP 設備是本機的一個網卡,他們之間相互連接。應用程序通過 read()/write() 操作,和本機網絡核心進行通訊。

VETH 設備總是成對出現,送到一端請求發送的數據總是從另一端以請求接受的形式出現。該設備不能被用戶程序直接操作,但使用起來比較簡單。創建並配置正確後,向其一端輸入數據,VETH 會改變數據的方向並將其送入內核網絡核心,完成數據的注入。在另一端能讀到此數據。

網絡設置舉例說明
為了更好的說明Linux 網絡設備的用法,下面將用一系列的例子,說明在一個複雜的Linux 網絡元素組合出的虛擬網絡裡,數據的流向。網絡設置簡介如下:一個中心Bridge:bridge0 下attach 了4 個網絡設備,包括2 個VETH 設備,1 個TAP 設備tap0,1 個物理網卡eth0。在VETH 的另外一端又創建了VLAN 子設備。Linux 上共存在2 個VLAN 網絡,既vlan100 與vlan200。物理網卡和外部網絡相連,並且在它之下創建了一個VLAN ID 為200 的VLAN 子設備。

從 vlan100 子設備發送ARP 報文


如圖所示,當用戶嘗試 ping 192.168.100.3 時,Linux 將會根據路由表,從 vlan100 子設備發出 ARP 報文,具體過程如下:
1) 用戶 ping 192.168.100.3
2) Linux 向 vlan100 子設備發送 ARP 信息。
3) ARP 報文被打上 VLAN ID 100 的Tag 成為 ARP@vlan100,轉發到母設備上。
4) VETH 設備將這一發送請求轉變方向,成為一個需要接受處理的報文送入內核網絡模塊。
5) 由於對端的 VETH 設備被加入到了 bridge0 上,並且內核發現它收到一個報文,於是報文被轉發到 bridge0 上。
6) bridge0 處理此 ARP@vlan100 信息,根據 TCP/IP 二層協議發現是一個廣播請求,於是向它所知道的所有端口廣播此報文,其中一路進入另一對 VETH 設備的一端,一路進入 TAP 設備 tap0,一路進入物理網卡設備 eth0。此時在 tap0 上,用戶程序可以通過 read() 操作讀到 ARP@vlan100,eth0 將會向外界發送 ARP@vlan100,但 eth0 的 VLAN 子設備不會收到它,因為此數據方向為請求發送而不是請求接收。
7) VETH 將請求方向轉換,此時在另一端得到請求接受的 ARP@vlan100 報文。
8) 對端 VETH 設備發現有數據需要接受,並且自己有兩個 VLAN 子設備,於是執行 VLAN 處理邏輯。其中一個子設備是 vlan100,與 ARP@vlan100 吻合,於是去除VLAN ID 100 的Tag 轉發到這個子設備上,重新成為標準的以太網ARP 報文。另一個子設備由於ID 不吻合,不會得到此報文。
9) 此 VLAN 子設備又被 attach 到另一個橋 bridge1 上,於是轉發自己收到的 ARP 報文。
10) bridge1 廣播ARP 報文。
11) 最終另外一個 TAP 設備 tap1 收到此請求發送報文,用戶程序通過 read() 可以得到它。

從 vlan200 子設備發送 ARP 報文


和前面情況類似,區別是 VLAN ID 是 200,對端的 vlan200 子設備設置為 reorder_hdr = 0,表示此設備被要求保留收到的報文中的 VLAN Tag。此時子設備會收到 ARP 報文,但是帶了 VLAN ID 200 的Tag,即 ARP@vlan200。

從中心 bridge 發送 ARP 報文


當 bridge0 擁有IP 時,通過Linux 路由表用戶程序可以直接將 ARP 報文發向 bridge0。這時 tap0 和外部網絡都能收到 ARP,但 VLAN 子設備由於 VLAN ID 過濾的原因,將收不到 ARP 信息。

從外部網絡向物理網卡發送 ARP@vlan200 報文


當外部網絡連接在一個支持 VLAN 並且對應端口為 vlan200 時,此情況會發生。此時所有的 VLAN ID 為 200 的 VLAN 子設備都將接受到報文,如果設置 reorder_hdr=0 則會收到帶 Tag 的 ARP@vlan200。

從 TAP 設備以 ping 方式發送 ARP


用戶程序指定 tap0 設備發送報文有兩種方式:socket 和 file operation。當用 socket_raw 標誌新建 socket 並指定設備編號時,可以要求內核將報文從 tap0 發送。但和前面的 ping from tap0 情況類似,由於報文方向問題,消息並不會被轉發到 bridge0 上。當用 open() 方式打開 tap 設備文件時,情況有所不同。當執行 write() 操作時,內核認為 tap0 收到了報文,從而會觸發轉發動作,bridge0 將收到它。如果發送的報文如圖所示,是一個以 A 為目的地的攜帶 VLAN ID 100 Tag 的單點報文,bridge0 將會找到對應的設備進行轉發,對應的 VLAN 子設備將收到沒有 VLAN ID 100 Tag 的報文。

Linux 上配置網絡設備命令舉例
以 Redhat6.2 紅帽Linux 發行版為例,如果已安裝 VLAN 內核模塊和管理工具 vconfig,TAP/TUN 設備管理工具 tunctl,那麼可以用以下命令設置前述網絡設備:
Bridge 操作
* 創建 Bridge:brctl addbr [BRIDGE NAME]
* 刪除 Bridge:brctl delbr [BRIDGE NAME]
* attach 設備到 Bridge:brctl addif [BRIDGE NAME] [DEVICE NAME]
* 從 Bridge detach 設備:brctl delif [BRIDGE NAME] [DEVICE NAME]
* 查詢 Bridge 情況:brctl show

VLAN 設定
* 創建 VLAN 設備:vconfig add [PARENT DEVICE NAME] [VLAN ID]
* 刪除 VLAN 設備:vconfig rem [VLAN DEVICE NAME]
* 設置 VLAN 設備 flag:vconfig set_flag [VLAN DEVICE NAME] [FLAG] [VALUE]
* 設置VLAN 設備qos:
-- vconfig set_egress_map [VLAN DEVICE NAME] [SKB_PRIORITY] [VLAN_QOS]
-- vconfig set_ingress_map [VLAN DEVICE NAME] [SKB_PRIORITY] [VLAN_QOS]
* 查詢VLAN 設備情況:cat /proc/net/vlan/[VLAN DEVICE NAME]

VETH & TAP 設定
* 創建 VETH 設備:ip link add link [DEVICE NAME] type veth
* 創建 TAP 設備:tunctl -p [TAP DEVICE NAME]
* 刪除 TAP 設備:tunctl -d [TAP DEVICE NAME]
* 查詢系統裡所有二層設備,包括 VETH/TAP 設備:ip link show

其他相關設定
* 刪除普通二層設備:ip link delete [DEVICE NAME] type [TYPE]


Supplement
Linux Bridge With ‘brctl’ Tutorial
HowTo: Configure Linux Virtual Local Area Network (VLAN)
VLAN is an acronym for Virtual Local Area Network. Several VLANs can co-exist on a single physical switch, which are configured via Linux software and not through hardware interface (you still need to configure actual hardware switch too)...

This message was edited 46 times. Last update was at 28/05/2015 12:51:03

沒有留言:

張貼留言

[Git 常見問題] error: The following untracked working tree files would be overwritten by merge

  Source From  Here 方案1: // x -----删除忽略文件已经对 git 来说不识别的文件 // d -----删除未被添加到 git 的路径中的文件 // f -----强制运行 #   git clean -d -fx 方案2: 今天在服务器上  gi...