Bridge(橋)是Linux上用來做TCP/IP二層協議交換的設備,與現實世界中的交換機功能相似。Bridge設備實例可以和Linux上其他網路設備實例連接,既attach一個從設備,類似於在現實世界中的交換機和一個用戶終端之間連接一根網線。當有數據到達時,Bridge會根據報文中的MAC信息進行... ...
本文分享自天翼雲開發者社區《Linux Bridge和Tap關係詳解》,作者:x****n
Linux Bridge介紹
Bridge(橋)是Linux上用來做TCP/IP二層協議交換的設備,與現實世界中的交換機功能相似。Bridge設備實例可以和Linux上其他網路設備實例連接,既attach一個從設備,類似於在現實世界中的交換機和一個用戶終端之間連接一根網線。當有數據到達時,Bridge會根據報文中的MAC信息進行廣播、轉發、丟棄處理。
如圖所示,Bridge的功能主要在內核里實現。當一個從設備被attach到Bridge上時,相當於現實世界里交換機的埠被插入了一根連有終端的網線。這時在內核程式里,netdev_rx_handler_register()被調用,一個用於接受數據的回調函數被註冊。以後每當這個從設備收到數據時都會調用這個函數可以把數據轉發到Bridge上。當Bridge接收到此數據時,br_handle_frame()被調用,進行一個和現實世界中的交換機類似的處理過程:判斷包的類別(廣播/單點),查找內部MAC埠映射表,定位目標埠號,將數據轉發到目標埠或丟棄,自動更新內部MAC埠映射表以自我學習。
Linux內核支持網口的橋接(目前只支持乙太網介面)。但是與單純的交換機不同,交換機只是一個二層設備,對於接收到的報文,要麼轉發、要麼丟棄。小型的交換機裡面只需要一塊交換晶元即可,並不需要CPU。而運行著Linux內核的機器本身就是一臺主機,有可能就是網路報文的目的地。其收到的報文除了轉 發和丟棄,還可能被送到網路協議棧的上層(網路層),從而被自己消化。
網橋的功能
概括來說,網橋實現最重要的兩點:
1.MAC學習:學習MAC地址,起初,網橋是沒有任何地址與埠的對應關係的,它發送數據,還是得想HUB一樣,但是每發送一個數據,它都會關心數據包的來源MAC是從自己的哪個埠來的,由於學習,建立地址-埠的對照表(CAM表)。
2.報文轉發:每發送一個數據包,網橋都會提取其目的MAC地址,從自己的地址-埠對照表(CAM表)中查找由哪個埠把數據包發送出去。
網橋配置ip
Bridge可以設置IP地址,當一個bridge0擁有IP後,Linux便可以通過路由表或者IP表規則在三層定位bridge0,此時相當於Linux擁有了另外一個隱藏的虛擬網卡和Bridge的隱藏埠相連。當一個設備被attach到Bridge上時,那個設備的IP會變的無效,Linux不再使用那個IP在三層接受數據。
對於一個被attach到Bridge上的設備來說,只有它收到數據時,此包數據才會被轉發到Bridge上,進而完成查表廣播等後續操作。當請求是發送類型時,數據是不會被轉發到Bridge上的,它會尋找下一個發送出口。
網橋處理包原則
網橋需要維護一個MAC地址-埠映射表(CAM),埠是指網橋自身提供的埠,而MAC地址是指與埠相連的另一端的MAC地址。
網橋處理包遵循以下幾條原則:
1.在一個介面上接收的包不會再在那個介面上發送這個數據包;
2.每個接收到的數據包都要學習其源地址;
3.如果數據包是多播或廣播包,則要在同一個網段中除了接收埠外的其他所有埠發送這個數據包,如果上層協議棧對多播包感興趣,則需要把數據包提交給上層協議棧;
4.如果數據包的目的MAC地址不能再CAM表中找到,則要在同一個網段中除了接收埠外的其他所有埠發送這個數據包;
5.如果能夠在CAM表中查詢到目的MAC地址,則在特定的埠上發送這個數據包,如果發送埠和接收埠是同一埠則不發送。
Tap設備介紹
TAP設備是一種讓用戶態程式向內核協議棧註入數據的設備,工作在二層。做為虛擬網卡驅動,Tap驅動程式的數據接收和發送並不直接和真實網卡打交道,而是通過用戶態來轉交。Tap驅動是利用設備文件實現用戶態和核心態的數據交互。
從結構上來說,Tap驅動並不單純是實現網卡驅動,同時它還實現了字元設備驅動部分。以字元設備的方式連接用戶態和核心態。下麵是示意圖:
Tap驅動程式中包含兩個部分,一部分是字元設備驅動,還有一部分是網卡驅動部分。利用網卡驅動部分接收來自TCP/IP協議棧的網路分包併發送或者反過來將接收到的網路分包傳給協議棧處理,而字元驅動部分則將網路分包在內核與用戶態之間傳送,模擬物理鏈路的數據接收和發送。Tap驅動很好的實現了兩種驅動的結合。
Tap驅動處理流程
如圖所示,當一個TAP設備被創建時,在Linux設備文件目錄下將會生成一個對應char設備,用戶程式可以像打開普通文件一樣打開這個文件進行讀寫;Linux protocol statck是Linux內核的tcp/ip協議棧。當執行write()操作時,數據進入TAP設備,此時對於Linux網路層來說,相當於TAP設備收到了一包數據,請求內核接受它,如同普通的物理網卡從外界收到一包數據一樣,不同的是其實數據來自Linux上的一個用戶程式。Linux收到此數據後將根據網路配置進行後續處理,從而完成了用戶程式向Linux內核網路層註入數據的功能。當用戶程式執行read()請求時,相當於向內核查詢TAP設備上是否有需要被髮送出去的數據,有的話取出到用戶程式里,完成TAP設備的發送數據功能。針對TAP設備的一個形象的比喻是:使用TAP設備的應用程式相當於另外一臺電腦,TAP設備是本機的一個網卡,他們之間相互連接。應用程式通過read()/write()操作,和本機網路核心進行通訊。