Created attachment 149617 [details] Change prelist_update to be usable by SIOCAIFADDR_IN6 When refreshing an existing ipv6 address pltime and vltime using SIOCAIFADDR_IN6 the prefix lifetime is not updated. Issue seen on 11.0-CURRENT r271879M with dhcpcd 6.4.3. My ISP is providing a prefix with a lifetime of 86400 seconds. dhcpcd uses SIOCAIFADDR_IN6 to update the address with pltime and vltime. The address lifetime gets refreshed on renewals but the prefix lifetime is not updated so it expires and the route for the prefix gets deleted. Attaching several patches trying to solve the problem in different ways. In both cases, if the prefix exists it will be refreshed. In case of several addresses for same prefix and different times, prefix time will be from the last one. 1. prelist_update.patch and prelist_update_long_lines.patch Change prelist_update so it can be used by both RA and SIOCAIFADDR_IN6. prelist_update_long_lines.patch keeps the long lines for smaller diff. prelist_update.patch wraps to 80 columns. 2. Add a separate function in6_prelist_update duplicating some of the code from prelist_update but doing less work than prelist_update. Possible to reproduce with ifconfig and two addresses with the same prefix. ifconfig -L lan0 inet6 2001:DB8::1 pltime 60 vltime 60 repeat ifconfig -L lan0 inet6 2001:DB8::2 pltime 1000 vltime 1000 Checking "ndp -p" after 60 seconds will show the prefix 2001:DB8::/64 as expired. With dhcpcd: Before: # netstat -rn -f inet6 WWWW:XXXX:YYYY:ZZZZ::/64 link#1 U lan0 WWWW:XXXX:YYYY:ZZZZ::1 link#1 UHS lo0 ... After more than 86400 seconds: # ifconfig -L lan0 inet6 lan0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500 options=8000b<RXCSUM,TXCSUM,VLAN_MTU,LINKSTATE> inet6 fe80::AAAA:BBBB:CCCC:DDDD%lan0 prefixlen 64 scopeid 0x1 inet6 WWWW:XXXX:YYYY:ZZZZ::1 prefixlen 64 pltime 57257 vltime 57257 nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL> # ndp -p WWWW:XXXX:YYYY:ZZZZ::/64 if=lan0 flags=L vltime=0, pltime=0, expired, ref=1 No advertising router ... # netstat -rn -f inet6 WWWW:XXXX:YYYY:ZZZZ::1 link#1 UHS lo0 ...
Created attachment 149619 [details] Change prelist_update to be usable by SIOCAIFADDR_IN6 (not wrapped to 80 columns)
Created attachment 149620 [details] Add in6_prelist_update function for SIOCAIFADDR_IN6
Discovered the same issue on NetBSD. Taking the route of separating ioctl address/prefix management from RA prefix management, patches towards the end of the thread. http://mail-index.netbsd.org/tech-net/2016/08/05/msg006044.html Patch for dhcpcd to workaround the issue here: http://roy.marples.name/projects/dhcpcd/vpatch?from=bef60c6f8b4da8c2&to=37ca8a2052507e64 (will be in the next dhcpcd release)
There is an additional problem that SIOCSPFXFLUSH_IN6 will trigger a KASSERT in nd6_prefix_del "prefix %p has referencing addresses" when kernel is built with INVARIANTS and you add a static address by rc.conf or ifconfig. Example: ifconfig vtnet0 inet6 2001:db8::1 ndp -P I removed my old patches. The NetBSD changes are the correct way and fix both issues. I am on my second attempt at porting them, need to do further adjustments to get fully working.
Bug 194485 patch is needed before the NetBSD "Separate ioctl address prefix management from RA prefix management" changes otherwise the interface route generated by the address won't be used for address neighbor matching. Changes to add RTF_CONNECTED are also needed to get routes added by dhcpcd 7.0.2 working. dhcpcd adds the interface route with RTF_STATIC but the patch in bug 194485 currently checks RTF_STATIC is not set (because there is no RTF_CONNECTED) so the address neighbor matching will still not work. My WIP with bug 194485 and "Separate ioctl address prefix management from RA prefix management" ported over to 12-CURRENT but missing RTF_CONNECTED: https://github.com/guyyur/freebsd/tree/fix_ipv6_address_prefix
Created attachment 192020 [details] ndp -P panic (In reply to guyyur from comment #4) The attached minimal patch ought to address this. SIOCSPFXFLUSH_IN6 ought to leave the associated prefix alone in your example, I believe.
It fixes the example but there is another scenario that still panics. # set static ula so can access host even if router is down ifconfig vtnet0 inet6 fdXX:: eui64 # enable accept_rtadv to learn global address via ra # rtadvd set to publish fdXX:: so learns ula prefix via ra too ifconfig vtnet0 inet6 accept_rtadv # request ra to learn the prefixes from the router rtsol vtnet0 # flush ndp -P In this scenario, when learning fdXX:: prefix via ra it will set ndpr_advrtrs but the prefix is associated with an address without IN6_IFF_AUTOCONF so the address won't be purged.
I created phabricator D15406 as my attempt to port the NetBSD changes to 12.0-CURRENT. Fix for 194485 is needed first. My attempts for fixes to that bug are D15404 and D15405.
updated D15406 for 13.0-CURRENT and rebased on D23695 instead of D15404 and D15405, dropping the need for RTF_CONNECTED.