I am in the process of building a Linux router on top of Alpine Linux.
Routing (and NAT) of IPv4 works flawlessly, but I cannot get IPv6 routing to work.
The router has two network interfaces:
-
eth1
is connected to my cable modem. -
eth0
is connected to the LAN.
On eth1
I get a /64 IPv6 prefix from my ISP:
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
inet 192.168.0.240/24 brd 192.168.0.255 scope global eth1
valid_lft forever preferred_lft forever
inet6 2a02:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx/64 scope global dynamic mngtmpaddr
valid_lft 4526sec preferred_lft 1826sec
inet6 fe80::xxxx:xxxx:xxxx:xxxx/64 scope link
valid_lft forever preferred_lft forever
On eth0
initially I donât have an IPv6 address (apart from the link-local one), but I set done manually using the prefix from eth1
:
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 192.168.1.1/24 scope global eth0
valid_lft forever preferred_lft forever
inet6 2a02:xxxx:xxxx:xxxx::1/64 scope global
valid_lft 86395sec preferred_lft 14395sec
inet6 fe80::xxxx:xxxx:xxxx:xxxx/64 scope link
valid_lft forever preferred_lft forever
I also installed radvd to send router advertisement to the LAN using the following configuration:
interface eth0
{
AdvSendAdvert on;
MaxRtrAdvInterval 10;
prefix ::/64
{
AdvOnLink on;
AdvAutonomous on;
AdvRouterAddr on;
};
};
And set net.ipv6.conf.eth1.accept_ra=2
using sysctl so I donât loose the IPv6 prefix I get from my ISP.
Using this configuration the computers on the LAN get an IPv6 address through stateless autoconfig, e.g. on my PC:
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
inet 192.168.1.205/24 brd 192.168.1.255 scope global br0
valid_lft forever preferred_lft forever
inet6 2a02:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx/64 scope global temporary dynamic
valid_lft 86393sec preferred_lft 14393sec
inet6 2a02:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx/64 scope global dynamic mngtmpaddr
valid_lft 86393sec preferred_lft 14393sec
inet6 fe80::xxxx:xxxx:xxxx:xxxx/64 scope link
valid_lft forever preferred_lft forever
(This one even has two.)
But I still cannot use IPv6. Neither can I access any IPv6 enabled websites nor can I ping any IPv6 enabled servers. Using tshark on the router I can see that the ping is being transmitted through eth1, but instead of getting a ping reply, I receive a neighbor solicitation (prtobably from my ISPâs router), which isnât forwarted to my PC:
9988 48.040945071 2a02:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:d821 â 2a00:1450:4001:81d::200e ICMPv6 118 Echo (ping) request id=0xc7dc, seq=1, hop limit=63
9989 48.063201702 fe80::de53:7cff:fe0e:4812 â ff02::1:xxxx:d821 ICMPv6 86 Neighbor Solicitation for 2a02:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:d821 from dc:53:7c:0e:48:12
My routes are looking like this (I didnât change anything manually):
2a02:xxxx:xxxxx:xxxx::/64 dev eth0 proto kernel metric 256 expires 86391sec pref medium
2a02:xxxx:xxxx:xxxx::/64 dev eth1 proto kernel metric 256 expires 4173sec pref medium
fe80::/64 dev eth0 proto kernel metric 256 pref medium
fe80::/64 dev eth1 proto kernel metric 256 pref medium
default via fe80::xxxx:xxxx:xxxx:xxxx dev eth1 proto ra metric 1024 expires 1529sec hoplimit 64 pref high
What am I missing?