基于Linux的ARP缓存老化时间原理的深入分析
第一.
众所周知,ARP是一种链路层地址解析协议,它以IP地址为键值,查询IP地址主机的MAC地址,协议细节不详细。你可以看到RFC或者读一本教科书。这里是写这篇文章的,主要是做一点记录,也为学生提供了一点思考的方法。具体来说,我遇到了两个问题:
1。简单的热备份系统到虚拟IP地址的使用,但虚拟IP地址属于哪个机基于热备用备用组来决定的,所以主机虚拟IP时,必须首先播放免费ARP,人们并不认为这是不必要的,热待机组工作很好,但事实上,这是必须的;
的2.arp缓存表项都有一个老化的时间,但在Linux系统中没有具体如何设置的老化时间。所以你如何建立这种老化时间的终结
两。回答问题前的解释
ARP协议的规范只给出了地址解析的细节,但不指定如何对协议栈的实现可以保持ARP缓存。ARP高速缓存中需要有一个到期时间,它是必要的,因为ARP不维护缓存映射,没有认证,所以协议本身并不能保证这种映射是永远正确的,它只能保证获取ARP响应时间有效地映射后的。这也给ARP欺骗是一个机会,但本文不讨论这种欺骗。
像Cisco或VRP这样的华为设备有明确的配置来配置ARP缓存的到期时间。然而,有Linux系统中没有这样的配置,但至少没有直接配置。Linux用户知道如果你需要配置系统的接口系统,然后使用sysctl配置工具procfs是一种方法,但是当我们谷歌很长时间,最后发现在/proc /sys / / /网IPv4嘶鸣/ ethX ARP的配置,N档我们最终在目录丢失,即使查询Linux内核文件也不能清楚地了解这些文件的具体含义,对于一个成熟的系统,如Linux,必须有一种方法来配置ARP缓存时间,但如何配置到底如何操作这必须由Linux实现的ARP状态机来说明。
如果你已经读过理解Linux网络内部真正深刻地了解它,这篇文章基本上是胡说八道,但很多人还没有看过这本书,所以这篇文章的内容还是有一定的价值。
linux协议栈的实现维护了ARP缓存的状态机。在了解了具体的行为,我们先看下面的图(图修改理解Linux网络内部,图中每场净胜第二十六章)。
在上面的图中,我们看到,只有ARP缓存项的可达状态是可用于外部数据包,它实际上是不可用的陈旧的ARP高速缓存中的项目。如果有人想在这个时候合同,所以重新分析的需要,对传统的理解,重新分析手段重新发送ARP请求,而实际上并不一定如此,因为Linux加ARP;事件;;不发送ARP请求和优化措施。ARP协议生成的缓存维护。事实上,这项措施是非常有效的。这是ARP 确认的机制,也就是说,如果从一个邻居发送一个数据包到机器的主动权,可以证实,包;一跳;邻居是有效的,但为什么只有机器的到来为了确定对包;在跳;邻居是有效的因为Linux不想给IP层的处理增加负担,也就是说,它不想改变IP层的原始语义。
Linux维护一个陈旧的状态,为了留住一个邻居结构,当其状态的变化,只有个别领域或填充改性。如果一个简单的实现了,只有一个可达状态可以保存,和ARP缓存表项期满后删除。Linux的方法是很多的优化,但如果你绞尽脑汁为这些优化这是一个悲剧。
如何保持三Linux的老化状态
在ARP Linux状态机的实现中,是最复杂的状态,在这个状态下ARP缓存表面临生死选择,选择是本地包,如果本地包使用陈旧的ARP缓存表发送,那么它将提前到延迟状态机状态。如果垃圾收集定时器过期没有使用邻居,那么有可能删除这个条目,删除结束吗因此,看看有没有其他的路径来使用它,关键是查看路由缓存,虽然路由缓存是第三层中的一个概念,但是保留了ARP缓存表下的路由,从这个意义上说,Linux路由缓存是一个转发表而不是路由表。
如果外部使用这个表,然后ARP状态机的进入延迟状态,延迟状态,只要当地的确认到达(当地接收数据包从最后一跳邻居),Linux将不会发送ARP请求,但是如果一直没有地方确认,然后Linux将实际的ARP请求,进入探头的状态。它可以从陈旧的状态,所有的状态只是一种优化措施,对陈旧的ARP缓存的状态是一个缓存,如果Linux是过期的可达状态的ARP缓存条目被删除,语义是相同的,但是认识和理解会更简单!
再次,可达过期为陈旧的状态而不是直接删除,以保护邻近结构,内存和CPU利用率的优化,其实在ARP缓存条目陈旧的状态是不可用的,使它可用,或在当地的延迟状态如定时器确定到期日,TCP收到一个包裹,或延迟状态由于进入探头状态后ARP请求回答。否则,它将被删除。
四、linux ARP缓存实现点
博客中的源代码分析是儿时的记忆,现在它不再是页面的浪费,只要你知道Linux在执行ARP时所维护的几个定时器的要点就可以了。
1、可达状态定时器
每当ARP响应到达时,就启动计时器,或者能够证明ARP表项所表示的邻居是真正可到达的。在配置时间到期时,相应的ARP缓存表项将转换到下一个状态。
2。垃圾收集定时器
定时计时器开始,下一次是什么原因,是基于对base_reachable_time配置来确定,具体请看下面的代码:
复制代码代码如下所示:
静态neigh_periodic_timer(unsigned long Arg)
{
…
如果(time_after(现在,TBL -> last_rand + 300 *赫兹)){ / /内核每5分钟再次配置
结构neigh_parms * P;
TBL -> last_rand =现在;
为(P = TBL ->参数;P;P = P - >下)
P > reachable_time =
neigh_rand_reach_time(P>base_reachable_time);
}
…
循环所有哈希桶 / / 2个base_reachable_time蜱。
* ARP超时范围从1 / 2到3 / 2 base_reachable_time
* base_reachable_time。
* /
过期= TBL -> parms.base_reachable_time > > 1;
/ =到期(TBL -> hash_mask + 1);
如果(!过期)
到期= 1;
下一次当由于 / /完全基于base_reachable_time);
mod_timer(TBL -> gc_timer,现在+过期);
…
}
静态neigh_periodic_timer(unsigned long Arg)
{
…
如果(time_after(现在,TBL -> last_rand + 300 *赫兹)){ / /内核每5分钟再次配置
结构neigh_parms * P;
TBL -> last_rand =现在;
为(P = TBL ->参数;P;P = P - >下)
P > reachable_time =
neigh_rand_reach_time(P>base_reachable_time);
}
…
循环所有哈希桶 / / 2个base_reachable_time蜱。
* ARP超时范围从1 / 2到3 / 2 base_reachable_time
* base_reachable_time。
* /
过期= TBL -> parms.base_reachable_time > > 1;
/ =到期(TBL -> hash_mask + 1);
如果(!过期)
到期= 1;
下一次当由于 / /完全基于base_reachable_time);
mod_timer(TBL -> gc_timer,现在+过期);
…
}
时间一到,该neigh_periodic_timer回调函数执行以下逻辑,即省略部分以上。
复制代码代码如下所示:
如果(atomic_read(n>refcnt) / / N - >用= = 5月1日是由于地方机制和推进确认;
(状态= = nud_failed | | time_after(现在,N ->参数-> gc_staletime){ n ->用+))
*下一步;
死亡= 1;
write_unlock(n>锁);
neigh_release(N);
继续;
}
如果(atomic_read(n>refcnt) / / N - >用= = 5月1日是由于地方机制和推进确认;
(状态= = nud_failed | | time_after(现在,N ->参数-> gc_staletime){ n ->用+))
*下一步;
死亡= 1;
write_unlock(n>锁);
neigh_release(N);
继续;
}
如果在实验中没有及时删除过期状态中的表项,请尝试执行以下命令:
{平}查看plaincopyprintip路由刷新缓存
IP路由刷新缓存,然后看看结果是所有IP嘶鸣。注意不要期望立即删除,因为垃圾收集计时器还没有过期,但我可以向您保证,缓存项将在很长一段时间后被删除。
五。第一个问题的解
当简单的基于VRRP热备份组启用,许多学生认为不需要重新绑定自己的MAC地址和虚拟IP地址进入主人的状态,但它从根本上是错误的,如果没有问题,说什么这是幸运的,因为每个路由器ARP超时时间,默认的配置是很短的,但我们不能依靠这个配置。请看下图:
如果有对ARP路由器缓存超时时间开关是1小时,所以在近一个小时,单向通信(假设数据不会在组主机不发送数据通过路由器,从地方;确认;毕竟,我不知道如果路由器不在操作上的路由器,Linux)的数据将继续原来的主人的方法,但原来的主人已经不再是一个虚拟的IP地址。
因此,为了使数据的行为不再依赖路由器的配置,需要手动绑定虚拟IP地址和MAC地址转换时掌握VRRP协议下。的arping是易于使用的Linux是:
{平}查看plaincopyprintarping我ethX的1.1.1.1 B C 1
我的arping ethX 1.1.1.1 B C 1作为一个结果,1.1.1.1的IP地址的主机的IP地址为255.255.255.255 ARP请求广播到整个网络,路由器运行Linux,路由器收到ARP请求根据源IP地址将更新其本地ARP缓存表(如果有)。然而,修正结果的状态是陈旧的,这仅仅是ARP协议的规定,具体体现在代码的功能上arp_process:
复制代码代码如下所示:
如果(ARP -> ar_op!= htons(arpop_reply)| | skb -> pkt_type!= packet_host)
状态= nud_stale;
neigh_update(n,沙,状态,覆盖neigh_update_f_override:0);
如果(ARP -> ar_op!= htons(arpop_reply)| | skb -> pkt_type!= packet_host)
状态= nud_stale;
neigh_update(n,沙,状态,覆盖neigh_update_f_override:0);
可以看出,只有当实际外包的下一跳是1.1.1.1,它会通过确认当地或发送ARP请求机制的方式将地图对应的MAC地址的可达状态。
修正:在阅读简单的源代码,这种担心是多余的,毕竟,简单的已经很成熟了,不应该犯这样的错误的简单的,在主开关的主人,会主动发送免费ARP在简单的代码:
复制代码代码如下所示:
vrrp_send_update(vrrp_rt * VRRP,ip_address * IP地址,int idx)
{
字符*;
焦addr_str { 41 };
如果(!ip_is6(IP地址)){
味精=无偿Arps ;
inet_ntop(af_inet,IP地址-> u.sin.sin_addr,addr_str,41);
send_gratuitous_arp(IP地址);
{人}
未经请求的邻居广告;
inet_ntop(af_inet6,IP地址-> u.sin6_addr,addr_str,41);
ndisc_send_unsolicited_na(IP地址);
}
如果(0 IDX调试= = 32){
log_message(log_info,vrrp_instance(%s)发送%s %s %s
VRRP -> iName,味精,if_name(IP地址-> IFP),addr_str);
}
}
vrrp_send_update(vrrp_rt * VRRP,ip_address * IP地址,int idx)
{
字符*;
焦addr_str { 41 };
如果(!ip_is6(IP地址)){
味精=无偿Arps ;
inet_ntop(af_inet,IP地址-> u.sin.sin_addr,addr_str,41);
send_gratuitous_arp(IP地址);
{人}
未经请求的邻居广告;
inet_ntop(af_inet6,IP地址-> u.sin6_addr,addr_str,41);
ndisc_send_unsolicited_na(IP地址);
}
如果(0 IDX调试= = 32){
log_message(log_info,vrrp_instance(%s)发送%s %s %s
VRRP -> iName,味精,if_name(IP地址-> IFP),addr_str);
}
}
六。第二题的解法
那么,如何在Linux上设置ARP缓存的老化时间呢
我们看到一些文件 /过程/系统/网络/网络/马嘶/ ethX目录下,这是老化时间的ARP缓存事实上,直接点是base_reachable_time文件。其他的只是优化措施的行为。例如,文件记录的gc_stale_time 缓存ARP缓存表;生存时间,时间只是一个缓存的时间,生存时间,如果你需要使用的邻居,然后直接用表格记录数据的ARP请求或内容可以得到;确认的可达状态后,直接,但不是由路由搜索,搜索了ARP ARP ARP,邻居邻居解析这种缓慢的方式。
默认情况下,可达超时是30秒,超过30秒,ARP缓存表将变为陈旧,这时,您可以想到表已经到期,只有Linux的实现没有删除它。gc_stale_time时间后,被删除的项目。ARP进入到达后,垃圾收集器负责实施gc_stale_time;后,被删除表;这件事,下一次定时器到期时间是根据base_reachable_time计算,这是neigh_periodic_timer:
复制代码代码如下所示:
如果(time_after(现在,TBL -> last_rand + 300 *赫兹)){
结构neigh_parms * P;
TBL -> last_rand =现在;
为(P = TBL ->参数;P;P = P - >下)
用计划很重要,要防止共振行为;ARP分析风暴引发的
P > reachable_time = neigh_rand_reach_time(P>base_reachable_time);
}
…
过期= TBL -> parms.base_reachable_time > > 1;
/ =到期(TBL -> hash_mask + 1);
如果(!过期)
到期= 1;
mod_timer(TBL -> gc_timer,现在+过期);
如果(time_after(现在,TBL -> last_rand + 300 *赫兹)){
结构neigh_parms * P;
TBL -> last_rand =现在;
为(P = TBL ->参数;P;P = P - >下)
用计划很重要,要防止共振行为;ARP分析风暴引发的
P > reachable_time = neigh_rand_reach_time(P>base_reachable_time);
}
…
过期= TBL -> parms.base_reachable_time > > 1;
/ =到期(TBL -> hash_mask + 1);
如果(!过期)
到期= 1;
mod_timer(TBL -> gc_timer,现在+过期);
多好的地方啊!正确的话,我们可以通过查看代码注释来理解这一点,好的人会写注释。为了清晰的实验,我们设计了以下两个场景:
1。使用iptables禁止所有本地接收,从而屏蔽ARP局部确认,使用sysctl设置base_reachable_time 5秒和5秒gc_stale_time。
2、关闭iptables的封禁政策,使用TCP下载到外部网络的一个额外的大文件,或继续使用短连接,base_reachable_time sysctl设置为5秒,5秒,gc_stale_time。
在两种情况下默认网关ping局域网使用ping命令,然后迅速下降的Ctrl-C平,IP又显示所有ARP可以看到一个默认网关,但是在1个场景,约5秒后将ARP过时不再变化,然后平。首先,延迟到探针台,然后到达,5秒再次变得陈旧,而在2幕,为到达和延迟ARP表,说明ARP协议状态机在Linux。所以,在方案1中,不会被删除,很长一段时间,当表项会变得陈旧实际上,这是因为有一个路由缓存项使用它,当删除路由缓存时,ARP表项很快被删除。
七。总结
1。在Linux如果你要设置你的ARP缓存老化时间,然后sysctl - W网。IPv4。嘶叫。ethX = Y只能设置如果其他影响性能,在Linux,其老化的ARP缓存的过期状态为准,而不是列表项被删除的标准,陈旧的缓存和缓存;
2。永远记住,在一个IP地址换到另一台网络设备,尽快免费Linux ARP广播,你可以用arping恶作剧。