日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

一,鏈路層

在報文接收方向上,網卡驅動把接收到的數據按照其對應的鏈路層協議(如以太網)組裝成報文,然后把它上交給鏈路層,接口是netif_receive_skb,至此網卡驅動的任務就結束了,報文交給鏈路層處理;

在報文發送方向上,網卡驅動受鏈路層驅使,鏈路層告知其有報文要發送時,網卡驅動才開始工作,接口是dev_queue_xmit。

上面是鏈路層和網卡驅動層的接口,然而在鏈路層不一定是報文最終的歸宿,從報文接收角度看,絕大多數報文都要最終給目的主機的應用層,協議報文會在不同協議所屬層次終結,所以大多數報文都還要由鏈路層處理后(或不處理)再向上層轉發,比如IP報文,在鏈路層由ip_rcv函數進入網絡層處理,比如由應用程序通過原始套接字獲取的報文將在鏈路層被直接送往socket層,比如arp協議報文會被送往arp模塊去處理……

再從報文發送角度看,不同的處理模塊,會通過其專有接口通知鏈路層要發送報文,比如對于網絡層,通過ip_finish_output(最終是ip_finish_output2)告訴鏈路層要發送報文(事實上是經由鄰居子系統模塊實際發送,鄰居子系統實現鏈路層和網絡層的映射,可以認為屬于鏈路層和網絡層的中間層),當然原始套接字的情況則比較簡單,直接調用dev_queue_xmit通知網卡驅動,然而對于網橋、vlan子接口的收發,鏈路層的處理就顯得極為必要,而從網絡分層理論看,網橋、vlan,正是邏輯鏈路層的內容,這些都屬于linux鏈路層的核心工作,典型的對于以太網的鏈路層,以太網類型、vlan、源目mac地址是鏈路層的協議字段。

此外,在鏈路層的無需三層協議轉發的二層隧道轉發方式,典型如按網絡層IP地址轉發的eoip(Ethernet over ip),也是鏈路層的任務。

更多Linux內核視頻教程文檔資料免費領取后臺私信【內核】自行獲取。

網橋、vlan、源目MAC地址的鏈路層處理

 

從功能上看,鏈路層完成以下任務:

  • 1、 實現與網卡驅動和協議棧上層的接口;
  • 2、 實現網橋,即實現按MAC地址轉發的二層交換機功能;
  • 3、 實現vlan處理,實現帶vlan報文的傳輸;
  • 4、 實現鄰居子系統,即實現鏈路層和網絡層的映射;
  • 5、 根據以太網類型,實現根據鏈路層協議類型收發報文;
  • 6、實現二層隧道功能(典型如依托于網絡層IP地址轉發的eoip隧道);
網橋、vlan、源目MAC地址的鏈路層處理

 

如上圖,鏈路層由netif_receive_skb收到報文后,依次進行網橋處理、L2隧道處理、按以太網類型處理(事實上在按以太網類型處理前,還可能有其他處理),網橋處理中會根據報文是否發給本機還是轉發做不同的處理,發給本機將修改報文輸入接口為橋端口并返回netif_receive_skb重新進協議棧處理,轉發則直接調用dev_queue_xmit從對應接口發送;L2隧道處理則根據所屬隧道的目的IP尋找路由,并根據路由結果指示的出接口轉發報文;按以太網類型處理,就根據以太網類型調用在之前注冊過的協議處理函數,如vlan報文調用vlan_skb_recv,IP報文調用ip_rcv,arp報文調用arp_rcv等等;

需要注意對于網橋和vlan的上本機的報文,會更新報文的輸入接口,由從網卡驅動接收接口改為對應的橋端口或vlan子接口(vlan報文還會去除vlan頭),這是因為事實上上層協議棧關心報文的“邏輯”輸入接口,而不是“物理”輸入接口,這些報文的反向報文也是由上層協議棧發送到橋端口或vlan子接口,再繼而轉換為其原始的報文輸入接口通往網卡驅動,簡單的說就是網橋、vlan報文對于上層協議棧可見的是橋端口、vlan子接口。

綜上所述,鏈路層的功能是提供協議棧與網卡驅動的接口、協議棧上層的接口(按以太網類型)、直接轉發(網橋或L2隧道),另外鄰居子系統實現了鏈路層和網絡層的映射(對于IPV4為arp),另外需要注意,netif_receive_skb是在軟中斷處理函數調用的,也就是說整個協議棧報文處理是處于軟中斷中。

接口的概念:

接口可以理解為鏈路層的每一個收發單元,每一個接口可以對應實際的一個網卡,也可以是一個沒有實際物理設備驅動對應的“虛”接口,比如網橋接口、vlan子接口,不論是“虛”接口還是“實”接口,在內核中都是以net_device結構體描述;

對于網絡層,最重要的工作是選路,即確定路由,而確定路由就是確定報文是轉發還是上送本機,如果是轉發的話從哪個接口發送(skb->_skb_dst),并且路由判決所需條件也包括報文的輸入接口即報文是從哪個接口上到網絡層的(skb->dev),除路由之外,上層協議棧其他部分也經常關注報文的輸入接口和路由轉發接口;

所以接口是報文實際輸入輸出的邏輯路徑,但不一定是物理路徑,如某報文的路由結果是從eth0.5接口轉發出去,那么這個eth0.5就是轉發的邏輯路徑,但它并沒有實際的物理驅動,而是再通過vlan子接口處理最終仍由eth0實際轉發報文,再如某報文由網橋br0上送到網絡層,那么br0是該報文的邏輯路徑,上層協議棧認為該報文就是從br0接收的,而實際該報文可能是由eth1實際接收的,經過網橋處理后輸入接口變為br0的。

之所以會有“虛”接口,都是因為一些特殊的目的,linux需要實現網橋,需要實現vlan,而這些都是邏輯上的概念,并不真的存在某種物理設備叫網橋或者叫vlan,所以需要人為的制造出這些“虛”接口,以滿足上層協議棧向下處理的統一性,而這些“虛”接口和“實接口的“虛實轉換”,就是需要鏈路層實現的內容。

“實”接口一般由網卡驅動生成,因為網卡驅動管理實際的物理設備,所以一般諸如eth0、wlan1、usb2之類“實”接口由網卡驅動生成,網卡驅動負責這些“實”接口的ops實現;而“虛”接口一般由應用程序生成,如網橋、vlan子接口,內核源碼負責這些類型的“虛”接口的ops。

可以把linux機器想象成一臺能夠實現交換機、路由器、主機的L2/3/4/5功能的結合體機器,“實”接口就是這個結合體機器的每個物理端口,“虛”接口表面上實現一些二層網絡功能,如vlan子接口實現物理端口的vlan功能,網橋接口實現二層交換功能,而實際上這些“虛”接口同樣被這個結合體機器的L3/4/5所識別。

二,網橋原理

網橋工作在鏈路層,所以它是二層的東西,對于以太網來說網橋和二層網絡設備交換機的工作方式幾乎是一樣的,每個交換機包含一系列以太網接口,交換機通過其內部的硬件交換芯片實現對這些以太網接口出入報文的二層接收轉發及過濾等二層qos功能,網橋在功能上和交換機幾乎是一樣的,只不過它是由軟件實現這些功能。

下圖是交換機和網橋的內部實現原理圖:

網橋、vlan、源目MAC地址的鏈路層處理

 


網橋、vlan、源目MAC地址的鏈路層處理

 

如上圖,可以把網橋本身看做一個二層交換機,該交換機下面有eth0、usb1、vlan2、wlan3共4個接口,每個網橋下可以有很多個接口,不考慮STP生成樹協議的話,可以認為網橋下接口是由用戶配置的,普遍用brctl應用程序工具生成網橋,并在每個網橋下增加和刪除接口,brctl使用舉例如下:

網橋、vlan、源目MAC地址的鏈路層處理

 

初始情況下,沒有網橋,由命令“brctl addbr br0”創建一個網橋br0,然后可以觀察到創建了網橋br0,此時它底下還沒有接口,然后由命令“brctl addif br0 XXX”在網橋br0下加入接口eth1、eth2,然后可以觀察到網橋br0底下有這兩個接口;同時網橋br0的MAC地址表還加入了兩個靜態的MAC地址,分別是接口eth1和eth2的MAC地址,這時如果從eth1接口進入屬于網橋br0的報文,并且該報文的目的MAC地址與eth2接口的MAC地址相同,那么報文將被從eth2接口轉發出去,并且會記錄該報文的源MAC地址和進入接口eth1的對應關系作為網橋br0的一個動態MAC地址條目。

再如,我們的網關設備做測試時,如需測試二層業務流性能,經常把wan接口和vlan1接口做橋接,然后即可打雙向二層業務流,同樣是通過網橋學習兩個接口進入報文的源MAC地址和進入接口的對應關系,實現網橋的兩個接口對打二層業務流,由此可見,這和二層交換機的MAC地址學習和轉發的道理是一樣的。

此外,linux的網橋同樣還實現了多種多樣的報文處理功能,同樣依托netfilter框架,通過不同的hook點掛載不同的包處理環節,其qos功能可以比二層交換機還要豐富。

三,linux的網橋實現

涉及文件:

Linux網橋實現在代碼樹的net/bridge/目錄下,主要文件如下:

  • l br_device.c:網橋net_device的ops實現;
  • l br_fdb.c:網橋的MAC地址表實現;
  • l br_forward.c:網橋的報文轉發邏輯實現;
  • l br_if.c:網橋及橋端口的創建增刪操作;
  • l br_input.c:網橋的報文處理函數;
  • l br_ioctl.c:網橋的用戶ioctl接口;
  • l br_netfilter.c:網橋的netfilter框架及默認掛載的hook;
  • l br_netlink.c:網橋的netlink接口;
  • l br_notify.c:網橋的內核通知鏈;
  • l 其余文件為網橋的STP協議相關和默認的netfilter處理函數實現;
  • l br.c:網橋模塊初始化;

重要數據結構

網橋創建:

我們知道linux內核協議棧的鏈路層中,任何一個收發實體都是以結構體net_device描述的,這一個個的收發實體可以是有實際物理設備支持的,如常見的以太網卡設備ethX、usb網卡設備、無線網卡設備等等,也可以是沒有實際物理設備支持的虛擬網卡設備,如vlan接口、網橋接口,之所以這樣做是因為在內核中對收發實體的一切處理邏輯都是統一的接口,事實上這體現的就是linux內核面向對象的重要思想。

所以每一個網橋在linux內核中也都是以net_device結構體描述,不同的是網橋net_device的私貨部分是結構體net_bridge,它描述了網橋與其他類型net_device諸如以太網卡設備、vlan接口等的區別,事實上不同類型的net_device,其區別主要是通過私貨部分標識,對于網橋net_device它的私貨就是結構體net_bridge,如下圖:

網橋、vlan、源目MAC地址的鏈路層處理

 

如不考慮STP生成樹協議部分的內容,net_bridge結構最值得注意的字段如下:

  • 1、dev:它標識該網橋自身的net_device,對于IP層及以上協議,鏈路層可見的是網橋,而不是網橋底下的接口,所以上層操作的net_device都是網橋的net_device;另外網橋自身的net_device也是區分不同網橋的依據,這些是該字段存在的重要意義;
  • 2、ageing_time:動態MAC地址的老化時間;
  • 3、stp_enabled:標識該網橋是否開啟STP功能,默認為關閉,本文不討論STP協議相關的內容;

創建了一個網橋就如同創建了一個交換機,但此時這個“交換機”底下還沒有接口

用戶應用程序(典型如brctl)創建網橋的過程如下:

網橋、vlan、源目MAC地址的鏈路層處理

 

創建網橋的核心函數是br_add_bridge,它創建了網橋的net_device并將其注冊進內核,注意用戶創建網橋時只需傳入網橋名稱即可;

網橋net_device的私貨是結構體net_bridge,new_bridge_dev函數對它進行初始化,主要內容包括:

  • 創建了網橋自身的net_device并由私貨回指(br->dev= dev);
  • 設置默認關閉STP協議(br->stp_enabled= BR_NO_STP);
  • 設置網橋的默認動態MAC地址老化時間為300秒(br->ageing_time= 300 * HZ);
  • 開啟動態MAC地址老化定時器(br_stp_timer_init(br));

網橋接口添加:

創建網橋后,需要再加入接口,網橋的每一個接口在linux內核中以net_bridge_port結構體描述,在內核中稱為橋端口,如下:

網橋、vlan、源目MAC地址的鏈路層處理

 

同樣如果不考慮STP協議相關內容,只需關注如下字段:

  • 1、 br:標識該橋端口屬于哪個網橋;
  • 2、 dev:標識該橋端口實際對應哪個接口;
  • 3、 state:標識該橋端口的狀態,一般為BR_STATE_FORWARDING即轉發;

在創建好網橋后,應用程序通過網橋的ops在網橋中加入接口,過程如下:

網橋、vlan、源目MAC地址的鏈路層處理

 

有了網橋,并在網橋下加入了接口,那么該網橋就可以發揮二層交換機的作用了。需要注意的問題如下:

  • 1、 同一個接口不能作為不同網橋的橋端口;
  • 2、 網橋下的橋端口,都必須是混雜模式,但網橋自身不一定是混雜模式,往往在有特殊需求時如需要抓包時,會把網橋自身接口設置為混雜模式,即網橋下所有橋端口接收到的報文都要送給本機一份;
  • 3、 每創建一個橋端口,都會把該橋端口對應接口的MAC地址作為靜態MAC地址記錄在所屬網橋的MAC地址表中,靜態MAC地址不會被老化,因為目的地址是該接口MAC地址,說明是送給該接口所在主機的報文即送本地的報文,所以不能老化掉這樣的MAC地址;
  • 4、 網橋自身接口的mtu和MAC地址是其底下所有橋接口的mtu最小值和MAC地址最小值,都也可以由用戶配置修改;
  • 5、 不考慮STP協議情況下,橋端口的狀態是轉發(BR_STATE_FORWARDING),一般情況下不必考慮橋端口的其他狀態;

網橋報文接收處理

前面已經提到,linux內核對于報文收發處理使用統一的接口,在報文接收處理中,都是由驅動層接收到報文后調用函數netif_receive_skb進入協議棧處理,網橋的處理入口函數為handle_bridge,實質處理函數是br_handle_frame,流程如下:

網橋、vlan、源目MAC地址的鏈路層處理

 

結合上圖,網橋處理的重點如下:

  • 1、 需要進行橋接處理的報文,其輸入接口必須屬于某網橋;
  • 2、 暫不考慮STP協議報文的處理,對于上圖重點關注“報文轉發流程”框之后的內容;
  • 3、 橋接處理前會檢查用戶是否通過ebtables工具在鏈路層對報文進行過濾或其他處理,ebtables工具類似iptables工具,可以加不同的規則,區別在于它工作在鏈路層,這實現了類似二層交換機的qos功能;
  • 4、 每次報文處理都首先進行動態MAC地址的學習或更新老化時間;
  • 5、 對于某些操作,如對網橋進行抓包,這會使網橋自身接口被設置為混雜模式,這時必須把報文復制一份送至本地;
  • 6、 組播/廣播/未知單播報文會洪泛到每個橋端口,已知單播報文若目的端口為本機則送至本機,若非本機則從對應橋端口轉發出去;可見網橋與二層交換機在單播和廣播報文的轉發方面是一樣的,唯一區別在于組播報文的處理,在我們的網關設備上通過修改內核,是不允許組播報文在網橋上傳播的;

網橋報文發送處理:

前面7.2.1.1一節中已經提到,網橋net_device的ops實現在內核的br_device.c文件中,如同網卡驅動一樣,網橋作為一種特殊的網絡設備,它也有它的ops方法集,linux已定義好它,如下圖:

網橋、vlan、源目MAC地址的鏈路層處理

 

網橋不同情況下的報文流向:

傳入本機:

切記這里的傳入本機,并不一定是要傳入本機傳輸層,而僅僅是意味著該報文的目的MAC地址是該網橋下某橋端口對應接口的MAC地址,即報文穿過網橋繼續走本機協議棧進行進一步處理,如下圖:

網橋、vlan、源目MAC地址的鏈路層處理

 

轉發出去:

轉發最終均調用dev_queue_xmit,這和所有的報文發送的道理是一樣的,需要注意的是轉發接口的更換和網橋轉發的兩次netfilter,如下圖:

網橋、vlan、源目MAC地址的鏈路層處理

 

傳入本機后再從網橋轉發:

這個情況實際是7.2.4.1中后續可能發生情況的一種,即在路由判決后,該報文應從一個網橋接口轉發,如下圖:

網橋、vlan、源目MAC地址的鏈路層處理

 

同理,該報文也可在傳入本機后再從某個其他接口轉發,如從某個以太網卡接口、usb接口、wlan接口等等。

分享到:
標簽:網橋
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定