資源描述:
《linux網(wǎng)橋淺析》由會員上傳分享,免費在線閱讀,更多相關(guān)內(nèi)容在行業(yè)資料-天天文庫。
1、什么是橋接?簡單來說,橋接就是把一臺機器上的若干個網(wǎng)絡接口“連接”起來。其結(jié)果是,其中一個網(wǎng)口收到的報文會被復制給其他網(wǎng)口并發(fā)送出去。以使得網(wǎng)口之間的報文能夠互相轉(zhuǎn)發(fā)。交換機就是這樣一個設備,它有若干個網(wǎng)口,并且這些網(wǎng)口是橋接起來的。于是,與交換機相連的若干主機就能夠通過交換機的報文轉(zhuǎn)發(fā)而互相通信。如下圖:主機A發(fā)送的報文被送到交換機S1的eth0口,由于eth0與eth1、eth2橋接在一起,故而報文被復制到eth1和eth2,并且發(fā)送出去,然后被主機B和交換機S2接收到。而S2又會將報文轉(zhuǎn)發(fā)給主機C、D。交換機在報文轉(zhuǎn)發(fā)的過程中并不會篡改
2、報文數(shù)據(jù),只是做原樣復制。然而橋接卻并不是在物理層實現(xiàn)的,而是在數(shù)據(jù)鏈路層。交換機能夠理解數(shù)據(jù)鏈路層的報文,所以實際上橋接卻又不是單純的報文轉(zhuǎn)發(fā)。交換機會關(guān)心填寫在報文的數(shù)據(jù)鏈路層頭部中的Mac地址信息(包括源地址和目的地址),以便了解每個Mac地址所代表的主機都在什么位置(與本交換機的哪個網(wǎng)口相連)。在報文轉(zhuǎn)發(fā)時,交換機就只需要向特定的網(wǎng)口轉(zhuǎn)發(fā)即可,從而避免不必要的網(wǎng)絡交互。這個就是交換機的“地址學習”。但是如果交換機遇到一個自己未學習到的地址,就不會知道這個報文應該從哪個網(wǎng)口轉(zhuǎn)發(fā),則只好將報文轉(zhuǎn)發(fā)給所有網(wǎng)口(接收報文的那個網(wǎng)口除外)。比如
3、主機C向主機A發(fā)送一個報文,報文來到了交換機S1的eth2網(wǎng)口上。假設S1剛剛啟動,還沒有學習到任何地址,則它會將報文轉(zhuǎn)發(fā)給eth0和eth1。同時,S1會根據(jù)報文的源Mac地址,記錄下“主機C是通過eth2網(wǎng)口接入的”。于是當主機A向C發(fā)送報文時,S1只需要將報文轉(zhuǎn)發(fā)到eth2網(wǎng)口即可。而當主機D向C發(fā)送報文時,假設交換機S2將報文轉(zhuǎn)發(fā)到了S1的eth2網(wǎng)口(實際上S2也多半會因為地址學習而不這么做),則S1會直接將報文丟棄而不做轉(zhuǎn)發(fā)(因為主機C就是從eth2接入的)。然而,網(wǎng)絡拓撲不可能是永不改變的。假設我們將主機B和主機C換個位置,當主
4、機C發(fā)出報文時(不管發(fā)給誰),交換機S1的eth1口收到報文,于是交換機S1會更新其學習到的地址,將原來的“主機C是通過eth2網(wǎng)口接入的”改為“主機C是通過eth1網(wǎng)口接入的”。但是如果主機C一直不發(fā)送報文呢?S1將一直認為“主機C是通過eth2網(wǎng)口接入的”,于是將其他主機發(fā)送給C的報文都從eth2轉(zhuǎn)發(fā)出去,結(jié)果報文就發(fā)丟了。所以交換機的地址學習需要有超時策略。對于交換機S1來說,如果距離最后一次收到主機C的報文已經(jīng)過去一定時間了(默認為5分鐘),則S1需要忘記“主機C是通過eth2網(wǎng)口接入的”這件事情。這樣一來,發(fā)往主機C的報文又會被轉(zhuǎn)發(fā)
5、到所有網(wǎng)口上去,而其中從eth1轉(zhuǎn)發(fā)出去的報文將被主機C收到。linux的橋接實現(xiàn)相關(guān)模型linux內(nèi)核支持網(wǎng)口的橋接(目前只支持以太網(wǎng)接口)。但是與單純的交換機不同,交換機只是一個二層設備,對于接收到的報文,要么轉(zhuǎn)發(fā)、要么丟棄。小型的交換機里面只需要一塊交換芯片即可,并不需要CPU。而運行著linux內(nèi)核的機器本身就是一臺主機,有可能就是網(wǎng)絡報文的目的地。其收到的報文除了轉(zhuǎn)發(fā)和丟棄,還可能被送到網(wǎng)絡協(xié)議棧的上層(網(wǎng)絡層),從而被自己消化。linux內(nèi)核是通過一個虛擬的網(wǎng)橋設備來實現(xiàn)橋接的。這個虛擬設備可以綁定若干個以太網(wǎng)接口設備,從而將它們
6、橋接起來。如下圖(摘自ULNI):網(wǎng)橋設備br0綁定了eth0和eth1。對于網(wǎng)絡協(xié)議棧的上層來說,只看得到br0,因為橋接是在數(shù)據(jù)鏈路層實現(xiàn)的,上層不需要關(guān)心橋接的細節(jié)。于是協(xié)議棧上層需要發(fā)送的報文被送到br0,網(wǎng)橋設備的處理代碼再來判斷報文該被轉(zhuǎn)發(fā)到eth0或是eth1,或者兩者皆是;反過來,從eth0或從eth1接收到的報文被提交給網(wǎng)橋的處理代碼,在這里會判斷報文該轉(zhuǎn)發(fā)、丟棄、或提交到協(xié)議棧上層。而有時候eth0、eth1也可能會作為報文的源地址或目的地址,直接參與報文的發(fā)送與接收(從而繞過網(wǎng)橋)。相關(guān)數(shù)據(jù)結(jié)構(gòu)要使用橋接功能,我們需要在
7、編譯內(nèi)核時指定相關(guān)的選項,并讓內(nèi)核加載橋接模塊。然后通過“brctladdbr{br_name}”命令新增一個網(wǎng)橋設備,最后通過“brctladdif{eth_if_name}”命令綁定若干網(wǎng)絡接口。完成這些操作后,內(nèi)核中的數(shù)據(jù)結(jié)構(gòu)關(guān)系如下圖所示(摘自ULNI):其中最左邊的net_device是一個代表網(wǎng)橋的虛擬設備結(jié)構(gòu),它關(guān)聯(lián)了一個net_bridge結(jié)構(gòu),這是網(wǎng)橋設備所特有的數(shù)據(jù)結(jié)構(gòu)。在net_bridge結(jié)構(gòu)中,port_list成員下掛一個鏈表,鏈表中的每一個節(jié)點(net_bridge_port結(jié)構(gòu))關(guān)聯(lián)到一個真實的網(wǎng)口設備的net
8、_device。網(wǎng)口設備也通過其br_port指針做反向的關(guān)聯(lián)(那么顯然,一個網(wǎng)口最多只能同時被綁定到一個網(wǎng)橋)。net_bridge結(jié)構(gòu)中還維護了一個hash表,