]>
git.proxmox.com Git - systemd.git/blob - src/network/networkd-address-pool.c
2 This file is part of systemd.
4 Copyright 2014 Lennart Poettering
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 #include "alloc-util.h"
21 #include "networkd-address-pool.h"
24 #include "string-util.h"
30 const union in_addr_union
*u
,
39 p
= new0(AddressPool
, 1);
45 p
->prefixlen
= prefixlen
;
48 LIST_PREPEND(address_pools
, m
->address_pools
, p
);
54 int address_pool_new_from_string(
61 union in_addr_union u
;
68 r
= in_addr_from_string(family
, p
, &u
);
72 return address_pool_new(m
, ret
, family
, &u
, prefixlen
);
75 void address_pool_free(AddressPool
*p
) {
81 LIST_REMOVE(address_pools
, p
->manager
->address_pools
, p
);
86 static bool address_pool_prefix_is_taken(
88 const union in_addr_union
*u
,
98 HASHMAP_FOREACH(l
, p
->manager
->links
, i
) {
102 /* Don't clash with assigned addresses */
103 SET_FOREACH(a
, l
->addresses
, j
) {
104 if (a
->family
!= p
->family
)
107 if (in_addr_prefix_intersect(p
->family
, u
, prefixlen
, &a
->in_addr
, a
->prefixlen
))
111 /* Don't clash with addresses already pulled from the pool, but not assigned yet */
112 LIST_FOREACH(addresses
, a
, l
->pool_addresses
) {
113 if (a
->family
!= p
->family
)
116 if (in_addr_prefix_intersect(p
->family
, u
, prefixlen
, &a
->in_addr
, a
->prefixlen
))
121 /* And don't clash with configured but un-assigned addresses either */
122 LIST_FOREACH(networks
, n
, p
->manager
->networks
) {
125 LIST_FOREACH(addresses
, a
, n
->static_addresses
) {
126 if (a
->family
!= p
->family
)
129 if (in_addr_prefix_intersect(p
->family
, u
, prefixlen
, &a
->in_addr
, a
->prefixlen
))
137 int address_pool_acquire(AddressPool
*p
, unsigned prefixlen
, union in_addr_union
*found
) {
138 union in_addr_union u
;
141 assert(prefixlen
> 0);
144 if (p
->prefixlen
> prefixlen
)
149 if (!address_pool_prefix_is_taken(p
, &u
, prefixlen
)) {
150 _cleanup_free_
char *s
= NULL
;
152 in_addr_to_string(p
->family
, &u
, &s
);
153 log_debug("Found range %s/%u", strna(s
), prefixlen
);
159 if (!in_addr_prefix_next(p
->family
, &u
, prefixlen
))
162 if (!in_addr_prefix_intersect(p
->family
, &p
->in_addr
, p
->prefixlen
, &u
, prefixlen
))