Linux中arp表的老化機制


Linux中arp表的老化機制

來源 https://juejin.im/post/6844904166545080334

 

Linux內核網絡協議棧中自動維護着一堆網絡協議,這堆網絡協議在內核中也是不同的存在,對於arp,Linux內核就提供了一種緩存機制來維護這張表。

實際的使用場景是,網絡設備維護的arp表與內核維護的arp表相同步,一旦有變化,便通過鈎子通知到上層的arp模塊。但對於網絡設備的arp模塊來說,還需要實現一個arp老化時間的功能,這個功能的實現便也依靠了linux內核的arp表老化。

內核是如何維護arp表

首先來看內核是如何維護arp表的:

如果調用命令(需要在busybox中編譯):
' ip -s neigh '

可以看到一個完整的arp條目變化的流程。其中有三個計時器,第一個表示到達delay之后的計時,第二個表示到達reachable的計時,第三個表示條目狀態變成stale之后的計時。 對於delay和reachable我們不做多解釋,重要的狀態在於stale。 當條目處於stale狀態時,可能會發現幾個問題,為什么沒有變成delay狀態?為什么過了stale_time,條目還不老化? 先一個一個問題解決。

為什么沒有變成delay狀態?

之所以使用stale狀態,是因為要減少網絡中arp交互的開銷,也就是盡量減少arp交互,但當條目變為stale之后,就說明,使用這個條目是不安全的不確定的。但是如果有應用用到這個條目發包,linux內核仍不進行arp交互,而是設立了一個delay的狀態,在這個狀態的持續過程中,收到了來自鄰居的包,那么說明,此條目可用,則轉為reachable的狀態,如果沒有,那么則會真正的進行arp交互,如果還沒有,那么說明在這個網絡中,此ip已經不對應任何一個mac地址,也沒有必要存在了,置為failed。

所以可見,linux設計這個緩存機制的目的主要有二,一減少arp交互,二減少條目的增加和刪除操作造成的開銷。 第二個問題,為什么過了這個時間還不老化,這也是這一次的主要bug。

首先我們先知道幾個參數的設置:

 

如果一個條目從reachable到老化需要經過多少時間
Timeout =random( base_reachable_time/2,  3*base_reachable_time/2) + gc_stale_time

這個時候,表項將被置為invalid狀態,等待下一個gc時間的到來,回收刪除。

所以問題,看定出在gc的時間。同時我們也得知了,設定老化時間的存在,必然不會非常准確,而是一個大概的值,所需要配置的項就是gc_stale_time。 這時我們留意到:

net.ipv4.neigh.default.gc_thresh1

存在於ARP高速緩存中的最少個數,如果少於這個數,垃圾收集器將不會運行 問題似乎就是在此,默認設置為128條,也就是說當條目大於128時,gc才會工作,只要將此項配置成0,便可以正常的實現arp老化。

當然,其實還是有簡單粗暴的方法,比如當已經過了stale_time狀態時,調用一下

ip neigh flush 

就好了。 其實還是有一個疑問,這個bug在linux4.4中出現,本人使用linux host也是一樣的表現,而其他的使用linux3.6或者更低版本的linux中,只需要配置gc_stale_time便可以實現老化,其他的參數配置完全一致,卻沒有出現不能老化的問題,或許內核版本差異,表項和gc的關系之間存在着不同,或是其他原因,尚未解決。

還記得在在查找資料的過程中,看到的,內核其實已經對維護arp表的存在進行了很多的努力,但是你卻對着這些優化絞盡腦汁,這就有點。。。。。

 

Linux ARP緩存配置和狀態查看命令

https://www.cnblogs.com/yorkwoo/p/4664535.html

  • 查看Linux ARP緩存老化時間

cat /proc/sys/net/ipv4/neigh/eth0/base_reachable_time
同目錄下還有一個文件gc_stale_time,官方解釋如下:
Determines how often to check for stale neighbour entries.
When a neighbour entry is considered stale it is resolved again before sending data to it.
Defaults to 60 seconds.

  • 查看Linux ARP緩存狀態

arp -a    #代碼對應於ioctl(s, SIOCGARP, &arpreq),沒法看到每條緩存的狀態是REACHABLE還是STALE

/isam/slot_1101/run # arp -a
? (135.251.197.136) at 00:19:8f:5f:bd:87 [ether] on eth0
? (135.251.196.1) at 00:e0:b1:ca:5a:48 [ether] on eth0

ip neigh show    #實現上是通過另一種系統調用netlink來獲取的

/proc/sys/net/ipv4/neigh/eth0 # ip neigh
135.251.197.136 dev eth0 lladdr 00:19:8f:5f:bd:87 REACHABLE
135.251.196.1 dev eth0 lladdr 00:e0:b1:ca:5a:48 STALE

  • 應用程序如何觸發arp緩存的添加和刷新呢?

經過一系列測試,結論如下:

執行arping命令,無法添加新的arp緩存。但是可以把STALE的緩存刷新為REACHABLE狀態。

arping有如下選項,是不是我少加了什么選項呢?注釋符#后面的解釋是man命令里面摘過來的。

arping -I eth0 135.251.196.1 -c 10

/isam/slot_default/run # arping -h
arping: invalid option -- 'h'
BusyBox v1.22.1 (2015-07-11 21:41:15 CEST) multi-call binary.

Usage: arping [-fqbDUA] [-c CNT] [-w TIMEOUT] [-I IFACE] [-s SRC_IP] DST_IP

Send ARP requests/replies

-f Quit on first ARP reply    #Finish after the first reply confirming that target is alive.
-q Quiet    #Quiet output. Nothing is displayed.
-b Keep broadcasting, don't go unicast    #Send only MAC level broadcasts. Normally arping starts from sending broadcast, and switch to unicast after reply received.
-D Duplicated address detection mode    #Duplicate address detection mode (DAD). See RFC2131, 4.4.1.  Returns 0, if DAD succeeded i.e. no replies are received    #如果是DAD模式,則原源主機地址一直沒有設置,那么就意味着源地址為0.0.0.0。這樣當目的主機接到之后,就會向0.0.0.0發送回復,就相當於廣播給以太網中所有的主機。因為進行D重復地址檢測模式的原因很可能是由於源主機的IP地址沒有設置,從而想設置自身的IP地址。在IP地址沒有設置的時候,主機只能接受到地址為0.0.0.0的廣播信號。
-U Unsolicited ARP mode, update your neighbors    #Unsolicited ARP mode to update neighbours<80><99> ARP caches.  No replies are expected.    #為了更新以太網鄰居的ARP快速緩存而主動進行的ARP。也就是免費ARP(gratuitous ARP),即請求自己的ip地址的mac地址。
-A ARP answer mode, update your neighbors    #與-U選項類似,但是發送的是ARP 回復報文,而不是ARP請求報文。
-c N Stop after sending N ARP requests
-w TIMEOUT Time to wait for ARP reply, seconds
-I IFACE Interface to use (default eth0)
-s SRC_IP Sender IP address
DST_IP Target IP address

從以上選項可以看出,我們並沒有漏掉什么選項,所以內核就是這么設計的。

還進行過如下測試,Linux shell ping竟然只能添加arp緩存,但是並不能把STALE的緩存刷新為REACHABLE狀態。而且ping是通的,這也說明了STALE還在被引用。

 

============== End

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM