When configured as a router, for instance for hosting virtual machines with KVM, a Debian machine with a somewhat recent kernel will not listen to router advertisements from others. This makes sense in many cases, but when you have a VM host in your internal network, which only router function is to allow communication to and from the virtual machines it hosts, the default behaviour is less than optimal.
ping6 reports the network as unreachable. Looking at ip -6 route reveals the problem. There’s no “default” line configured.
# ping6 google.com connect: Network is unreachable # ip -6 route 2001:4fa0:baaa:1::/64 dev eth0 proto kernel metric 256 expires 86394sec pref medium fe80::/64 dev eth0 proto kernel metric 256 pref medium
After verifying with tcpdump -i eth0 ip6 that router advertisements were indeed being received, I looked around for a bit and found this post by Andy Smith that explains the problem in detail.
In short, accepting router advertisements is governed by /proc/sys/net/ipv6/conf/$IFACE/accept_ra. These values are documented in ip-sysctl.txt (local archive here).
accept_ra - INTEGER Accept Router Advertisements; autoconfigure using them. It also determines whether or not to transmit Router Solicitations. If and only if the functional setting is to accept Router Advertisements, Router Solicitations will be transmitted. Possible values are: 0 Do not accept Router Advertisements. 1 Accept Router Advertisements if forwarding is disabled. 2 Overrule forwarding behaviour. Accept Router Advertisements even if forwarding is enabled. Functional default: enabled if local forwarding is disabled. disabled if local forwarding is enabled.
The solution is thus to set accept_ra to 2 to allow for accepting router advertisements even if forwarding is set to 1.
Since I use Shorewall to enable the forwarding, I ended up with a somewhat different config than Andy, but I still use the pre-up statements in /etc/network/interfaces to resolve the issue.
allow-hotplug eth0 iface eth0 inet static address 192.168.6.10 netmask 255.255.255.0 gateway 192.168.6.1 dns-nameservers 192.168.6.1 pre-up echo 2 > /proc/sys/net/ipv6/conf/$IFACE/accept_ra
The rest of the config is only shown for reference. The important part is the pre-up line. Setting this, and then manually writing to /proc/sys/net/ipv6/conf/eth0/accept_ra to apply the configuration immediately, I had a default route within seconds, and ping to Google worked like a charm.
# ip -6 route 2001:4fa0:baaa:1::/64 dev eth0 proto kernel metric 256 expires 86394sec pref medium fe80::/64 dev eth0 proto kernel metric 256 pref medium default via fe80::1:1 dev eth0 proto ra metric 1024 expires 50sec hoplimit 64 pref medium # ping6 -c4 google.com PING google.com(arn09s11-in-x0e.1e100.net (2a00:1450:400f:807::200e)) 56 data bytes 64 bytes from arn09s11-in-x0e.1e100.net (2a00:1450:400f:807::200e): icmp_seq=1 ttl=55 time=19.0 ms 64 bytes from arn09s11-in-x0e.1e100.net (2a00:1450:400f:807::200e): icmp_seq=2 ttl=55 time=18.6 ms 64 bytes from arn09s11-in-x0e.1e100.net (2a00:1450:400f:807::200e): icmp_seq=3 ttl=55 time=22.3 ms 64 bytes from arn09s11-in-x0e.1e100.net (2a00:1450:400f:807::200e): icmp_seq=4 ttl=55 time=17.8 ms --- google.com ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3004ms rtt min/avg/max/mdev = 17.823/19.474/22.359/1.725 ms
1 Comment
Add inet6 part
iface eth0 inet6 auto
accept_ra 2
may help you 🙂
And also, according to debian stretch manual, if you use auto in inet6, it’s automatically set to 2, so you may even omit accept_ra part.
accept_ra int
Accept router advertisements (0=off, 1=on, 2=on+forwarding). Default value: “2”