summaryrefslogtreecommitdiff
path: root/src/network
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2014-06-18 18:26:03 +0200
committerLennart Poettering <lennart@poettering.net>2014-06-18 18:28:29 +0200
commit4f4349389760480759612b2b1d0fb02c1743dff3 (patch)
tree8037693a06ce935418a4d810634bdb43fdbaaf3c /src/network
parent11bf3cced13c885ca215c108cb0bdb7a148520d6 (diff)
networkd: configure dhcp server range only after successfully setting an IP address on the interface
This way we can make use of the addresses of the IP pool.
Diffstat (limited to 'src/network')
-rw-r--r--src/network/networkd-link.c100
1 files changed, 62 insertions, 38 deletions
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index e7753dc98..5b2dabc0d 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -251,6 +251,35 @@ static void link_enter_failed(Link *link) {
link_save(link);
}
+static Address* link_find_dhcp_server_address(Link *link) {
+ Address *address;
+
+ assert(link);
+ assert(link->network);
+
+ /* The the first statically configured address if there is any */
+ LIST_FOREACH(addresses, address, link->network->static_addresses) {
+
+ if (address->family != AF_INET)
+ continue;
+
+ if (in_addr_null(address->family, &address->in_addr))
+ continue;
+
+ return address;
+ }
+
+ /* If that didn't work, find a suitable address we got from the pool */
+ LIST_FOREACH(addresses, address, link->pool_addresses) {
+ if (address->family != AF_INET)
+ continue;
+
+ return address;
+ }
+
+ return NULL;
+}
+
static int link_enter_configured(Link *link) {
int r;
@@ -258,10 +287,42 @@ static int link_enter_configured(Link *link) {
assert(link->network);
assert(link->state == LINK_STATE_SETTING_ROUTES);
-
if (link->network->dhcp_server) {
+ struct in_addr pool_start;
+ Address *address;
+
+ address = link_find_dhcp_server_address(link);
+ if (!address) {
+ log_warning_link(link, "Failed to find suitable address for DHCPv4 server instance.");
+ link_enter_failed(link);
+ return 0;
+ }
+
log_debug_link(link, "offering DHCPv4 leases");
+ r = sd_dhcp_server_set_address(link->dhcp_server, &address->in_addr.in);
+ if (r < 0)
+ return r;
+
+ /* offer 32 addresses starting from the address following the server address */
+ pool_start.s_addr = htobe32(be32toh(address->in_addr.in.s_addr) + 1);
+ r = sd_dhcp_server_set_lease_pool(link->dhcp_server,
+ &pool_start, 32);
+ if (r < 0)
+ return r;
+
+ /* TODO:
+ r = sd_dhcp_server_set_router(link->dhcp_server,
+ &main_address->in_addr.in);
+ if (r < 0)
+ return r;
+
+ r = sd_dhcp_server_set_prefixlen(link->dhcp_server,
+ main_address->prefixlen);
+ if (r < 0)
+ return r;
+ */
+
r = sd_dhcp_server_start(link->dhcp_server);
if (r < 0) {
log_warning_link(link, "could not start DHCPv4 server "
@@ -1723,8 +1784,6 @@ static int link_configure(Link *link) {
}
if (link->network->dhcp_server) {
- Address *address;
-
r = sd_dhcp_server_new(&link->dhcp_server, link->ifindex);
if (r < 0)
return r;
@@ -1732,41 +1791,6 @@ static int link_configure(Link *link) {
r = sd_dhcp_server_attach_event(link->dhcp_server, NULL, 0);
if (r < 0)
return r;
-
- LIST_FOREACH(addresses, address,
- link->network->static_addresses) {
- struct in_addr pool_start;
-
- if (address->family != AF_INET)
- continue;
-
- /* currently this is picked essentially at random */
- r = sd_dhcp_server_set_address(link->dhcp_server,
- &address->in_addr.in);
- if (r < 0)
- return r;
-
- /* offer 32 addresses starting from the address following the server address */
- pool_start.s_addr = htobe32(be32toh(address->in_addr.in.s_addr) + 1);
- r = sd_dhcp_server_set_lease_pool(link->dhcp_server,
- &pool_start, 32);
- if (r < 0)
- return r;
-
- break;
- }
-
- /* TODO:
- r = sd_dhcp_server_set_router(link->dhcp_server,
- &main_address->in_addr.in);
- if (r < 0)
- return r;
-
- r = sd_dhcp_server_set_prefixlen(link->dhcp_server,
- main_address->prefixlen);
- if (r < 0)
- return r;
- */
}
if (link_has_carrier(link->flags, link->kernel_operstate)) {