diff options
Diffstat (limited to 'src/core/dhcp')
| -rw-r--r-- | src/core/dhcp/nm-dhcp-client.c | 35 | ||||
| -rw-r--r-- | src/core/dhcp/nm-dhcp-nettools.c | 62 | ||||
| -rw-r--r-- | src/core/dhcp/nm-dhcp-options.c | 36 | ||||
| -rw-r--r-- | src/core/dhcp/nm-dhcp-options.h | 28 | ||||
| -rw-r--r-- | src/core/dhcp/nm-dhcp-systemd.c | 33 |
5 files changed, 131 insertions, 63 deletions
diff --git a/src/core/dhcp/nm-dhcp-client.c b/src/core/dhcp/nm-dhcp-client.c index 600cb930..1fc2d944 100644 --- a/src/core/dhcp/nm-dhcp-client.c +++ b/src/core/dhcp/nm-dhcp-client.c @@ -241,7 +241,8 @@ nm_dhcp_client_create_l3cd(NMDhcpClient *self) GHashTable * nm_dhcp_client_create_options_dict(NMDhcpClient *self, gboolean static_keys) { - NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE(self); + NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE(self); + const int IS_IPv4 = NM_IS_IPv4(priv->config.addr_family); GHashTable *options; GBytes *effective_client_id; @@ -249,22 +250,18 @@ nm_dhcp_client_create_options_dict(NMDhcpClient *self, gboolean static_keys) effective_client_id = nm_dhcp_client_get_effective_client_id(self); if (effective_client_id) { - guint option = NM_IS_IPv4(priv->config.addr_family) ? NM_DHCP_OPTION_DHCP4_CLIENT_ID - : NM_DHCP_OPTION_DHCP6_CLIENT_ID; - gs_free char *str = nm_dhcp_utils_duid_to_string(effective_client_id); + guint option = IS_IPv4 ? NM_DHCP_OPTION_DHCP4_CLIENT_ID : NM_DHCP_OPTION_DHCP6_CLIENT_ID; + gs_free char *str = nm_dhcp_utils_duid_to_string(effective_client_id); /* Note that for the nm-dhcp-helper based plugins (dhclient), the plugin * may send the used client-id/DUID via the environment variables and * overwrite them yet again. */ - if (static_keys) { - nm_dhcp_option_add_option(options, priv->config.addr_family, option, str); - } else { - g_hash_table_insert( - options, - g_strdup(nm_dhcp_option_request_string(priv->config.addr_family, option)), - g_steal_pointer(&str)); - } + nm_dhcp_option_take_option(options, + static_keys, + priv->config.addr_family, + option, + g_steal_pointer(&str)); } return options; @@ -1591,6 +1588,20 @@ maybe_add_option(NMDhcpClient *self, GHashTable *hash, const char *key, GVariant str_value = nm_dhcp_utils_duid_to_string(bytes); } + if (!IS_IPv4 && nm_streq(key, "iaid")) { + gs_free char *str = g_steal_pointer(&str_value); + guint32 iaid; + + /* Validate and normalize the iaid. */ + + if (!nm_dhcp_iaid_from_hexstr(str, &iaid)) { + /* Seems invalid. Ignore */ + return; + } + + str_value = nm_dhcp_iaid_to_hexstr(iaid, g_malloc(NM_DHCP_IAID_TO_HEXSTR_BUF_LEN)); + } + g_hash_table_insert(hash, g_strdup(key), str_value); /* dhclient has no special labels for private dhcp options: it uses "unknown_xyz" diff --git a/src/core/dhcp/nm-dhcp-nettools.c b/src/core/dhcp/nm-dhcp-nettools.c index 9cdfd9aa..f36dfb4d 100644 --- a/src/core/dhcp/nm-dhcp-nettools.c +++ b/src/core/dhcp/nm-dhcp-nettools.c @@ -84,6 +84,11 @@ static void dhcp4_event_pop_all_events_on_idle(NMDhcpNettools *self); /*****************************************************************************/ +#define _add_option(options, option, str) \ + nm_dhcp_option_add_option((options), TRUE, AF_INET, (option), (str)) + +/*****************************************************************************/ + static void set_error_nettools(GError **error, int r, const char *message) { @@ -266,26 +271,34 @@ lease_parse_address(NMDhcpNettools *self /* for logging context only */, } nm_dhcp_option_add_option_in_addr(options, + TRUE, AF_INET, NM_DHCP_OPTION_DHCP4_NM_IP_ADDRESS, a_address.s_addr); nm_dhcp_option_add_option_in_addr(options, + TRUE, AF_INET, NM_DHCP_OPTION_DHCP4_SUBNET_MASK, a_netmask); nm_dhcp_option_add_option_u64(options, + TRUE, AF_INET, NM_DHCP_OPTION_DHCP4_IP_ADDRESS_LEASE_TIME, (guint64) a_lifetime); if (a_expiry != G_MAXUINT64) { - nm_dhcp_option_add_option_u64(options, AF_INET, NM_DHCP_OPTION_DHCP4_NM_EXPIRY, a_expiry); + nm_dhcp_option_add_option_u64(options, + TRUE, + AF_INET, + NM_DHCP_OPTION_DHCP4_NM_EXPIRY, + a_expiry); } n_dhcp4_client_lease_get_siaddr(lease, &a_next_server); if (a_next_server.s_addr != INADDR_ANY) { nm_dhcp_option_add_option_in_addr(options, + TRUE, AF_INET, NM_DHCP_OPTION_DHCP4_NM_NEXT_SERVER, a_next_server.s_addr); @@ -368,7 +381,7 @@ lease_parse_address_list(NDhcp4ClientLease *lease, } } - nm_dhcp_option_add_option(options, AF_INET, option, nm_str_buf_get_str(sbuf)); + _add_option(options, option, nm_str_buf_get_str(sbuf)); } static void @@ -446,7 +459,7 @@ lease_parse_routes(NDhcp4ClientLease *lease, } has_classless = TRUE; - nm_dhcp_option_add_option(options, AF_INET, option_code, nm_str_buf_get_str(sbuf)); + _add_option(options, option_code, nm_str_buf_get_str(sbuf)); } r = _client_lease_query(lease, NM_DHCP_OPTION_DHCP4_STATIC_ROUTE, &l_data, &l_data_len); @@ -489,10 +502,7 @@ lease_parse_routes(NDhcp4ClientLease *lease, })); } - nm_dhcp_option_add_option(options, - AF_INET, - NM_DHCP_OPTION_DHCP4_STATIC_ROUTE, - nm_str_buf_get_str(sbuf)); + _add_option(options, NM_DHCP_OPTION_DHCP4_STATIC_ROUTE, nm_str_buf_get_str(sbuf)); } r = _client_lease_query(lease, NM_DHCP_OPTION_DHCP4_ROUTER, &l_data, &l_data_len); @@ -534,10 +544,7 @@ lease_parse_routes(NDhcp4ClientLease *lease, })); } - nm_dhcp_option_add_option(options, - AF_INET, - NM_DHCP_OPTION_DHCP4_ROUTER, - nm_str_buf_get_str(sbuf)); + _add_option(options, NM_DHCP_OPTION_DHCP4_ROUTER, nm_str_buf_get_str(sbuf)); } } @@ -570,6 +577,7 @@ lease_parse_search_domains(NDhcp4ClientLease *lease, nm_l3_config_data_add_search(l3cd, AF_INET, domains[i]); nm_dhcp_option_take_option(options, + TRUE, AF_INET, NM_DHCP_OPTION_DHCP4_DOMAIN_SEARCH_LIST, g_strjoinv(" ", domains)); @@ -598,7 +606,7 @@ lease_parse_private_options(NDhcp4ClientLease *lease, GHashTable *options) continue; option_string = nm_utils_bin2hexstr_full(l_data, l_data_len, ':', FALSE, NULL); - nm_dhcp_option_take_option(options, AF_INET, i, g_steal_pointer(&option_string)); + nm_dhcp_option_take_option(options, TRUE, AF_INET, i, g_steal_pointer(&option_string)); } } @@ -632,6 +640,7 @@ lease_to_ip4_config(NMDhcpNettools *self, NDhcp4ClientLease *lease, GError **err r = n_dhcp4_client_lease_get_server_identifier(lease, &v_inaddr_s); if (r == 0) { nm_dhcp_option_add_option_in_addr(options, + TRUE, AF_INET, NM_DHCP_OPTION_DHCP4_SERVER_ID, v_inaddr_s.s_addr); @@ -645,6 +654,7 @@ lease_to_ip4_config(NMDhcpNettools *self, NDhcp4ClientLease *lease, GError **err iface, NM_DHCP_OPTION_DHCP4_BROADCAST)) { nm_dhcp_option_add_option_in_addr(options, + TRUE, AF_INET, NM_DHCP_OPTION_DHCP4_BROADCAST, v_inaddr); @@ -696,10 +706,7 @@ lease_to_ip4_config(NMDhcpNettools *self, NDhcp4ClientLease *lease, GError **err } if (sbuf.len > 0) { - nm_dhcp_option_add_option(options, - AF_INET, - NM_DHCP_OPTION_DHCP4_DOMAIN_NAME, - nm_str_buf_get_str(&sbuf)); + _add_option(options, NM_DHCP_OPTION_DHCP4_DOMAIN_NAME, nm_str_buf_get_str(&sbuf)); } } @@ -713,7 +720,11 @@ lease_to_ip4_config(NMDhcpNettools *self, NDhcp4ClientLease *lease, GError **err iface, AF_INET, NM_DHCP_OPTION_DHCP4_INTERFACE_MTU)) { - nm_dhcp_option_add_option_u64(options, AF_INET, NM_DHCP_OPTION_DHCP4_INTERFACE_MTU, v_u16); + nm_dhcp_option_add_option_u64(options, + TRUE, + AF_INET, + NM_DHCP_OPTION_DHCP4_INTERFACE_MTU, + v_u16); nm_l3_config_data_set_mtu(l3cd, v_u16); } @@ -731,7 +742,7 @@ lease_to_ip4_config(NMDhcpNettools *self, NDhcp4ClientLease *lease, GError **err iface, AF_INET, NM_DHCP_OPTION_DHCP4_HOST_NAME)) { - nm_dhcp_option_add_option(options, AF_INET, NM_DHCP_OPTION_DHCP4_HOST_NAME, s); + _add_option(options, NM_DHCP_OPTION_DHCP4_HOST_NAME, s); } } @@ -755,6 +766,7 @@ lease_to_ip4_config(NMDhcpNettools *self, NDhcp4ClientLease *lease, GError **err /* "Its minimum length is 1." */ } else { nm_dhcp_option_add_option_utf8safe_escape(options, + TRUE, AF_INET, NM_DHCP_OPTION_DHCP4_ROOT_PATH, l_data, @@ -782,10 +794,7 @@ lease_to_ip4_config(NMDhcpNettools *self, NDhcp4ClientLease *lease, GError **err const char *escaped; escaped = nm_utils_buf_utf8safe_escape((char *) l_data, l_data_len, 0, &to_free); - nm_dhcp_option_add_option(options, - AF_INET, - NM_DHCP_OPTION_DHCP4_PRIVATE_PROXY_AUTODISCOVERY, - escaped ?: ""); + _add_option(options, NM_DHCP_OPTION_DHCP4_PRIVATE_PROXY_AUTODISCOVERY, escaped ?: ""); nm_l3_config_data_set_proxy_method(l3cd, NM_PROXY_CONFIG_METHOD_AUTO); nm_l3_config_data_set_proxy_pac_url(l3cd, escaped ?: ""); @@ -808,7 +817,7 @@ lease_to_ip4_config(NMDhcpNettools *self, NDhcp4ClientLease *lease, GError **err NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL, &to_free); - nm_dhcp_option_add_option(options, AF_INET, NM_DHCP_OPTION_DHCP4_NIS_DOMAIN, v_str ?: ""); + _add_option(options, NM_DHCP_OPTION_DHCP4_NIS_DOMAIN, v_str ?: ""); nm_l3_config_data_set_nis_domain(l3cd, v_str ?: ""); } @@ -820,7 +829,7 @@ lease_to_ip4_config(NMDhcpNettools *self, NDhcp4ClientLease *lease, GError **err -1, NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL, &to_free); - nm_dhcp_option_add_option(options, AF_INET, NM_DHCP_OPTION_DHCP4_NM_FILENAME, v_str ?: ""); + _add_option(options, NM_DHCP_OPTION_DHCP4_NM_FILENAME, v_str ?: ""); } r = _client_lease_query(lease, NM_DHCP_OPTION_DHCP4_BOOTFILE_NAME, &l_data, &l_data_len); @@ -837,10 +846,7 @@ lease_to_ip4_config(NMDhcpNettools *self, NDhcp4ClientLease *lease, GError **err l_data_len, NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL, &to_free); - nm_dhcp_option_add_option(options, - AF_INET, - NM_DHCP_OPTION_DHCP4_BOOTFILE_NAME, - v_str ?: ""); + _add_option(options, NM_DHCP_OPTION_DHCP4_BOOTFILE_NAME, v_str ?: ""); } lease_parse_address_list(lease, l3cd, iface, NM_DHCP_OPTION_DHCP4_NIS_SERVERS, options, &sbuf); diff --git a/src/core/dhcp/nm-dhcp-options.c b/src/core/dhcp/nm-dhcp-options.c index d95fe016..33a9f4ed 100644 --- a/src/core/dhcp/nm-dhcp-options.c +++ b/src/core/dhcp/nm-dhcp-options.c @@ -383,8 +383,14 @@ nm_dhcp_option_find(int addr_family, guint option) /*****************************************************************************/ void -nm_dhcp_option_take_option(GHashTable *options, int addr_family, guint option, char *value) +nm_dhcp_option_take_option(GHashTable *options, + gboolean static_keys, + int addr_family, + guint option, + char *value) { + const char *key; + nm_assert_addr_family(addr_family); nm_assert(value); nm_assert(g_utf8_validate(value, -1, NULL)); @@ -395,19 +401,13 @@ nm_dhcp_option_take_option(GHashTable *options, int addr_family, guint option, c return; } - g_hash_table_insert(options, - (gpointer) nm_dhcp_option_request_string(addr_family, option), - value); -} - -void -nm_dhcp_option_add_option(GHashTable *options, int addr_family, guint option, const char *value) -{ - nm_dhcp_option_take_option(options, addr_family, option, g_strdup(value)); + key = nm_dhcp_option_request_string(addr_family, option), + g_hash_table_insert(options, static_keys ? (gpointer) key : g_strdup(key), value); } void nm_dhcp_option_add_option_utf8safe_escape(GHashTable *options, + gboolean static_keys, int addr_family, guint option, const guint8 *data, @@ -420,13 +420,18 @@ nm_dhcp_option_add_option_utf8safe_escape(GHashTable *options, n_data, NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL, &to_free); - nm_dhcp_option_add_option(options, addr_family, option, escaped ?: ""); + nm_dhcp_option_add_option(options, static_keys, addr_family, option, escaped ?: ""); } void -nm_dhcp_option_add_option_u64(GHashTable *options, int addr_family, guint option, guint64 value) +nm_dhcp_option_add_option_u64(GHashTable *options, + gboolean static_keys, + int addr_family, + guint option, + guint64 value) { nm_dhcp_option_take_option(options, + static_keys, addr_family, option, g_strdup_printf("%" G_GUINT64_FORMAT, value)); @@ -434,13 +439,18 @@ nm_dhcp_option_add_option_u64(GHashTable *options, int addr_family, guint option void nm_dhcp_option_add_option_in_addr(GHashTable *options, + gboolean static_keys, int addr_family, guint option, in_addr_t value) { char sbuf[NM_INET_ADDRSTRLEN]; - nm_dhcp_option_add_option(options, addr_family, option, nm_inet4_ntop(value, sbuf)); + nm_dhcp_option_add_option(options, + static_keys, + addr_family, + option, + nm_inet4_ntop(value, sbuf)); } void diff --git a/src/core/dhcp/nm-dhcp-options.h b/src/core/dhcp/nm-dhcp-options.h index fcc6f9cd..050080d9 100644 --- a/src/core/dhcp/nm-dhcp-options.h +++ b/src/core/dhcp/nm-dhcp-options.h @@ -208,20 +208,38 @@ nm_dhcp_option_request_string(int addr_family, guint option) return nm_dhcp_option_get_name(nm_dhcp_option_find(addr_family, option)); } -void nm_dhcp_option_take_option(GHashTable *options, int addr_family, guint option, char *value); -void -nm_dhcp_option_add_option(GHashTable *options, int addr_family, guint option, const char *value); +void nm_dhcp_option_take_option(GHashTable *options, + gboolean static_keys, + int addr_family, + guint option, + char *value); + +static inline void +nm_dhcp_option_add_option(GHashTable *options, + gboolean static_keys, + int addr_family, + guint option, + const char *value) +{ + nm_dhcp_option_take_option(options, static_keys, addr_family, option, g_strdup(value)); +} + void nm_dhcp_option_add_option_utf8safe_escape(GHashTable *options, + gboolean static_keys, int addr_family, guint option, const guint8 *data, gsize n_data); void nm_dhcp_option_add_option_in_addr(GHashTable *options, + gboolean static_keys, int addr_family, guint option, in_addr_t value); -void -nm_dhcp_option_add_option_u64(GHashTable *options, int addr_family, guint option, guint64 value); +void nm_dhcp_option_add_option_u64(GHashTable *options, + gboolean static_keys, + int addr_family, + guint option, + guint64 value); void nm_dhcp_option_add_requests_to_options(GHashTable *options, int addr_family); GHashTable *nm_dhcp_option_create_options_dict(gboolean static_keys); diff --git a/src/core/dhcp/nm-dhcp-systemd.c b/src/core/dhcp/nm-dhcp-systemd.c index 10990822..6f9312da 100644 --- a/src/core/dhcp/nm-dhcp-systemd.c +++ b/src/core/dhcp/nm-dhcp-systemd.c @@ -70,11 +70,13 @@ G_DEFINE_TYPE(NMDhcpSystemd, nm_dhcp_systemd, NM_TYPE_DHCP_CLIENT) static NML3ConfigData * lease_to_ip6_config(NMDhcpSystemd *self, sd_dhcp6_lease *lease, gint32 ts, GError **error) { + const NMDhcpClientConfig *config; nm_auto_unref_l3cd_init NML3ConfigData *l3cd = NULL; gs_unref_hashtable GHashTable *options = NULL; struct in6_addr tmp_addr; const struct in6_addr *dns; char addr_str[NM_INET_ADDRSTRLEN]; + char iaid_buf[NM_DHCP_IAID_TO_HEXSTR_BUF_LEN]; char **domains; char **ntp_fqdns; const struct in6_addr *ntp_addrs; @@ -84,11 +86,19 @@ lease_to_ip6_config(NMDhcpSystemd *self, sd_dhcp6_lease *lease, gint32 ts, GErro nm_assert(lease); + config = nm_dhcp_client_get_config(NM_DHCP_CLIENT(self)); + l3cd = nm_dhcp_client_create_l3cd(NM_DHCP_CLIENT(self)); options = nm_dhcp_client_create_options_dict(NM_DHCP_CLIENT(self), TRUE); - if (!nm_dhcp_client_get_config(NM_DHCP_CLIENT(self))->v6.info_only) { + nm_dhcp_option_add_option(options, + TRUE, + AF_INET6, + NM_DHCP_OPTION_DHCP6_NM_IAID, + nm_dhcp_iaid_to_hexstr(config->v6.iaid, iaid_buf)); + + if (!config->v6.info_only) { gboolean has_any_addresses = FALSE; uint32_t lft_pref; uint32_t lft_valid; @@ -115,6 +125,7 @@ lease_to_ip6_config(NMDhcpSystemd *self, sd_dhcp6_lease *lease, gint32 ts, GErro if (str->len) { nm_dhcp_option_add_option(options, + TRUE, AF_INET6, NM_DHCP_OPTION_DHCP6_NM_IP_ADDRESS, str->str); @@ -137,7 +148,11 @@ lease_to_ip6_config(NMDhcpSystemd *self, sd_dhcp6_lease *lease, gint32 ts, GErro g_string_append(nm_gstring_add_space_delimiter(str), addr_str); nm_l3_config_data_add_nameserver_detail(l3cd, AF_INET6, &dns[i], NULL); } - nm_dhcp_option_add_option(options, AF_INET6, NM_DHCP_OPTION_DHCP6_DNS_SERVERS, str->str); + nm_dhcp_option_add_option(options, + TRUE, + AF_INET6, + NM_DHCP_OPTION_DHCP6_DNS_SERVERS, + str->str); } num = sd_dhcp6_lease_get_domains(lease, &domains); @@ -147,11 +162,15 @@ lease_to_ip6_config(NMDhcpSystemd *self, sd_dhcp6_lease *lease, gint32 ts, GErro g_string_append(nm_gstring_add_space_delimiter(str), domains[i]); nm_l3_config_data_add_search(l3cd, AF_INET6, domains[i]); } - nm_dhcp_option_add_option(options, AF_INET6, NM_DHCP_OPTION_DHCP6_DOMAIN_LIST, str->str); + nm_dhcp_option_add_option(options, + TRUE, + AF_INET6, + NM_DHCP_OPTION_DHCP6_DOMAIN_LIST, + str->str); } if (sd_dhcp6_lease_get_fqdn(lease, &s) >= 0) { - nm_dhcp_option_add_option(options, AF_INET6, NM_DHCP_OPTION_DHCP6_FQDN, s); + nm_dhcp_option_add_option(options, TRUE, AF_INET6, NM_DHCP_OPTION_DHCP6_FQDN, s); } /* RFC 5908, section 4 states: "This option MUST include one, and only @@ -175,7 +194,11 @@ lease_to_ip6_config(NMDhcpSystemd *self, sd_dhcp6_lease *lease, gint32 ts, GErro } } if (str->len) { - nm_dhcp_option_add_option(options, AF_INET6, NM_DHCP_OPTION_DHCP6_NTP_SERVER, str->str); + nm_dhcp_option_add_option(options, + TRUE, + 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)); |