I am trying to do a test where I forward ICMP responses to a TAP interface. I created a TAP interface and assigned it the address

My linux setup uses the interface enp0s3 as the default option. To forward any ICMP response to the TAP interface, I tried the following rules:

# iptables -t nat -A PREROUTING -i enp0s3 -p icmp -j DNAT --to
# iptables -A FORWARD -p icmp -i enp0s3 -j ACCEPT
# iptables -t nat -A POSTROUTING -o -j MASQUERADE

At the moment, the TAP interface is in UP state, and I have a program which is listening to the TAP interface.

If I ping an external IP like, the ping program is still able to get the response. I want to ask shouldn't the ping program not receive any response because ICMP response is getting forwarded to the TAP interface ? Also, is my approach to redirect traffic to the TAP device correct ?


The IP assigned to the TAP interface belongs to the host, so is a local IP. Example:

# ip -4 address show tap0
20: tap0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000
    inet scope global tap0
       valid_lft forever preferred_lft forever
# ip route get
local dev lo src uid 0 
    cache <local> 

What does matter is the route to the TAP interface. That is, because of the implicit route added when the interface is brought up, any IP in except

# ip route get dev tap0 src uid 0 

So if you want your program to actually see any traffic, try replacing in your rules with for example It's up to the attached program to actually reply from this IP if that's the goal (and if using tap rather than tun, reply to ARP as well).

Other notes:

  • you made a typo in the last rule it's a destination address so -d rather than -o. It's up to you to choose to MASQUERADE the source at all, it's not needed to route the packet to the program and have a (correct) reply sent back to the initial source.
  • it's not clear if you're actually involving an other peer to do the test. Doing the test from the host itself would not require nat/PREROUTING and filter/FORWARD but nat/OUTPUT and filter/OUTPUT.
  • If an other peer was indeed involved, as it was, your test would have been using filter/INPUT rather than filter/FORWARD and not using nat/POSTROUTING, since the destination is local. Anyway once corrected it would be using filter/FORWARD and nat/POSTROUTING.
  • if using tap (layer 2: ethernet) rather than tun (layer3: ip), when looking for this icmp (with tcpdump or in the attached program) and not seing it, look also for unanswered ARP requests.

Further reference: https://backreference.org/2010/03/26/tuntap-interface-tutorial/

  • Since the ICMP response is coming from outside, I think the bullet 2 in your response doesn't apply; I think I need to follow bullet 3 (am I accurate ?). I changed the NAT PREROUTING rule to and the rule doesn't get hit. But at the same time if add a simple mangle PREROUTING (say to change a header field just for test), that rule gets hit. Why does a mangle rule for PREROUTING get used while a nat rule does not ? Thanks for your time. – Jake Mar 26 '19 at 16:27
  • I found another diagram stuffphilwrites.com/wp-content/uploads/2018/11/…. I think since NAT PREROUTING is not getting hit, that means the localhost source ? resulted in a yes decision. But I still don't get why that is the case as the the source of the ICMP response is the external IP address ? – Jake Mar 26 '19 at 16:40
  • Indeed bullet 2 is only if the test is done from the host itself and won't apply from elsewhere. The only way to be sure about your other issue is if you edit your question and add the complete test you were doing. I did a few tests on my own before answering.Minor problems are often hidden in details that require data. Probably the best chart would be en.wikipedia.org/wiki/Netfilter#/media/… – A.B Mar 26 '19 at 18:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.