1
0
mirror of https://github.com/systemd/systemd.git synced 2024-12-22 17:35:35 +03:00

Merge pull request #28917 from yuwata/network-address-pool

undefined
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2023-08-24 15:58:31 +02:00 committed by GitHub
commit ebbc92405b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -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;