From 586ac6f711e2eccceb12421df22fca4f117226c4 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 27 Aug 2015 01:47:42 +0200 Subject: networkd: make DHCP lease timeouts configurable --- src/libsystemd-network/dhcp-server-internal.h | 4 +++- src/libsystemd-network/sd-dhcp-server.c | 34 +++++++++++++++++++++++---- src/network/networkd-link.c | 16 +++++++++++++ src/network/networkd-network-gperf.gperf | 2 ++ src/network/networkd.h | 1 + src/systemd/sd-dhcp-server.h | 3 +++ 6 files changed, 55 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/libsystemd-network/dhcp-server-internal.h b/src/libsystemd-network/dhcp-server-internal.h index 74b09d6f37..4f562c73ef 100644 --- a/src/libsystemd-network/dhcp-server-internal.h +++ b/src/libsystemd-network/dhcp-server-internal.h @@ -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); diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c index bfb799a63d..35564d8317 100644 --- a/src/libsystemd-network/sd-dhcp-server.c +++ b/src/libsystemd-network/sd-dhcp-server.c @@ -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; +} diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 09c27de22b..5b7ebfb79d 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -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; diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index c8c612d4eb..21e33efb42 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -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) diff --git a/src/network/networkd.h b/src/network/networkd.h index a337ea7bf0..d5da764bab 100644 --- a/src/network/networkd.h +++ b/src/network/networkd.h @@ -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; diff --git a/src/systemd/sd-dhcp-server.h b/src/systemd/sd-dhcp-server.h index a2e1995cf9..e070174a88 100644 --- a/src/systemd/sd-dhcp-server.h +++ b/src/systemd/sd-dhcp-server.h @@ -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 -- cgit v1.2.3-54-g00ecf