I’m working on a blog post explaining route type 5 in EVPN. To demonstrate a scenario with a silent host, I want to simulate this behavior. Normally, hosts can be quite chatty and ARP for their GW, for example. In this post I will show how arptables on Linux can be used to simulate a silent host.
Currently the leaf switch has an ARP entry for the host:
Leaf4# show ip arp vrf Tenant1 Flags: * - Adjacencies learnt on non-active FHRP router + - Adjacencies synced via CFSoE # - Adjacencies Throttled for Glean CP - Added via L2RIB, Control plane Adjacencies PS - Added via L2RIB, Peer Sync RO - Re-Originated Peer Sync Entry D - Static Adjacencies attached to down interface IP ARP Table for context Tenant1 Total number of entries: 1 Address Age MAC Address Interface Flags 198.51.100.44 00:15:20 0050.56ad.7d68 Vlan10
It is possible to ping the host from the leaf switch:
Leaf4# ping 198.51.100.44 vrf Tenant1 PING 198.51.100.44 (198.51.100.44): 56 data bytes 64 bytes from 198.51.100.44: icmp_seq=0 ttl=63 time=1.355 ms 64 bytes from 198.51.100.44: icmp_seq=1 ttl=63 time=0.687 ms 64 bytes from 198.51.100.44: icmp_seq=2 ttl=63 time=0.733 ms 64 bytes from 198.51.100.44: icmp_seq=3 ttl=63 time=0.714 ms 64 bytes from 198.51.100.44: icmp_seq=4 ttl=63 time=0.709 ms --- 198.51.100.44 ping statistics --- 5 packets transmitted, 5 packets received, 0.00% packet loss round-trip min/avg/max = 0.687/0.839/1.355 ms
It is also possible to ping this host from another network:
server2:~$ ping 198.51.100.44 PING 198.51.100.44 (198.51.100.44) 56(84) bytes of data. 64 bytes from 198.51.100.44: icmp_seq=1 ttl=62 time=5.02 ms 64 bytes from 198.51.100.44: icmp_seq=2 ttl=62 time=5.26 ms 64 bytes from 198.51.100.44: icmp_seq=3 ttl=62 time=5.38 ms ^C --- 198.51.100.44 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2003ms rtt min/avg/max/mdev = 5.024/5.221/5.379/0.147 ms
The idea with using arptables is to only allow responses to ARP requests out, but not ARP requests. In theory, this should keep server4 (198.51.100.44) from generating any traffic unless it was initiated from another host. The following is implemented using arptables:
sudo arptables -A OUTPUT --out-interface ens160 --opcode 1 -j DROP
Let’s check the current ruleset:
sudo arptables -L Chain INPUT (policy ACCEPT) Chain OUTPUT (policy ACCEPT) -j DROP -o ens160 --opcode Request
The server has the current ARP cache:
ip neighbor | grep 198.51 198.51.100.1 dev ens160 lladdr 00:01:00:01:00:01 STALE 198.51.100.11 dev ens160 lladdr 00:50:56:ad:85:06 STALE
Let’s clear these entries:
sudo ip neighbor flush dev ens160
Then let’s try to ping the gateway:
ping 198.51.100.1 PING 198.51.100.1 (198.51.100.1) 56(84) bytes of data. From 198.51.100.44 icmp_seq=1 Destination Host Unreachable From 198.51.100.44 icmp_seq=2 Destination Host Unreachable From 198.51.100.44 icmp_seq=3 Destination Host Unreachable ^C --- 198.51.100.1 ping statistics --- 4 packets transmitted, 0 received, +3 errors, 100% packet loss, time 3077ms
This does not work. Let’s try to ping the host from the leaf:
Leaf4# ping 198.51.100.44 vrf Tenant1 PING 198.51.100.44 (198.51.100.44): 56 data bytes Request 0 timed out Request 1 timed out Request 2 timed out Request 3 timed out ^C --- 198.51.100.44 ping statistics --- 5 packets transmitted, 0 packets received, 100.00% packet loss
No good! Why is that? The leaf already has the MAC of the host in it’s ARP cache:
Leaf4# show ip arp vrf Tenant1 Flags: * - Adjacencies learnt on non-active FHRP router + - Adjacencies synced via CFSoE # - Adjacencies Throttled for Glean CP - Added via L2RIB, Control plane Adjacencies PS - Added via L2RIB, Peer Sync RO - Re-Originated Peer Sync Entry D - Static Adjacencies attached to down interface IP ARP Table for context Tenant1 Total number of entries: 1 Address Age MAC Address Interface Flags 198.51.100.44 00:05:50 0050.56ad.7d68 Vlan10
Because of this, the leaf will not send an ARP request for the host and the host will not learn the MAC of the SVI on the leaf. Let’s clear the ARP cache on the leaf:
Leaf4# clear ip arp vrf Tenant1
Then let’s try the ping again:
Leaf4# ping 198.51.100.44 vrf Tenant1 PING 198.51.100.44 (198.51.100.44): 56 data bytes 64 bytes from 198.51.100.44: icmp_seq=0 ttl=63 time=1.265 ms 64 bytes from 198.51.100.44: icmp_seq=1 ttl=63 time=0.622 ms 64 bytes from 198.51.100.44: icmp_seq=2 ttl=63 time=0.711 ms 64 bytes from 198.51.100.44: icmp_seq=3 ttl=63 time=0.626 ms 64 bytes from 198.51.100.44: icmp_seq=4 ttl=63 time=0.707 ms --- 198.51.100.44 ping statistics --- 5 packets transmitted, 5 packets received, 0.00% packet loss round-trip min/avg/max = 0.622/0.786/1.265 ms
That worked nicely! Let’s verify that the host has the leaf MAC address in its ARP cache:
ip neighbor show | grep 198 198.51.100.1 dev ens160 lladdr 00:01:00:01:00:01 PROBE
One thing to highlight here is that the host will probe for the MAC so the entry only remains in the cache for a very limited amount of time, around five seconds:
ip neighbor show | grep 198 198.51.100.1 dev ens160 FAILED
The relevant timer for this is found in the manual of arp:
delay_first_probe_time (since Linux 2.2) Delay before first probe after it has been decided that a neighbor is stale. Defaults to 5 seconds.
This timer can be changed if you want it to stay longer in the ARP cache.
Finally, when you clear ARP cache on NX-OS, if you want to just clear the entry and not have an ARP request sent out, use force-delete
:
Leaf4# clear ip arp vrf Tenant1 ? <CR> force-delete Clear the entries from ARP table without refresh
I have now cleared the cache:
Leaf4# clear ip arp vrf Tenant1 force-delete Leaf4# show ip arp vrf Tenant1 Flags: * - Adjacencies learnt on non-active FHRP router + - Adjacencies synced via CFSoE # - Adjacencies Throttled for Glean CP - Added via L2RIB, Control plane Adjacencies PS - Added via L2RIB, Peer Sync RO - Re-Originated Peer Sync Entry D - Static Adjacencies attached to down interface IP ARP Table for context Tenant1 Total number of entries: 0 Address Age MAC Address Interface Flags Leaf4#
My host will now remain silent as long as I have the arptables filter implemented.
In this post we learned that hosts are normally chatty and try to ARP for their gateway and to refresh entries that are in the ARP cache. By using arptables it’s possible to filter outgoing requests, but still allow responses. This simulates a host being silent or shy, which can be an interesting experiment, especially in a VXLAN network.
Hello Daniel,
Thanks for the great post.
When you say host are really chatty, so do the hosts sends arp requests automatically to its default gateway even though th host is not initiating any traffic?
It will vary, but if a host has learned the MAC of its gateway before then there is generally some ARP probing going on to verify if that MAC is still reachable. It will also depend on how your NICs are setup. For example, a Windows machine with single NIC will guaranteed be generating a lot of background noise. Checking for updates, mDNS, and other stuff. Linux is generally more quiet, though.
Some silent hosts (I won’t name them) will not reply to ARP requests. They will only request the MAC address of the gateway via ARP when they need to communicate to some server and then remain silent. It might be useful to explore that kind of scenario.