summaryrefslogtreecommitdiff
path: root/src/network
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2015-08-26 19:19:32 +0200
committerLennart Poettering <lennart@poettering.net>2015-08-26 20:44:20 +0200
commit8eb9058dc1f99a5eb9b8726a978fcc0720837a10 (patch)
tree9e2670f8a77d6fd01d763c7097908f6824694571 /src/network
parent43f447b121b38c01a7c5626a51cc571a822250b8 (diff)
dhcp,network: implement RFC 4833 (DHCP Timezone option)
This one is simply to add: encode the tzdata timezone in the DHCP options and optionally make use of it.
Diffstat (limited to 'src/network')
-rw-r--r--src/network/networkctl.c9
-rw-r--r--src/network/networkd-dhcp4.c5
-rw-r--r--src/network/networkd-link.c29
-rw-r--r--src/network/networkd-network-gperf.gperf3
-rw-r--r--src/network/networkd-network.c40
-rw-r--r--src/network/networkd.h5
6 files changed, 88 insertions, 3 deletions
diff --git a/src/network/networkctl.c b/src/network/networkctl.c
index c9b53dc3f6..2281d4b718 100644
--- a/src/network/networkctl.c
+++ b/src/network/networkctl.c
@@ -497,7 +497,7 @@ static int link_status_one(
sd_hwdb *hwdb,
const char *name) {
_cleanup_strv_free_ char **dns = NULL, **ntp = NULL, **domains = NULL;
- _cleanup_free_ char *setup_state = NULL, *operational_state = NULL;
+ _cleanup_free_ char *setup_state = NULL, *operational_state = NULL, *timezone = NULL;
_cleanup_netlink_message_unref_ sd_netlink_message *req = NULL, *reply = NULL;
_cleanup_device_unref_ sd_device *d = NULL;
char devid[2 + DECIMAL_STR_MAX(int)];
@@ -570,7 +570,6 @@ static int link_status_one(
setup_state_to_color(setup_state, &on_color_setup, &off_color_setup);
sd_network_link_get_dns(ifindex, &dns);
- sd_network_link_get_ntp(ifindex, &ntp);
sd_network_link_get_domains(ifindex, &domains);
r = sd_network_link_get_wildcard_domain(ifindex);
if (r > 0) {
@@ -652,6 +651,8 @@ static int link_status_one(
dump_list(" DNS: ", dns);
if (!strv_isempty(domains))
dump_list(" Domain: ", domains);
+
+ (void) sd_network_link_get_ntp(ifindex, &ntp);
if (!strv_isempty(ntp))
dump_list(" NTP: ", ntp);
@@ -661,6 +662,10 @@ static int link_status_one(
if (!strv_isempty(carrier_bound_by))
dump_list("Carrier Bound By: ", carrier_bound_by);
+ (void) sd_network_link_get_timezone(ifindex, &timezone);
+ if (timezone)
+ printf(" Time Zone: %s", timezone);
+
return 0;
}
diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c
index 1b2ff7c769..7fce389fa2 100644
--- a/src/network/networkd-dhcp4.c
+++ b/src/network/networkd-dhcp4.c
@@ -624,6 +624,11 @@ int dhcp4_configure(Link *link) {
return r;
}
+ /* Always acquire the timezone */
+ r = sd_dhcp_client_set_request_option(link->dhcp_client, DHCP_OPTION_NEW_TZDB_TIMEZONE);
+ if (r < 0)
+ return r;
+
if (link->network->dhcp_sendhost) {
_cleanup_free_ char *hostname = NULL;
const char *hn = NULL;
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index cc9dc393c6..c179aafebb 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -672,6 +672,27 @@ static int link_enter_set_addresses(Link *link) {
return r;
*/
+ if (link->network->dhcp_server_emit_timezone) {
+ _cleanup_free_ char *buffer = NULL;
+ const char *tz;
+
+ if (link->network->dhcp_server_timezone)
+ tz = link->network->dhcp_server_timezone;
+ else {
+ r = get_timezone(&buffer);
+ if (r < 0)
+ log_warning_errno(r, "Failed to determine timezone: %m");
+ else
+ tz = buffer;
+ }
+
+ if (tz) {
+ r = sd_dhcp_server_set_timezone(link->dhcp_server, tz);
+ if (r < 0)
+ return r;
+ }
+ }
+
r = sd_dhcp_server_start(link->dhcp_server);
if (r < 0) {
log_link_warning_errno(link, r, "Could not start DHCPv4 server instance: %m");
@@ -2414,6 +2435,14 @@ int link_save(Link *link) {
}
if (link->dhcp_lease) {
+ const char *tz = NULL;
+
+ r = sd_dhcp_lease_get_timezone(link->dhcp_lease, &tz);
+ if (r >= 0)
+ fprintf(f, "TIMEZONE=%s\n", tz);
+ }
+
+ if (link->dhcp_lease) {
assert(link->network);
r = sd_dhcp_lease_save(link->dhcp_lease, link->lease_file);
diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf
index 7ac7ef1ea3..c8c612d4eb 100644
--- a/src/network/networkd-network-gperf.gperf
+++ b/src/network/networkd-network-gperf.gperf
@@ -73,6 +73,9 @@ DHCP.RequestBroadcast, config_parse_bool, 0
DHCP.CriticalConnection, config_parse_bool, 0, offsetof(Network, dhcp_critical)
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.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)
Bridge.UseBPDU, config_parse_bool, 0, offsetof(Network, use_bpdu)
Bridge.HairPin, config_parse_bool, 0, offsetof(Network, hairpin)
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index 8f773e738d..3619e3160c 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -124,7 +124,8 @@ static int network_load_one(Manager *manager, const char *filename) {
"Address\0"
"Route\0"
"DHCP\0"
- "DHCPv4\0"
+ "DHCPv4\0" /* compat */
+ "DHCPServer\0"
"Bridge\0"
"BridgeFDB\0",
config_item_perf_lookup, network_network_gperf_lookup,
@@ -258,6 +259,8 @@ void network_free(Network *network) {
condition_free_list(network->match_kernel);
condition_free_list(network->match_arch);
+ free(network->dhcp_server_timezone);
+
free(network);
}
@@ -849,3 +852,38 @@ int config_parse_hostname(
*hostname = hostname_cleanup(hn);
return 0;
}
+
+int config_parse_timezone(
+ const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+
+ char **timezone = data, *tz = NULL;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+
+ r = config_parse_string(unit, filename, line, section, section_line, lvalue, ltype, rvalue, &tz, userdata);
+ if (r < 0)
+ return r;
+
+ if (!timezone_is_valid(tz)) {
+ log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Timezone is not valid, ignoring assignment: %s", rvalue);
+ free(tz);
+ return 0;
+ }
+
+ free(*timezone);
+ *timezone = tz;
+
+ return 0;
+}
diff --git a/src/network/networkd.h b/src/network/networkd.h
index 5340922bf1..a337ea7bf0 100644
--- a/src/network/networkd.h
+++ b/src/network/networkd.h
@@ -143,12 +143,15 @@ struct Network {
bool dhcp_broadcast;
bool dhcp_critical;
bool dhcp_routes;
+ bool dhcp_timezone;
unsigned dhcp_route_metric;
AddressFamilyBoolean link_local;
bool ipv4ll_route;
union in_addr_union ipv6_token;
bool dhcp_server;
+ char *dhcp_server_timezone;
+ bool dhcp_server_emit_timezone;
bool use_bpdu;
bool hairpin;
@@ -461,3 +464,5 @@ int config_parse_ipv6_privacy_extensions(const char *unit, const char *filename,
/* Hostname */
int config_parse_hostname(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+
+int config_parse_timezone(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);