天天看點

ebtables的OUTPUT鍊DNAT問題

man一下ebtables即可知道,或者随便想一下也會知道,ebtables在OUTPUT鍊上可以做DNAT,修改目的MAC位址,和iptables一樣,到達OUTPUT鍊的時候已經經過路由表了,隻不過對于橋裝置,該路由表是一個“MAC位址-出口裝置”的映射表。我們知道,IP層的OUTPUT鍊上作了DNAT後需要重新路由,這是IP-DNAT這個target自己完成的,在IP-OUTPUT的鈎子函數中調用了ip_route_me_harder重新路由,然而在鍊路層的BR-OUTPUT中我們沒有發現重新路由的代碼,這樣會有問題嗎?如果做一個實驗,發現這樣是有問題的,一個橋兩個口,分别是1和2,如果本地發出的包準備從2發出,此時發生了DNAT,DNAT的結果目的MAC位于1的那一側,由于沒有重新路由(查找位址-端口映射表),資料幀依然從2發出,啟動了STP的網絡,資料幀将永遠到達不了目的地,這就出了問題了...

    且慢,雖然這是個問題,然而以太網鍊路層的路由和IP路由卻是兩碼事,其機制一點都不一樣,可以說鍊路層的路由是自動學習得到的,其方式就是衆所周知的交換機學習,而IP路由卻是需要顯式配置的,雖然有所謂的動态路由協定,但是還是需要應用層程式的幫助,對于自動學習的表項,它早晚是要收斂的,也就是說即使沒有重新路由,由于鍊路層裝置遵循要麼往特定出口發,要麼泛洪,是以DNAT後的目的位址早晚會被橋裝置學習到的,鍊路層的映射表永遠都處于一種躁動不安的狀态,不像IP路由,一旦有個永久的靜态路由,OUTPUT中執行了DNAT不重新路由就杯具了...

    既然鍊路層可以自動學習映射表,無需人工幫助,那麼BR-OUTPUT之後不打擾這種機制也是必要的,為何要重新路由呢?此時說不定正在泛洪,你再重路由就要重新泛洪,本來在n個口泛洪,每個口執行了DNAT後重路由都可能要再次泛洪...隻要DNAT後的目的裝置發一個包到達橋裝置,就算學習成功了。隻有在DNAT之前和之後永久的位于不同側的時候才會出現不通的問題,如果你的網絡足夠大,啟用了STP,那麼不同時刻兩個位址是否位于同側是不一定的。

    是以,我覺的在泛洪時不重新路由,而不泛洪時重新路由,這樣比較好。

 本文轉自 dog250 51CTO部落格,原文連結:http://blog.51cto.com/dog250/1268993

繼續閱讀