Bug#1117959: ipv6_route flags RTF_ADDRCONF and RTF_PREFIX_RT are not cleared when static on-link routes are added during IPv6 address configuration
Control: tags -1 + moreinfo
Hi,
On Sun, Oct 12, 2025 at 11:56:09PM +0200, Garri Djavadyan wrote:
> Package: linux-image-amd64
> Version: 6.12.48-1
>
> Dear Debian Linux Kernel Maintainers,
>
> I noticed that the ipv6_route flags RTF_ADDRCONF and RTF_PREFIX_RT are
> not cleared when static on-link routes are added during IPv6 address
> configuration, and it leads to situations when the kernel updates the
> static on-link routes with expiration time.
>
> To replicate the problem I used the latest Debian 13.1 distribution
> with the kernel 6.12.48-1 and radvd (on the second machine) with the
> following configuration:
>
> root@localhost:~# cat /etc/debian_version
> 13.1
>
> root@localhost:~# uname -a
> Linux localhost 6.12.48+deb13-amd64 #1 SMP PREEMPT_DYNAMIC Debian
> 6.12.48-1 (2025-09-20) x86_64 GNU/Linux
>
> radvd.conf (on a directly connected machine):
> interface veth1
> {
> AdvSendAdvert on;
> MinRtrAdvInterval 45;
> MaxRtrAdvInterval 60;
> AdvDefaultLifetime 0;
> AdvDefaultPreference low;
> AdvHomeAgentFlag off;
> prefix fd00::/64
> {
> AdvOnLink on;
> AdvAutonomous on;
> AdvRouterAddr off;
> AdvPreferredLifetime 60;
> AdvValidLifetime 120;
> };
> };
>
>
> When I first add a manual IPv6 address to the interface receiving
> ICMPv6 RA packets and then receive an ICMPv6 RA with the same on-link
> prefix, the packet is silently ignored and no ipv6_route flags,
> including RTF_EXPIRES, get set on the static route. Everything works as
> expected.
>
> However, if an ICMPv6 RA is received before a manual IPv6 address is
> set on the interface, and the RA route is installed in the IPv6 route
> table, along with the ipv6_route flags RTF_ADDRCONF, RTF_PREFIX_RT, and
> RTF_EXPIRES, only the flag RTF_EXPIRES gets cleared when a manual IPv6
> address is configured on the interface later. As a result, after
> configuring the IPv6 address, it does not have any associated
> expiration time, but the kernel still treats it as an RA-learned route,
> so the next received RA packet sets the expiration time again.
>
> Below are the steps leading to the described issue:
>
>
> # RAs are accepted by the inteface ens4
> root@localhost:~# cat /proc/sys/net/ipv6/conf/ens4/accept_ra
> 1
>
>
> # Nothing is assigned to ens4 yet
> root@localhost:~# ip -6 addr show dev ens4
> root@localhost:~# ip -6 ro show dev ens4
> root@localhost:~#
>
>
> # No fd00::/64 routes are present in the IPv6 route table
> root@localhost:~# egrep '^fd0+\ ' /proc/net/ipv6_route
> root@localhost:~#
>
>
> # Received on-link prefix fd00::/64 from the router
> root@localhost:~# tcpdump -vi ens4 'icmp6[0] = 134'
> tcpdump: listening on ens4, link-type EN10MB (Ethernet), snapshot
> length 262144 bytes
>
> 20:41:57.733151 IP6 (flowlabel 0x15aa0, hlim 255, next-header ICMPv6
> (58) payload length: 56) fe80::f83a:f0ff:fe69:27d2 > ip6-allnodes:
> [icmp6 sum ok] ICMP6, router advertisement, length 56
> hop limit 64, Flags [none], pref low, router lifetime 0s,
> reachable time 0ms, retrans timer 0ms
> prefix info option (3), length 32 (4): fd00::/64, Flags
> [onlink, auto], valid time 120s, pref. time 60s
> source link-address option (1), length 8 (1):
> fa:3a:f0:69:27:d2
>
>
> # The RA route is installed in the ipv6_route structure with the flags
> 0x004c0001
> # 0x4c: RTF_ADDRCONF, RTF_PREFIX_RT, and RTF_EXPIRES
> root@localhost:~# egrep '^fd0+\ ' /proc/net/ipv6_route
> fd000000000000000000000000000000 40 00000000000000000000000000000000 00
> 00000000000000000000000000000000 00000100 00000002 00000000 004c0001
> ens4
>
>
> # The route has an expiration time assigned as expected
> root@localhost:~# ip -6 ro show dev ens4
> fd00::/64 proto kernel metric 256 expires 88sec pref medium
>
>
> # Now, the manual IPv6 address from the subnet fd00::/64 is configured
> on the interface
> root@localhost:~# ip addr add fd00::2/64 dev ens4
> root@localhost:~# ip -6 addr show dev ens4
> 3: ens4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel
> state UP group default qlen 1000
> altname enp0s4
> altname enx525400123457
> inet6 fd00::2/64 scope global
> valid_lft forever preferred_lft forever
> inet6 fd00::5054:ff:fe12:3457/64 scope global dynamic mngtmpaddr
> proto kernel_ra
> valid_lft 88sec preferred_lft 28sec
>
>
> # The ipv6_route entry for fd00::/64 gets updated: the flags are
> changed to 0x000c0001.
> # 0x0c: RTF_ADDRCONF, RTF_PREFIX_RT
> # The flag RTF_EXPIRES is removed but the RA-specific flags
> RTF_ADDRCONF, RTF_PREFIX_RT are still set.
> root@localhost:~# egrep '^fd0+\ ' /proc/net/ipv6_route
> fd000000000000000000000000000000 40 00000000000000000000000000000000 00
> 00000000000000000000000000000000 00000100 00000001 00000000 000c0001
> ens4
>
>
> # From user's perspective the on-link route looks permanent, no
> expiration time is present
> root@localhost:~# ip -6 ro show dev ens4
> fd00::/64 proto kernel metric 256 pref medium
>
>
> # Next RA packet has come at this point
>
>
> # And the permanent route turned into a temporary one again
> (0x004c0001)
> root@localhost:~# egrep '^fd0+\ ' /proc/net/ipv6_route
> fd000000000000000000000000000000 40 00000000000000000000000000000000 00
> 00000000000000000000000000000000 00000100 00000002 00000000 004c0001
> ens4
>
> root@localhost:~# ip -6 ro show dev ens4
> fd00::/64 proto kernel metric 256 expires 77sec pref medium
>
>
> # The kernel is instructed not to accept RAs anymore
> root@localhost:~# echo 0 > /proc/sys/net/ipv6/conf/ens4/accept_ra
> root@localhost:~# cat /proc/sys/net/ipv6/conf/ens4/accept_ra
> 0
>
>
> # After 2 minutes, the on-link route gets vanished
> # while the manual IPv6 address is still installed on the interface
> root@localhost:~# ping -Oi 10 fd00::1
> PING fd00::1 (fd00::1) 56 data bytes
> 64 bytes from fd00::1: icmp_seq=1 ttl=64 time=0.508 ms
> 64 bytes from fd00::1: icmp_seq=2 ttl=64 time=1.18 ms
> 64 bytes from fd00::1: icmp_seq=3 ttl=64 time=0.519 ms
> 64 bytes from fd00::1: icmp_seq=4 ttl=64 time=0.565 ms
> 64 bytes from fd00::1: icmp_seq=5 ttl=64 time=0.702 ms
> 64 bytes from fd00::1: icmp_seq=6 ttl=64 time=0.737 ms
> 64 bytes from fd00::1: icmp_seq=7 ttl=64 time=1.10 ms
> 64 bytes from fd00::1: icmp_seq=8 ttl=64 time=0.643 ms
> 64 bytes from fd00::1: icmp_seq=9 ttl=64 time=0.668 ms
> 64 bytes from fd00::1: icmp_seq=10 ttl=64 time=0.679 ms
> 64 bytes from fd00::1: icmp_seq=11 ttl=64 time=0.529 ms
> 64 bytes from fd00::1: icmp_seq=12 ttl=64 time=1.24 ms
> 64 bytes from fd00::1: icmp_seq=13 ttl=64 time=0.738 ms
> no answer yet for icmp_seq=14
> no answer yet for icmp_seq=15
>
> root@localhost:~# ip -6 ro show dev ens4
> root@localhost:~# egrep '^fd0+\ ' /proc/net/ipv6_route
> root@localhost:~#
>
> root@localhost:~# ip -6 addr show dev ens4
> 3: ens4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel
> state UP group default qlen 1000
> altname enp0s4
> altname enx525400123457
> inet6 fd00::2/64 scope global
> valid_lft forever preferred_lft forever
>
>
> In some environements, in which RA-sending routers are present and the
> RA processing is disabled by the interface init scripts, a race
> condition may lead to automatic removal of the permanent on-link
> routes. For example:
>
> 1. the OS boots, RAs are accepted;
> 2. RA with PIO is received from router #1;
> 3. the kernel installs a temporary on-link route;
> 4. the OS's init scripts configure a manual IPv6 address;
> 5. the kernel removes the expiration time from the on-link route;
> 6. RA with PIO is received from router #2;
> 7. the kernel sets the expiration time to the on-link route;
> 8. the OS's init scripts set 'net.ipv6.conf.xxx.accept_ra = 0' for the
> interface;
> 9. the installed IPv6 route is no longer updated by the RAs;
> 10. the installed IPv6 route expires after N seconds leading to IPv6
> reachability issues
>
>
> The problem was first noticed in a Debian 11 system running kernel
> 5.10.197-1. The respective bug report [1] in the upstream tracker was
> created a year ago.
Thanks for reporting the issue, I have updated some metadata on the
bug. I think the best course of action here is that you try to get
upstream's attation again with your issue to see if they agree on th
issue (you might want to include the netdev mailinglist I think,
other: correct me if there is better place). Please do include this
bugreport in CC.
Until then we cannot have an action donwstream in Debian.
Regards,
Salvatore
Reply to: