- odhcpd_setup_route(addr, 128, iface, NULL, add);
+ qsort(addr, len, sizeof(*addr), prefixcmp);
+
+ for (int i = 0; i < len; ++i) {
+ addr[i].addr.s6_addr32[3] = 0;
+
+ if (addr[i].preferred < UINT32_MAX - now)
+ addr[i].preferred += now;
+
+ if (addr[i].valid < UINT32_MAX - now)
+ addr[i].valid += now;
+ }
+
+ bool change = len != (ssize_t)iface->ia_addr_len;
+ for (ssize_t i = 0; !change && i < len; ++i)
+ if (!IN6_ARE_ADDR_EQUAL(&addr[i].addr, &iface->ia_addr[i].addr) ||
+ (addr[i].preferred > 0) != (iface->ia_addr[i].preferred > 0) ||
+ addr[i].valid < iface->ia_addr[i].valid ||
+ addr[i].preferred < iface->ia_addr[i].preferred)
+ change = true;
+
+ if (change)
+ dhcpv6_ia_preupdate(iface);
+
+ memcpy(iface->ia_addr, addr, len * sizeof(*addr));
+ iface->ia_addr_len = len;
+
+ if (change)
+ dhcpv6_ia_postupdate(iface, now);
+
+ if (change)
+ raise(SIGUSR1);