- bool change = len != (int)iface->ia_addr_len;
- for (int i = 0; !change && i < len; ++i)
- if (addr[i].addr.s6_addr32[0] != iface->ia_addr[i].addr.s6_addr32[0] ||
- addr[i].addr.s6_addr32[1] != iface->ia_addr[i].addr.s6_addr32[1] ||
- (addr[i].preferred > 0) != (iface->ia_addr[i].preferred > 0) ||
- (addr[i].valid > (uint32_t)now + 7200) !=
- (iface->ia_addr[i].valid > (uint32_t)now + 7200))
- change = true;
-
- if (change) {
- struct dhcpv6_assignment *c;
- list_for_each_entry(c, &iface->ia_assignments, head)
- if (c != border && !iface->managed)
- apply_lease(iface, c, false);
- }
-
- memcpy(iface->ia_addr, addr, len * sizeof(*addr));
- iface->ia_addr_len = len;
+ struct list_head reassign = LIST_HEAD_INIT(reassign);
+ struct dhcpv6_assignment *c, *d;
+ list_for_each_entry_safe(c, d, &iface->ia_assignments, head) {
+ if (c->clid_len == 0 || (!INFINITE_VALID(c->valid_until) && c->valid_until < now) ||
+ c->managed_size)
+ continue;