diff options
author | Lennart Poettering <lennart@poettering.net> | 2014-06-18 18:22:14 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2014-06-18 18:28:29 +0200 |
commit | 11bf3cced13c885ca215c108cb0bdb7a148520d6 (patch) | |
tree | a4b0af55dee44c786b80bcfab13e3eb0f3f84a4e /src/network/networkd-manager.c | |
parent | 059f6c42b744a18d0deec0c79a9e0730ec6c1c76 (diff) |
networkd: add address pool support
When an address is configured to be all zeroes, networkd will now
automatically find a locally unused network of the right size from a
list of pre-configured pools. Currently those pools are 10.0.0.0/8,
172.16.0.0/12, 192.168.0.0/16 and fc00::/7, i.e. the network ranges for
private networks. They are compiled in, but should be configurable
eventually.
This allows applying the same configuration to a large number of
interfaces with each time a different IP range block, and management of
these IP ranges is fully automatic.
When allocating an address range from the pool it is made sure the range
is not used otherwise.
Diffstat (limited to 'src/network/networkd-manager.c')
-rw-r--r-- | src/network/networkd-manager.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index 2a0d5342da..5cc88723e5 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -75,6 +75,33 @@ static int setup_signals(Manager *m) { return 0; } +static int setup_default_address_pool(Manager *m) { + AddressPool *p; + int r; + + assert(m); + + /* Add in the well-known private address ranges. */ + + r = address_pool_new_from_string(m, &p, AF_INET6, "fc00::", 7); + if (r < 0) + return r; + + r = address_pool_new_from_string(m, &p, AF_INET, "192.168.0.0", 16); + if (r < 0) + return r; + + r = address_pool_new_from_string(m, &p, AF_INET, "172.16.0.0", 12); + if (r < 0) + return r; + + r = address_pool_new_from_string(m, &p, AF_INET, "10.0.0.0", 8); + if (r < 0) + return r; + + return 0; +} + int manager_new(Manager **ret) { _cleanup_manager_free_ Manager *m = NULL; int r; @@ -129,6 +156,10 @@ int manager_new(Manager **ret) { LIST_HEAD_INIT(m->networks); + r = setup_default_address_pool(m); + if (r < 0) + return r; + *ret = m; m = NULL; @@ -139,6 +170,7 @@ void manager_free(Manager *m) { Network *network; NetDev *netdev; Link *link; + AddressPool *pool; if (!m) return; @@ -164,6 +196,9 @@ void manager_free(Manager *m) { netdev_unref(netdev); hashmap_free(m->netdevs); + while ((pool = m->address_pools)) + address_pool_free(pool); + sd_rtnl_unref(m->rtnl); free(m); @@ -460,3 +495,23 @@ finish: return r; } + +int manager_address_pool_acquire(Manager *m, unsigned family, unsigned prefixlen, union in_addr_union *found) { + AddressPool *p; + int r; + + assert(m); + assert(prefixlen > 0); + assert(found); + + LIST_FOREACH(address_pools, p, m->address_pools) { + if (p->family != family) + continue; + + r = address_pool_acquire(p, prefixlen, found); + if (r != 0) + return r; + } + + return 0; +} |