* Re: pppd and IPv6 routes
2026-04-13 12:37 pppd and IPv6 routes Mikulas Patocka
@ 2026-04-25 0:27 ` Benjamin Cama
0 siblings, 0 replies; 2+ messages in thread
From: Benjamin Cama @ 2026-04-25 0:27 UTC (permalink / raw)
To: Mikulas Patocka; +Cc: linux-ppp
Hi Mikulas,
Le lundi 13 avril 2026 à 14:37, Mikulas Patocka a écrit :
>I have a problem with pppd and IPv6. I use pppd 2.4.9 from Debian 12.
For reference, on my side I’m also using Debian 12, pppd 2.4.9 and
kernel version 6.12.22+bpo-amd64.
Also, I’m doing my tests just on a looped back dummy connection, like
so:
pppd noauth pty "pppd noauth notty" debug nodetach
I just get link-local addresses, but it’s enough to test.
>I get this ppp0 device from my ISP (using ppp-over-ethernet):
>23: ppp0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1492 state UNKNOWN qlen 3
> inet6 2a00:1028:8391:4349:4839:8541:daa4:adcf/64 scope global dynamic mngtmpaddr
> valid_lft 86287sec preferred_lft 3487sec
> inet6 fe80::4839:8541:daa4:adcf peer fe80::e681:84ff:fec2:4b34/128 scope link
> valid_lft forever preferred_lft forever
Same thing here (but no GUA).
>I run wide-dhcpv6-client, it sends "dhcp6 solicit" to "ff02::1:2":
BTW, WIDE is really an ancient implementation, you may run in some
strange interaction with recent code.
>fe80::4839:8541:daa4:adcf.dhcpv6-client > ff02::1:2.dhcpv6-server: dhcp6 solicit
>I receive dhcp6 advertise from the ISP:
>e681:84ff:fec2:4b34.dhcpv6-server > fe80::4839:8541:daa4:adcf.dhcpv6-client: dhcp6 advertise
(I did not test DHCPv6)
>The problem is that the kernel doesn't pass the packet to the dhcp6c
>daemon, it rejects the packet with a redirect to itself:
>fe80::4839:8541:daa4:adcf > fe80::e681:84ff:fec2:4b34: ICMP6, redirect, fe80::4839:8541:daa4:adcf to fe80::4839:8541:daa4:adcf, length 176
Quite strange.
>According to RFC, redirect to itself means that the sender should send the
>packet to the same interface to a different host.
I’m not sure where you interpret that from. A redirect is a hint that
the address is present on the same *link* (not interface), but may be a
different host or itself, maybe. But in this case, as you clearly see
the address *is* in fact from this very interface, something very wrong
is going on.
>"ping fe80::e681:84ff:fec2:4b34%ppp0" also doesn't work - tcpdump shows
>that the reply arrives, but the kernel rejects it with a redirect to
>itself.
By default, in my case, I get ping correctly answered.
>There are the following routes set up on the ppp0 interface:
>
>anycast 2a00:1028:8391:4349:: dev ppp0 proto kernel metric 0 pref medium
>2a00:1028:8391:4349::/64 dev ppp0 proto kernel metric 256 expires 85949sec pref medium
>fe80::fe80::4839:8541:daa4:adcf dev ppp0 proto kernel metric 256 pref medium
>fe80::e681:84ff:fec2:4b34 dev ppp0 proto kernel metric 256 pref medium
>multicast ff00::/8 dev ppp0 proto kernel metric 256 pref medium
>default via fe80::e681:84ff:fec2:4b34 dev ppp0 proto ra metric 1024
>expires 4049sec hoplimit 64 pref medium
Here, an excerpt from my setup, showing routes from all the table as you
do:
$ ip -6 r show table all|grep ppp0
fe80::117e:f5e4:95b7:b93d dev ppp0 proto kernel metric 256 pref medium
fe80::14af:cf07:dc47:6de5 dev ppp0 proto kernel metric 256 pref medium
local fe80::117e:f5e4:95b7:b93d dev ppp0 table local proto kernel metric 0 pref medium
multicast ff00::/8 dev ppp0 table local proto kernel metric 256 pref medium
>If I delete the route to "fe80::fe80::4839:8541:daa4:adcf" and add the
>same route with the "local' specifier, the problem is fixed, ping works
>and dhcp6c correctly receives the responses and sets up IPv6 addresses in
>the inner network:
>
># ip -6 route del fe80::4839:8541:daa4:adcf dev ppp0
># ip -6 route add local fe80::4839:8541:daa4:adcf dev ppp0
And indeed, when I do the opposite (removing the local route), I get a
redirect like you on ppp0, then the ping response being repeated on ppp0
many times before hop limit is reached and I get an ICMPv6 time exceeded
on lo. The kernel does not recognize this address as belonging to
itself.
So you are on the right track with the missing local route. Note that my
table output show *two* routes for the host’s link-local address, on
from the main table *and* one from the local table. I note that your
table output does not specify table: did you somehow pasted everything
together in your message, or is this really your output only from the
main table? In the latter case, something is very wrong if e.g. an
anycast route shows up here. To show e.g. only the local routing table,
use "ip route show table local".
>So, the question is - why doesn't pppd set the local route as "local"? Is
>it a bug in pppd? Or a bug in the kernel?
I think the local route is *not* set by pppd, but indeed by the kernel
itself, for its special local table. But also maybe WIDE dhcp is
mangling this, I’ve already seen strange behavior with it in a distant
past.
>I tried to set up the local route in
>/etc/ppp/ipv6-up.d/wide-dhcpv6-client, but it is not reliable, sometimes
>it works and sometimes it doesn't, the script is probably racing with pppd
>setting the routes:
>
>#!/bin/sh
>sleep 3
>ip -6 route del "$PPP_LOCAL" dev ppp0
>ip -6 route add local "$PPP_LOCAL" dev ppp0
In general, you should *not* have to play with local route. I think
something is wrong either on the kernel side, or with the WIDE dhcp
client interaction.
Regards.
-- Benjamin
^ permalink raw reply [flat|nested] 2+ messages in thread