路線新增/刪除後的計時問題(路線未使用)

路線新增/刪除後的計時問題(路線未使用)

我有一個正在運行原始 IP 套接字的應用程序,該套接字的目標由透過“ip route add”命令安裝的路由控制。這些路由可能會在套接字的生命週期內發生變化(例如,因為下一跳會變更)

簡單來說,假設我有 2 個接口,eth0並且eth1.我還有一條預設路由eth0

例如10.10.10.10,原始套接字的端點是 eth1 有位址100.0.0.1,我在原始套接字的生命週期中執行以下操作:

ip -f inet route delete 10.10.10.10
ip -f inet route add 100.0.0.2 dev eth1
ip -f inet route add 10.10.10.10/32 via 100.0.0.2 dev eth1

現在我看到的是,在此操作之後,流量正確通過eth1了幾秒鐘,然後(通過eth0)出現了一小會兒(不到半秒),然後又再次正確了(據我所知,永久) )。

所以我的主要問題是:-任何人都可以解釋這裡可能會出現什麼問題嗎?我嘗試ip route flush cache在前面提到的序列之後添加,但這沒有任何作用。我目前很困惑為什麼流量有時會下降。我認為這要么是路由命令中的計時問題,要么是其他一些觸發器瞬間禁用了路由,但我已經沒有選擇了。

我確實嘗試在原始套接字上使用該SO_BINDTODEVICE選項,但這並沒有多大幫助,主要區別在於,當流量出錯時,它不會被發送出去根本不,因為它會通過錯誤的介面。然而,我希望這會將 errno 設定為 E_CANNOTROUTE 之類的東西(這不存在),這樣我就可以捕獲它並重試發送資料包。它目前不這樣做,但是有沒有辦法我可以捕捉到這樣的失敗?我(幾乎)完全控制系統和運行套接字的應用程式。

我知道可行的一個解決方案是不使用 L3 原始套接字,而是AF_PACKET使用套接字(而且我自己也執行 ARP/ND),但我現在還不想討論這個問題。

更新

透過更改此路線更改行為,我改進了系統中的行為。當我必須更新下一跳時,我現在會查看已安裝的路由並據此採取行動:

  • 如果不存在,我只需安裝新路線並跳過刪除。
  • 如果確切的路線已經存在(相同的 nh,相同的開發),我現在什麼都不做。
  • 如果此路線存在另一個 nh,我現在僅針對此 nh 進行更具體的刪除,然後新增。

雖然這穩定了我的大部分問題,但當實際刪除+添加發生時(新機制中的最後一種情況),我有時仍然會看到同樣的事情發生(儘管頻率要低得多)。另外,這實際上仍然不能解釋出了什麼問題(它只是規避了它),所以我暫時保留這個問題,因為我真的很好奇這裡出了什麼問題。

僅供參考:我在 centos 上遇到了問題,據我所知,從 centos4 到 centos6(32 位元)。

答案1

如果我理解正確,資料包應該始終從 eth1 發出,而您的問題是,當更新到 eth1 上的新下一跳時,您的資料包有時會從 eth0 發出?那是因為您的刪除+新增不是原子操作。

嘗試先執行添加,然後執行刪除。刪除必須是特定的(我相信是設備和下一跳),這樣它就不會刪除您剛剛添加的新路由。

答案2

是否有透過 eth0 的預設路由(或覆蓋 10.10.10.10/32 的其他路由)?如果您先刪除然後添加,則可能會出現競爭條件,其中發生刪除,資料包在刪除和添加之間的時間內離開預設路由,然後添加發生並且資料包開始到達您期望的位置。

對我來說,這絕對聽起來像是某種形式的競爭條件,很可能是由於您提到的兩個路由操作的非原子性質(如 Law29 所述)。

相關內容