I. As we all know, ARP is a link layer Address Resolution Protocol, which uses the IP address as the key value to query the MAC address of the host with this IP address. The details of the Protocol are not detailed. you can read RFC or textbooks. This article mainly aims to make some records and provide some ideas for the students. Specifically, I have met two
I. As we all know, ARP is a link layer Address Resolution Protocol, which uses the IP address as the key value to query the MAC address of the host with this IP address. The details of the Protocol are not detailed. you can read RFC or textbooks. This article mainly aims to make some records and provide some ideas for the students. Specifically, I have encountered two problems: 1. the system that uses keepalived for hot backup requires a virtual IP address. however, which machine the virtual IP address belongs to depends on the master and backup of the hot backup group, therefore, when the host obtains the virtual IP address, it must broadcast a free arp. at first, people thought this was unnecessary because it was not necessary to do so, and the hot standby group also worked well, however, it turns out that this is necessary; 2. ARP cache table items have an aging time, but in linux, it does not show how to set the aging time. So how can we set this aging time?
II. The preceding explanation only describes the details of address resolution, but does not specify how to maintain the ARP cache for the implementation of the protocol stack. The ARP cache requires an expiration time. this is necessary because the ARP cache does not maintain the ing status or perform authentication. Therefore, the protocol itself cannot guarantee that this ING is always correct, it can only ensure that the ING is valid for a certain period of time after obtaining the arp response. This also gives ARP spoofing an opportunity, but this is not discussed in this article.
Huawei devices such as Cisco or VRP have clear configurations to configure the arp cache Expiration Time. However, such a configuration is not available in Linux systems. at least it can be said that there is no such direct configuration. Linux users know what system behavior to configure, so using sysctl tool to configure the sys interface under procfs is a method. However, when we google for a long time, finally, we found that when the ARP configuration was in/proc/sys/net/ipv4/neigh/ethX, we were confused about N files in the directory, even if you query the Linux kernel's Documents, you cannot clearly understand the specific meanings of these files. For a mature system like Linux, you must have a way to configure the expiration time of the ARP Cache. but how do you configure it? This should start with the ARP state machine implemented in Linux.
If you have read Understading Linux NetworkingInternals and have a deep understanding of it, this article is basically nonsense, but many people have not read this book, therefore, the content of this article is of some value.
The implementation of the Linux protocol stack maintains a state machine for the ARP Cache. before understanding specific behaviors, first look at the following figure of the listener (this figure is modified based on-13 in UnderstadingLinux Networking Internals, in chapter 2 ):
In, we can see that only the reachable status of arp cache items is available for outgoing packets. for arp cache items in the stale status, it is actually unavailable. If someone wants to send a packet at this time, it needs to be re-parsed. for general understanding, re-parsing means re-sending the arp request, but in fact it is not necessarily the case, linux adds an "event point" for arp to "do not send arp requests" and optimizes the cache maintenance measures generated by arp. In fact, this measure is very effective. This is arp's "validation" mechanism. that is to say, if a packet is sent from a neighbor to the local machine, it can be confirmed that the "last hop" neighbor of the packet is valid, however, why can the "last hop" neighbor be confirmed only when the package arrives at the local machine? Because Linux does not want to increase the burden on the IP layer processing, that is, it does not want to change the original semantics of the IP layer.
Linux maintains a stale state to keep a neighbor structure. when the state changes, only individual fields are modified or filled. If you follow the simple implementation, only one reachable state can be saved, and when it expires, the arp cache table item will be deleted. Linux has only been optimized a lot, but if you have racked your brains for these optimizations, it will be a tragedy ......
3. How does Linux maintain the stale state in the ARP state machine implemented by Linux? the most complicated is the stale state. in this state, arp cache table items are faced with a life-and-death decision, the attacker is the local package. if the local package uses the arp cache table entry in the stale state, the state machine is pushed to the delay state, if no one uses this neighbor after the "garbage collection" timer expires, it is possible to delete this table item. Are you sure you want to delete it? In this way, we can see that there are other paths to use it. The key is to look at the routing cache. Although the routing cache is a layer-3 concept, it retains the next ARP cache table item of the route, in this sense, the Linux route cache is actually a forwarding table instead of a route table.
If an external packet uses this table item, the ARP state machine of this table item will enter the delay state, in the delay state, as long as there is a "local" confirmation (the last hop of the local receiving package comes from this neighbor), linux still does not send ARP requests, but if there is no local confirmation, then Linux will send a real ARP request and enter the probe status. Therefore, we can see that from the stale status, all statuses exist only for an optimization measure. the ARP cache table entry in the stale status is a cache, if Linux only deletes expired arp cache table items in the reachable state, the meaning is the same, but the implementation looks and understands much easier!
Again, it is emphasized that the reachable enters the stale state after expiration instead of directly deleting it. it is used to reserve the neighbor structure, optimize memory and CPU utilization, and in fact it is unavailable when the arp cache table entry enters the stale state, to make it available, either a local confirmation is made before the delay status timer expires. for example, if tcp receives a packet or the delay status expires and enters the probe status, the arp request is responded. Otherwise it will be deleted.
4. Linux's ARP cache implementation points: analyzing the source code in the blog is a childhood memory, and now it is no longer a waste of layout. You only need to know the key points of the timer that Linux maintains when implementing arp.
1. the Reachable status timer starts whenever an arp response arrives or another neighbor that can prove that the ARP table entry is actually available. The corresponding ARP cache table entry is converted to the next state at the expiration time based on the configured time.
2. the garbage collection timer regularly starts the timer. the specific next expiration time depends on the configured base_reachable_time. for details, see the following code: [cpp] view plaincopy static void neigh_periodic_timer (unsigned longarg)
{......
If (time_after (now, tbl-> last_rand + 300 * HZ) {// re-configure struct neigh_parms * p every 5 minutes; tbl-> last_rand = now; for (p = & tbl-> parms; p = p-> next)
P-> reachable_time = neigh_rand_reach_time (p-> base_reachable_time );}......
/* Cycle through all hash buckets every base_reachable_time/2ticks. * ARP entry timeouts range from 1/2 base_reachable_time to3/2 * base_reachable_time. */expire = tbl-> parms. base_reachable_time> 1; expire/= (tbl-> hash_mask + 1); if (! Expire)
Expire = 1; // The next expiration time is based entirely on base_reachable_time); mod_timer (& tbl-> gc_timer, now + expire );......
} Once the timer expires, the neigh_periodic_timer callback function will be executed, which contains the following logic, that is, the above ...... Omitted part: [cpp] view plaincopy if (atomic_read (& n-> refcnt) = 1 & // n-> used may be pushed forward due to the local validation mechanism (state = NUD_FAILED | time_after (now, n-> used + n-> parms-> gc_staletime) {* np = n-> next; n-> dead = 1; write_unlock (& n-> lock ); neigh_release (n); continue ;}
If your table item in the stale state is not deleted in time in the experiment, try to execute the following command: [plain] viewplaincopy ip route flush cache and then check the result of ip neigh lsall. Note that you should not expect it to be deleted immediately because the garbage collection timer has not expired yet ...... However, I can assure that after a short time, the cached table item will be deleted.
5. The solution to the first problem is to enable keepalived for vrrp-based hot backup groups. many people think that they do not need to re-bind their MAC address and virtual IP address when entering the master status, however, this is a fundamental error. if there is no problem, it is also lucky because the default arp timeout time configured on each vro is generally very short. However, we cannot rely on this configuration. See the following figure:
If a switchover occurs, assuming that the arp cache timeout on the vro is one hour, one-way data cannot be communicated within nearly one hour (assuming that the hosts in the group do not send data through the vro, after all, I don't know if the vro is running Linux.) the data on the vro will be continuously transferred to the original master, however, the original matser no longer holds the virtual IP address.
Therefore, in order to make the data behavior no longer dependent on the vro configuration, you must manually bind the virtual IP address and your MAC address when switching to the master node under vrrp protocol. in Linux, the convenient arping is: [plain] view plaincopy arping-I ethX-S 1.1.1.1-B-c1. in this way, the master host with the IP address 1.1.1.1 broadcasts ARP requests with the IP address 255.255.255.255 to the whole network, if the vroarp runs Linux, the vroarp will update its local ARP cache table (if any) based on the source IP address after receiving the ARP Request. However, the problem is, the update result status of this table item is stale, which is only the specification of ARP, which is embodied in the code. at the end of the arp_process function: [cpp] view plaincopy if (arp-> ar_op! = Htons (ARPOP_REPLY) | skb-> pkt_type! = PACKET_HOST)
State = NUD_STALE; neigh_update (n, sha, state, override? NEIGH_UPDATE_F_OVERRIDE: 0); it can be seen that only when the next hop of the actual outbound packet is 1.1.1.1, then, the corresponding MAC address is mapped to the reachable status through the local confirmation mechanism or the actual ARP request.
Sat. The second problem is solved so much. in Linux, how do I set the ARP cache aging time?
We can see that the/proc/sys/net/ipv4/neigh/ethX directory contains multiple files. which one is the ARP cache aging time? In fact, it is the file base_reachable_time. Others are just measures to optimize the behavior. For example, the gc_stale_time file records the survival time of the "ARP cache table item cache". this time is only the cache survival time. during this time, if you need to use this neighbor, you can directly use the data recorded in the table item as the content of the ARP request, or directly set it to reachable after obtaining the "local confirmation, instead of using route lookup, ARP lookup, ARP neighbor creation, and ARP neighbor parsing.
By default, the timeout value of the reachable state is 30 seconds. after 30 seconds, the ARP cache table entry is changed to the stale state. at this time, you can think that the table entry has expired, it is only in Linux that the table item is deleted after gc_stale_time. After the ARP cache table item is non-reachable, the garbage collector is responsible for executing the "delete the table item after gc_stale_time" operation, the next expiration time of this timer is calculated based on base_reachable_time, specifically in neigh_periodic_timer: [cpp] view plaincopy if (time_after (now, tbl-> last_rand + 300 * HZ )) {struct neigh_parms * p; tbl-> last_rand = now; for (p = & tbl-> parms; p = p-> next)
// It is very important to compile the program on demand to prevent ARP parsing storms caused by "resonance behavior". p-> reachable_time = neigh_rand_reach_time (p-> base_reachable_time );}......
Expire = tbl-> parms. base_reachable_time> 1; expire/= (tbl-> hash_mask + 1); if (! Expire)
Expire = 1; mod_timer (& tbl-> gc_timer, now + expire );
This is evident! As appropriate, we can understand this by reading the code comments, and all the good guys will write comments. To make the experiment clear, we design the following two scenarios: 1. useIptablesDisable local reception to block local arp Confirmation. use sysctl to set base_reachable_time to 5 seconds and gc_stale_time to 5 seconds.
2. disable the iptables prohibiting policy. use TCP to download a large file from the external network or perform persistent short connections. use sysctl to set base_reachable_time to 5 seconds and gc_stale_time to 5 seconds.
In both scenarios, use the ping command to ping the default gateway of the local LAN, and then quickly press Ctrl-C to drop the ping. use the ip neighshowall to view the arp table items of the default gateway, however, in Scenario 1, the arp table entry changes to stale in about five seconds, and then the table entry changes to delay, probe, and reachable after ping, in five seconds, it becomes stale again. in scenario 2, arp table items continue to be reachable and dealy, which shows the ARP state machine in Linux. In Scenario 1, when the table item becomes stale, it will not be deleted for a long time? In fact, this is because a route cache item is still in use. after you delete the route cache, the arp table item is quickly deleted.
7. Conclusion 1. in Linux, if you want to set the aging time of your ARP cache, run sysctl-wnet. ipv4.neigh. ethX = Y. If you set anything else, it only affects the performance. in Linux, ARP cache aging is subject to the change to stale status, rather than the deletion of its table items, the stale status only caches the cache. 2. always remember to broadcast free ARP as quickly as possible when you replace an IP address with another local network segment device. you can use arping on Linux for tips.