summaryrefslogtreecommitdiff
path: root/src/network/networkd-address-pool.c
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2019-02-21 13:31:35 +0900
committerYu Watanabe <watanabe.yu+github@gmail.com>2019-03-01 16:34:44 +0900
commit304e7e9d53621b78b44c52e6aff20ed5828afc67 (patch)
treed17ea2ba2d43e6c75105513dfe3b426d92bd0ddd /src/network/networkd-address-pool.c
parente762ea74812c8c75a40eb707f8fca10304ce2abc (diff)
downloadsystemd-304e7e9d53621b78b44c52e6aff20ed5828afc67.tar.gz
systemd-304e7e9d53621b78b44c52e6aff20ed5828afc67.tar.bz2
systemd-304e7e9d53621b78b44c52e6aff20ed5828afc67.zip
network: generate random prefix from address pool
Fixes #9955.
Diffstat (limited to 'src/network/networkd-address-pool.c')
-rw-r--r--src/network/networkd-address-pool.c31
1 files changed, 16 insertions, 15 deletions
diff --git a/src/network/networkd-address-pool.c b/src/network/networkd-address-pool.c
index 26c73acbb7..eaf056d118 100644
--- a/src/network/networkd-address-pool.c
+++ b/src/network/networkd-address-pool.c
@@ -6,6 +6,8 @@
#include "set.h"
#include "string-util.h"
+#define RANDOM_PREFIX_TRIAL_MAX 1024
+
static int address_pool_new(
Manager *m,
AddressPool **ret,
@@ -121,35 +123,34 @@ static bool address_pool_prefix_is_taken(
int address_pool_acquire(AddressPool *p, unsigned prefixlen, union in_addr_union *found) {
union in_addr_union u;
+ unsigned i;
+ int r;
assert(p);
assert(prefixlen > 0);
assert(found);
- if (p->prefixlen > prefixlen)
+ if (p->prefixlen >= prefixlen)
return 0;
u = p->in_addr;
- for (;;) {
- if (!address_pool_prefix_is_taken(p, &u, prefixlen)) {
- _cleanup_free_ char *s = NULL;
- int r;
- r = in_addr_to_string(p->family, &u, &s);
- if (r < 0)
- return r;
+ for (i = 0; i < RANDOM_PREFIX_TRIAL_MAX; i++) {
+ r = in_addr_random_prefix(p->family, &u, p->prefixlen, prefixlen);
+ if (r <= 0)
+ return r;
- log_debug("Found range %s/%u", strna(s), prefixlen);
+ if (!address_pool_prefix_is_taken(p, &u, prefixlen)) {
+ if (DEBUG_LOGGING) {
+ _cleanup_free_ char *s = NULL;
+
+ (void) in_addr_to_string(p->family, &u, &s);
+ log_debug("Found range %s/%u", strna(s), prefixlen);
+ }
*found = u;
return 1;
}
-
- if (!in_addr_prefix_next(p->family, &u, prefixlen))
- return 0;
-
- if (!in_addr_prefix_intersect(p->family, &p->in_addr, p->prefixlen, &u, prefixlen))
- return 0;
}
return 0;