Linux 網絡協議棧開發基礎篇—— 網橋br0


 一、橋接的概念

      簡單來說,橋接就是把一台機器上的若干個網絡接口“連接”起來。其結果是,其中一個網口收到的報文會被復制給其他網口並發送出去。以使得網口之間的報文能夠互相轉發

     交換機就是這樣一個設備,它有若干個網口,並且這些網口是橋接起來的。於是,與交換機相連的若干主機就能夠通過交換機的報文轉發而互相通信。

     如下圖:主機A發送的報文被送到交換機S1的eth0口,由於eth0與eth1、eth2橋接在一起,故而報文被復制到eth1和eth2,並且發送出 去,然后被主機B和交換機S2接收到。而S2又會將報文轉發給主機C、D。

      交換機在報文轉發的過程中並不會篡改報文數據,只是做原樣復制。然而橋接卻並不是在物理層實現的,而是在數據鏈路層。交換機能夠理解數據鏈路層的報文,所以實際上橋接卻又不是單純的報文轉發。

     交換機會關心填寫在報文的數據鏈路層頭部中的Mac地址信息(包括源地址和目的地址),以便了解每個Mac地址所代表的主機都在什么位置(與本交換機的哪 個網口相連)。在報文轉發時,交換機就只需要向特定的網口轉發即可,從而避免不必要的網絡交互。這個就是交換機的“地址學習”。但是如果交換機遇到一個自 己未學習到的地址,就不會知道這個報文應該從哪個網口轉發,則只好將報文轉發給所有網口(接收報文的那個網口除外)。

      比如主機C向主機A發送一個報文,報文來到了交換機S1的eth2網口上。假設S1剛剛啟動,還沒有學習到任何地址,則它會將報文轉發給eth0和 eth1。同時,S1會根據報文的源Mac地址,記錄下“主機C是通過eth2網口接入的”。於是當主機A向C發送報文時,S1只需要將報文轉發到 eth2網口即可。而當主機D向C發送報文時,假設交換機S2將報文轉發到了S1的eth2網口(實際上S2也多半會因為地址學習而不這么做),則S1會 直接將報文丟棄而不做轉發(因為主機C就是從eth2接入的)。

     然而,網絡拓撲不可能是永不改變的。假設我們將主機B和主機C換個位置,當主機C發出報文時(不管發給誰),交換機S1的eth1口收到報文,於是交換機 S1會更新其學習到的地址,將原來的“主機C是通過eth2網口接入的”改為“主機C是通過eth1網口接入的”。

     但是如果主機C一直不發送報文呢?S1將一直認為“主機C是通過eth2網口接入的”,於是將其他主機發送給C的報文都從eth2轉發出去,結果報文就發 丟了。所以交換機的地址學習需要有超時策略(FDB的老化)。對於交換機S1來說,如果距離最后一次收到主機C的報文已經過去一定時間了(默認為5分鍾),則S1需要忘記 “主機C是通過eth2網口接入的”這件事情。這樣一來,發往主機C的報文又會被轉發到所有網口上去,而其中從eth1轉發出去的報文將被主機C收到。

 

二、linux的橋接實現

       linux內核支持網口的橋接(目前只支持以太網接口)。但是與單純的交換機不同,交換機只是一個二層設備,對於接收到的報文,要么轉發、要么丟棄。小型的交換機里面只需要一塊交換芯片即可,並不需要CPU。而運行着linux內核的機器本身就是一台主機,有可能就是網絡報文的目的地。其收到的報文除了轉發和丟棄,還可能被送到網絡協議棧的上層(網絡層),從而被自己消化

      linux內核是通過一個虛擬的網橋設備來實現橋接的。這個虛擬設備可以綁定若干個以太網接口設備,從而將它們橋接起來。

      網橋設備br0綁定了eth0和eth1。對於網絡協議棧的上層來說,只看得到br0,因為橋接是在數據鏈路層實現的,上層不需要關心橋接的細節。於是協議棧上層需要發送的報文被送到br0,網橋設備的處理代碼再來判斷報文該被轉發到eth0或是eth1,或者兩者皆是;反過來,從eth0或從eth1接收到的報文被提交給網橋的處理代碼,在這里會判斷報文該轉發、丟棄、或提交到協議棧上層。

     而有時候eth0、eth1也可能會作為報文的源地址或目的地址,直接參與報文的發送與接收(從而繞過網橋)。

 

三、網橋的功能

       概括來說,網橋實現最重要的兩點:

1、MAC學習

      學習MAC地址,起初,網橋是沒有任何地址與端口的對應關系的,它發送數據,還是得想HUB一樣,但是每發送一個數據,它都會關心數據包的來源MAC是從自己的哪個端口來的,由於學習,建立地址-端口的對照表(CAM表)。

2、報文轉發

     每發送一個數據包,網橋都會提取其目的MAC地址,從自己的地址-端口對照表(CAM表)中查找由哪個端口把數據包發送出去。

 

四、網橋的配置

      在Linux里面使用網橋非常簡單,僅需要做兩件事情就可以配置了。其一是在編譯內核里把CONFIG_BRIDGE或CONDIG_BRIDGE_MODULE編譯選項打開;其二是安裝brctl工具。第一步是使內核協議棧支持網橋,第二步是安裝用戶空間工具,通過一系列的ioctl調用來配置網橋。下面以一個相對簡單的實例來貫穿全文,以便分析代碼。

     Linux機器有4個網卡,分別是eth0~eth4,其中eth0用於連接外網,而eth1, eth2, eth3都連接到一台PC機,用於配置網橋。只需要用下面的命令就可以完成網橋的配置

Brctl addbr br0    //(建立一個網橋br0, 同時在Linux內核里面創建虛擬網卡br0)

Brctl addif br0 eth1

Brctl addif br0 eth2

Brctl addif br0 eth3  // (分別為網橋br0添加接口eth1, eth2和eth3)

      其中br0作為一個網橋,同時也是虛擬的網絡設備,它即可以用作網橋的管理端口,也可作為網橋所連接局域網的網關,具體情況視你的需求而定。要使用br0接口時,必需為它分配IP地址。為正常工作,PC1, PC2,PC3和br0的IP地址分配在同一個網段。

 

Over...

 

參考鏈接:

1. Linux 網絡協議棧開發基礎篇(七)—— 網橋br0


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM