Date: Sun, 5 Oct 2014 23:59:20 +0300 From: Guy Yur <guyyur@gmail.com> To: freebsd-net@freebsd.org Subject: [patch] ipv6 prefix lifetime is not updated when address is updated through SIOCAIFADDR_IN6 Message-ID: <CAC67Hz856UmNsWZq_QZDMsJKNuHJ5QbyJQ=VeXgREorjdhPaSA@mail.gmail.com>
next in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
Hi,
I am running dhcpcd 6.4.3 on 11.0-CURRENT r271879M
to get an ipv6 prefix from my ISP.
The prefix is received with a lifetime of 86400 seconds.
dhcpcd adds an address using the prefix with pltime and vltime of 86400.
Before the address expires dhcpcd refreshes it but the interface route
for the prefix is still deleted after 86400 seconds.
dhcpcd uses SIOCAIFADDR_IN6 to update the address and the kernel
doesn't update the prefix lifetime if the prefix already exists.
Since ndpr_lastupdate is also not updated the prefix will expire.
The issue doesn't happen when updating lifetime using ifconfig
with pltime and vltime since ifconfig removes the address before
adding it (each ifconfig invocation will reset the prefix lifetime).
I created a patch to update the prefix lifetimes in SIOCAIFADDR_IN6
from the added address's lifetime.
If there are two addresses with same prefix but different lifetimes
it means the last one added will set the prefix lifetime.
Another way will be to move the check in SIOCAIFADDR_IN6 to a new
function nd6_prelist_update that will call nd6_prefix_lookup.
If the prefix doesn't exist, call nd6_prelist_add.
If it does exist, copy lifetimes (and ndpr_flags?).
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
...
Regards,
Guy
[-- Attachment #2 --]
Index: sys/netinet6/in6.c
===================================================================
--- sys/netinet6/in6.c (revision 272566)
+++ sys/netinet6/in6.c (working copy)
@@ -678,6 +678,8 @@ in6_control(struct socket *so, u_long cmd, caddr_t
goto out;
}
}
+ else
+ nd6_prefix_update_ltimes(pr, &pr0);
/* relate the address to the prefix */
if (ia->ia6_ndpr == NULL) {
Index: sys/netinet6/nd6.h
===================================================================
--- sys/netinet6/nd6.h (revision 272566)
+++ sys/netinet6/nd6.h (working copy)
@@ -445,6 +445,7 @@ int nd6_prelist_add(struct nd_prefixctl *, struct
void pfxlist_onlink_check(void);
struct nd_defrouter *defrouter_lookup(struct in6_addr *, struct ifnet *);
struct nd_prefix *nd6_prefix_lookup(struct nd_prefixctl *);
+int nd6_prefix_update_ltimes(struct nd_prefix *, struct nd_prefixctl *);
void rt6_flush(struct in6_addr *, struct ifnet *);
int nd6_setdefaultiface(int);
int in6_tmpifadd(const struct in6_ifaddr *, int, int);
Index: sys/netinet6/nd6_rtr.c
===================================================================
--- sys/netinet6/nd6_rtr.c (revision 272566)
+++ sys/netinet6/nd6_rtr.c (working copy)
@@ -853,6 +853,21 @@ nd6_prefix_lookup(struct nd_prefixctl *key)
}
int
+nd6_prefix_update_ltimes(struct nd_prefix *pr, struct nd_prefixctl *prctl)
+{
+ int error;
+
+ pr->ndpr_vltime = prctl->ndpr_vltime;
+ pr->ndpr_pltime = prctl->ndpr_pltime;
+ if ((error = in6_init_prefix_ltimes(pr)) != 0) {
+ return (error);
+ }
+ pr->ndpr_lastupdate = time_uptime;
+
+ return 0;
+}
+
+int
nd6_prelist_add(struct nd_prefixctl *pr, struct nd_defrouter *dr,
struct nd_prefix **newp)
{
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAC67Hz856UmNsWZq_QZDMsJKNuHJ5QbyJQ=VeXgREorjdhPaSA>
