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