diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2019-02-21 05:31:35 +0100 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2019-03-01 08:34:44 +0100 |
commit | 304e7e9d53621b78b44c52e6aff20ed5828afc67 (patch) | |
tree | d17ea2ba2d43e6c75105513dfe3b426d92bd0ddd /src/network/networkd-address-pool.c | |
parent | test: add tests for in_addr_random_prefix() (diff) | |
download | systemd-304e7e9d53621b78b44c52e6aff20ed5828afc67.tar.xz 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.c | 31 |
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; |