【內核】Linux內核參數group_fwd_mask-設置bridge過濾MAC地址範圍

筆者在利用gns3模擬器搭建網絡實驗時,發現交換機設備和服務器之間無法成功協商LACP協議,CISCO NEXUS 9K互相之間卻可以成功協商LACP, 在交換機和服務器上抓包發現,Nexus 9K發出的LACP報文中的目的MAC地址爲00:01:02:03:04:05(而標準LACP協議中規定的是01:80:c2:00:00:02),服務器發出的LACP報文的目的MAC是01:80:c2:00:00:02。然而,進一步思考,爲什麼在gns3模擬器中, Nexus 9K的LACP的目標MAC跟標準協議不同呢?經過查閱,這是因爲在gns3上的所有虛擬設備都是運行在同一個物理服務器上,互相之間通過網橋相連,默認情況下,linux的網橋會將01:80:c2:00:00:0x的目標MAC地址全部過濾,Nexus 9K爲了避免該問題調整了LACP的目標MAC, 而服務器卻沒有調整。調整group_fwd_mask這個內核參數,可以控制linux網橋對MAC地址的過濾範圍,這也是本文想要探討的問題。

IEEE 802.1D協議中規定的網橋過濾MAC地址

下面一段話引用自IEEE Standard Group MAC Addresses tutorial,IEEE 802.1D協議規定,01-80-C2-00-00-00  -- 01-80-C2-00-00-0F是IEEE爲標準協議留出的範圍,使用這些地址的包將被網橋過濾,而不會被轉發。

IEEE 802.1D MAC Bridge Filtered MAC Group Addresses: 01-80-C2-00-00-00 to 01-80-C2-00-00-0F; MAC frames that have a destination MAC address within this range are not relayed by MAC bridges conforming to IEEE 802.1D.

IEEE協議中規定的預留的MAC地址表如下:

MAC address Protocol
01-80-C2-00-00-00 Spanning Tree (STP/RSPT/MSTP)
01-80-C2-00-00-01 Ethernet Flow Control (pause frames)
01-80-C2-00-00-02 Link Aggregation Control Protocol (LACP)
01-80-C2-00-00-03 802.1X Port-Based Network Access Control
01-80-C2-00-00-08 Provider Bridge protocols (STP)
01-80-C2-00-00-0D Provider Bridge protocols (MVRP)
01-80-C2-00-00-0E 802.1AB Link Layer Discovery Protocol (LLDP)

 

 

出現的問題

所有使用上述MAC地址的協議,都會被網橋過濾掉(因爲網橋符合IEEE 802.1D協議的規定),如果使用的是物理網橋,這樣的情況將無法改變,但是對於linux中的虛擬網橋呢,是不是也是一樣呢?默認情況下,linux的虛擬網橋完全符合IEEE 802.1D的規定,跟物理網橋一樣,完全過濾了目的MAC地址爲01-80-C2-00-00-0x的協議,因此造成了本文開頭所述的情況。

解決方法

那怎樣才能在gns3上模擬這麼多被過濾的協議呢?顯然一定還有其他人遇到過相同的問題,只要google一下便不難找到解決方法了。從Linux Kernel 2.6開始,就可以通過調整內核參數/sys/class/net/bridge-iface/bridge/group_fwd_mask來控制虛擬網橋對802.1D中規定的地址範圍中,哪些MAC地址不再過濾。/sys/class/net/bridge-iface/bridge/group_fwd_mask的默認值爲0,意味着將對01-80-C2-00-00-0x的所有地址進行過濾。將/sys/class/net/bridge-iface/bridge/group_fwd_mask的值設爲16384, 則可以讓虛擬網橋轉發LLDP報文(目的MAC:  01-80-C2-00-00-0E)

echo 16384 > /sys/class/net/br0/bridge/group_fwd_mask

 需要注意的是,在默認的發行版本中,對於該MAC地址範圍中的前三個(-00,-01,-02)是不能通過以上方式控制的, 意味着在gns3的模擬環境中,我們仍然不能成功的測試STP,流控和LACP。要克服這個限制,必須要自己編譯linux kernel纔行,點擊查看方法,也可以下載EVE編譯好的版本,點擊進入鏈接。這樣就可以隨意調整group_fwd_mask的值,支持不過濾01-80-C2-00-00-0x的所有地址了。

bitmasks和group_fwd_mask

前文中把group_fwd_mask設爲16384,對應的MAC是01-80-C2-00-00-0E,對應的協議是LLDP, 那麼group_fwd_mask是如何計算的呢?

例1: 如果要允許01-80-C2-00-00-0E,對應的表格如下,MAC地址的最後兩位是0E, 則將下表中的0E的bit置爲1。

MAC 0F 0E 0D 0C 0B 0A 09 08 07 06 05 04 03 02 01 00
BIT 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0

 

bitmasks是二進制數0100 0000 0000 0000, 轉換成10進制則爲16384。

例2: 如果要允許01-80-C2-00-00-0E,01-80-C2-00-00-03,01-80-C2-00-00-02, 則對應的表如下, 將表中的0E,03,02的bit置爲1。

MAC 0F 0E 0D 0C 0B 0A 09 08 07 06 05 04 03 02 01 00
BIT 0 1 0 0 0 0 0 0 0 0 0 0 0 0

bitmasks是二進制數0100 0000 0000 1100, 轉換成10進制則爲16396。這樣就可以允許LLDP,LACP,802.1x協議了。

按照這樣的方法,要解除linux網橋對規定地址範圍內所有地址的過濾,就把所有的bit都置爲1 即可:

  1. 打過patch的kernel: 
    echo 65535 > /sys/class/net/br0/bridge/group_fwd_mask
  2. 官方kernel(最後3位不能爲1):
    echo 65528 > /sys/class/net/br0/bridge/group_fwd_mask

注意 

在生產環境中要慎用這個參數,否則可能造成bridge轉發很多不必要的包造成網絡風暴引起故障或性能下降。但在使用linux搭建虛擬網絡實驗環境時還是非常有用的,可以實現各種協議的模擬。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章