I'm having trouble communicating with my virtual tap devices via ipv6. Essentially ping6 -I eth0 <tap interface link-local ipv6 address> doesn't return anything. I can't even ping the host-facing endpoint of the tap:

[user ~]$ ping6 -I eth0 fe80::88a2:f6ff:fe6f:90cb
PING fe80::88a2:f6ff:fe6f:90cb(fe80::88a2:f6ff:fe6f:90cb) from fe80::4f3:9ff:fec9:2032%eth0 eth0: 56 data bytes
--- fe80::88a2:f6ff:fe6f:90cb ping statistics ---
8 packets transmitted, 0 received, 100% packet loss, time 7162ms

and the tcpdump output from eth0:

20:54:00.658849 IP6 (flowlabel 0x1efcb, hlim 64, next-header ICMPv6 (58) payload length: 64) fe80::4f3:9ff:fec9:2032 > fe80::88a2:f6ff:fe6f:90cb: [icmp6 sum ok] ICMP6, echo request, seq 1
20:54:01.673920 IP6 (flowlabel 0x1efcb, hlim 64, next-header ICMPv6 (58) payload length: 64) fe80::4f3:9ff:fec9:2032 > fe80::88a2:f6ff:fe6f:90cb: [icmp6 sum ok] ICMP6, echo request, seq 2
20:54:02.698029 IP6 (flowlabel 0x1efcb, hlim 64, next-header ICMPv6 (58) payload length: 64) fe80::4f3:9ff:fec9:2032 > fe80::88a2:f6ff:fe6f:90cb: [icmp6 sum ok] ICMP6, echo request, seq 3
20:54:03.722004 IP6 (flowlabel 0x1efcb, hlim 64, next-header ICMPv6 (58) payload length: 64) fe80::4f3:9ff:fec9:2032 > fe80::88a2:f6ff:fe6f:90cb: [icmp6 sum ok] ICMP6, echo request, seq 4
20:54:04.745974 IP6 (flowlabel 0x1efcb, hlim 64, next-header ICMPv6 (58) payload length: 64) fe80::4f3:9ff:fec9:2032 > fe80::88a2:f6ff:fe6f:90cb: [icmp6 sum ok] ICMP6, echo request, seq 5

And as expected with the error the tcpdump from the tap device interface is empty. I'm able to ping eth0 from itself. I'm unable to ping eth0 from the tap interface w/ error connect: Network is unreachable. However, this is a separate issue I believe as tcpdump indicates the pings aren't even reaching the tap device in the first place.

Here's my network setup

[user ~]$ ifconfig eth0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 9001
        inet  netmask  broadcast
        inet6 2600:1f14:XXXX:XXXX:e134:ff0c:cccd:b262  prefixlen 128  scopeid 0x0<global>
        inet6 fe80::4f3:9ff:fec9:2032  prefixlen 64  scopeid 0x20<link>
        ether 06:f3:09:c9:20:32  txqueuelen 1000  (Ethernet)

[user ~]$ ifconfig tp-0ge-0000gf-0
tp-0ge-0000gf-0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet  netmask  broadcast
        inet6 fe80::88a2:f6ff:fe6f:90cb  prefixlen 64  scopeid 0x20<link>
        ether 8a:a2:f6:6f:90:cb  txqueuelen 1000  (Ethernet)

and the current routes:

[user ~]$ ip -6 r s
    2600:1f14:XXXX:XXXX:XXXX:ff0c:cccd:b262 dev eth0 proto kernel metric 256 expires 439sec pref medium
    fe80::4f3:9ff:fec9:2032 dev eth0 metric 1024 pref medium
    fe80::88a2:f6ff:fe6f:90cb dev tp-0ge-0000gf-0 metric 1024 pref medium
    default via fe80::460:a1ff:fec3:9cb6 dev eth0 metric 1024 pref medium

and ip6tables filter table is letting everything through

[user ~]$ sudo ip6tables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination 

I have net.ipv6.conf.[inteface].forwarding enabled on both the tap and eth0, and clearly ipv6 is enabled. If any other important kernel parameters come to mind i'll add them here.

This is on amazon linux 2, cat /etc/os-release:

NAME="Amazon Linux"
ID_LIKE="centos rhel fedora"
PRETTY_NAME="Amazon Linux 2"

Let me know if there's any other information I should include. Any suggestions at all are much appreciated.


2 Answers 2


As introduction remark, you should get used to never using ifconfig, even if it's barely able to handle IPv6. The same way you're using ip -6 route show, just always use ip address show (and ip link show). You'll avoid problems due to limitations (on Linux) of the ifconfig command which is now obsolete (because using a deprecated kernel API).

I can see three points where you might need informations.

  1. IPv6 link-local addresses require also an interface to be a complete address

Since in each network attached to an IPv6 interface an identical link-local address is allowed to exist, it's mandatory to specify the address' interface to have a complete link-layer address. It's specified in RFC 4007:

One possible candidate for these strings would be interface names, as interfaces uniquely disambiguate any scopes.

For your system, these are the completely specified link-local addresses:

  1. Local addresses belong to the host

And are thus routed through the lo (loopback) interface between them, if such route is allowed. Don't try ping -I eth0 it will force the packet to be sent on the wire through eth0 where there's nothing to receive it. So the ping that will work is:

    ping fe80::88a2:f6ff:fe6f:90cb%tp-0ge-0000gf-0

and being local, by default the system will choose the same source. It's probably not allowed to ping from one local link-local address attached to an interface to an other one attached to an other interface (but from one global on any interface to a link-local on any (even other) interface, or for a second local on the same interface would be fine too). So this would fail:

    ping -I fe80::4f3:9ff:fec9:2032%eth0 fe80::88a2:f6ff:fe6f:90cb%tp-0ge-0000gf-0

but this would work:

    ping -I 2600:1f14:XXXX:XXXX:e134:ff0c:cccd:b262 fe80::88a2:f6ff:fe6f:90cb%tp-0ge-0000gf-0

Note that this won't tell that your TAP interface is working: you're pinging the local system from itself and not using the TAP interface at all.

  1. The important part of a TUN/TAP interface isn't the local address visible on it

What is important for a TUN/TAP interface is the running process attached behind this interface which is the one which is supposed to receive frames or packets and handle (or tunnel) them. In your tutorial, that's the process run at step 6:

    STEP#6 KVM qemu command to startup Guest using tap0 device

which uses this option: -net tap,script=no,ifname=tap0,vlan=0 to attach to the tap0 interface that was set up before. That's the whole point of a TUN/TAP interface: linking system's network to a process.

Since the interface tp-0ge-0000gf-0 auto assigned a link local address, that means there is or was such a running process attached to tp-0ge-0000gf-0. If you were using ip link show tp-0ge-0000gf-0 or ip address show tp-0ge-0000gf-0 you could confirm this with the presence of LOWER_UP (which here translates to process attached) instead of NO-CARRIER (process not attached). ifconfig won't display such information. Such process could be for example openvpn or QEMU. Relaying/tunneling applications like ssh (which has a tun or tap tunnel mode) or even the socat tool have options to attach (but eg for socat only in order to relay: it doesn't include a built-in network stack).

If it's configured to handle (or tunnel) IPv6, then it assigned on its (invisible) side an link-local address and possibly a global address.

You should be able to discover (the) remote link-local IPv6 address(es) by pinging the link-local all nodes address destination, still specifying the interface:

    ping ff02::1%tp-0ge-0000gf-0

To discover router(s) there, if any, one can ping the link-local all routers address:

    ping ff02::2%tp-0ge-0000gf-0
  • Thanks very much for the information, that clears a lot of things up conceptually for me. I posted this question thinking that this was the root cause of my issue, but after reading your response I realize it isn't. My actual issue pertains to what you were getting at with your 3rd bullet, if you have any time to take a look at it I would be very thankful unix.stackexchange.com/questions/591743/…. I learned a lot from your response, thanks again :)
    – waffles
    Jun 9, 2020 at 2:21

That's a IPv6 local link address, it only "lives" inside the link tp-0ge-0000gf-0 and is not routeable, you cannot reach it from eth0.

To ping it you have to specify the device at the end, like this:

$ ping6 fe80::88a2:f6ff:fe6f:90cb%tp-0ge-0000gf-0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .