- struct device_prefix_assignment *old, *new;
- old = container_of(node_old, struct device_prefix_assignment, node);
- new = container_of(node_new, struct device_prefix_assignment, node);
-
- // Assignments persist across interface reloads etc.
- // so use indirection to avoid dangling pointers
- struct interface *iface = vlist_find(&interfaces,
- (node_new) ? new->name : old->name, iface, node);
-
- if (node_old && node_new) {
- new->addr = old->addr;
- new->length = old->length;
- } else if (node_old) {
- if (iface)
- interface_set_prefix_address(iface, false, old);
- free(old);
- } else if (node_new) {
- struct device_prefix *prefix = new->prefix;
- uint64_t want = 1ULL << (64 - new->length);
- prefix->avail &= ~(want - 1);
- prefix->avail -= want;
-
- // Invert assignment
- uint64_t assigned = ~prefix->avail;
- assigned &= (1ULL << (64 - prefix->length)) - 1;
- assigned &= ~(want - 1);