+ rtnl_addr_set_family(rta, AF_INET6);
+ rtnl_addr_set_ifindex(rta, entry->prefix->ifindex);
+ rtnl_addr_set_local(rta, nl);
+ rtnl_addr_set_prefixlen(rta, entry->prefix->address.prefix_len);
+
+ ret = rtnl_addr_delete(handle, rta, 0);
+
+ rtnl_addr_free(rta);
+ nl_addr_destroy(nl);
+
+ return ret;
+}
+
+static int add_to_map(struct nid_prefix_map *map, struct nid_prefix_map *new)
+{
+ struct nid_prefix_map *i;
+#define PUT_IT_IN_PLACE(node, member, om) \
+ /* find the correct location in the list */ \
+ for (i = map->node.next; i->node.next && i->member < \
+ new->member; i = i->node.next) \
+ ; \
+ if (i && i->member == new->member && i->om == new->om) \
+ return 0; \
+ /* first in the list */ \
+ if (!i || !i->node.prev) { \
+ new->node.prev = NULL; \
+ new->node.next = i; \
+ map->node.next = new; \
+ if (i) \
+ i->node.prev = new; \
+ } \
+ /* last in the list */ \
+ else if (i->node.next == NULL) { \
+ new->node.prev = i; \
+ new->node.next = NULL; \
+ i->node.next = new; \
+ } \
+ /* somewhere in the middle */ \
+ else { \
+ new->node.prev = i->node.prev; \
+ new->node.next = i; \
+ i->node.prev->node.next = new; \
+ i->node.prev = new; \
+ }
+ PUT_IT_IN_PLACE(p, prefix, nid)
+ PUT_IT_IN_PLACE(n, nid, prefix)
+ return 1;
+}
+
+static inline void remove_from_map(struct nid_prefix_map *map,
+ struct nid_prefix_map *entry)
+{
+ if (map->n.next == entry)
+ map->n.next = entry->n.next;
+ if (map->n.prev == entry)
+ map->n.prev = entry->n.prev;
+ if (map->p.next == entry)
+ map->p.next = entry->p.next;
+ if (map->p.prev == entry)
+ map->p.prev = entry->p.prev;
+}
+
+static inline void remove_from_map_and_free(struct nid_prefix_map *map,
+ struct nid_prefix_map *entry)
+{
+ remove_from_map(map, entry);
+ free(entry);
+}
+
+static int add_nid_to_map(struct nid_prefix_map *map, struct prefix *prefix,
+ nid_t nid)
+{
+ struct nid_prefix_map *new = calloc(1, sizeof(struct nid_prefix_map));
+ int ret;
+
+ if (!new)