summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLubomir Rintel <lkundrak@v3.sk>2022-02-01 10:57:19 +0100
committerLubomir Rintel <lkundrak@v3.sk>2022-02-01 10:57:19 +0100
commitee2fff92d6e48b414edc0ce78730aa919f0ab9f5 (patch)
tree24663261603d9d8a78c544e7fef2bf5a0d825530
parent81cf70b0c12eb35a7e80399f191900ff1ee8a8cb (diff)
dhcp: include "dhcp6_ntp_server" in Dhcp6Configlr/dhcp6-ntp-server
Works for the internal DHCP client only as sd-dhcp does the option parsing for us. The option 56 is not understood by dhclient so we would need to parse it ourselves. Let's not do it for now, as the RFC seems to written in a somewhat poor taste. https://bugzilla.redhat.com/show_bug.cgi?id=2047415#c2
-rw-r--r--src/core/dhcp/nm-dhcp-options.c2
-rw-r--r--src/core/dhcp/nm-dhcp-options.h3
-rw-r--r--src/core/dhcp/nm-dhcp-systemd.c26
3 files changed, 30 insertions, 1 deletions
diff --git a/src/core/dhcp/nm-dhcp-options.c b/src/core/dhcp/nm-dhcp-options.c
index ab64a67c1c..4f7896743e 100644
--- a/src/core/dhcp/nm-dhcp-options.c
+++ b/src/core/dhcp/nm-dhcp-options.c
@@ -201,6 +201,7 @@ const NMDhcpOption _nm_dhcp_option_dhcp6_options[] = {
REQ(NM_DHCP_OPTION_DHCP6_DOMAIN_LIST, "dhcp6_domain_search", TRUE),
REQ(NM_DHCP_OPTION_DHCP6_SNTP_SERVERS, "dhcp6_sntp_servers", TRUE),
REQ(NM_DHCP_OPTION_DHCP6_FQDN, "fqdn_fqdn", FALSE),
+ REQ(NM_DHCP_OPTION_DHCP6_NTP_SERVER, "dhcp6_ntp_server", TRUE),
REQ(NM_DHCP_OPTION_DHCP6_MUD_URL, "dhcp6_mud_url", FALSE),
/* Internal values */
@@ -235,6 +236,7 @@ static const NMDhcpOption *const _sorted_options_6[G_N_ELEMENTS(_nm_dhcp_option_
A(13),
A(14),
A(15),
+ A(16),
#undef A
};
diff --git a/src/core/dhcp/nm-dhcp-options.h b/src/core/dhcp/nm-dhcp-options.h
index 1e26a5bfe3..4c978c4f97 100644
--- a/src/core/dhcp/nm-dhcp-options.h
+++ b/src/core/dhcp/nm-dhcp-options.h
@@ -163,6 +163,7 @@ typedef enum {
NM_DHCP_OPTION_DHCP6_DOMAIN_LIST = 24,
NM_DHCP_OPTION_DHCP6_SNTP_SERVERS = 31,
NM_DHCP_OPTION_DHCP6_FQDN = 39,
+ NM_DHCP_OPTION_DHCP6_NTP_SERVER = 56, /* RFC 5908 */
NM_DHCP_OPTION_DHCP6_MUD_URL = 112,
/* Internal values */
@@ -187,7 +188,7 @@ typedef struct {
} NMDhcpOption;
extern const NMDhcpOption _nm_dhcp_option_dhcp4_options[143];
-extern const NMDhcpOption _nm_dhcp_option_dhcp6_options[16];
+extern const NMDhcpOption _nm_dhcp_option_dhcp6_options[17];
static inline const char *
nm_dhcp_option_get_name(const NMDhcpOption *option)
diff --git a/src/core/dhcp/nm-dhcp-systemd.c b/src/core/dhcp/nm-dhcp-systemd.c
index 46da3b7630..efb2a83fd5 100644
--- a/src/core/dhcp/nm-dhcp-systemd.c
+++ b/src/core/dhcp/nm-dhcp-systemd.c
@@ -771,6 +771,8 @@ lease_to_ip6_config(NMDedupMultiIndex *multi_idx,
uint32_t lft_pref, lft_valid;
char addr_str[NM_UTILS_INET_ADDRSTRLEN];
char **domains;
+ char **ntp_fqdns;
+ struct in6_addr *ntp_addrs;
const char *s;
nm_auto_free_gstring GString *str = NULL;
gboolean has_any_addresses = FALSE;
@@ -839,6 +841,30 @@ lease_to_ip6_config(NMDedupMultiIndex *multi_idx,
nm_dhcp_option_add_option(options, AF_INET6, NM_DHCP_OPTION_DHCP6_FQDN, s);
}
+ /* RFC 5908, section 4 states: "This option MUST include one, and only
+ * one, time source suboption." It is not clear why systemd chose to
+ * return array of addresses and FQDNs. Given there seem to be no
+ * technical obstacles to including multiple options, let's just
+ * pass on whatever systemd tells us.
+ */
+ nm_gstring_prepare(&str);
+ num = sd_dhcp6_lease_get_ntp_fqdn(lease, &ntp_fqdns);
+ if (num > 0) {
+ for (i = 0; i < num; i++) {
+ g_string_append(nm_gstring_add_space_delimiter(str), ntp_fqdns[i]);
+ }
+ }
+ num = sd_dhcp6_lease_get_ntp_addrs(lease, &ntp_addrs);
+ if (num > 0) {
+ for (i = 0; i < num; i++) {
+ _nm_utils_inet6_ntop(&ntp_addrs[i], addr_str);
+ g_string_append(nm_gstring_add_space_delimiter(str), addr_str);
+ }
+ }
+ if (str->len) {
+ nm_dhcp_option_add_option(options, AF_INET6, NM_DHCP_OPTION_DHCP6_NTP_SERVER, str->str);
+ }
+
nm_l3_config_data_set_dhcp_lease_from_options(l3cd, AF_INET6, g_steal_pointer(&options));
return g_steal_pointer(&l3cd);