If IPv6 is not working properly in Linux, here are steps you can follow to debug the issue.
check kernel boot param
Check these two files
cat /proc/cmdline
cat /etc/default/grub
If ipv6.disable=1
is set, the kernel IPv6 stack will be disabled. If ipv6.disable_ipv6=1
is set, the kernel keeps the IPv6 stack functional but will not assign IPv6 addresses to any of your network devices.
Make sure you do not use any of these kernel options if you want to use IPv6.
check interface disable_ipv6 settings
sysctl net.ipv6.conf.lo.disable_ipv6
sysctl net.ipv6.conf.eno1.disable_ipv6
# -r list all values matching this pattern
sysctl -r 'net.ipv6.conf.*.disable_ipv6' net.ipv6.conf
Make sure all of the interfaces that you want to have ipv6 enabled has disable_ipv6=0
. Specifically, you SHOULD also enable ipv6 on lo
interface. You should also enable IPv6 on Linux bridge and the physical interface that it is connected to.
check interface RA settings if you use SLAAC
RA stands for router advertisement. It is a broadcast packet that allow configuration of IP address and routing. SLAAC relies on RA to work.
sysctl net.ipv6.conf.all.accept_ra
# replace vmbr0 with your interface
sysctl net.ipv6.conf.vmbr0.accept_ra
It should be 1 or 2 depending on your device.
If it’s 0, you need to set this at boot time. e.g. in /etc/network/interfaces
To learn more about accept_ra
param, see Linux kernel document. Search accept_ra
in that page.
For example, on one of my promox VE node, I have
auto vmbr0
iface vmbr0 inet static
address 192.168.2.47/24
gateway 192.168.2.1
bridge-ports eno1
bridge-stp off
bridge-fd 0
iface vmbr0 inet6 auto
accept_ra 2
If you doubt whether RA is working properly, run tcpdump
to capture the packet and view it in wireshark.
# replace INTERFACE with your interface name
sudo tcpdump -i INTERFACE -w /tmp/ra_packets.pcap 'icmp6 and (ip6[40] = 134 or ip6[40] = 133)'
check lo ip6-loopback ping
ping6 ::1
ping6 ip6-loopback
check local hostname is ipv6 resolvable
in /etc/hosts
::1 entry should include your fqdn
check whether ipv6 address is assigned on interface
ip -6 a
ip -6 a vmbr0
If your IPv6 network use SLAAC, IP address should be assigned automatically. One interface usually has one public IPv6 address (starts with 2x:xx:xx
) and more than one private IPv6 address (starts with fx:xx:xx
).
If your IPv6 network use DHCPv6 only, you should config DHCP in /etc/network/interface
or corresponding RHEL config file or Network Manager config file. To just test DHCPv6 is working, you can run:
dhclient -6 INTERFACE
check ipv6 routes is added
ip -6 r
ip -6 r | grep default
IPv6 routes are added by clients via RA (router advertisement).
Make sure the default route either has no expire field or has a good expire field. In openwrt default config, default route expire should be between 1200s and 1800s. If it’s less than 1200s, RA is not properly received and processed by host.
In some home server, if you enable IPv6 on IPMI/SBC/iLO/iDrac and use the shared network port, host OS will no longer receive the RA packet. You may see low expire on default route or missing a default route. In that case, you should disable IPv6 on IPMI.
check IPv6 neighbors for nodes in the same LAN
ip -6 n show|grep -v -E '(FAILED|STALE)'
At least one router should be listed when IPv6 is working. You can compare results on different nodes in the same LAN.
check you can visit other IPv6 nodes on the Internet
ping6 aliyun.com
curl -6 https://aliyun.com
curl -I -6 https://mirrors.tuna.tsinghua.edu.cn/
# test whether your OS prefer IPv6 or IPv4 when both are available
curl test.ipw.cn