]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/network/networkd-address-pool.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 #include "alloc-util.h"
4 #include "networkd-address-pool.h"
5 #include "networkd-manager.h"
7 #include "string-util.h"
13 const union in_addr_union
*u
,
22 p
= new0(AddressPool
, 1);
28 p
->prefixlen
= prefixlen
;
31 LIST_PREPEND(address_pools
, m
->address_pools
, p
);
37 int address_pool_new_from_string(
44 union in_addr_union u
;
51 r
= in_addr_from_string(family
, p
, &u
);
55 return address_pool_new(m
, ret
, family
, &u
, prefixlen
);
58 void address_pool_free(AddressPool
*p
) {
64 LIST_REMOVE(address_pools
, p
->manager
->address_pools
, p
);
69 static bool address_pool_prefix_is_taken(
71 const union in_addr_union
*u
,
81 HASHMAP_FOREACH(l
, p
->manager
->links
, i
) {
85 /* Don't clash with assigned addresses */
86 SET_FOREACH(a
, l
->addresses
, j
) {
87 if (a
->family
!= p
->family
)
90 if (in_addr_prefix_intersect(p
->family
, u
, prefixlen
, &a
->in_addr
, a
->prefixlen
))
94 /* Don't clash with addresses already pulled from the pool, but not assigned yet */
95 LIST_FOREACH(addresses
, a
, l
->pool_addresses
) {
96 if (a
->family
!= p
->family
)
99 if (in_addr_prefix_intersect(p
->family
, u
, prefixlen
, &a
->in_addr
, a
->prefixlen
))
104 /* And don't clash with configured but un-assigned addresses either */
105 LIST_FOREACH(networks
, n
, p
->manager
->networks
) {
108 LIST_FOREACH(addresses
, a
, n
->static_addresses
) {
109 if (a
->family
!= p
->family
)
112 if (in_addr_prefix_intersect(p
->family
, u
, prefixlen
, &a
->in_addr
, a
->prefixlen
))
120 int address_pool_acquire(AddressPool
*p
, unsigned prefixlen
, union in_addr_union
*found
) {
121 union in_addr_union u
;
124 assert(prefixlen
> 0);
127 if (p
->prefixlen
> prefixlen
)
132 if (!address_pool_prefix_is_taken(p
, &u
, prefixlen
)) {
133 _cleanup_free_
char *s
= NULL
;
136 r
= in_addr_to_string(p
->family
, &u
, &s
);
140 log_debug("Found range %s/%u", strna(s
), prefixlen
);
146 if (!in_addr_prefix_next(p
->family
, &u
, prefixlen
))
149 if (!in_addr_prefix_intersect(p
->family
, &p
->in_addr
, p
->prefixlen
, &u
, prefixlen
))