IEEE 802.1D MAC網橋過濾MAC組地址
LACP的協議是使用01-80-C2-00-00-0x范圍內的MAC地址,這個范圍在IEEE標准802.1D中定義為“MAC橋接過濾MAC組地址”。這是IEEE為使用鏈路本地組播與相鄰設備通信的標准協議預留的范圍。使用這些MAC地址的幀應該是顯式鏈接本地的;引用IEEE標准組MAC地址教程:
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 802.1D MAC網橋過濾MAC組地址:01-80- c2 -00-00至01-80-C2-00-00-0F;在此范圍內具有目標MAC地址的MAC幀不會由符合IEEE 802.1的MAC橋接器中繼。
IEEE維護了一個協議列表,如下列表:
| 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) |
實際應用中的問題
任何符合IEEE 802.1的橋接都必須過濾這些幀:要么處理它們,要么刪除它們。在任何情況下,都不允許將它們連同其他接收器一起轉發。這在2000年那時候是有道理的,那時網橋是硬件。但在虛擬化時代,情況就不同了。
比如,我使用基於kvm的主機來模擬多個虛擬網絡設備。我使用Linux網橋來連接這些設備,當然,我希望網橋盡可能像一根電線一樣直接連接我的虛擬設備。不幸的是,Linux橋接器編寫得很好,符合IEEE 802.1,它使用01-80-C2-00-00-0x范圍內的目標地址過濾所有以太網幀。這意味着我不能使用我的虛擬環境來測試上表中的任何協議。悲劇!
解決方法
可是我確實有需求在構建網絡實驗時測試LLDP、LACP、STP、802.1X,所以必須找到一個解決方案。顯然,我不是第一個遇到這種情況的人,所以有一些解決方案。由於Linux內核2.6有一個設置,允許您通過在/sys/class/net/bridge-iface/bridge/group_fwd_mask中設置一個特定的位掩碼,來控制從IEEE 802.1D中定義的橋接器應該轉發的范圍內的哪個本地幀。默認值0表示Linux橋接器不轉發任何鏈接本地幀。例如,將這個值設置為16384將允許橋接轉發LLDP幀(01-80-C2-00-00-0E):
echo 16384 > /sys/class/net/br0/bridge/group_fwd_mask
有個問題是:在默認內核發行版中,前三個MAC地址(-00、-01和-02)的位掩碼值是受限制的,這意味着我們仍然不能使用這個技巧在我們的實驗環境中啟用STP和LACP協議。要刪除這個限制,就需要自己對內核進行補丁並編譯,就像EVE-NG中的人員所做的那樣。為了簡便,所以我只是從EVE-NG存儲庫中獲取編譯后的內核。現在,我們可以將group_fwd_mask設置為我們喜歡的任何值。
group_fwd_mask 掩碼值解析
那么這個位掩碼應該用什么值呢?位掩碼是一個16位的數字,其中第1位代表MAC地址01-80- c2 -00-00,第16位代表01-80-C2-00-00-0F。默認值(所有位都是0)不轉發任何鏈接本地幀。為了能夠轉發特定MAC地址的幀,我們需要將對應的位設置為1。例如,為了允許轉發LLDP幀(01-80-C2-00-00-0E),我們需要將第15位設為1,其余的設為0:
| MAC | 0F | 0E | 0D | 0C | 0B | 0A | 09 | 08 | 07 | 06 | 05 | 04 | 03 | 02 | 01 | 00 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| MAC | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
這意味着我們使用二進制數字0100 0000 0000作為位掩碼,它翻譯成十進制數字16384,就像我們在前面的示例中使用的一樣。
如果我們想在mix中加入LACP (01-80-C2-00-00-02)和802.1X (01-80-C2-00-00-03),我們也會將第3位和第4位設為1:
| MAC | 0F | 0E | 0D | 0C | 0B | 0A | 09 | 08 | 07 | 06 | 05 | 04 | 03 | 02 | 01 | 00 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| MAC | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 |
這導致二進制數0100 0000 0000 1100,在小數中是16396。使用此方法,您現在可以完全控制轉發或篩選哪種類型的幀。
很簡單對不對。對於我的實驗環境,我只想允許盡可能多的協議,這樣我就可以測試任何我想要的協議。所以我把所有的位都設為1:
對於打過補丁的內核,我可以使用所有的位:1111 1111 1111 1111 = 65535
對於未打補丁的內核,我不能使用前三位:1111 1111 1111 1000 = 65528
換句話說:要使開箱即用的Linux橋接器能夠轉發所有經過IEEE 802.1D MAC橋接器過濾的MAC組地址(受限制的三種類型除外),請執行以下命令:
echo 65528 > /sys/class/net/br0/bridge/group_fwd_mask
最后注意
在生產環境中,這可能不是最明智的做法,特別是使用修補過的內核泛洪STP BPDUs時。您最好只將其用於(虛擬)網絡實驗環境。祝你好運!
