]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
networkd: make DHCP lease timeouts configurable
authorLennart Poettering <lennart@poettering.net>
Wed, 26 Aug 2015 23:47:42 +0000 (01:47 +0200)
committerLennart Poettering <lennart@poettering.net>
Wed, 26 Aug 2015 23:47:42 +0000 (01:47 +0200)
src/libsystemd-network/dhcp-server-internal.h
src/libsystemd-network/sd-dhcp-server.c
src/network/networkd-link.c
src/network/networkd-network-gperf.gperf
src/network/networkd.h
src/systemd/sd-dhcp-server.h

index 74b09d6f37199025ef3a97c25ef386a9c9602368..4f562c73ef2c8bd4a7af27654aaf31c38ab91ff5 100644 (file)
@@ -65,6 +65,8 @@ struct sd_dhcp_server {
 
         Hashmap *leases_by_client_id;
         DHCPLease **bound_leases;
+
+        uint32_t max_lease_time, default_lease_time;
 };
 
 typedef struct DHCPRequest {
@@ -76,7 +78,7 @@ typedef struct DHCPRequest {
         size_t max_optlen;
         be32_t server_id;
         be32_t requested_ip;
-        int lifetime;
+        uint32_t lifetime;
 } DHCPRequest;
 
 DEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp_server*, sd_dhcp_server_unref);
index bfb799a63d232ee1a4f76717eae7e4811c310d02..35564d83179c0be92ef752f85fa27e56d39bed09 100644 (file)
@@ -28,7 +28,8 @@
 #include "dhcp-server-internal.h"
 #include "dhcp-internal.h"
 
-#define DHCP_DEFAULT_LEASE_TIME         3600 /* one hour */
+#define DHCP_DEFAULT_LEASE_TIME_USEC USEC_PER_HOUR
+#define DHCP_MAX_LEASE_TIME_USEC (USEC_PER_HOUR*12)
 
 int sd_dhcp_server_set_lease_pool(sd_dhcp_server *server,
                                   struct in_addr *address,
@@ -172,6 +173,8 @@ int sd_dhcp_server_new(sd_dhcp_server **ret, int ifindex) {
         server->netmask = htobe32(INADDR_ANY);
         server->ifindex = ifindex;
         server->leases_by_client_id = hashmap_new(&client_id_hash_ops);
+        server->default_lease_time = DIV_ROUND_UP(DHCP_DEFAULT_LEASE_TIME_USEC, USEC_PER_SEC);
+        server->max_lease_time = DIV_ROUND_UP(DHCP_MAX_LEASE_TIME_USEC, USEC_PER_SEC);
 
         *ret = server;
         server = NULL;
@@ -598,7 +601,7 @@ static void dhcp_request_free(DHCPRequest *req) {
 DEFINE_TRIVIAL_CLEANUP_FUNC(DHCPRequest*, dhcp_request_free);
 #define _cleanup_dhcp_request_free_ _cleanup_(dhcp_request_freep)
 
-static int ensure_sane_request(DHCPRequest *req, DHCPMessage *message) {
+static int ensure_sane_request(sd_dhcp_server *server, DHCPRequest *req, DHCPMessage *message) {
         assert(req);
         assert(message);
 
@@ -624,7 +627,10 @@ static int ensure_sane_request(DHCPRequest *req, DHCPMessage *message) {
                 req->max_optlen = DHCP_MIN_OPTIONS_SIZE;
 
         if (req->lifetime <= 0)
-                req->lifetime = DHCP_DEFAULT_LEASE_TIME;
+                req->lifetime = MAX(1ULL, server->default_lease_time);
+
+        if (server->max_lease_time > 0 && req->lifetime > server->max_lease_time)
+                req->lifetime = server->max_lease_time;
 
         return 0;
 }
@@ -665,7 +671,7 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message,
         if (type < 0)
                 return 0;
 
-        r = ensure_sane_request(req, message);
+        r = ensure_sane_request(server, req, message);
         if (r < 0)
                 /* this only fails on critical errors */
                 return r;
@@ -1016,3 +1022,23 @@ int sd_dhcp_server_set_timezone(sd_dhcp_server *server, const char *timezone) {
 
         return 1;
 }
+
+int sd_dhcp_server_set_max_lease_time(sd_dhcp_server *server, uint32_t t) {
+        assert_return(server, -EINVAL);
+
+        if (t == server->max_lease_time)
+                return 0;
+
+        server->max_lease_time = t;
+        return 1;
+}
+
+int sd_dhcp_server_set_default_lease_time(sd_dhcp_server *server, uint32_t t) {
+        assert_return(server, -EINVAL);
+
+        if (t == server->default_lease_time)
+                return 0;
+
+        server->default_lease_time = t;
+        return 1;
+}
index 09c27de22b582a512e624cef7813493b7b849d15..5b7ebfb79d7b794392c3e90f5b36a7f51d849dd6 100644 (file)
@@ -673,6 +673,22 @@ static int link_enter_set_addresses(Link *link) {
                         return r;
                 */
 
+                if (link->network->dhcp_server_max_lease_time_usec > 0) {
+                        r = sd_dhcp_server_set_max_lease_time(
+                                        link->dhcp_server,
+                                        DIV_ROUND_UP(link->network->dhcp_server_max_lease_time_usec, USEC_PER_SEC));
+                        if (r < 0)
+                                return r;
+                }
+
+                if (link->network->dhcp_server_default_lease_time_usec > 0) {
+                        r = sd_dhcp_server_set_default_lease_time(
+                                        link->dhcp_server,
+                                        DIV_ROUND_UP(link->network->dhcp_server_default_lease_time_usec, USEC_PER_SEC));
+                        if (r < 0)
+                                return r;
+                }
+
                 if (link->network->dhcp_server_emit_timezone) {
                         _cleanup_free_ char *buffer = NULL;
                         const char *tz;
index c8c612d4ebafe6504a69f763ab2b19913e9ef179..21e33efb426fc710e1c2c56d9bd8fe1c9f686b2b 100644 (file)
@@ -74,6 +74,8 @@ DHCP.CriticalConnection,       config_parse_bool,                              0
 DHCP.VendorClassIdentifier,    config_parse_string,                            0,                             offsetof(Network, dhcp_vendor_class_identifier)
 DHCP.RouteMetric,              config_parse_unsigned,                          0,                             offsetof(Network, dhcp_route_metric)
 DHCP.UseTimezone,              config_parse_bool,                              0,                             offsetof(Network, dhcp_timezone)
+DHCPServer.MaxLeaseTimeSec,    config_parse_sec,                               0,                             offsetof(Network, dhcp_server_max_lease_time_usec)
+DHCPServer.DefaultLeaseTimeSec,config_parse_sec,                               0,                             offsetof(Network, dhcp_server_default_lease_time_usec)
 DHCPServer.EmitTimezone,       config_parse_bool,                              0,                             offsetof(Network, dhcp_server_emit_timezone)
 DHCPServer.Timezone,           config_parse_timezone,                          0,                             offsetof(Network, dhcp_server_timezone)
 Bridge.Cost,                   config_parse_unsigned,                          0,                             offsetof(Network, cost)
index a337ea7bf03d6fd8d314d1d3b8d5b772a329f658..d5da764babc0d6bc1571fd1e1ba1a603ddc012c8 100644 (file)
@@ -152,6 +152,7 @@ struct Network {
         bool dhcp_server;
         char *dhcp_server_timezone;
         bool dhcp_server_emit_timezone;
+        usec_t dhcp_server_default_lease_time_usec, dhcp_server_max_lease_time_usec;
 
         bool use_bpdu;
         bool hairpin;
index a2e1995cf9edc9c411d5f279305f1b3139a6dc3d..e070174a88887e3bf04d52819ac391d181ddf96b 100644 (file)
@@ -49,5 +49,8 @@ int sd_dhcp_server_set_lease_pool(sd_dhcp_server *server, struct in_addr *start,
 
 int sd_dhcp_server_set_timezone(sd_dhcp_server *server, const char *timezone);
 
+int sd_dhcp_server_set_max_lease_time(sd_dhcp_server *server, uint32_t t);
+int sd_dhcp_server_set_default_lease_time(sd_dhcp_server *server, uint32_t t);
+
 int sd_dhcp_server_forcerenew(sd_dhcp_server *server);
 #endif