IPv6 routing problems

Today I found that fetching my mail with getmail would take two minutes. Two full minutes. Then I tried to SSH into my server and .. waited for two minutes.

When forcing SSH to use IPv4 (ssh -4 ...), I got an connection immediately. Pinging my server also showed different behavior on IPv4 and IPv6: ping -4 cweiske.de would work fine, ping -6 cweiske.de had 100% packet loss.

Network setup

IPv4

My home network is easy on the IPv4 side:

 |Home server| <--> |Router| <--> |Internet|
|      | <--[DHCP]-----> |           |      +------+      +--------+
|      | <--[DNS]------> |           |
+------+                 +-----------+]]>

The home server forwards packets to the router, and is also responsible for DHCP.

IPv6

With IPv6, things got complicated:

 |Home server| <--> |Router| <--> |Internet|
|      | <--[DNS]--------> |           |      |      |      +--------+
|      |                   +-----------+      |      |
|      | <--[global SLAAC]------------------> |      |
|      | <--[Packets]-----------------------> |      |
+------+                                      +------+
  ]]>

Routing

Back to my problem: I looked at my laptop's routing table and saw this:

$ route -6n
Kernel-IPv6-Routentabelle
Destination                    Next Hop                   Flag Met Ref Use If
::1/128                        ::                         U    256 2     0 lo
2003:d9:ebc4:9400::/64         ::                         U    600 1     0 wlp1s0
2003:d9:ebc4:9400::/56         fe80::5e49:79ff:fe3b:b1de  UG   600 1     0 wlp1s0
fdc3:e153::/64                 ::                         U    600 1     0 wlp1s0
fe80::/64                      ::                         U    600 2     0 wlp1s0
::/0                           fe80::d250:99ff:fe2c:f8c8  UG   600 1     0 wlp1s0
::/0                           fe80::5e49:79ff:fe3b:b1de  UG   600 1     0 wlp1s0
::1/128                        ::                         Un   0   7     0 lo
2003:d9:ebc4:9400:1acf:5eff:fed7:c3bc/128 ::              Un   0   2     0 wlp1s0
2003:d9:ebc4:9400:d4f2:9d24:a70e:82c8/128 ::              Un   0   3     0 wlp1s0
fdc3:e153::1acf:5eff:fed7:c3bc/128 ::                     Un   0   2     0 wlp1s0
fe80::1acf:5eff:fed7:c3bc/128  ::                         Un   0   3     0 wlp1s0
ff00::/8                       ::                         U    256 7     0 wlp1s0
::/0                           ::                         !n   -1  1     0 lo

There were two routes for internet addresses, one to ..:f8c8, which is my home server, and one for ..:b1de, which is the router.

The problem was clearly visible now: My laptop sent IPv6 packets to my home server, which does not forward them, and never gets a response. After two minutes, it falls back to IPv4 and that works.

Wireshark

So my home server said that clients should route packets through it. I used the priceless Wireshark to inspect the SLAAC Router Advertisement packets:

Home server
Internet Protocol Version 6, Src: fe80::d250:99ff:fe2c:f8c8, Dst: fe80::1acf:5eff:fed7:c3bc
Internet Control Message Protocol v6
    Type: Router Advertisement (134)
    Code: 0
    Checksum: 0x07e6 [correct]
    [Checksum Status: Good]
    Cur hop limit: 64
    Flags: 0x00, Prf (Default Router Preference): Medium
    Router lifetime (s): 1800
    Reachable time (ms): 0
    Retrans timer (ms): 0
    ICMPv6 Option (Prefix information : fdc3:e153::/64)
    ICMPv6 Option (MTU : 1492)
    ICMPv6 Option (Source link-layer address : d0:50:99:2c:f8:c8)
    ICMPv6 Option (DNS Search List Option home.cweiske.de)
    ICMPv6 Option (Recursive DNS Server fdc3:e153::3)
Router
Internet Protocol Version 6, Src: fe80::5e49:79ff:fe3b:b1de, Dst: ff02::1
Internet Control Message Protocol v6
    Type: Router Advertisement (134)
    Code: 0
    Checksum: 0x3df4 [correct]
    [Checksum Status: Good]
    Cur hop limit: 255
    Flags: 0x00, Prf (Default Router Preference): Medium
    Router lifetime (s): 1800
    Reachable time (ms): 0
    Retrans timer (ms): 0
    ICMPv6 Option (Prefix information : 2003:d9:ebc1:7000::/64)
    ICMPv6 Option (Prefix information : 2003:d9:ebc4:9400::/64)
    ICMPv6 Option (Recursive DNS Server fdc3:e153::3)
    ICMPv6 Option (MTU : 1492)
    ICMPv6 Option (Route Information : Medium ::/0)
    ICMPv6 Option (Route Information : Medium 2003:d9:ebc4:9400::/56)
    ICMPv6 Option (Source link-layer address : 5c:49:79:3b:b1:de)

I saw that the router actually had "Route Information" in its advertisements, but the home server did not - but my laptop still used it as router.

RFC 4861 shed light onto the issue:

Router Lifetime

[...]

A Lifetime of 0 indicates that the router is not a default router and SHOULD NOT appear on the default router list.

So every machine sending out SLAAC router advertisements is automatically usable as a router, unless it sends a lifetime of zero.

dnsmasq

Now I had to configure the dnsmasq instance on my home server to set the routing life time to 0.

The dnsmasq man page tells us how:

--ra-param=<interface>,[mtu:<integer>|<interface>|off,][high,|low,]<ra-interval>[,<router lifetime>]

The lifetime of the route may be changed or set to zero, which allows a router to advertise prefixes but not a route via itself. --ra-param=eth0,0,0

After I had this set, wireshark showed me a

Router lifetime (s): 0

and the latop only had one catchall-route, and everything worked fine.

Written by Christian Weiske.

Comments? Please send an e-mail.