diff --git a/src/network/networkd-address-pool.c b/src/network/networkd-address-pool.c index 51f092ac69c..d9ac78a1a9f 100644 --- a/src/network/networkd-address-pool.c +++ b/src/network/networkd-address-pool.c @@ -4,7 +4,7 @@ #include "networkd-address-pool.h" #include "networkd-address.h" #include "networkd-manager.h" -#include "set.h" +#include "networkd-queue.h" #include "string-util.h" #define RANDOM_PREFIX_TRIAL_MAX 1024 @@ -84,41 +84,53 @@ int address_pool_setup_default(Manager *m) { return 0; } +static bool address_intersect( + const Address *a, + int family, + const union in_addr_union *u, + unsigned prefixlen) { + + assert(a); + assert(u); + + if (a->family != family) + return false; + + return in_addr_prefix_intersect(family, u, prefixlen, &a->in_addr, a->prefixlen); +} + static bool address_pool_prefix_is_taken( AddressPool *p, const union in_addr_union *u, unsigned prefixlen) { + Address *a; Link *l; Network *n; + Request *req; assert(p); assert(u); - HASHMAP_FOREACH(l, p->manager->links_by_index) { - Address *a; - - /* Don't clash with assigned addresses */ - SET_FOREACH(a, l->addresses) { - if (a->family != p->family) - continue; - - if (in_addr_prefix_intersect(p->family, u, prefixlen, &a->in_addr, a->prefixlen)) + /* Don't clash with assigned addresses. */ + HASHMAP_FOREACH(l, p->manager->links_by_index) + SET_FOREACH(a, l->addresses) + if (address_intersect(a, p->family, u, prefixlen)) return true; - } - } - /* And don't clash with configured but un-assigned addresses either */ - ORDERED_HASHMAP_FOREACH(n, p->manager->networks) { - Address *a; - - ORDERED_HASHMAP_FOREACH(a, n->addresses_by_section) { - if (a->family != p->family) - continue; - - if (in_addr_prefix_intersect(p->family, u, prefixlen, &a->in_addr, a->prefixlen)) + /* And don't clash with configured but un-assigned addresses either. */ + ORDERED_HASHMAP_FOREACH(n, p->manager->networks) + ORDERED_HASHMAP_FOREACH(a, n->addresses_by_section) + if (address_intersect(a, p->family, u, prefixlen)) return true; - } + + /* Also check queued addresses. */ + ORDERED_SET_FOREACH(req, p->manager->request_queue) { + if (req->type != REQUEST_TYPE_ADDRESS) + continue; + + if (address_intersect(req->userdata, p->family, u, prefixlen)) + return true; } return false;